|
27 | 27 | //! These types mimic the structure of the object stores and indices created in
|
28 | 28 | //! [`crate::event_cache_store::migrations`].
|
29 | 29 |
|
30 |
| -use std::sync::LazyLock; |
| 30 | +use std::{sync::LazyLock, time::Duration}; |
31 | 31 |
|
32 | 32 | use matrix_sdk_base::{
|
33 | 33 | event_cache::store::media::{IgnoreMediaRetentionPolicy, MediaRetentionPolicy},
|
@@ -154,6 +154,22 @@ static INDEXED_KEY_UPPER_EVENT_POSITION: LazyLock<Position> = LazyLock::new(|| P
|
154 | 154 | index: INDEXED_KEY_UPPER_EVENT_INDEX,
|
155 | 155 | });
|
156 | 156 |
|
| 157 | +/// The minimum possible [`Duration`]. |
| 158 | +/// |
| 159 | +/// This value is useful for constructing a key range over all keys which |
| 160 | +/// contain time-related values when used in conjunction with |
| 161 | +/// [`INDEXED_KEY_UPPER_DURATION`]. |
| 162 | +const INDEXED_KEY_LOWER_DURATION: Duration = Duration::ZERO; |
| 163 | + |
| 164 | +/// A [`Duration`] constructed with [`js_sys::Number::MAX_SAFE_INTEGER`] |
| 165 | +/// seconds. |
| 166 | +/// |
| 167 | +/// This value is useful for constructing a key range over all keys which |
| 168 | +/// contain time-related values in seconds when used in conjunction with |
| 169 | +/// [`INDEXED_KEY_LOWER_DURATION`]. |
| 170 | +const INDEXED_KEY_UPPER_DURATION_SECONDS: Duration = |
| 171 | + Duration::from_secs(js_sys::Number::MAX_SAFE_INTEGER as u64); |
| 172 | + |
157 | 173 | /// Representation of a range of keys of type `K`. This is loosely
|
158 | 174 | /// correlated with [IDBKeyRange][1], with a few differences.
|
159 | 175 | ///
|
@@ -300,6 +316,10 @@ pub type IndexedMediaContent = Vec<u8>;
|
300 | 316 | /// is suitable for use in an IndexedDB key
|
301 | 317 | pub type IndexedMediaContentSize = usize;
|
302 | 318 |
|
| 319 | +/// A representation of time in seconds since the [Unix |
| 320 | +/// Epoch](std::time::UNIX_EPOCH) which is suitable for use in an IndexedDB key |
| 321 | +pub type IndexedSecondsSinceUnixEpoch = u64; |
| 322 | + |
303 | 323 | /// Represents the [`LEASES`][1] object store.
|
304 | 324 | ///
|
305 | 325 | /// [1]: crate::event_cache_store::migrations::v1::create_lease_object_store
|
@@ -916,6 +936,9 @@ pub struct IndexedMedia {
|
916 | 936 | /// The size (in bytes) of the media content and whether to ignore the
|
917 | 937 | /// [`MediaRetentionPolicy`]
|
918 | 938 | pub content_size: IndexedMediaContentSizeKey,
|
| 939 | + /// The last time the media was accessed and whether to ignore the |
| 940 | + /// [`MediaRetentionPolicy`] |
| 941 | + pub last_access: IndexedMediaLastAccessKey, |
919 | 942 | /// The (possibly) encrypted metadata - i.e., [`MediaMetadata`][1]
|
920 | 943 | ///
|
921 | 944 | /// [1]: crate::event_cache_store::types::MediaMetadata
|
@@ -958,6 +981,10 @@ impl Indexed for Media {
|
958 | 981 | (self.metadata.ignore_policy, content.len()),
|
959 | 982 | serializer,
|
960 | 983 | ),
|
| 984 | + last_access: IndexedMediaLastAccessKey::encode( |
| 985 | + (self.metadata.ignore_policy, self.metadata.last_access), |
| 986 | + serializer, |
| 987 | + ), |
961 | 988 | metadata: serializer.maybe_encrypt_value(&self.metadata)?,
|
962 | 989 | content,
|
963 | 990 | })
|
@@ -1070,3 +1097,54 @@ impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy>
|
1070 | 1097 | (prefix, IndexedMediaContentSize::MAX)
|
1071 | 1098 | }
|
1072 | 1099 | }
|
| 1100 | + |
| 1101 | +/// The value associated with the [`last_access`](IndexedMedia::last_access) |
| 1102 | +/// index of the [`MEDIA`][1] object store, which is constructed from: |
| 1103 | +/// |
| 1104 | +/// - The value of [`IgnoreMediaRetentionPolicy`] |
| 1105 | +/// - The last time the associated [`IndexedMedia`] was accessed (in seconds |
| 1106 | +/// since the Unix Epoch) |
| 1107 | +/// |
| 1108 | +/// [1]: crate::event_cache_store::migrations::v1::create_media_object_store |
| 1109 | +#[derive(Debug, Serialize, Deserialize)] |
| 1110 | +pub struct IndexedMediaLastAccessKey( |
| 1111 | + #[serde(with = "ignore_media_retention_policy")] IgnoreMediaRetentionPolicy, |
| 1112 | + IndexedSecondsSinceUnixEpoch, |
| 1113 | +); |
| 1114 | + |
| 1115 | +impl IndexedKey<Media> for IndexedMediaLastAccessKey { |
| 1116 | + type KeyComponents<'a> = (IgnoreMediaRetentionPolicy, Duration); |
| 1117 | + |
| 1118 | + fn encode( |
| 1119 | + (ignore_policy, last_access): Self::KeyComponents<'_>, |
| 1120 | + _: &IndexeddbSerializer, |
| 1121 | + ) -> Self { |
| 1122 | + Self(ignore_policy, last_access.as_secs()) |
| 1123 | + } |
| 1124 | +} |
| 1125 | + |
| 1126 | +impl IndexedKeyComponentBounds<Media> for IndexedMediaLastAccessKey { |
| 1127 | + fn lower_key_components() -> Self::KeyComponents<'static> { |
| 1128 | + Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::No) |
| 1129 | + } |
| 1130 | + |
| 1131 | + fn upper_key_components() -> Self::KeyComponents<'static> { |
| 1132 | + Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::Yes) |
| 1133 | + } |
| 1134 | +} |
| 1135 | + |
| 1136 | +impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy> |
| 1137 | + for IndexedMediaLastAccessKey |
| 1138 | +{ |
| 1139 | + fn lower_key_components_with_prefix( |
| 1140 | + prefix: IgnoreMediaRetentionPolicy, |
| 1141 | + ) -> Self::KeyComponents<'a> { |
| 1142 | + (prefix, INDEXED_KEY_LOWER_DURATION) |
| 1143 | + } |
| 1144 | + |
| 1145 | + fn upper_key_components_with_prefix( |
| 1146 | + prefix: IgnoreMediaRetentionPolicy, |
| 1147 | + ) -> Self::KeyComponents<'a> { |
| 1148 | + (prefix, INDEXED_KEY_UPPER_DURATION_SECONDS) |
| 1149 | + } |
| 1150 | +} |
0 commit comments