use crate::{
entity::{AccountEntity, PreferenceEntity, PreferenceRow},
Error,
};
use async_sqlite::Client;
use async_trait::async_trait;
use sos_core::AccountId;
use sos_preferences::{Preference, PreferenceMap, PreferencesStorage};
pub struct PreferenceProvider<E>
where
E: std::error::Error
+ std::fmt::Debug
+ From<Error>
+ From<sos_preferences::Error>
+ Send
+ Sync
+ 'static,
{
client: Client,
marker: std::marker::PhantomData<E>,
}
impl<E> PreferenceProvider<E>
where
E: std::error::Error
+ std::fmt::Debug
+ From<Error>
+ From<sos_preferences::Error>
+ Send
+ Sync
+ 'static,
{
pub fn new(client: Client) -> Self {
Self {
client,
marker: std::marker::PhantomData,
}
}
}
#[async_trait]
impl<E> PreferencesStorage for PreferenceProvider<E>
where
E: std::error::Error
+ std::fmt::Debug
+ From<Error>
+ From<sos_preferences::Error>
+ Send
+ Sync
+ 'static,
{
type Error = E;
async fn load_preferences(
&self,
account_id: Option<&AccountId>,
) -> Result<PreferenceMap, Self::Error> {
let account_id = account_id.cloned();
let rows =
self.client
.conn_and_then(move |conn| match account_id {
Some(account_id) => {
let account = AccountEntity::new(&conn);
let account_row =
account.find_optional(&account_id)?;
let prefs = PreferenceEntity::new(&conn);
Ok::<_, Error>(prefs.load_preferences(
account_row.map(|r| r.row_id),
)?)
}
None => {
let prefs = PreferenceEntity::new(&conn);
Ok::<_, Error>(prefs.load_preferences(None)?)
}
})
.await?;
let mut map: PreferenceMap = Default::default();
for row in rows {
let (key, pref) = row.try_into()?;
map.insert(key, pref);
}
Ok(map)
}
async fn insert_preference(
&self,
account_id: Option<&AccountId>,
key: &str,
pref: &Preference,
) -> Result<(), Self::Error> {
let account_id = account_id.cloned();
let row = PreferenceRow::new_update(key, pref)?;
Ok(self
.client
.conn(move |conn| match account_id {
Some(account_id) => {
let account = AccountEntity::new(&conn);
let account_row = account.find_optional(&account_id)?;
let prefs = PreferenceEntity::new(&conn);
Ok(prefs.upsert_preference(
account_row.map(|r| r.row_id),
&row,
)?)
}
None => {
let prefs = PreferenceEntity::new(&conn);
Ok(prefs.upsert_preference(None, &row)?)
}
})
.await
.map_err(Error::from)?)
}
async fn remove_preference(
&self,
account_id: Option<&AccountId>,
key: &str,
) -> Result<(), Self::Error> {
let account_id = account_id.cloned();
let key = key.to_owned();
Ok(self
.client
.conn(move |conn| match account_id {
Some(account_id) => {
let account = AccountEntity::new(&conn);
let account_row = account.find_optional(&account_id)?;
let prefs = PreferenceEntity::new(&conn);
Ok(prefs.delete_preference(
account_row.map(|r| r.row_id),
&key,
)?)
}
None => {
let prefs = PreferenceEntity::new(&conn);
Ok(prefs.delete_preference(None, &key)?)
}
})
.await
.map_err(Error::from)?)
}
async fn clear_preferences(
&self,
account_id: Option<&AccountId>,
) -> Result<(), Self::Error> {
let account_id = account_id.cloned();
Ok(self
.client
.conn(move |conn| match account_id {
Some(account_id) => {
let account = AccountEntity::new(&conn);
let account_row = account.find_optional(&account_id)?;
let prefs = PreferenceEntity::new(&conn);
Ok(prefs.delete_all_preferences(
account_row.map(|r| r.row_id),
)?)
}
None => {
let prefs = PreferenceEntity::new(&conn);
Ok(prefs.delete_all_preferences(None)?)
}
})
.await
.map_err(Error::from)?)
}
}