diff --git a/crates/matrix-sdk-indexeddb/src/media_store/transaction.rs b/crates/matrix-sdk-indexeddb/src/media_store/transaction.rs index 0c3059f09..837d437d0 100644 --- a/crates/matrix-sdk-indexeddb/src/media_store/transaction.rs +++ b/crates/matrix-sdk-indexeddb/src/media_store/transaction.rs @@ -14,18 +14,22 @@ use std::ops::Deref; -use indexed_db_futures::transaction as inner; -use matrix_sdk_base::media::{store::MediaRetentionPolicy, MediaRequestParameters}; +use indexed_db_futures::{cursor::CursorDirection, transaction as inner}; +use matrix_sdk_base::media::{ + store::{IgnoreMediaRetentionPolicy, MediaRetentionPolicy}, + MediaRequestParameters, +}; use ruma::MxcUri; use crate::{ media_store::{ serializer::indexed_types::{ - IndexedCoreIdKey, IndexedLeaseIdKey, IndexedMediaIdKey, IndexedMediaUriKey, + IndexedCoreIdKey, IndexedLeaseIdKey, IndexedMediaContentSizeKey, IndexedMediaIdKey, + IndexedMediaRetentionMetadataKey, IndexedMediaUriKey, }, types::{Lease, Media, MediaCleanupTime, UnixTime}, }, - serializer::IndexedTypeSerializer, + serializer::{IndexedKeyRange, IndexedTypeSerializer}, transaction::{Transaction, TransactionError}, }; @@ -153,6 +157,51 @@ impl<'a> IndexeddbMediaStoreTransaction<'a> { Ok(medias) } + /// Query IndexedDB for all [content size](IndexedMediaContentSizeKey) keys + /// whose associated [`Media`] matches the given + /// [`IgnoreMediaRetentionPolicy`]. + pub async fn get_media_keys_by_content_size( + &self, + ignore_policy: IgnoreMediaRetentionPolicy, + ) -> Result, TransactionError> { + self.get_keys::(IndexedKeyRange::all_with_prefix( + ignore_policy, + self.serializer().inner(), + )) + .await + } + + /// Query IndexedDB for [retention metadata][1] keys that match the given + /// key range. Iterate over the keys in the given + /// [`direction`](CursorDirection) using a cursor and fold them into an + /// accumulator while the given function `f` returns [`Some`]. + /// + /// This function returns the final value of the accumulator and the key, if + /// any, which caused the fold to short circuit. + /// + /// Note that the use of cursor means that keys are read lazily from + /// IndexedDB. + /// + /// [1]: IndexedMediaRetentionMetadataKey + pub async fn fold_media_keys_by_retention_metadata_while( + &self, + direction: CursorDirection, + ignore_policy: IgnoreMediaRetentionPolicy, + init: Acc, + f: F, + ) -> Result<(Acc, Option), TransactionError> + where + F: FnMut(&Acc, &IndexedMediaRetentionMetadataKey) -> Option, + { + self.fold_keys_while::( + direction, + IndexedKeyRange::all_with_prefix(ignore_policy, self.serializer().inner()), + init, + f, + ) + .await + } + /// Adds [`Media`] to IndexedDB. If an item with the same key already /// exists, it will be rejected. pub async fn add_media(&self, media: &Media) -> Result<(), TransactionError> {