base: Add initial state store based on sled.
This commit is contained in:
parent
cd3d90df3f
commit
045ab25fb7
4 changed files with 110 additions and 7 deletions
|
@ -15,7 +15,7 @@ features = ["docs"]
|
|||
rustdoc-args = ["--cfg", "feature=\"docs\""]
|
||||
|
||||
[features]
|
||||
default = ["encryption", "sqlite_cryptostore", "messages"]
|
||||
default = []
|
||||
messages = []
|
||||
encryption = ["matrix-sdk-crypto"]
|
||||
sqlite_cryptostore = ["matrix-sdk-crypto/sqlite_cryptostore"]
|
||||
|
|
|
@ -20,8 +20,6 @@ use std::{
|
|||
sync::Arc,
|
||||
};
|
||||
|
||||
use sled::{self, Config as SledConfig, Db as Sled};
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
use matrix_sdk_common::locks::Mutex;
|
||||
use matrix_sdk_common::{
|
||||
|
@ -49,7 +47,7 @@ use matrix_sdk_crypto::{
|
|||
};
|
||||
use zeroize::Zeroizing;
|
||||
|
||||
use crate::{error::Result, session::Session};
|
||||
use crate::{error::Result, session::Session, store::Store};
|
||||
|
||||
pub type Token = String;
|
||||
|
||||
|
@ -170,7 +168,7 @@ pub struct BaseClient {
|
|||
/// The current sync token that should be used for the next sync call.
|
||||
pub(crate) sync_token: Arc<RwLock<Option<Token>>>,
|
||||
/// Database
|
||||
sled: Sled,
|
||||
store: Store,
|
||||
#[cfg(feature = "encryption")]
|
||||
olm: Arc<Mutex<Option<OlmMachine>>>,
|
||||
#[cfg(feature = "encryption")]
|
||||
|
@ -276,7 +274,7 @@ impl BaseClient {
|
|||
Ok(BaseClient {
|
||||
session: 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")]
|
||||
olm: Arc::new(Mutex::new(None)),
|
||||
#[cfg(feature = "encryption")]
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
//! of Synapse in compliance with the Matrix API specification.
|
||||
#![deny(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
unused_extern_crates,
|
||||
|
@ -46,6 +45,9 @@ pub use matrix_sdk_common::*;
|
|||
mod client;
|
||||
mod error;
|
||||
mod session;
|
||||
mod store;
|
||||
|
||||
pub use store::Store;
|
||||
|
||||
pub use client::{BaseClient, BaseClientConfig, RoomState, RoomStateType};
|
||||
|
||||
|
|
103
matrix_sdk_base/src/store.rs
Normal file
103
matrix_sdk_base/src/store.rs
Normal file
|
@ -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 a new issue