+ Adding badge_ids to db-lib backend

With this frontend points now return proper data  structures which of course contain
badge_id vectors

Along with defaulting to '[]' strings in  mysql configuration serde_json  calls
now fallback to .unwrap_or(Vec::new()) for cheapish callbacks.
These fallback calls are cheap because Vec::new doesn't allocate anything on the heap
because they're empty.
This commit is contained in:
shockrah 2021-05-20 16:44:08 -07:00
parent fc24ad3430
commit a2f8cfb09d
3 changed files with 35 additions and 39 deletions

View File

@ -16,13 +16,20 @@ 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 FROM channels WHERE id = :id";
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)> =
let row: Option<(String, Option<String>, i32, String)> =
conn.exec_first(q, params).await?;
if let Some(row) = row {
let chan = Channel { id, name: row.0, description: row.1, kind: row.2 };
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)
@ -36,11 +43,14 @@ impl Channel {
if kind == VOICE_CHANNEL || kind ==TEXT_CHANNEL {
let mut conn = p.get_conn().await?;
let q = "SELECT id, name, description, kind FROM channels WHERE kind = :kind";
let q = "SELECT id, name, description, kind, badge_ids FROM channels WHERE kind = :kind";
let params = params!{"kind" => kind};
let channels = conn.exec_map(q, params, |(id, name, description, kind)| {
type Row = (u64, String, Option<String>, i32, String);
let channels = conn.exec_map(q, params, |(id, name, description, kind, badge_ids): Row| {
println!("{}", badge_ids);
let badge_ids: Vec<u32> = serde_json::from_str(&badge_ids).unwrap_or(Vec::new());
Channel {
id, name, description, kind
id, name, description, kind, badge_ids
}
}).await?;
Ok(Response::Set(channels))
@ -71,7 +81,8 @@ impl Channel {
id,
name: name.to_string(),
description: Some(description.to_string()),
kind
kind,
badge_ids: Vec::new()
}))
}
else {

View File

@ -66,7 +66,7 @@ pub struct Channel {
pub name: VarChar,
pub description: Option<VarChar>,
pub kind: Integer,
pub badges: Vec<Badge>
pub badge_ids: Vec<u32>
}
#[derive(Serialize, Debug)]
@ -83,7 +83,7 @@ pub struct Member {
pub name: VarChar,
pub status: Integer,
pub permissions: UBigInt,
pub badges: Vec<Badge>
pub badge_ids: Vec<u32>
}
#[derive(Serialize)]
@ -92,7 +92,7 @@ pub struct PublicMember {
pub name: VarChar,
pub status: Integer,
pub permissions: UBigInt,
pub badges: Vec<Badge>
pub badge_ids: Vec<u32> // badge id's
}
#[derive(Debug, Deserialize, Serialize)]

View File

@ -20,14 +20,15 @@ impl Member {
//! @returns Other on failure
let mut conn = p.get_conn().await?;
let q = "SELECT secret, name, status, permissions FROM members WHERE id = :id";
let q = "SELECT secret, name, status, permissions, badge_ids FROM members WHERE id = :id";
let params = params!{"id" => id};
let row: Option<(VarChar, VarChar, Integer, UBigInt)> =
let row: Option<(VarChar, VarChar, Integer, UBigInt, String)> =
conn.exec_first(q, params).await?;
if let Some((secret, name, status, permissions)) = row {
if let Some((secret, name, status, permissions, bids_str)) = row {
let badge_ids: Vec<u32> = serde_json::from_str(&bids_str).unwrap_or(Vec::new());
Ok(Response::Row(Member {
id, secret, name, status, permissions
id, secret, name, status, permissions, badge_ids
}))
} else {
Ok(Response::Empty)
@ -35,26 +36,6 @@ impl Member {
}
pub async fn filter(p: &Pool, status: Integer) -> Result<Response<PublicMember>, SqlError> {
//! @params status i32
//! @returns Response::Set(PublicMember)
if !(status == STATUS_ONLINE || status == STATUS_AWAY || status == STATUS_OFFLINE || status == STATUS_DO_NOT_DISTURB) {
Ok(Response::RestrictedInput(format!("Invalid status")))
} else {
let mut conn = p.get_conn().await?;
let q =
"SELECT id, name, status, permissions FROM members
WHERE status = :stat LIMIT 100"; // high limit for now
let params = params!{"stat" => status};
let members = conn.exec_map(q, params, |(id, name , status, permissions)| {
PublicMember {
id, name, status, permissions
}
}).await?;
Ok(Response::Set(members))
}
}
pub async fn add(p: &Pool, name: &str, enc_secret: &str, perms: u64) -> Result<Response<Self>, SqlError> {
//! @param {pool} p
//! @param {&str} name of new user
@ -83,7 +64,8 @@ impl Member {
secret: enc_secret.into(),
name: name.into(),
status: STATUS_ONLINE,
permissions: perms
permissions: perms,
badge_ids: Vec::new()
}))
}
@ -126,12 +108,15 @@ impl PublicMember {
return Ok(Response::RestrictedInput(format!("Invalid status value")));
} else {
let mut conn = p.get_conn().await?;
let q = "SELECT id, name, permissions FROM members
let q = "SELECT id, name, permissions badge_ids FROM members
WHERE status = :status LIMIT 1000";
let params = params!{"status" => status};
let members = conn.exec_map(q, params, |(id, name, permissions)| {
PublicMember { id, name, permissions, status }
type Row = (u64, String, u64, String);
let members = conn.exec_map(q, params, |(id, name, permissions, ids): Row| {
let badge_ids: Vec<u32> = serde_json::from_str(&ids)
.unwrap_or(Vec::new());
PublicMember { id, name, permissions, status, badge_ids }
}).await?;
return Ok(Response::Set(members));