From c02e96d82e9dea41d345e17328dafffb7ca2b32f Mon Sep 17 00:00:00 2001 From: Seba Kerckhof Date: Mon, 19 Jun 2017 22:33:08 +0200 Subject: [PATCH] Create mongo-typed upsert document --- packages/minimongo/minimongo.js | 25 ++++++++++++++++++++++-- packages/mongo/mongo_driver.js | 34 +++++++-------------------------- 2 files changed, 30 insertions(+), 29 deletions(-) diff --git a/packages/minimongo/minimongo.js b/packages/minimongo/minimongo.js index 59229269bc..1af6547190 100644 --- a/packages/minimongo/minimongo.js +++ b/packages/minimongo/minimongo.js @@ -1118,10 +1118,30 @@ LocalCollection.prototype.resumeObservers = function () { self._observeQueue.drain(); }; +LocalCollection._isModificationMod = function (mod) { + var isReplace = false; + var isModify = false; + for (var k in mod) { + if (k.substr(0, 1) === '$') { + isModify = true; + } else { + isReplace = true; + } + } + if (isModify && isReplace) { + throw new Error( + "Update parameter cannot have both modifier and non-modifier fields."); + } + return isModify; +}; // Calculates the document to insert in case we're doing an upsert and the selector // does not match any elements LocalCollection._createUpsertDocument = function (selector, modifier) { + if (!LocalCollection._isModificationMod(modifier)) { + return modifier; + } else { + let selectorDocument = populateDocumentWithQueryFields(selector); const newDoc = {}; @@ -1131,8 +1151,9 @@ LocalCollection._createUpsertDocument = function (selector, modifier) { } // This double _modify call is made to help with nested properties (see issue #8631). - LocalCollection._modify(newDoc, {$set: selectorDocument}); - LocalCollection._modify(newDoc, modifier, {isInsert: true}); + LocalCollection._modify(newDoc, { $set: selectorDocument }); + LocalCollection._modify(newDoc, modifier, { isInsert: true }); return newDoc; + } }; diff --git a/packages/mongo/mongo_driver.js b/packages/mongo/mongo_driver.js index 582cf8e8b9..8c2bf72f88 100644 --- a/packages/mongo/mongo_driver.js +++ b/packages/mongo/mongo_driver.js @@ -513,18 +513,15 @@ MongoConnection.prototype._update = function (collection_name, selector, mod, var isModify = isModificationMod(mongoMod); - var newDoc; + var isModify = LocalCollection._isModificationMod(mongoMod); + + // We've already run replaceTypes/replaceMeteorAtomWithMongo on + // selector and mod. We assume it doesn't matter, as far as + // the behavior of modifiers is concerned, whether `_modify` + // is run on EJSON or on mongo-converted EJSON. + var newDoc = LocalCollection._createUpsertDocument(mongoSelector, mongoMod); // Run this code up front so that it fails fast if someone uses // a Mongo update operator we don't support. - if (isModify) { - // We've already run replaceTypes/replaceMeteorAtomWithMongo on - // selector and mod. We assume it doesn't matter, as far as - // the behavior of modifiers is concerned, whether `_modify` - // is run on EJSON or on mongo-converted EJSON. - newDoc = LocalCollection._createUpsertDocument(selector, mod); - } else { - newDoc = mod; - } var knownId = newDoc._id; @@ -596,23 +593,6 @@ MongoConnection.prototype._update = function (collection_name, selector, mod, } }; -var isModificationMod = function (mod) { - var isReplace = false; - var isModify = false; - for (var k in mod) { - if (k.substr(0, 1) === '$') { - isModify = true; - } else { - isReplace = true; - } - } - if (isModify && isReplace) { - throw new Error( - "Update parameter cannot have both modifier and non-modifier fields."); - } - return isModify; -}; - var transformResult = function (driverResult) { var meteorResult = { numberAffected: 0 }; if (driverResult) {