Removal of chrono and async_trait as dependancy in db-lib
Removig chrono from api code as well
This commit is contained in:
parent
cb5975f235
commit
ba14600b34
1576
json-api/db/Cargo.lock
generated
1576
json-api/db/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@ -10,7 +10,5 @@ edition = "2018"
|
||||
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,
|
||||
|
Loading…
Reference in New Issue
Block a user