diff --git a/crates/matrix-sdk-base/src/store/memory_store.rs b/crates/matrix-sdk-base/src/store/memory_store.rs index dbd2a16bc..b69a41ef8 100644 --- a/crates/matrix-sdk-base/src/store/memory_store.rs +++ b/crates/matrix-sdk-base/src/store/memory_store.rs @@ -438,6 +438,24 @@ impl MemoryStore { Ok(()) } + + async fn remove_room(&self, room_id: &RoomId) -> Result<()> { + self.members.remove(room_id); + self.profiles.remove(room_id); + self.display_names.remove(room_id); + self.joined_user_ids.remove(room_id); + self.invited_user_ids.remove(room_id); + self.room_info.remove(room_id); + self.room_state.remove(room_id); + self.room_account_data.remove(room_id); + self.stripped_room_info.remove(room_id); + self.stripped_room_state.remove(room_id); + self.stripped_members.remove(room_id); + self.room_user_receipts.remove(room_id); + self.room_event_receipts.remove(room_id); + + Ok(()) + } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] @@ -584,6 +602,10 @@ impl StateStore for MemoryStore { async fn remove_media_content_for_uri(&self, uri: &MxcUri) -> Result<()> { self.remove_media_content_for_uri(uri).await } + + async fn remove_room(&self, room_id: &RoomId) -> Result<()> { + self.remove_room(room_id).await + } } #[cfg(test)] diff --git a/crates/matrix-sdk-base/src/store/mod.rs b/crates/matrix-sdk-base/src/store/mod.rs index 6a0482486..7cb1c2ef3 100644 --- a/crates/matrix-sdk-base/src/store/mod.rs +++ b/crates/matrix-sdk-base/src/store/mod.rs @@ -313,6 +313,13 @@ pub trait StateStore: AsyncTraitDeps { /// /// * `uri` - The `MxcUri` of the media files. async fn remove_media_content_for_uri(&self, uri: &MxcUri) -> Result<()>; + + /// Removes a room and all elements associated from the state store. + /// + /// # Arguments + /// + /// * `room_id` - The `RoomId` of the room to delete. + async fn remove_room(&self, room_id: &RoomId) -> Result<()>; } /// A state store wrapper for the SDK. diff --git a/crates/matrix-sdk-base/src/store/sled_store/mod.rs b/crates/matrix-sdk-base/src/store/sled_store/mod.rs index 565776ff4..9f0c5fae6 100644 --- a/crates/matrix-sdk-base/src/store/sled_store/mod.rs +++ b/crates/matrix-sdk-base/src/store/sled_store/mod.rs @@ -846,6 +846,121 @@ impl SledStore { Ok(self.media.apply_batch(batch)?) } + + async fn remove_room(&self, room_id: &RoomId) -> Result<()> { + let room_key = room_id.encode(); + + let mut members_batch = sled::Batch::default(); + for key in self.members.scan_prefix(room_key.as_slice()).keys() { + members_batch.remove(key?) + } + + let mut profiles_batch = sled::Batch::default(); + for key in self.profiles.scan_prefix(room_key.as_slice()).keys() { + profiles_batch.remove(key?) + } + + let mut display_names_batch = sled::Batch::default(); + for key in self.display_names.scan_prefix(room_key.as_slice()).keys() { + display_names_batch.remove(key?) + } + + let mut joined_user_ids_batch = sled::Batch::default(); + for key in self.joined_user_ids.scan_prefix(room_key.as_slice()).keys() { + joined_user_ids_batch.remove(key?) + } + + let mut invited_user_ids_batch = sled::Batch::default(); + for key in self.invited_user_ids.scan_prefix(room_key.as_slice()).keys() { + invited_user_ids_batch.remove(key?) + } + + let mut room_state_batch = sled::Batch::default(); + for key in self.room_state.scan_prefix(room_key.as_slice()).keys() { + room_state_batch.remove(key?) + } + + let mut room_account_data_batch = sled::Batch::default(); + for key in self.room_account_data.scan_prefix(room_key.as_slice()).keys() { + room_account_data_batch.remove(key?) + } + + let mut stripped_members_batch = sled::Batch::default(); + for key in self.stripped_members.scan_prefix(room_key.as_slice()).keys() { + stripped_members_batch.remove(key?) + } + + let mut stripped_room_state_batch = sled::Batch::default(); + for key in self.stripped_room_state.scan_prefix(room_key.as_slice()).keys() { + stripped_room_state_batch.remove(key?) + } + + let mut room_user_receipts_batch = sled::Batch::default(); + for key in self.room_user_receipts.scan_prefix(room_key.as_slice()).keys() { + room_user_receipts_batch.remove(key?) + } + + let mut room_event_receipts_batch = sled::Batch::default(); + for key in self.room_event_receipts.scan_prefix(room_key.as_slice()).keys() { + room_event_receipts_batch.remove(key?) + } + + let ret: Result<(), TransactionError> = ( + &self.members, + &self.profiles, + &self.display_names, + &self.joined_user_ids, + &self.invited_user_ids, + &self.room_info, + &self.room_state, + &self.room_account_data, + &self.stripped_room_info, + &self.stripped_members, + &self.stripped_room_state, + &self.room_user_receipts, + &self.room_event_receipts, + ) + .transaction( + |( + members, + profiles, + display_names, + joined, + invited, + rooms, + state, + room_account_data, + stripped_rooms, + stripped_members, + stripped_state, + room_user_receipts, + room_event_receipts, + )| { + rooms.remove(room_key.as_slice())?; + stripped_rooms.remove(room_key.as_slice())?; + + members.apply_batch(&members_batch)?; + profiles.apply_batch(&profiles_batch)?; + display_names.apply_batch(&display_names_batch)?; + joined.apply_batch(&joined_user_ids_batch)?; + invited.apply_batch(&invited_user_ids_batch)?; + state.apply_batch(&room_state_batch)?; + room_account_data.apply_batch(&room_account_data_batch)?; + stripped_members.apply_batch(&stripped_members_batch)?; + stripped_state.apply_batch(&stripped_room_state_batch)?; + room_user_receipts.apply_batch(&room_user_receipts_batch)?; + room_event_receipts.apply_batch(&room_event_receipts_batch)?; + + Ok(()) + }, + ); + + ret?; + + self.inner.flush_async().await?; + + Ok(()) + } } #[async_trait] @@ -987,6 +1102,10 @@ impl StateStore for SledStore { async fn remove_media_content_for_uri(&self, uri: &MxcUri) -> Result<()> { self.remove_media_content_for_uri(uri).await } + + async fn remove_room(&self, room_id: &RoomId) -> Result<()> { + self.remove_room(room_id).await + } } #[cfg(test)] diff --git a/crates/matrix-sdk/src/room/left.rs b/crates/matrix-sdk/src/room/left.rs index 3adeba91c..59f56e8f2 100644 --- a/crates/matrix-sdk/src/room/left.rs +++ b/crates/matrix-sdk/src/room/left.rs @@ -42,6 +42,7 @@ impl Left { pub async fn forget(&self) -> Result<()> { let request = forget_room::Request::new(self.inner.room_id()); let _response = self.client.send(request, None).await?; + self.client.store().remove_room(self.inner.room_id()).await?; Ok(()) }