re-integrate sled and indexeddb stores into base

This commit is contained in:
Benjamin Kampmann
2022-02-23 19:38:35 +01:00
parent 692f9d893a
commit ed0974eba3
8 changed files with 103 additions and 63 deletions

View File

@@ -311,10 +311,10 @@ impl SledStore {
})
}
pub fn open() -> Result<Self> {
let db = Config::new().temporary(true).open()?;
pub fn open() -> StoreResult<Self> {
let db = Config::new().temporary(true).open().map_err(|e| StoreError::Backend(anyhow!(e)))?;
SledStore::open_helper(db, None, None)
SledStore::open_helper(db, None, None).map_err(|e| e.into())
}
pub fn open_with_passphrase(path: impl AsRef<Path>, passphrase: &str) -> Result<Self> {

View File

@@ -24,12 +24,12 @@ default = [
"native-tls"
]
indexeddb_stores = []
indexeddb_stores = ["matrix-sdk-indexeddb"]
encryption = ["matrix-sdk-base/encryption"]
qrcode = ["encryption", "matrix-sdk-base/qrcode"]
# TODO merge those two sled features
sled_state_store = []
sled_cryptostore = []
sled_state_store = ["matrix-sdk-sled"]
sled_cryptostore = ["matrix-sdk-sled", "encryption"]
markdown = ["ruma/markdown"]
native-tls = ["reqwest/native-tls"]
rustls-tls = ["reqwest/rustls-tls"]
@@ -67,7 +67,11 @@ thiserror = "1.0.25"
tracing = "0.1.26"
url = "2.2.2"
zeroize = "1.3.0"
async-stream = "0.3.2"
async-stream = "0.3.2"
#
matrix-sdk-sled = { path = "../matrix-sdk-sled", optional = true }
matrix-sdk-indexeddb = { path = "../matrix-sdk-indexeddb", optional = true }
[dependencies.image]
version = "0.24.0"

View File

@@ -1,7 +1,7 @@
use std::{env, process::exit};
use matrix_sdk::{
config::{ClientConfig, SyncSettings},
config::{ClientConfig, default_store_with_name, SyncSettings},
room::Room,
ruma::events::room::member::StrippedRoomMemberEvent,
Client,
@@ -48,7 +48,7 @@ async fn login_and_sync(
let mut home = dirs::home_dir().expect("no home directory found");
home.push("autojoin_bot");
let client_config = ClientConfig::new().store_path(home);
let client_config = ClientConfig::new()?.state_store(default_store_with_name(home.to_str().expect("home dir path must be utf-8"), None)?);
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
let client = Client::new_with_config(homeserver_url, client_config).await.unwrap();

View File

@@ -1,7 +1,7 @@
use std::{env, process::exit};
use matrix_sdk::{
config::{ClientConfig, SyncSettings},
config::{ClientConfig, SyncSettings, default_store_with_name},
room::Room,
ruma::events::room::message::{
MessageType, RoomMessageEventContent, SyncRoomMessageEvent, TextMessageEventContent,
@@ -41,7 +41,7 @@ async fn login_and_sync(
let mut home = dirs::home_dir().expect("no home directory found");
home.push("party_bot");
let client_config = ClientConfig::new().store_path(home);
let client_config = ClientConfig::new()?.state_store(default_store_with_name(home.to_str().expect("home dir path must be utf-8"), None)?);
let homeserver_url = Url::parse(&homeserver_url).expect("Couldn't parse the homeserver URL");
// create a new Client with the given homeserver url and config

View File

@@ -166,7 +166,7 @@ impl Client {
///
/// * `homeserver_url` - The homeserver that the client should connect to.
pub async fn new(homeserver_url: Url) -> Result<Self> {
let config = ClientConfig::new();
let config = ClientConfig::new()?;
Client::new_with_config(homeserver_url, config).await
}
@@ -245,7 +245,7 @@ impl Client {
///
/// [spec]: https://spec.matrix.org/unstable/client-server-api/#well-known-uri
pub async fn new_from_user_id(user_id: &UserId) -> Result<Self> {
let config = ClientConfig::new();
let config = ClientConfig::new()?;
Client::new_from_user_id_with_config(user_id, config).await
}
@@ -2371,7 +2371,7 @@ pub(crate) mod test {
device_id: device_id!("DEVICEID").to_owned(),
};
let homeserver = url::Url::parse(&mockito::server_url()).unwrap();
let config = ClientConfig::new().request_config(RequestConfig::new().disable_retry());
let config = ClientConfig::new().unwrap().request_config(RequestConfig::new().disable_retry());
let client = Client::new_with_config(homeserver, config).await.unwrap();
client.restore_login(session).await.unwrap();
@@ -2469,7 +2469,7 @@ pub(crate) mod test {
#[async_test]
async fn login_with_discovery() {
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
let config = ClientConfig::new().use_discovery_response();
let config = ClientConfig::new().unwrap().use_discovery_response();
let client = Client::new_with_config(homeserver, config).await.unwrap();
@@ -2489,7 +2489,7 @@ pub(crate) mod test {
#[async_test]
async fn login_no_discovery() {
let homeserver = Url::from_str(&mockito::server_url()).unwrap();
let config = ClientConfig::new().use_discovery_response();
let config = ClientConfig::new().unwrap().use_discovery_response();
let client = Client::new_with_config(homeserver.clone(), config).await.unwrap();
@@ -2620,8 +2620,7 @@ pub(crate) mod test {
// test store reloads with correct room state from the sled store
let path = tempfile::tempdir().unwrap();
let config = ClientConfig::default()
.store_path(path)
let config = ClientConfig::with_named_store(path.into_path().to_str().unwrap(), None).unwrap()
.request_config(RequestConfig::new().disable_retry());
let joined_client = Client::new_with_config(homeserver, config).await.unwrap();
joined_client.restore_login(session).await.unwrap();

View File

@@ -20,7 +20,7 @@ use std::{
};
use http::header::InvalidHeaderValue;
use matrix_sdk_base::BaseClientConfig;
use matrix_sdk_base::{BaseClientConfig, StateStore};
use crate::{config::RequestConfig, HttpSend, Result};
@@ -35,7 +35,7 @@ use crate::{config::RequestConfig, HttpSend, Result};
/// use matrix_sdk::config::ClientConfig;
/// // To pass all the request through mitmproxy set the proxy and disable SSL
/// // verification
/// let client_config = ClientConfig::new()
/// let client_config = ClientConfig::new()?
/// .proxy("http://localhost:8080")?
/// .disable_ssl_verification();
/// # matrix_sdk::Result::<()>::Ok(())
@@ -57,7 +57,7 @@ use crate::{config::RequestConfig, HttpSend, Result};
/// .no_proxy()
/// .user_agent("MyApp/v3.0");
///
/// let client_config = ClientConfig::new()
/// let client_config = ClientConfig::new()?
/// .client(Arc::new(builder.build()?));
/// # matrix_sdk::Result::<()>::Ok(())
/// ```
@@ -89,11 +89,74 @@ impl Debug for ClientConfig {
}
}
#[cfg(feature = "sled_state_store")]
mod store_helpers {
use super::Result;
use matrix_sdk_sled::StateStore;
/// Build the sled Store with the default settings - as a temporary storage
///
pub fn default_store() -> Result<Box<StateStore>> {
Ok(Box::new(StateStore::open()?))
}
/// Build a sled store at `name` (being a relative or full path), and open
/// the store with the given passphrase (if given) for encryption
pub fn default_store_with_name(name: &str, passphrase: Option<&str>) -> Result<Box<StateStore>> {
unimplemented!{}
}
}
#[cfg(feature = "indexeddb_state_store")]
mod store_helpers {
use super::Result;
use matrix_sdk_sled::StateStore;
/// Open the IndexedDB store with the default name, unencrypted
pub fn default_store() -> Result<Box<StateStore>> {
Ok(Box::new(StateStore::default()))
}
/// Open the indexeddb store at `name` (IndexedDB Database name), and open
/// the store with the given passphrase (if given) for encryption
pub fn default_store_with_name(name: &str, passphrase: Option<&str>) -> Result<Box<StateStore>> {
unimplemented!{}
}
}
#[cfg(not(any(feature = "indexeddb_state_store", feature = "sled_state_store")))]
mod store_helpers {
use super::Result;
use matrix_sdk_base::state::MemoryStore as StateStore;
/// Open a new in-memory StateStore
pub fn default_store() -> Result<Box<StateStore>> {
Ok(Box::new(StateStore::default()))
}
/// Alias for `default_store` - in Memory Stores are never named
pub fn default_store_with_name(_name: &str, _passphrase: Option<&str>) -> Result<Box<StateStore>> {
Ok(Box::new(StateStore::default()))
}
}
#[allow(dead_code)]
pub use store_helpers::{default_store, default_store_with_name};
impl ClientConfig {
/// Create a new default `ClientConfig`.
#[must_use]
pub fn new() -> Self {
Default::default()
pub fn new() -> Result<Self> {
let mut d = Self::default();
d.base_config = d.base_config.state_store(default_store()?);
Ok(d)
}
/// Create a new ClientConfig with a named state store, encrypted with the given passphrase (if any)
pub fn with_named_store(name: &str, passphrase: Option<&str>) -> Result<Self> {
let mut d = Self::default();
d.base_config = d.base_config.state_store(default_store_with_name(name, passphrase)?);
Ok(d)
}
/// Set the proxy through which all the HTTP requests should go.
@@ -109,7 +172,7 @@ impl ClientConfig {
/// ```
/// use matrix_sdk::{Client, config::ClientConfig};
///
/// let client_config = ClientConfig::new()
/// let client_config = ClientConfig::new()?
/// .proxy("http://localhost:8080")?;
///
/// # Result::<_, matrix_sdk::Error>::Ok(())
@@ -133,45 +196,12 @@ impl ClientConfig {
Ok(self)
}
///// Set a custom implementation of a `StateStore`.
/////
///// The state store should be opened before being set.
//#[must_use]
//pub fn state_store(mut self, store: Box<dyn StateStore>) -> Self {
// self.base_config = self.base_config.state_store(store);
// self
//}
/// Set the path for storage.
/// Set a custom implementation of a `StateStore`.
///
/// # Arguments
///
/// * `path` - The path where the stores should save data in. It is the
/// callers responsibility to make sure that the path exists.
///
/// In the default configuration, and if the corresponding features
/// (`sled_state_store` and `sled_cryptostore`) are enabled, the client will
/// open default implementations for the crypto store and the state store.
/// It will use the given path to open the stores. If no path is provided an
/// in-memory store will be opened.
#[must_use]
pub fn store_path(mut self, path: impl AsRef<Path>) -> Self {
self.base_config = self.base_config.store_path(path);
self
}
/// Set the passphrase to encrypt the crypto store.
///
/// # Argument
///
/// * `passphrase` - The passphrase that will be used to encrypt the data in
/// the cryptostore.
///
/// This is only used if no custom cryptostore is set.
#[must_use]
pub fn passphrase(mut self, passphrase: String) -> Self {
self.base_config = self.base_config.passphrase(passphrase);
self
/// The state store should be opened before being set.
pub fn state_store(mut self, store: Box<dyn StateStore>) -> Self {
self.base_config = self.base_config.state_store(store);
self
}
/// Set the default timeout, fail and retry behavior for all HTTP requests.

View File

@@ -20,6 +20,6 @@ mod client;
mod request;
mod sync;
pub use client::ClientConfig;
pub use client::{ClientConfig, default_store, default_store_with_name};
pub use request::RequestConfig;
pub use sync::SyncSettings;

View File

@@ -109,6 +109,11 @@ pub enum Error {
#[error("the queried endpoint requires authentication but was called before logging in")]
AuthenticationRequired,
/// Attempting to restore a session after the olm-machine has already been set up fails
#[cfg(feature = "encryption")]
#[error("The olm machine has already been initialized")]
BadCryptoStoreState,
/// An error de/serializing type for the `StateStore`
#[error(transparent)]
SerdeJson(#[from] JsonError),
@@ -250,6 +255,8 @@ impl From<SdkBaseError> for Error {
#[cfg(feature = "encryption")]
SdkBaseError::CryptoStore(e) => Self::CryptoStoreError(e),
#[cfg(feature = "encryption")]
SdkBaseError::BadCryptoStoreState => Self::BadCryptoStoreState,
#[cfg(feature = "encryption")]
SdkBaseError::OlmError(e) => Self::OlmError(e),
#[cfg(feature = "encryption")]
SdkBaseError::MegolmError(e) => Self::MegolmError(e),