Skip to content

Commit 8c56c25

Browse files
Make Documents mutable (#4548)
1 parent bce35ce commit 8c56c25

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+1719
-2253
lines changed

packages/firestore/src/core/bundle.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717

1818
import { LoadBundleTaskProgress } from '@firebase/firestore-types';
1919

20-
import { MaybeDocumentMap } from '../model/collections';
21-
import { MaybeDocument } from '../model/document';
20+
import { DocumentMap } from '../model/collections';
21+
import { MutableDocument } from '../model/document';
2222
import { DocumentKey } from '../model/document_key';
2323
import { BundledDocumentMetadata as ProtoBundledDocumentMetadata } from '../protos/firestore_bundle_proto';
2424
import {
@@ -46,7 +46,7 @@ export type BundledDocuments = BundledDocument[];
4646
export class BundleLoadResult {
4747
constructor(
4848
readonly progress: LoadBundleTaskProgress,
49-
readonly changedDocs: MaybeDocumentMap
49+
readonly changedDocs: DocumentMap
5050
) {}
5151
}
5252

@@ -89,9 +89,9 @@ export interface BundleConverter {
8989
toDocumentKey(name: string): DocumentKey;
9090

9191
/**
92-
* Converts a BundleDocument to a MaybeDocument.
92+
* Converts a BundleDocument to a MutableDocument.
9393
*/
94-
toMaybeDocument(bundledDoc: BundledDocument): MaybeDocument;
94+
toMutableDocument(bundledDoc: BundledDocument): MutableDocument;
9595

9696
toSnapshotVersion(time: ApiTimestamp): SnapshotVersion;
9797
}

packages/firestore/src/core/bundle_impl.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
localStoreSaveNamedQuery
2424
} from '../local/local_store_impl';
2525
import { documentKeySet, DocumentKeySet } from '../model/collections';
26-
import { MaybeDocument, NoDocument } from '../model/document';
26+
import { MutableDocument } from '../model/document';
2727
import { DocumentKey } from '../model/document_key';
2828
import {
2929
BundleMetadata as ProtoBundleMetadata,
@@ -58,17 +58,17 @@ export class BundleConverterImpl implements BundleConverter {
5858
}
5959

6060
/**
61-
* Converts a BundleDocument to a MaybeDocument.
61+
* Converts a BundleDocument to a MutableDocument.
6262
*/
63-
toMaybeDocument(bundledDoc: BundledDocument): MaybeDocument {
63+
toMutableDocument(bundledDoc: BundledDocument): MutableDocument {
6464
if (bundledDoc.metadata.exists) {
6565
debugAssert(
6666
!!bundledDoc.document,
6767
'Document is undefined when metadata.exist is true.'
6868
);
6969
return fromDocument(this.serializer, bundledDoc.document!, false);
7070
} else {
71-
return new NoDocument(
71+
return MutableDocument.newNoDocument(
7272
this.toDocumentKey(bundledDoc.metadata.name!),
7373
this.toSnapshotVersion(bundledDoc.metadata.readTime!)
7474
);

packages/firestore/src/core/firestore_client.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
localStoreReadDocument
3232
} from '../local/local_store_impl';
3333
import { Persistence } from '../local/persistence';
34-
import { Document, NoDocument } from '../model/document';
34+
import { Document } from '../model/document';
3535
import { DocumentKey } from '../model/document_key';
3636
import { Mutation } from '../model/mutation';
3737
import { toByteStreamReader } from '../platform/byte_stream_reader';
@@ -498,10 +498,10 @@ async function readDocumentFromCache(
498498
result: Deferred<Document | null>
499499
): Promise<void> {
500500
try {
501-
const maybeDoc = await localStoreReadDocument(localStore, docKey);
502-
if (maybeDoc instanceof Document) {
503-
result.resolve(maybeDoc);
504-
} else if (maybeDoc instanceof NoDocument) {
501+
const document = await localStoreReadDocument(localStore, docKey);
502+
if (document.isFoundDocument()) {
503+
result.resolve(document);
504+
} else if (document.isNoDocument()) {
505505
result.resolve(null);
506506
} else {
507507
result.reject(

packages/firestore/src/core/query.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,7 @@ export function stringifyQuery(query: Query): string {
456456
/** Returns whether `doc` matches the constraints of `query`. */
457457
export function queryMatches(query: Query, doc: Document): boolean {
458458
return (
459+
doc.isFoundDocument() &&
459460
queryMatchesPathAndCollectionGroup(query, doc) &&
460461
queryMatchesOrderBy(query, doc) &&
461462
queryMatchesFilters(query, doc) &&
@@ -491,7 +492,7 @@ function queryMatchesPathAndCollectionGroup(
491492
function queryMatchesOrderBy(query: Query, doc: Document): boolean {
492493
for (const orderBy of query.explicitOrderBy) {
493494
// order by key always matches
494-
if (!orderBy.field.isKeyField() && doc.field(orderBy.field) === null) {
495+
if (!orderBy.field.isKeyField() && doc.data.field(orderBy.field) === null) {
495496
return false;
496497
}
497498
}

packages/firestore/src/core/sync_engine_impl.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ import { TargetData, TargetPurpose } from '../local/target_data';
4545
import {
4646
DocumentKeySet,
4747
documentKeySet,
48-
MaybeDocumentMap
48+
DocumentMap
4949
} from '../model/collections';
50-
import { MaybeDocument, NoDocument } from '../model/document';
50+
import { MutableDocument } from '../model/document';
5151
import { DocumentKey } from '../model/document_key';
5252
import { Mutation } from '../model/mutation';
5353
import { MutationBatchResult } from '../model/mutation_batch';
@@ -161,7 +161,7 @@ class LimboResolution {
161161
*/
162162
type ApplyDocChangesHandler = (
163163
queryView: QueryView,
164-
changes: MaybeDocumentMap,
164+
changes: DocumentMap,
165165
remoteEvent?: RemoteEvent
166166
) => Promise<ViewSnapshot | undefined>;
167167

@@ -618,12 +618,12 @@ export async function syncEngineRejectListen(
618618
// This is kind of a hack. Ideally, we would have a method in the local
619619
// store to purge a document. However, it would be tricky to keep all of
620620
// the local store's invariants with another method.
621-
let documentUpdates = new SortedMap<DocumentKey, MaybeDocument>(
621+
let documentUpdates = new SortedMap<DocumentKey, MutableDocument>(
622622
DocumentKey.comparator
623623
);
624624
documentUpdates = documentUpdates.insert(
625625
limboKey,
626-
new NoDocument(limboKey, SnapshotVersion.min())
626+
MutableDocument.newNoDocument(limboKey, SnapshotVersion.min())
627627
);
628628
const resolvedLimboDocuments = documentKeySet().add(limboKey);
629629
const event = new RemoteEvent(
@@ -1001,7 +1001,7 @@ export function syncEngineGetEnqueuedLimboDocumentResolutions(
10011001

10021002
export async function syncEngineEmitNewSnapsAndNotifyLocalStore(
10031003
syncEngine: SyncEngine,
1004-
changes: MaybeDocumentMap,
1004+
changes: DocumentMap,
10051005
remoteEvent?: RemoteEvent
10061006
): Promise<void> {
10071007
const syncEngineImpl = debugCast(syncEngine, SyncEngineImpl);
@@ -1052,7 +1052,7 @@ export async function syncEngineEmitNewSnapsAndNotifyLocalStore(
10521052
async function applyDocChanges(
10531053
syncEngineImpl: SyncEngineImpl,
10541054
queryView: QueryView,
1055-
changes: MaybeDocumentMap,
1055+
changes: DocumentMap,
10561056
remoteEvent?: RemoteEvent
10571057
): Promise<ViewSnapshot | undefined> {
10581058
let viewDocChanges = queryView.view.computeDocChanges(changes);

packages/firestore/src/core/target.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ export class FieldFilter extends Filter {
298298
}
299299

300300
matches(doc: Document): boolean {
301-
const other = doc.field(this.field);
301+
const other = doc.data.field(this.field);
302302
// Types do not have to match in NOT_EQUAL filters.
303303
if (this.op === Operator.NOT_EQUAL) {
304304
return (
@@ -459,7 +459,7 @@ export class ArrayContainsFilter extends FieldFilter {
459459
}
460460

461461
matches(doc: Document): boolean {
462-
const other = doc.field(this.field);
462+
const other = doc.data.field(this.field);
463463
return isArray(other) && arrayValueContains(other.arrayValue, this.value);
464464
}
465465
}
@@ -472,7 +472,7 @@ export class InFilter extends FieldFilter {
472472
}
473473

474474
matches(doc: Document): boolean {
475-
const other = doc.field(this.field);
475+
const other = doc.data.field(this.field);
476476
return other !== null && arrayValueContains(this.value.arrayValue!, other);
477477
}
478478
}
@@ -490,7 +490,7 @@ export class NotInFilter extends FieldFilter {
490490
) {
491491
return false;
492492
}
493-
const other = doc.field(this.field);
493+
const other = doc.data.field(this.field);
494494
return other !== null && !arrayValueContains(this.value.arrayValue!, other);
495495
}
496496
}
@@ -503,7 +503,7 @@ export class ArrayContainsAnyFilter extends FieldFilter {
503503
}
504504

505505
matches(doc: Document): boolean {
506-
const other = doc.field(this.field);
506+
const other = doc.data.field(this.field);
507507
if (!isArray(other) || !other.arrayValue.values) {
508508
return false;
509509
}
@@ -588,7 +588,7 @@ export function sortsBeforeDocument(
588588
doc.key
589589
);
590590
} else {
591-
const docValue = doc.field(orderByComponent.field);
591+
const docValue = doc.data.field(orderByComponent.field);
592592
debugAssert(
593593
docValue !== null,
594594
'Field should exist since document matched the orderBy already.'

packages/firestore/src/core/transaction.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717

1818
import { ParsedSetData, ParsedUpdateData } from '../lite/user_data_reader';
19-
import { Document, MaybeDocument, NoDocument } from '../model/document';
19+
import { Document } from '../model/document';
2020
import { DocumentKey } from '../model/document_key';
2121
import {
2222
DeleteMutation,
@@ -60,7 +60,7 @@ export class Transaction {
6060

6161
constructor(private datastore: Datastore) {}
6262

63-
async lookup(keys: DocumentKey[]): Promise<MaybeDocument[]> {
63+
async lookup(keys: DocumentKey[]): Promise<Document[]> {
6464
this.ensureCommitNotCalled();
6565

6666
if (this.mutations.length > 0) {
@@ -70,13 +70,7 @@ export class Transaction {
7070
);
7171
}
7272
const docs = await invokeBatchGetDocumentsRpc(this.datastore, keys);
73-
docs.forEach(doc => {
74-
if (doc instanceof NoDocument || doc instanceof Document) {
75-
this.recordVersion(doc);
76-
} else {
77-
fail('Document in a transaction was a ' + doc.constructor.name);
78-
}
79-
});
73+
docs.forEach(doc => this.recordVersion(doc));
8074
return docs;
8175
}
8276

@@ -120,12 +114,12 @@ export class Transaction {
120114
this.committed = true;
121115
}
122116

123-
private recordVersion(doc: MaybeDocument): void {
117+
private recordVersion(doc: Document): void {
124118
let docVersion: SnapshotVersion;
125119

126-
if (doc instanceof Document) {
120+
if (doc.isFoundDocument()) {
127121
docVersion = doc.version;
128-
} else if (doc instanceof NoDocument) {
122+
} else if (doc.isNoDocument()) {
129123
// For deleted docs, we must use baseVersion 0 when we overwrite them.
130124
docVersion = SnapshotVersion.min();
131125
} else {

0 commit comments

Comments
 (0)