From 15b56353b87bce7ca82f18cd3e82a74cc82abc31 Mon Sep 17 00:00:00 2001 From: shockrah Date: Tue, 30 Mar 2021 21:39:44 -0700 Subject: [PATCH] Removing passthrough for message send handler This means we get more opaque errors for the clients but it also results in way less code to maintain --- json-api/db/src/messages.rs | 91 ++++++++++++------------------------- 1 file changed, 28 insertions(+), 63 deletions(-) diff --git a/json-api/db/src/messages.rs b/json-api/db/src/messages.rs index 4b1bc01..1b4effa 100644 --- a/json-api/db/src/messages.rs +++ b/json-api/db/src/messages.rs @@ -4,15 +4,12 @@ use tokio::fs; use tokio::io::AsyncWriteExt; use mysql_async::params; -use mysql_async::{Pool, Conn}; +use mysql_async::Pool; use mysql_async::prelude::Queryable; -use mysql_async::error::Error as SqlError; -use mysql_async::QueryResult; -use mysql_async::BinaryProtocol; +use mysql_async::Error as SqlError; - -use crate::{Response, sql_err}; -use crate::{UBigInt, BigInt, VarChar}; +use crate::Response; +use crate::{UBigInt, BigInt}; use crate::{Message, UserMessage}; use rand::RngCore; @@ -33,42 +30,12 @@ impl Message { } } - fn message_passthrough_no_err(res: Result, SqlError>, passthrough: Self) - -> Result, SqlError> { - /* You shouldn't have cum here.webm - * Basically sending messages with mysql is kinda painful so we - * do some special error checking by hand to see if - * a message was sent to an existing channel. - * The whole point of this is to avoid sending back a 500 to user clients - * which may cause confusing error handling in userland. This means we have - * confusing error handling on the server side but one of the parties has to - * do this stupid check so fuck it at least its mostly pointers anyway - */ - if let Err(e) = res { - return match e { - SqlError::Server(err) => { - if err.code == 1452 { - return Ok(Response::RestrictedInput("Channel not found".into())) - } - else { - Ok(Response::Other(sql_err!("db::messages::send"))) - } - }, - _ => Ok(Response::Other(sql_err!("db::messages::send"))) - } - - } - // all good response - else { - return Ok(Response::Row(passthrough)); - } - } pub async fn send(p: &Pool, content: &str, content_type: &str, cid: UBigInt, uid: UBigInt) -> Result, SqlError> { //! @returns on_sucess -> empty //! @returns on_failure Err(SqlErr) - let conn = p.get_conn().await?; + let mut conn = p.get_conn().await?; let q = "INSERT INTO messages (id, time, content, content_type, author_id, channel_id) VALUES (id, :time, :content, :ctype, :author, :channel)"; @@ -84,7 +51,7 @@ impl Message { if content.len() > 4_000 { Ok(Response::RestrictedInput("Large text not allowed".into())) } else { - let res = conn.prep_exec(q, params!{ + let res = conn.exec_drop(q, params!{ "id" => id, "time" => now, "content" => content, @@ -92,8 +59,13 @@ impl Message { "author" => uid, "channel" => cid }).await; - let msg = Message::new(id, now, content, content_type, uid, cid); - Self::message_passthrough_no_err(res, msg) + match Ok(res) { + Ok(_) => { + let msg = Message::new(id, now, content, content_type, uid, cid); + Ok(Response::Row(msg)) + }, + Err(e) => Err(e) + } } }, _ => { @@ -117,7 +89,7 @@ impl Message { }; let content_ref = format!("{cid}-{time}.{ext}", cid=cid, time=now, ext=extension); - let res = conn.prep_exec(q, params!{ + let res = conn.exec_drop(q, params!{ "id" => id, "time" => now, "content" => &content_ref, // store a ref to a file instead of the actual payload @@ -125,13 +97,13 @@ impl Message { "author" => uid, "channel" => cid }).await; - let msg = Message::new(id, now, content, content_type, uid, cid); - if let Ok(ret) = Self::message_passthrough_no_err(res, msg) { + if let Ok(ret) = res { // now save the data to disk match fs::File::create(content_ref).await { Ok(mut file) => { file.write_all(content.as_bytes()).await.expect("Failed to write, but the ref is saved"); - Ok(ret) + let msg = Message::new(id, now, content, content_type, uid, cid); + Ok(Response::Row(msg)) }, Err(_) => { Ok(Response::Other("Saved ref but couldn't save file data".into())) @@ -156,7 +128,7 @@ impl Message { Ok(Response::RestrictedInput("Invalid start/end parameters".into())) } else { - let conn = p.get_conn().await?; + let mut conn = p.get_conn().await?; let limit = if let Some(limit) = limit { match limit { 1 ..= MAX_MESSAGES => limit, @@ -172,17 +144,13 @@ impl Message { WHERE channel_id = :channel AND time >= :start AND time < :end LIMIT :limit"; - let select_result = conn.prep_exec( - q, params!{ - "start" => start, - "end" => end, - "channel" => channel_id, - "limit" => limit - }).await?; - - let(_conn, messages) = select_result.map_and_drop(|row| { - type Tuple = (VarChar, UBigInt, BigInt, String, String, UBigInt); - let (name, id, time, content, content_type, author_id): Tuple = mysql_async::from_row(row); + let params = params!{ + "start" => start, + "end" => end, + "channel" => channel_id, + "limit" => limit + }; + let messages = conn.exec_map(q, params, |(name, id, time, content, content_type, author_id)| { UserMessage { id, time, @@ -202,7 +170,7 @@ impl Message { //! @returns on success : Set(Vec) //! @returns on user failure : RestrictedInput(String) //! @returns on failure : Err(SqlError) - let conn = p.get_conn().await?; + let mut conn = p.get_conn().await?; let limit = if let Some(limit) = limit{ match limit { 1 ..= MAX_MESSAGES => limit, @@ -221,11 +189,8 @@ impl Message { "limit" => limit }; - let select_result = conn.prep_exec(q, params).await?; - - let (_conn, messages) = select_result.map_and_drop(|row| { - type Tuple = (UBigInt, BigInt, VarChar, VarChar, UBigInt); - let (id, time, content, content_type, author_id): Tuple = mysql_async::from_row(row); + let messages = conn.exec_map(q, params, + |(id, time, content, content_type, author_id)| { Self { id, time,