-
Notifications
You must be signed in to change notification settings - Fork 945
Backport Android updateTransform changes #4225
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 1 commit
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 |
---|---|---|
|
@@ -87,11 +87,11 @@ export class MutationResult { | |
*/ | ||
readonly version: SnapshotVersion, | ||
/** | ||
* The resulting fields returned from the backend after a | ||
* TransformMutation has been committed. Contains one FieldValue for each | ||
* FieldTransform that was in the mutation. | ||
* The resulting fields returned from the backend after a mutation | ||
* containing field transforms has been committed. Contains one FieldValue | ||
* for each FieldTransform that was in the mutation. | ||
* | ||
* Will be null if the mutation was not a TransformMutation. | ||
* Will be null if the mutation did not contain any field transforms. | ||
*/ | ||
readonly transformResults: Array<ProtoValue | null> | null | ||
) {} | ||
|
@@ -178,8 +178,8 @@ export function preconditionIsValidForDocument( | |
* Mutations not only act on the value of the document but also its version. | ||
* | ||
* For local mutations (mutations that haven't been committed yet), we preserve | ||
* the existing version for Set, Patch, and Transform mutations. For Delete | ||
* mutations, we reset the version to 0. | ||
* the existing version for Set and Patch mutations. For Delete mutations, we | ||
* reset the version to 0. | ||
* | ||
* Here's the expected transition table. | ||
* | ||
|
@@ -191,28 +191,22 @@ export function preconditionIsValidForDocument( | |
* PatchMutation Document(v3) Document(v3) | ||
* PatchMutation NoDocument(v3) NoDocument(v3) | ||
* PatchMutation null null | ||
* TransformMutation Document(v3) Document(v3) | ||
* TransformMutation NoDocument(v3) NoDocument(v3) | ||
* TransformMutation null null | ||
* DeleteMutation Document(v3) NoDocument(v0) | ||
* DeleteMutation NoDocument(v3) NoDocument(v0) | ||
* DeleteMutation null NoDocument(v0) | ||
* | ||
* For acknowledged mutations, we use the updateTime of the WriteResponse as | ||
* the resulting version for Set, Patch, and Transform mutations. As deletes | ||
* have no explicit update time, we use the commitTime of the WriteResponse for | ||
* the resulting version for Set and Patch mutations. As deletes have no | ||
* explicit update time, we use the commitTime of the WriteResponse for | ||
* Delete mutations. | ||
* | ||
* If a mutation is acknowledged by the backend but fails the precondition check | ||
* locally, we return an `UnknownDocument` and rely on Watch to send us the | ||
* updated version. | ||
* | ||
* Note that TransformMutations don't create Documents (in the case of being | ||
* applied to a NoDocument), even though they would on the backend. This is | ||
* because the client always combines the TransformMutation with a SetMutation | ||
* or PatchMutation and we only want to apply the transform if the prior | ||
* mutation resulted in a Document (always true for a SetMutation, but not | ||
* necessarily for a PatchMutation). | ||
* Field transforms are used only with Patcdh and Set Mutations. We use the | ||
* `updateTransforms` message to store transforms, rather than the `transforms`s | ||
* messages. | ||
* | ||
* ## Subclassing Notes | ||
* | ||
|
@@ -335,13 +329,7 @@ export function extractMutationBaseValue( | |
mutation: Mutation, | ||
maybeDoc: MaybeDocument | null | ||
): ObjectValue | null { | ||
if (mutation.fieldTransforms !== undefined) { | ||
return extractTransformMutationBaseValue( | ||
mutation.fieldTransforms, | ||
maybeDoc | ||
); | ||
} | ||
return null; | ||
return extractTransformMutationBaseValue(mutation.fieldTransforms, maybeDoc); | ||
} | ||
|
||
function extractTransformMutationBaseValue( | ||
|
@@ -489,19 +477,17 @@ function applySetMutationToLocalView( | |
} | ||
|
||
let newData = mutation.value; | ||
if (mutation.fieldTransforms) { | ||
const transformResults = localTransformResults( | ||
mutation.fieldTransforms, | ||
localWriteTime, | ||
maybeDoc, | ||
baseDoc | ||
); | ||
newData = transformObject( | ||
mutation.fieldTransforms, | ||
newData, | ||
transformResults | ||
); | ||
} | ||
const transformResults = localTransformResults( | ||
mutation.fieldTransforms, | ||
localWriteTime, | ||
maybeDoc, | ||
baseDoc | ||
); | ||
newData = transformObject( | ||
mutation.fieldTransforms, | ||
newData, | ||
transformResults | ||
); | ||
|
||
const version = getPostMutationVersion(maybeDoc); | ||
return new Document(mutation.key, version, newData, { | ||
|
@@ -623,8 +609,8 @@ function patchObject(mutation: PatchMutation, data: ObjectValue): ObjectValue { | |
|
||
/** | ||
* Creates a list of "transform results" (a transform result is a field value | ||
* representing the result of applying a transform) for use after a | ||
* TransformMutation has been acknowledged by the server. | ||
* representing the result of applying a transform) for use after a mutation | ||
* containing transforms has been acknowledged by the server. | ||
* | ||
* @param fieldTransforms - The field transforms to apply the result to. | ||
* @param baseDoc - The document prior to applying this mutation batch. | ||
|
@@ -664,10 +650,10 @@ function serverTransformResults( | |
/** | ||
* Creates a list of "transform results" (a transform result is a field value | ||
* representing the result of applying a transform) for use when applying a | ||
* TransformMutation locally. | ||
* transform locally. | ||
* | ||
* @param fieldTransforms - The field transforms to apply the result to. | ||
* @param localWriteTime - The local time of the transform mutation (used to | ||
* @param localWriteTime - The local time of the mutation (used to | ||
* generate ServerTimestampValues). | ||
* @param maybeDoc - The current state of the document after applying all | ||
* previous mutations. | ||
|
@@ -689,14 +675,6 @@ function localTransformResults( | |
previousValue = maybeDoc.field(fieldTransform.field); | ||
} | ||
|
||
if (previousValue === null && baseDoc instanceof Document) { | ||
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. Why is this logic no longer needed? This seems pretty critical. Or is it handled elsewhere now? 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. My understanding is that this if-statement checks for the edge case where a PatchMutation clears the values of a nested map before the TransformMutation is applied. With the addition of updateTransforms, field transformation are encoded directly on the Patch or Set Mutation, rather than in a separate TransformMutation. This means that we won't bump into this edge case anymore since the update and fieldTransform are on the same mutation and thus applied at the same time. I've also removed the now obsolete server timestamp test that tested this edge case. |
||
// If the current document does not contain a value for the mutated | ||
// field, use the value that existed before applying this mutation | ||
// batch. This solves an edge case where a PatchMutation clears the | ||
// values in a nested map before the TransformMutation is applied. | ||
previousValue = baseDoc.field(fieldTransform.field); | ||
} | ||
|
||
transformResults.push( | ||
applyTransformOperationToLocalView( | ||
transform, | ||
|
Uh oh!
There was an error while loading. Please reload this page.