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;
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                messages.load_system_messages(account_row.row_id)
79            })
80            .await?;
81
82        let mut messages = HashMap::new();
83        for row in rows {
84            let (key, message) = row.try_into()?;
85            messages.insert(key, message);
86        }
87
88        Ok(messages.into())
89    }
90
91    async fn insert_system_message(
92        &mut self,
93        key: Urn,
94        message: SysMessage,
95    ) -> Result<(), Self::Error> {
96        let account_id = self.account_id;
97        let row: SystemMessageRow = (key, message).try_into()?;
98        Ok(self
99            .client
100            .conn(move |conn| {
101                let account = AccountEntity::new(&conn);
102                let account_row = account.find_one(&account_id)?;
103                let messages = SystemMessageEntity::new(&conn);
104                messages.insert_system_message(account_row.row_id, &row)
105            })
106            .await
107            .map_err(Error::from)?)
108    }
109
110    async fn remove_system_message(
111        &mut self,
112        key: &Urn,
113    ) -> Result<(), Self::Error> {
114        let account_id = self.account_id;
115        let key = key.to_string();
116        Ok(self
117            .client
118            .conn(move |conn| {
119                let account = AccountEntity::new(&conn);
120                let account_row = account.find_one(&account_id)?;
121                let messages = SystemMessageEntity::new(&conn);
122                messages.delete_system_message(account_row.row_id, &key)
123            })
124            .await
125            .map_err(Error::from)?)
126    }
127
128    async fn mark_system_message(
129        &mut self,
130        key: &Urn,
131        is_read: bool,
132    ) -> Result<(), Self::Error> {
133        let account_id = self.account_id;
134        let key = key.to_string();
135        Ok(self
136            .client
137            .conn_and_then(move |conn| {
138                let account = AccountEntity::new(&conn);
139                let account_row = account.find_one(&account_id)?;
140                let messages = SystemMessageEntity::new(&conn);
141                messages.mark_system_message(
142                    account_row.row_id,
143                    &key,
144                    is_read,
145                )
146            })
147            .await?)
148    }
149
150    async fn clear_system_messages(&mut self) -> Result<(), Self::Error> {
151        let account_id = self.account_id;
152        Ok(self
153            .client
154            .conn(move |conn| {
155                let account = AccountEntity::new(&conn);
156                let account_row = account.find_one(&account_id)?;
157                let messages = SystemMessageEntity::new(&conn);
158                messages.delete_system_messages(account_row.row_id)
159            })
160            .await
161            .map_err(Error::from)?)
162    }
163}