|
|
|
@ -19,8 +19,6 @@ use ruma::{ |
|
|
|
state_res::{self, Event, RoomVersion, StateMap}, |
|
|
|
state_res::{self, Event, RoomVersion, StateMap}, |
|
|
|
uint, EventId, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId, |
|
|
|
uint, EventId, RoomAliasId, RoomId, RoomVersionId, ServerName, UserId, |
|
|
|
}; |
|
|
|
}; |
|
|
|
use sled::IVec; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
use std::{ |
|
|
|
use std::{ |
|
|
|
collections::{BTreeMap, HashMap, HashSet}, |
|
|
|
collections::{BTreeMap, HashMap, HashSet}, |
|
|
|
convert::{TryFrom, TryInto}, |
|
|
|
convert::{TryFrom, TryInto}, |
|
|
|
@ -28,62 +26,61 @@ use std::{ |
|
|
|
sync::Arc, |
|
|
|
sync::Arc, |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
use super::{admin::AdminCommand, pusher}; |
|
|
|
use super::{abstraction::Tree, admin::AdminCommand, pusher}; |
|
|
|
|
|
|
|
|
|
|
|
/// The unique identifier of each state group.
|
|
|
|
/// The unique identifier of each state group.
|
|
|
|
///
|
|
|
|
///
|
|
|
|
/// This is created when a state group is added to the database by
|
|
|
|
/// This is created when a state group is added to the database by
|
|
|
|
/// hashing the entire state.
|
|
|
|
/// hashing the entire state.
|
|
|
|
pub type StateHashId = IVec; |
|
|
|
pub type StateHashId = Vec<u8>; |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Clone)] |
|
|
|
|
|
|
|
pub struct Rooms { |
|
|
|
pub struct Rooms { |
|
|
|
pub edus: edus::RoomEdus, |
|
|
|
pub edus: edus::RoomEdus, |
|
|
|
pub(super) pduid_pdu: sled::Tree, // PduId = RoomId + Count
|
|
|
|
pub(super) pduid_pdu: Arc<dyn Tree>, // PduId = RoomId + Count
|
|
|
|
pub(super) eventid_pduid: sled::Tree, |
|
|
|
pub(super) eventid_pduid: Arc<dyn Tree>, |
|
|
|
pub(super) roomid_pduleaves: sled::Tree, |
|
|
|
pub(super) roomid_pduleaves: Arc<dyn Tree>, |
|
|
|
pub(super) alias_roomid: sled::Tree, |
|
|
|
pub(super) alias_roomid: Arc<dyn Tree>, |
|
|
|
pub(super) aliasid_alias: sled::Tree, // AliasId = RoomId + Count
|
|
|
|
pub(super) aliasid_alias: Arc<dyn Tree>, // AliasId = RoomId + Count
|
|
|
|
pub(super) publicroomids: sled::Tree, |
|
|
|
pub(super) publicroomids: Arc<dyn Tree>, |
|
|
|
|
|
|
|
|
|
|
|
pub(super) tokenids: sled::Tree, // TokenId = RoomId + Token + PduId
|
|
|
|
pub(super) tokenids: Arc<dyn Tree>, // TokenId = RoomId + Token + PduId
|
|
|
|
|
|
|
|
|
|
|
|
/// Participating servers in a room.
|
|
|
|
/// Participating servers in a room.
|
|
|
|
pub(super) roomserverids: sled::Tree, // RoomServerId = RoomId + ServerName
|
|
|
|
pub(super) roomserverids: Arc<dyn Tree>, // RoomServerId = RoomId + ServerName
|
|
|
|
pub(super) serverroomids: sled::Tree, // ServerRoomId = ServerName + RoomId
|
|
|
|
pub(super) serverroomids: Arc<dyn Tree>, // ServerRoomId = ServerName + RoomId
|
|
|
|
|
|
|
|
|
|
|
|
pub(super) userroomid_joined: sled::Tree, |
|
|
|
pub(super) userroomid_joined: Arc<dyn Tree>, |
|
|
|
pub(super) roomuserid_joined: sled::Tree, |
|
|
|
pub(super) roomuserid_joined: Arc<dyn Tree>, |
|
|
|
pub(super) roomuseroncejoinedids: sled::Tree, |
|
|
|
pub(super) roomuseroncejoinedids: Arc<dyn Tree>, |
|
|
|
pub(super) userroomid_invitestate: sled::Tree, // InviteState = Vec<Raw<Pdu>>
|
|
|
|
pub(super) userroomid_invitestate: Arc<dyn Tree>, // InviteState = Vec<Raw<Pdu>>
|
|
|
|
pub(super) roomuserid_invitecount: sled::Tree, // InviteCount = Count
|
|
|
|
pub(super) roomuserid_invitecount: Arc<dyn Tree>, // InviteCount = Count
|
|
|
|
pub(super) userroomid_leftstate: sled::Tree, |
|
|
|
pub(super) userroomid_leftstate: Arc<dyn Tree>, |
|
|
|
pub(super) roomuserid_leftcount: sled::Tree, |
|
|
|
pub(super) roomuserid_leftcount: Arc<dyn Tree>, |
|
|
|
|
|
|
|
|
|
|
|
pub(super) userroomid_notificationcount: sled::Tree, // NotifyCount = u64
|
|
|
|
pub(super) userroomid_notificationcount: Arc<dyn Tree>, // NotifyCount = u64
|
|
|
|
pub(super) userroomid_highlightcount: sled::Tree, // HightlightCount = u64
|
|
|
|
pub(super) userroomid_highlightcount: Arc<dyn Tree>, // HightlightCount = u64
|
|
|
|
|
|
|
|
|
|
|
|
/// Remember the current state hash of a room.
|
|
|
|
/// Remember the current state hash of a room.
|
|
|
|
pub(super) roomid_shortstatehash: sled::Tree, |
|
|
|
pub(super) roomid_shortstatehash: Arc<dyn Tree>, |
|
|
|
/// Remember the state hash at events in the past.
|
|
|
|
/// Remember the state hash at events in the past.
|
|
|
|
pub(super) shorteventid_shortstatehash: sled::Tree, |
|
|
|
pub(super) shorteventid_shortstatehash: Arc<dyn Tree>, |
|
|
|
/// StateKey = EventType + StateKey, ShortStateKey = Count
|
|
|
|
/// StateKey = EventType + StateKey, ShortStateKey = Count
|
|
|
|
pub(super) statekey_shortstatekey: sled::Tree, |
|
|
|
pub(super) statekey_shortstatekey: Arc<dyn Tree>, |
|
|
|
pub(super) shorteventid_eventid: sled::Tree, |
|
|
|
pub(super) shorteventid_eventid: Arc<dyn Tree>, |
|
|
|
/// ShortEventId = Count
|
|
|
|
/// ShortEventId = Count
|
|
|
|
pub(super) eventid_shorteventid: sled::Tree, |
|
|
|
pub(super) eventid_shorteventid: Arc<dyn Tree>, |
|
|
|
/// ShortEventId = Count
|
|
|
|
/// ShortEventId = Count
|
|
|
|
pub(super) statehash_shortstatehash: sled::Tree, |
|
|
|
pub(super) statehash_shortstatehash: Arc<dyn Tree>, |
|
|
|
/// ShortStateHash = Count
|
|
|
|
/// ShortStateHash = Count
|
|
|
|
/// StateId = ShortStateHash + ShortStateKey
|
|
|
|
/// StateId = ShortStateHash + ShortStateKey
|
|
|
|
pub(super) stateid_shorteventid: sled::Tree, |
|
|
|
pub(super) stateid_shorteventid: Arc<dyn Tree>, |
|
|
|
|
|
|
|
|
|
|
|
/// RoomId + EventId -> outlier PDU.
|
|
|
|
/// RoomId + EventId -> outlier PDU.
|
|
|
|
/// Any pdu that has passed the steps 1-8 in the incoming event /federation/send/txn.
|
|
|
|
/// Any pdu that has passed the steps 1-8 in the incoming event /federation/send/txn.
|
|
|
|
pub(super) eventid_outlierpdu: sled::Tree, |
|
|
|
pub(super) eventid_outlierpdu: Arc<dyn Tree>, |
|
|
|
|
|
|
|
|
|
|
|
/// RoomId + EventId -> Parent PDU EventId.
|
|
|
|
/// RoomId + EventId -> Parent PDU EventId.
|
|
|
|
pub(super) prevevent_parent: sled::Tree, |
|
|
|
pub(super) prevevent_parent: Arc<dyn Tree>, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl Rooms { |
|
|
|
impl Rooms { |
|
|
|
@ -92,10 +89,8 @@ impl Rooms { |
|
|
|
pub fn state_full_ids(&self, shortstatehash: u64) -> Result<Vec<EventId>> { |
|
|
|
pub fn state_full_ids(&self, shortstatehash: u64) -> Result<Vec<EventId>> { |
|
|
|
Ok(self |
|
|
|
Ok(self |
|
|
|
.stateid_shorteventid |
|
|
|
.stateid_shorteventid |
|
|
|
.scan_prefix(&shortstatehash.to_be_bytes()) |
|
|
|
.scan_prefix(shortstatehash.to_be_bytes().to_vec()) |
|
|
|
.values() |
|
|
|
.map(|(_, bytes)| self.shorteventid_eventid.get(&bytes).ok().flatten()) |
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
|
|
|
|
.map(|bytes| self.shorteventid_eventid.get(&bytes).ok().flatten()) |
|
|
|
|
|
|
|
.flatten() |
|
|
|
.flatten() |
|
|
|
.map(|bytes| { |
|
|
|
.map(|bytes| { |
|
|
|
Ok::<_, Error>( |
|
|
|
Ok::<_, Error>( |
|
|
|
@ -117,10 +112,8 @@ impl Rooms { |
|
|
|
) -> Result<BTreeMap<(EventType, String), PduEvent>> { |
|
|
|
) -> Result<BTreeMap<(EventType, String), PduEvent>> { |
|
|
|
Ok(self |
|
|
|
Ok(self |
|
|
|
.stateid_shorteventid |
|
|
|
.stateid_shorteventid |
|
|
|
.scan_prefix(shortstatehash.to_be_bytes()) |
|
|
|
.scan_prefix(shortstatehash.to_be_bytes().to_vec()) |
|
|
|
.values() |
|
|
|
.map(|(_, bytes)| self.shorteventid_eventid.get(&bytes).ok().flatten()) |
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
|
|
|
|
.map(|bytes| self.shorteventid_eventid.get(&bytes).ok().flatten()) |
|
|
|
|
|
|
|
.flatten() |
|
|
|
.flatten() |
|
|
|
.map(|bytes| { |
|
|
|
.map(|bytes| { |
|
|
|
Ok::<_, Error>( |
|
|
|
Ok::<_, Error>( |
|
|
|
@ -211,16 +204,16 @@ impl Rooms { |
|
|
|
self.eventid_shorteventid |
|
|
|
self.eventid_shorteventid |
|
|
|
.get(event_id.as_bytes())? |
|
|
|
.get(event_id.as_bytes())? |
|
|
|
.map_or(Ok(None), |shorteventid| { |
|
|
|
.map_or(Ok(None), |shorteventid| { |
|
|
|
Ok(self.shorteventid_shortstatehash.get(shorteventid)?.map_or( |
|
|
|
Ok(self |
|
|
|
Ok::<_, Error>(None), |
|
|
|
.shorteventid_shortstatehash |
|
|
|
|bytes| { |
|
|
|
.get(&shorteventid)? |
|
|
|
|
|
|
|
.map_or(Ok::<_, Error>(None), |bytes| { |
|
|
|
Ok(Some(utils::u64_from_bytes(&bytes).map_err(|_| { |
|
|
|
Ok(Some(utils::u64_from_bytes(&bytes).map_err(|_| { |
|
|
|
Error::bad_database( |
|
|
|
Error::bad_database( |
|
|
|
"Invalid shortstatehash bytes in shorteventid_shortstatehash", |
|
|
|
"Invalid shortstatehash bytes in shorteventid_shortstatehash", |
|
|
|
) |
|
|
|
) |
|
|
|
})?)) |
|
|
|
})?)) |
|
|
|
}, |
|
|
|
})?) |
|
|
|
)?) |
|
|
|
|
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -285,7 +278,8 @@ impl Rooms { |
|
|
|
// Look for PDUs in that room.
|
|
|
|
// Look for PDUs in that room.
|
|
|
|
Ok(self |
|
|
|
Ok(self |
|
|
|
.pduid_pdu |
|
|
|
.pduid_pdu |
|
|
|
.get_gt(&prefix)? |
|
|
|
.iter_from(&prefix, false) |
|
|
|
|
|
|
|
.next() |
|
|
|
.filter(|(k, _)| k.starts_with(&prefix)) |
|
|
|
.filter(|(k, _)| k.starts_with(&prefix)) |
|
|
|
.is_some()) |
|
|
|
.is_some()) |
|
|
|
} |
|
|
|
} |
|
|
|
@ -471,10 +465,17 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn latest_pdu_count(&self, room_id: &RoomId) -> Result<u64> { |
|
|
|
pub fn latest_pdu_count(&self, room_id: &RoomId) -> Result<u64> { |
|
|
|
|
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
|
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut last_possible_key = prefix.clone(); |
|
|
|
|
|
|
|
last_possible_key.extend_from_slice(&u64::MAX.to_be_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
self.pduid_pdu |
|
|
|
self.pduid_pdu |
|
|
|
.scan_prefix(room_id.as_bytes()) |
|
|
|
.iter_from(&last_possible_key, true) |
|
|
|
.last() |
|
|
|
.take_while(move |(k, _)| k.starts_with(&prefix)) |
|
|
|
.map(|b| self.pdu_count(&b?.0)) |
|
|
|
.next() |
|
|
|
|
|
|
|
.map(|b| self.pdu_count(&b.0)) |
|
|
|
.transpose() |
|
|
|
.transpose() |
|
|
|
.map(|op| op.unwrap_or_default()) |
|
|
|
.map(|op| op.unwrap_or_default()) |
|
|
|
} |
|
|
|
} |
|
|
|
@ -499,7 +500,7 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Returns the pdu's id.
|
|
|
|
/// Returns the pdu's id.
|
|
|
|
pub fn get_pdu_id(&self, event_id: &EventId) -> Result<Option<IVec>> { |
|
|
|
pub fn get_pdu_id(&self, event_id: &EventId) -> Result<Option<Vec<u8>>> { |
|
|
|
self.eventid_pduid |
|
|
|
self.eventid_pduid |
|
|
|
.get(event_id.as_bytes())? |
|
|
|
.get(event_id.as_bytes())? |
|
|
|
.map_or(Ok(None), |pdu_id| Ok(Some(pdu_id))) |
|
|
|
.map_or(Ok(None), |pdu_id| Ok(Some(pdu_id))) |
|
|
|
@ -570,11 +571,11 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Removes a pdu and creates a new one with the same id.
|
|
|
|
/// Removes a pdu and creates a new one with the same id.
|
|
|
|
fn replace_pdu(&self, pdu_id: &IVec, pdu: &PduEvent) -> Result<()> { |
|
|
|
fn replace_pdu(&self, pdu_id: &[u8], pdu: &PduEvent) -> Result<()> { |
|
|
|
if self.pduid_pdu.get(&pdu_id)?.is_some() { |
|
|
|
if self.pduid_pdu.get(&pdu_id)?.is_some() { |
|
|
|
self.pduid_pdu.insert( |
|
|
|
self.pduid_pdu.insert( |
|
|
|
&pdu_id, |
|
|
|
&pdu_id, |
|
|
|
&*serde_json::to_string(pdu).expect("PduEvent::to_string always works"), |
|
|
|
&serde_json::to_vec(pdu).expect("PduEvent::to_vec always works"), |
|
|
|
)?; |
|
|
|
)?; |
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
@ -591,11 +592,11 @@ impl Rooms { |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.roomid_pduleaves |
|
|
|
self.roomid_pduleaves |
|
|
|
.scan_prefix(prefix) |
|
|
|
.scan_prefix(dbg!(prefix)) |
|
|
|
.values() |
|
|
|
.map(|(key, bytes)| { |
|
|
|
.map(|bytes| { |
|
|
|
dbg!(key); |
|
|
|
Ok::<_, Error>( |
|
|
|
Ok::<_, Error>( |
|
|
|
EventId::try_from(utils::string_from_bytes(&bytes?).map_err(|_| { |
|
|
|
EventId::try_from(utils::string_from_bytes(&bytes).map_err(|_| { |
|
|
|
Error::bad_database("EventID in roomid_pduleaves is invalid unicode.") |
|
|
|
Error::bad_database("EventID in roomid_pduleaves is invalid unicode.") |
|
|
|
})?) |
|
|
|
})?) |
|
|
|
.map_err(|_| Error::bad_database("EventId in roomid_pduleaves is invalid."))?, |
|
|
|
.map_err(|_| Error::bad_database("EventId in roomid_pduleaves is invalid."))?, |
|
|
|
@ -612,8 +613,8 @@ impl Rooms { |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
for key in self.roomid_pduleaves.scan_prefix(&prefix).keys() { |
|
|
|
for (key, _) in self.roomid_pduleaves.scan_prefix(prefix.clone()) { |
|
|
|
self.roomid_pduleaves.remove(key?)?; |
|
|
|
self.roomid_pduleaves.remove(&key)?; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for event_id in event_ids { |
|
|
|
for event_id in event_ids { |
|
|
|
@ -628,7 +629,7 @@ impl Rooms { |
|
|
|
pub fn is_pdu_referenced(&self, pdu: &PduEvent) -> Result<bool> { |
|
|
|
pub fn is_pdu_referenced(&self, pdu: &PduEvent) -> Result<bool> { |
|
|
|
let mut key = pdu.room_id().as_bytes().to_vec(); |
|
|
|
let mut key = pdu.room_id().as_bytes().to_vec(); |
|
|
|
key.extend_from_slice(pdu.event_id().as_bytes()); |
|
|
|
key.extend_from_slice(pdu.event_id().as_bytes()); |
|
|
|
self.prevevent_parent.contains_key(key).map_err(Into::into) |
|
|
|
Ok(self.prevevent_parent.get(&key)?.is_some()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Returns the pdu from the outlier tree.
|
|
|
|
/// Returns the pdu from the outlier tree.
|
|
|
|
@ -646,7 +647,7 @@ impl Rooms { |
|
|
|
pub fn add_pdu_outlier(&self, event_id: &EventId, pdu: &CanonicalJsonObject) -> Result<()> { |
|
|
|
pub fn add_pdu_outlier(&self, event_id: &EventId, pdu: &CanonicalJsonObject) -> Result<()> { |
|
|
|
self.eventid_outlierpdu.insert( |
|
|
|
self.eventid_outlierpdu.insert( |
|
|
|
&event_id.as_bytes(), |
|
|
|
&event_id.as_bytes(), |
|
|
|
&*serde_json::to_string(&pdu).expect("CanonicalJsonObject is valid string"), |
|
|
|
&serde_json::to_vec(&pdu).expect("CanonicalJsonObject is valid"), |
|
|
|
)?; |
|
|
|
)?; |
|
|
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
@ -662,7 +663,7 @@ impl Rooms { |
|
|
|
pdu: &PduEvent, |
|
|
|
pdu: &PduEvent, |
|
|
|
mut pdu_json: CanonicalJsonObject, |
|
|
|
mut pdu_json: CanonicalJsonObject, |
|
|
|
count: u64, |
|
|
|
count: u64, |
|
|
|
pdu_id: IVec, |
|
|
|
pdu_id: &[u8], |
|
|
|
leaves: &[EventId], |
|
|
|
leaves: &[EventId], |
|
|
|
db: &Database, |
|
|
|
db: &Database, |
|
|
|
) -> Result<()> { |
|
|
|
) -> Result<()> { |
|
|
|
@ -698,7 +699,7 @@ impl Rooms { |
|
|
|
let mut key = pdu.room_id().as_bytes().to_vec(); |
|
|
|
let mut key = pdu.room_id().as_bytes().to_vec(); |
|
|
|
key.extend_from_slice(leaf.as_bytes()); |
|
|
|
key.extend_from_slice(leaf.as_bytes()); |
|
|
|
self.prevevent_parent |
|
|
|
self.prevevent_parent |
|
|
|
.insert(key, pdu.event_id().as_bytes())?; |
|
|
|
.insert(&key, pdu.event_id().as_bytes())?; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
self.replace_pdu_leaves(&pdu.room_id, leaves)?; |
|
|
|
self.replace_pdu_leaves(&pdu.room_id, leaves)?; |
|
|
|
@ -710,15 +711,13 @@ impl Rooms { |
|
|
|
self.reset_notification_counts(&pdu.sender, &pdu.room_id)?; |
|
|
|
self.reset_notification_counts(&pdu.sender, &pdu.room_id)?; |
|
|
|
|
|
|
|
|
|
|
|
self.pduid_pdu.insert( |
|
|
|
self.pduid_pdu.insert( |
|
|
|
&pdu_id, |
|
|
|
pdu_id, |
|
|
|
&*serde_json::to_string(&pdu_json) |
|
|
|
&serde_json::to_vec(&pdu_json).expect("CanonicalJsonObject is always a valid"), |
|
|
|
.expect("CanonicalJsonObject is always a valid String"), |
|
|
|
|
|
|
|
)?; |
|
|
|
)?; |
|
|
|
|
|
|
|
|
|
|
|
// This also replaces the eventid of any outliers with the correct
|
|
|
|
// This also replaces the eventid of any outliers with the correct
|
|
|
|
// pduid, removing the place holder.
|
|
|
|
// pduid, removing the place holder.
|
|
|
|
self.eventid_pduid |
|
|
|
self.eventid_pduid.insert(pdu.event_id.as_bytes(), pdu_id)?; |
|
|
|
.insert(pdu.event_id.as_bytes(), &*pdu_id)?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// See if the event matches any known pushers
|
|
|
|
// See if the event matches any known pushers
|
|
|
|
for user in db |
|
|
|
for user in db |
|
|
|
@ -760,22 +759,14 @@ impl Rooms { |
|
|
|
userroom_id.extend_from_slice(pdu.room_id.as_bytes()); |
|
|
|
userroom_id.extend_from_slice(pdu.room_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
if notify { |
|
|
|
if notify { |
|
|
|
self.userroomid_notificationcount |
|
|
|
self.userroomid_notificationcount.increment(&userroom_id)?; |
|
|
|
.update_and_fetch(&userroom_id, utils::increment)? |
|
|
|
|
|
|
|
.expect("utils::increment will always put in a value"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if highlight { |
|
|
|
if highlight { |
|
|
|
self.userroomid_highlightcount |
|
|
|
self.userroomid_highlightcount.increment(&userroom_id)?; |
|
|
|
.update_and_fetch(&userroom_id, utils::increment)? |
|
|
|
|
|
|
|
.expect("utils::increment will always put in a value"); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for senderkey in db |
|
|
|
for senderkey in db.pusher.get_pusher_senderkeys(&user) { |
|
|
|
.pusher |
|
|
|
|
|
|
|
.get_pusher_senderkeys(&user) |
|
|
|
|
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
db.sending.send_push_pdu(&*pdu_id, senderkey)?; |
|
|
|
db.sending.send_push_pdu(&*pdu_id, senderkey)?; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -840,7 +831,7 @@ impl Rooms { |
|
|
|
key.extend_from_slice(word.as_bytes()); |
|
|
|
key.extend_from_slice(word.as_bytes()); |
|
|
|
key.push(0xff); |
|
|
|
key.push(0xff); |
|
|
|
key.extend_from_slice(&pdu_id); |
|
|
|
key.extend_from_slice(&pdu_id); |
|
|
|
self.tokenids.insert(key, &[])?; |
|
|
|
self.tokenids.insert(&key, &[])?; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if body.starts_with(&format!("@conduit:{}: ", db.globals.server_name())) |
|
|
|
if body.starts_with(&format!("@conduit:{}: ", db.globals.server_name())) |
|
|
|
@ -991,7 +982,7 @@ impl Rooms { |
|
|
|
Some(shortstatehash) => { |
|
|
|
Some(shortstatehash) => { |
|
|
|
// State already existed in db
|
|
|
|
// State already existed in db
|
|
|
|
self.shorteventid_shortstatehash |
|
|
|
self.shorteventid_shortstatehash |
|
|
|
.insert(shorteventid, &*shortstatehash)?; |
|
|
|
.insert(&shorteventid, &*shortstatehash)?; |
|
|
|
return Ok(()); |
|
|
|
return Ok(()); |
|
|
|
} |
|
|
|
} |
|
|
|
None => { |
|
|
|
None => { |
|
|
|
@ -1037,7 +1028,7 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
self.shorteventid_shortstatehash |
|
|
|
self.shorteventid_shortstatehash |
|
|
|
.insert(shorteventid, &*shortstatehash)?; |
|
|
|
.insert(&shorteventid, &*shortstatehash)?; |
|
|
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1070,7 +1061,7 @@ impl Rooms { |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
self.shorteventid_shortstatehash |
|
|
|
self.shorteventid_shortstatehash |
|
|
|
.insert(shorteventid, &old_shortstatehash)?; |
|
|
|
.insert(&shorteventid, &old_shortstatehash)?; |
|
|
|
if new_pdu.state_key.is_none() { |
|
|
|
if new_pdu.state_key.is_none() { |
|
|
|
return utils::u64_from_bytes(&old_shortstatehash).map_err(|_| { |
|
|
|
return utils::u64_from_bytes(&old_shortstatehash).map_err(|_| { |
|
|
|
Error::bad_database("Invalid shortstatehash in roomid_shortstatehash.") |
|
|
|
Error::bad_database("Invalid shortstatehash in roomid_shortstatehash.") |
|
|
|
@ -1078,17 +1069,16 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
self.stateid_shorteventid |
|
|
|
self.stateid_shorteventid |
|
|
|
.scan_prefix(&old_shortstatehash) |
|
|
|
.scan_prefix(old_shortstatehash.clone()) |
|
|
|
.filter_map(|pdu| pdu.map_err(|e| error!("{}", e)).ok()) |
|
|
|
|
|
|
|
// Chop the old_shortstatehash out leaving behind the short state key
|
|
|
|
// Chop the old_shortstatehash out leaving behind the short state key
|
|
|
|
.map(|(k, v)| (k[old_shortstatehash.len()..].to_vec(), v)) |
|
|
|
.map(|(k, v)| (k[old_shortstatehash.len()..].to_vec(), v)) |
|
|
|
.collect::<HashMap<Vec<u8>, IVec>>() |
|
|
|
.collect::<HashMap<Vec<u8>, Box<[u8]>>>() |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
HashMap::new() |
|
|
|
HashMap::new() |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
if let Some(state_key) = &new_pdu.state_key { |
|
|
|
if let Some(state_key) = &new_pdu.state_key { |
|
|
|
let mut new_state: HashMap<Vec<u8>, IVec> = old_state; |
|
|
|
let mut new_state: HashMap<Vec<u8>, Box<[u8]>> = old_state; |
|
|
|
|
|
|
|
|
|
|
|
let mut new_state_key = new_pdu.kind.as_ref().as_bytes().to_vec(); |
|
|
|
let mut new_state_key = new_pdu.kind.as_ref().as_bytes().to_vec(); |
|
|
|
new_state_key.push(0xff); |
|
|
|
new_state_key.push(0xff); |
|
|
|
@ -1205,6 +1195,7 @@ impl Rooms { |
|
|
|
room_id: &RoomId, |
|
|
|
room_id: &RoomId, |
|
|
|
db: &Database, |
|
|
|
db: &Database, |
|
|
|
) -> Result<EventId> { |
|
|
|
) -> Result<EventId> { |
|
|
|
|
|
|
|
dbg!(&pdu_builder); |
|
|
|
let PduBuilder { |
|
|
|
let PduBuilder { |
|
|
|
event_type, |
|
|
|
event_type, |
|
|
|
content, |
|
|
|
content, |
|
|
|
@ -1366,7 +1357,7 @@ impl Rooms { |
|
|
|
&pdu, |
|
|
|
&pdu, |
|
|
|
pdu_json, |
|
|
|
pdu_json, |
|
|
|
count, |
|
|
|
count, |
|
|
|
pdu_id.clone().into(), |
|
|
|
&pdu_id, |
|
|
|
// Since this PDU references all pdu_leaves we can update the leaves
|
|
|
|
// Since this PDU references all pdu_leaves we can update the leaves
|
|
|
|
// of the room
|
|
|
|
// of the room
|
|
|
|
&[pdu.event_id.clone()], |
|
|
|
&[pdu.event_id.clone()], |
|
|
|
@ -1385,7 +1376,7 @@ impl Rooms { |
|
|
|
db.sending.send_pdu(&server, &pdu_id)?; |
|
|
|
db.sending.send_pdu(&server, &pdu_id)?; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for appservice in db.appservice.iter_all().filter_map(|r| r.ok()) { |
|
|
|
for appservice in db.appservice.iter_all()?.filter_map(|r| r.ok()) { |
|
|
|
if let Some(namespaces) = appservice.1.get("namespaces") { |
|
|
|
if let Some(namespaces) = appservice.1.get("namespaces") { |
|
|
|
let users = namespaces |
|
|
|
let users = namespaces |
|
|
|
.get("users") |
|
|
|
.get("users") |
|
|
|
@ -1464,23 +1455,23 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over all PDUs in a room.
|
|
|
|
/// Returns an iterator over all PDUs in a room.
|
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
pub fn all_pdus( |
|
|
|
pub fn all_pdus<'a>( |
|
|
|
&self, |
|
|
|
&'a self, |
|
|
|
user_id: &UserId, |
|
|
|
user_id: &UserId, |
|
|
|
room_id: &RoomId, |
|
|
|
room_id: &RoomId, |
|
|
|
) -> Result<impl Iterator<Item = Result<(IVec, PduEvent)>>> { |
|
|
|
) -> impl Iterator<Item = Result<(Box<[u8]>, PduEvent)>> + 'a { |
|
|
|
self.pdus_since(user_id, room_id, 0) |
|
|
|
self.pdus_since(user_id, room_id, 0) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Returns a double-ended iterator over all events in a room that happened after the event with id `since`
|
|
|
|
/// Returns an iterator over all events in a room that happened after the event with id `since`
|
|
|
|
/// in chronological order.
|
|
|
|
/// in chronological order.
|
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
pub fn pdus_since( |
|
|
|
pub fn pdus_since<'a>( |
|
|
|
&self, |
|
|
|
&'a self, |
|
|
|
user_id: &UserId, |
|
|
|
user_id: &UserId, |
|
|
|
room_id: &RoomId, |
|
|
|
room_id: &RoomId, |
|
|
|
since: u64, |
|
|
|
since: u64, |
|
|
|
) -> Result<impl DoubleEndedIterator<Item = Result<(IVec, PduEvent)>>> { |
|
|
|
) -> impl Iterator<Item = Result<(Box<[u8]>, PduEvent)>> + 'a { |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
@ -1488,19 +1479,10 @@ impl Rooms { |
|
|
|
let mut first_pdu_id = prefix.clone(); |
|
|
|
let mut first_pdu_id = prefix.clone(); |
|
|
|
first_pdu_id.extend_from_slice(&(since + 1).to_be_bytes()); |
|
|
|
first_pdu_id.extend_from_slice(&(since + 1).to_be_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
let mut last_pdu_id = prefix; |
|
|
|
|
|
|
|
last_pdu_id.extend_from_slice(&u64::MAX.to_be_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let user_id = user_id.clone(); |
|
|
|
let user_id = user_id.clone(); |
|
|
|
Ok(self |
|
|
|
self.pduid_pdu |
|
|
|
.pduid_pdu |
|
|
|
.iter_from(&first_pdu_id, false) |
|
|
|
.range(first_pdu_id..last_pdu_id) |
|
|
|
.take_while(move |(k, _)| k.starts_with(&prefix)) |
|
|
|
.filter_map(|r| { |
|
|
|
|
|
|
|
if r.is_err() { |
|
|
|
|
|
|
|
error!("Bad pdu in pduid_pdu: {:?}", r); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
r.ok() |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.map(move |(pdu_id, v)| { |
|
|
|
.map(move |(pdu_id, v)| { |
|
|
|
let mut pdu = serde_json::from_slice::<PduEvent>(&v) |
|
|
|
let mut pdu = serde_json::from_slice::<PduEvent>(&v) |
|
|
|
.map_err(|_| Error::bad_database("PDU in db is invalid."))?; |
|
|
|
.map_err(|_| Error::bad_database("PDU in db is invalid."))?; |
|
|
|
@ -1508,17 +1490,17 @@ impl Rooms { |
|
|
|
pdu.unsigned.remove("transaction_id"); |
|
|
|
pdu.unsigned.remove("transaction_id"); |
|
|
|
} |
|
|
|
} |
|
|
|
Ok((pdu_id, pdu)) |
|
|
|
Ok((pdu_id, pdu)) |
|
|
|
})) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over all events and their tokens in a room that happened before the
|
|
|
|
/// Returns an iterator over all events and their tokens in a room that happened before the
|
|
|
|
/// event with id `until` in reverse-chronological order.
|
|
|
|
/// event with id `until` in reverse-chronological order.
|
|
|
|
pub fn pdus_until( |
|
|
|
pub fn pdus_until<'a>( |
|
|
|
&self, |
|
|
|
&'a self, |
|
|
|
user_id: &UserId, |
|
|
|
user_id: &UserId, |
|
|
|
room_id: &RoomId, |
|
|
|
room_id: &RoomId, |
|
|
|
until: u64, |
|
|
|
until: u64, |
|
|
|
) -> impl Iterator<Item = Result<(IVec, PduEvent)>> { |
|
|
|
) -> impl Iterator<Item = Result<(Box<[u8]>, PduEvent)>> + 'a { |
|
|
|
// Create the first part of the full pdu id
|
|
|
|
// Create the first part of the full pdu id
|
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
@ -1530,9 +1512,7 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
let user_id = user_id.clone(); |
|
|
|
let user_id = user_id.clone(); |
|
|
|
self.pduid_pdu |
|
|
|
self.pduid_pdu |
|
|
|
.range(..current) |
|
|
|
.iter_from(current, true) |
|
|
|
.rev() |
|
|
|
|
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
|
|
|
|
.take_while(move |(k, _)| k.starts_with(&prefix)) |
|
|
|
.take_while(move |(k, _)| k.starts_with(&prefix)) |
|
|
|
.map(move |(pdu_id, v)| { |
|
|
|
.map(move |(pdu_id, v)| { |
|
|
|
let mut pdu = serde_json::from_slice::<PduEvent>(&v) |
|
|
|
let mut pdu = serde_json::from_slice::<PduEvent>(&v) |
|
|
|
@ -1547,12 +1527,12 @@ impl Rooms { |
|
|
|
/// Returns an iterator over all events and their token in a room that happened after the event
|
|
|
|
/// Returns an iterator over all events and their token in a room that happened after the event
|
|
|
|
/// with id `from` in chronological order.
|
|
|
|
/// with id `from` in chronological order.
|
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
pub fn pdus_after( |
|
|
|
pub fn pdus_after<'a>( |
|
|
|
&self, |
|
|
|
&'a self, |
|
|
|
user_id: &UserId, |
|
|
|
user_id: &UserId, |
|
|
|
room_id: &RoomId, |
|
|
|
room_id: &RoomId, |
|
|
|
from: u64, |
|
|
|
from: u64, |
|
|
|
) -> impl Iterator<Item = Result<(IVec, PduEvent)>> { |
|
|
|
) -> impl Iterator<Item = Result<(Box<[u8]>, PduEvent)>> + 'a { |
|
|
|
// Create the first part of the full pdu id
|
|
|
|
// Create the first part of the full pdu id
|
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
@ -1564,8 +1544,7 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
let user_id = user_id.clone(); |
|
|
|
let user_id = user_id.clone(); |
|
|
|
self.pduid_pdu |
|
|
|
self.pduid_pdu |
|
|
|
.range(current..) |
|
|
|
.iter_from(current, false) |
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
|
|
|
|
.take_while(move |(k, _)| k.starts_with(&prefix)) |
|
|
|
.take_while(move |(k, _)| k.starts_with(&prefix)) |
|
|
|
.map(move |(pdu_id, v)| { |
|
|
|
.map(move |(pdu_id, v)| { |
|
|
|
let mut pdu = serde_json::from_slice::<PduEvent>(&v) |
|
|
|
let mut pdu = serde_json::from_slice::<PduEvent>(&v) |
|
|
|
@ -1744,7 +1723,7 @@ impl Rooms { |
|
|
|
self.serverroomids.insert(&serverroom_id, &[])?; |
|
|
|
self.serverroomids.insert(&serverroom_id, &[])?; |
|
|
|
self.userroomid_invitestate.insert( |
|
|
|
self.userroomid_invitestate.insert( |
|
|
|
&userroom_id, |
|
|
|
&userroom_id, |
|
|
|
serde_json::to_vec(&last_state.unwrap_or_default()) |
|
|
|
&serde_json::to_vec(&last_state.unwrap_or_default()) |
|
|
|
.expect("state to bytes always works"), |
|
|
|
.expect("state to bytes always works"), |
|
|
|
)?; |
|
|
|
)?; |
|
|
|
self.roomuserid_invitecount |
|
|
|
self.roomuserid_invitecount |
|
|
|
@ -1766,7 +1745,7 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
self.userroomid_leftstate.insert( |
|
|
|
self.userroomid_leftstate.insert( |
|
|
|
&userroom_id, |
|
|
|
&userroom_id, |
|
|
|
serde_json::to_vec(&Vec::<Raw<AnySyncStateEvent>>::new()).unwrap(), |
|
|
|
&serde_json::to_vec(&Vec::<Raw<AnySyncStateEvent>>::new()).unwrap(), |
|
|
|
)?; // TODO
|
|
|
|
)?; // TODO
|
|
|
|
self.roomuserid_leftcount |
|
|
|
self.roomuserid_leftcount |
|
|
|
.insert(&roomuser_id, &db.globals.next_count()?.to_be_bytes())?; |
|
|
|
.insert(&roomuser_id, &db.globals.next_count()?.to_be_bytes())?; |
|
|
|
@ -1966,8 +1945,8 @@ impl Rooms { |
|
|
|
roomuser_id.push(0xff); |
|
|
|
roomuser_id.push(0xff); |
|
|
|
roomuser_id.extend_from_slice(user_id.as_bytes()); |
|
|
|
roomuser_id.extend_from_slice(user_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
self.userroomid_leftstate.remove(userroom_id)?; |
|
|
|
self.userroomid_leftstate.remove(&userroom_id)?; |
|
|
|
self.roomuserid_leftcount.remove(roomuser_id)?; |
|
|
|
self.roomuserid_leftcount.remove(&roomuser_id)?; |
|
|
|
|
|
|
|
|
|
|
|
Ok(()) |
|
|
|
Ok(()) |
|
|
|
} |
|
|
|
} |
|
|
|
@ -1981,26 +1960,26 @@ impl Rooms { |
|
|
|
if let Some(room_id) = room_id { |
|
|
|
if let Some(room_id) = room_id { |
|
|
|
// New alias
|
|
|
|
// New alias
|
|
|
|
self.alias_roomid |
|
|
|
self.alias_roomid |
|
|
|
.insert(alias.alias(), room_id.as_bytes())?; |
|
|
|
.insert(&alias.alias().as_bytes(), room_id.as_bytes())?; |
|
|
|
let mut aliasid = room_id.as_bytes().to_vec(); |
|
|
|
let mut aliasid = room_id.as_bytes().to_vec(); |
|
|
|
aliasid.push(0xff); |
|
|
|
aliasid.push(0xff); |
|
|
|
aliasid.extend_from_slice(&globals.next_count()?.to_be_bytes()); |
|
|
|
aliasid.extend_from_slice(&globals.next_count()?.to_be_bytes()); |
|
|
|
self.aliasid_alias.insert(aliasid, &*alias.as_bytes())?; |
|
|
|
self.aliasid_alias.insert(&aliasid, &*alias.as_bytes())?; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
// room_id=None means remove alias
|
|
|
|
// room_id=None means remove alias
|
|
|
|
let room_id = self |
|
|
|
if let Some(room_id) = self.alias_roomid.get(&alias.alias().as_bytes())? { |
|
|
|
.alias_roomid |
|
|
|
|
|
|
|
.remove(alias.alias())? |
|
|
|
|
|
|
|
.ok_or(Error::BadRequest( |
|
|
|
|
|
|
|
ErrorKind::NotFound, |
|
|
|
|
|
|
|
"Alias does not exist.", |
|
|
|
|
|
|
|
))?; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut prefix = room_id.to_vec(); |
|
|
|
let mut prefix = room_id.to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
for key in self.aliasid_alias.scan_prefix(prefix).keys() { |
|
|
|
for (key, _) in self.aliasid_alias.scan_prefix(prefix) { |
|
|
|
self.aliasid_alias.remove(key?)?; |
|
|
|
self.aliasid_alias.remove(&key)?; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
self.alias_roomid.remove(&alias.alias().as_bytes())?; |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
return Err(Error::BadRequest( |
|
|
|
|
|
|
|
ErrorKind::NotFound, |
|
|
|
|
|
|
|
"Alias does not exist.", |
|
|
|
|
|
|
|
)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@ -2009,7 +1988,7 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
pub fn id_from_alias(&self, alias: &RoomAliasId) -> Result<Option<RoomId>> { |
|
|
|
pub fn id_from_alias(&self, alias: &RoomAliasId) -> Result<Option<RoomId>> { |
|
|
|
self.alias_roomid |
|
|
|
self.alias_roomid |
|
|
|
.get(alias.alias())? |
|
|
|
.get(alias.alias().as_bytes())? |
|
|
|
.map_or(Ok(None), |bytes| { |
|
|
|
.map_or(Ok(None), |bytes| { |
|
|
|
Ok(Some( |
|
|
|
Ok(Some( |
|
|
|
RoomId::try_from(utils::string_from_bytes(&bytes).map_err(|_| { |
|
|
|
RoomId::try_from(utils::string_from_bytes(&bytes).map_err(|_| { |
|
|
|
@ -2020,15 +1999,15 @@ impl Rooms { |
|
|
|
}) |
|
|
|
}) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn room_aliases(&self, room_id: &RoomId) -> impl Iterator<Item = Result<RoomAliasId>> { |
|
|
|
pub fn room_aliases<'a>( |
|
|
|
|
|
|
|
&'a self, |
|
|
|
|
|
|
|
room_id: &RoomId, |
|
|
|
|
|
|
|
) -> impl Iterator<Item = Result<RoomAliasId>> + 'a { |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.aliasid_alias |
|
|
|
self.aliasid_alias.scan_prefix(prefix).map(|(_, bytes)| { |
|
|
|
.scan_prefix(prefix) |
|
|
|
Ok(utils::string_from_bytes(&bytes) |
|
|
|
.values() |
|
|
|
|
|
|
|
.map(|bytes| { |
|
|
|
|
|
|
|
Ok(utils::string_from_bytes(&bytes?) |
|
|
|
|
|
|
|
.map_err(|_| Error::bad_database("Invalid alias bytes in aliasid_alias."))? |
|
|
|
.map_err(|_| Error::bad_database("Invalid alias bytes in aliasid_alias."))? |
|
|
|
.try_into() |
|
|
|
.try_into() |
|
|
|
.map_err(|_| Error::bad_database("Invalid alias in aliasid_alias."))?) |
|
|
|
.map_err(|_| Error::bad_database("Invalid alias in aliasid_alias."))?) |
|
|
|
@ -2046,13 +2025,13 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn is_public_room(&self, room_id: &RoomId) -> Result<bool> { |
|
|
|
pub fn is_public_room(&self, room_id: &RoomId) -> Result<bool> { |
|
|
|
Ok(self.publicroomids.contains_key(room_id.as_bytes())?) |
|
|
|
Ok(self.publicroomids.get(room_id.as_bytes())?.is_some()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn public_rooms(&self) -> impl Iterator<Item = Result<RoomId>> { |
|
|
|
pub fn public_rooms<'a>(&'a self) -> impl Iterator<Item = Result<RoomId>> + 'a { |
|
|
|
self.publicroomids.iter().keys().map(|bytes| { |
|
|
|
self.publicroomids.iter().map(|(bytes, _)| { |
|
|
|
Ok( |
|
|
|
Ok( |
|
|
|
RoomId::try_from(utils::string_from_bytes(&bytes?).map_err(|_| { |
|
|
|
RoomId::try_from(utils::string_from_bytes(&bytes).map_err(|_| { |
|
|
|
Error::bad_database("Room ID in publicroomids is invalid unicode.") |
|
|
|
Error::bad_database("Room ID in publicroomids is invalid unicode.") |
|
|
|
})?) |
|
|
|
})?) |
|
|
|
.map_err(|_| Error::bad_database("Room ID in publicroomids is invalid."))?, |
|
|
|
.map_err(|_| Error::bad_database("Room ID in publicroomids is invalid."))?, |
|
|
|
@ -2073,16 +2052,22 @@ impl Rooms { |
|
|
|
.map(str::to_lowercase) |
|
|
|
.map(str::to_lowercase) |
|
|
|
.collect::<Vec<_>>(); |
|
|
|
.collect::<Vec<_>>(); |
|
|
|
|
|
|
|
|
|
|
|
let iterators = words.clone().into_iter().map(move |word| { |
|
|
|
let iterators = words |
|
|
|
|
|
|
|
.clone() |
|
|
|
|
|
|
|
.into_iter() |
|
|
|
|
|
|
|
.map(move |word| { |
|
|
|
let mut prefix2 = prefix.clone(); |
|
|
|
let mut prefix2 = prefix.clone(); |
|
|
|
prefix2.extend_from_slice(word.as_bytes()); |
|
|
|
prefix2.extend_from_slice(word.as_bytes()); |
|
|
|
prefix2.push(0xff); |
|
|
|
prefix2.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let mut last_possible_id = prefix2.clone(); |
|
|
|
|
|
|
|
last_possible_id.extend_from_slice(&u64::MAX.to_be_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok::<_, Error>( |
|
|
|
self.tokenids |
|
|
|
self.tokenids |
|
|
|
.scan_prefix(&prefix2) |
|
|
|
.iter_from(&last_possible_id, true) // Newest pdus first
|
|
|
|
.keys() |
|
|
|
.take_while(move |(k, _)| k.starts_with(&prefix2)) |
|
|
|
.rev() // Newest pdus first
|
|
|
|
.map(|(key, _)| { |
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
|
|
|
|
.map(|key| { |
|
|
|
|
|
|
|
let pduid_index = key |
|
|
|
let pduid_index = key |
|
|
|
.iter() |
|
|
|
.iter() |
|
|
|
.enumerate() |
|
|
|
.enumerate() |
|
|
|
@ -2096,8 +2081,10 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
Ok::<_, Error>(pdu_id) |
|
|
|
Ok::<_, Error>(pdu_id) |
|
|
|
}) |
|
|
|
}) |
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
.filter_map(|r| r.ok()), |
|
|
|
}); |
|
|
|
) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.filter_map(|r| r.ok()); |
|
|
|
|
|
|
|
|
|
|
|
Ok(( |
|
|
|
Ok(( |
|
|
|
utils::common_elements(iterators, |a, b| { |
|
|
|
utils::common_elements(iterators, |a, b| { |
|
|
|
@ -2113,21 +2100,24 @@ impl Rooms { |
|
|
|
pub fn get_shared_rooms<'a>( |
|
|
|
pub fn get_shared_rooms<'a>( |
|
|
|
&'a self, |
|
|
|
&'a self, |
|
|
|
users: Vec<UserId>, |
|
|
|
users: Vec<UserId>, |
|
|
|
) -> impl Iterator<Item = Result<RoomId>> + 'a { |
|
|
|
) -> Result<impl Iterator<Item = Result<RoomId>> + 'a> { |
|
|
|
let iterators = users.into_iter().map(move |user_id| { |
|
|
|
let iterators = users |
|
|
|
|
|
|
|
.into_iter() |
|
|
|
|
|
|
|
.map(move |user_id| { |
|
|
|
let mut prefix = user_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = user_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Ok::<_, Error>( |
|
|
|
self.userroomid_joined |
|
|
|
self.userroomid_joined |
|
|
|
.scan_prefix(&prefix) |
|
|
|
.scan_prefix(prefix) |
|
|
|
.keys() |
|
|
|
.map(|(key, _)| { |
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
|
|
|
|
.map(|key| { |
|
|
|
|
|
|
|
let roomid_index = key |
|
|
|
let roomid_index = key |
|
|
|
.iter() |
|
|
|
.iter() |
|
|
|
.enumerate() |
|
|
|
.enumerate() |
|
|
|
.find(|(_, &b)| b == 0xff) |
|
|
|
.find(|(_, &b)| b == 0xff) |
|
|
|
.ok_or_else(|| Error::bad_database("Invalid userroomid_joined in db."))? |
|
|
|
.ok_or_else(|| { |
|
|
|
|
|
|
|
Error::bad_database("Invalid userroomid_joined in db.") |
|
|
|
|
|
|
|
})? |
|
|
|
.0 |
|
|
|
.0 |
|
|
|
+ 1; // +1 because the room id starts AFTER the separator
|
|
|
|
+ 1; // +1 because the room id starts AFTER the separator
|
|
|
|
|
|
|
|
|
|
|
|
@ -2135,30 +2125,34 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
Ok::<_, Error>(room_id) |
|
|
|
Ok::<_, Error>(room_id) |
|
|
|
}) |
|
|
|
}) |
|
|
|
.filter_map(|r| r.ok()) |
|
|
|
.filter_map(|r| r.ok()), |
|
|
|
}); |
|
|
|
) |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
.filter_map(|r| r.ok()); |
|
|
|
|
|
|
|
|
|
|
|
// We use the default compare function because keys are sorted correctly (not reversed)
|
|
|
|
// We use the default compare function because keys are sorted correctly (not reversed)
|
|
|
|
utils::common_elements(iterators, Ord::cmp) |
|
|
|
Ok(utils::common_elements(iterators, Ord::cmp) |
|
|
|
.expect("users is not empty") |
|
|
|
.expect("users is not empty") |
|
|
|
.map(|bytes| { |
|
|
|
.map(|bytes| { |
|
|
|
RoomId::try_from(utils::string_from_bytes(&*bytes).map_err(|_| { |
|
|
|
RoomId::try_from(utils::string_from_bytes(&*bytes).map_err(|_| { |
|
|
|
Error::bad_database("Invalid RoomId bytes in userroomid_joined") |
|
|
|
Error::bad_database("Invalid RoomId bytes in userroomid_joined") |
|
|
|
})?) |
|
|
|
})?) |
|
|
|
.map_err(|_| Error::bad_database("Invalid RoomId in userroomid_joined.")) |
|
|
|
.map_err(|_| Error::bad_database("Invalid RoomId in userroomid_joined.")) |
|
|
|
}) |
|
|
|
})) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator of all servers participating in this room.
|
|
|
|
/// Returns an iterator of all servers participating in this room.
|
|
|
|
pub fn room_servers(&self, room_id: &RoomId) -> impl Iterator<Item = Result<Box<ServerName>>> { |
|
|
|
pub fn room_servers<'a>( |
|
|
|
|
|
|
|
&'a self, |
|
|
|
|
|
|
|
room_id: &RoomId, |
|
|
|
|
|
|
|
) -> impl Iterator<Item = Result<Box<ServerName>>> + 'a { |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.roomserverids.scan_prefix(prefix).keys().map(|key| { |
|
|
|
self.roomserverids.scan_prefix(prefix).map(|(key, _)| { |
|
|
|
Ok(Box::<ServerName>::try_from( |
|
|
|
Ok(Box::<ServerName>::try_from( |
|
|
|
utils::string_from_bytes( |
|
|
|
utils::string_from_bytes( |
|
|
|
&key? |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
.rsplit(|&b| b == 0xff) |
|
|
|
|
|
|
|
.next() |
|
|
|
.next() |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
) |
|
|
|
) |
|
|
|
@ -2171,15 +2165,17 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator of all rooms a server participates in (as far as we know).
|
|
|
|
/// Returns an iterator of all rooms a server participates in (as far as we know).
|
|
|
|
pub fn server_rooms(&self, server: &ServerName) -> impl Iterator<Item = Result<RoomId>> { |
|
|
|
pub fn server_rooms<'a>( |
|
|
|
|
|
|
|
&'a self, |
|
|
|
|
|
|
|
server: &ServerName, |
|
|
|
|
|
|
|
) -> impl Iterator<Item = Result<RoomId>> + 'a { |
|
|
|
let mut prefix = server.as_bytes().to_vec(); |
|
|
|
let mut prefix = server.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.serverroomids.scan_prefix(prefix).keys().map(|key| { |
|
|
|
self.serverroomids.scan_prefix(prefix).map(|(key, _)| { |
|
|
|
Ok(RoomId::try_from( |
|
|
|
Ok(RoomId::try_from( |
|
|
|
utils::string_from_bytes( |
|
|
|
utils::string_from_bytes( |
|
|
|
&key? |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
.rsplit(|&b| b == 0xff) |
|
|
|
|
|
|
|
.next() |
|
|
|
.next() |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
) |
|
|
|
) |
|
|
|
@ -2191,18 +2187,17 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over all joined members of a room.
|
|
|
|
/// Returns an iterator over all joined members of a room.
|
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
pub fn room_members(&self, room_id: &RoomId) -> impl Iterator<Item = Result<UserId>> { |
|
|
|
pub fn room_members<'a>( |
|
|
|
|
|
|
|
&'a self, |
|
|
|
|
|
|
|
room_id: &RoomId, |
|
|
|
|
|
|
|
) -> impl Iterator<Item = Result<UserId>> + 'a { |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.roomuserid_joined |
|
|
|
self.roomuserid_joined.scan_prefix(prefix).map(|(key, _)| { |
|
|
|
.scan_prefix(prefix) |
|
|
|
|
|
|
|
.keys() |
|
|
|
|
|
|
|
.map(|key| { |
|
|
|
|
|
|
|
Ok(UserId::try_from( |
|
|
|
Ok(UserId::try_from( |
|
|
|
utils::string_from_bytes( |
|
|
|
utils::string_from_bytes( |
|
|
|
&key? |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
.rsplit(|&b| b == 0xff) |
|
|
|
|
|
|
|
.next() |
|
|
|
.next() |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
) |
|
|
|
) |
|
|
|
@ -2215,18 +2210,19 @@ impl Rooms { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over all User IDs who ever joined a room.
|
|
|
|
/// Returns an iterator over all User IDs who ever joined a room.
|
|
|
|
pub fn room_useroncejoined(&self, room_id: &RoomId) -> impl Iterator<Item = Result<UserId>> { |
|
|
|
pub fn room_useroncejoined<'a>( |
|
|
|
|
|
|
|
&'a self, |
|
|
|
|
|
|
|
room_id: &RoomId, |
|
|
|
|
|
|
|
) -> impl Iterator<Item = Result<UserId>> + 'a { |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.roomuseroncejoinedids |
|
|
|
self.roomuseroncejoinedids |
|
|
|
.scan_prefix(prefix) |
|
|
|
.scan_prefix(prefix) |
|
|
|
.keys() |
|
|
|
.map(|(key, _)| { |
|
|
|
.map(|key| { |
|
|
|
|
|
|
|
Ok(UserId::try_from( |
|
|
|
Ok(UserId::try_from( |
|
|
|
utils::string_from_bytes( |
|
|
|
utils::string_from_bytes( |
|
|
|
&key? |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
.rsplit(|&b| b == 0xff) |
|
|
|
|
|
|
|
.next() |
|
|
|
.next() |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
) |
|
|
|
) |
|
|
|
@ -2240,18 +2236,19 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over all invited members of a room.
|
|
|
|
/// Returns an iterator over all invited members of a room.
|
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
pub fn room_members_invited(&self, room_id: &RoomId) -> impl Iterator<Item = Result<UserId>> { |
|
|
|
pub fn room_members_invited<'a>( |
|
|
|
|
|
|
|
&'a self, |
|
|
|
|
|
|
|
room_id: &RoomId, |
|
|
|
|
|
|
|
) -> impl Iterator<Item = Result<UserId>> + 'a { |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = room_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.roomuserid_invitecount |
|
|
|
self.roomuserid_invitecount |
|
|
|
.scan_prefix(prefix) |
|
|
|
.scan_prefix(prefix) |
|
|
|
.keys() |
|
|
|
.map(|(key, _)| { |
|
|
|
.map(|key| { |
|
|
|
|
|
|
|
Ok(UserId::try_from( |
|
|
|
Ok(UserId::try_from( |
|
|
|
utils::string_from_bytes( |
|
|
|
utils::string_from_bytes( |
|
|
|
&key? |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
.rsplit(|&b| b == 0xff) |
|
|
|
|
|
|
|
.next() |
|
|
|
.next() |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
) |
|
|
|
) |
|
|
|
@ -2270,7 +2267,7 @@ impl Rooms { |
|
|
|
key.extend_from_slice(user_id.as_bytes()); |
|
|
|
key.extend_from_slice(user_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
self.roomuserid_invitecount |
|
|
|
self.roomuserid_invitecount |
|
|
|
.get(key)? |
|
|
|
.get(&key)? |
|
|
|
.map_or(Ok(None), |bytes| { |
|
|
|
.map_or(Ok(None), |bytes| { |
|
|
|
Ok(Some(utils::u64_from_bytes(&bytes).map_err(|_| { |
|
|
|
Ok(Some(utils::u64_from_bytes(&bytes).map_err(|_| { |
|
|
|
Error::bad_database("Invalid invitecount in db.") |
|
|
|
Error::bad_database("Invalid invitecount in db.") |
|
|
|
@ -2285,7 +2282,7 @@ impl Rooms { |
|
|
|
key.extend_from_slice(user_id.as_bytes()); |
|
|
|
key.extend_from_slice(user_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
self.roomuserid_leftcount |
|
|
|
self.roomuserid_leftcount |
|
|
|
.get(key)? |
|
|
|
.get(&key)? |
|
|
|
.map_or(Ok(None), |bytes| { |
|
|
|
.map_or(Ok(None), |bytes| { |
|
|
|
Ok(Some(utils::u64_from_bytes(&bytes).map_err(|_| { |
|
|
|
Ok(Some(utils::u64_from_bytes(&bytes).map_err(|_| { |
|
|
|
Error::bad_database("Invalid leftcount in db.") |
|
|
|
Error::bad_database("Invalid leftcount in db.") |
|
|
|
@ -2295,15 +2292,16 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over all rooms this user joined.
|
|
|
|
/// Returns an iterator over all rooms this user joined.
|
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
pub fn rooms_joined(&self, user_id: &UserId) -> impl Iterator<Item = Result<RoomId>> { |
|
|
|
pub fn rooms_joined<'a>( |
|
|
|
|
|
|
|
&'a self, |
|
|
|
|
|
|
|
user_id: &UserId, |
|
|
|
|
|
|
|
) -> impl Iterator<Item = Result<RoomId>> + 'a { |
|
|
|
self.userroomid_joined |
|
|
|
self.userroomid_joined |
|
|
|
.scan_prefix(user_id.as_bytes()) |
|
|
|
.scan_prefix(user_id.as_bytes().to_vec()) |
|
|
|
.keys() |
|
|
|
.map(|(key, _)| { |
|
|
|
.map(|key| { |
|
|
|
|
|
|
|
Ok(RoomId::try_from( |
|
|
|
Ok(RoomId::try_from( |
|
|
|
utils::string_from_bytes( |
|
|
|
utils::string_from_bytes( |
|
|
|
&key? |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
.rsplit(|&b| b == 0xff) |
|
|
|
|
|
|
|
.next() |
|
|
|
.next() |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
.expect("rsplit always returns an element"), |
|
|
|
) |
|
|
|
) |
|
|
|
@ -2317,15 +2315,16 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over all rooms a user was invited to.
|
|
|
|
/// Returns an iterator over all rooms a user was invited to.
|
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
pub fn rooms_invited( |
|
|
|
pub fn rooms_invited<'a>( |
|
|
|
&self, |
|
|
|
&'a self, |
|
|
|
user_id: &UserId, |
|
|
|
user_id: &UserId, |
|
|
|
) -> impl Iterator<Item = Result<(RoomId, Vec<Raw<AnyStrippedStateEvent>>)>> { |
|
|
|
) -> impl Iterator<Item = Result<(RoomId, Vec<Raw<AnyStrippedStateEvent>>)>> + 'a { |
|
|
|
let mut prefix = user_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = user_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.userroomid_invitestate.scan_prefix(prefix).map(|r| { |
|
|
|
self.userroomid_invitestate |
|
|
|
let (key, state) = r?; |
|
|
|
.scan_prefix(prefix) |
|
|
|
|
|
|
|
.map(|(key, state)| { |
|
|
|
let room_id = RoomId::try_from( |
|
|
|
let room_id = RoomId::try_from( |
|
|
|
utils::string_from_bytes( |
|
|
|
utils::string_from_bytes( |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
@ -2356,7 +2355,7 @@ impl Rooms { |
|
|
|
key.extend_from_slice(&room_id.as_bytes()); |
|
|
|
key.extend_from_slice(&room_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
self.userroomid_invitestate |
|
|
|
self.userroomid_invitestate |
|
|
|
.get(key)? |
|
|
|
.get(&key)? |
|
|
|
.map(|state| { |
|
|
|
.map(|state| { |
|
|
|
let state = serde_json::from_slice(&state) |
|
|
|
let state = serde_json::from_slice(&state) |
|
|
|
.map_err(|_| Error::bad_database("Invalid state in userroomid_invitestate."))?; |
|
|
|
.map_err(|_| Error::bad_database("Invalid state in userroomid_invitestate."))?; |
|
|
|
@ -2377,7 +2376,7 @@ impl Rooms { |
|
|
|
key.extend_from_slice(&room_id.as_bytes()); |
|
|
|
key.extend_from_slice(&room_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
self.userroomid_leftstate |
|
|
|
self.userroomid_leftstate |
|
|
|
.get(key)? |
|
|
|
.get(&key)? |
|
|
|
.map(|state| { |
|
|
|
.map(|state| { |
|
|
|
let state = serde_json::from_slice(&state) |
|
|
|
let state = serde_json::from_slice(&state) |
|
|
|
.map_err(|_| Error::bad_database("Invalid state in userroomid_leftstate."))?; |
|
|
|
.map_err(|_| Error::bad_database("Invalid state in userroomid_leftstate."))?; |
|
|
|
@ -2389,15 +2388,16 @@ impl Rooms { |
|
|
|
|
|
|
|
|
|
|
|
/// Returns an iterator over all rooms a user left.
|
|
|
|
/// Returns an iterator over all rooms a user left.
|
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
#[tracing::instrument(skip(self))] |
|
|
|
pub fn rooms_left( |
|
|
|
pub fn rooms_left<'a>( |
|
|
|
&self, |
|
|
|
&'a self, |
|
|
|
user_id: &UserId, |
|
|
|
user_id: &UserId, |
|
|
|
) -> impl Iterator<Item = Result<(RoomId, Vec<Raw<AnySyncStateEvent>>)>> { |
|
|
|
) -> impl Iterator<Item = Result<(RoomId, Vec<Raw<AnySyncStateEvent>>)>> + 'a { |
|
|
|
let mut prefix = user_id.as_bytes().to_vec(); |
|
|
|
let mut prefix = user_id.as_bytes().to_vec(); |
|
|
|
prefix.push(0xff); |
|
|
|
prefix.push(0xff); |
|
|
|
|
|
|
|
|
|
|
|
self.userroomid_leftstate.scan_prefix(prefix).map(|r| { |
|
|
|
self.userroomid_leftstate |
|
|
|
let (key, state) = r?; |
|
|
|
.scan_prefix(prefix) |
|
|
|
|
|
|
|
.map(|(key, state)| { |
|
|
|
let room_id = RoomId::try_from( |
|
|
|
let room_id = RoomId::try_from( |
|
|
|
utils::string_from_bytes( |
|
|
|
utils::string_from_bytes( |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
&key.rsplit(|&b| b == 0xff) |
|
|
|
@ -2422,7 +2422,7 @@ impl Rooms { |
|
|
|
userroom_id.push(0xff); |
|
|
|
userroom_id.push(0xff); |
|
|
|
userroom_id.extend_from_slice(room_id.as_bytes()); |
|
|
|
userroom_id.extend_from_slice(room_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
Ok(self.roomuseroncejoinedids.get(userroom_id)?.is_some()) |
|
|
|
Ok(self.roomuseroncejoinedids.get(&userroom_id)?.is_some()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn is_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> { |
|
|
|
pub fn is_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> { |
|
|
|
@ -2430,7 +2430,7 @@ impl Rooms { |
|
|
|
userroom_id.push(0xff); |
|
|
|
userroom_id.push(0xff); |
|
|
|
userroom_id.extend_from_slice(room_id.as_bytes()); |
|
|
|
userroom_id.extend_from_slice(room_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
Ok(self.userroomid_joined.get(userroom_id)?.is_some()) |
|
|
|
Ok(self.userroomid_joined.get(&userroom_id)?.is_some()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn is_invited(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> { |
|
|
|
pub fn is_invited(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> { |
|
|
|
@ -2438,7 +2438,7 @@ impl Rooms { |
|
|
|
userroom_id.push(0xff); |
|
|
|
userroom_id.push(0xff); |
|
|
|
userroom_id.extend_from_slice(room_id.as_bytes()); |
|
|
|
userroom_id.extend_from_slice(room_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
Ok(self.userroomid_invitestate.get(userroom_id)?.is_some()) |
|
|
|
Ok(self.userroomid_invitestate.get(&userroom_id)?.is_some()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn is_left(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> { |
|
|
|
pub fn is_left(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> { |
|
|
|
@ -2446,6 +2446,6 @@ impl Rooms { |
|
|
|
userroom_id.push(0xff); |
|
|
|
userroom_id.push(0xff); |
|
|
|
userroom_id.extend_from_slice(room_id.as_bytes()); |
|
|
|
userroom_id.extend_from_slice(room_id.as_bytes()); |
|
|
|
|
|
|
|
|
|
|
|
Ok(self.userroomid_leftstate.get(userroom_id)?.is_some()) |
|
|
|
Ok(self.userroomid_leftstate.get(&userroom_id)?.is_some()) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|