Skip to content

Commit 3bd9313

Browse files
mgoldenbergHywan
authored andcommitted
feat(indexeddb): add IndexedDB-backed impl for EventCacheStore::load_last_chunk
Signed-off-by: Michael Goldenberg <m@mgoldenberg.net>
1 parent 153618b commit 3bd9313

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

crates/matrix-sdk-indexeddb/src/event_cache_store/error.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,14 @@ impl<T> AsyncErrorDeps for T where T: std::error::Error + SendOutsideWasm + Sync
3333
pub enum IndexeddbEventCacheStoreError {
3434
#[error("DomException {name} ({code}): {message}")]
3535
DomException { name: String, message: String, code: u16 },
36+
#[error("chunks contain disjoint lists")]
37+
ChunksContainDisjointLists,
38+
#[error("chunks contain cycle")]
39+
ChunksContainCycle,
40+
#[error("unable to load chunk")]
41+
UnableToLoadChunk,
42+
#[error("no max chunk id")]
43+
NoMaxChunkId,
3644
#[error("transaction: {0}")]
3745
Transaction(#[from] IndexeddbEventCacheStoreTransactionError),
3846
#[error("media store: {0}")]
@@ -52,7 +60,11 @@ impl From<web_sys::DomException> for IndexeddbEventCacheStoreError {
5260
impl From<IndexeddbEventCacheStoreError> for EventCacheStoreError {
5361
fn from(value: IndexeddbEventCacheStoreError) -> Self {
5462
match value {
55-
IndexeddbEventCacheStoreError::DomException { .. } => {
63+
IndexeddbEventCacheStoreError::DomException { .. }
64+
| IndexeddbEventCacheStoreError::ChunksContainCycle
65+
| IndexeddbEventCacheStoreError::ChunksContainDisjointLists
66+
| IndexeddbEventCacheStoreError::NoMaxChunkId
67+
| IndexeddbEventCacheStoreError::UnableToLoadChunk => {
5668
Self::InvalidData { details: value.to_string() }
5769
}
5870
IndexeddbEventCacheStoreError::Transaction(ref inner) => match inner {

crates/matrix-sdk-indexeddb/src/event_cache_store/mod.rs

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ use web_sys::IdbTransactionMode;
3636
use crate::event_cache_store::{
3737
migrations::current::keys,
3838
serializer::IndexeddbEventCacheStoreSerializer,
39-
transaction::IndexeddbEventCacheStoreTransaction,
39+
transaction::{IndexeddbEventCacheStoreTransaction, IndexeddbEventCacheStoreTransactionError},
4040
types::{ChunkType, InBandEvent},
4141
};
4242

@@ -300,10 +300,38 @@ impl_event_cache_store! {
300300
(Option<RawChunk<Event, Gap>>, ChunkIdentifierGenerator),
301301
IndexeddbEventCacheStoreError,
302302
> {
303-
self.memory_store
304-
.load_last_chunk(linked_chunk_id)
305-
.await
306-
.map_err(IndexeddbEventCacheStoreError::MemoryStore)
303+
let linked_chunk_id = linked_chunk_id.to_owned();
304+
let room_id = linked_chunk_id.room_id();
305+
let transaction = self.transaction(
306+
&[keys::LINKED_CHUNKS, keys::EVENTS, keys::GAPS],
307+
IdbTransactionMode::Readonly,
308+
)?;
309+
310+
if transaction.get_chunks_count_in_room(room_id).await? == 0 {
311+
return Ok((None, ChunkIdentifierGenerator::new_from_scratch()));
312+
}
313+
match transaction.get_chunk_by_next_chunk_id(room_id, &None).await {
314+
Err(IndexeddbEventCacheStoreTransactionError::ItemIsNotUnique) => {
315+
Err(IndexeddbEventCacheStoreError::ChunksContainDisjointLists)
316+
}
317+
Err(e) => Err(e.into()),
318+
Ok(None) => Err(IndexeddbEventCacheStoreError::ChunksContainCycle),
319+
Ok(Some(last_chunk)) => {
320+
let last_chunk_identifier = ChunkIdentifier::new(last_chunk.identifier);
321+
let last_raw_chunk = transaction
322+
.load_chunk_by_id(room_id, &last_chunk_identifier)
323+
.await?
324+
.ok_or(IndexeddbEventCacheStoreError::UnableToLoadChunk)?;
325+
let max_chunk_id = transaction
326+
.get_max_chunk_by_id(room_id)
327+
.await?
328+
.map(|chunk| ChunkIdentifier::new(chunk.identifier))
329+
.ok_or(IndexeddbEventCacheStoreError::NoMaxChunkId)?;
330+
let generator =
331+
ChunkIdentifierGenerator::new_from_previous_chunk_identifier(max_chunk_id);
332+
Ok((Some(last_raw_chunk), generator))
333+
}
334+
}
307335
}
308336

309337
async fn load_previous_chunk(

0 commit comments

Comments
 (0)