Skip to content

Commit 950c427

Browse files
committed
refactor(sqlite): Save the event type of an event in the SQLite event cache
1 parent f91ffb4 commit 950c427

2 files changed

Lines changed: 101 additions & 9 deletions

File tree

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
-- For the event decryption to happen in the event cache we need the ability to
2+
-- fetch only `m.room.encrypted` events out of the store.
3+
--
4+
-- To accomplish that, we are emptying the event cache. New events inserted with
5+
-- the event type and the session ID of the room key as separate columns.
6+
7+
DELETE from linked_chunks;
8+
DELETE from event_chunks; -- should be done by cascading
9+
DELETE from gap_chunks; -- should be done by cascading
10+
DELETE from events;
11+
12+
DROP TABLE events;
13+
14+
-- Events and their content.
15+
CREATE TABLE "events" (
16+
-- The room in which the event is located.
17+
"room_id" BLOB NOT NULL,
18+
19+
-- The `OwnedEventId` of this event.
20+
"event_id" BLOB NOT NULL,
21+
22+
-- The event type of this event.
23+
"event_type" BLOB NOT NULL,
24+
25+
-- The ID of the session that was used to encrypt this event, may be null if
26+
-- the event wasn't encrypted.
27+
"session_id" BLOB NULL,
28+
29+
-- JSON serialized `TimelineEvent` (encrypted value).
30+
"content" BLOB NOT NULL,
31+
32+
-- If this event is an aggregation (related event), the event id of the event it relates to.
33+
-- Can be null if this event isn't an aggregation.
34+
"relates_to" BLOB,
35+
36+
-- If this event is an aggregation (related event), the kind of relation it has to the event it
37+
-- relates to.
38+
-- Can be null if this event isn't an aggregation.
39+
"rel_type" BLOB,
40+
41+
-- Primary key is the event ID.
42+
PRIMARY KEY (event_id)
43+
)
44+
WITHOUT ROWID;
45+
46+
-- Add an index to speed up queries that look for related events in a room.
47+
CREATE INDEX "relates_to_idx"
48+
ON "events" ("room_id", "relates_to");
49+
50+
-- Add an index to speed up queries that look for related events in a room, with an additional
51+
-- filter.
52+
CREATE INDEX "relates_to_rel_type_idx"
53+
ON "events" ("room_id", "relates_to", "rel_type");
54+
55+
-- Add an index to speed up queries that look for related events in a room.
56+
CREATE INDEX "event_type_index"
57+
ON "events" ("room_id", "event_type", "session_id");

crates/matrix-sdk-sqlite/src/event_cache_store.rs

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ use crate::{
5353
mod keys {
5454
// Tables
5555
pub const LINKED_CHUNKS: &str = "linked_chunks";
56+
pub const EVENTS: &str = "events";
5657
}
5758

5859
/// The database name.
@@ -63,7 +64,7 @@ const DATABASE_NAME: &str = "matrix-sdk-event-cache.sqlite3";
6364
/// This is used to figure whether the SQLite database requires a migration.
6465
/// Every new SQL migration should imply a bump of this number, and changes in
6566
/// the [`run_migrations`] function.
66-
const DATABASE_VERSION: u8 = 11;
67+
const DATABASE_VERSION: u8 = 12;
6768

6869
/// The string used to identify a chunk of type events, in the `type` field in
6970
/// the database.
@@ -472,6 +473,16 @@ async fn run_migrations(conn: &SqliteAsyncConn, version: u8) -> Result<()> {
472473
.await?;
473474
}
474475

476+
if version < 12 {
477+
conn.with_transaction(|txn| {
478+
txn.execute_batch(include_str!(
479+
"../migrations/event_cache_store/012_store_event_type.sql"
480+
))?;
481+
txn.set_db_version(12)
482+
})
483+
.await?;
484+
}
485+
475486
Ok(())
476487
}
477488

@@ -632,7 +643,7 @@ impl EventCacheStore for SqliteEventCacheStore {
632643
// deduplicated and moved to another position; or because it was inserted
633644
// outside the context of a linked chunk (e.g. pinned event).
634645
let mut content_statement = txn.prepare(
635-
"INSERT OR REPLACE INTO events(room_id, event_id, content, relates_to, rel_type) VALUES (?, ?, ?, ?, ?)"
646+
"INSERT OR REPLACE INTO events(room_id, event_id, event_type, session_id, content, relates_to, rel_type) VALUES (?, ?, ?, ?, ?, ?, ?)"
636647
)?;
637648

638649
let invalid_event = |event: TimelineEvent| {
@@ -641,20 +652,28 @@ impl EventCacheStore for SqliteEventCacheStore {
641652
return None;
642653
};
643654

644-
Some((event_id.to_string(), event))
655+
let Some(event_type) = event.kind.event_type() else {
656+
error!(%event_id, "Trying to save an event with no event type");
657+
return None;
658+
};
659+
660+
Some((event_id.to_string(), event_type, event))
645661
};
646662

647663
let room_id = linked_chunk_id.room_id();
648664
let hashed_room_id = this.encode_key(keys::LINKED_CHUNKS, room_id);
649665

650-
for (i, (event_id, event)) in items.into_iter().filter_map(invalid_event).enumerate() {
666+
for (i, (event_id, event_type, event)) in items.into_iter().filter_map(invalid_event).enumerate() {
651667
// Insert the location information into the database.
652668
let index = at.index() + i;
653669
chunk_statement.execute((chunk_id, &hashed_linked_chunk_id, &event_id, index))?;
654670

671+
let session_id = event.kind.session_id().map(|s| this.encode_key(keys::EVENTS, s));
672+
let event_type = this.encode_key(keys::EVENTS, event_type);
673+
655674
// Now, insert the event content into the database.
656675
let encoded_event = this.encode_event(&event)?;
657-
content_statement.execute((&hashed_room_id, event_id, encoded_event.content, encoded_event.relates_to, encoded_event.rel_type))?;
676+
content_statement.execute((&hashed_room_id, event_id, event_type, session_id, encoded_event.content, encoded_event.relates_to, encoded_event.rel_type))?;
658677
}
659678
}
660679

@@ -671,15 +690,23 @@ impl EventCacheStore for SqliteEventCacheStore {
671690
continue;
672691
};
673692

693+
let Some(event_type) = event.kind.event_type() else {
694+
error!(%event_id, "Trying to save an event with no event type");
695+
continue;
696+
};
697+
698+
let session_id = event.kind.session_id().map(|s| this.encode_key(keys::EVENTS, s));
699+
let event_type = this.encode_key(keys::EVENTS, event_type);
700+
674701
// Replace the event's content. Really we'd like to update, but in case the
675702
// event id changed, we are a bit lenient here and will allow an insertion
676703
// of the new event.
677704
let encoded_event = this.encode_event(&event)?;
678705
let room_id = linked_chunk_id.room_id();
679706
let hashed_room_id = this.encode_key(keys::LINKED_CHUNKS, room_id);
680707
txn.execute(
681-
"INSERT OR REPLACE INTO events(room_id, event_id, content, relates_to, rel_type) VALUES (?, ?, ?, ?, ?)"
682-
, (&hashed_room_id, &event_id, encoded_event.content, encoded_event.relates_to, encoded_event.rel_type))?;
708+
"INSERT OR REPLACE INTO events(room_id, event_id, event_type, session_id, content, relates_to, rel_type) VALUES (?, ?, ?, ?, ?, ?, ?)",
709+
(&hashed_room_id, &event_id, event_type, session_id, encoded_event.content, encoded_event.relates_to, encoded_event.rel_type))?;
683710

684711
// Replace the event id in the linked chunk, in case it changed.
685712
txn.execute(
@@ -1336,6 +1363,14 @@ impl EventCacheStore for SqliteEventCacheStore {
13361363
return Ok(());
13371364
};
13381365

1366+
let Some(event_type) = event.kind.event_type() else {
1367+
error!(%event_id, "Trying to save an event with no event type");
1368+
return Ok(());
1369+
};
1370+
1371+
let event_type = self.encode_key(keys::EVENTS, event_type);
1372+
let session_id = event.kind.session_id().map(|s| self.encode_key(keys::EVENTS, s));
1373+
13391374
let hashed_room_id = self.encode_key(keys::LINKED_CHUNKS, room_id);
13401375
let event_id = event_id.to_string();
13411376
let encoded_event = self.encode_event(&event)?;
@@ -1344,8 +1379,8 @@ impl EventCacheStore for SqliteEventCacheStore {
13441379
.await?
13451380
.with_transaction(move |txn| -> Result<_> {
13461381
txn.execute(
1347-
"INSERT OR REPLACE INTO events(room_id, event_id, content, relates_to, rel_type) VALUES (?, ?, ?, ?, ?)"
1348-
, (&hashed_room_id, &event_id, encoded_event.content, encoded_event.relates_to, encoded_event.rel_type))?;
1382+
"INSERT OR REPLACE INTO events(room_id, event_id, event_type, session_id, content, relates_to, rel_type) VALUES (?, ?, ?, ?, ?, ?, ?)",
1383+
(&hashed_room_id, &event_id, event_type, session_id, encoded_event.content, encoded_event.relates_to, encoded_event.rel_type))?;
13491384

13501385
Ok(())
13511386
})

0 commit comments

Comments
 (0)