diff --git a/json-api/client-tests/client.py b/json-api/client-tests/client.py index c06193b..90fd9c2 100644 --- a/json-api/client-tests/client.py +++ b/json-api/client-tests/client.py @@ -84,10 +84,6 @@ class Worker: for key in ids: self.responses[key].log() - # Logg the provided data to ensure that _it_ wasn't the cause for error - resp = self.responses[key] - if resp.code != resp.expected: - self.responses[key].log() # if body is request to be shown then dump it tabbed out by 1 tab if self.body_logs[key] is True: print(f'\tBody: {self.responses[key].body}') diff --git a/json-api/db/src/lib.rs b/json-api/db/src/lib.rs index fb243ad..9180621 100644 --- a/json-api/db/src/lib.rs +++ b/json-api/db/src/lib.rs @@ -1,4 +1,5 @@ -extern crate serde; +use serde::Serialize; + pub mod member; pub mod common; pub mod invites; @@ -33,6 +34,25 @@ pub enum Response { Other(String) } +#[allow(dead_code)] +#[derive(Serialize)] +pub struct Message { + pub id: UBigInt, + pub time: BigInt, + pub content: VarChar, + pub author_id: UBigInt, + pub channel_id: UBigInt +} + +#[derive(Serialize)] +pub struct UserMessage { + pub id: UBigInt, + pub time: BigInt, + pub content: VarChar, + pub author_id: UBigInt, + pub channel_id: UBigInt, + pub name: VarChar +} #[macro_export] macro_rules! fetch_row { diff --git a/json-api/db/src/messages.rs b/json-api/db/src/messages.rs index db72679..0ac4be6 100644 --- a/json-api/db/src/messages.rs +++ b/json-api/db/src/messages.rs @@ -1,123 +1,16 @@ -use mysql_async::{params, Pool, Conn}; +use mysql_async::{params, Pool}; 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::{Response, sql_err}; use crate::{UBigInt, BigInt, VarChar}; - -use crate::common::FromDB; - -#[allow(dead_code)] -#[derive(Serialize)] -pub struct Message { - pub id: UBigInt, - pub time: BigInt, - pub content: VarChar, - pub author_id: UBigInt, - pub channel_id: UBigInt -} +use crate::UserMessage; const MAX_MESSAGES: u64 = 1000; -#[async_trait] -impl FromDB for Message { - type Row = Option<(UBigInt, BigInt, VarChar, UBigInt, UBigInt)>; - async fn get(p: &Pool, id: UBigInt) -> Response { - //! Typically used as the backend to the .update(...) method to - //! pick out a message to later edit - if let Ok(conn) = p.get_conn().await { - let q = "SELECT id, time, content, author_id, channel_id 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, - time: row.1, - content: row.2, - author_id: row.3, - channel_id: row.4 - }), - None => Response::Empty - } - } - return Response::Other(sql_err!("Message::FromDB::get")); - } - return Response::Other(no_conn!("Message")); - } - async fn update(p: &Pool, row: Self) -> Response { - //! Primarily used by users to edit previous comments - // NOTE: we only allow the changing of content in this since - // no other column has good reason to be modified - if let Ok(conn) = p.get_conn().await { - let q = "UPDATE messages - SET content = :content - WHERE id = :id"; - let result: Result = - conn.drop_exec(q, params!{"id" => row.id, "content" => row.content}).await; - return match result { - Ok(_) => Response::Success, - Err(_) => Response::Other(sql_err!("Message::FromDB::update")) - } - } - return Response::Other(no_conn!("Message::FromDB::update")) - } - - async fn delete(p: &Pool, id: UBigInt) -> Response { - //! Deletes a single message - //! Typically used by normal users/bots to remove unwanted comments - if let Ok(conn) = p.get_conn().await { - let q = "DELETE FROM messages WHERE id = :id"; - let result: Result = - conn.drop_exec(q, params!{"id" => id}).await; - return match result { - Ok(_) => Response::Success, - Err(_) => Response::Other(sql_err!("Message::FromDB::delete")) - } - } - return Response::Other(no_conn!("Message::FromDB::update")) - } - - async fn filter(p: &Pool, (time, channel_id): (BigInt, UBigInt)) -> Response { - //! FIlter happens via unix_timestamp and channel_id respectively - if let Ok(conn) = p.get_conn().await { - let q = "SELECT id, time, content, author_id"; - if let Ok(query)= conn.prep_exec(q, params!{"time" => time, "cid" => channel_id}).await { - let mapping_r = query.map_and_drop(|row| { - let (id, time, content, author_id): (UBigInt, BigInt, VarChar, UBigInt) = - mysql_async::from_row(row); - - Message { - id, - time, - content, - author_id, - channel_id - } - }).await; - - match mapping_r { - Ok((_, messages)) => Response::Set(messages), - Err(_) => Response::Other(sql_err!("db::Message::filter")) - } - } - else { - return Response::Empty; - } - - } - else { - return Response::Other(no_conn!("db::Message::filter")); - } - } -} - -impl Message { +impl crate::Message { pub async fn send(p: &Pool, content: &str, cid: UBigInt, uid: UBigInt) -> Result, SqlError> { //! @returns on_sucess -> empty //! @returns on_failure Err(SqlErr) @@ -156,7 +49,7 @@ impl Message { } - pub async fn get_time_range(p: &Pool, channel_id: UBigInt, start: BigInt, end: BigInt, limit: Option) -> Result, SqlError> { + pub async fn get_time_range(p: &Pool, channel_id: UBigInt, start: BigInt, end: BigInt, limit: Option) -> Result, SqlError> { //! @returns on success : Set(Vec) //! @returns on userfail: RestrictedInput(message) //! @returns on error : Err(SqlError) @@ -175,7 +68,8 @@ impl Message { MAX_MESSAGES }; - let q = "SELECT id, time, content, author_id FROM messages + let q = "SELECT mem.name, msg.id, msg.time, msg.content, msg.author_id FROM messages as msg + JOIN members as mem ON mem.id = msg.author_id WHERE channel_id = :channel AND time >= :start AND time < :end LIMIT :limit"; @@ -188,13 +82,14 @@ impl Message { }).await?; let(_conn, messages) = select_result.map_and_drop(|row| { - type Tuple = (UBigInt, BigInt, String, UBigInt); - let (id, time, content, author_id): Tuple = mysql_async::from_row(row); - Self { + type Tuple = (VarChar, UBigInt, BigInt, String, UBigInt); + let (name, id, time, content, author_id): Tuple = mysql_async::from_row(row); + UserMessage { id, time, content, author_id, + name, channel_id } }).await?; diff --git a/json-api/src/messages.rs b/json-api/src/messages.rs index e084723..c28d4fc 100644 --- a/json-api/src/messages.rs +++ b/json-api/src/messages.rs @@ -8,7 +8,7 @@ use std::collections::HashMap; use crate::http::set_json_body; use crate::perms; use crate::qs_param; -use db::messages::Message; +use db::Message; pub async fn get_by_time(pool: &Pool, response: &mut Response, params: HashMap) { /* @@ -87,7 +87,7 @@ pub async fn send_message(pool: &Pool, response: &mut Response, body: Body if content.len() == 0 || channel_id.is_none() { *response.status_mut() = StatusCode::BAD_REQUEST; } else { - match db::messages::Message::send(pool, &content, channel_id.unwrap(), uid).await { + match db::Message::send(pool, &content, channel_id.unwrap(), uid).await { Ok(Empty) => {}, // nothing to do hyper defaults to 200 Ok(RestrictedInput(_msg)) => *response.status_mut() = StatusCode::BAD_REQUEST, Ok(Other(msg)) => {