From 0b42675739365dbbd4b79bd1851a5135ea01c41a Mon Sep 17 00:00:00 2001 From: shockrah Date: Wed, 16 Sep 2020 23:14:07 -0700 Subject: [PATCH] general code for invites db wrapper --- server-api/db/src/invites.rs | 86 ++++++++++++++++++++++++++++++++++++ server-api/db/src/lib.rs | 1 + 2 files changed, 87 insertions(+) create mode 100644 server-api/db/src/invites.rs diff --git a/server-api/db/src/invites.rs b/server-api/db/src/invites.rs new file mode 100644 index 0000000..92f7558 --- /dev/null +++ b/server-api/db/src/invites.rs @@ -0,0 +1,86 @@ +use mysql_async::{params, Pool, Conn}; +use mysql_async::prelude::Queryable; +use mysql_async::error::Error as SqlError; + +use async_trait::async_trait; + +use crate::{UBigInt, BigInt}; +use crate::common::FromDB; +use crate::Response; + +#[allow(dead_code)] +struct Invite { + id: BigInt, + uses: Option, + expires: bool +} + +#[async_trait] +impl FromDB for Invite { + type Row = Option<(BigInt, Option, bool)>; + + async fn get(p: &Pool, id: UBigInt) -> Response { + if id <= 0 { + return Response::Empty; + } + + 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; + + 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 Response::Empty; + } + + async fn update(p: &Pool, row: Self) -> Response { + let q = r#"UPDATE invites + SET id = :id, uses = :uses, expires: :exp + "#; + // 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.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 { + 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.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; + } +} diff --git a/server-api/db/src/lib.rs b/server-api/db/src/lib.rs index bbb2255..a67becb 100644 --- a/server-api/db/src/lib.rs +++ b/server-api/db/src/lib.rs @@ -1,5 +1,6 @@ mod member; mod common; +mod invites; use std::vec::Vec;