diff --git a/server-api/db/src/messages.rs b/server-api/db/src/messages.rs index 068bb60..8790ed8 100644 --- a/server-api/db/src/messages.rs +++ b/server-api/db/src/messages.rs @@ -190,5 +190,44 @@ impl Message { } } + pub async fn get_from_id(p: &Pool, channel_id: UBigInt, start: UBigInt, limit: Option) -> Result, SqlError> { + //! @returns on success : Set(Vec) + //! @returns on failure : Err(SqlError) + let conn = p.get_conn().await?; + const MAX: u64 = 1000; + let limit = if let Some(limit) = limit{ + match limit { + 1 ..= MAX => limit, + _ => MAX + } + } else { + MAX // messages at a time + }; + + let q = "SELECT id, time, content, author_id FROM messages WHERE + channel_id = :channel AND id >= :start LIMIT :limit"; + + let params = params!{ + "channel" => channel_id, + "start" => start, + "limit" => limit + }; + + let select_result = conn.prep_exec(q, params).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 { + id, + time, + content, + author_id, + channel_id + } + }).await?; + + Ok(Response::Set(messages)) + } } diff --git a/server-api/src/messages.rs b/server-api/src/messages.rs index c2d4008..8f9948a 100644 --- a/server-api/src/messages.rs +++ b/server-api/src/messages.rs @@ -4,6 +4,7 @@ use serde_json::Value; use hyper::header::HeaderValue; use serde_json::json; +use db::messages::Message; pub async fn get_by_time(pool: &Pool, response: &mut Response, params: Value) { /* @@ -30,7 +31,7 @@ pub async fn get_by_time(pool: &Pool, response: &mut Response, params: Val Some(val) => val.as_i64(), None => None }; - use db::messages::Message; + // TODO: flatten me mommy match (channel, start_time, end_time) { (Some(channel), Some(start), Some(end)) => { match Message::get_time_range(pool, channel, start, end).await { @@ -108,6 +109,57 @@ pub async fn send_message(pool: &Pool, response: &mut Response, params: Va } } +pub async fn from_id(pool: &Pool, response: &mut Response, params: Value) { + /* + * @start-id: u64 + * @limit: optional + * @channel: u64 + * { + * "channel": 1, + * "start": 123, + * "limit": 100 + * } + */ + let channel = match params.get("channel") { + Some(chan_v) => chan_v.as_u64(), + None => None + }; + let start_id = match params.get("start-id") { + Some(val) => val.as_u64(), + None => None + }; + let limit = match params.get("limit") { + Some(val) => val.as_u64(), + None => None + }; + + // TODO: untested lmao + if let (Some(channel), Some(start_id)) = (channel, start_id) { + match Message::get_from_id(pool, channel, start_id, limit).await { + Ok(db_response) => { + match db_response { + db::Response::Set(messages) => { + response.headers_mut().insert( + "Content-Type", + HeaderValue::from_static("application/json")); + + let payload = json!({"messages": messages}); + *response.body_mut() = Body::from(payload.to_string()); + }, + _ => *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR + }; + }, + Err(err) => { + *response.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; + eprintln!("{}", err); + } + }; + } + else { + *response.status_mut() = StatusCode::BAD_REQUEST; + } +} + #[cfg(test)] mod messaging_tests { use crate::testing::{get_pool, hyper_resp};