139 lines
4.9 KiB
Rust
139 lines
4.9 KiB
Rust
use mysql_async::{params, Pool, Conn};
|
|
use mysql_async::prelude::Queryable;
|
|
use mysql_async::error::Error as SqlError;
|
|
|
|
use async_trait::async_trait;
|
|
|
|
use crate::{Response, no_conn, sql_err};
|
|
use crate::{UBigInt, BigInt, VarChar};
|
|
|
|
use crate::common::{FromDB};
|
|
|
|
#[allow(dead_code)]
|
|
pub struct Message {
|
|
pub id: UBigInt,
|
|
pub time: BigInt,
|
|
pub content: VarChar,
|
|
pub author_id: UBigInt,
|
|
pub channel_name: VarChar
|
|
}
|
|
|
|
#[async_trait]
|
|
impl FromDB<Message, (BigInt, UBigInt)> for Message {
|
|
type Row = Option<(UBigInt, BigInt, VarChar, UBigInt, VarChar)>;
|
|
|
|
async fn get(p: &Pool, id: UBigInt) -> Response<Self> {
|
|
//! 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_name 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: id,
|
|
time: row.1,
|
|
content: row.2,
|
|
author_id: row.3,
|
|
channel_name: 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<Self> {
|
|
//! 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, SqlError> =
|
|
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<Self> {
|
|
//! 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, SqlError> =
|
|
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<Self> {
|
|
//! 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, uid): (UBigInt, BigInt, VarChar, UBigInt) =
|
|
mysql_async::from_row(row);
|
|
|
|
Message {
|
|
id: id,
|
|
time: time,
|
|
content: content,
|
|
author_id: uid,
|
|
channel_name: "".into() // no point at this point tbh
|
|
}
|
|
}).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 {
|
|
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();
|
|
|
|
conn.prep_exec(q, params!{
|
|
"time" => now,
|
|
"content" => content,
|
|
"author" => uid,
|
|
"channel" => cid
|
|
}).await?;
|
|
|
|
return Ok(Response::Empty);
|
|
}
|
|
}
|
|
|