-
Notifications
You must be signed in to change notification settings - Fork 1.8k
feat(NODE-4034)!: make internal bulk result private #3515
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
Conversation
96a8512
to
51873e2
Compare
const mergeResult = mergeBatchResults(batch, bulkOperation.s.bulkResult, err, result); | ||
const writeResult = new BulkWriteResult(bulkOperation.s.bulkResult); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mergeBatchResults()
mutates the provided bulkResult
so we move the construction of the BulkWriteResult
until afterwards so it acts as immutable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just clarification for further reviewers.
Before the changes in this PR, BulkWriteResult
used getters to provide access to each property on the raw bulk result, so constructing the BulkWriteResult
before modifying the raw result was okay.
Now, we assign the properties directly in the constructor, so we need to create the BulkWriteResult
after we process the raw result.
* @internal | ||
*/ | ||
constructor(bulkResult: BulkResult) { | ||
this.result = bulkResult; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason to assign result
here and then override it in line 207?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The override was to set it as non-enumerable but typescript complained if I did it all in one go here. (It couldn't figure out that Object.defineProperty
was setting this.result
.
const mergeResult = mergeBatchResults(batch, bulkOperation.s.bulkResult, err, result); | ||
const writeResult = new BulkWriteResult(bulkOperation.s.bulkResult); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just clarification for further reviewers.
Before the changes in this PR, BulkWriteResult
used getters to provide access to each property on the raw bulk result, so constructing the BulkWriteResult
before modifying the raw result was okay.
Now, we assign the properties directly in the constructor, so we need to create the BulkWriteResult
after we process the raw result.
test/integration/retryable-writes/retryable_writes.spec.test.ts
Outdated
Show resolved
Hide resolved
test/integration/retryable-writes/retryable_writes.spec.test.ts
Outdated
Show resolved
Hide resolved
this.deletedCount = this.result.nRemoved ?? 0; | ||
this.upsertedCount = this.result.upserted.length ?? 0; | ||
this.upsertedIds = BulkWriteResult.generateIdMap(this.result.upserted); | ||
this.insertedIds = BulkWriteResult.generateIdMap(this.result.insertedIds); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Have you had a chance to check with any other drivers to see why they aren't running into the same insertedIds issues? It may be good to know if they are also implementing an internal work around, or aren't spec compliant themselves, or perhaps interpreting the spec differently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ruby iterates over the keys in the expected result and checks the actual object for that specific property, so it does not error when the actual result has more properties than the expected. Python does the same. It seems we are probably the only driver looking for an exact match of the actual and expected object properties, which makes us less flexible on adding other properties to our result classes.
The CRUD spec is clear about required and optional fields in the result objects, but does not say if additional properties on the result classes are forbidden. It seems like Node took the spec strictly but other drivers allowed a bit more flexibility - neither is incorrect in my opinion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dariakp Are you okay with this answer? This is the last outstanding thread on this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The "Evaluating Matches" section of the unified runner spec is very explicit about asserting that the properties of a subdocument inside an expected result property must match exactly:
https://github.com/mongodb/specifications/blob/master/source/unified-test-format/unified-test-format.rst#evaluating-matches
also
Test runners MUST NOT permit additional fields in nested documents.
So, per the spec, we are correct, and the spec tests must account for allowed optional properties via special test operators (basically, what you have filed in the DRIVERS-2523 is addressing a bug in the test implementation for RewrapManyDataKey; it is also an omission for the unified spec that we don't have the rewrapManyDataKey operation defined in the unified format spec and are also not referencing the spec where that operation is expected to be defined). This is an issue for insertMany tests, too, and for the "acknowledged" property in general (which perhaps no driver implements); surprised that is not coming up here (unless we already have the logic to handle it). I don't think we should treat BulkWriteResult as a root level document, because we do know what optional fields are allowed to exist on it, and we do not want it to have arbitrary fields beyond the ones defined by the spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added a comment to the drivers ticket, we don't need to keep this PR open on that account
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the test updates merged for DRIVERS-2523 I just went ahead and added them here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@durran Should that ticket be updated to "teams implementing"? (That way we can tag the generated node ticket number in this PR and it'll auto-link in jira)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did update it but for some reason it didn't generate any individual language tickets. Hmm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description updated with NODE-4973 now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also linked all 3 tickets to NODE-4034 now in JIRA.
Description
Makes the internal
BulkResult
on theBulkWriteResult
private.What is changing?
BulkResult
interface as internal.result
property of theBulkWriteResult
private and non-enumerable.BulkWriteResult
per the crud spec definition actual properties instead of getters.toJSON()
.insertedIds
from the result enumerable in unified tests.mongosh CI failures fix in this PR: mongodb-js/mongosh#1386
Is there new documentation needed for these changes?
None
What is the motivation for this change?
NODE-4034/NODE-4393/NODE-4973
Double check the following
npm run check:lint
scripttype(NODE-xxxx)[!]: description
feat(NODE-1234)!: rewriting everything in coffeescript