From 65be779bb0725ef0809a602cb8ab9f2225393b90 Mon Sep 17 00:00:00 2001 From: Benjamin Bouvier Date: Thu, 27 Mar 2025 15:47:14 +0100 Subject: [PATCH] refactor(event cache): move relation extraction into common store helpers --- .../src/event_cache/store/mod.rs | 31 ++++++++++++++++++ .../src/event_cache_store.rs | 32 ++++--------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/crates/matrix-sdk-base/src/event_cache/store/mod.rs b/crates/matrix-sdk-base/src/event_cache/store/mod.rs index 08679cb11..d6ffaf2c6 100644 --- a/crates/matrix-sdk-base/src/event_cache/store/mod.rs +++ b/crates/matrix-sdk-base/src/event_cache/store/mod.rs @@ -32,6 +32,8 @@ use matrix_sdk_common::store_locks::{ BackingStore, CrossProcessStoreLock, CrossProcessStoreLockGuard, LockStoreError, }; pub use matrix_sdk_store_encryption::Error as StoreEncryptionError; +use ruma::{events::AnySyncTimelineEvent, serde::Raw, OwnedEventId}; +use tracing::trace; #[cfg(any(test, feature = "testing"))] pub use self::integration_tests::EventCacheStoreIntegrationTests; @@ -193,3 +195,32 @@ impl BackingStore for LockableEventCacheStore { self.0.try_take_leased_lock(lease_duration_ms, key, holder).await } } + +/// Helper to extract the relation information from an event. +/// +/// If the event isn't in relation to another event, then this will return +/// `None`. Otherwise, returns both the event id this event relates to, and the +/// kind of relation as a string (e.g. `m.replace`). +pub fn extract_event_relation(event: &Raw) -> Option<(OwnedEventId, String)> { + #[derive(serde::Deserialize)] + struct RelatesTo { + event_id: OwnedEventId, + rel_type: String, + } + + #[derive(serde::Deserialize)] + struct EventContent { + #[serde(rename = "m.relates_to")] + rel: Option, + } + + match event.get_field::("content") { + Ok(event_content) => { + event_content.and_then(|c| c.rel).map(|rel| (rel.event_id, rel.rel_type)) + } + Err(err) => { + trace!("when extracting relation data from an event: {err}"); + None + } + } +} diff --git a/crates/matrix-sdk-sqlite/src/event_cache_store.rs b/crates/matrix-sdk-sqlite/src/event_cache_store.rs index 288c1c7ed..dda5d5441 100644 --- a/crates/matrix-sdk-sqlite/src/event_cache_store.rs +++ b/crates/matrix-sdk-sqlite/src/event_cache_store.rs @@ -22,6 +22,7 @@ use matrix_sdk_base::{ deserialized_responses::TimelineEvent, event_cache::{ store::{ + extract_event_relation, media::{ EventCacheStoreMedia, IgnoreMediaRetentionPolicy, MediaRetentionPolicy, MediaService, @@ -199,35 +200,16 @@ impl SqliteEventCacheStore { // Extract the relationship info here. let raw_event = event.raw(); - - #[derive(serde::Deserialize)] - struct RelatesTo { - // For the purpose of storing the related event id in the database, a string is - // sufficient; we'll lose the static typing of `OwnedEventId` immediately anyways. - event_id: String, - rel_type: String, - } - - #[derive(serde::Deserialize)] - struct EventContent { - #[serde(rename = "m.relates_to")] - rel: Option, - } - - let (relates_to, rel_type) = match raw_event.get_field::("content") { - Ok(event_content) => { - event_content.and_then(|c| c.rel).map(|rel| (rel.event_id, rel.rel_type)).unzip() - } - Err(err) => { - error!("when extracting relation data before inserting in database: {err}"); - (None, None) - } - }; + let (relates_to, rel_type) = extract_event_relation(raw_event).unzip(); // The content may be encrypted. let content = self.encode_value(serialized)?; - Ok(EncodedEvent { content, rel_type, relates_to }) + Ok(EncodedEvent { + content, + rel_type, + relates_to: relates_to.map(|relates_to| relates_to.to_string()), + }) } }