29
29
30
30
use matrix_sdk_base:: linked_chunk:: ChunkIdentifier ;
31
31
use matrix_sdk_crypto:: CryptoStoreError ;
32
- use ruma:: RoomId ;
32
+ use ruma:: { events :: relation :: RelationType , EventId , OwnedEventId , RoomId } ;
33
33
use serde:: { Deserialize , Serialize } ;
34
+ use thiserror:: Error ;
34
35
35
36
use crate :: {
36
37
event_cache_store:: {
37
38
migrations:: current:: keys,
38
39
serializer:: traits:: { Indexed , IndexedKey , IndexedKeyBounds } ,
39
- types:: Chunk ,
40
+ types:: { Chunk , Event , Position } ,
40
41
} ,
41
42
serializer:: { IndexeddbSerializer , MaybeEncrypted } ,
42
43
} ;
43
44
45
+ /// The first unicode character, and hence the lower bound for IndexedDB keys
46
+ /// (or key components) which are represented as strings.
47
+ ///
48
+ /// This value is useful for constructing a key range over all strings when used
49
+ /// in conjunction with [`INDEXED_KEY_UPPER_CHARACTER`].
50
+ const INDEXED_KEY_LOWER_CHARACTER : char = '\u{0000}' ;
51
+
52
+ /// The last unicode character in the [Basic Multilingual Plane][1]. This seems
53
+ /// like a reasonable place to set the upper bound for IndexedDB keys (or key
54
+ /// components) which are represented as strings, though one could
55
+ /// theoretically set it to `\u{10FFFF}`.
56
+ ///
57
+ /// This value is useful for constructing a key range over all strings when used
58
+ /// in conjunction with [`INDEXED_KEY_LOWER_CHARACTER`].
59
+ ///
60
+ /// [1]: https://en.wikipedia.org/wiki/Plane_(Unicode)#Basic_Multilingual_Plane
61
+ const INDEXED_KEY_UPPER_CHARACTER : char = '\u{FFFF}' ;
62
+
44
63
/// Represents the [`LINKED_CHUNKS`][1] object store.
45
64
///
46
65
/// [1]: crate::event_cache_store::migrations::v1::create_linked_chunks_object_store
@@ -206,6 +225,46 @@ pub struct IndexedEvent {
206
225
pub content : IndexedEventContent ,
207
226
}
208
227
228
+ #[ derive( Debug , Error ) ]
229
+ pub enum IndexedEventError {
230
+ #[ error( "no event id" ) ]
231
+ NoEventId ,
232
+ #[ error( "crypto store: {0}" ) ]
233
+ CryptoStore ( #[ from] CryptoStoreError ) ,
234
+ }
235
+
236
+ impl Indexed for Event {
237
+ type IndexedType = IndexedEvent ;
238
+ type Error = IndexedEventError ;
239
+
240
+ fn to_indexed (
241
+ & self ,
242
+ room_id : & RoomId ,
243
+ serializer : & IndexeddbSerializer ,
244
+ ) -> Result < Self :: IndexedType , Self :: Error > {
245
+ let event_id = self . event_id ( ) . ok_or ( Self :: Error :: NoEventId ) ?;
246
+ let id = IndexedEventIdKey :: encode ( room_id, & event_id, serializer) ;
247
+ let position = self
248
+ . position ( )
249
+ . map ( |position| IndexedEventPositionKey :: encode ( room_id, & position, serializer) ) ;
250
+ let relation = self . relation ( ) . map ( |( related_event, relation_type) | {
251
+ IndexedEventRelationKey :: encode (
252
+ room_id,
253
+ & ( related_event, RelationType :: from ( relation_type) ) ,
254
+ serializer,
255
+ )
256
+ } ) ;
257
+ Ok ( IndexedEvent { id, position, relation, content : serializer. maybe_encrypt_value ( self ) ? } )
258
+ }
259
+
260
+ fn from_indexed (
261
+ indexed : Self :: IndexedType ,
262
+ serializer : & IndexeddbSerializer ,
263
+ ) -> Result < Self , Self :: Error > {
264
+ serializer. maybe_decrypt_value ( indexed. content ) . map_err ( Into :: into)
265
+ }
266
+ }
267
+
209
268
/// The value associated with the [primary key](IndexedEvent::id) of the
210
269
/// [`EVENTS`][1] object store, which is constructed from:
211
270
///
@@ -216,6 +275,30 @@ pub struct IndexedEvent {
216
275
#[ derive( Debug , Serialize , Deserialize ) ]
217
276
pub struct IndexedEventIdKey ( IndexedRoomId , IndexedEventId ) ;
218
277
278
+ impl IndexedKey < Event > for IndexedEventIdKey {
279
+ type KeyComponents = OwnedEventId ;
280
+
281
+ fn encode ( room_id : & RoomId , event_id : & OwnedEventId , serializer : & IndexeddbSerializer ) -> Self {
282
+ let room_id = serializer. encode_key_as_string ( keys:: ROOMS , room_id) ;
283
+ let event_id = serializer. encode_key_as_string ( keys:: EVENTS , event_id) ;
284
+ Self ( room_id, event_id)
285
+ }
286
+ }
287
+
288
+ impl IndexedKeyBounds < Event > for IndexedEventIdKey {
289
+ fn encode_lower ( room_id : & RoomId , serializer : & IndexeddbSerializer ) -> Self {
290
+ let room_id = serializer. encode_key_as_string ( keys:: ROOMS , room_id) ;
291
+ let event_id = String :: from ( INDEXED_KEY_LOWER_CHARACTER ) ;
292
+ Self ( room_id, event_id)
293
+ }
294
+
295
+ fn encode_upper ( room_id : & RoomId , serializer : & IndexeddbSerializer ) -> Self {
296
+ let room_id = serializer. encode_key_as_string ( keys:: ROOMS , room_id) ;
297
+ let event_id = String :: from ( INDEXED_KEY_UPPER_CHARACTER ) ;
298
+ Self ( room_id, event_id)
299
+ }
300
+ }
301
+
219
302
pub type IndexedEventId = String ;
220
303
221
304
/// The value associated with the [`position`](IndexedEvent::position) index of
@@ -229,6 +312,36 @@ pub type IndexedEventId = String;
229
312
#[ derive( Debug , Serialize , Deserialize ) ]
230
313
pub struct IndexedEventPositionKey ( IndexedRoomId , IndexedChunkId , IndexedEventPositionIndex ) ;
231
314
315
+ impl IndexedKey < Event > for IndexedEventPositionKey {
316
+ type KeyComponents = Position ;
317
+
318
+ fn encode ( room_id : & RoomId , position : & Position , serializer : & IndexeddbSerializer ) -> Self {
319
+ let room_id = serializer. encode_key_as_string ( keys:: ROOMS , room_id) ;
320
+ Self ( room_id, position. chunk_identifier , position. index )
321
+ }
322
+ }
323
+
324
+ impl IndexedKeyBounds < Event > for IndexedEventPositionKey {
325
+ fn encode_lower ( room_id : & RoomId , serializer : & IndexeddbSerializer ) -> Self {
326
+ <Self as IndexedKey < Event > >:: encode (
327
+ room_id,
328
+ & Position { chunk_identifier : 0 , index : 0 } ,
329
+ serializer,
330
+ )
331
+ }
332
+
333
+ fn encode_upper ( room_id : & RoomId , serializer : & IndexeddbSerializer ) -> Self {
334
+ <Self as IndexedKey < Event > >:: encode (
335
+ room_id,
336
+ & Position {
337
+ chunk_identifier : js_sys:: Number :: MAX_SAFE_INTEGER as u64 ,
338
+ index : js_sys:: Number :: MAX_SAFE_INTEGER as usize ,
339
+ } ,
340
+ serializer,
341
+ )
342
+ }
343
+ }
344
+
232
345
pub type IndexedEventPositionIndex = usize ;
233
346
234
347
/// The value associated with the [`relation`](IndexedEvent::relation) index of
@@ -242,6 +355,39 @@ pub type IndexedEventPositionIndex = usize;
242
355
#[ derive( Debug , Serialize , Deserialize ) ]
243
356
pub struct IndexedEventRelationKey ( IndexedRoomId , IndexedEventId , IndexedRelationType ) ;
244
357
358
+ impl IndexedKey < Event > for IndexedEventRelationKey {
359
+ type KeyComponents = ( OwnedEventId , RelationType ) ;
360
+
361
+ fn encode (
362
+ room_id : & RoomId ,
363
+ ( related_event_id, relation_type) : & ( OwnedEventId , RelationType ) ,
364
+ serializer : & IndexeddbSerializer ,
365
+ ) -> Self {
366
+ let room_id = serializer. encode_key_as_string ( keys:: ROOMS , room_id) ;
367
+ let related_event_id =
368
+ serializer. encode_key_as_string ( keys:: EVENTS_RELATION_RELATED_EVENTS , related_event_id) ;
369
+ let relation_type = serializer
370
+ . encode_key_as_string ( keys:: EVENTS_RELATION_RELATION_TYPES , relation_type. to_string ( ) ) ;
371
+ Self ( room_id, related_event_id, relation_type)
372
+ }
373
+ }
374
+
375
+ impl IndexedKeyBounds < Event > for IndexedEventRelationKey {
376
+ fn encode_lower ( room_id : & RoomId , serializer : & IndexeddbSerializer ) -> Self {
377
+ let room_id = serializer. encode_key_as_string ( keys:: ROOMS , room_id) ;
378
+ let related_event_id = String :: from ( INDEXED_KEY_LOWER_CHARACTER ) ;
379
+ let relation_type = String :: from ( INDEXED_KEY_LOWER_CHARACTER ) ;
380
+ Self ( room_id, related_event_id, relation_type)
381
+ }
382
+
383
+ fn encode_upper ( room_id : & RoomId , serializer : & IndexeddbSerializer ) -> Self {
384
+ let room_id = serializer. encode_key_as_string ( keys:: ROOMS , room_id) ;
385
+ let related_event_id = String :: from ( INDEXED_KEY_UPPER_CHARACTER ) ;
386
+ let relation_type = String :: from ( INDEXED_KEY_UPPER_CHARACTER ) ;
387
+ Self ( room_id, related_event_id, relation_type)
388
+ }
389
+ }
390
+
245
391
/// A representation of the relationship between two events (see
246
392
/// [`RelationType`](ruma::events::relation::RelationType))
247
393
pub type IndexedRelationType = String ;
0 commit comments