diff --git a/crates/core/src/database/auth.rs b/crates/core/src/database/auth.rs index fcd34be..4ced643 100644 --- a/crates/core/src/database/auth.rs +++ b/crates/core/src/database/auth.rs @@ -101,13 +101,9 @@ impl DataManager { permissions: FinePermission::from_bits(get!(x->7(i32)) as u32).unwrap(), is_verified: get!(x->8(i32)) as i8 == 1, notification_count: { - let x = get!(x->9(i32)); - if x > (usize::MAX - 1000) as i32 { - // we're a little too close to the maximum count, clearly something's gone wrong - 0 - } else { - x as usize - } + let x = get!(x->9(i32)) as usize; + // we're a little too close to the maximum count, clearly something's gone wrong + if x > usize::MAX - 1000 { 0 } else { x } }, follower_count: get!(x->10(i32)) as usize, following_count: get!(x->11(i32)) as usize, @@ -116,12 +112,8 @@ impl DataManager { recovery_codes: serde_json::from_str(&get!(x->14(String)).to_string()).unwrap(), post_count: get!(x->15(i32)) as usize, request_count: { - let x = get!(x->16(i32)); - if x > (usize::MAX - 1000) as i32 { - 0 - } else { - x as usize - } + let x = get!(x->16(i32)) as usize; + if x > usize::MAX - 1000 { 0 } else { x } }, connections: serde_json::from_str(&get!(x->17(String)).to_string()).unwrap(), stripe_id: get!(x->18(String)), diff --git a/crates/core/src/database/drivers/sql/version_migrations.sql b/crates/core/src/database/drivers/sql/version_migrations.sql index 1988e63..c101e7d 100644 --- a/crates/core/src/database/drivers/sql/version_migrations.sql +++ b/crates/core/src/database/drivers/sql/version_migrations.sql @@ -9,3 +9,7 @@ ADD COLUMN IF NOT EXISTS is_deactivated INT DEFAULT 0; -- apps storage_capacity ALTER TABLE apps ADD COLUMN IF NOT EXISTS storage_capacity TEXT DEFAULT '"Tier1"'; + +-- letters replying_to +ALTER TABLE letters +ADD COLUMN IF NOT EXISTS replying_to TEXT DEFAULT 0; diff --git a/crates/core/src/database/letters.rs b/crates/core/src/database/letters.rs index 32f8187..fe9bbac 100644 --- a/crates/core/src/database/letters.rs +++ b/crates/core/src/database/letters.rs @@ -13,6 +13,7 @@ impl DataManager { subject: get!(x->4(String)), content: get!(x->5(String)), read_by: serde_json::from_str(&get!(x->6(String))).unwrap(), + replying_to: get!(x->7(i32)) as usize, } } @@ -66,6 +67,30 @@ impl DataManager { Ok(res.unwrap()) } + /// Get all letters which are replying to the given letter. + /// + /// # Arguments + /// * `id` - the ID of the letter to fetch letters for + pub async fn get_letters_by_replying_to(&self, id: usize) -> Result> { + let conn = match self.0.connect().await { + Ok(c) => c, + Err(e) => return Err(Error::DatabaseConnection(e.to_string())), + }; + + let res = query_rows!( + &conn, + "SELECT * FROM letters WHERE replying_to = $1 ORDER BY created DESC", + &[&(id as i64)], + |x| { Self::get_letter_from_row(x) } + ); + + if res.is_err() { + return Err(Error::GeneralNotFound("letter".to_string())); + } + + Ok(res.unwrap()) + } + /// Create a new letter in the database. /// /// # Arguments @@ -92,7 +117,7 @@ impl DataManager { let res = execute!( &conn, - "INSERT INTO letters VALUES ($1, $2, $3, $4, $5, $6, $7)", + "INSERT INTO letters VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", params![ &(data.id as i64), &(data.created as i64), @@ -101,6 +126,7 @@ impl DataManager { &data.subject, &data.content, &serde_json::to_string(&data.read_by).unwrap(), + &(data.replying_to as i64) ] ); diff --git a/crates/core/src/model/mail.rs b/crates/core/src/model/mail.rs index 849aaae..8336821 100644 --- a/crates/core/src/model/mail.rs +++ b/crates/core/src/model/mail.rs @@ -17,11 +17,19 @@ pub struct Letter { /// This field can be updated by anyone in the letter's `receivers` field. /// Other fields in the letter can only be updated by the letter's `owner`. pub read_by: Vec, + /// The ID of the letter this letter is replying to. + pub replying_to: usize, } impl Letter { /// Create a new [`Letter`]. - pub fn new(owner: usize, receivers: Vec, subject: String, content: String) -> Self { + pub fn new( + owner: usize, + receivers: Vec, + subject: String, + content: String, + replying_to: usize, + ) -> Self { Self { id: Snowflake::new().to_string().parse::().unwrap(), created: unix_epoch_timestamp(), @@ -30,6 +38,7 @@ impl Letter { subject, content, read_by: Vec::new(), + replying_to, } } }