use std::str::FromStr;
use sea_orm::{
ActiveModelTrait as _,
ActiveValue::{NotSet, Set},
DatabaseTransaction, EntityTrait,
sqlx::types::chrono::{self, TimeZone},
};
use crate::{
SignerDaemon,
entity::oper_log,
model::{
deltaobject::{deltaobject::DeltaField, oper_log_do::OperLogDO},
viewobject::OperLogVO,
},
};
use super::{CrdtType, crdt::CrdtDelta};
impl CrdtType for OperLogDO {
type PrimaryKey = String;
async fn put(
&self,
_daemon: &SignerDaemon,
tx: &DatabaseTransaction,
) -> anyhow::Result<CrdtDelta<Self>> {
let id = uuid::Uuid::from_str(&self.id)?;
let ol = oper_log::Entity::find_by_id(id).one(tx).await?;
if let Some(val) = &ol {
if !self.has_changed(&val.clone().into()) {
return Ok(CrdtDelta::Skip);
}
}
let m = oper_log::ActiveModel {
id: Set(id),
title: self.title.clone().into(),
content: self.content.clone().into(),
level: self.level.clone().into(),
create_time: match &self.create_time {
DeltaField::Set(val) => {
Set(chrono::Utc.timestamp_millis_opt(*val).unwrap().naive_utc())
}
DeltaField::NotSet => NotSet,
},
};
match ol {
Some(val) => {
let m = m.update(tx).await?;
let oper_log_do = OperLogDO::new(&m.into(), &val.into())?;
Ok(CrdtDelta::Put(oper_log_do))
}
None => {
let m = m.insert(tx).await?;
Ok(CrdtDelta::Del(m.id.to_string()))
}
}
}
async fn del(
_daemon: &SignerDaemon,
key: &String,
tx: &DatabaseTransaction,
) -> anyhow::Result<CrdtDelta<Self>> {
let id = uuid::Uuid::from_str(&key)?;
let ol = oper_log::Entity::find_by_id(id).one(tx).await?;
match &ol {
Some(val) => {
let oper_log_do = OperLogDO::from(OperLogVO::from(val.clone()));
oper_log::Entity::delete_by_id(val.id).exec(tx).await?;
Ok(CrdtDelta::Put(oper_log_do))
}
None => Ok(CrdtDelta::Skip),
}
}
}