mirror of
https://gitlab.com/famedly/conduit.git
synced 2025-07-22 17:18:35 +00:00
Work on rooms/state and database
This commit is contained in:
parent
03b2867a84
commit
7c166aa468
6 changed files with 144 additions and 136 deletions
|
@ -26,7 +26,7 @@ pub mod persy;
|
|||
))]
|
||||
pub mod watchers;
|
||||
|
||||
pub trait DatabaseEngine: Send + Sync {
|
||||
pub trait KeyValueDatabaseEngine: Send + Sync {
|
||||
fn open(config: &Config) -> Result<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
|
@ -40,7 +40,7 @@ pub trait DatabaseEngine: Send + Sync {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait Tree: Send + Sync {
|
||||
pub trait KeyValueTree: Send + Sync {
|
||||
fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>>;
|
||||
|
||||
fn insert(&self, key: &[u8], value: &[u8]) -> Result<()>;
|
||||
|
|
65
src/database/key_value.rs
Normal file
65
src/database/key_value.rs
Normal file
|
@ -0,0 +1,65 @@
|
|||
use crate::service;
|
||||
|
||||
impl service::room::state::Data for KeyValueDatabase {
|
||||
fn get_room_shortstatehash(&self, room_id: &RoomId) -> Result<Option<u64>> {
|
||||
self.roomid_shortstatehash
|
||||
.get(room_id.as_bytes())?
|
||||
.map_or(Ok(None), |bytes| {
|
||||
Ok(Some(utils::u64_from_bytes(&bytes).map_err(|_| {
|
||||
Error::bad_database("Invalid shortstatehash in roomid_shortstatehash")
|
||||
})?))
|
||||
})
|
||||
}
|
||||
|
||||
fn set_room_state(room_id: &RoomId, new_shortstatehash: u64
|
||||
_mutex_lock: &MutexGuard<'_, StateLock>, // Take mutex guard to make sure users get the room state mutex
|
||||
) -> Result<()> {
|
||||
self.roomid_shortstatehash
|
||||
.insert(room_id.as_bytes(), &new_shortstatehash.to_be_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn set_event_state() -> Result<()> {
|
||||
db.shorteventid_shortstatehash
|
||||
.insert(&shorteventid.to_be_bytes(), &shortstatehash.to_be_bytes())?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_pdu_leaves(&self, room_id: &RoomId) -> Result<HashSet<Arc<EventId>>> {
|
||||
let mut prefix = room_id.as_bytes().to_vec();
|
||||
prefix.push(0xff);
|
||||
|
||||
self.roomid_pduleaves
|
||||
.scan_prefix(prefix)
|
||||
.map(|(_, bytes)| {
|
||||
EventId::parse_arc(utils::string_from_bytes(&bytes).map_err(|_| {
|
||||
Error::bad_database("EventID in roomid_pduleaves is invalid unicode.")
|
||||
})?)
|
||||
.map_err(|_| Error::bad_database("EventId in roomid_pduleaves is invalid."))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn set_forward_extremities(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
event_ids: impl IntoIterator<Item = &'a EventId> + Debug,
|
||||
_mutex_lock: &MutexGuard<'_, StateLock>, // Take mutex guard to make sure users get the room state mutex
|
||||
) -> Result<()> {
|
||||
let mut prefix = room_id.as_bytes().to_vec();
|
||||
prefix.push(0xff);
|
||||
|
||||
for (key, _) in self.roomid_pduleaves.scan_prefix(prefix.clone()) {
|
||||
self.roomid_pduleaves.remove(&key)?;
|
||||
}
|
||||
|
||||
for event_id in event_ids {
|
||||
let mut key = prefix.to_owned();
|
||||
key.extend_from_slice(event_id.as_bytes());
|
||||
self.roomid_pduleaves.insert(&key, event_id.as_bytes())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
}
|
|
@ -15,7 +15,7 @@ pub mod users;
|
|||
|
||||
use self::admin::create_admin_room;
|
||||
use crate::{utils, Config, Error, Result};
|
||||
use abstraction::DatabaseEngine;
|
||||
use abstraction::KeyValueDatabaseEngine;
|
||||
use directories::ProjectDirs;
|
||||
use futures_util::{stream::FuturesUnordered, StreamExt};
|
||||
use lru_cache::LruCache;
|
||||
|
@ -39,8 +39,8 @@ use std::{
|
|||
use tokio::sync::{mpsc, OwnedRwLockReadGuard, RwLock as TokioRwLock, Semaphore};
|
||||
use tracing::{debug, error, info, warn};
|
||||
|
||||
pub struct Database {
|
||||
_db: Arc<dyn DatabaseEngine>,
|
||||
pub struct KeyValueDatabase {
|
||||
_db: Arc<dyn KeyValueDatabaseEngine>,
|
||||
pub globals: globals::Globals,
|
||||
pub users: users::Users,
|
||||
pub uiaa: uiaa::Uiaa,
|
||||
|
@ -55,7 +55,7 @@ pub struct Database {
|
|||
pub pusher: pusher::PushData,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
impl KeyValueDatabase {
|
||||
/// Tries to remove the old database but ignores all errors.
|
||||
pub fn try_remove(server_name: &str) -> Result<()> {
|
||||
let mut path = ProjectDirs::from("xyz", "koesters", "conduit")
|
||||
|
@ -124,7 +124,7 @@ impl Database {
|
|||
.map_err(|_| Error::BadConfig("Database folder doesn't exists and couldn't be created (e.g. due to missing permissions). Please create the database folder yourself."))?;
|
||||
}
|
||||
|
||||
let builder: Arc<dyn DatabaseEngine> = match &*config.database_backend {
|
||||
let builder: Arc<dyn KeyValueDatabaseEngine> = match &*config.database_backend {
|
||||
"sqlite" => {
|
||||
#[cfg(not(feature = "sqlite"))]
|
||||
return Err(Error::BadConfig("Database backend not found."));
|
||||
|
@ -955,7 +955,7 @@ impl Database {
|
|||
}
|
||||
|
||||
/// Sets the emergency password and push rules for the @conduit account in case emergency password is set
|
||||
fn set_emergency_access(db: &Database) -> Result<bool> {
|
||||
fn set_emergency_access(db: &KeyValueDatabase) -> Result<bool> {
|
||||
let conduit_user = UserId::parse_with_server_name("conduit", db.globals.server_name())
|
||||
.expect("@conduit:server_name is a valid UserId");
|
||||
|
||||
|
@ -979,39 +979,3 @@ fn set_emergency_access(db: &Database) -> Result<bool> {
|
|||
|
||||
res
|
||||
}
|
||||
|
||||
pub struct DatabaseGuard(OwnedRwLockReadGuard<Database>);
|
||||
|
||||
impl Deref for DatabaseGuard {
|
||||
type Target = OwnedRwLockReadGuard<Database>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "conduit_bin")]
|
||||
#[axum::async_trait]
|
||||
impl<B> axum::extract::FromRequest<B> for DatabaseGuard
|
||||
where
|
||||
B: Send,
|
||||
{
|
||||
type Rejection = axum::extract::rejection::ExtensionRejection;
|
||||
|
||||
async fn from_request(
|
||||
req: &mut axum::extract::RequestParts<B>,
|
||||
) -> Result<Self, Self::Rejection> {
|
||||
use axum::extract::Extension;
|
||||
|
||||
let Extension(db): Extension<Arc<TokioRwLock<Database>>> =
|
||||
Extension::from_request(req).await?;
|
||||
|
||||
Ok(DatabaseGuard(db.read_owned().await))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<OwnedRwLockReadGuard<Database>> for DatabaseGuard {
|
||||
fn from(val: OwnedRwLockReadGuard<Database>) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue