diff --git a/packages/minimongo/common.js b/packages/minimongo/common.js index 213396301f..82d966fb2b 100644 --- a/packages/minimongo/common.js +++ b/packages/minimongo/common.js @@ -857,7 +857,7 @@ export function isOperatorObject(valueSelector, inconsistentOK) { let theseAreOperators = undefined; Object.keys(valueSelector).forEach(selKey => { - const thisIsOperator = selKey.substr(0, 1) === '$'; + const thisIsOperator = selKey.substr(0, 1) === '$' || selKey === 'diff'; if (theseAreOperators === undefined) { theseAreOperators = thisIsOperator; diff --git a/packages/minimongo/cursor.js b/packages/minimongo/cursor.js index 8d5a938be2..a555fb74c0 100644 --- a/packages/minimongo/cursor.js +++ b/packages/minimongo/cursor.js @@ -25,7 +25,7 @@ export default class Cursor { this.skip = options.skip || 0; this.limit = options.limit; - this.fields = options.fields; + this.fields = options.projection || options.fields; this._projectionFn = LocalCollection._compileProjection(this.fields || {}); diff --git a/packages/mongo/collection_tests.js b/packages/mongo/collection_tests.js index e6f3228392..da34c62792 100644 --- a/packages/mongo/collection_tests.js +++ b/packages/mongo/collection_tests.js @@ -94,7 +94,7 @@ Tinytest.add('collection - call native find with sort function', return doc.a; }); }, - /Illegal sort clause/ + /Invalid sort format: undefined Sort must be a valid object/ ); } } @@ -159,7 +159,7 @@ Tinytest.add('collection - calling find with a valid readPreference', if (Meteor.isServer) { const defaultReadPreference = 'primary'; const customReadPreference = 'secondaryPreferred'; - const collection = new Mongo.Collection('readPreferenceTest1'); + const collection = new Mongo.Collection('readPreferenceTest'); const defaultCursor = collection.find(); const customCursor = collection.find( {}, @@ -171,14 +171,15 @@ Tinytest.add('collection - calling find with a valid readPreference', customCursor.count(); // defaultCursor._synchronousCursor._dbCursor.operation is not an option anymore - // defaultCursor._synchronousCursor._dbCursor.option is + // as the cursor options are now private + // You can check on abstract_cursor.ts the exposed public getters test.equal( - defaultCursor._synchronousCursor._dbCursor.options.readPreference + defaultCursor._synchronousCursor._dbCursor.readPreference .mode, defaultReadPreference ); test.equal( - customCursor._synchronousCursor._dbCursor.options.readPreference.mode, + customCursor._synchronousCursor._dbCursor.readPreference.mode, customReadPreference ); } @@ -198,7 +199,7 @@ Tinytest.add('collection - calling find with an invalid readPreference', test.throws(function() { // Trigger the creation of _synchronousCursor cursor.count(); - }, `Invalid read preference mode ${invalidReadPreference}`); + }, `Invalid read preference mode "${invalidReadPreference}"`); } } ); diff --git a/packages/mongo/mongo_driver.js b/packages/mongo/mongo_driver.js index e9d86c8be0..849c3396f3 100644 --- a/packages/mongo/mongo_driver.js +++ b/packages/mongo/mongo_driver.js @@ -376,8 +376,16 @@ MongoConnection.prototype._insert = function (collection_name, document, callback = bindEnvironmentForWrite(writeCallback(write, refresh, callback)); try { var collection = self.rawCollection(collection_name); - collection.insertOne(replaceTypes(document, replaceMeteorAtomWithMongo), - {safe: true}, callback); + collection.insertOne( + replaceTypes(document, replaceMeteorAtomWithMongo), + { + safe: true, + } + ).then(({insertedId}) => { + callback(null, transformResult({ result : {modifiedCount : insertedId ? 1 : 0} }).numberAffected); + }).catch((e) => { + callback(e) + }); } catch (err) { write.committed(); throw err; @@ -424,15 +432,15 @@ MongoConnection.prototype._remove = function (collection_name, selector, try { var collection = self.rawCollection(collection_name); - let result = {}; - try { - const {deletedCount} = collection.deleteMany(replaceTypes(selector, replaceMeteorAtomWithMongo), - {safe: true}).await(); - result.modifiedCount = deletedCount; - }catch(err){ - callback(err) - } - callback(null, transformResult({result}).numberAffected) + collection + .deleteMany(replaceTypes(selector, replaceMeteorAtomWithMongo), { + safe: true, + }) + .then(({ deletedCount }) => { + callback(null, transformResult({ result : {modifiedCount : deletedCount} }).numberAffected); + }).catch((err) => { + callback(err); + }); } catch (err) { write.committed(); throw err; @@ -610,7 +618,11 @@ MongoConnection.prototype._update = function (collection_name, selector, mod, const strings = Object.keys(mongoMod).filter((key) => !key.startsWith("$")); let updateMethod = strings.length > 0 ? 'replaceOne' : 'updateMany'; - updateMethod = updateMethod === 'updateMany' && !mongoOpts.multi ? 'updateOne' : updateMethod; + updateMethod = + updateMethod === 'updateMany' && !mongoOpts.multi + ? 'updateOne' + : updateMethod; + console.log(`Choose method ${updateMethod} for ${JSON.stringify(mongoMod)}`) collection[updateMethod].bind(collection)( mongoSelector, mongoMod, mongoOpts, bindEnvironmentForWrite(function (err, result) { @@ -727,44 +739,60 @@ var simulateUpsertWithInsertedId = function (collection, selector, mod, } else { let method = collection.updateMany; if(!Object.keys(mod).some(key => key.startsWith("$"))){ + console.log(`Choose method replace for ${JSON.stringify(mod)} on selector ${JSON.stringify(selector)}`) + method = collection.replaceOne.bind(collection); mod = replacementWithId; + console.trace("Aqui") } - method(selector, mod, {upsert:true,...mongoOptsForUpdate}, - bindEnvironmentForWrite(function (err, result) { - if (err) { - callback(err); - } else if (result && (result.modifiedCount || result.upsertedCount)) { - callback(null, { - numberAffected: result.modifiedCount || result.upsertedCount, - insertedId: result.upsertedId - }); - } else { - doConditionalInsert(); - } - })); + console.log("mongoOptsForUpdate"); + console.log(mongoOptsForUpdate); + console.log("method"); + console.log(method); + method( + selector, + mod, + { upsert: true, ...mongoOptsForUpdate }, + bindEnvironmentForWrite(function(err, result) { + console.log(err) + if (err) { + callback(err); + } else if (result && (result.modifiedCount || result.upsertedCount)) { + callback(null, { + numberAffected: result.modifiedCount || result.upsertedCount, + insertedId: result.upsertedId, + }); + } else { + doConditionalInsert(); + } + }) + ); } }; - var doConditionalInsert = function () { - collection.replaceOne(selector, replacementWithId, mongoOptsForInsert, - bindEnvironmentForWrite(function (err, result) { - if (err) { - // figure out if this is a - // "cannot change _id of document" error, and - // if so, try doUpdate() again, up to 3 times. - if (MongoConnection._isCannotChangeIdError(err)) { - doUpdate(); - } else { - callback(err); - } - } else { - callback(null, { - numberAffected: result.upsertedCount, - insertedId: result.upsertedId, - }); - } - })); + var doConditionalInsert = function() { + collection.replaceOne( + selector, + replacementWithId, + mongoOptsForInsert, + bindEnvironmentForWrite(function(err, result) { + if (err) { + // figure out if this is a + // "cannot change _id of document" error, and + // if so, try doUpdate() again, up to 3 times. + if (MongoConnection._isCannotChangeIdError(err)) { + doUpdate(); + } else { + callback(err); + } + } else { + callback(null, { + numberAffected: result.upsertedCount, + insertedId: result.upsertedId, + }); + } + }) + ); }; doUpdate(); @@ -977,8 +1005,8 @@ MongoConnection.prototype._createSynchronousCursor = function( sort: cursorOptions.sort, limit: cursorOptions.limit, skip: cursorOptions.skip, - projection: cursorOptions.fields, - readPreference: cursorOptions.readPreference + projection: cursorOptions.fields || cursorOptions.projection, + readPreference: cursorOptions.readPreference, }; // Do we want a tailable cursor (which only works on capped collections)? diff --git a/packages/mongo/mongo_livedata_tests.js b/packages/mongo/mongo_livedata_tests.js index 55c4f3ad6e..20aacf8f18 100644 --- a/packages/mongo/mongo_livedata_tests.js +++ b/packages/mongo/mongo_livedata_tests.js @@ -1779,7 +1779,9 @@ _.each(Meteor.isServer ? [true, false] : [true], function (minimongo) { test.isTrue(result1.insertedId); compareResults(test, skipIds, coll.find().fetch(), [{foo: 'bar', _id: result1.insertedId}]); + // !!!! var result2 = upsert(coll, useUpdate, {foo: 'bar'}, {foo: 'baz'}); + // !!!! test.equal(result2.numberAffected, 1); if (! skipIds) test.isFalse(result2.insertedId); @@ -3309,7 +3311,7 @@ Meteor.isServer && Tinytest.add( } ); -Meteor.isServer && Tinytest.only("mongo-livedata - npm modules", function (test) { +Meteor.isServer && Tinytest.add("mongo-livedata - npm modules", function (test) { // Make sure the version number looks like a version number. test.matches(MongoInternals.NpmModules.mongodb.version, /^4\.(\d+)\.(\d+)/); console.log(MongoInternals.NpmModules.mongodb) diff --git a/packages/mongo/oplog_observe_driver.js b/packages/mongo/oplog_observe_driver.js index 55fe120516..ec669c834c 100644 --- a/packages/mongo/oplog_observe_driver.js +++ b/packages/mongo/oplog_observe_driver.js @@ -86,7 +86,9 @@ OplogObserveDriver = function (options) { self._registerPhaseChange(PHASE.QUERYING); self._matcher = options.matcher; - var projection = self._cursorDescription.options.fields || {}; + // we are now using projection, not fields in the cursor description even if you pass {fields} + // in the cursor construction + var projection = self._cursorDescription.options.fields || self._cursorDescription.options.projection || {}; self._projectionFn = LocalCollection._compileProjection(projection); // Projection function, result of combining important fields for selector and // existing fields projection