Skip to content

Commit

Permalink
feat(listCollections): add support for nameOnly option
Browse files Browse the repository at this point in the history
Fixes NODE-1471
  • Loading branch information
daprahamian committed May 23, 2018
1 parent 552c50a commit d2d0367
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 3 deletions.
14 changes: 11 additions & 3 deletions lib/db.js
Original file line number Diff line number Diff line change
Expand Up @@ -455,8 +455,10 @@ Db.prototype.collection = function(name, options, callback) {
return callback(new MongoError('topology was destroyed'));
}

const listCollectionOptions = Object.assign({}, options, { nameOnly: true });

// Strict mode
this.listCollections({ name: name }, options).toArray(function(err, collections) {
this.listCollections({ name: name }, listCollectionOptions).toArray(function(err, collections) {
if (err != null) return handleCallback(callback, err, null);
if (collections.length === 0)
return handleCallback(
Expand Down Expand Up @@ -486,9 +488,11 @@ var createCollection = function(self, name, options, callback) {
return callback(new MongoError('topology was destroyed'));
}

const listCollectionOptions = Object.assign({}, finalOptions, { nameOnly: true });

// Check if we have the name
self
.listCollections({ name: name }, finalOptions)
.listCollections({ name: name }, listCollectionOptions)
.setReadPreference(ReadPreference.PRIMARY)
.toArray(function(err, collections) {
if (err != null) return handleCallback(callback, err, null);
Expand Down Expand Up @@ -653,6 +657,7 @@ var listCollectionsTranforms = function(databaseName) {
* @method
* @param {object} [filter={}] Query to filter collections by
* @param {object} [options=null] Optional settings.
* @param {boolean} [options.nameOnly=false] Since 4.0: If true, will only return the collection name in the response, and will omit additional info
* @param {number} [options.batchSize=null] The batchSize for the returned command cursor or if pre 2.8 the systems batch collection
* @param {(ReadPreference|string)} [options.readPreference=null] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
* @param {ClientSession} [options.session] optional session to use for this operation
Expand All @@ -678,8 +683,10 @@ Db.prototype.listCollections = function(filter, options) {
if (this.serverConfig.capabilities().hasListCollectionsCommand) {
// Cursor options
var cursor = options.batchSize ? { batchSize: options.batchSize } : {};

const nameOnly = typeof options.nameOnly === 'boolean' ? options.nameOnly : false;
// Build the command
var command = { listCollections: true, filter: filter, cursor: cursor };
var command = { listCollections: true, filter, cursor, nameOnly };
// Set the AggregationCursor constructor
options.cursorFactory = CommandCursor;
// Create the cursor
Expand Down Expand Up @@ -917,6 +924,7 @@ Db.prototype.collections = function(options, callback) {
};

var collections = function(self, options, callback) {
options = Object.assign({}, options, { nameOnly: true });
// Let's get the collection names
self.listCollections({}, options).toArray(function(err, documents) {
if (err != null) return handleCallback(callback, err, null);
Expand Down
86 changes: 86 additions & 0 deletions test/unit/db_list_collections_tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
'use strict';

const mock = require('mongodb-mock-server');
const expect = require('chai').expect;
const MongoClient = require('../../lib/mongo_client');

describe('db.listCollections', function() {
const testHarness = {};
afterEach(() => mock.cleanup());
beforeEach(() => {
return mock.createServer().then(server => {
server.setMessageHandler(request => {
const doc = request.document;

if (doc.ismaster) {
return request.reply(Object.assign({}, mock.DEFAULT_ISMASTER));
}

if (doc.listCollections) {
return request.reply({
ok: 1,
cursor: {
id: 0,
ns: 'test.$cmd.listCollections',
firstBatch: [{ name: 'test', type: 'collection' }]
}
});
}
});
testHarness.server = server;
});
});

[
{
description: 'should always send nameOnly option, defaulting to false',
command: db => db.listCollections().toArray(() => {}),
listCollectionsValue: false
},
{
description: 'should propagate the nameOnly option',
command: db => db.listCollections({}, { nameOnly: true }).toArray(() => {}),
listCollectionsValue: true
},
{
description: 'should send nameOnly: true for db.createCollection',
command: db => db.createCollection('foo', () => {}),
listCollectionsValue: true
},
{
description: 'should send nameOnly: true for db.collections',
command: db => db.collections(() => {}),
listCollectionsValue: true
},
{
description: 'should send nameOnly: true for db.collection',
command: db => db.collection('foo', { strict: true }, () => {}),
listCollectionsValue: true
}
].forEach(config => {
function testFn(done) {
const client = new MongoClient(`mongodb://${testHarness.server.uri()}/test`, {
monitorCommands: true
});

client.connect((err, client) => {
const db = client.db('foo');

client.on('commandStarted', e => {
if (e.commandName === 'listCollections') {
try {
expect(e).to.have.nested.property('command.nameOnly', config.listCollectionsValue);
client.close(done);
} catch (err) {
client.close(() => done(err));
}
}
});

config.command(db);
});
}

it(config.description, { test: testFn, metadata: { requires: { mongodb: '>=2.7.6' } } });
});
});

0 comments on commit d2d0367

Please sign in to comment.