use sea_orm::{ActiveModelTrait, ActiveValue::Set, DatabaseTransaction, EntityTrait};
use crate::{
SignerMeta, crdt::errors::CrdtError, delta::user_do::UserDO, entity::user, view::UserVO,
};
use super::{CrdtType, crdt::CrdtDelta};
impl CrdtType for UserDO {
type PrimaryKey = String;
async fn put(
&self,
_core: &SignerMeta,
tx: &DatabaseTransaction,
) -> Result<CrdtDelta<Self>, CrdtError> {
let u = user::Entity::find_by_id(&self.pub_key).one(tx).await?;
if let Some(val) = &u {
if !self.has_changed(&val.clone().into()) {
return Ok(CrdtDelta::Skip);
}
}
let m = user::ActiveModel {
pub_key: Set(self.pub_key.clone()),
user_public: self.user_public.clone().into(),
signed_user_public: self.signed_user_public.clone().into(),
};
match u {
Some(val) => {
let m = m.update(tx).await?;
let user_do = UserDO::new(&m.into(), &val.into())?;
Ok(CrdtDelta::Put(user_do))
}
None => {
let m = m.insert(tx).await?;
Ok(CrdtDelta::Del(m.pub_key))
}
}
}
async fn del(
_core: &SignerMeta,
key: &String,
tx: &DatabaseTransaction,
) -> Result<CrdtDelta<Self>, CrdtError> {
let m = user::Entity::find_by_id(key).one(tx).await?;
match m {
Some(val) => {
let user_do = UserDO::from(UserVO::from(val.clone()));
user::Entity::delete_by_id(&val.pub_key).exec(tx).await?;
Ok(CrdtDelta::Put(user_do))
}
None => Ok(CrdtDelta::Skip),
}
}
}