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"
|
mysql_async = "0.23.1"
|
||||||
async-trait = "0.1.40"
|
async-trait = "0.1.40"
|
||||||
|
|
||||||
serde_json = "1.0"
|
|
||||||
serde = { version = "1.0.117", features = [ "derive" ] }
|
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_export]
|
||||||
macro_rules! no_conn {
|
macro_rules! no_conn {
|
||||||
($spec:literal) => {
|
($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::prelude::Queryable;
|
||||||
use mysql_async::error::Error as SqlError;
|
use mysql_async::error::Error as SqlError;
|
||||||
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use crate::{BigInt, Invite, Response};
|
||||||
|
|
||||||
use crate::{UBigInt, BigInt};
|
impl Invite {
|
||||||
use crate::common::FromDB;
|
pub async fn get(p: &Pool, id: BigInt) -> Result<Response<Self>, SqlError> {
|
||||||
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> {
|
|
||||||
// NOTE: cast is required for this as `id` is used as unix timestamp
|
// NOTE: cast is required for this as `id` is used as unix timestamp
|
||||||
let id: BigInt = id as BigInt;
|
let id: BigInt = id as BigInt;
|
||||||
|
|
||||||
if id <= 0 {
|
if id <= 0 {
|
||||||
return Response::Empty;
|
return Ok(Response::RestrictedInput(format!("<{}> not found", id)))
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(conn) = p.get_conn().await {
|
let conn = p.get_conn().await?;
|
||||||
let q = "SELECT id, uses, expires FROM invites WHERE id = :id ";
|
let q = "SELECT uses, expires FROM invites WHERE id = :id ";
|
||||||
let result: Result<(Conn, Self::Row), SqlError> =
|
let (_, data_row): (_, Option<(Option<BigInt>, bool)>) =
|
||||||
conn.first_exec(q, params!{"id" => id}).await;
|
conn.first_exec(q, params!{"id" => id}).await?;
|
||||||
|
|
||||||
if let Ok((_, row)) = result {
|
return if let Some(row) = data_row {
|
||||||
return match row {
|
Ok(Response::Row(Invite{
|
||||||
Some(row) => Response::Row(Self {
|
id,
|
||||||
id: id as BigInt,
|
uses: row.0,
|
||||||
uses: row.1,
|
expires: row.1,
|
||||||
expires: row.2
|
}))
|
||||||
}),
|
} else {
|
||||||
None => Response::Empty
|
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 {
|
pub fn new(uses: Option<i64>, expires: bool) -> Invite {
|
||||||
let result: Result<Conn, SqlError> =
|
// now + 30 minutes
|
||||||
conn.drop_exec(q, params!{
|
let later = SystemTime::now() + Duration::from_secs(60 * 30);
|
||||||
"id" => row.id,
|
let id: i64 = later.duration_since(UNIX_EPOCH).expect("honestly idk").as_millis() as i64;
|
||||||
"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 {
|
Invite {
|
||||||
id,
|
id,
|
||||||
uses,
|
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;
|
|
||||||
|
|
||||||
Invite {
|
|
||||||
id: (Utc::now() + chrono::Duration::minutes(30)).timestamp_millis(),
|
|
||||||
uses,
|
|
||||||
expires
|
expires
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add(&self, p: &Pool) -> Result<(), SqlError> {
|
pub async fn add(&self, p: &Pool) -> Result<(), SqlError> {
|
||||||
let conn = p.get_conn().await?;
|
let conn = p.get_conn().await?;
|
||||||
|
|
||||||
@ -140,4 +58,5 @@ impl Invite {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -66,13 +66,19 @@ pub struct Channel {
|
|||||||
pub kind: Integer
|
pub kind: Integer
|
||||||
}
|
}
|
||||||
|
|
||||||
#[macro_export]
|
#[derive(Serialize, Debug)]
|
||||||
macro_rules! fetch_row {
|
pub struct Invite {
|
||||||
($table:literal, $col:literal, $key:expr, $rtype:ty,$conn:expr) => {
|
pub id: BigInt,
|
||||||
let lib_str = format!("SELECT * FROM {} WHERE {} = :{}", $table, $col, $col);
|
pub uses: Option<BigInt>,
|
||||||
let (_, $rtype) = $conn.first_exec!(lib_str, sql_params{
|
pub expires: bool
|
||||||
$col => $key,
|
}
|
||||||
});
|
|
||||||
}
|
#[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::prelude::Queryable;
|
||||||
use mysql_async::error::Error as SqlError;
|
use mysql_async::error::Error as SqlError;
|
||||||
|
|
||||||
use async_trait::async_trait;
|
|
||||||
|
|
||||||
use serde::Serialize;
|
|
||||||
|
|
||||||
use crate::{Response, no_conn, sql_err};
|
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;
|
pub const STATUS_ONLINE: Integer = 0;
|
||||||
@ -33,16 +21,14 @@ pub const STATUS_DO_NOT_DISTURB: Integer = 3;
|
|||||||
* return response based on result
|
* return response based on result
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#[async_trait]
|
impl Member {
|
||||||
impl FromDB<Member, Integer> for Member {
|
pub async fn get(p: &Pool, id: UBigInt) -> Response<Self> {
|
||||||
type Row = Option<(VarChar, VarChar, BigInt, Integer, UBigInt)>;
|
|
||||||
|
|
||||||
async fn get(p: &Pool, id: UBigInt) -> Response<Self> {
|
|
||||||
//! @returns Row on success
|
//! @returns Row on success
|
||||||
//! @returns Other on failure
|
//! @returns Other on failure
|
||||||
if let Ok(conn) = p.get_conn().await {
|
if let Ok(conn) = p.get_conn().await {
|
||||||
let q = "SELECT secret, name, joindate, status, permissions FROM members WHERE id = :id";
|
let q = "SELECT secret, name, status, permissions FROM members WHERE id = :id";
|
||||||
let db_res : Result<(Conn, Self::Row), SqlError>
|
type Row = Option<(VarChar, VarChar, Integer, UBigInt)>;
|
||||||
|
let db_res : Result<(Conn, Row), SqlError>
|
||||||
= conn.first_exec(q, params!{"id" => id}).await;
|
= conn.first_exec(q, params!{"id" => id}).await;
|
||||||
if let Ok((_, row)) = db_res {
|
if let Ok((_, row)) = db_res {
|
||||||
return match row {
|
return match row {
|
||||||
@ -50,9 +36,8 @@ impl FromDB<Member, Integer> for Member {
|
|||||||
id,
|
id,
|
||||||
secret: row.0,
|
secret: row.0,
|
||||||
name: row.1,
|
name: row.1,
|
||||||
joindate: row.2,
|
status: row.2,
|
||||||
status: row.3,
|
permissions: row.3
|
||||||
permissions: row.4
|
|
||||||
}),
|
}),
|
||||||
None => Response::Empty
|
None => Response::Empty
|
||||||
}
|
}
|
||||||
@ -62,52 +47,8 @@ impl FromDB<Member, Integer> for Member {
|
|||||||
return Response::Other(no_conn!("Member::FromDB::get"));
|
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 {
|
pub async fn filter(p: &Pool, status: Integer) -> Response<Self> {
|
||||||
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> {
|
|
||||||
//! @params status
|
//! @params status
|
||||||
return match (p.get_conn().await, status) {
|
return match (p.get_conn().await, status) {
|
||||||
(Ok(conn), STATUS_ONLINE) | (Ok(conn), STATUS_OFFLINE) |
|
(Ok(conn), STATUS_ONLINE) | (Ok(conn), STATUS_OFFLINE) |
|
||||||
@ -127,7 +68,6 @@ impl FromDB<Member, Integer> for Member {
|
|||||||
id,
|
id,
|
||||||
secret: "".into(), // no show for obv reasons
|
secret: "".into(), // no show for obv reasons
|
||||||
name,
|
name,
|
||||||
joindate: 0, // doesn't matter
|
|
||||||
status,
|
status,
|
||||||
permissions
|
permissions
|
||||||
}
|
}
|
||||||
@ -144,9 +84,6 @@ impl FromDB<Member, Integer> for Member {
|
|||||||
_ => Response::Other(sql_err!("err"))
|
_ => Response::Other(sql_err!("err"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl Member {
|
|
||||||
pub async fn add(p: &Pool, name: &str, secret: &str, perms: u64) -> Result<Response<Self>, SqlError> {
|
pub async fn add(p: &Pool, name: &str, secret: &str, perms: u64) -> Result<Response<Self>, SqlError> {
|
||||||
//! @param {pool} p
|
//! @param {pool} p
|
||||||
//! @param {&str} name of new user
|
//! @param {&str} name of new user
|
||||||
@ -156,23 +93,15 @@ impl Member {
|
|||||||
//! @returns : on_succes => Ok(Response<Member>)
|
//! @returns : on_succes => Ok(Response<Member>)
|
||||||
//! @returns : on_partial_succes => Ok(Response<Member>)
|
//! @returns : on_partial_succes => Ok(Response<Member>)
|
||||||
//! @returns : on_failure => Err(SomeBS)
|
//! @returns : on_failure => Err(SomeBS)
|
||||||
use chrono::Utc;
|
|
||||||
|
|
||||||
let conn = p.get_conn().await?;
|
let conn = p.get_conn().await?;
|
||||||
|
|
||||||
//name
|
|
||||||
//perms
|
|
||||||
//secret
|
|
||||||
let now: BigInt = Utc::now().timestamp();
|
|
||||||
|
|
||||||
|
|
||||||
let conn = conn.drop_exec(
|
let conn = conn.drop_exec(
|
||||||
"INSERT INTO members(secret, name, joindate, status, permissions)
|
"INSERT INTO members(secret, name, status, permissions)
|
||||||
VALUES(:secret, :name, :joindate, :status, :permissions)",
|
VALUES(:secret, :name, :status, :permissions)",
|
||||||
mysql_async::params!{
|
mysql_async::params!{
|
||||||
"secret" => secret.clone(),
|
"secret" => secret.clone(),
|
||||||
"name" => name.clone(),
|
"name" => name.clone(),
|
||||||
"joindate" => now,
|
|
||||||
"status" => STATUS_ONLINE,
|
"status" => STATUS_ONLINE,
|
||||||
"permissions" => perms
|
"permissions" => perms
|
||||||
}).await?;
|
}).await?;
|
||||||
@ -188,7 +117,6 @@ impl Member {
|
|||||||
id,
|
id,
|
||||||
secret: secret.into(),
|
secret: secret.into(),
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
joindate: now,
|
|
||||||
status: STATUS_ONLINE,
|
status: STATUS_ONLINE,
|
||||||
permissions: perms
|
permissions: perms
|
||||||
}))
|
}))
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
use std::time::{SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
use mysql_async::{params, Pool};
|
use mysql_async::{params, Pool};
|
||||||
use mysql_async::prelude::Queryable;
|
use mysql_async::prelude::Queryable;
|
||||||
use mysql_async::error::Error as SqlError;
|
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::{Response, sql_err};
|
||||||
use crate::{UBigInt, BigInt, VarChar};
|
use crate::{UBigInt, BigInt, VarChar};
|
||||||
use crate::UserMessage;
|
use crate::{Message, UserMessage};
|
||||||
|
|
||||||
const MAX_MESSAGES: u64 = 1000;
|
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> {
|
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_sucess -> empty
|
||||||
//! @returns on_failure Err(SqlErr)
|
//! @returns on_failure Err(SqlErr)
|
||||||
|
|
||||||
use chrono::Utc;
|
|
||||||
let conn = p.get_conn().await?;
|
let conn = p.get_conn().await?;
|
||||||
let q = "INSERT INTO messages
|
let q = "INSERT INTO messages
|
||||||
(time, content, content_type, author_id, channel_id)
|
(time, content, content_type, author_id, channel_id)
|
||||||
VALUES (:time, :content, :ctype, :author, :channel)";
|
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!{
|
let res = conn.prep_exec(q, params!{
|
||||||
"time" => now,
|
"time" => now,
|
||||||
|
Loading…
Reference in New Issue
Block a user