-
Notifications
You must be signed in to change notification settings - Fork 289
feat(event cache store): add an IndexedDB implementation #4617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
6955428
b8bfd3e
c2761d5
3c6ca6a
7eb8946
64e68ba
1328003
eebe00e
e49bda6
1b1029d
c317bd8
0f8ebf1
ee40ddd
73713ac
d3b6f87
8528522
7622be4
01cb5ba
8f2b427
722bac2
4ca221f
0e05ac8
28647b6
eee0bad
0b0e15e
993283c
d755cc0
abee3ab
06b0395
ae25b35
4dcf22a
610860b
ebda277
1af016f
6d8b405
4179750
6c7b729
c686f90
8cfe19c
18c6287
b6a8e08
533b1c3
4b7f73d
9e34ac0
a28f40b
a8082ba
8906c94
824c183
372ac98
d83b6f2
191cf48
7b1ba9e
762dba4
fc576ee
93ff358
ad6284b
8e6cc59
db030c7
866e2fa
9219a68
22308f5
4912477
69b45c7
b219c9b
7cd8fd4
99048c2
46ae727
ab61ffe
81930a1
ab4afbc
d390e07
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
use super::{ | ||
migrations::MigrationConflictStrategy, operations::get_media_retention_policy, | ||
IndexeddbEventCacheStore, Result, | ||
}; | ||
use crate::event_cache_store::{ | ||
indexeddb_serializer::IndexeddbSerializer, migrations::open_and_upgrade_db, | ||
}; | ||
use matrix_sdk_base::event_cache::store::media::{MediaRetentionPolicy, MediaService}; | ||
use matrix_sdk_store_encryption::StoreCipher; | ||
use std::sync::Arc; | ||
|
||
/// Builder for [`IndexeddbEventCacheStore`] | ||
// #[derive(Debug)] // TODO StoreCipher cannot be derived | ||
pub struct IndexeddbEventCacheStoreBuilder { | ||
name: Option<String>, | ||
store_cipher: Option<Arc<StoreCipher>>, | ||
migration_conflict_strategy: MigrationConflictStrategy, | ||
} | ||
|
||
impl IndexeddbEventCacheStoreBuilder { | ||
pub fn new() -> Self { | ||
Self { | ||
name: None, | ||
store_cipher: None, | ||
migration_conflict_strategy: MigrationConflictStrategy::BackupAndDrop, | ||
} | ||
} | ||
|
||
pub fn name(mut self, name: String) -> Self { | ||
self.name = Some(name); | ||
self | ||
} | ||
|
||
pub fn store_cipher(mut self, store_cipher: Arc<StoreCipher>) -> Self { | ||
self.store_cipher = Some(store_cipher); | ||
self | ||
} | ||
|
||
/// The strategy to use when a merge conflict is found. | ||
/// | ||
/// See [`MigrationConflictStrategy`] for details. | ||
pub fn migration_conflict_strategy(mut self, value: MigrationConflictStrategy) -> Self { | ||
self.migration_conflict_strategy = value; | ||
self | ||
} | ||
|
||
pub async fn build(self) -> Result<IndexeddbEventCacheStore> { | ||
// let migration_strategy = self.migration_conflict_strategy.clone(); | ||
let name = self.name.unwrap_or_else(|| "event_cache".to_owned()); | ||
|
||
let serializer = IndexeddbSerializer::new(self.store_cipher.clone()); | ||
let inner = open_and_upgrade_db(&name, &serializer).await?; | ||
|
||
let media_service = MediaService::new(); | ||
let policy: Option<MediaRetentionPolicy> = get_media_retention_policy(&inner).await?; | ||
media_service.restore(policy); | ||
|
||
let store = IndexeddbEventCacheStore { | ||
inner, | ||
store_cipher: self.store_cipher, | ||
serializer, | ||
media_service: Arc::new(media_service), | ||
}; | ||
Ok(store) | ||
} | ||
} | ||
|
||
impl Default for IndexeddbEventCacheStoreBuilder { | ||
fn default() -> Self { | ||
Self::new() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use matrix_sdk_base::{event_cache::store::EventCacheStoreError, StoreError}; | ||
use matrix_sdk_crypto::store::CryptoStoreError; | ||
use matrix_sdk_store_encryption::Error as EncryptionError; | ||
|
||
#[derive(Debug, thiserror::Error)] | ||
pub enum IndexeddbEventCacheStoreError { | ||
#[error(transparent)] | ||
Json(#[from] serde_json::Error), | ||
#[error(transparent)] | ||
Encryption(#[from] EncryptionError), | ||
#[error("DomException {name} ({code}): {message}")] | ||
DomException { name: String, message: String, code: u16 }, | ||
#[error(transparent)] | ||
StoreError(#[from] StoreError), | ||
#[error("Can't migrate {name} from {old_version} to {new_version} without deleting data. See MigrationConflictStrategy for ways to configure.")] | ||
MigrationConflict { name: String, old_version: u32, new_version: u32 }, | ||
#[error(transparent)] | ||
CryptoStoreError(#[from] CryptoStoreError), | ||
#[error("Uknown Chunk Type {0}")] | ||
UnknownChunkType(String), | ||
} | ||
|
||
impl From<web_sys::DomException> for IndexeddbEventCacheStoreError { | ||
fn from(frm: web_sys::DomException) -> IndexeddbEventCacheStoreError { | ||
IndexeddbEventCacheStoreError::DomException { | ||
name: frm.name(), | ||
message: frm.message(), | ||
code: frm.code(), | ||
} | ||
} | ||
} | ||
|
||
impl From<IndexeddbEventCacheStoreError> for StoreError { | ||
fn from(e: IndexeddbEventCacheStoreError) -> Self { | ||
match e { | ||
IndexeddbEventCacheStoreError::Json(e) => StoreError::Json(e), | ||
IndexeddbEventCacheStoreError::StoreError(e) => e, | ||
IndexeddbEventCacheStoreError::Encryption(e) => StoreError::Encryption(e), | ||
_ => StoreError::backend(e), | ||
} | ||
} | ||
} | ||
|
||
impl From<IndexeddbEventCacheStoreError> for EventCacheStoreError { | ||
fn from(e: IndexeddbEventCacheStoreError) -> Self { | ||
match e { | ||
IndexeddbEventCacheStoreError::Json(e) => EventCacheStoreError::Serialization(e), | ||
IndexeddbEventCacheStoreError::StoreError(e) => { | ||
EventCacheStoreError::Backend(Box::new(e)) | ||
} | ||
IndexeddbEventCacheStoreError::Encryption(e) => EventCacheStoreError::Encryption(e), | ||
_ => EventCacheStoreError::backend(e), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. backend => Backend, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was not implemented by me, comes from the sdk-base and the implemented traits |
||
} | ||
} | ||
} | ||
|
||
impl From<IndexeddbEventCacheStoreError> for CryptoStoreError { | ||
fn from(frm: IndexeddbEventCacheStoreError) -> CryptoStoreError { | ||
match frm { | ||
IndexeddbEventCacheStoreError::Json(e) => CryptoStoreError::Serialization(e), | ||
IndexeddbEventCacheStoreError::CryptoStoreError(e) => e, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would think this needs a wrapper as well, right? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't know, copied what was there from the state_store, this all were required there I think |
||
_ => CryptoStoreError::backend(frm), | ||
ospfranco marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
|
||
impl From<serde_wasm_bindgen::Error> for IndexeddbEventCacheStoreError { | ||
fn from(e: serde_wasm_bindgen::Error) -> Self { | ||
IndexeddbEventCacheStoreError::Json(serde::de::Error::custom(e.to_string())) | ||
} | ||
} | ||
|
||
impl From<rmp_serde::encode::Error> for IndexeddbEventCacheStoreError { | ||
fn from(e: rmp_serde::encode::Error) -> Self { | ||
IndexeddbEventCacheStoreError::Json(serde::ser::Error::custom(e.to_string())) | ||
} | ||
} | ||
|
||
impl From<rmp_serde::decode::Error> for IndexeddbEventCacheStoreError { | ||
fn from(e: rmp_serde::decode::Error) -> Self { | ||
IndexeddbEventCacheStoreError::Json(serde::de::Error::custom(e.to_string())) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this compile, I'm surprised it doesn't need a wrapper for StoreError here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using the command Jonas gave and it compiles with that, it will not pass the tests but the compiler shows no errors left: