signer-daemon 0.2.5

Signer daemon package.
Documentation
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter, QueryOrder};

use crate::{
  entity::{chat, message},
  model::{
    crdt::crdt::{CrdtDelta, CrdtDeltaBox},
    deltaobject::chat_do::ChatDO,
    viewobject::{ChatVO, MessageContent, MessageKeyVO, MessageVO, Null},
  },
};

use super::{SignerDaemon, signer_daemon_event::SignerDaemonEvent};

impl SignerDaemon {
  pub async fn list_chat(&self) -> anyhow::Result<Vec<ChatVO>> {
    let r = chat::Entity::find().all(&self.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_chat(&self, vo: ChatVO) -> anyhow::Result<()> {
    let r = chat::Entity::find()
      .filter(
        chat::Column::ChatKey
          .eq(&vo.chat_key(&self).await?)
          .and(chat::Column::ChatVariant.eq(&vo.chat_variant())),
      )
      .one(&self.db)
      .await?;
    let chat_do = match &r {
      Some(val) => {
        let chat_do =
          ChatDO::new(&self, &serde_json::from_str(&val.view_object)?, &vo)
            .await?;
        if !chat_do.has_changed(&vo) {
          return Ok(());
        }
        chat_do
      }
      None => ChatDO::from_vo(&self, vo.clone()).await?,
    };

    let delta = CrdtDeltaBox::Chat(CrdtDelta::Put(chat_do));
    self.emit(SignerDaemonEvent::InsertDelta(delta))?;

    self.wait_apply().await?;

    Ok(())
  }

  pub async fn del_chat(
    &self,
    chat_key: &str,
    chat_variant: &str,
  ) -> anyhow::Result<()> {
    if self.get_chat(chat_key, chat_variant).await?.is_none() {
      return Ok(());
    }

    let delta = CrdtDeltaBox::Chat(CrdtDelta::Del((
      chat_key.to_string(),
      chat_variant.to_string(),
    )));
    self.emit(SignerDaemonEvent::InsertDelta(delta))?;

    Ok(())
  }

  pub async fn get_chat(
    &self,
    chat_key: &str,
    chat_variant: &str,
  ) -> anyhow::Result<Option<ChatVO>> {
    let r = chat::Entity::find()
      .filter(
        chat::Column::ChatKey
          .eq(chat_key)
          .and(chat::Column::ChatVariant.eq(chat_variant)),
      )
      .one(&self.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,
  ) -> anyhow::Result<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.db)
      .await?;

    let mut message_keys = Vec::new();
    for record in records {
      let message_vo = MessageVO::from_model(&self.db, &record).await?;
      message_keys.push(MessageKeyVO::from_message(&self, &message_vo).await?);
    }

    Ok(message_keys)
  }
}