-
Notifications
You must be signed in to change notification settings - Fork 938
Implement sequence number migration #1374
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ import { SnapshotVersion } from '../core/snapshot_version'; | |
import { BATCHID_UNKNOWN } from '../model/mutation_batch'; | ||
import { encode, EncodedResourcePath } from './encoded_resource_path'; | ||
import { removeMutationBatch } from './indexeddb_mutation_queue'; | ||
import { getHighestListenSequenceNumber } from './indexeddb_query_cache'; | ||
import { dbDocumentSize } from './indexeddb_remote_document_cache'; | ||
import { LocalSerializer } from './local_serializer'; | ||
import { PersistencePromise } from './persistence_promise'; | ||
|
@@ -39,8 +40,10 @@ import { SimpleDbSchemaConverter, SimpleDbTransaction } from './simple_db'; | |
* https://github.com/firebase/firebase-ios-sdk/issues/1548 | ||
* 4. Multi-Tab Support. | ||
* 5. Removal of held write acks. | ||
* 6. Create document global for tracking document cache size. | ||
* 7. Ensure every cached document has a sentinel row with a sequence number. | ||
*/ | ||
export const SCHEMA_VERSION = 6; | ||
export const SCHEMA_VERSION = 7; | ||
|
||
/** Performs database creation and schema upgrades. */ | ||
export class SchemaConverter implements SimpleDbSchemaConverter { | ||
|
@@ -115,6 +118,10 @@ export class SchemaConverter implements SimpleDbSchemaConverter { | |
}); | ||
} | ||
|
||
if (fromVersion < 7 && toVersion >= 7) { | ||
p = p.next(() => this.ensureSequenceNumbers(txn)); | ||
} | ||
|
||
return p; | ||
} | ||
|
||
|
@@ -172,6 +179,53 @@ export class SchemaConverter implements SimpleDbSchemaConverter { | |
}); | ||
}); | ||
} | ||
|
||
/** | ||
* Ensures that every document in the remote document cache has a corresponding sentinel row | ||
* with a sequence number. Missing rows are given the most recently used sequence number. | ||
*/ | ||
private ensureSequenceNumbers( | ||
txn: SimpleDbTransaction | ||
): PersistencePromise<void> { | ||
const documentTargetStore = txn.store< | ||
DbTargetDocumentKey, | ||
DbTargetDocument | ||
>(DbTargetDocument.store); | ||
const documentsStore = txn.store<DbRemoteDocumentKey, DbRemoteDocument>( | ||
DbRemoteDocument.store | ||
); | ||
|
||
return getHighestListenSequenceNumber(txn).next(currentSequenceNumber => { | ||
const writeSentinelKey = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this would be easier to read if a) this was declared one level higher (as a direct child of Optional. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaving as-is. It can't go in a higher scope as it closes over the result of |
||
path: ResourcePath | ||
): PersistencePromise<void> => { | ||
return documentTargetStore.put( | ||
new DbTargetDocument(0, encode(path), currentSequenceNumber) | ||
); | ||
}; | ||
|
||
const promises: Array<PersistencePromise<void>> = []; | ||
return documentsStore | ||
.iterate((key, doc) => { | ||
const path = new ResourcePath(key); | ||
const docSentinelKey = sentinelKey(path); | ||
promises.push( | ||
documentTargetStore.get(docSentinelKey).next(maybeSentinel => { | ||
if (!maybeSentinel) { | ||
return writeSentinelKey(path); | ||
} else { | ||
return PersistencePromise.resolve(); | ||
} | ||
}) | ||
); | ||
}) | ||
.next(() => PersistencePromise.waitFor(promises)); | ||
}); | ||
} | ||
} | ||
|
||
function sentinelKey(path: ResourcePath): DbTargetDocumentKey { | ||
return [0, encode(path)]; | ||
} | ||
|
||
// TODO(mikelehen): Get rid of "as any" if/when TypeScript fixes their types. | ||
|
Uh oh!
There was an error while loading. Please reload this page.