Skip to content

Commit f36edc1

Browse files
committed
BREAKING CHANGE: make 1-arg syntax for updateOne, updateMany, findOneAndX set conditions not update, add findOneAndReplace
Fix #104 Re: Automattic/mongoose#15363
1 parent 4a77a21 commit f36edc1

File tree

5 files changed

+201
-46
lines changed

5 files changed

+201
-46
lines changed

lib/collection/collection.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const methods = [
1414
'estimatedDocumentCount',
1515
'distinct',
1616
'findOneAndDelete',
17+
'findOneAndReplace',
1718
'findOneAndUpdate',
1819
'aggregate',
1920
'findCursor',

lib/collection/node.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,13 @@ class NodeCollection extends Collection {
100100
return this.collection.findOneAndUpdate(match, update, options);
101101
}
102102

103+
/**
104+
* findOneAndReplace(match, update, options)
105+
*/
106+
async findOneAndReplace(match, update, options) {
107+
return this.collection.findOneAndReplace(match, update, options);
108+
}
109+
103110
/**
104111
* var cursor = findCursor(match, options)
105112
*/

lib/mquery.js

Lines changed: 64 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2058,11 +2058,6 @@ Query.prototype._distinct = async function _distinct() {
20582058
*/
20592059

20602060
Query.prototype.updateMany = function updateMany(criteria, doc, options) {
2061-
if (arguments.length === 1) {
2062-
doc = criteria;
2063-
criteria = options = undefined;
2064-
}
2065-
20662061
return _update(this, 'updateMany', criteria, doc, options);
20672062
};
20682063

@@ -2093,11 +2088,6 @@ Query.prototype._updateMany = async function() {
20932088
*/
20942089

20952090
Query.prototype.updateOne = function updateOne(criteria, doc, options) {
2096-
if (arguments.length === 1) {
2097-
doc = criteria;
2098-
criteria = options = undefined;
2099-
}
2100-
21012091
return _update(this, 'updateOne', criteria, doc, options);
21022092
};
21032093

@@ -2128,11 +2118,6 @@ Query.prototype._updateOne = async function() {
21282118
*/
21292119

21302120
Query.prototype.replaceOne = function replaceOne(criteria, doc, options) {
2131-
if (arguments.length === 1) {
2132-
doc = criteria;
2133-
criteria = options = undefined;
2134-
}
2135-
21362121
this.setOptions({ overwrite: true });
21372122
return _update(this, 'replaceOne', criteria, doc, options);
21382123
};
@@ -2255,7 +2240,7 @@ Query.prototype._deleteMany = async function() {
22552240
};
22562241

22572242
/**
2258-
* Issues a mongodb [findAndModify](http://www.mongodb.org/display/DOCS/findAndModify+Command) update command.
2243+
* Issues a mongodb findOneAndUpdate command.
22592244
*
22602245
* Finds a matching document, updates it according to the `update` arg, passing any `options`, and returns the found document (if any).
22612246
*
@@ -2288,11 +2273,6 @@ Query.prototype.findOneAndUpdate = function(criteria, doc, options) {
22882273
this.op = 'findOneAndUpdate';
22892274
this._validate();
22902275

2291-
if (arguments.length === 1) {
2292-
doc = criteria;
2293-
criteria = options = undefined;
2294-
}
2295-
22962276
if (Query.canMerge(criteria)) {
22972277
this.merge(criteria);
22982278
}
@@ -2319,6 +2299,68 @@ Query.prototype._findOneAndUpdate = async function() {
23192299
return this._collection.findOneAndUpdate(conds, update, options);
23202300
};
23212301

2302+
/**
2303+
* Issues a mongodb findOneAndReplace command.
2304+
*
2305+
* Finds a matching document, replaces it according to the `replacement` arg, passing any `options`, and returns the found document (if any).
2306+
*
2307+
* #### Available options
2308+
*
2309+
* - `new`: bool - true to return the modified document rather than the original. defaults to true
2310+
* - `upsert`: bool - creates the object if it doesn't exist. defaults to false.
2311+
* - `sort`: if multiple docs are found by the conditions, sets the sort order to choose which doc to update
2312+
*
2313+
* #### Examples:
2314+
*
2315+
* await query.findOneAndReplace(conditions, replacement, options) // executes
2316+
* query.findOneAndReplace(conditions, replacement, options) // returns Query
2317+
* await query.findOneAndReplace(conditions, replacement) // executes
2318+
* query.findOneAndReplace(conditions, replacement) // returns Query
2319+
* await query.findOneAndReplace(replacement) // returns Query
2320+
* query.findOneAndReplace(replacement) // returns Query
2321+
* await query.findOneAndReplace() // executes
2322+
* query.findOneAndReplace() // returns Query
2323+
*
2324+
* @param {Object|Query} [query]
2325+
* @param {Object} [replacement]
2326+
* @param {Object} [options]
2327+
* @see mongodb http://www.mongodb.org/display/DOCS/findAndModify+Command
2328+
* @return {Query} this
2329+
* @api public
2330+
*/
2331+
2332+
Query.prototype.findOneAndReplace = function(criteria, replacement, options) {
2333+
this.op = 'findOneAndReplace';
2334+
this._validate();
2335+
2336+
if (Query.canMerge(criteria)) {
2337+
this.merge(criteria);
2338+
}
2339+
2340+
// apply replacement
2341+
if (replacement) {
2342+
this._updateDoc = replacement;
2343+
this.options = this.options || {};
2344+
this.options.overwrite = true;
2345+
}
2346+
2347+
options && this.setOptions(options);
2348+
2349+
return this;
2350+
};
2351+
2352+
/**
2353+
* Executes a `findOneAndReplace` Query
2354+
* @returns the results
2355+
*/
2356+
Query.prototype._findOneAndReplace = async function() {
2357+
const conds = this._conditions;
2358+
const replacement = this._updateForExec();
2359+
const options = this._optionsForExec();
2360+
2361+
return this._collection.findOneAndReplace(conds, replacement, options);
2362+
};
2363+
23222364
/**
23232365
* Issues a mongodb findOneAndDelete.
23242366
*
@@ -2573,7 +2615,7 @@ Query.prototype._fieldsForExec = function() {
25732615
*/
25742616

25752617
Query.prototype._updateForExec = function() {
2576-
const update = utils.clone(this._updateDoc);
2618+
const update = this._updateDoc == null ? {} : utils.clone(this._updateDoc);
25772619
const ops = utils.keys(update);
25782620
const ret = {};
25792621

lib/permissions.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,21 @@ denied.findOneAndUpdate.skip =
5353
denied.findOneAndUpdate.batchSize =
5454
denied.findOneAndUpdate.tailable = true;
5555

56+
denied.findOneAndReplace = function(self) {
57+
const keys = Object.keys(denied.findOneAndUpdate);
58+
let err;
59+
60+
keys.every(function(option) {
61+
if (self.options[option]) {
62+
err = option;
63+
return false;
64+
}
65+
return true;
66+
});
67+
68+
return err;
69+
};
70+
5671

5772
denied.countDocuments = function(self) {
5873
if (self._fields && Object.keys(self._fields).length > 0) {

0 commit comments

Comments
 (0)