
➕ Moving Messages struct in db-lib to root for less namespacing uglyness ➖ Removing an whole unused trait ✨ Message::get_time_range now returns a special 'UserMessage' struct that includes the name of the author ❗ More code must be removed from db-lib since a ton of the trait methods aren't used anymore
141 lines
4.5 KiB
Rust
141 lines
4.5 KiB
Rust
use mysql_async::{params, Pool};
|
|
use mysql_async::prelude::Queryable;
|
|
use mysql_async::error::Error as SqlError;
|
|
|
|
|
|
use crate::{Response, sql_err};
|
|
use crate::{UBigInt, BigInt, VarChar};
|
|
use crate::UserMessage;
|
|
|
|
const MAX_MESSAGES: u64 = 1000;
|
|
|
|
|
|
impl crate::Message {
|
|
pub async fn send(p: &Pool, content: &str, cid: UBigInt, uid: UBigInt) -> Result<Response<Self>, SqlError> {
|
|
//! @returns on_sucess -> empty
|
|
//! @returns on_failure Err(SqlErr)
|
|
|
|
use chrono::Utc;
|
|
let conn = p.get_conn().await?;
|
|
let q = "INSERT INTO messages
|
|
(time, content, author_id, channel_id)
|
|
VALUES (:time, :content, :author, :channel)";
|
|
let now = Utc::now().timestamp();
|
|
|
|
let res = conn.prep_exec(q, params!{
|
|
"time" => now,
|
|
"content" => content,
|
|
"author" => uid,
|
|
"channel" => cid
|
|
}).await;
|
|
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::Empty);
|
|
}
|
|
|
|
}
|
|
|
|
pub async fn get_time_range(p: &Pool, channel_id: UBigInt, start: BigInt, end: BigInt, limit: Option<u64>) -> Result<Response<UserMessage>, SqlError> {
|
|
//! @returns on success : Set(Vec<Messages>)
|
|
//! @returns on userfail: RestrictedInput(message)
|
|
//! @returns on error : Err(SqlError)
|
|
|
|
if start >= end {
|
|
Ok(Response::RestrictedInput("Invalid start/end parameters".into()))
|
|
}
|
|
else {
|
|
let conn = p.get_conn().await?;
|
|
let limit = if let Some(limit) = limit {
|
|
match limit {
|
|
1 ..= MAX_MESSAGES => limit,
|
|
_ => MAX_MESSAGES
|
|
}
|
|
} else {
|
|
MAX_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";
|
|
|
|
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, UBigInt);
|
|
let (name, id, time, content, author_id): Tuple = mysql_async::from_row(row);
|
|
UserMessage {
|
|
id,
|
|
time,
|
|
content,
|
|
author_id,
|
|
name,
|
|
channel_id
|
|
}
|
|
}).await?;
|
|
|
|
Ok(Response::Set(messages))
|
|
}
|
|
}
|
|
|
|
pub async fn get_from_id(p: &Pool, channel_id: UBigInt, start: UBigInt, limit: Option<UBigInt>) -> Result<Response<Self>, SqlError> {
|
|
//! @returns on success : Set(Vec<Messages>)
|
|
//! @returns on failure : Err(SqlError)
|
|
let conn = p.get_conn().await?;
|
|
let limit = if let Some(limit) = limit{
|
|
match limit {
|
|
1 ..= MAX_MESSAGES => limit,
|
|
_ => MAX_MESSAGES
|
|
}
|
|
} else {
|
|
MAX_MESSAGES // 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))
|
|
}
|
|
}
|
|
|