use crate::{
ChatStore, CrdtAdapterController, CrdtEventController, SignerDaemonCore,
entity::message,
model::{
crdt::{
crdt::{CrdtDelta, CrdtDeltaBox},
crdt_message::MessageKey,
},
deltaobject::message_do::MessageDO,
viewobject::{MessageContent, MessageVO, Null},
},
};
use sea_orm::prelude::*;
pub struct MessageStore {
core: SignerDaemonCore,
chat_store: ChatStore,
crdt_event: CrdtEventController,
crdt_adapter: CrdtAdapterController,
}
impl MessageStore {
pub fn new(core: SignerDaemonCore) -> Self {
Self {
core: core.clone(),
chat_store: ChatStore::new(core.clone()),
crdt_event: CrdtEventController::new(core.clone()),
crdt_adapter: CrdtAdapterController::new(core.clone()),
}
}
pub async fn list(&self) -> crate::DaemonResult<Vec<MessageVO>> {
let r = message::Entity::find().all(&self.core.db).await?;
let mut messages = Vec::new();
for i in r {
messages.push(MessageVO::from_model(&self.core.db, &i).await?);
}
Ok(messages)
}
pub async fn put(&mut self, vo: MessageVO) -> crate::DaemonResult<()> {
self.chat_store.put(vo.chat.clone()).await?;
let r = message::Entity::find()
.filter(
message::Column::Id.eq(&vo.id).and(
message::Column::UserKey
.eq(&vo.user_key)
.and(message::Column::ChatKey.eq(&vo.chat.chat_key(&self.core).await?))
.and(message::Column::ChatVariant.eq(&vo.chat.chat_variant())),
),
)
.one(&self.core.db)
.await?;
let message_do = match &r {
Some(val) => {
let message_do =
MessageDO::new(&MessageVO::from_model(&self.core.db, &val).await?, &vo)?;
if !message_do.has_changed(&vo) {
return Ok(());
}
message_do
}
None => MessageDO::from(vo.clone()),
};
let delta = CrdtDeltaBox::Message(CrdtDelta::Put(message_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,
id: &str,
user_key: &str,
chat_key: &str,
chat_variant: &str,
) -> crate::DaemonResult<()> {
if self
.get(id, user_key, chat_key, chat_variant)
.await?
.is_none()
{
return Ok(());
}
let delta = CrdtDeltaBox::Message(CrdtDelta::Del(MessageKey {
id: id.to_string(),
user_key: user_key.to_string(),
chat_key: chat_key.to_string(),
chat_variant: 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,
id: &str,
user_key: &str,
chat_key: &str,
chat_variant: &str,
) -> crate::DaemonResult<Option<MessageVO>> {
let r = message::Entity::find()
.filter(
message::Column::Id.eq(id).and(
message::Column::UserKey
.eq(user_key)
.and(message::Column::ChatKey.eq(chat_key))
.and(message::Column::ChatVariant.eq(chat_variant)),
),
)
.one(&self.core.db)
.await?;
let m = match &r {
None => None,
Some(val) => Some(MessageVO::from_model(&self.core.db, val).await?),
};
Ok(m)
}
pub async fn list_checked(
&self,
id: &str,
user_key: &str,
chat_key: &str,
chat_variant: &str,
) -> crate::DaemonResult<Vec<MessageVO>> {
let r = message::Entity::find()
.filter(
message::Column::ParentId
.eq(id)
.and(message::Column::ParentUserKey.eq(user_key))
.and(message::Column::ChatKey.eq(chat_key))
.and(message::Column::ChatVariant.eq(chat_variant))
.and(
message::Column::Content
.eq(serde_json::to_string(&MessageContent::Check(Null {}))?),
),
)
.all(&self.core.db)
.await?;
let mut messages = Vec::new();
for i in r {
messages.push(MessageVO::from_model(&self.core.db, &i).await?);
}
Ok(messages)
}
}