use crate::{
CrdtAdapterController, CrdtEventController, RemoteController, SignerDaemonCore,
SignerDaemonState,
entity::server,
model::{
crdt::crdt::{CrdtDelta, CrdtDeltaBox},
deltaobject::server_do::ServerDO,
viewobject::ServerVO,
},
};
use sea_orm::prelude::*;
pub struct ServerStore {
core: SignerDaemonCore,
remote: RemoteController,
crdt_event: CrdtEventController,
crdt_adapter: CrdtAdapterController,
}
impl ServerStore {
pub fn new(core: SignerDaemonCore) -> Self {
Self {
core: core.clone(),
remote: RemoteController::new(core.clone()),
crdt_event: CrdtEventController::new(core.clone()),
crdt_adapter: CrdtAdapterController::new(core.clone()),
}
}
pub async fn list(&self) -> crate::DaemonResult<Vec<ServerVO>> {
let servers = server::Entity::find().all(&self.core.db).await?;
Ok(servers.into_iter().map(|i| i.into()).collect())
}
pub async fn put(
&mut self,
state: &mut SignerDaemonState,
server_vo: ServerVO,
) -> crate::DaemonResult<()> {
let r = server::Entity::find_by_id(&server_vo.addr)
.one(&self.core.db)
.await?;
let server_do = match &r {
Some(val) => {
let server_do = ServerDO::new(&val.clone().into(), &server_vo)?;
if !server_do.has_changed(&server_vo) {
return Ok(());
}
server_do
}
None => ServerDO::from(server_vo.clone()),
};
let server_delta = CrdtDeltaBox::Server(CrdtDelta::Put(server_do));
self.crdt_event.insert_delta(server_delta.clone()).await?;
self.crdt_adapter.apply_all().await?;
self.remote.reconcile(state).await?;
self.core.change_notifier.notify(server_delta);
Ok(())
}
pub async fn del(
&mut self,
state: &mut SignerDaemonState,
addr: &str,
) -> crate::DaemonResult<()> {
if self.get(addr).await?.is_none() {
return Ok(());
}
let server_delta = CrdtDeltaBox::Server(CrdtDelta::Del(addr.to_string()));
self.crdt_event.insert_delta(server_delta.clone()).await?;
self.crdt_adapter.apply_all().await?;
self.remote.reconcile(state).await?;
self.core.change_notifier.notify(server_delta);
Ok(())
}
pub async fn get(&self, addr: &str) -> crate::DaemonResult<Option<ServerVO>> {
let r = server::Entity::find_by_id(addr).one(&self.core.db).await?;
Ok(r.map(|i| i.into()))
}
}