sos_database/entity/
system_message.rs

1use crate::Result;
2use async_sqlite::rusqlite::{Connection, Error as SqlError, Row};
3use sos_core::UtcDateTime;
4use sos_system_messages::SysMessage;
5use sql_query_builder as sql;
6use std::ops::Deref;
7use urn::Urn;
8
9/// SystemMessage row from the database.
10#[doc(hidden)]
11#[derive(Debug, Default)]
12pub struct SystemMessageRow {
13    pub row_id: i64,
14    created_at: String,
15    modified_at: String,
16    key: String,
17    json_data: String,
18}
19
20impl<'a> TryFrom<&Row<'a>> for SystemMessageRow {
21    type Error = SqlError;
22    fn try_from(row: &Row<'a>) -> std::result::Result<Self, Self::Error> {
23        Ok(SystemMessageRow {
24            row_id: row.get(0)?,
25            created_at: row.get(1)?,
26            modified_at: row.get(2)?,
27            key: row.get(3)?,
28            json_data: row.get(4)?,
29        })
30    }
31}
32
33impl TryFrom<SystemMessageRow> for (Urn, SysMessage) {
34    type Error = crate::Error;
35    fn try_from(
36        row: SystemMessageRow,
37    ) -> std::result::Result<Self, Self::Error> {
38        Ok((row.key.parse()?, serde_json::from_str(&row.json_data)?))
39    }
40}
41
42impl TryFrom<(Urn, SysMessage)> for SystemMessageRow {
43    type Error = crate::Error;
44    fn try_from(
45        value: (Urn, SysMessage),
46    ) -> std::result::Result<Self, Self::Error> {
47        Ok(Self {
48            created_at: UtcDateTime::default().to_rfc3339()?,
49            modified_at: UtcDateTime::default().to_rfc3339()?,
50            key: value.0.to_string(),
51            json_data: serde_json::to_string(&value.1)?,
52            ..Default::default()
53        })
54    }
55}
56
57/// SystemMessage entity.
58pub struct SystemMessageEntity<'conn, C>
59where
60    C: Deref<Target = Connection>,
61{
62    conn: &'conn C,
63}
64
65impl<'conn, C> SystemMessageEntity<'conn, C>
66where
67    C: Deref<Target = Connection>,
68{
69    /// Create a new server entity.
70    pub fn new(conn: &'conn C) -> Self {
71        Self { conn }
72    }
73
74    /// Load system messages for an account.
75    pub fn load_system_messages(
76        &self,
77        account_id: i64,
78    ) -> Result<Vec<SystemMessageRow>> {
79        let query = sql::Select::new()
80            .select(
81                r#"
82                    system_message_id,
83                    created_at,
84                    modified_at,
85                    key,
86                    json_data
87                "#,
88            )
89            .from("system_messages")
90            .where_clause("account_id = ?1");
91        let mut stmt = self.conn.prepare_cached(&query.as_string())?;
92
93        fn convert_row(row: &Row<'_>) -> Result<SystemMessageRow> {
94            Ok(row.try_into()?)
95        }
96
97        let rows = stmt.query_and_then([account_id], convert_row)?;
98        let mut messages = Vec::new();
99        for row in rows {
100            messages.push(row?);
101        }
102        Ok(messages)
103    }
104
105    /// Update the is_read flag for a system message.
106    pub fn mark_system_message(
107        &self,
108        account_id: i64,
109        key: &str,
110        is_read: bool,
111    ) -> Result<()> {
112        let modified_at = UtcDateTime::default().to_rfc3339()?;
113        let query = sql::Update::new()
114            .update("system_messages")
115            .set(
116                "
117                modified_at = ?1,
118                json_data = json_replace (json_data, '$.isRead', json(?2))
119            ",
120            )
121            .where_clause("account_id = ?3")
122            .where_and("key = ?4");
123        let mut stmt = self.conn.prepare_cached(&query.as_string())?;
124        stmt.execute((modified_at, is_read, account_id, key))?;
125        Ok(())
126    }
127
128    /// Delete a system message for an account.
129    pub fn delete_system_message(
130        &self,
131        account_id: i64,
132        key: &str,
133    ) -> std::result::Result<(), SqlError> {
134        let query = sql::Delete::new()
135            .delete_from("system_messages")
136            .where_clause("account_id = ?1")
137            .where_and("key = ?2");
138        let mut stmt = self.conn.prepare_cached(&query.as_string())?;
139        stmt.execute((account_id, key))?;
140        Ok(())
141    }
142
143    /// Delete system messages for an account.
144    pub fn delete_system_messages(
145        &self,
146        account_id: i64,
147    ) -> std::result::Result<(), SqlError> {
148        let query = sql::Delete::new()
149            .delete_from("system_messages")
150            .where_clause("account_id = ?1");
151        let mut stmt = self.conn.prepare_cached(&query.as_string())?;
152        stmt.execute([account_id])?;
153        Ok(())
154    }
155
156    /// Create system message in the database.
157    pub fn insert_system_message(
158        &self,
159        account_id: i64,
160        row: &SystemMessageRow,
161    ) -> std::result::Result<(), SqlError> {
162        let query = sql::Insert::new()
163            .insert_into(
164                r#"
165                system_messages
166                (
167                    account_id,
168                    created_at,
169                    modified_at,
170                    key,
171                    json_data
172                )
173                "#,
174            )
175            .values("(?1, ?2, ?3, ?4, ?5)");
176        let mut stmt = self.conn.prepare_cached(&query.as_string())?;
177        stmt.execute((
178            account_id,
179            &row.created_at,
180            &row.modified_at,
181            &row.key,
182            &row.json_data,
183        ))?;
184        Ok(())
185    }
186
187    /// Create system messages in the database.
188    pub fn insert_system_messages(
189        &self,
190        account_id: i64,
191        system_messages: &[SystemMessageRow],
192    ) -> std::result::Result<(), SqlError> {
193        for row in system_messages {
194            self.insert_system_message(account_id, row)?;
195        }
196        Ok(())
197    }
198}