Skip to content

Commit 71f0862

Browse files
committed
Overlay migration
1 parent 104964e commit 71f0862

File tree

1 file changed

+102
-3
lines changed

1 file changed

+102
-3
lines changed

packages/firestore/src/local/indexeddb_schema_converter.ts

Lines changed: 102 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@
1515
* limitations under the License.
1616
*/
1717

18+
import { User } from '../auth/user';
19+
import { ListenSequence } from '../core/listen_sequence';
1820
import { SnapshotVersion } from '../core/snapshot_version';
21+
import { documentKeySet } from '../model/collections';
1922
import { DocumentKey } from '../model/document_key';
2023
import { ResourcePath } from '../model/path';
2124
import { debugAssert, fail, hardAssert } from '../util/assert';
@@ -25,10 +28,13 @@ import {
2528
decodeResourcePath,
2629
encodeResourcePath
2730
} from './encoded_resource_path';
31+
import { IndexedDbDocumentOverlayCache } from './indexeddb_document_overlay_cache';
2832
import {
2933
dbDocumentSize,
3034
removeMutationBatch
3135
} from './indexeddb_mutation_batch_impl';
36+
import { IndexedDbMutationQueue } from './indexeddb_mutation_queue';
37+
import { newIndexedDbRemoteDocumentCache } from './indexeddb_remote_document_cache';
3238
import {
3339
DbCollectionParent,
3440
DbDocumentMutation,
@@ -107,16 +113,20 @@ import {
107113
DbTargetQueryTargetsKeyPath,
108114
DbTargetStore
109115
} from './indexeddb_sentinels';
116+
import { IndexedDbTransaction } from './indexeddb_transaction';
117+
import { LocalDocumentsView } from './local_documents_view';
110118
import {
111119
fromDbMutationBatch,
112120
fromDbTarget,
113121
LocalSerializer,
114122
toDbTarget
115123
} from './local_serializer';
116124
import { MemoryCollectionParentIndex } from './memory_index_manager';
125+
import { MemoryEagerDelegate, MemoryPersistence } from './memory_persistence';
117126
import { PersistencePromise } from './persistence_promise';
118127
import { SimpleDbSchemaConverter, SimpleDbTransaction } from './simple_db';
119128

129+
120130
/** Performs database creation and schema upgrades. */
121131
export class SchemaConverter implements SimpleDbSchemaConverter {
122132
constructor(private readonly serializer: LocalSerializer) {}
@@ -240,9 +250,9 @@ export class SchemaConverter implements SimpleDbSchemaConverter {
240250
}
241251

242252
if (fromVersion < 14 && toVersion >= 14) {
243-
p = p.next(() => {
244-
createFieldIndex(db);
245-
});
253+
p = p
254+
.next(() => createFieldIndex(db))
255+
.next(() => this.runOverlayMigration(db, simpleDbTransaction));
246256
}
247257

248258
return p;
@@ -455,6 +465,95 @@ export class SchemaConverter implements SimpleDbSchemaConverter {
455465
})
456466
.next(() => PersistencePromise.waitFor(writes));
457467
}
468+
469+
private runOverlayMigration(
470+
db: IDBDatabase,
471+
transaction: SimpleDbTransaction
472+
): PersistencePromise<void> {
473+
const queuesStore = transaction.store<DbMutationQueueKey, DbMutationQueue>(
474+
DbMutationQueueStore
475+
);
476+
const mutationsStore = transaction.store<
477+
DbMutationBatchKey,
478+
DbMutationBatch
479+
>(DbMutationBatchStore);
480+
481+
const promises: Array<PersistencePromise<void>> = [];
482+
let userIds = new Set<string>();
483+
484+
return queuesStore
485+
.loadAll()
486+
.next(queues => {
487+
for (const queue of queues) {
488+
userIds = userIds.add(queue.userId);
489+
}
490+
})
491+
.next(() => {
492+
userIds.forEach(userId => {
493+
const user = new User(userId);
494+
const remoteDocumentCache = newIndexedDbRemoteDocumentCache(
495+
this.serializer
496+
);
497+
const documentOverlayCache = IndexedDbDocumentOverlayCache.forUser(
498+
this.serializer,
499+
user
500+
);
501+
let allDocumentKeysForUser = documentKeySet();
502+
const range = IDBKeyRange.bound(
503+
[userId, BATCHID_UNKNOWN],
504+
[userId, Number.POSITIVE_INFINITY]
505+
);
506+
promises.push(
507+
mutationsStore
508+
.loadAll(DbMutationBatchUserMutationsIndex, range)
509+
.next(dbBatches => {
510+
dbBatches.forEach(dbBatch => {
511+
hardAssert(
512+
dbBatch.userId === userId,
513+
`Cannot process batch ${dbBatch.batchId} from unexpected user`
514+
);
515+
const batch = fromDbMutationBatch(this.serializer, dbBatch);
516+
batch
517+
.keys()
518+
.forEach(
519+
key =>
520+
(allDocumentKeysForUser =
521+
allDocumentKeysForUser.add(key))
522+
);
523+
});
524+
})
525+
.next(() => {
526+
// NOTE: The index manager and the reference delegate are
527+
// irrelevant for the purpose of recalculating and saving
528+
// overlays. We can therefore simply use the memory
529+
// implementation.
530+
const memoryPersistence = new MemoryPersistence(
531+
MemoryEagerDelegate.factory,
532+
this.serializer.remoteSerializer
533+
);
534+
const indexManager = memoryPersistence.getIndexManager(user);
535+
const mutationQueue = IndexedDbMutationQueue.forUser(
536+
user,
537+
this.serializer,
538+
indexManager,
539+
memoryPersistence.referenceDelegate
540+
);
541+
const localDocumentsView = new LocalDocumentsView(
542+
remoteDocumentCache,
543+
mutationQueue,
544+
documentOverlayCache,
545+
indexManager
546+
);
547+
return localDocumentsView.recalculateAndSaveOverlaysForDocumentKeys(
548+
new IndexedDbTransaction(transaction, ListenSequence.INVALID),
549+
allDocumentKeysForUser
550+
);
551+
})
552+
);
553+
});
554+
})
555+
.next(() => PersistencePromise.waitFor(promises));
556+
}
458557
}
459558

460559
function sentinelKey(path: ResourcePath): DbTargetDocumentKey {

0 commit comments

Comments
 (0)