sos_database/entity/
system_message.rs1use 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#[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
57pub 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 pub fn new(conn: &'conn C) -> Self {
71 Self { conn }
72 }
73
74 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], |row| {
98 Ok::<_, crate::Error>(convert_row(row)?)
99 })?;
100 let mut messages = Vec::new();
101 for row in rows {
102 messages.push(row?);
103 }
104 Ok(messages)
105 }
106
107 pub fn mark_system_message(
109 &self,
110 account_id: i64,
111 key: &str,
112 is_read: bool,
113 ) -> Result<()> {
114 let modified_at = UtcDateTime::default().to_rfc3339()?;
115 let query = sql::Update::new()
116 .update("system_messages")
117 .set(
118 "
119 modified_at = ?1,
120 json_data = json_replace (json_data, '$.isRead', ?2)
121 ",
122 )
123 .where_clause("account_id = ?3")
124 .where_and("key = ?4");
125 let mut stmt = self.conn.prepare_cached(&query.as_string())?;
126 stmt.execute((modified_at, is_read, account_id, key))?;
127 Ok(())
128 }
129
130 pub fn delete_system_message(
132 &self,
133 account_id: i64,
134 key: &str,
135 ) -> std::result::Result<(), SqlError> {
136 let query = sql::Delete::new()
137 .delete_from("system_messages")
138 .where_clause("account_id = ?1")
139 .where_and("key = ?2");
140 let mut stmt = self.conn.prepare_cached(&query.as_string())?;
141 stmt.execute((account_id, key))?;
142 Ok(())
143 }
144
145 pub fn delete_system_messages(
147 &self,
148 account_id: i64,
149 ) -> std::result::Result<(), SqlError> {
150 let query = sql::Delete::new()
151 .delete_from("system_messages")
152 .where_clause("account_id = ?1");
153 let mut stmt = self.conn.prepare_cached(&query.as_string())?;
154 stmt.execute([account_id])?;
155 Ok(())
156 }
157
158 pub fn insert_system_message(
160 &self,
161 account_id: i64,
162 row: &SystemMessageRow,
163 ) -> std::result::Result<(), SqlError> {
164 let query = sql::Insert::new()
165 .insert_into(
166 r#"
167 system_messages
168 (
169 account_id,
170 created_at,
171 modified_at,
172 key,
173 json_data
174 )
175 "#,
176 )
177 .values("(?1, ?2, ?3, ?4, ?5)");
178 let mut stmt = self.conn.prepare_cached(&query.as_string())?;
179 stmt.execute((
180 account_id,
181 &row.created_at,
182 &row.modified_at,
183 &row.key,
184 &row.json_data,
185 ))?;
186 Ok(())
187 }
188
189 pub fn insert_system_messages(
191 &self,
192 account_id: i64,
193 system_messages: &[SystemMessageRow],
194 ) -> std::result::Result<(), SqlError> {
195 for row in system_messages {
196 self.insert_system_message(account_id, row)?;
197 }
198 Ok(())
199 }
200}