base: Add initial state store based on sled.
parent
cd3d90df3f
commit
045ab25fb7
|
@ -15,7 +15,7 @@ features = ["docs"]
|
||||||
rustdoc-args = ["--cfg", "feature=\"docs\""]
|
rustdoc-args = ["--cfg", "feature=\"docs\""]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["encryption", "sqlite_cryptostore", "messages"]
|
default = []
|
||||||
messages = []
|
messages = []
|
||||||
encryption = ["matrix-sdk-crypto"]
|
encryption = ["matrix-sdk-crypto"]
|
||||||
sqlite_cryptostore = ["matrix-sdk-crypto/sqlite_cryptostore"]
|
sqlite_cryptostore = ["matrix-sdk-crypto/sqlite_cryptostore"]
|
||||||
|
|
|
@ -20,8 +20,6 @@ use std::{
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use sled::{self, Config as SledConfig, Db as Sled};
|
|
||||||
|
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
use matrix_sdk_common::locks::Mutex;
|
use matrix_sdk_common::locks::Mutex;
|
||||||
use matrix_sdk_common::{
|
use matrix_sdk_common::{
|
||||||
|
@ -49,7 +47,7 @@ use matrix_sdk_crypto::{
|
||||||
};
|
};
|
||||||
use zeroize::Zeroizing;
|
use zeroize::Zeroizing;
|
||||||
|
|
||||||
use crate::{error::Result, session::Session};
|
use crate::{error::Result, session::Session, store::Store};
|
||||||
|
|
||||||
pub type Token = String;
|
pub type Token = String;
|
||||||
|
|
||||||
|
@ -170,7 +168,7 @@ pub struct BaseClient {
|
||||||
/// The current sync token that should be used for the next sync call.
|
/// The current sync token that should be used for the next sync call.
|
||||||
pub(crate) sync_token: Arc<RwLock<Option<Token>>>,
|
pub(crate) sync_token: Arc<RwLock<Option<Token>>>,
|
||||||
/// Database
|
/// Database
|
||||||
sled: Sled,
|
store: Store,
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
olm: Arc<Mutex<Option<OlmMachine>>>,
|
olm: Arc<Mutex<Option<OlmMachine>>>,
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
|
@ -276,7 +274,7 @@ impl BaseClient {
|
||||||
Ok(BaseClient {
|
Ok(BaseClient {
|
||||||
session: Arc::new(RwLock::new(None)),
|
session: Arc::new(RwLock::new(None)),
|
||||||
sync_token: Arc::new(RwLock::new(None)),
|
sync_token: Arc::new(RwLock::new(None)),
|
||||||
sled: SledConfig::new().temporary(true).open().unwrap(),
|
store: Store::open(),
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
olm: Arc::new(Mutex::new(None)),
|
olm: Arc::new(Mutex::new(None)),
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
|
|
|
@ -28,7 +28,6 @@
|
||||||
//! of Synapse in compliance with the Matrix API specification.
|
//! of Synapse in compliance with the Matrix API specification.
|
||||||
#![deny(
|
#![deny(
|
||||||
missing_debug_implementations,
|
missing_debug_implementations,
|
||||||
missing_docs,
|
|
||||||
trivial_casts,
|
trivial_casts,
|
||||||
trivial_numeric_casts,
|
trivial_numeric_casts,
|
||||||
unused_extern_crates,
|
unused_extern_crates,
|
||||||
|
@ -46,6 +45,9 @@ pub use matrix_sdk_common::*;
|
||||||
mod client;
|
mod client;
|
||||||
mod error;
|
mod error;
|
||||||
mod session;
|
mod session;
|
||||||
|
mod store;
|
||||||
|
|
||||||
|
pub use store::Store;
|
||||||
|
|
||||||
pub use client::{BaseClient, BaseClientConfig, RoomState, RoomStateType};
|
pub use client::{BaseClient, BaseClientConfig, RoomState, RoomStateType};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
use serde_json;
|
||||||
|
|
||||||
|
use sled::{transaction::TransactionalTree, Config, Db, Tree};
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Store {
|
||||||
|
inner: Db,
|
||||||
|
session_tree: Tree,
|
||||||
|
}
|
||||||
|
|
||||||
|
use crate::Session;
|
||||||
|
|
||||||
|
pub struct TransactionalStore<'a> {
|
||||||
|
inner: &'a TransactionalTree,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> std::fmt::Debug for TransactionalStore<'a> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("TransactionalStore").finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a> TransactionalStore<'a> {
|
||||||
|
pub fn store_session(&self, session: &Session) {
|
||||||
|
self.inner
|
||||||
|
.insert("session", serde_json::to_vec(session).unwrap())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Store {
|
||||||
|
pub fn open() -> Self {
|
||||||
|
let db = Config::new().temporary(true).open().unwrap();
|
||||||
|
let session_tree = db.open_tree("session").unwrap();
|
||||||
|
|
||||||
|
Self {
|
||||||
|
inner: db,
|
||||||
|
session_tree,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_session(&self) -> Option<Session> {
|
||||||
|
self.session_tree
|
||||||
|
.get("session")
|
||||||
|
.unwrap()
|
||||||
|
.map(|s| serde_json::from_slice(&s).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn transaction<F, R>(&self, callback: F) -> R
|
||||||
|
where
|
||||||
|
F: Fn(&TransactionalStore) -> R,
|
||||||
|
{
|
||||||
|
let ret = self
|
||||||
|
.session_tree
|
||||||
|
.transaction::<_, _, ()>(|t| {
|
||||||
|
let transaction = TransactionalStore { inner: t };
|
||||||
|
Ok(callback(&transaction))
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
self.inner.flush_async().await.unwrap();
|
||||||
|
|
||||||
|
ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod test {
|
||||||
|
use matrix_sdk_common::identifiers::{user_id, DeviceIdBox, UserId};
|
||||||
|
use matrix_sdk_test::async_test;
|
||||||
|
|
||||||
|
use super::Store;
|
||||||
|
use crate::Session;
|
||||||
|
|
||||||
|
fn user_id() -> UserId {
|
||||||
|
user_id!("@example:localhost")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn device_id() -> DeviceIdBox {
|
||||||
|
"DEVICEID".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_test]
|
||||||
|
async fn test_session_saving() {
|
||||||
|
let session = Session {
|
||||||
|
user_id: user_id(),
|
||||||
|
device_id: device_id().into(),
|
||||||
|
access_token: "TEST_TOKEN".to_owned(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let store = Store::open();
|
||||||
|
|
||||||
|
store
|
||||||
|
.transaction(|t| {
|
||||||
|
t.store_session(&session);
|
||||||
|
()
|
||||||
|
})
|
||||||
|
.await;
|
||||||
|
let stored_session = store.get_session().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(session, stored_session);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue