
Removig chrono from api code as well Removing chrono as dep in api code + Using Content-Type for /message/send content type Updating cargo lists for removal of fluff deps Removal of more fluff Addking makefile to avoid compiling debug builds by accident while developing
151 lines
5.0 KiB
Rust
151 lines
5.0 KiB
Rust
use std::time::{SystemTime, UNIX_EPOCH};
|
|
|
|
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::{Message, UserMessage};
|
|
|
|
const MAX_MESSAGES: u64 = 1000;
|
|
|
|
|
|
impl Message {
|
|
pub async fn send(p: &Pool, content: &str, content_type: &str, cid: UBigInt, uid: UBigInt) -> Result<Response<Self>, SqlError> {
|
|
//! @returns on_sucess -> empty
|
|
//! @returns on_failure Err(SqlErr)
|
|
|
|
let conn = p.get_conn().await?;
|
|
let q = "INSERT INTO messages
|
|
(time, content, content_type, author_id, channel_id)
|
|
VALUES (:time, :content, :ctype, :author, :channel)";
|
|
|
|
let now: i64 = SystemTime::now()
|
|
.duration_since(UNIX_EPOCH)
|
|
.expect("System time `NOW` failed")
|
|
.as_millis() as i64;
|
|
|
|
let res = conn.prep_exec(q, params!{
|
|
"time" => now,
|
|
"content" => content,
|
|
"ctype" => content_type,
|
|
"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.content_type, 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, String, UBigInt);
|
|
let (name, id, time, content, content_type, author_id): Tuple = mysql_async::from_row(row);
|
|
UserMessage {
|
|
id,
|
|
time,
|
|
content,
|
|
content_type,
|
|
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 user failure : RestrictedInput(String)
|
|
//! @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, content_type, 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, VarChar, VarChar, UBigInt);
|
|
let (id, time, content, content_type, author_id): Tuple = mysql_async::from_row(row);
|
|
Self {
|
|
id,
|
|
time,
|
|
content,
|
|
content_type,
|
|
author_id,
|
|
channel_id
|
|
}
|
|
}).await?;
|
|
|
|
Ok(Response::Set(messages))
|
|
}
|
|
}
|
|
|