diff options
Diffstat (limited to 'src/message/app.rs')
| -rw-r--r-- | src/message/app.rs | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/src/message/app.rs b/src/message/app.rs index 3385af2..eed6ba4 100644 --- a/src/message/app.rs +++ b/src/message/app.rs @@ -2,13 +2,14 @@ use chrono::TimeDelta; use itertools::Itertools; use sqlx::sqlite::SqlitePool; -use super::{repo::Provider as _, Id, Message}; +use super::{repo::Provider as _, Body, Id, Message}; use crate::{ channel::{self, repo::Provider as _}, clock::DateTime, db::NotFound as _, event::{repo::Provider as _, Broadcaster, Event, Sequence}, login::Login, + name, }; pub struct Messages<'a> { @@ -26,7 +27,7 @@ impl<'a> Messages<'a> { channel: &channel::Id, sender: &Login, sent_at: &DateTime, - body: &str, + body: &Body, ) -> Result<Message, SendError> { let mut tx = self.db.begin().await?; let channel = tx @@ -46,8 +47,17 @@ impl<'a> Messages<'a> { pub async fn delete(&self, message: &Id, deleted_at: &DateTime) -> Result<(), DeleteError> { let mut tx = self.db.begin().await?; + let message = tx + .messages() + .by_id(message) + .await + .not_found(|| DeleteError::NotFound(message.clone()))?; + message + .as_snapshot() + .ok_or_else(|| DeleteError::Deleted(message.id().clone()))?; + let deleted = tx.sequence().next(deleted_at).await?; - let message = tx.messages().delete(message, &deleted).await?; + let message = tx.messages().delete(&message, &deleted).await?; tx.commit().await?; self.events.broadcast( @@ -91,6 +101,17 @@ impl<'a> Messages<'a> { Ok(()) } + + pub async fn purge(&self, relative_to: &DateTime) -> Result<(), sqlx::Error> { + // Somewhat arbitrarily, purge after 6 hours. + let purge_at = relative_to.to_owned() - TimeDelta::hours(6); + + let mut tx = self.db.begin().await?; + tx.messages().purge(&purge_at).await?; + tx.commit().await?; + + Ok(()) + } } #[derive(Debug, thiserror::Error)] @@ -98,15 +119,27 @@ pub enum SendError { #[error("channel {0} not found")] ChannelNotFound(channel::Id), #[error(transparent)] - DatabaseError(#[from] sqlx::Error), + Database(#[from] sqlx::Error), + #[error(transparent)] + Name(#[from] name::Error), +} + +impl From<channel::repo::LoadError> for SendError { + fn from(error: channel::repo::LoadError) -> Self { + use channel::repo::LoadError; + match error { + LoadError::Database(error) => error.into(), + LoadError::Name(error) => error.into(), + } + } } #[derive(Debug, thiserror::Error)] pub enum DeleteError { - #[error("channel {0} not found")] - ChannelNotFound(channel::Id), #[error("message {0} not found")] NotFound(Id), + #[error("message {0} deleted")] + Deleted(Id), #[error(transparent)] - DatabaseError(#[from] sqlx::Error), + Database(#[from] sqlx::Error), } |
