use crate::{
CrdtAdapterController, CrdtEventController, SignerDaemonCore, SignerDaemonOption,
SignerDaemonState,
entity::user,
model::{
crdt::crdt::{CrdtDelta, CrdtDeltaBox},
deltaobject::user_do::UserDO,
viewobject::UserVO,
},
signer_daemon::user_info_synchronizer::UserInfoSynchronizer,
};
use sea_orm::prelude::*;
pub struct UserStore {
core: SignerDaemonCore,
crdt_event: CrdtEventController,
crdt_adapter: CrdtAdapterController,
option: SignerDaemonOption,
}
impl UserStore {
pub fn new(core: SignerDaemonCore, option: SignerDaemonOption) -> Self {
Self {
core: core.clone(),
crdt_event: CrdtEventController::new(core.clone()),
crdt_adapter: CrdtAdapterController::new(core.clone()),
option: option.clone(),
}
}
pub async fn list(&self) -> crate::DaemonResult<Vec<UserVO>> {
let users = user::Entity::find().all(&self.core.db).await?;
Ok(users.into_iter().map(|i| i.into()).collect())
}
pub async fn put(
&mut self,
state: &mut SignerDaemonState,
user_vo: UserVO,
) -> crate::DaemonResult<()> {
let e = user::Entity::find_by_id(&user_vo.pub_key)
.one(&self.core.db)
.await?;
let user_do = match &e {
None => UserDO::from(user_vo.clone()),
Some(e) => {
let db_vo = UserVO::from(e.clone());
let user_do = UserDO::new(&db_vo, &user_vo)?;
if !user_do.has_changed(&db_vo) {
return Ok(());
}
user_do
}
};
let user_delta = CrdtDeltaBox::User(CrdtDelta::Put(user_do));
self.crdt_event.insert_delta(user_delta.clone()).await?;
self.crdt_adapter.apply_all().await?;
let mut syncer = UserInfoSynchronizer::new(self.core.clone(), self.option.clone());
Box::pin(syncer.sync(state)).await?;
self.core.change_notifier.notify(user_delta);
Ok(())
}
pub async fn del(&mut self, pub_key: &str) -> crate::DaemonResult<()> {
if self.get(pub_key).await?.is_none() {
return Ok(());
}
let user_delta = CrdtDeltaBox::User(CrdtDelta::Del(pub_key.to_string()));
self.crdt_event.insert_delta(user_delta.clone()).await?;
self.crdt_adapter.apply_all().await?;
self.core.change_notifier.notify(user_delta);
Ok(())
}
pub async fn get(&self, pub_key: &str) -> crate::DaemonResult<Option<UserVO>> {
let u = user::Entity::find_by_id(pub_key).one(&self.core.db).await?;
Ok(u.map(|i| i.into()))
}
}