15
15
* limitations under the License.
16
16
*/
17
17
18
+ import { User } from '../auth/user' ;
19
+ import { ListenSequence } from '../core/listen_sequence' ;
18
20
import { SnapshotVersion } from '../core/snapshot_version' ;
21
+ import {
22
+ DocumentKeyMap ,
23
+ DocumentKeySet ,
24
+ documentKeySet
25
+ } from '../model/collections' ;
19
26
import { DocumentKey } from '../model/document_key' ;
27
+ import { FieldMask } from '../model/field_mask' ;
20
28
import { ResourcePath } from '../model/path' ;
21
29
import { debugAssert , fail , hardAssert } from '../util/assert' ;
22
30
import { BATCHID_UNKNOWN } from '../util/types' ;
@@ -25,10 +33,13 @@ import {
25
33
decodeResourcePath ,
26
34
encodeResourcePath
27
35
} from './encoded_resource_path' ;
36
+ import { IndexedDbDocumentOverlayCache } from './indexeddb_document_overlay_cache' ;
28
37
import {
29
38
dbDocumentSize ,
30
39
removeMutationBatch
31
40
} from './indexeddb_mutation_batch_impl' ;
41
+ import { IndexedDbMutationQueue } from './indexeddb_mutation_queue' ;
42
+ import { newIndexedDbRemoteDocumentCache } from './indexeddb_remote_document_cache' ;
32
43
import {
33
44
DbCollectionParent ,
34
45
DbDocumentMutation ,
@@ -107,13 +118,16 @@ import {
107
118
DbTargetQueryTargetsKeyPath ,
108
119
DbTargetStore
109
120
} from './indexeddb_sentinels' ;
121
+ import { IndexedDbTransaction } from './indexeddb_transaction' ;
122
+ import { LocalDocumentsView } from './local_documents_view' ;
110
123
import {
111
124
fromDbMutationBatch ,
112
125
fromDbTarget ,
113
126
LocalSerializer ,
114
127
toDbTarget
115
128
} from './local_serializer' ;
116
129
import { MemoryCollectionParentIndex } from './memory_index_manager' ;
130
+ import { MemoryEagerDelegate , MemoryPersistence } from './memory_persistence' ;
117
131
import { PersistencePromise } from './persistence_promise' ;
118
132
import { SimpleDbSchemaConverter , SimpleDbTransaction } from './simple_db' ;
119
133
@@ -240,9 +254,11 @@ export class SchemaConverter implements SimpleDbSchemaConverter {
240
254
}
241
255
242
256
if ( fromVersion < 14 && toVersion >= 14 ) {
243
- p = p . next ( ( ) => {
244
- createFieldIndex ( db ) ;
245
- } ) ;
257
+ p = p . next ( ( ) => this . runOverlayMigration ( db , simpleDbTransaction ) ) ;
258
+ }
259
+
260
+ if ( fromVersion < 15 && toVersion >= 15 ) {
261
+ p = p . next ( ( ) => createFieldIndex ( db ) ) ;
246
262
}
247
263
248
264
return p ;
@@ -455,6 +471,74 @@ export class SchemaConverter implements SimpleDbSchemaConverter {
455
471
} )
456
472
. next ( ( ) => PersistencePromise . waitFor ( writes ) ) ;
457
473
}
474
+
475
+ private runOverlayMigration (
476
+ db : IDBDatabase ,
477
+ transaction : SimpleDbTransaction
478
+ ) : PersistencePromise < void > {
479
+ const mutationsStore = transaction . store <
480
+ DbMutationBatchKey ,
481
+ DbMutationBatch
482
+ > ( DbMutationBatchStore ) ;
483
+
484
+ const remoteDocumentCache = newIndexedDbRemoteDocumentCache (
485
+ this . serializer
486
+ ) ;
487
+ const memoryPersistence = new MemoryPersistence (
488
+ MemoryEagerDelegate . factory ,
489
+ this . serializer . remoteSerializer
490
+ ) ;
491
+
492
+ const promises : Array <
493
+ PersistencePromise < DocumentKeyMap < FieldMask | null > >
494
+ > = [ ] ;
495
+ const userToDocumentSet = new Map < string , DocumentKeySet > ( ) ;
496
+
497
+ return mutationsStore
498
+ . loadAll ( )
499
+ . next ( dbBatches => {
500
+ dbBatches . forEach ( dbBatch => {
501
+ let documentSet =
502
+ userToDocumentSet . get ( dbBatch . userId ) ?? documentKeySet ( ) ;
503
+ const batch = fromDbMutationBatch ( this . serializer , dbBatch ) ;
504
+ batch . keys ( ) . forEach ( key => ( documentSet = documentSet . add ( key ) ) ) ;
505
+ userToDocumentSet . set ( dbBatch . userId , documentSet ) ;
506
+ } ) ;
507
+ } )
508
+ . next ( ( ) => {
509
+ userToDocumentSet . forEach ( ( allDocumentKeysForUser , userId ) => {
510
+ const user = new User ( userId ) ;
511
+ const documentOverlayCache = IndexedDbDocumentOverlayCache . forUser (
512
+ this . serializer ,
513
+ user
514
+ ) ;
515
+ // NOTE: The index manager and the reference delegate are
516
+ // irrelevant for the purpose of recalculating and saving
517
+ // overlays. We can therefore simply use the memory
518
+ // implementation.
519
+ const indexManager = memoryPersistence . getIndexManager ( user ) ;
520
+ const mutationQueue = IndexedDbMutationQueue . forUser (
521
+ user ,
522
+ this . serializer ,
523
+ indexManager ,
524
+ memoryPersistence . referenceDelegate
525
+ ) ;
526
+ const localDocumentsView = new LocalDocumentsView (
527
+ remoteDocumentCache ,
528
+ mutationQueue ,
529
+ documentOverlayCache ,
530
+ indexManager
531
+ ) ;
532
+ promises . push (
533
+ localDocumentsView . recalculateAndSaveOverlaysForDocumentKeys (
534
+ new IndexedDbTransaction ( transaction , ListenSequence . INVALID ) ,
535
+ allDocumentKeysForUser
536
+ )
537
+ ) ;
538
+ } ) ;
539
+ } )
540
+ . next ( ( ) => PersistencePromise . waitFor ( promises ) ) ;
541
+ }
458
542
}
459
543
460
544
function sentinelKey ( path : ResourcePath ) : DbTargetDocumentKey {
0 commit comments