
The badges_id field has proved to bubble up some issues with updating deep structures Basically this just means that feature branches for deep features like this are a good idea ! Issue: RTC feature flag was working fine but without the feature flag `Row`'s had no pickup This meant correct responses were slipping into previously unreachable sections of code
110 lines
3.8 KiB
Rust
110 lines
3.8 KiB
Rust
use mysql_async::{params, Pool};
|
|
use mysql_async::prelude::Queryable;
|
|
use mysql_async::Error as SqlError;
|
|
|
|
use crate::{Channel, UBigInt, Integer};
|
|
use crate::Response;
|
|
|
|
use rand::RngCore;
|
|
|
|
pub const VOICE_CHANNEL: Integer = 1;
|
|
pub const TEXT_CHANNEL: Integer = 2;
|
|
|
|
pub const MAX_NAME_LEN: usize = 256;
|
|
pub const MAX_DESCRIPTION_LEN: usize = 2048;
|
|
|
|
impl Channel {
|
|
pub async fn get(p: &Pool, id: u64) -> Result<Option<Channel>, SqlError> {
|
|
let mut conn = p.get_conn().await?;
|
|
let q = "SELECT name, description, kind, badge_ids FROM channels WHERE id = :id";
|
|
let params = params!{"id" => id};
|
|
let row: Option<(String, Option<String>, i32, String)> =
|
|
conn.exec_first(q, params).await?;
|
|
|
|
if let Some(row) = row {
|
|
let badge_ids: Vec<u32> = serde_json::from_str(&row.3).unwrap_or(Vec::new());
|
|
let chan = Channel {
|
|
id,
|
|
name: row.0,
|
|
description: row.1,
|
|
kind: row.2,
|
|
badge_ids
|
|
};
|
|
Ok(Some(chan))
|
|
} else {
|
|
Ok(None)
|
|
}
|
|
}
|
|
|
|
pub async fn filter(p: &Pool, kind: Integer) -> Result<Response<Self>, SqlError> {
|
|
//! @returns -> on success : Ok(Response::Set(Vec<Channel>))
|
|
//! @throw -> on sql fail : Err(SqlError)
|
|
|
|
if kind == VOICE_CHANNEL || kind ==TEXT_CHANNEL {
|
|
let mut conn = p.get_conn().await?;
|
|
|
|
let q = "SELECT id, name, description, kind, badge_ids FROM channels WHERE kind = :kind";
|
|
let params = params!{"kind" => kind};
|
|
type Row = (u64, String, Option<String>, i32, String);
|
|
let channels = conn.exec_map(q, params, |(id, name, description, kind, badge_ids): Row| {
|
|
let badge_ids: Vec<u32> = serde_json::from_str(&badge_ids).unwrap_or(Vec::new());
|
|
Channel {
|
|
id, name, description, kind, badge_ids
|
|
}
|
|
}).await?;
|
|
Ok(Response::Set(channels))
|
|
} else {
|
|
return Ok(Response::RestrictedInput("Channel kind is invalid".into()));
|
|
}
|
|
|
|
}
|
|
|
|
pub async fn add(p: &Pool, name: &str, description: &str, kind: Integer)
|
|
-> Result<Response<Channel>, SqlError> {
|
|
//! @returns on success -> Response::Row<Channel>
|
|
//! @returns on user failure -> Response::RestrictedInput(msg)
|
|
|
|
// bounds are literally [1, 2]
|
|
if kind == TEXT_CHANNEL || kind == VOICE_CHANNEL {
|
|
let mut conn = p.get_conn().await?;
|
|
// Badge id's are not required here as they have a default server-side
|
|
// value of '[]'
|
|
let q = "INSERT INTO channels (id, name, description, kind) VALUES (:i, :n, :d, :k)";
|
|
let id = rand::rngs::OsRng.next_u64(); // generate id's randomly for channels
|
|
conn.exec_drop(q, params!{
|
|
"i" => id,
|
|
"n" => name,
|
|
"d" => description,
|
|
"k" => kind
|
|
}).await?;
|
|
|
|
Ok(Response::Row(Self {
|
|
id,
|
|
name: name.to_string(),
|
|
description: Some(description.to_string()),
|
|
kind,
|
|
badge_ids: Vec::new()
|
|
}))
|
|
}
|
|
else {
|
|
return Ok(Response::RestrictedInput(String::from("Invalid channel type")));
|
|
}
|
|
}
|
|
|
|
pub async fn delete(p: &Pool, id: UBigInt) -> Result<Response<Self>, SqlError> {
|
|
//! Deletes channel given UBigInt as the row key
|
|
//! @param p -> SqlPool
|
|
//! @param id -> UBigInt
|
|
//! @return on success -> Response::Success
|
|
//! @return on server failure -> Response::Other
|
|
let mut conn = p.get_conn().await?;
|
|
|
|
let q = "DELETE FROM channels WHERE id = :id";
|
|
conn.exec_drop(q, params!{"id" => id}).await?;
|
|
Ok(Response::Success)
|
|
}
|
|
|
|
|
|
}
|
|
|