feat(sqlite): allow storing the same events in multiple linked chunks

This commit is contained in:
Benjamin Bouvier
2026-01-26 17:08:49 +01:00
parent 67a45b0772
commit 2a968661e7
2 changed files with 45 additions and 1 deletions
@@ -0,0 +1,34 @@
-- Remove uniqueness constraint on event_id, replace with regular index.
-- Empties event cache as data migration is not needed.
DELETE FROM linked_chunks;
DELETE FROM event_chunks; -- should be done by cascading
DELETE FROM gap_chunks; -- should be done by cascading
DROP TABLE event_chunks;
-- Recreate event_chunks with new PRIMARY KEY
CREATE TABLE "event_chunks" (
-- Which linked chunk does this event belong to? (hashed key shared with linked_chunks)
"linked_chunk_id" BLOB NOT NULL,
-- Which chunk does this event refer to? Corresponds to a `ChunkIdentifier`.
"chunk_id" INTEGER NOT NULL,
-- `OwnedEventId` for events.
"event_id" BLOB NOT NULL,
-- Position (index) in the chunk.
"position" INTEGER NOT NULL,
-- We need a uniqueness constraint over the `linked_chunk_id`, `chunk_id` and
-- `position` tuple because (i) they must be unique, (ii) it dramatically
-- improves the performance. Also, we don't have a ROWID, so we must use a PRIMARY KEY, hence
-- we use this composite key as the primary key.
PRIMARY KEY (linked_chunk_id, chunk_id, position),
-- If the owning chunk gets deleted, delete the entry too.
FOREIGN KEY (linked_chunk_id, chunk_id) REFERENCES linked_chunks(linked_chunk_id, id) ON DELETE CASCADE
)
WITHOUT ROWID;
-- Create a non-unique index on `event_id` for query performance.
CREATE INDEX "event_chunks_event_id_idx" ON "event_chunks" ("event_id");
@@ -67,7 +67,7 @@ const DATABASE_NAME: &str = "matrix-sdk-event-cache.sqlite3";
/// This is used to figure whether the SQLite database requires a migration.
/// Every new SQL migration should imply a bump of this number, and changes in
/// the [`run_migrations`] function.
const DATABASE_VERSION: u8 = 13;
const DATABASE_VERSION: u8 = 14;
/// The string used to identify a chunk of type events, in the `type` field in
/// the database.
@@ -496,6 +496,16 @@ async fn run_migrations(conn: &SqliteAsyncConn, version: u8) -> Result<()> {
.await?;
}
if version < 14 {
conn.with_transaction(|txn| {
txn.execute_batch(include_str!(
"../migrations/event_cache_store/014_event_chunks_event_id_index.sql"
))?;
txn.set_db_version(14)
})
.await?;
}
Ok(())
}