Skip to content
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

Add createTime to Document. #6781

Merged
merged 10 commits into from Dec 2, 2022
30 changes: 22 additions & 8 deletions packages/firestore/src/model/document.ts
Expand Up @@ -101,6 +101,13 @@ export interface Document {
*/
readonly readTime: SnapshotVersion;

/**
* The timestamp at which the document was created. This value increases
ehsannas marked this conversation as resolved.
Show resolved Hide resolved
* monotonically when a document is deleted then recreated. It can also be
* compared to `createTime` of other documents and the `readTime` of a query.
*/
readonly createTime: SnapshotVersion;

/** The underlying data of this document or an empty value if no data exists. */
readonly data: ObjectValue;

Expand Down Expand Up @@ -163,6 +170,7 @@ export class MutableDocument implements Document {
private documentType: DocumentType,
public version: SnapshotVersion,
public readTime: SnapshotVersion,
public createTime: SnapshotVersion,
public data: ObjectValue,
private documentState: DocumentState
) {}
Expand All @@ -175,8 +183,9 @@ export class MutableDocument implements Document {
return new MutableDocument(
documentKey,
DocumentType.INVALID,
SnapshotVersion.min(),
SnapshotVersion.min(),
/* version */ SnapshotVersion.min(),
/* readTime */ SnapshotVersion.min(),
/* createTime */ SnapshotVersion.min(),
ObjectValue.empty(),
DocumentState.SYNCED
);
Expand All @@ -189,13 +198,15 @@ export class MutableDocument implements Document {
static newFoundDocument(
documentKey: DocumentKey,
version: SnapshotVersion,
createTime: SnapshotVersion,
value: ObjectValue
): MutableDocument {
return new MutableDocument(
documentKey,
DocumentType.FOUND_DOCUMENT,
version,
SnapshotVersion.min(),
/* version */ version,
/* readTime */ SnapshotVersion.min(),
/* createTime */ createTime,
value,
DocumentState.SYNCED
);
Expand All @@ -209,8 +220,9 @@ export class MutableDocument implements Document {
return new MutableDocument(
documentKey,
DocumentType.NO_DOCUMENT,
version,
SnapshotVersion.min(),
/* version */ version,
/* readTime */ SnapshotVersion.min(),
/* createTime */ SnapshotVersion.min(),
ObjectValue.empty(),
DocumentState.SYNCED
);
Expand All @@ -228,8 +240,9 @@ export class MutableDocument implements Document {
return new MutableDocument(
documentKey,
DocumentType.UNKNOWN_DOCUMENT,
version,
SnapshotVersion.min(),
/* version */ version,
/* readTime */ SnapshotVersion.min(),
/* createTime */ SnapshotVersion.min(),
ObjectValue.empty(),
DocumentState.HAS_COMMITTED_MUTATIONS
);
Expand Down Expand Up @@ -340,6 +353,7 @@ export class MutableDocument implements Document {
this.documentType,
this.version,
this.readTime,
this.createTime,
this.data.clone(),
this.documentState
);
Expand Down
28 changes: 24 additions & 4 deletions packages/firestore/src/remote/serializer.ts
Expand Up @@ -395,7 +395,8 @@ export function toDocument(
return {
name: toName(serializer, document.key),
fields: document.data.value.mapValue.fields,
updateTime: toTimestamp(serializer, document.version.toTimestamp())
updateTime: toTimestamp(serializer, document.version.toTimestamp()),
createTime: toTimestamp(serializer, document.createTime.toTimestamp())
};
}

Expand All @@ -406,8 +407,16 @@ export function fromDocument(
): MutableDocument {
const key = fromName(serializer, document.name!);
const version = fromVersion(document.updateTime!);
const createTime = document.createTime
? fromVersion(document.createTime)
: SnapshotVersion.min();
const data = new ObjectValue({ mapValue: { fields: document.fields } });
const result = MutableDocument.newFoundDocument(key, version, data);
const result = MutableDocument.newFoundDocument(
key,
version,
createTime,
data
);
if (hasCommittedMutations) {
result.setHasCommittedMutations();
}
Expand All @@ -426,8 +435,11 @@ function fromFound(
assertPresent(doc.found.updateTime, 'doc.found.updateTime');
const key = fromName(serializer, doc.found.name);
const version = fromVersion(doc.found.updateTime);
const createTime = doc.found.createTime
? fromVersion(doc.found.createTime)
: SnapshotVersion.min();
const data = new ObjectValue({ mapValue: { fields: doc.found.fields } });
return MutableDocument.newFoundDocument(key, version, data);
return MutableDocument.newFoundDocument(key, version, createTime, data);
}

function fromMissing(
Expand Down Expand Up @@ -493,10 +505,18 @@ export function fromWatchChange(
);
const key = fromName(serializer, entityChange.document.name);
const version = fromVersion(entityChange.document.updateTime);
const createTime = entityChange.document.createTime
? fromVersion(entityChange.document.createTime)
: SnapshotVersion.min();
const data = new ObjectValue({
mapValue: { fields: entityChange.document.fields }
});
const doc = MutableDocument.newFoundDocument(key, version, data);
const doc = MutableDocument.newFoundDocument(
key,
version,
createTime,
data
);
const updatedTargetIds = entityChange.targetIds || [];
const removedTargetIds = entityChange.removedTargetIds || [];
watchChange = new DocumentWatchChange(
Expand Down
27 changes: 27 additions & 0 deletions packages/firestore/test/unit/local/local_store.test.ts
Expand Up @@ -1958,6 +1958,33 @@ function genericLocalStoreTests(
.finish();
});

it('handles document creation time', () => {
return (
expectLocalStore()
.afterAllocatingQuery(query('col'))
.toReturnTargetId(2)
.after(docAddedRemoteEvent(doc('col/doc1', 12, { foo: 'bar' }, 5), [2]))
.toReturnChanged(doc('col/doc1', 12, { foo: 'bar' }, 5))
.toContain(doc('col/doc1', 12, { foo: 'bar' }, 5))
.after(setMutation('col/doc1', { foo: 'newBar' }))
.toReturnChanged(
doc('col/doc1', 12, { foo: 'newBar' }, 5).setHasLocalMutations()
)
.toContain(
doc('col/doc1', 12, { foo: 'newBar' }, 5).setHasLocalMutations()
)
.afterAcknowledgingMutation({ documentVersion: 13 })
// We haven't seen the remote event yet
.toReturnChanged(
doc('col/doc1', 13, { foo: 'newBar' }, 5).setHasCommittedMutations()
)
.toContain(
doc('col/doc1', 13, { foo: 'newBar' }, 5).setHasCommittedMutations()
)
.finish()
);
});

ehsannas marked this conversation as resolved.
Show resolved Hide resolved
it('uses target mapping to execute queries', () => {
if (gcIsEager) {
return;
Expand Down
5 changes: 3 additions & 2 deletions packages/firestore/test/unit/remote/serializer.helper.ts
Expand Up @@ -799,11 +799,12 @@ export function serializerTest(
});

it('toDocument() / fromDocument', () => {
const d = doc('foo/bar', 42, { a: 5, b: 'b' });
const d = doc('foo/bar', 42, { a: 5, b: 'b' }, /* createTime */ 12);
const proto = {
name: toName(s, d.key),
fields: d.data.value.mapValue.fields,
updateTime: toVersion(s, d.version)
updateTime: toVersion(s, d.version),
createTime: toVersion(s, d.createTime)
};
const serialized = toDocument(s, d);
expect(serialized).to.deep.equal(proto);
Expand Down
4 changes: 3 additions & 1 deletion packages/firestore/test/util/helpers.ts
Expand Up @@ -155,11 +155,13 @@ export function ref(key: string, offset?: number): DocumentReference {
export function doc(
keyStr: string,
ver: TestSnapshotVersion,
jsonOrObjectValue: JsonObject<unknown> | ObjectValue
jsonOrObjectValue: JsonObject<unknown> | ObjectValue,
createTime?: TestSnapshotVersion
): MutableDocument {
return MutableDocument.newFoundDocument(
key(keyStr),
version(ver),
createTime ? version(createTime) : SnapshotVersion.min(),
jsonOrObjectValue instanceof ObjectValue
? jsonOrObjectValue
: wrapObject(jsonOrObjectValue)
Expand Down