summaryrefslogtreecommitdiff
path: root/src/repo/sequence.rs
diff options
context:
space:
mode:
authorOwen Jacobson <owen@grimoire.ca>2024-10-01 22:30:04 -0400
committerOwen Jacobson <owen@grimoire.ca>2024-10-01 22:43:14 -0400
commitb8392a5fe824eff46f912a58885546e7b0f37e6f (patch)
treeff4061bbf4be30c53f84c179f86e8e6ab584dbda /src/repo/sequence.rs
parent7645411bcf7201e3a4927566da78080dc6a84ccf (diff)
Track event sequences globally, not per channel.
Per-channel event sequences were a cute idea, but it made reasoning about event resumption much, much harder (case in point: recovering the order of events in a partially-ordered collection is quadratic, since it's basically graph sort). The minor overhead of a global sequence number is likely tolerable, and this simplifies both the API and the internals.
Diffstat (limited to 'src/repo/sequence.rs')
-rw-r--r--src/repo/sequence.rs45
1 files changed, 45 insertions, 0 deletions
diff --git a/src/repo/sequence.rs b/src/repo/sequence.rs
new file mode 100644
index 0000000..8fe9dab
--- /dev/null
+++ b/src/repo/sequence.rs
@@ -0,0 +1,45 @@
+use sqlx::{sqlite::Sqlite, SqliteConnection, Transaction};
+
+pub trait Provider {
+ fn sequence(&mut self) -> Sequences;
+}
+
+impl<'c> Provider for Transaction<'c, Sqlite> {
+ fn sequence(&mut self) -> Sequences {
+ Sequences(self)
+ }
+}
+
+#[derive(
+ Clone,
+ Copy,
+ Debug,
+ Eq,
+ Ord,
+ PartialEq,
+ PartialOrd,
+ serde::Deserialize,
+ serde::Serialize,
+ sqlx::Type,
+)]
+#[serde(transparent)]
+#[sqlx(transparent)]
+pub struct Sequence(i64);
+
+pub struct Sequences<'t>(&'t mut SqliteConnection);
+
+impl<'c> Sequences<'c> {
+ pub async fn next(&mut self) -> Result<Sequence, sqlx::Error> {
+ let next = sqlx::query_scalar!(
+ r#"
+ update event_sequence
+ set last_value = last_value + 1
+ returning last_value as "next_value: Sequence"
+ "#,
+ )
+ .fetch_one(&mut *self.0)
+ .await?;
+
+ Ok(next)
+ }
+}