@@ -15,7 +15,7 @@ use matrix_sdk_store_encryption::StoreCipher;
15
15
use ruma:: { MilliSecondsSinceUnixEpoch , RoomId } ;
16
16
use rusqlite:: { OptionalExtension , Transaction } ;
17
17
use tokio:: fs;
18
- use tracing:: debug;
18
+ use tracing:: { debug, trace } ;
19
19
20
20
use crate :: {
21
21
error:: { Error , Result } ,
@@ -201,20 +201,35 @@ impl EventCacheStore for SqliteEventCacheStore {
201
201
room_id : & RoomId ,
202
202
updates : & [ Update < Event , Gap > ] ,
203
203
) -> Result < ( ) , Self :: Error > {
204
- let room_id = self . encode_key ( keys:: LINKED_CHUNKS , room_id) ;
204
+ let hashed_room_id = self . encode_key ( keys:: LINKED_CHUNKS , room_id) ;
205
205
206
206
for up in updates {
207
207
match up {
208
208
Update :: NewItemsChunk { previous, new, next } => {
209
209
let new = new. clone ( ) ;
210
210
let previous = previous. clone ( ) ;
211
211
let next = next. clone ( ) ;
212
- let room_id = room_id. clone ( ) ;
212
+ let hashed_room_id = hashed_room_id. clone ( ) ;
213
+
214
+ trace ! (
215
+ %room_id,
216
+ "new events chunk (prev={:?}, i={}, next={:?})" ,
217
+ previous. as_ref( ) . map( ChunkIdentifier :: index) ,
218
+ new. index( ) ,
219
+ next. as_ref( ) . map( ChunkIdentifier :: index)
220
+ ) ;
213
221
214
222
self . acquire ( )
215
223
. await ?
216
224
. with_transaction ( move |txn| {
217
- insert_chunk ( txn, & room_id, previous. as_ref ( ) , new, next. as_ref ( ) , "E" )
225
+ insert_chunk (
226
+ txn,
227
+ & hashed_room_id,
228
+ previous. as_ref ( ) ,
229
+ new,
230
+ next. as_ref ( ) ,
231
+ "E" ,
232
+ )
218
233
} )
219
234
. await ?;
220
235
}
@@ -223,17 +238,26 @@ impl EventCacheStore for SqliteEventCacheStore {
223
238
let new = new. clone ( ) ;
224
239
let previous = previous. clone ( ) ;
225
240
let next = next. clone ( ) ;
226
- let room_id = room_id. clone ( ) ;
241
+ let hashed_room_id = hashed_room_id. clone ( ) ;
242
+
243
+ let serialized = serde_json:: to_vec ( & gap. prev_token ) ?;
244
+ let prev_token = self . encode_value ( serialized) ?;
227
245
228
- let prev_token = self . encode_value ( gap. prev_token . clone ( ) . into_bytes ( ) ) ?;
246
+ trace ! (
247
+ %room_id,
248
+ "new gap chunk (prev={:?}, i={}, next={:?})" ,
249
+ previous. as_ref( ) . map( ChunkIdentifier :: index) ,
250
+ new. index( ) ,
251
+ next. as_ref( ) . map( ChunkIdentifier :: index)
252
+ ) ;
229
253
230
254
self . acquire ( )
231
255
. await ?
232
256
. with_transaction ( move |txn| -> rusqlite:: Result < ( ) > {
233
257
// Insert the chunk as a gap.
234
258
insert_chunk (
235
259
txn,
236
- & room_id ,
260
+ & hashed_room_id ,
237
261
previous. as_ref ( ) ,
238
262
new,
239
263
next. as_ref ( ) ,
@@ -248,7 +272,7 @@ impl EventCacheStore for SqliteEventCacheStore {
248
272
INSERT INTO gaps(chunk_id, room_id, prev_token)
249
273
VALUES (?, ?, ?)
250
274
"# ,
251
- ( new. index ( ) , room_id , prev_token) ,
275
+ ( new. index ( ) , hashed_room_id , prev_token) ,
252
276
) ?;
253
277
254
278
Ok ( ( ) )
@@ -257,32 +281,34 @@ impl EventCacheStore for SqliteEventCacheStore {
257
281
}
258
282
259
283
Update :: RemoveChunk ( chunk_identifier) => {
260
- let room_id = room_id . clone ( ) ;
284
+ let hashed_room_id = hashed_room_id . clone ( ) ;
261
285
let chunk_id = chunk_identifier. index ( ) ;
262
286
287
+ trace ! ( %room_id, "removing chunk @ {chunk_id}" ) ;
288
+
263
289
self . acquire ( )
264
290
. await ?
265
291
. with_transaction ( move |txn| -> rusqlite:: Result < ( ) > {
266
292
// Find chunk to delete.
267
293
let ( previous, next) : ( Option < usize > , Option < usize > ) = txn. query_row (
268
294
"SELECT previous, next FROM linked_chunks WHERE id = ? AND room_id = ?" ,
269
- ( chunk_id, & room_id ) ,
295
+ ( chunk_id, & hashed_room_id ) ,
270
296
|row| Ok ( ( row. get ( 0 ) ?, row. get ( 1 ) ?) )
271
297
) ?;
272
298
273
299
// Replace its previous' next to its own next.
274
300
if let Some ( previous) = previous {
275
- txn. execute ( "UPDATE linked_chunks SET next = ? WHERE id = ? AND room_id = ?" , ( next, previous, & room_id ) ) ?;
301
+ txn. execute ( "UPDATE linked_chunks SET next = ? WHERE id = ? AND room_id = ?" , ( next, previous, & hashed_room_id ) ) ?;
276
302
}
277
303
278
304
// Replace its next' previous to its own previous.
279
305
if let Some ( next) = next {
280
- txn. execute ( "UPDATE linked_chunks SET previous = ? WHERE id = ? AND room_id = ?" , ( previous, next, & room_id ) ) ?;
306
+ txn. execute ( "UPDATE linked_chunks SET previous = ? WHERE id = ? AND room_id = ?" , ( previous, next, & hashed_room_id ) ) ?;
281
307
}
282
308
283
309
// Now delete it, and let cascading delete corresponding entries in the
284
310
// other data tables.
285
- txn. execute ( "DELETE FROM linked_chunks WHERE id = ? AND room_id = ?" , ( chunk_id, room_id ) ) ?;
311
+ txn. execute ( "DELETE FROM linked_chunks WHERE id = ? AND room_id = ?" , ( chunk_id, hashed_room_id ) ) ?;
286
312
287
313
Ok ( ( ) )
288
314
} )
@@ -291,7 +317,9 @@ impl EventCacheStore for SqliteEventCacheStore {
291
317
292
318
Update :: PushItems { at, items } => {
293
319
let chunk_id = at. chunk_identifier ( ) . index ( ) ;
294
- let room_id = room_id. clone ( ) ;
320
+ let hashed_room_id = hashed_room_id. clone ( ) ;
321
+
322
+ trace ! ( %room_id, "pushing items @ {chunk_id}" ) ;
295
323
296
324
let entries = items
297
325
. into_iter ( )
@@ -301,7 +329,7 @@ impl EventCacheStore for SqliteEventCacheStore {
301
329
let raw = self . encode_value ( serialized) ?;
302
330
let event_id = event. event_id ( ) . map ( |event_id| event_id. to_string ( ) ) ;
303
331
let index = at. index ( ) + i;
304
- Ok ( ( chunk_id , event_id, raw, index) )
332
+ Ok ( ( event_id, raw, index) )
305
333
} )
306
334
. collect :: < Result < Vec < _ > , _ > > ( ) ?;
307
335
@@ -311,10 +339,10 @@ impl EventCacheStore for SqliteEventCacheStore {
311
339
for entry in entries {
312
340
txn. execute (
313
341
r#"
314
- INSERT INTO events(chunk_id, room_id, event_id, raw, index )
315
- VALUES (?, ?, ?, ?)
342
+ INSERT INTO events(chunk_id, room_id, event_id, raw, position )
343
+ VALUES (?, ?, ?, ?, ? )
316
344
"# ,
317
- ( entry . 0 , & room_id , entry. 1 , entry. 2 , entry. 3 ) ,
345
+ ( chunk_id , & hashed_room_id , entry. 0 , entry. 1 , entry. 2 ) ,
318
346
) ?;
319
347
}
320
348
@@ -324,25 +352,27 @@ impl EventCacheStore for SqliteEventCacheStore {
324
352
}
325
353
326
354
Update :: RemoveItem { at } => {
327
- let room_id = room_id . clone ( ) ;
355
+ let hashed_room_id = hashed_room_id . clone ( ) ;
328
356
let chunk_id = at. chunk_identifier ( ) . index ( ) ;
329
357
let index = at. index ( ) ;
330
358
359
+ trace ! ( %room_id, "removing item @ {chunk_id}:{index}" ) ;
360
+
331
361
self . acquire ( )
332
362
. await ?
333
363
. with_transaction ( move |txn| -> rusqlite:: Result < ( ) > {
334
364
// Remove the entry.
335
- txn. execute ( "DELETE FROM events WHERE room_id = ? AND chunk_id = ? AND index = ?" , ( & room_id , chunk_id, index) ) ?;
365
+ txn. execute ( "DELETE FROM events WHERE room_id = ? AND chunk_id = ? AND position = ?" , ( & hashed_room_id , chunk_id, index) ) ?;
336
366
337
367
// Decrement the index of each item after the one we're going to
338
368
// remove.
339
369
txn. execute (
340
370
r#"
341
371
UPDATE events
342
- SET index = index - 1
343
- WHERE room_id = ? AND chunk_id = ? AND index > ?
372
+ SET position = position - 1
373
+ WHERE room_id = ? AND chunk_id = ? AND position > ?
344
374
"# ,
345
- ( & room_id , chunk_id, index)
375
+ ( & hashed_room_id , chunk_id, index)
346
376
) ?;
347
377
348
378
Ok ( ( ) )
@@ -351,15 +381,17 @@ impl EventCacheStore for SqliteEventCacheStore {
351
381
}
352
382
353
383
Update :: DetachLastItems { at } => {
354
- let room_id = room_id . clone ( ) ;
384
+ let hashed_room_id = hashed_room_id . clone ( ) ;
355
385
let chunk_id = at. chunk_identifier ( ) . index ( ) ;
356
386
let index = at. index ( ) ;
357
387
388
+ trace ! ( %room_id, "truncating items >= {chunk_id}:{index}" ) ;
389
+
358
390
self . acquire ( )
359
391
. await ?
360
392
. with_transaction ( move |txn| -> rusqlite:: Result < ( ) > {
361
393
// Remove these entries.
362
- txn. execute ( "DELETE FROM events WHERE room_id = ? AND chunk_id = ? AND index >= ?" , ( & room_id , chunk_id, index) ) ?;
394
+ txn. execute ( "DELETE FROM events WHERE room_id = ? AND chunk_id = ? AND position >= ?" , ( & hashed_room_id , chunk_id, index) ) ?;
363
395
Ok ( ( ) )
364
396
} )
365
397
. await ?;
@@ -391,8 +423,11 @@ impl EventCacheStore for SqliteEventCacheStore {
391
423
async fn reload_linked_chunk (
392
424
& self ,
393
425
room_id : & RoomId ,
394
- ) -> Result < LinkedChunk < DEFAULT_CHUNK_CAPACITY , Event , Gap > , Self :: Error > {
395
- let room_id = self . encode_key ( keys:: LINKED_CHUNKS , room_id) ;
426
+ ) -> Result < Option < LinkedChunk < DEFAULT_CHUNK_CAPACITY , Event , Gap > > , Self :: Error > {
427
+ let room_id = room_id. to_owned ( ) ;
428
+ let hashed_room_id = self . encode_key ( keys:: LINKED_CHUNKS , & room_id) ;
429
+
430
+ let this = self . clone ( ) ;
396
431
397
432
let result = self
398
433
. acquire ( )
@@ -404,7 +439,7 @@ impl EventCacheStore for SqliteEventCacheStore {
404
439
. prepare (
405
440
"SELECT id, previous, next, type FROM linked_chunks WHERE room_id = ?" ,
406
441
) ?
407
- . query_map ( ( & room_id , ) , |row| {
442
+ . query_map ( ( & hashed_room_id , ) , |row| {
408
443
Ok ( (
409
444
row. get :: < _ , u64 > ( 0 ) ?,
410
445
row. get :: < _ , Option < u64 > > ( 1 ) ?,
@@ -415,15 +450,19 @@ impl EventCacheStore for SqliteEventCacheStore {
415
450
{
416
451
let ( id, previous, next, chunk_type) = data?;
417
452
453
+ trace ! ( %room_id, "reloaded chunk {id} of type {chunk_type}" ) ;
454
+
418
455
match chunk_type. as_str ( ) {
419
456
"G" => {
420
457
// It's a gap! There's at most one row for it in the database, so a
421
458
// call to `query_row` is sufficient.
422
- let prev_token : String = txn. query_row (
459
+ let encoded_prev_token : Vec < u8 > = txn. query_row (
423
460
"SELECT prev_token FROM gaps WHERE chunk_id = ? AND room_id = ?" ,
424
- ( id, & room_id ) ,
461
+ ( id, & hashed_room_id ) ,
425
462
|row| row. get ( 0 ) ,
426
463
) ?;
464
+ let prev_token_bytes = this. decode_value ( & encoded_prev_token) ?;
465
+ let prev_token = serde_json:: from_slice ( & prev_token_bytes) ?;
427
466
428
467
let previous = previous. map ( ChunkIdentifier :: from_raw) ;
429
468
let next = next. map ( ChunkIdentifier :: from_raw) ;
@@ -444,12 +483,13 @@ impl EventCacheStore for SqliteEventCacheStore {
444
483
r#"
445
484
SELECT raw FROM events
446
485
WHERE chunk_id = ? AND room_id = ?
447
- ORDER BY index ASC
486
+ ORDER BY position ASC
448
487
"# ,
449
488
) ?
450
- . query_map ( ( id, & room_id ) , |row| row. get :: < _ , Vec < u8 > > ( 0 ) ) ?
489
+ . query_map ( ( id, & hashed_room_id ) , |row| row. get :: < _ , Vec < u8 > > ( 0 ) ) ?
451
490
{
452
- let raw = event_data?;
491
+ let encoded_raw = event_data?;
492
+ let raw = this. decode_value ( & encoded_raw) ?;
453
493
let raw_event = serde_json:: from_slice ( & raw ) ?;
454
494
455
495
// TODO: keep encryption information around!
@@ -473,7 +513,7 @@ impl EventCacheStore for SqliteEventCacheStore {
473
513
474
514
builder. set_observable ( ) ;
475
515
476
- Ok ( builder. build ( ) . unwrap_or_default ( ) )
516
+ Ok ( builder. build ( ) )
477
517
} )
478
518
. await ?;
479
519
0 commit comments