summaryrefslogtreecommitdiff
path: root/src/message/app.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/message/app.rs')
-rw-r--r--src/message/app.rs47
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),
}