Removal of chrono and async_trait as dependancy in db-lib
Removig chrono from api code as well Removing chrono as dep in api code + Using Content-Type for /message/send content type Updating cargo lists for removal of fluff deps Removal of more fluff Addking makefile to avoid compiling debug builds by accident while developing
This commit is contained in:
1576
json-api/db/Cargo.lock
generated
1576
json-api/db/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -8,9 +8,6 @@ edition = "2018"
|
||||
|
||||
[dependencies]
|
||||
mysql_async = "0.23.1"
|
||||
async-trait = "0.1.40"
|
||||
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0.117", features = [ "derive" ] }
|
||||
|
||||
chrono = "0.4.0"
|
||||
|
||||
@@ -1,9 +1,3 @@
|
||||
use mysql_async::Pool;
|
||||
use async_trait::async_trait;
|
||||
|
||||
use crate::Response;
|
||||
use crate::UBigInt;
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! no_conn {
|
||||
($spec:literal) => {
|
||||
@@ -30,24 +24,3 @@ macro_rules! sql_err_log {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE: pay attention to work on async in traits for rust
|
||||
* Each of one these funcs will implicitly do a single heap allocation which
|
||||
* for our case is fine though ideally we don't
|
||||
*
|
||||
* As soon as we finda way around that we should depecrate `#[async_trait`
|
||||
* for the performance
|
||||
* */
|
||||
|
||||
#[async_trait]
|
||||
pub trait FromDB<T, FilterType> {
|
||||
type Row;
|
||||
|
||||
async fn get(p: &Pool, id: UBigInt) -> Response<T>;
|
||||
|
||||
async fn update(p: &Pool, row: T) -> Response<T>;
|
||||
|
||||
async fn delete(p: &Pool, id: UBigInt) -> Response<T>;
|
||||
|
||||
async fn filter(p: &Pool, filter_val: FilterType) -> Response<T>;
|
||||
}
|
||||
|
||||
@@ -1,132 +1,50 @@
|
||||
use mysql_async::{params, Pool, Conn};
|
||||
use std::time::{SystemTime, Duration, UNIX_EPOCH};
|
||||
|
||||
use mysql_async::{params, Pool};
|
||||
use mysql_async::prelude::Queryable;
|
||||
use mysql_async::error::Error as SqlError;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use crate::{BigInt, Invite, Response};
|
||||
|
||||
use crate::{UBigInt, BigInt};
|
||||
use crate::common::FromDB;
|
||||
use crate::{Response, no_conn};
|
||||
|
||||
#[allow(dead_code)]
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct Invite {
|
||||
pub id: BigInt,
|
||||
pub uses: Option<BigInt>,
|
||||
pub expires: bool
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl FromDB<Invite, bool> for Invite {
|
||||
type Row = Option<(BigInt, Option<BigInt>, bool)>;
|
||||
|
||||
async fn get(p: &Pool, id: UBigInt) -> Response<Self> {
|
||||
impl Invite {
|
||||
pub async fn get(p: &Pool, id: BigInt) -> Result<Response<Self>, SqlError> {
|
||||
// NOTE: cast is required for this as `id` is used as unix timestamp
|
||||
let id: BigInt = id as BigInt;
|
||||
|
||||
if id <= 0 {
|
||||
return Response::Empty;
|
||||
return Ok(Response::RestrictedInput(format!("<{}> not found", id)))
|
||||
}
|
||||
|
||||
if let Ok(conn) = p.get_conn().await {
|
||||
let q = "SELECT id, uses, expires FROM invites WHERE id = :id ";
|
||||
let result: Result<(Conn, Self::Row), SqlError> =
|
||||
conn.first_exec(q, params!{"id" => id}).await;
|
||||
let conn = p.get_conn().await?;
|
||||
let q = "SELECT uses, expires FROM invites WHERE id = :id ";
|
||||
let (_, data_row): (_, Option<(Option<BigInt>, bool)>) =
|
||||
conn.first_exec(q, params!{"id" => id}).await?;
|
||||
|
||||
if let Ok((_, row)) = result {
|
||||
return match row {
|
||||
Some(row) => Response::Row(Self {
|
||||
id: id as BigInt,
|
||||
uses: row.1,
|
||||
expires: row.2
|
||||
}),
|
||||
None => Response::Empty
|
||||
}
|
||||
}
|
||||
return if let Some(row) = data_row {
|
||||
Ok(Response::Row(Invite{
|
||||
id,
|
||||
uses: row.0,
|
||||
expires: row.1,
|
||||
}))
|
||||
} else {
|
||||
Ok(Response::Empty)
|
||||
}
|
||||
return Response::Empty;
|
||||
}
|
||||
|
||||
async fn update(p: &Pool, row: Self) -> Response<Self> {
|
||||
let q = r#"UPDATE invites
|
||||
SET uses = :uses, expires: :exp
|
||||
WHERE id = :id
|
||||
"#;
|
||||
// forcibly udpate even if theres nothing there
|
||||
// this way we avoid doing an extra network hit
|
||||
if row.id <= 0 {
|
||||
return Response::Empty;
|
||||
}
|
||||
|
||||
if let Ok(conn) = p.get_conn().await {
|
||||
let result: Result<Conn, SqlError> =
|
||||
conn.drop_exec(q, params!{
|
||||
"id" => row.id,
|
||||
"uses" => row.uses,
|
||||
"exp" => row.expires
|
||||
}).await;
|
||||
|
||||
return match result {
|
||||
Ok(_) => Response::Success,
|
||||
Err(_) => Response::Other(format!("Could not update entry {}", row.id))
|
||||
}
|
||||
}
|
||||
return Response::Empty;
|
||||
}
|
||||
async fn delete(p: &Pool, id: UBigInt) -> Response<Self> {
|
||||
if id <= 0 { // really lame "assertion" that each method has to use for invites since they all internally use
|
||||
return Response::Empty;
|
||||
}
|
||||
if let Ok(conn) = p.get_conn().await {
|
||||
let q = "DELETE FROM invites WHERE id = :id";
|
||||
let result: Result<Conn, SqlError> =
|
||||
conn.drop_exec(q, params!{"id" => id as BigInt}).await;
|
||||
return match result {
|
||||
Ok(_) => Response::Success,
|
||||
Err(_) => Response::Other(format!("Could not delete {}", id))
|
||||
}
|
||||
}
|
||||
return Response::Success;
|
||||
}
|
||||
async fn filter(p: &Pool, expirey_flag: bool) -> Response<Self> {
|
||||
if let Ok(conn) = p.get_conn().await {
|
||||
let q = "SELECT id, uses, expires FROM invites WHERE expires = :exp";
|
||||
if let Ok(query) = conn.prep_exec(q, params!{"exp" => expirey_flag}).await {
|
||||
let mapping_r = query.map_and_drop(|row| {
|
||||
let (id, uses): (BigInt, Option<BigInt>) = mysql_async::from_row(row);
|
||||
Invite {
|
||||
id,
|
||||
uses,
|
||||
expires: expirey_flag
|
||||
}
|
||||
}).await;
|
||||
return match mapping_r {
|
||||
Ok((_, invites)) => Response::Set(invites),
|
||||
Err(_) => Response::Empty
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Response::Other(no_conn!("db::Invite::filter"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
return Response::Other(no_conn!("db::Invites::filter"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Invite {
|
||||
pub fn new(uses: Option<i64>, expires: bool) -> Invite {
|
||||
use chrono::Utc;
|
||||
|
||||
// now + 30 minutes
|
||||
let later = SystemTime::now() + Duration::from_secs(60 * 30);
|
||||
let id: i64 = later.duration_since(UNIX_EPOCH).expect("honestly idk").as_millis() as i64;
|
||||
|
||||
Invite {
|
||||
id: (Utc::now() + chrono::Duration::minutes(30)).timestamp_millis(),
|
||||
id,
|
||||
uses,
|
||||
expires
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn add(&self, p: &Pool) -> Result<(), SqlError> {
|
||||
let conn = p.get_conn().await?;
|
||||
|
||||
@@ -140,4 +58,5 @@ impl Invite {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -66,13 +66,19 @@ pub struct Channel {
|
||||
pub kind: Integer
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! fetch_row {
|
||||
($table:literal, $col:literal, $key:expr, $rtype:ty,$conn:expr) => {
|
||||
let lib_str = format!("SELECT * FROM {} WHERE {} = :{}", $table, $col, $col);
|
||||
let (_, $rtype) = $conn.first_exec!(lib_str, sql_params{
|
||||
$col => $key,
|
||||
});
|
||||
}
|
||||
#[derive(Serialize, Debug)]
|
||||
pub struct Invite {
|
||||
pub id: BigInt,
|
||||
pub uses: Option<BigInt>,
|
||||
pub expires: bool
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Member {
|
||||
pub id: UBigInt,
|
||||
pub secret: VarChar,
|
||||
pub name: VarChar,
|
||||
pub status: Integer,
|
||||
pub permissions: UBigInt,
|
||||
}
|
||||
|
||||
|
||||
@@ -2,24 +2,12 @@ use mysql_async::{params, Pool, Conn};
|
||||
use mysql_async::prelude::Queryable;
|
||||
use mysql_async::error::Error as SqlError;
|
||||
|
||||
use async_trait::async_trait;
|
||||
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::{Response, no_conn, sql_err};
|
||||
use crate::{UBigInt, BigInt, Integer, VarChar};
|
||||
use crate::{UBigInt, Integer, VarChar};
|
||||
use crate::Member;
|
||||
|
||||
use crate::common::FromDB;
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
pub struct Member {
|
||||
pub id: UBigInt,
|
||||
pub secret: VarChar,
|
||||
pub name: VarChar,
|
||||
pub joindate: BigInt,
|
||||
pub status: Integer,
|
||||
pub permissions: UBigInt,
|
||||
}
|
||||
|
||||
|
||||
pub const STATUS_ONLINE: Integer = 0;
|
||||
@@ -33,16 +21,14 @@ pub const STATUS_DO_NOT_DISTURB: Integer = 3;
|
||||
* return response based on result
|
||||
*
|
||||
*/
|
||||
#[async_trait]
|
||||
impl FromDB<Member, Integer> for Member {
|
||||
type Row = Option<(VarChar, VarChar, BigInt, Integer, UBigInt)>;
|
||||
|
||||
async fn get(p: &Pool, id: UBigInt) -> Response<Self> {
|
||||
impl Member {
|
||||
pub async fn get(p: &Pool, id: UBigInt) -> Response<Self> {
|
||||
//! @returns Row on success
|
||||
//! @returns Other on failure
|
||||
if let Ok(conn) = p.get_conn().await {
|
||||
let q = "SELECT secret, name, joindate, status, permissions FROM members WHERE id = :id";
|
||||
let db_res : Result<(Conn, Self::Row), SqlError>
|
||||
let q = "SELECT secret, name, status, permissions FROM members WHERE id = :id";
|
||||
type Row = Option<(VarChar, VarChar, Integer, UBigInt)>;
|
||||
let db_res : Result<(Conn, Row), SqlError>
|
||||
= conn.first_exec(q, params!{"id" => id}).await;
|
||||
if let Ok((_, row)) = db_res {
|
||||
return match row {
|
||||
@@ -50,9 +36,8 @@ impl FromDB<Member, Integer> for Member {
|
||||
id,
|
||||
secret: row.0,
|
||||
name: row.1,
|
||||
joindate: row.2,
|
||||
status: row.3,
|
||||
permissions: row.4
|
||||
status: row.2,
|
||||
permissions: row.3
|
||||
}),
|
||||
None => Response::Empty
|
||||
}
|
||||
@@ -62,52 +47,8 @@ impl FromDB<Member, Integer> for Member {
|
||||
return Response::Other(no_conn!("Member::FromDB::get"));
|
||||
}
|
||||
|
||||
async fn update(p: &Pool, row: Member) -> Response<Self> {
|
||||
let q = r#"UPDATE members
|
||||
SET status = :status, permissions = :perms, name = :name
|
||||
WHERE id = :id"#;
|
||||
|
||||
if let Ok(conn) = p.get_conn().await {
|
||||
let query = conn.drop_exec(q, params!{
|
||||
"id" => row.id,
|
||||
"status" => row.status,
|
||||
"name" => row.name,
|
||||
"perms" => row.permissions
|
||||
}).await;
|
||||
|
||||
return match query {
|
||||
Ok(_) => Response::Success,
|
||||
Err(err) => Response::Other(sql_err!(err))
|
||||
}
|
||||
}
|
||||
|
||||
return Response::Other(no_conn!("db::Member::update"));
|
||||
}
|
||||
|
||||
async fn delete(p: &Pool, id: UBigInt) -> Response<Self> {
|
||||
if let Ok(conn) = p.get_conn().await {
|
||||
let q = "DELETE from members WHERE id = :id";
|
||||
let db_result: Result<Conn, SqlError>
|
||||
= conn.drop_exec(q, params!{"id" => id}).await;
|
||||
match Member::get(p, id).await {
|
||||
Response::Row(_) => {
|
||||
if let Ok(conn) = db_result {
|
||||
return match conn.prep_exec("", params!{"id" => id}).await {
|
||||
Ok(_) => Response::Success,
|
||||
Err(_) => Response::Other(sql_err!("Member::FromDB::delete"))
|
||||
}
|
||||
}
|
||||
return Response::Success
|
||||
},
|
||||
Response::Empty => return Response::Empty,
|
||||
_ => return Response::Other(sql_err!("Member::FromDB::delete | another stupid get happened delid this"))
|
||||
}
|
||||
}
|
||||
|
||||
return Response::Empty;
|
||||
}
|
||||
|
||||
async fn filter(p: &Pool, status: Integer) -> Response<Self> {
|
||||
pub async fn filter(p: &Pool, status: Integer) -> Response<Self> {
|
||||
//! @params status
|
||||
return match (p.get_conn().await, status) {
|
||||
(Ok(conn), STATUS_ONLINE) | (Ok(conn), STATUS_OFFLINE) |
|
||||
@@ -127,7 +68,6 @@ impl FromDB<Member, Integer> for Member {
|
||||
id,
|
||||
secret: "".into(), // no show for obv reasons
|
||||
name,
|
||||
joindate: 0, // doesn't matter
|
||||
status,
|
||||
permissions
|
||||
}
|
||||
@@ -144,9 +84,6 @@ impl FromDB<Member, Integer> for Member {
|
||||
_ => Response::Other(sql_err!("err"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Member {
|
||||
pub async fn add(p: &Pool, name: &str, secret: &str, perms: u64) -> Result<Response<Self>, SqlError> {
|
||||
//! @param {pool} p
|
||||
//! @param {&str} name of new user
|
||||
@@ -156,23 +93,15 @@ impl Member {
|
||||
//! @returns : on_succes => Ok(Response<Member>)
|
||||
//! @returns : on_partial_succes => Ok(Response<Member>)
|
||||
//! @returns : on_failure => Err(SomeBS)
|
||||
use chrono::Utc;
|
||||
|
||||
let conn = p.get_conn().await?;
|
||||
|
||||
//name
|
||||
//perms
|
||||
//secret
|
||||
let now: BigInt = Utc::now().timestamp();
|
||||
|
||||
|
||||
let conn = conn.drop_exec(
|
||||
"INSERT INTO members(secret, name, joindate, status, permissions)
|
||||
VALUES(:secret, :name, :joindate, :status, :permissions)",
|
||||
"INSERT INTO members(secret, name, status, permissions)
|
||||
VALUES(:secret, :name, :status, :permissions)",
|
||||
mysql_async::params!{
|
||||
"secret" => secret.clone(),
|
||||
"name" => name.clone(),
|
||||
"joindate" => now,
|
||||
"status" => STATUS_ONLINE,
|
||||
"permissions" => perms
|
||||
}).await?;
|
||||
@@ -188,7 +117,6 @@ impl Member {
|
||||
id,
|
||||
secret: secret.into(),
|
||||
name: name.into(),
|
||||
joindate: now,
|
||||
status: STATUS_ONLINE,
|
||||
permissions: perms
|
||||
}))
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
|
||||
use mysql_async::{params, Pool};
|
||||
use mysql_async::prelude::Queryable;
|
||||
use mysql_async::error::Error as SqlError;
|
||||
@@ -5,22 +7,25 @@ use mysql_async::error::Error as SqlError;
|
||||
|
||||
use crate::{Response, sql_err};
|
||||
use crate::{UBigInt, BigInt, VarChar};
|
||||
use crate::UserMessage;
|
||||
use crate::{Message, UserMessage};
|
||||
|
||||
const MAX_MESSAGES: u64 = 1000;
|
||||
|
||||
|
||||
impl crate::Message {
|
||||
impl Message {
|
||||
pub async fn send(p: &Pool, content: &str, content_type: &str, cid: UBigInt, uid: UBigInt) -> Result<Response<Self>, SqlError> {
|
||||
//! @returns on_sucess -> empty
|
||||
//! @returns on_failure Err(SqlErr)
|
||||
|
||||
use chrono::Utc;
|
||||
let conn = p.get_conn().await?;
|
||||
let q = "INSERT INTO messages
|
||||
(time, content, content_type, author_id, channel_id)
|
||||
VALUES (:time, :content, :ctype, :author, :channel)";
|
||||
let now = Utc::now().timestamp();
|
||||
|
||||
let now: i64 = SystemTime::now()
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("System time `NOW` failed")
|
||||
.as_millis() as i64;
|
||||
|
||||
let res = conn.prep_exec(q, params!{
|
||||
"time" => now,
|
||||
|
||||
Reference in New Issue
Block a user