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)] pub struct Invite { pub id: BigInt, pub uses: Option, pub 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; } }