sos_database/
system_messages.rs

1//! System messages provider for a database table.
2use std::collections::HashMap;
3
4use crate::{
5    entity::{AccountEntity, SystemMessageEntity, SystemMessageRow},
6    Error,
7};
8use async_sqlite::Client;
9use async_trait::async_trait;
10use sos_core::AccountId;
11use sos_system_messages::{
12    SysMessage, SystemMessageMap, SystemMessageStorage,
13};
14use urn::Urn;
15
16/// Database storage provider for system messages.
17pub struct SystemMessagesProvider<E>
18where
19    E: std::error::Error
20        + std::fmt::Debug
21        + From<sos_system_messages::Error>
22        + From<Error>
23        + From<std::io::Error>
24        + Send
25        + Sync
26        + 'static,
27{
28    account_id: AccountId,
29    client: Client,
30    marker: std::marker::PhantomData<E>,
31}
32
33impl<E> SystemMessagesProvider<E>
34where
35    E: std::error::Error
36        + std::fmt::Debug
37        + From<sos_system_messages::Error>
38        + From<Error>
39        + From<std::io::Error>
40        + Send
41        + Sync
42        + 'static,
43{
44    /// Create a system messages provider.
45    pub fn new(account_id: AccountId, client: Client) -> Self {
46        Self {
47            account_id,
48            client,
49            marker: std::marker::PhantomData,
50        }
51    }
52}
53
54#[async_trait]
55impl<E> SystemMessageStorage for SystemMessagesProvider<E>
56where
57    E: std::error::Error
58        + std::fmt::Debug
59        + From<sos_system_messages::Error>
60        + From<Error>
61        + From<std::io::Error>
62        + Send
63        + Sync
64        + 'static,
65{
66    type Error = E;
67
68    async fn list_system_messages(
69        &self,
70    ) -> Result<SystemMessageMap, Self::Error> {
71        let account_id = self.account_id.clone();
72        let rows = self
73            .client
74            .conn_and_then(move |conn| {
75                let account = AccountEntity::new(&conn);
76                let account_row = account.find_one(&account_id)?;
77                let messages = SystemMessageEntity::new(&conn);
78                Ok::<_, Error>(
79                    messages.load_system_messages(account_row.row_id)?,
80                )
81            })
82            .await
83            .map_err(Error::from)?;
84
85        let mut messages = HashMap::new();
86        for row in rows {
87            let (key, message) = row.try_into()?;
88            messages.insert(key, message);
89        }
90
91        Ok(messages.into())
92    }
93
94    async fn insert_system_message(
95        &mut self,
96        key: Urn,
97        message: SysMessage,
98    ) -> Result<(), Self::Error> {
99        let account_id = self.account_id.clone();
100        let row: SystemMessageRow = (key, message).try_into()?;
101        Ok(self
102            .client
103            .conn(move |conn| {
104                let account = AccountEntity::new(&conn);
105                let account_row = account.find_one(&account_id)?;
106                let messages = SystemMessageEntity::new(&conn);
107                Ok(messages
108                    .insert_system_message(account_row.row_id, &row)?)
109            })
110            .await
111            .map_err(Error::from)?)
112    }
113
114    async fn remove_system_message(
115        &mut self,
116        key: &Urn,
117    ) -> Result<(), Self::Error> {
118        let account_id = self.account_id.clone();
119        let key = key.to_string();
120        Ok(self
121            .client
122            .conn(move |conn| {
123                let account = AccountEntity::new(&conn);
124                let account_row = account.find_one(&account_id)?;
125                let messages = SystemMessageEntity::new(&conn);
126                Ok(messages
127                    .delete_system_message(account_row.row_id, &key)?)
128            })
129            .await
130            .map_err(Error::from)?)
131    }
132
133    async fn mark_system_message(
134        &mut self,
135        key: &Urn,
136        is_read: bool,
137    ) -> Result<(), Self::Error> {
138        let account_id = self.account_id.clone();
139        let key = key.to_string();
140        Ok(self
141            .client
142            .conn_and_then(move |conn| {
143                let account = AccountEntity::new(&conn);
144                let account_row = account.find_one(&account_id)?;
145                let messages = SystemMessageEntity::new(&conn);
146                messages.mark_system_message(
147                    account_row.row_id,
148                    &key,
149                    is_read,
150                )
151            })
152            .await?)
153    }
154
155    async fn clear_system_messages(&mut self) -> Result<(), Self::Error> {
156        let account_id = self.account_id.clone();
157        Ok(self
158            .client
159            .conn(move |conn| {
160                let account = AccountEntity::new(&conn);
161                let account_row = account.find_one(&account_id)?;
162                let messages = SystemMessageEntity::new(&conn);
163                Ok(messages.delete_system_messages(account_row.row_id)?)
164            })
165            .await
166            .map_err(Error::from)?)
167    }
168}