|
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
|
@@ -919,6 +939,7 @@ pub struct IndexedMedia {
|
919 | 939 | /// The (possibly) encrypted metadata - i.e., [`MediaMetadata`][1]
|
920 | 940 | ///
|
921 | 941 | /// [1]: crate::event_cache_store::types::MediaMetadata
|
| 942 | + pub last_access: IndexedMediaLastAccessKey, |
922 | 943 | pub metadata: IndexedMediaMetadata,
|
923 | 944 | /// The (possibly) encrypted content - i.e., [`Media::content`]
|
924 | 945 | pub content: IndexedMediaContent,
|
@@ -958,6 +979,10 @@ impl Indexed for Media {
|
958 | 979 | (self.metadata.ignore_policy, content.len()),
|
959 | 980 | serializer,
|
960 | 981 | ),
|
| 982 | + last_access: IndexedMediaLastAccessKey::encode( |
| 983 | + (self.metadata.ignore_policy, self.metadata.last_access), |
| 984 | + serializer, |
| 985 | + ), |
961 | 986 | metadata: serializer.maybe_encrypt_value(&self.metadata)?,
|
962 | 987 | content,
|
963 | 988 | })
|
@@ -1070,3 +1095,54 @@ impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy>
|
1070 | 1095 | (prefix, IndexedMediaContentSize::MAX)
|
1071 | 1096 | }
|
1072 | 1097 | }
|
| 1098 | + |
| 1099 | +/// The value associated with the [`last_access`](IndexedMedia::last_access) |
| 1100 | +/// index of the [`MEDIA`][1] object store, which is constructed from: |
| 1101 | +/// |
| 1102 | +/// - The value of [`IgnoreMediaRetentionPolicy`] |
| 1103 | +/// - The last time the associated [`IndexedMedia`] was accessed (in seconds |
| 1104 | +/// since the Unix Epoch) |
| 1105 | +/// |
| 1106 | +/// [1]: crate::event_cache_store::migrations::v1::create_media_object_store |
| 1107 | +#[derive(Debug, Serialize, Deserialize)] |
| 1108 | +pub struct IndexedMediaLastAccessKey( |
| 1109 | + #[serde(with = "ignore_media_retention_policy")] IgnoreMediaRetentionPolicy, |
| 1110 | + IndexedSecondsSinceUnixEpoch, |
| 1111 | +); |
| 1112 | + |
| 1113 | +impl IndexedKey<Media> for IndexedMediaLastAccessKey { |
| 1114 | + type KeyComponents<'a> = (IgnoreMediaRetentionPolicy, Duration); |
| 1115 | + |
| 1116 | + fn encode( |
| 1117 | + (ignore_policy, last_access): Self::KeyComponents<'_>, |
| 1118 | + _: &IndexeddbSerializer, |
| 1119 | + ) -> Self { |
| 1120 | + Self(ignore_policy, last_access.as_secs()) |
| 1121 | + } |
| 1122 | +} |
| 1123 | + |
| 1124 | +impl IndexedKeyComponentBounds<Media> for IndexedMediaLastAccessKey { |
| 1125 | + fn lower_key_components() -> Self::KeyComponents<'static> { |
| 1126 | + Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::No) |
| 1127 | + } |
| 1128 | + |
| 1129 | + fn upper_key_components() -> Self::KeyComponents<'static> { |
| 1130 | + Self::lower_key_components_with_prefix(IgnoreMediaRetentionPolicy::Yes) |
| 1131 | + } |
| 1132 | +} |
| 1133 | + |
| 1134 | +impl<'a> IndexedPrefixKeyComponentBounds<'a, Media, IgnoreMediaRetentionPolicy> |
| 1135 | + for IndexedMediaLastAccessKey |
| 1136 | +{ |
| 1137 | + fn lower_key_components_with_prefix( |
| 1138 | + prefix: IgnoreMediaRetentionPolicy, |
| 1139 | + ) -> Self::KeyComponents<'a> { |
| 1140 | + (prefix, INDEXED_KEY_LOWER_DURATION) |
| 1141 | + } |
| 1142 | + |
| 1143 | + fn upper_key_components_with_prefix( |
| 1144 | + prefix: IgnoreMediaRetentionPolicy, |
| 1145 | + ) -> Self::KeyComponents<'a> { |
| 1146 | + (prefix, INDEXED_KEY_UPPER_DURATION_SECONDS) |
| 1147 | + } |
| 1148 | +} |
0 commit comments