diff --git a/kordophone-db/src/repository.rs b/kordophone-db/src/repository.rs index 468ed68..8189d62 100644 --- a/kordophone-db/src/repository.rs +++ b/kordophone-db/src/repository.rs @@ -222,6 +222,18 @@ impl<'a> Repository<'a> { Ok(message_record.map(|r| r.into())) } + pub fn delete_all_conversations(&mut self) -> Result<()> { + use crate::schema::conversations::dsl::*; + diesel::delete(conversations).execute(self.connection)?; + Ok(()) + } + + pub fn delete_all_messages(&mut self) -> Result<()> { + use crate::schema::messages::dsl::*; + diesel::delete(messages).execute(self.connection)?; + Ok(()) + } + // Helper function to get the last inserted row ID // This is a workaround since the Sqlite backend doesn't support `RETURNING` // Huge caveat with this is that it depends on whatever the last insert was, prevents concurrent inserts. diff --git a/kordophoned/include/net.buzzert.kordophonecd.Server.xml b/kordophoned/include/net.buzzert.kordophonecd.Server.xml index bbe5263..37ad35f 100644 --- a/kordophoned/include/net.buzzert.kordophonecd.Server.xml +++ b/kordophoned/include/net.buzzert.kordophonecd.Server.xml @@ -40,6 +40,11 @@ value="Emitted when the list of conversations is updated."/> + + + + diff --git a/kordophoned/src/daemon/events.rs b/kordophoned/src/daemon/events.rs index b7839cb..97427e9 100644 --- a/kordophoned/src/daemon/events.rs +++ b/kordophoned/src/daemon/events.rs @@ -29,6 +29,9 @@ pub enum Event { /// - conversation_id: The ID of the conversation to get messages for. /// - last_message_id: (optional) The ID of the last message to get. If None, all messages are returned. GetMessages(String, Option, Reply>), + + /// Delete all conversations from the database. + DeleteAllConversations(Reply<()>), } diff --git a/kordophoned/src/daemon/mod.rs b/kordophoned/src/daemon/mod.rs index 4528f40..a7f9997 100644 --- a/kordophoned/src/daemon/mod.rs +++ b/kordophoned/src/daemon/mod.rs @@ -206,6 +206,15 @@ impl Daemon { let messages = self.get_messages(conversation_id, last_message_id).await; reply.send(messages).unwrap(); }, + + Event::DeleteAllConversations(reply) => { + self.delete_all_conversations().await + .unwrap_or_else(|e| { + log::error!("Failed to delete all conversations: {}", e); + }); + + reply.send(()).unwrap(); + }, } } @@ -313,6 +322,18 @@ impl Daemon { Ok(client) } + async fn delete_all_conversations(&mut self) -> Result<()> { + self.database.with_repository(|r| -> Result<()> { + r.delete_all_conversations()?; + r.delete_all_messages()?; + Ok(()) + }).await?; + + self.signal_sender.send(Signal::ConversationsUpdated).await?; + + Ok(()) + } + fn get_database_path() -> PathBuf { if let Some(proj_dirs) = ProjectDirs::from("net", "buzzert", "kordophonecd") { let data_dir = proj_dirs.data_dir(); diff --git a/kordophoned/src/dbus/server_impl.rs b/kordophoned/src/dbus/server_impl.rs index 25a1f3c..04632e2 100644 --- a/kordophoned/src/dbus/server_impl.rs +++ b/kordophoned/src/dbus/server_impl.rs @@ -99,6 +99,10 @@ impl DbusRepository for ServerImpl { }).collect() }) } + + fn delete_all_conversations(&mut self) -> Result<(), dbus::MethodErr> { + self.send_event_sync(Event::DeleteAllConversations) + } } impl DbusSettings for ServerImpl { diff --git a/kpcli/src/daemon/mod.rs b/kpcli/src/daemon/mod.rs index 561c60a..2212f8b 100644 --- a/kpcli/src/daemon/mod.rs +++ b/kpcli/src/daemon/mod.rs @@ -42,6 +42,9 @@ pub enum Commands { conversation_id: String, last_message_id: Option, }, + + /// Deletes all conversations. + DeleteAllConversations, } #[derive(Subcommand)] @@ -75,6 +78,7 @@ impl Commands { Commands::Config { command } => client.config(command).await, Commands::Signals => client.wait_for_signals().await, Commands::Messages { conversation_id, last_message_id } => client.print_messages(conversation_id, last_message_id).await, + Commands::DeleteAllConversations => client.delete_all_conversations().await, } } } @@ -188,4 +192,8 @@ impl DaemonCli { .map_err(|e| anyhow::anyhow!("Failed to set credential item: {}", e)) } + pub async fn delete_all_conversations(&mut self) -> Result<()> { + KordophoneRepository::delete_all_conversations(&self.proxy()) + .map_err(|e| anyhow::anyhow!("Failed to delete all conversations: {}", e)) + } } \ No newline at end of file