Skip to content

Commit bc196ab

Browse files
WIP
1 parent 2d04af9 commit bc196ab

File tree

9 files changed

+373
-29
lines changed

9 files changed

+373
-29
lines changed

packages/firestore/src/api/index_configuration.ts

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

1818
import { fieldPathFromDotSeparatedString } from '../lite-api/user_data_reader';
19-
import { FieldIndex, Kind, Segment } from '../model/field_index';
19+
import { FieldIndex, IndexKind, IndexSegment } from '../model/field_index';
2020
import { Code, FirestoreError } from '../util/error';
2121
import { cast } from '../util/input_validation';
2222

@@ -160,7 +160,7 @@ export function setIndexConfiguration(
160160
for (const index of indexConfiguration.indexes) {
161161
const collectionGroup = tryGetString(index, 'collectionGroup');
162162

163-
const segments: Segment[] = [];
163+
const segments: IndexSegment[] = [];
164164
if (Array.isArray(index.fields)) {
165165
for (const field of index.fields) {
166166
const fieldPathString = tryGetString(field, 'fieldPath');
@@ -170,11 +170,11 @@ export function setIndexConfiguration(
170170
);
171171

172172
if (field.arrayConfig === 'CONTAINS') {
173-
segments.push(new Segment(fieldPath, Kind.CONTAINS));
173+
segments.push(new IndexSegment(fieldPath, IndexKind.CONTAINS));
174174
} else if (field.order === 'ASCENDING') {
175-
segments.push(new Segment(fieldPath, Kind.ASCENDING));
175+
segments.push(new IndexSegment(fieldPath, IndexKind.ASCENDING));
176176
} else if (field.order === 'DESCENDING') {
177-
segments.push(new Segment(fieldPath, Kind.DESCENDING));
177+
segments.push(new IndexSegment(fieldPath, IndexKind.DESCENDING));
178178
}
179179
}
180180
}

packages/firestore/src/local/indexeddb_remote_document_cache.ts

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,10 @@ class IndexedDbRemoteDocumentCacheImpl implements IndexedDbRemoteDocumentCache {
289289
return;
290290
}
291291

292-
const document = fromDbRemoteDocument(this.serializer, dbRemoteDoc);
292+
const document = this.maybeDecodeDocument(
293+
DocumentKey.fromSegments(key),
294+
dbRemoteDoc
295+
);
293296
if (!query.path.isPrefixOf(document.key.path)) {
294297
control.done();
295298
} else if (queryMatches(query, document)) {
@@ -334,12 +337,15 @@ class IndexedDbRemoteDocumentCacheImpl implements IndexedDbRemoteDocumentCache {
334337
* Decodes `remoteDoc` and returns the document (or null, if the document
335338
* corresponds to the format used for sentinel deletes).
336339
*/
337-
private maybeDecodeDocument(
340+
maybeDecodeDocument(
338341
documentKey: DocumentKey,
339342
dbRemoteDoc: DbRemoteDocument | null
340343
): MutableDocument {
341344
if (dbRemoteDoc) {
342-
const doc = fromDbRemoteDocument(this.serializer, dbRemoteDoc);
345+
let doc = fromDbRemoteDocument(this.serializer, dbRemoteDoc);
346+
if (dbRemoteDoc.readTime) {
347+
doc = doc.withReadTime(fromDbTimestampKey(dbRemoteDoc.readTime));
348+
}
343349

344350
// Whether the document is a sentinel removal and should only be used in the
345351
// `getNewDocumentChanges()`
@@ -392,11 +398,11 @@ export function remoteDocumentCacheGetNewDocumentChanges(
392398
return documentsStore
393399
.iterate(
394400
{ index: DbRemoteDocument.readTimeIndex, range },
395-
(_, dbRemoteDoc) => {
401+
(key, dbRemoteDoc) => {
396402
// Unlike `getEntry()` and others, `getNewDocumentChanges()` parses
397403
// the documents directly since we want to keep sentinel deletes.
398-
const doc = fromDbRemoteDocument(
399-
remoteDocumentCacheImpl.serializer,
404+
const doc = remoteDocumentCacheImpl.maybeDecodeDocument(
405+
DocumentKey.fromSegments(key),
400406
dbRemoteDoc
401407
);
402408
changedDocs = changedDocs.insert(doc.key, doc);
@@ -487,8 +493,7 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
487493
);
488494
const doc = toDbRemoteDocument(
489495
this.documentCache.serializer,
490-
documentChange.document,
491-
this.getReadTime(key)
496+
documentChange.document.withReadTime(this.getReadTime(key))
492497
);
493498
collectionParents = collectionParents.add(key.path.popLast());
494499

@@ -504,8 +509,10 @@ class IndexedDbRemoteDocumentChangeBuffer extends RemoteDocumentChangeBuffer {
504509
// preserved in `getNewDocumentChanges()`.
505510
const deletedDoc = toDbRemoteDocument(
506511
this.documentCache.serializer,
507-
MutableDocument.newNoDocument(key, SnapshotVersion.min()),
508-
this.getReadTime(key)
512+
MutableDocument.newNoDocument(
513+
key,
514+
SnapshotVersion.min()
515+
).withReadTime(this.getReadTime(key))
509516
);
510517
promises.push(
511518
this.documentCache.addEntry(transaction, key, deletedDoc)

packages/firestore/src/local/local_serializer.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,10 +94,9 @@ export function fromDbRemoteDocument(
9494
/** Encodes a document for storage locally. */
9595
export function toDbRemoteDocument(
9696
localSerializer: LocalSerializer,
97-
document: MutableDocument,
98-
readTime: SnapshotVersion
97+
document: MutableDocument
9998
): DbRemoteDocument {
100-
const dbReadTime = toDbTimestampKey(readTime);
99+
const dbReadTime = toDbTimestampKey(document.readTime);
101100
const parentPath = document.key.path.popLast().toArray();
102101
if (document.isFoundDocument()) {
103102
const doc = toDocument(localSerializer.remoteSerializer, document);

packages/firestore/src/local/memory_remote_document_cache.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ export type DocumentSizer = (doc: Document) => number;
3939
interface MemoryRemoteDocumentCacheEntry {
4040
document: Document;
4141
size: number;
42-
readTime: SnapshotVersion;
4342
}
4443

4544
type DocumentEntryMap = SortedMap<DocumentKey, MemoryRemoteDocumentCacheEntry>;
@@ -99,9 +98,8 @@ class MemoryRemoteDocumentCacheImpl implements MemoryRemoteDocumentCache {
9998
const currentSize = this.sizer(doc);
10099

101100
this.docs = this.docs.insert(key, {
102-
document: doc.mutableCopy(),
103-
size: currentSize,
104-
readTime
101+
document: doc.mutableCopy().withReadTime(readTime),
102+
size: currentSize
105103
});
106104

107105
this.size += currentSize - previousSize;
@@ -173,12 +171,12 @@ class MemoryRemoteDocumentCacheImpl implements MemoryRemoteDocumentCache {
173171
while (iterator.hasNext()) {
174172
const {
175173
key,
176-
value: { document, readTime }
174+
value: { document }
177175
} = iterator.getNext();
178176
if (!query.path.isPrefixOf(key.path)) {
179177
break;
180178
}
181-
if (readTime.compareTo(sinceReadTime) <= 0) {
179+
if (document.readTime.compareTo(sinceReadTime) <= 0) {
182180
continue;
183181
}
184182
if (!queryMatches(query, document)) {

packages/firestore/src/model/document.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,12 @@ export interface Document {
9595
*/
9696
readonly version: SnapshotVersion;
9797

98+
/**
99+
* The timestamp at which this document was read from the remote server. Uses
100+
* `SnapshotVersion.min()` for documents created by the user.
101+
*/
102+
readonly readTime: SnapshotVersion;
103+
98104
/** The underlying data of this document or an empty value if no data exists. */
99105
readonly data: ObjectValue;
100106

@@ -156,6 +162,7 @@ export class MutableDocument implements Document {
156162
readonly key: DocumentKey,
157163
private documentType: DocumentType,
158164
public version: SnapshotVersion,
165+
public readTime: SnapshotVersion,
159166
public data: ObjectValue,
160167
private documentState: DocumentState
161168
) {}
@@ -169,6 +176,7 @@ export class MutableDocument implements Document {
169176
documentKey,
170177
DocumentType.INVALID,
171178
SnapshotVersion.min(),
179+
SnapshotVersion.min(),
172180
ObjectValue.empty(),
173181
DocumentState.SYNCED
174182
);
@@ -187,6 +195,7 @@ export class MutableDocument implements Document {
187195
documentKey,
188196
DocumentType.FOUND_DOCUMENT,
189197
version,
198+
SnapshotVersion.min(),
190199
value,
191200
DocumentState.SYNCED
192201
);
@@ -201,6 +210,7 @@ export class MutableDocument implements Document {
201210
documentKey,
202211
DocumentType.NO_DOCUMENT,
203212
version,
213+
SnapshotVersion.min(),
204214
ObjectValue.empty(),
205215
DocumentState.SYNCED
206216
);
@@ -219,6 +229,7 @@ export class MutableDocument implements Document {
219229
documentKey,
220230
DocumentType.UNKNOWN_DOCUMENT,
221231
version,
232+
SnapshotVersion.min(),
222233
ObjectValue.empty(),
223234
DocumentState.HAS_COMMITTED_MUTATIONS
224235
);
@@ -282,6 +293,11 @@ export class MutableDocument implements Document {
282293
return this;
283294
}
284295

296+
withReadTime(readTime: SnapshotVersion): MutableDocument {
297+
this.readTime = readTime;
298+
return this;
299+
}
300+
285301
get hasLocalMutations(): boolean {
286302
return this.documentState === DocumentState.HAS_LOCAL_MUTATIONS;
287303
}
@@ -326,6 +342,7 @@ export class MutableDocument implements Document {
326342
this.key,
327343
this.documentType,
328344
this.version,
345+
this.readTime,
329346
this.data.clone(),
330347
this.documentState
331348
);

packages/firestore/src/model/document_key.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export class DocumentKey {
3939
return new DocumentKey(ResourcePath.fromString(name).popFirst(5));
4040
}
4141

42+
static empty(): DocumentKey {
43+
return new DocumentKey(ResourcePath.emptyPath());
44+
}
45+
4246
/** Returns true if the document is in the specified collectionId. */
4347
hasCollectionId(collectionId: string): boolean {
4448
return (

0 commit comments

Comments
 (0)