From 6c26f62008beed9b7f16808dca7bd770168a2896 Mon Sep 17 00:00:00 2001 From: Joscha Date: Sun, 26 Jun 2022 15:56:51 +0200 Subject: [PATCH] Create room table for easier room deletion --- src/euph/room.rs | 1 + src/vault/euph.rs | 52 +++++++++++++++++++++++++++++++++++++++++++- src/vault/migrate.rs | 13 +++++++---- 3 files changed, 61 insertions(+), 5 deletions(-) diff --git a/src/euph/room.rs b/src/euph/room.rs index a7badb8..3be5ec8 100644 --- a/src/euph/room.rs +++ b/src/euph/room.rs @@ -167,6 +167,7 @@ impl State { } Data::SnapshotEvent(d) => { info!("e&{}: successfully joined", self.name); + self.vault.join(); self.last_msg_id = Some(d.log.last().map(|m| m.id)); self.vault.add_messages(d.log, None); let _ = self.ui_event_tx.send(UiEvent::Redraw); diff --git a/src/vault/euph.rs b/src/vault/euph.rs index 89d2606..d796826 100644 --- a/src/vault/euph.rs +++ b/src/vault/euph.rs @@ -9,7 +9,7 @@ use tokio::sync::{mpsc, oneshot}; use crate::euph::api::{Message, Snowflake, Time}; use crate::store::{Msg, MsgStore, Path, Tree}; -use super::Request; +use super::{Request, Vault}; impl ToSql for Snowflake { fn to_sql(&self) -> rusqlite::Result> { @@ -76,6 +76,16 @@ impl From for Request { } } +impl Vault { + pub async fn euph_rooms(&self) -> Vec { + // TODO vault::Error + let (tx, rx) = oneshot::channel(); + let request = EuphRequest::Rooms { result: tx }; + let _ = self.tx.send(request.into()); + rx.await.unwrap() + } +} + #[derive(Debug, Clone)] pub struct EuphVault { pub(super) tx: mpsc::UnboundedSender, @@ -83,6 +93,13 @@ pub struct EuphVault { } impl EuphVault { + pub fn join(&self) { + let request = EuphRequest::Join { + room: self.room.clone(), + }; + let _ = self.tx.send(request.into()); + } + pub fn add_message(&self, msg: Message, prev_msg: Option) { let request = EuphRequest::AddMsg { room: self.room.clone(), @@ -187,6 +204,12 @@ impl MsgStore for EuphVault { } pub(super) enum EuphRequest { + Rooms { + result: oneshot::Sender>, + }, + Join { + room: String, + }, AddMsg { room: String, msg: Message, @@ -234,6 +257,8 @@ pub(super) enum EuphRequest { impl EuphRequest { pub(super) fn perform(self, conn: &mut Connection) { let result = match self { + EuphRequest::Rooms { result } => Self::rooms(conn, result), + EuphRequest::Join { room } => Self::join(conn, room), EuphRequest::AddMsg { room, msg, @@ -265,6 +290,31 @@ impl EuphRequest { } } + fn rooms(conn: &mut Connection, result: oneshot::Sender>) -> rusqlite::Result<()> { + let rooms = conn + .prepare( + " + SELECT room + FROM euph_rooms + ", + )? + .query_map([], |row| row.get(0))? + .collect::>()?; + let _ = result.send(rooms); + Ok(()) + } + + fn join(conn: &mut Connection, room: String) -> rusqlite::Result<()> { + conn.execute( + " + INSERT INTO euph_rooms (room) + VALUES (?) + ", + [room], + )?; + Ok(()) + } + fn insert_msgs(tx: &Transaction, room: &str, msgs: Vec) -> rusqlite::Result<()> { let mut insert_msg = tx.prepare( " diff --git a/src/vault/migrate.rs b/src/vault/migrate.rs index 0348e8c..14e4516 100644 --- a/src/vault/migrate.rs +++ b/src/vault/migrate.rs @@ -21,6 +21,10 @@ const MIGRATIONS: [fn(&mut Transaction) -> rusqlite::Result<()>; 1] = [m1]; fn m1(tx: &mut Transaction) -> rusqlite::Result<()> { tx.execute_batch( " + CREATE TABLE euph_rooms ( + room TEXT NOT NULL PRIMARY KEY + ) STRICT; + CREATE TABLE euph_msgs ( -- Message room TEXT NOT NULL, @@ -45,7 +49,9 @@ fn m1(tx: &mut Transaction) -> rusqlite::Result<()> { client_address TEXT, real_client_address TEXT, - PRIMARY KEY (room, id) + PRIMARY KEY (room, id), + FOREIGN KEY (room) REFERENCES euph_rooms (room) + ON DELETE CASCADE ) STRICT; CREATE TABLE euph_spans ( @@ -54,9 +60,8 @@ fn m1(tx: &mut Transaction) -> rusqlite::Result<()> { end INT, UNIQUE (room, start, end), - FOREIGN KEY (room, start) REFERENCES euph_msgs (room, id), - FOREIGN KEY (room, end) REFERENCES euph_msgs (room, id), - + FOREIGN KEY (room) REFERENCES euph_rooms (room) + ON DELETE CASCADE, CHECK (start IS NULL OR end IS NOT NULL) ) STRICT;