1
- use std:: { fs , num:: NonZeroUsize , path :: Path , sync:: Arc , time:: Duration } ;
1
+ use std:: { num:: NonZeroUsize , sync:: Arc , time:: Duration } ;
2
2
3
3
use futures_util:: StreamExt ;
4
4
use matrix_sdk:: {
@@ -16,17 +16,21 @@ use matrix_sdk::{
16
16
VersionBuilderError ,
17
17
} ,
18
18
Client as MatrixClient , ClientBuildError as MatrixClientBuildError , HttpError , IdParseError ,
19
- RumaApiError , SqliteStoreConfig ,
19
+ RumaApiError ,
20
20
} ;
21
21
use matrix_sdk_common:: { SendOutsideWasm , SyncOutsideWasm } ;
22
22
use ruma:: api:: error:: { DeserializationError , FromHttpResponseError } ;
23
23
use tracing:: { debug, error} ;
24
- use zeroize:: Zeroizing ;
25
24
26
25
use super :: client:: Client ;
27
26
use crate :: {
28
- authentication:: OidcConfiguration , client:: ClientSessionDelegate , error:: ClientError ,
29
- helpers:: unwrap_or_clone_arc, runtime:: get_runtime_handle, task_handle:: TaskHandle ,
27
+ authentication:: OidcConfiguration ,
28
+ client:: ClientSessionDelegate ,
29
+ error:: ClientError ,
30
+ helpers:: unwrap_or_clone_arc,
31
+ runtime:: get_runtime_handle,
32
+ session_store:: { SessionStoreConfig , SessionStoreResult } ,
33
+ task_handle:: TaskHandle ,
30
34
} ;
31
35
32
36
/// A list of bytes containing a certificate in DER or PEM form.
@@ -266,11 +270,7 @@ impl From<ClientError> for ClientBuildError {
266
270
267
271
#[ derive( Clone , uniffi:: Object ) ]
268
272
pub struct ClientBuilder {
269
- session_paths : Option < SessionPaths > ,
270
- session_passphrase : Zeroizing < Option < String > > ,
271
- session_pool_max_size : Option < usize > ,
272
- session_cache_size : Option < u32 > ,
273
- session_journal_size_limit : Option < u32 > ,
273
+ session_store : Option < SessionStoreConfig > ,
274
274
system_is_memory_constrained : bool ,
275
275
username : Option < String > ,
276
276
homeserver_cfg : Option < HomeserverConfig > ,
@@ -296,11 +296,7 @@ impl ClientBuilder {
296
296
#[ uniffi:: constructor]
297
297
pub fn new ( ) -> Arc < Self > {
298
298
Arc :: new ( Self {
299
- session_paths : None ,
300
- session_passphrase : Zeroizing :: new ( None ) ,
301
- session_pool_max_size : None ,
302
- session_cache_size : None ,
303
- session_journal_size_limit : None ,
299
+ session_store : None ,
304
300
system_is_memory_constrained : false ,
305
301
username : None ,
306
302
homeserver_cfg : None ,
@@ -351,73 +347,6 @@ impl ClientBuilder {
351
347
Arc :: new ( builder)
352
348
}
353
349
354
- /// Sets the paths that the client will use to store its data and caches.
355
- /// Both paths **must** be unique per session as the SDK stores aren't
356
- /// capable of handling multiple users, however it is valid to use the
357
- /// same path for both stores on a single session.
358
- ///
359
- /// Leaving this unset tells the client to use an in-memory data store.
360
- pub fn session_paths ( self : Arc < Self > , data_path : String , cache_path : String ) -> Arc < Self > {
361
- let mut builder = unwrap_or_clone_arc ( self ) ;
362
- builder. session_paths = Some ( SessionPaths { data_path, cache_path } ) ;
363
- Arc :: new ( builder)
364
- }
365
-
366
- /// Set the passphrase for the stores given to
367
- /// [`ClientBuilder::session_paths`].
368
- pub fn session_passphrase ( self : Arc < Self > , passphrase : Option < String > ) -> Arc < Self > {
369
- let mut builder = unwrap_or_clone_arc ( self ) ;
370
- builder. session_passphrase = Zeroizing :: new ( passphrase) ;
371
- Arc :: new ( builder)
372
- }
373
-
374
- /// Set the pool max size for the SQLite stores given to
375
- /// [`ClientBuilder::session_paths`].
376
- ///
377
- /// Each store exposes an async pool of connections. This method controls
378
- /// the size of the pool. The larger the pool is, the more memory is
379
- /// consumed, but also the more the app is reactive because it doesn't need
380
- /// to wait on a pool to be available to run queries.
381
- ///
382
- /// See [`SqliteStoreConfig::pool_max_size`] to learn more.
383
- pub fn session_pool_max_size ( self : Arc < Self > , pool_max_size : Option < u32 > ) -> Arc < Self > {
384
- let mut builder = unwrap_or_clone_arc ( self ) ;
385
- builder. session_pool_max_size = pool_max_size
386
- . map ( |size| size. try_into ( ) . expect ( "`pool_max_size` is too large to fit in `usize`" ) ) ;
387
- Arc :: new ( builder)
388
- }
389
-
390
- /// Set the cache size for the SQLite stores given to
391
- /// [`ClientBuilder::session_paths`].
392
- ///
393
- /// Each store exposes a SQLite connection. This method controls the cache
394
- /// size, in **bytes (!)**.
395
- ///
396
- /// The cache represents data SQLite holds in memory at once per open
397
- /// database file. The default cache implementation does not allocate the
398
- /// full amount of cache memory all at once. Cache memory is allocated
399
- /// in smaller chunks on an as-needed basis.
400
- ///
401
- /// See [`SqliteStoreConfig::cache_size`] to learn more.
402
- pub fn session_cache_size ( self : Arc < Self > , cache_size : Option < u32 > ) -> Arc < Self > {
403
- let mut builder = unwrap_or_clone_arc ( self ) ;
404
- builder. session_cache_size = cache_size;
405
- Arc :: new ( builder)
406
- }
407
-
408
- /// Set the size limit for the SQLite WAL files of stores given to
409
- /// [`ClientBuilder::session_paths`].
410
- ///
411
- /// Each store uses the WAL journal mode. This method controls the size
412
- /// limit of the WAL files, in **bytes (!)**.
413
- ///
414
- /// See [`SqliteStoreConfig::journal_size_limit`] to learn more.
415
- pub fn session_journal_size_limit ( self : Arc < Self > , limit : Option < u32 > ) -> Arc < Self > {
416
- let mut builder = unwrap_or_clone_arc ( self ) ;
417
- builder. session_journal_size_limit = limit;
418
- Arc :: new ( builder)
419
- }
420
-
421
350
/// Tell the client that the system is memory constrained, like in a push
422
351
/// notification process for example.
423
352
///
@@ -583,50 +512,23 @@ impl ClientBuilder {
583
512
inner_builder. cross_process_store_locks_holder_name ( holder_name. clone ( ) ) ;
584
513
}
585
514
586
- let store_path = if let Some ( session_paths) = & builder. session_paths {
587
- // This is the path where both the state store and the crypto store will live.
588
- let data_path = Path :: new ( & session_paths. data_path ) ;
589
- // This is the path where the event cache store will live.
590
- let cache_path = Path :: new ( & session_paths. cache_path ) ;
591
-
592
- debug ! (
593
- data_path = %data_path. to_string_lossy( ) ,
594
- event_cache_path = %cache_path. to_string_lossy( ) ,
595
- "Creating directories for data (state and crypto) and cache stores." ,
596
- ) ;
597
-
598
- fs:: create_dir_all ( data_path) ?;
599
- fs:: create_dir_all ( cache_path) ?;
600
-
601
- let mut sqlite_store_config = if builder. system_is_memory_constrained {
602
- SqliteStoreConfig :: with_low_memory_config ( data_path)
603
- } else {
604
- SqliteStoreConfig :: new ( data_path)
605
- } ;
606
-
607
- sqlite_store_config =
608
- sqlite_store_config. passphrase ( builder. session_passphrase . as_deref ( ) ) ;
609
-
610
- if let Some ( size) = builder. session_pool_max_size {
611
- sqlite_store_config = sqlite_store_config. pool_max_size ( size) ;
612
- }
613
-
614
- if let Some ( size) = builder. session_cache_size {
615
- sqlite_store_config = sqlite_store_config. cache_size ( size) ;
616
- }
617
-
618
- if let Some ( limit) = builder. session_journal_size_limit {
619
- sqlite_store_config = sqlite_store_config. journal_size_limit ( limit) ;
515
+ let mut store_path = None ;
516
+ if let Some ( session_store) = builder. session_store {
517
+ match session_store. build ( ) ? {
518
+ #[ cfg( feature = "indexeddb" ) ]
519
+ SessionStoreResult :: IndexedDb { name, passphrase } => {
520
+ inner_builder = inner_builder. indexeddb_store ( & name, passphrase. as_deref ( ) ) ;
521
+ }
522
+ #[ cfg( feature = "sqlite" ) ]
523
+ SessionStoreResult :: Sqlite { config, cache_path, store_path : data_path } => {
524
+ inner_builder = inner_builder
525
+ . sqlite_store_with_config_and_cache_path ( config, Some ( cache_path) ) ;
526
+ store_path = Some ( data_path) ;
527
+ }
620
528
}
621
-
622
- inner_builder = inner_builder
623
- . sqlite_store_with_config_and_cache_path ( sqlite_store_config, Some ( cache_path) ) ;
624
-
625
- Some ( data_path. to_owned ( ) )
626
529
} else {
627
- debug ! ( "Not using a store path." ) ;
628
- None
629
- } ;
530
+ debug ! ( "Not using a session store." )
531
+ }
630
532
631
533
// Determine server either from URL, server name or user ID.
632
534
inner_builder = match builder. homeserver_cfg {
@@ -804,14 +706,32 @@ impl ClientBuilder {
804
706
}
805
707
}
806
708
807
- /// The store paths the client will use when built.
808
- #[ derive( Clone ) ]
809
- struct SessionPaths {
810
- /// The path that the client will use to store its data.
811
- data_path : String ,
812
- /// The path that the client will use to store its caches. This path can be
813
- /// the same as the data path if you prefer to keep everything in one place.
814
- cache_path : String ,
709
+ #[ cfg( feature = "sqlite" ) ]
710
+ #[ matrix_sdk_ffi_macros:: export]
711
+ impl ClientBuilder {
712
+ /// Tell the client to use sqlite to store session data.
713
+ pub fn session_store_sqlite (
714
+ self : Arc < Self > ,
715
+ config : Arc < crate :: session_store:: SqliteSessionStoreBuilder > ,
716
+ ) -> Arc < Self > {
717
+ let mut builder = unwrap_or_clone_arc ( self ) ;
718
+ builder. session_store = Some ( SessionStoreConfig :: Sqlite ( config. as_ref ( ) . clone ( ) ) ) ;
719
+ Arc :: new ( builder)
720
+ }
721
+ }
722
+
723
+ #[ cfg( feature = "indexeddb" ) ]
724
+ #[ matrix_sdk_ffi_macros:: export]
725
+ impl ClientBuilder {
726
+ /// Tell the client to use IndexedDb to store session data.
727
+ pub fn session_store_indexeddb (
728
+ self : Arc < Self > ,
729
+ config : Arc < crate :: session_store:: IndexedDbSessionStoreBuilder > ,
730
+ ) -> Arc < Self > {
731
+ let mut builder = unwrap_or_clone_arc ( self ) ;
732
+ builder. session_store = Some ( SessionStoreConfig :: IndexedDb ( config. as_ref ( ) . clone ( ) ) ) ;
733
+ Arc :: new ( builder)
734
+ }
815
735
}
816
736
817
737
#[ derive( Clone , uniffi:: Record ) ]
0 commit comments