use crate::{
CrdtAdapterController, CrdtEventController, SignerDaemonCore,
entity::{chat, message},
model::{
crdt::crdt::{CrdtDelta, CrdtDeltaBox},
deltaobject::chat_do::ChatDO,
viewobject::{ChatVO, MessageContent, MessageKeyVO, MessageVO, Null},
},
};
use sea_orm::{QueryOrder, prelude::*};
pub struct ChatStore {
core: SignerDaemonCore,
crdt_event: CrdtEventController,
crdt_adapter: CrdtAdapterController,
}
impl ChatStore {
pub fn new(core: SignerDaemonCore) -> Self {
Self {
core: core.clone(),
crdt_event: CrdtEventController::new(core.clone()),
crdt_adapter: CrdtAdapterController::new(core.clone()),
}
}
pub async fn list(&self) -> crate::DaemonResult<Vec<ChatVO>> {
let r = chat::Entity::find().all(&self.core.db).await?;
let mut chats = Vec::new();
for i in r {
chats.push(serde_json::from_str(&i.view_object)?);
}
Ok(chats)
}
pub async fn put(&mut self, vo: ChatVO) -> crate::DaemonResult<()> {
let r = chat::Entity::find()
.filter(
chat::Column::ChatKey
.eq(&vo.chat_key(&self.core).await?)
.and(chat::Column::ChatVariant.eq(&vo.chat_variant())),
)
.one(&self.core.db)
.await?;
let chat_do = match &r {
Some(val) => {
let chat_do =
ChatDO::new(&self.core, &serde_json::from_str(&val.view_object)?, &vo).await?;
if !chat_do.has_changed(&vo) {
return Ok(());
}
chat_do
}
None => ChatDO::from_vo(&self.core, vo.clone()).await?,
};
let delta = CrdtDeltaBox::Chat(CrdtDelta::Put(chat_do));
self.crdt_event.insert_delta(delta.clone()).await?;
self.crdt_adapter.apply_all().await?;
self.core.change_notifier.notify(delta);
Ok(())
}
pub async fn del(&mut self, chat_key: &str, chat_variant: &str) -> crate::DaemonResult<()> {
if self.get(chat_key, chat_variant).await?.is_none() {
return Ok(());
}
let delta = CrdtDeltaBox::Chat(CrdtDelta::Del((
chat_key.to_string(),
chat_variant.to_string(),
)));
self.crdt_event.insert_delta(delta.clone()).await?;
self.crdt_adapter.apply_all().await?;
self.core.change_notifier.notify(delta);
Ok(())
}
pub async fn get(
&self,
chat_key: &str,
chat_variant: &str,
) -> crate::DaemonResult<Option<ChatVO>> {
let r = chat::Entity::find()
.filter(
chat::Column::ChatKey
.eq(chat_key)
.and(chat::Column::ChatVariant.eq(chat_variant)),
)
.one(&self.core.db)
.await?;
Ok(r.map(|i| serde_json::from_str(&i.view_object).expect("serialize view object failed")))
}
pub async fn list_message_key(
&self,
chat_key: &str,
chat_variant: &str,
) -> crate::DaemonResult<Vec<MessageKeyVO>> {
let records = message::Entity::find()
.filter(
message::Column::ChatKey
.eq(chat_key)
.and(message::Column::ChatVariant.eq(chat_variant))
.and(message::Column::ContentType.ne(MessageContent::Check(Null {}).ty())),
)
.order_by_asc(message::Column::CreateTime)
.all(&self.core.db)
.await?;
let mut message_keys = Vec::new();
for record in records {
let message_vo = MessageVO::from_model(&self.core.db, &record).await?;
message_keys.push(MessageKeyVO::from_message(&self.core, &message_vo).await?);
}
Ok(message_keys)
}
}