diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index b2249d9f0..04da5d06c 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -17,7 +17,7 @@ use matrix_sdk::{ VersionBuilderError, }, Client as MatrixClient, ClientBuildError as MatrixClientBuildError, HttpError, IdParseError, - RumaApiError, + RumaApiError, SqliteStoreConfig, }; use ruma::api::error::{DeserializationError, FromHttpResponseError}; use tracing::{debug, error}; @@ -256,6 +256,9 @@ impl From for ClientBuildError { pub struct ClientBuilder { session_paths: Option, session_passphrase: Zeroizing>, + session_pool_max_size: Option, + session_cache_size: Option, + session_journal_size_limit: Option, username: Option, homeserver_cfg: Option, user_agent: Option, @@ -284,9 +287,12 @@ impl ClientBuilder { pub fn new() -> Arc { Arc::new(Self { session_paths: None, + session_passphrase: Zeroizing::new(None), + session_pool_max_size: None, + session_cache_size: None, + session_journal_size_limit: None, username: None, homeserver_cfg: None, - session_passphrase: Zeroizing::new(None), user_agent: None, sliding_sync_version_builder: SlidingSyncVersionBuilder::None, proxy: None, @@ -371,6 +377,53 @@ impl ClientBuilder { Arc::new(builder) } + /// Set the pool max size for the SQLite stores given to + /// [`ClientBuilder::session_paths`]. + /// + /// Each store exposes an async pool of connections. This method controls + /// the size of the pool. The larger the pool is, the more memory is + /// consumed, but also the more the app is reactive because it doesn't need + /// to wait on a pool to be available to run queries. + /// + /// See [`SqliteStoreConfig::pool_max_size`] to learn more. + pub fn session_pool_max_size(self: Arc, pool_max_size: Option) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.session_pool_max_size = pool_max_size + .map(|size| size.try_into().expect("`pool_max_size` is too large to fit in `usize`")); + Arc::new(builder) + } + + /// Set the cache size for the SQLite stores given to + /// [`ClientBuilder::session_paths`]. + /// + /// Each store exposes a SQLite connection. This method controls the cache + /// size, in **bytes (!)**. + /// + /// The cache represents data SQLite holds in memory at once per open + /// database file. The default cache implementation does not allocate the + /// full amount of cache memory all at once. Cache memory is allocated + /// in smaller chunks on an as-needed basis. + /// + /// See [`SqliteStoreConfig::cache_size`] to learn more. + pub fn session_cache_size(self: Arc, cache_size: Option) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.session_cache_size = cache_size; + Arc::new(builder) + } + + /// Set the size limit for the SQLite WAL files of stores given to + /// [`ClientBuilder::session_paths`]. + /// + /// Each store uses the WAL journal mode. This method controls the size + /// limit of the WAL files, in **bytes (!)**. + /// + /// See [`SqliteStoreConfig::journal_size_limit`] to learn more. + pub fn session_journal_size_limit(self: Arc, limit: Option) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.session_journal_size_limit = limit; + Arc::new(builder) + } + pub fn username(self: Arc, username: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.username = Some(username); @@ -523,11 +576,23 @@ impl ClientBuilder { fs::create_dir_all(data_path)?; fs::create_dir_all(cache_path)?; - inner_builder = inner_builder.sqlite_store_with_cache_path( - data_path, - cache_path, - builder.session_passphrase.as_deref(), - ); + let mut sqlite_store_config = + SqliteStoreConfig::new(data_path).passphrase(builder.session_passphrase.as_deref()); + + if let Some(size) = builder.session_pool_max_size { + sqlite_store_config = sqlite_store_config.pool_max_size(size); + } + + if let Some(size) = builder.session_cache_size { + sqlite_store_config = sqlite_store_config.cache_size(size); + } + + if let Some(limit) = builder.session_journal_size_limit { + sqlite_store_config = sqlite_store_config.journal_size_limit(limit); + } + + inner_builder = inner_builder + .sqlite_store_with_config_and_cache_path(sqlite_store_config, Some(cache_path)); } else { debug!("Not using a store path."); } diff --git a/crates/matrix-sdk/src/lib.rs b/crates/matrix-sdk/src/lib.rs index 791fd91d5..8d8bd68f3 100644 --- a/crates/matrix-sdk/src/lib.rs +++ b/crates/matrix-sdk/src/lib.rs @@ -76,7 +76,7 @@ pub use http_client::TransmissionProgress; #[cfg(all(feature = "e2e-encryption", feature = "sqlite"))] pub use matrix_sdk_sqlite::SqliteCryptoStore; #[cfg(feature = "sqlite")] -pub use matrix_sdk_sqlite::{SqliteEventCacheStore, SqliteStateStore}; +pub use matrix_sdk_sqlite::{SqliteEventCacheStore, SqliteStateStore, SqliteStoreConfig}; pub use media::Media; pub use pusher::Pusher; pub use room::Room;