From 5be7bb980da01249014f32d9d2ecb7401ccad9ca Mon Sep 17 00:00:00 2001 From: Amanda Graven Date: Wed, 25 Aug 2021 11:39:43 +0200 Subject: [PATCH 1/4] Add custom storage Add an additional tree to the Store where custom api consumer data may be stored. --- matrix_sdk/src/client.rs | 10 ++++++++++ matrix_sdk_base/src/store/memory_store.rs | 18 ++++++++++++++++++ matrix_sdk_base/src/store/mod.rs | 16 ++++++++++++++++ matrix_sdk_base/src/store/sled_store/mod.rs | 20 ++++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index 0656cdaf..fda18550 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -828,6 +828,16 @@ impl Client { self.base_client.store() } + /// Store a value in the custom tree on the store + pub async fn store_save_value(&self, key: &[u8], value: Vec) -> Result>> { + Ok(self.store().set_custom_value(key, value).await?) + } + + /// Get a value in the custom tree in the store + pub async fn store_get_value(&self, key: &[u8]) -> Result>> { + Ok(self.store().get_custom_value(key).await?) + } + /// Sets the mxc avatar url of the client's owner. The avatar gets unset if /// `url` is `None`. pub async fn set_avatar_url(&self, url: Option<&MxcUri>) -> Result<()> { diff --git a/matrix_sdk_base/src/store/memory_store.rs b/matrix_sdk_base/src/store/memory_store.rs index 311e6373..1007b006 100644 --- a/matrix_sdk_base/src/store/memory_store.rs +++ b/matrix_sdk_base/src/store/memory_store.rs @@ -66,6 +66,7 @@ pub struct MemoryStore { room_event_receipts: Arc>>>>, media: Arc>>>, + custom: Arc, Vec>>, } impl MemoryStore { @@ -90,6 +91,7 @@ impl MemoryStore { room_user_receipts: DashMap::new().into(), room_event_receipts: DashMap::new().into(), media: Arc::new(Mutex::new(LruCache::new(100))), + custom: DashMap::new().into(), } } @@ -407,6 +409,14 @@ impl MemoryStore { .unwrap_or_else(Vec::new)) } + async fn get_custom_value(&self, key: &[u8]) -> Result>> { + Ok(self.custom.get(key).map(|e| e.value().clone())) + } + + async fn set_custom_value(&self, key: &[u8], value: Vec) -> Result>> { + Ok(self.custom.insert(key.to_vec(), value)) + } + async fn add_media_content(&self, request: &MediaRequest, data: Vec) -> Result<()> { self.media.lock().await.put(request.unique_key(), data); @@ -563,6 +573,14 @@ impl StateStore for MemoryStore { self.get_event_room_receipt_events(room_id, receipt_type, event_id).await } + async fn get_custom_value(&self, key: &[u8]) -> Result>> { + self.get_custom_value(key).await + } + + async fn set_custom_value(&self, key: &[u8], value: Vec) -> Result>> { + self.set_custom_value(key, value).await + } + async fn add_media_content(&self, request: &MediaRequest, data: Vec) -> Result<()> { self.add_media_content(request, data).await } diff --git a/matrix_sdk_base/src/store/mod.rs b/matrix_sdk_base/src/store/mod.rs index 17c77c1a..6c9f19fa 100644 --- a/matrix_sdk_base/src/store/mod.rs +++ b/matrix_sdk_base/src/store/mod.rs @@ -263,6 +263,22 @@ pub trait StateStore: AsyncTraitDeps { event_id: &EventId, ) -> Result>; + /// Get arbitrary data from the custom store + /// + /// # Arguments + /// + /// * `key` - The key to fetch data for + async fn get_custom_value(&self, key: &[u8]) -> Result>>; + + /// Put arbitrary data into the custom store + /// + /// # Arguments + /// + /// * `key` - The key to insert data into + /// + /// * `value` - The value to insert + async fn set_custom_value(&self, key: &[u8], value: Vec) -> Result>>; + /// Add a media file's content in the media store. /// /// # Arguments diff --git a/matrix_sdk_base/src/store/sled_store/mod.rs b/matrix_sdk_base/src/store/sled_store/mod.rs index ea7db5c2..441f63c7 100644 --- a/matrix_sdk_base/src/store/sled_store/mod.rs +++ b/matrix_sdk_base/src/store/sled_store/mod.rs @@ -189,6 +189,7 @@ pub struct SledStore { room_user_receipts: Tree, room_event_receipts: Tree, media: Tree, + custom: Tree, } impl std::fmt::Debug for SledStore { @@ -226,6 +227,8 @@ impl SledStore { let media = db.open_tree("media")?; + let custom = db.open_tree("custom")?; + Ok(Self { path, inner: db, @@ -247,6 +250,7 @@ impl SledStore { room_user_receipts, room_event_receipts, media, + custom, }) } @@ -762,6 +766,14 @@ impl SledStore { .map(|m| m.to_vec())) } + async fn get_custom_value(&self, key: &[u8]) -> Result>> { + Ok(self.custom.get(key)?.map(|v| v.to_vec())) + } + + async fn set_custom_value(&self, key: &[u8], value: Vec) -> Result>> { + Ok(self.custom.insert(key, value)?.map(|v| v.to_vec())) + } + async fn remove_media_content(&self, request: &MediaRequest) -> Result<()> { self.media.remove( (request.media_type.unique_key().as_str(), request.format.unique_key().as_str()) @@ -899,6 +911,14 @@ impl StateStore for SledStore { self.get_event_room_receipt_events(room_id, receipt_type, event_id).await } + async fn get_custom_value(&self, key: &[u8]) -> Result>> { + self.get_custom_value(key).await + } + + async fn set_custom_value(&self, key: &[u8], value: Vec) -> Result>> { + self.set_custom_value(key, value).await + } + async fn add_media_content(&self, request: &MediaRequest, data: Vec) -> Result<()> { self.add_media_content(request, data).await } From 85fde6796a8a9094a72406eb3bdc9fab36a64db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 9 Sep 2021 11:54:08 +0200 Subject: [PATCH 2/4] fix(sdk): Remove the custom storage methods from the Client --- matrix_sdk/src/client.rs | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index fda18550..0656cdaf 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -828,16 +828,6 @@ impl Client { self.base_client.store() } - /// Store a value in the custom tree on the store - pub async fn store_save_value(&self, key: &[u8], value: Vec) -> Result>> { - Ok(self.store().set_custom_value(key, value).await?) - } - - /// Get a value in the custom tree in the store - pub async fn store_get_value(&self, key: &[u8]) -> Result>> { - Ok(self.store().get_custom_value(key).await?) - } - /// Sets the mxc avatar url of the client's owner. The avatar gets unset if /// `url` is `None`. pub async fn set_avatar_url(&self, url: Option<&MxcUri>) -> Result<()> { From b09b667782495dcf4e9deb0a1bd19bb930cb5aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 9 Sep 2021 11:55:05 +0200 Subject: [PATCH 3/4] fix(base): Flush when we're saving custom stuff in the sled store --- matrix_sdk_base/src/store/sled_store/mod.rs | 22 +++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/matrix_sdk_base/src/store/sled_store/mod.rs b/matrix_sdk_base/src/store/sled_store/mod.rs index 441f63c7..e03e8731 100644 --- a/matrix_sdk_base/src/store/sled_store/mod.rs +++ b/matrix_sdk_base/src/store/sled_store/mod.rs @@ -771,7 +771,10 @@ impl SledStore { } async fn set_custom_value(&self, key: &[u8], value: Vec) -> Result>> { - Ok(self.custom.insert(key, value)?.map(|v| v.to_vec())) + let ret = self.custom.insert(key, value)?.map(|v| v.to_vec()); + self.inner.flush_async().await?; + + Ok(ret) } async fn remove_media_content(&self, request: &MediaRequest) -> Result<()> { @@ -959,7 +962,7 @@ mod test { }; use serde_json::json; - use super::{SledStore, StateChanges}; + use super::{Result, SledStore, StateChanges}; use crate::{ deserialized_responses::MemberEvent, media::{MediaFormat, MediaRequest, MediaThumbnailSize, MediaType}, @@ -1175,4 +1178,19 @@ mod test { assert!(store.get_media_content(&request_file).await.unwrap().is_none()); assert!(store.get_media_content(&request_thumbnail).await.unwrap().is_none()); } + + #[async_test] + async fn test_custom_storage() -> Result<()> { + let key = "my_key"; + let value = &[0, 1, 2, 3]; + let store = SledStore::open().unwrap(); + + store.set_custom_value(key.as_bytes(), value.to_vec()).await?; + + let read = store.get_custom_value(key.as_bytes()).await?; + + assert_eq!(Some(value.as_ref()), read.as_deref()); + + Ok(()) + } } From 13b97f6dba47f975829273bd08007437bbc1a435 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 9 Sep 2021 12:01:15 +0200 Subject: [PATCH 4/4] fix(base): Remove an unnecessary unwrap from a test --- matrix_sdk_base/src/store/sled_store/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/matrix_sdk_base/src/store/sled_store/mod.rs b/matrix_sdk_base/src/store/sled_store/mod.rs index e03e8731..242744da 100644 --- a/matrix_sdk_base/src/store/sled_store/mod.rs +++ b/matrix_sdk_base/src/store/sled_store/mod.rs @@ -1183,7 +1183,7 @@ mod test { async fn test_custom_storage() -> Result<()> { let key = "my_key"; let value = &[0, 1, 2, 3]; - let store = SledStore::open().unwrap(); + let store = SledStore::open()?; store.set_custom_value(key.as_bytes(), value.to_vec()).await?;