diff --git a/src/logger.rs b/src/logger.rs index 7a80295..6528591 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -85,6 +85,15 @@ impl MsgStore for Logger { Tree::new(*tree_id, msgs) } + async fn first_tree_id(&self) -> Option { + let empty = self.messages.lock().is_empty(); + Some(0).filter(|_| !empty) + } + + async fn last_tree_id(&self) -> Option { + self.messages.lock().len().checked_sub(1) + } + async fn prev_tree_id(&self, tree_id: &usize) -> Option { tree_id.checked_sub(1) } @@ -94,13 +103,20 @@ impl MsgStore for Logger { tree_id.checked_add(1).filter(|t| *t < len) } - async fn first_tree_id(&self) -> Option { - let empty = self.messages.lock().is_empty(); - Some(0).filter(|_| !empty) + async fn oldest_msg_id(&self) -> Option { + self.first_tree_id().await } - async fn last_tree_id(&self) -> Option { - self.messages.lock().len().checked_sub(1) + async fn newest_msg_id(&self) -> Option { + self.last_tree_id().await + } + + async fn older_msg_id(&self, id: &usize) -> Option { + self.prev_tree_id(id).await + } + + async fn newer_msg_id(&self, id: &usize) -> Option { + self.next_tree_id(id).await } } diff --git a/src/store.rs b/src/store.rs index 457b92e..0952757 100644 --- a/src/store.rs +++ b/src/store.rs @@ -120,8 +120,12 @@ impl Tree { pub trait MsgStore { async fn path(&self, id: &M::Id) -> Path; async fn tree(&self, tree_id: &M::Id) -> Tree; - async fn prev_tree_id(&self, tree_id: &M::Id) -> Option; - async fn next_tree_id(&self, tree_id: &M::Id) -> Option; async fn first_tree_id(&self) -> Option; async fn last_tree_id(&self) -> Option; + async fn prev_tree_id(&self, tree_id: &M::Id) -> Option; + async fn next_tree_id(&self, tree_id: &M::Id) -> Option; + async fn oldest_msg_id(&self) -> Option; + async fn newest_msg_id(&self) -> Option; + async fn older_msg_id(&self, id: &M::Id) -> Option; + async fn newer_msg_id(&self, id: &M::Id) -> Option; } diff --git a/src/vault/euph.rs b/src/vault/euph.rs index 982e4a3..b56ddb9 100644 --- a/src/vault/euph.rs +++ b/src/vault/euph.rs @@ -155,6 +155,28 @@ impl MsgStore for EuphVault { rx.await.unwrap() } + async fn first_tree_id(&self) -> Option { + // TODO vault::Error + let (tx, rx) = oneshot::channel(); + let request = EuphRequest::GetFirstTreeId { + room: self.room.clone(), + result: tx, + }; + let _ = self.vault.tx.send(request.into()); + rx.await.unwrap() + } + + async fn last_tree_id(&self) -> Option { + // TODO vault::Error + let (tx, rx) = oneshot::channel(); + let request = EuphRequest::GetLastTreeId { + room: self.room.clone(), + result: tx, + }; + let _ = self.vault.tx.send(request.into()); + rx.await.unwrap() + } + async fn prev_tree_id(&self, tree_id: &Snowflake) -> Option { // TODO vault::Error let (tx, rx) = oneshot::channel(); @@ -179,10 +201,10 @@ impl MsgStore for EuphVault { rx.await.unwrap() } - async fn first_tree_id(&self) -> Option { + async fn oldest_msg_id(&self) -> Option { // TODO vault::Error let (tx, rx) = oneshot::channel(); - let request = EuphRequest::GetFirstTreeId { + let request = EuphRequest::GetOldestMsgId { room: self.room.clone(), result: tx, }; @@ -190,16 +212,40 @@ impl MsgStore for EuphVault { rx.await.unwrap() } - async fn last_tree_id(&self) -> Option { + async fn newest_msg_id(&self) -> Option { // TODO vault::Error let (tx, rx) = oneshot::channel(); - let request = EuphRequest::GetLastTreeId { + let request = EuphRequest::GetNewestMsgId { room: self.room.clone(), result: tx, }; let _ = self.vault.tx.send(request.into()); rx.await.unwrap() } + + async fn older_msg_id(&self, id: &Snowflake) -> Option { + // TODO vault::Error + let (tx, rx) = oneshot::channel(); + let request = EuphRequest::GetOlderMsgId { + room: self.room.clone(), + id: *id, + result: tx, + }; + let _ = self.vault.tx.send(request.into()); + rx.await.unwrap() + } + + async fn newer_msg_id(&self, id: &Snowflake) -> Option { + // TODO vault::Error + let (tx, rx) = oneshot::channel(); + let request = EuphRequest::GetNewerMsgId { + room: self.room.clone(), + id: *id, + result: tx, + }; + let _ = self.vault.tx.send(request.into()); + rx.await.unwrap() + } } pub(super) enum EuphRequest { @@ -254,6 +300,14 @@ pub(super) enum EuphRequest { root: Snowflake, result: oneshot::Sender>, }, + GetFirstTreeId { + room: String, + result: oneshot::Sender>, + }, + GetLastTreeId { + room: String, + result: oneshot::Sender>, + }, GetPrevTreeId { room: String, root: Snowflake, @@ -264,14 +318,24 @@ pub(super) enum EuphRequest { root: Snowflake, result: oneshot::Sender>, }, - GetFirstTreeId { + GetOldestMsgId { room: String, result: oneshot::Sender>, }, - GetLastTreeId { + GetNewestMsgId { room: String, result: oneshot::Sender>, }, + GetOlderMsgId { + room: String, + id: Snowflake, + result: oneshot::Sender>, + }, + GetNewerMsgId { + room: String, + id: Snowflake, + result: oneshot::Sender>, + }, } impl EuphRequest { @@ -295,17 +359,29 @@ impl EuphRequest { EuphRequest::GetLastSpan { room, result } => Self::get_last_span(conn, room, result), EuphRequest::GetPath { room, id, result } => Self::get_path(conn, room, id, result), EuphRequest::GetTree { room, root, result } => Self::get_tree(conn, room, root, result), + EuphRequest::GetFirstTreeId { room, result } => { + Self::get_first_tree_id(conn, room, result) + } + EuphRequest::GetLastTreeId { room, result } => { + Self::get_last_tree_id(conn, room, result) + } EuphRequest::GetPrevTreeId { room, root, result } => { Self::get_prev_tree_id(conn, room, root, result) } EuphRequest::GetNextTreeId { room, root, result } => { Self::get_next_tree_id(conn, room, root, result) } - EuphRequest::GetFirstTreeId { room, result } => { - Self::get_first_tree_id(conn, room, result) + EuphRequest::GetOldestMsgId { room, result } => { + Self::get_oldest_msg_id(conn, room, result) } - EuphRequest::GetLastTreeId { room, result } => { - Self::get_last_tree_id(conn, room, result) + EuphRequest::GetNewestMsgId { room, result } => { + Self::get_newest_msg_id(conn, room, result) + } + EuphRequest::GetOlderMsgId { room, id, result } => { + Self::get_older_msg_id(conn, room, id, result) + } + EuphRequest::GetNewerMsgId { room, id, result } => { + Self::get_newer_msg_id(conn, room, id, result) } }; if let Err(e) = result { @@ -679,6 +755,48 @@ impl EuphRequest { Ok(()) } + fn get_first_tree_id( + conn: &Connection, + room: String, + result: oneshot::Sender>, + ) -> rusqlite::Result<()> { + let tree = conn + .prepare( + " + SELECT id + FROM euph_trees + WHERE room = ? + ORDER BY id ASC + LIMIT 1 + ", + )? + .query_row([room], |row| row.get(0)) + .optional()?; + let _ = result.send(tree); + Ok(()) + } + + fn get_last_tree_id( + conn: &Connection, + room: String, + result: oneshot::Sender>, + ) -> rusqlite::Result<()> { + let tree = conn + .prepare( + " + SELECT id + FROM euph_trees + WHERE room = ? + ORDER BY id DESC + LIMIT 1 + ", + )? + .query_row([room], |row| row.get(0)) + .optional()?; + let _ = result.send(tree); + Ok(()) + } + fn get_prev_tree_id( conn: &Connection, room: String, @@ -725,7 +843,7 @@ impl EuphRequest { Ok(()) } - fn get_first_tree_id( + fn get_oldest_msg_id( conn: &Connection, room: String, result: oneshot::Sender>, @@ -734,7 +852,7 @@ impl EuphRequest { .prepare( " SELECT id - FROM euph_trees + FROM euph_msgs WHERE room = ? ORDER BY id ASC LIMIT 1 @@ -746,7 +864,7 @@ impl EuphRequest { Ok(()) } - fn get_last_tree_id( + fn get_newest_msg_id( conn: &Connection, room: String, result: oneshot::Sender>, @@ -755,7 +873,7 @@ impl EuphRequest { .prepare( " SELECT id - FROM euph_trees + FROM euph_msgs WHERE room = ? ORDER BY id DESC LIMIT 1 @@ -766,4 +884,50 @@ impl EuphRequest { let _ = result.send(tree); Ok(()) } + + fn get_older_msg_id( + conn: &Connection, + room: String, + id: Snowflake, + result: oneshot::Sender>, + ) -> rusqlite::Result<()> { + let tree = conn + .prepare( + " + SELECT id + FROM euph_msgs + WHERE room = ? + AND id < ? + ORDER BY id DESC + LIMIT 1 + ", + )? + .query_row(params![room, id], |row| row.get(0)) + .optional()?; + let _ = result.send(tree); + Ok(()) + } + + fn get_newer_msg_id( + conn: &Connection, + room: String, + id: Snowflake, + result: oneshot::Sender>, + ) -> rusqlite::Result<()> { + let tree = conn + .prepare( + " + SELECT id + FROM euph_msgs + WHERE room = ? + AND id > ? + ORDER BY id ASC + LIMIT 1 + ", + )? + .query_row(params![room, id], |row| row.get(0)) + .optional()?; + let _ = result.send(tree); + Ok(()) + } }