This commit is contained in:
2020-08-20 11:44:32 +02:00
parent 4715fc1814
commit 6aceefeb2f
2891 changed files with 11239 additions and 347539 deletions

View File

@@ -11,6 +11,8 @@ const applyRetryableWrites = require('../utils').applyRetryableWrites;
const applyWriteConcern = require('../utils').applyWriteConcern;
const executeLegacyOperation = require('../utils').executeLegacyOperation;
const isPromiseLike = require('../utils').isPromiseLike;
const hasAtomicOperators = require('../utils').hasAtomicOperators;
const maxWireVersion = require('../core/utils').maxWireVersion;
// Error codes
const WRITE_CONCERN_ERROR = 64;
@@ -641,6 +643,10 @@ class FindOperators {
document.hint = updateDocument.hint;
}
if (!hasAtomicOperators(updateDocument)) {
throw new TypeError('Update document requires atomic operators');
}
// Clear out current Op
this.s.currentOp = null;
return this.s.options.addToOperationsList(this, UPDATE, document);
@@ -650,12 +656,33 @@ class FindOperators {
* Add a replace one operation to the bulk operation
*
* @method
* @param {object} updateDocument the new document to replace the existing one with
* @param {object} replacement the new document to replace the existing one with
* @throws {MongoError} If operation cannot be added to bulk write
* @return {OrderedBulkOperation|UnorderedBulkOperation} A reference to the parent BulkOperation
*/
replaceOne(updateDocument) {
this.updateOne(updateDocument);
replaceOne(replacement) {
// Perform upsert
const upsert = typeof this.s.currentOp.upsert === 'boolean' ? this.s.currentOp.upsert : false;
// Establish the update command
const document = {
q: this.s.currentOp.selector,
u: replacement,
multi: false,
upsert: upsert
};
if (replacement.hint) {
document.hint = replacement.hint;
}
if (hasAtomicOperators(replacement)) {
throw new TypeError('Replacement document must not use atomic operators');
}
// Clear out current Op
this.s.currentOp = null;
return this.s.options.addToOperationsList(this, UPDATE, document);
}
/**
@@ -943,6 +970,12 @@ class BulkOperationBase {
// Crud spec update format
if (op.updateOne || op.updateMany || op.replaceOne) {
if (op.replaceOne && hasAtomicOperators(op[key].replacement)) {
throw new TypeError('Replacement document must not use atomic operators');
} else if ((op.updateOne || op.updateMany) && !hasAtomicOperators(op[key].update)) {
throw new TypeError('Update document requires atomic operators');
}
const multi = op.updateOne || op.replaceOne ? false : true;
const operation = {
q: op[key].filter,
@@ -960,7 +993,15 @@ class BulkOperationBase {
} else {
if (op[key].upsert) operation.upsert = true;
}
if (op[key].arrayFilters) operation.arrayFilters = op[key].arrayFilters;
if (op[key].arrayFilters) {
// TODO: this check should be done at command construction against a connection, not a topology
if (maxWireVersion(this.s.topology) < 6) {
throw new TypeError('arrayFilters are only supported on MongoDB 3.6+');
}
operation.arrayFilters = op[key].arrayFilters;
}
return this.s.options.addToOperationsList(this, UPDATE, operation);
}
@@ -979,6 +1020,9 @@ class BulkOperationBase {
if (op.deleteOne || op.deleteMany) {
const limit = op.deleteOne ? 1 : 0;
const operation = { q: op[key].filter, limit: limit };
if (op[key].hint) {
operation.hint = op[key].hint;
}
if (this.isOrdered) {
if (op.collation) operation.collation = op.collation;
}