diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/channel/app.rs | 8 | ||||
| -rw-r--r-- | src/channel/handlers/send/mod.rs | 4 | ||||
| -rw-r--r-- | src/channel/handlers/send/test.rs | 2 | ||||
| -rw-r--r-- | src/channel/history.rs | 9 | ||||
| -rw-r--r-- | src/message/app.rs | 16 | ||||
| -rw-r--r-- | src/message/repo.rs | 7 |
6 files changed, 31 insertions, 15 deletions
diff --git a/src/channel/app.rs b/src/channel/app.rs index dc9e584..e3b169c 100644 --- a/src/channel/app.rs +++ b/src/channel/app.rs @@ -48,14 +48,14 @@ impl<'a> Channels<'a> { // This function is careless with respect to time, and gets you the channel as // it exists in the specific moment when you call it. pub async fn get(&self, channel: &Id) -> Result<Channel, Error> { - let not_found = || Error::NotFound(channel.clone()); - let deleted = || Error::Deleted(channel.clone()); + let to_not_found = || Error::NotFound(channel.clone()); + let to_deleted = || Error::Deleted(channel.clone()); let mut tx = self.db.begin().await?; - let channel = tx.channels().by_id(channel).await.not_found(not_found)?; + let channel = tx.channels().by_id(channel).await.not_found(to_not_found)?; tx.commit().await?; - channel.as_snapshot().ok_or_else(deleted) + channel.as_snapshot().ok_or_else(to_deleted) } pub async fn delete(&self, channel: &Id, deleted_at: &DateTime) -> Result<(), DeleteError> { diff --git a/src/channel/handlers/send/mod.rs b/src/channel/handlers/send/mod.rs index aa241e2..bde39e5 100644 --- a/src/channel/handlers/send/mod.rs +++ b/src/channel/handlers/send/mod.rs @@ -54,7 +54,9 @@ impl IntoResponse for Error { fn into_response(self) -> response::Response { let Self(error) = self; match error { - SendError::ChannelNotFound(_) => NotFound(error).into_response(), + SendError::ChannelNotFound(_) | SendError::ChannelDeleted(_) => { + NotFound(error).into_response() + } SendError::Name(_) | SendError::Database(_) => Internal::from(error).into_response(), } } diff --git a/src/channel/handlers/send/test.rs b/src/channel/handlers/send/test.rs index d77e07d..70d45eb 100644 --- a/src/channel/handlers/send/test.rs +++ b/src/channel/handlers/send/test.rs @@ -125,6 +125,6 @@ async fn deleted_channel() { assert!(matches!( error, - SendError::ChannelNotFound(error_channel) if channel.id == error_channel + SendError::ChannelDeleted(error_channel) if channel.id == error_channel )); } diff --git a/src/channel/history.rs b/src/channel/history.rs index 7f18e45..85da5a5 100644 --- a/src/channel/history.rs +++ b/src/channel/history.rs @@ -27,6 +27,15 @@ impl History { self.channel.clone() } + pub fn as_of<S>(&self, sequence: S) -> Option<Channel> + where + S: Into<Sequence>, + { + self.events() + .filter(Sequence::up_to(sequence.into())) + .collect() + } + // Snapshot of this channel as of all events recorded in this history. pub fn as_snapshot(&self) -> Option<Channel> { self.events().collect() diff --git a/src/message/app.rs b/src/message/app.rs index 3c74628..9792c8f 100644 --- a/src/message/app.rs +++ b/src/message/app.rs @@ -29,13 +29,17 @@ impl<'a> Messages<'a> { sent_at: &DateTime, body: &Body, ) -> Result<Message, SendError> { + let to_not_found = || SendError::ChannelNotFound(channel.clone()); + let to_deleted = || SendError::ChannelDeleted(channel.clone()); + let mut tx = self.db.begin().await?; - let channel = tx - .channels() - .by_id(channel) - .await - .not_found(|| SendError::ChannelNotFound(channel.clone()))?; + let channel = tx.channels().by_id(channel).await.not_found(to_not_found)?; + + // Ordering: don't bother allocating a sequence number before we know the channel might + // exist. let sent = tx.sequence().next(sent_at).await?; + let channel = channel.as_of(sent).ok_or_else(to_deleted)?; + let message = tx.messages().create(&channel, sender, &sent, body).await?; tx.commit().await?; @@ -126,6 +130,8 @@ impl<'a> Messages<'a> { pub enum SendError { #[error("channel {0} not found")] ChannelNotFound(channel::Id), + #[error("channel {0} deleted")] + ChannelDeleted(channel::Id), #[error(transparent)] Database(#[from] sqlx::Error), #[error(transparent)] diff --git a/src/message/repo.rs b/src/message/repo.rs index 9a4f72f..e753134 100644 --- a/src/message/repo.rs +++ b/src/message/repo.rs @@ -2,7 +2,7 @@ use sqlx::{SqliteConnection, Transaction, sqlite::Sqlite}; use super::{Body, History, Id, snapshot::Message}; use crate::{ - channel, + channel::{self, Channel}, clock::DateTime, event::{Instant, Sequence}, user::{self, User}, @@ -23,13 +23,12 @@ pub struct Messages<'t>(&'t mut SqliteConnection); impl Messages<'_> { pub async fn create( &mut self, - channel: &channel::History, + channel: &Channel, sender: &User, sent: &Instant, body: &Body, ) -> Result<History, sqlx::Error> { let id = Id::generate(); - let channel_id = channel.id(); let message = sqlx::query!( r#" @@ -45,7 +44,7 @@ impl Messages<'_> { body as "body: Body" "#, id, - channel_id, + channel.id, sender.id, sent.at, sent.sequence, |
