conduwuit/src/database/key_value/rooms/user.rs

150 lines
5.2 KiB
Rust
Raw Normal View History

2022-10-09 17:25:06 +02:00
use ruma::{OwnedRoomId, OwnedUserId, RoomId, UserId};
2022-10-05 20:34:31 +02:00
use crate::{database::KeyValueDatabase, service, services, utils, Error, Result};
2022-10-05 18:36:12 +02:00
impl service::rooms::user::Data for KeyValueDatabase {
fn reset_notification_counts(&self, user_id: &UserId, room_id: &RoomId) -> Result<()> {
let mut userroom_id = user_id.as_bytes().to_vec();
userroom_id.push(0xff);
userroom_id.extend_from_slice(room_id.as_bytes());
let mut roomuser_id = room_id.as_bytes().to_vec();
roomuser_id.push(0xff);
roomuser_id.extend_from_slice(user_id.as_bytes());
2022-06-19 22:56:14 +02:00
self.userroomid_notificationcount
.insert(&userroom_id, &0_u64.to_be_bytes())?;
self.userroomid_highlightcount
2022-06-19 22:56:14 +02:00
.insert(&userroom_id, &0_u64.to_be_bytes())?;
2021-04-13 15:00:45 +02:00
self.roomuserid_lastnotificationread.insert(
&roomuser_id,
&services().globals.next_count()?.to_be_bytes(),
)?;
2021-04-13 15:00:45 +02:00
Ok(())
}
fn notification_count(&self, user_id: &UserId, room_id: &RoomId) -> Result<u64> {
let mut userroom_id = user_id.as_bytes().to_vec();
userroom_id.push(0xff);
userroom_id.extend_from_slice(room_id.as_bytes());
2022-06-19 22:56:14 +02:00
self.userroomid_notificationcount
.get(&userroom_id)?
.map(|bytes| {
2022-06-19 22:56:14 +02:00
utils::u64_from_bytes(&bytes)
.map_err(|_| Error::bad_database("Invalid notification count in db."))
2020-05-25 23:24:13 +02:00
})
2022-06-19 22:56:14 +02:00
.unwrap_or(Ok(0))
2020-05-25 23:24:13 +02:00
}
fn highlight_count(&self, user_id: &UserId, room_id: &RoomId) -> Result<u64> {
2022-06-19 22:56:14 +02:00
let mut userroom_id = user_id.as_bytes().to_vec();
userroom_id.push(0xff);
userroom_id.extend_from_slice(room_id.as_bytes());
2022-06-19 22:56:14 +02:00
self.userroomid_highlightcount
.get(&userroom_id)?
.map(|bytes| {
utils::u64_from_bytes(&bytes)
.map_err(|_| Error::bad_database("Invalid highlight count in db."))
})
.unwrap_or(Ok(0))
}
fn last_notification_read(&self, user_id: &UserId, room_id: &RoomId) -> Result<u64> {
let mut key = room_id.as_bytes().to_vec();
key.push(0xff);
key.extend_from_slice(user_id.as_bytes());
Ok(self
.roomuserid_lastnotificationread
.get(&key)?
.map(|bytes| {
utils::u64_from_bytes(&bytes).map_err(|_| {
Error::bad_database("Count in roomuserid_lastprivatereadupdate is invalid.")
})
})
.transpose()?
.unwrap_or(0))
}
fn associate_token_shortstatehash(
2022-06-19 22:56:14 +02:00
&self,
2020-08-18 12:15:27 +02:00
room_id: &RoomId,
2022-06-19 22:56:14 +02:00
token: u64,
shortstatehash: u64,
) -> Result<()> {
2022-10-05 20:34:31 +02:00
let shortroomid = services()
.rooms
.short
.get_shortroomid(room_id)?
.expect("room exists");
2020-08-18 12:15:27 +02:00
2022-06-19 22:56:14 +02:00
let mut key = shortroomid.to_be_bytes().to_vec();
key.extend_from_slice(&token.to_be_bytes());
2020-08-18 12:15:27 +02:00
2022-06-19 22:56:14 +02:00
self.roomsynctoken_shortstatehash
.insert(&key, &shortstatehash.to_be_bytes())
}
fn get_token_shortstatehash(&self, room_id: &RoomId, token: u64) -> Result<Option<u64>> {
2022-10-05 20:34:31 +02:00
let shortroomid = services()
.rooms
.short
.get_shortroomid(room_id)?
.expect("room exists");
2022-06-19 22:56:14 +02:00
let mut key = shortroomid.to_be_bytes().to_vec();
key.extend_from_slice(&token.to_be_bytes());
2020-08-18 12:15:27 +02:00
2022-06-19 22:56:14 +02:00
self.roomsynctoken_shortstatehash
.get(&key)?
.map(|bytes| {
utils::u64_from_bytes(&bytes).map_err(|_| {
Error::bad_database("Invalid shortstatehash in roomsynctoken_shortstatehash")
})
})
.transpose()
}
2020-08-18 12:15:27 +02:00
fn get_shared_rooms<'a>(
&'a self,
2022-10-09 17:25:06 +02:00
users: Vec<OwnedUserId>,
) -> Result<Box<dyn Iterator<Item = Result<OwnedRoomId>> + 'a>> {
2021-06-17 20:34:14 +02:00
let iterators = users.into_iter().map(move |user_id| {
let mut prefix = user_id.as_bytes().to_vec();
prefix.push(0xff);
self.userroomid_joined
.scan_prefix(prefix)
.map(|(key, _)| {
let roomid_index = key
.iter()
.enumerate()
.find(|(_, &b)| b == 0xff)
.ok_or_else(|| Error::bad_database("Invalid userroomid_joined in db."))?
.0
+ 1; // +1 because the room id starts AFTER the separator
let room_id = key[roomid_index..].to_vec();
Ok::<_, Error>(room_id)
})
.filter_map(std::result::Result::ok)
2021-06-17 20:34:14 +02:00
});
// We use the default compare function because keys are sorted correctly (not reversed)
2022-10-09 17:25:06 +02:00
Ok(Box::new(
2022-10-05 20:34:31 +02:00
utils::common_elements(iterators, Ord::cmp)
.expect("users is not empty")
.map(|bytes| {
2022-10-10 14:09:11 +02:00
RoomId::parse(utils::string_from_bytes(&bytes).map_err(|_| {
2022-10-05 20:34:31 +02:00
Error::bad_database("Invalid RoomId bytes in userroomid_joined")
})?)
.map_err(|_| Error::bad_database("Invalid RoomId in userroomid_joined."))
}),
2022-10-09 17:25:06 +02:00
))
2020-08-18 12:15:27 +02:00
}
}