Skip to content

Commit

Permalink
fix(connection): respect connection-level bufferCommands option if …
Browse files Browse the repository at this point in the history
…`mongoose.connect()` is called after `mongoose.model()`

Re: #9179
  • Loading branch information
vkarpov15 committed Jul 12, 2020
1 parent 35869a3 commit 9a23c42
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 38 deletions.
31 changes: 25 additions & 6 deletions lib/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,6 @@ function Collection(name, conn, opts) {
opts.capped = {};
}

opts.bufferCommands = undefined === opts.bufferCommands
? true
: opts.bufferCommands;

if (typeof opts.capped === 'number') {
opts.capped = { size: opts.capped };
}
Expand All @@ -40,7 +36,7 @@ function Collection(name, conn, opts) {
this.collectionName = name;
this.conn = conn;
this.queue = [];
this.buffer = this.opts.bufferCommands;
this.buffer = true;
this.emitter = new EventEmitter();

if (STATES.connected === this.conn.readyState) {
Expand Down Expand Up @@ -93,7 +89,7 @@ Collection.prototype.onOpen = function() {
*/

Collection.prototype.onClose = function(force) {
if (this.opts.bufferCommands && !force) {
if (this._shouldBufferCommands() && !force) {
this.buffer = true;
}
};
Expand Down Expand Up @@ -262,6 +258,29 @@ Collection.prototype.watch = function() {
throw new Error('Collection#watch unimplemented by driver');
};

/*!
* ignore
*/

Collection.prototype._shouldBufferCommands = function _shouldBufferCommands() {
const conn = this.conn;
const opts = this.opts;

if (opts.bufferCommands != null) {
return opts.bufferCommands;
}
if (opts && opts.schemaUserProvidedOptions != null && opts.schemaUserProvidedOptions.bufferCommands != null) {
return opts.schemaUserProvidedOptions.bufferCommands;
}
if (conn.config.bufferCommands != null) {
return conn.config.bufferCommands;
}
if (conn.base != null && conn.base.get('bufferCommands') != null) {
return conn.base.get('bufferCommands');
}
return true;
};

/*!
* Module exports.
*/
Expand Down
5 changes: 4 additions & 1 deletion lib/drivers/node-mongodb-native/collection.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,14 +140,17 @@ function iter(i) {
}
}

if (this.buffer) {
if (this._shouldBufferCommands() && this.buffer) {
if (syncCollectionMethods[i]) {
throw new Error('Collection method ' + i + ' is synchronous');
}
if (typeof lastArg === 'function') {
this.addQueue(i, args);
return;
}

this.conn.emit('buffer', { method: i, args: args });

return new this.Promise((resolve, reject) => {
this.addQueue(i, [].concat(args).concat([(err, res) => {
if (err != null) {
Expand Down
28 changes: 2 additions & 26 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -4737,23 +4737,8 @@ Model.compile = function compile(name, schema, collectionName, connection, base)

const _userProvidedOptions = schema._userProvidedOptions || {};

// `bufferCommands` is true by default...
let bufferCommands = true;
// First, take the global option
if (connection.base.get('bufferCommands') != null) {
bufferCommands = connection.base.get('bufferCommands');
}
// Connection-specific overrides the global option
if (connection.config.bufferCommands != null) {
bufferCommands = connection.config.bufferCommands;
}
// And schema options override global and connection
if (_userProvidedOptions.bufferCommands != null) {
bufferCommands = _userProvidedOptions.bufferCommands;
}

const collectionOptions = {
bufferCommands: bufferCommands,
schemaUserProvidedOptions: _userProvidedOptions,
capped: schema.options.capped,
autoCreate: schema.options.autoCreate,
Promise: model.base.Promise
Expand Down Expand Up @@ -4847,17 +4832,8 @@ Model.__subclass = function subclass(conn, schema, collection) {
utils.toCollectionName(_this.modelName, this.base.pluralize());
}

let bufferCommands = true;
if (s) {
if (conn.config.bufferCommands != null) {
bufferCommands = conn.config.bufferCommands;
}
if (_userProvidedOptions.bufferCommands != null) {
bufferCommands = _userProvidedOptions.bufferCommands;
}
}
const collectionOptions = {
bufferCommands: bufferCommands,
schemaUserProvidedOptions: _userProvidedOptions,
capped: s && options.capped
};

Expand Down
13 changes: 10 additions & 3 deletions test/connection.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -715,19 +715,26 @@ describe('connections:', function() {
let db = mongoose.createConnection('mongodb://localhost:27017/test', opts);

let M = db.model('gh5720', new Schema({}));
assert.ok(!M.collection.buffer);
assert.ok(!M.collection._shouldBufferCommands());
db.close();

opts = { bufferCommands: true };
db = mongoose.createConnection('mongodb://localhost:27017/test', opts);
M = db.model('gh5720', new Schema({}, { bufferCommands: false }));
assert.ok(!M.collection.buffer);
assert.ok(!M.collection._shouldBufferCommands());
db.close();

opts = { bufferCommands: true };
db = mongoose.createConnection('mongodb://localhost:27017/test', opts);
M = db.model('gh5720', new Schema({}));
assert.ok(M.collection.buffer);
assert.ok(M.collection._shouldBufferCommands());

db = mongoose.createConnection();
M = db.model('gh5720', new Schema({}));
opts = { bufferCommands: false };
db.openUri('mongodb://localhost:27017/test', opts);
assert.ok(!M.collection._shouldBufferCommands());

db.close(done);
});

Expand Down
11 changes: 9 additions & 2 deletions test/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,21 @@ describe('mongoose module:', function() {
assert.strictEqual(mongoose.options.bufferCommands, false);
});

it('bufferCommands option (gh-5879)', function() {
it('bufferCommands option (gh-5879) (gh-9179)', function() {
const mongoose = new Mongoose();

mongoose.set('bufferCommands', false);

const M = mongoose.model('Test', new Schema({}));

assert.ok(!M.collection.buffer);
assert.ok(!M.collection._shouldBufferCommands());

// Allow changing bufferCommands after defining model (gh-9179)
mongoose.set('bufferCommands', true);
assert.ok(M.collection._shouldBufferCommands());

mongoose.set('bufferCommands', false);
assert.ok(!M.collection._shouldBufferCommands());
});

it('cloneSchemas option (gh-6274)', function() {
Expand Down

0 comments on commit 9a23c42

Please sign in to comment.