Create mongo-typed upsert document

This commit is contained in:
Seba Kerckhof
2017-06-19 22:33:08 +02:00
committed by Ben Newman
parent 3580edfeae
commit c02e96d82e
2 changed files with 30 additions and 29 deletions

View File

@@ -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;
}
};

View File

@@ -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) {