Use async functions for running insert/delete

Fix "projection" field usage on observers
This commit is contained in:
Renan Castro
2022-01-05 15:03:51 -03:00
committed by Filipe Névola
parent 86024fc7d9
commit ebf91b0dfe
6 changed files with 89 additions and 56 deletions

View File

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

View File

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

View File

@@ -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}"`);
}
}
);

View File

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

View File

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

View File

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