refactor(event cache): move relation extraction into common store helpers

This commit is contained in:
Benjamin Bouvier
2025-03-27 15:47:14 +01:00
parent 45f1dca6a3
commit 65be779bb0
2 changed files with 38 additions and 25 deletions

View File

@@ -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<AnySyncTimelineEvent>) -> 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<RelatesTo>,
}
match event.get_field::<EventContent>("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
}
}
}

View File

@@ -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<RelatesTo>,
}
let (relates_to, rel_type) = match raw_event.get_field::<EventContent>("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()),
})
}
}