From d7aaed9e001ff30b2b2fed9f0c23a115709bfb44 Mon Sep 17 00:00:00 2001 From: projectmoon Date: Sat, 7 Nov 2020 20:47:49 +0000 Subject: [PATCH] Implement room clearing, log to info for member updates. --- src/bot/event_handlers.rs | 6 ++-- src/db/rooms.rs | 76 +++++++++++++++++++++++++++++++++++---- 2 files changed, 72 insertions(+), 10 deletions(-) diff --git a/src/bot/event_handlers.rs b/src/bot/event_handlers.rs index 526bb64..f115a39 100644 --- a/src/bot/event_handlers.rs +++ b/src/bot/event_handlers.rs @@ -100,13 +100,13 @@ impl EventEmitter for DiceBot { let (room_id, username) = (room.room_id.as_str(), &room_member.state_key); let result = if event_affects_us && !adding_user { - debug!("Clearing all information for room ID {}", room_id); + info!("Clearing all information for room ID {}", room_id); self.db.rooms.clear_info(room_id) } else if !event_affects_us && adding_user { - debug!("Adding {} to room ID {}", username, room_id); + info!("Adding user {} to room ID {}", username, room_id); self.db.rooms.add_user_to_room(username, room_id) } else if !event_affects_us && !adding_user { - debug!("Removing {} from room ID {}", username, room_id); + info!("Removing user {} from room ID {}", username, room_id); self.db.rooms.remove_user_from_room(username, room_id) } else { debug!("Ignoring a room member event: {:#?}", room_member); diff --git a/src/db/rooms.rs b/src/db/rooms.rs index 9eb8249..c80db5a 100644 --- a/src/db/rooms.rs +++ b/src/db/rooms.rs @@ -17,6 +17,7 @@ pub struct Rooms { pub(in crate::db) username_roomids: Tree, } +#[derive(Clone, Copy)] enum TxableTree<'a> { Tree(&'a Tree), Tx(&'a TransactionalTree), @@ -45,6 +46,17 @@ fn get_set<'a, T: Into>>(tree: T, key: &[u8]) -> Result> + Copy>( + tree: T, + key: &[u8], + value_to_remove: &str, +) -> Result<(), DataError> { + let mut set = get_set(tree, key)?; + set.remove(value_to_remove); + insert_set(tree, key, set)?; + Ok(()) +} + fn insert_set<'a, T: Into>>( tree: T, key: &[u8], @@ -115,13 +127,25 @@ impl Rooms { Ok(()) } - pub fn clear_info(&self, _room_id: &str) -> Result<(), DataError> { - //TODO implement me - //when bot leaves a room, it must, atomically: - // - delete roominfo struct from room info tree. - // - load list of users it knows about in room. - // - remove room id from every user's list. (cannot reuse existing fn because atomicity) - // - delete list of users in room from tree. + pub fn clear_info(&self, room_id: &str) -> Result<(), DataError> { + (&self.username_roomids, &self.roomid_usernames).transaction( + |(tx_username_roomids, tx_roomid_usernames)| { + let roomid_key = room_id.as_bytes(); + let users_in_room = get_set(tx_roomid_usernames, roomid_key)?; + + //Remove the room ID from every user's room ID list. + for username in users_in_room { + remove_from_set(tx_username_roomids, username.as_bytes(), room_id)?; + } + + //Remove this room entry for the room ID -> username tree. + tx_roomid_usernames.remove(roomid_key)?; + + //TODO: delete roominfo struct from room info tree. + Ok(()) + }, + )?; + Ok(()) } } @@ -184,4 +208,42 @@ mod tests { assert_eq!(HashSet::new(), users_in_room); assert_eq!(HashSet::new(), rooms_for_user); } + + #[test] + fn clear_info() { + let rooms = create_test_instance(); + rooms + .add_user_to_room("testuser", "myroom1") + .expect("Could not add user to room1"); + + rooms + .add_user_to_room("testuser", "myroom2") + .expect("Could not add user to room2"); + + rooms + .clear_info("myroom1") + .expect("Could not clear room info"); + + let users_in_room1 = rooms + .get_users_in_room("myroom1") + .expect("Could not retrieve users in room1"); + + let users_in_room2 = rooms + .get_users_in_room("myroom2") + .expect("Could not retrieve users in room2"); + + let rooms_for_user = rooms + .get_rooms_for_user("testuser") + .expect("Could not get rooms for user"); + + let expected_users_in_room2: HashSet = + vec![String::from("testuser")].into_iter().collect(); + + let expected_rooms_for_user: HashSet = + vec![String::from("myroom2")].into_iter().collect(); + + assert_eq!(HashSet::new(), users_in_room1); + assert_eq!(expected_users_in_room2, users_in_room2); + assert_eq!(expected_rooms_for_user, rooms_for_user); + } }