12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031 |
- 'use strict';
- const EventEmitter = require('events').EventEmitter;
- const inherits = require('util').inherits;
- const getSingleProperty = require('./utils').getSingleProperty;
- const CommandCursor = require('./command_cursor');
- const handleCallback = require('./utils').handleCallback;
- const filterOptions = require('./utils').filterOptions;
- const toError = require('./utils').toError;
- const ReadPreference = require('mongodb-core').ReadPreference;
- const MongoError = require('mongodb-core').MongoError;
- const ObjectID = require('mongodb-core').ObjectID;
- const Logger = require('mongodb-core').Logger;
- const Collection = require('./collection');
- const mergeOptionsAndWriteConcern = require('./utils').mergeOptionsAndWriteConcern;
- const executeOperation = require('./utils').executeOperation;
- const applyWriteConcern = require('./utils').applyWriteConcern;
- const resolveReadPreference = require('./utils').resolveReadPreference;
- const ChangeStream = require('./change_stream');
- const deprecate = require('util').deprecate;
- const deprecateOptions = require('./utils').deprecateOptions;
- const CONSTANTS = require('./constants');
- // Operations
- const addUser = require('./operations/db_ops').addUser;
- const aggregate = require('./operations/aggregate').aggregate;
- const collections = require('./operations/db_ops').collections;
- const createCollection = require('./operations/db_ops').createCollection;
- const createIndex = require('./operations/db_ops').createIndex;
- const createListener = require('./operations/db_ops').createListener;
- const dropCollection = require('./operations/db_ops').dropCollection;
- const dropDatabase = require('./operations/db_ops').dropDatabase;
- const ensureIndex = require('./operations/db_ops').ensureIndex;
- const evaluate = require('./operations/db_ops').evaluate;
- const executeCommand = require('./operations/db_ops').executeCommand;
- const executeDbAdminCommand = require('./operations/db_ops').executeDbAdminCommand;
- const indexInformation = require('./operations/db_ops').indexInformation;
- const listCollectionsTransforms = require('./operations/db_ops').listCollectionsTransforms;
- const profilingInfo = require('./operations/db_ops').profilingInfo;
- const profilingLevel = require('./operations/db_ops').profilingLevel;
- const removeUser = require('./operations/db_ops').removeUser;
- const setProfilingLevel = require('./operations/db_ops').setProfilingLevel;
- const validateDatabaseName = require('./operations/db_ops').validateDatabaseName;
- /**
- * @fileOverview The **Db** class is a class that represents a MongoDB Database.
- *
- * @example
- * const MongoClient = require('mongodb').MongoClient;
- * // Connection url
- * const url = 'mongodb://localhost:27017';
- * // Database Name
- * const dbName = 'test';
- * // Connect using MongoClient
- * MongoClient.connect(url, function(err, client) {
- * // Select the database by name
- * const testDb = client.db(dbName);
- * client.close();
- * });
- */
- // Allowed parameters
- const legalOptionNames = [
- 'w',
- 'wtimeout',
- 'fsync',
- 'j',
- 'readPreference',
- 'readPreferenceTags',
- 'native_parser',
- 'forceServerObjectId',
- 'pkFactory',
- 'serializeFunctions',
- 'raw',
- 'bufferMaxEntries',
- 'authSource',
- 'ignoreUndefined',
- 'promoteLongs',
- 'promiseLibrary',
- 'readConcern',
- 'retryMiliSeconds',
- 'numberOfRetries',
- 'parentDb',
- 'noListener',
- 'loggerLevel',
- 'logger',
- 'promoteBuffers',
- 'promoteLongs',
- 'promoteValues',
- 'compression',
- 'retryWrites'
- ];
- /**
- * Creates a new Db instance
- * @class
- * @param {string} databaseName The name of the database this instance represents.
- * @param {(Server|ReplSet|Mongos)} topology The server topology for the database.
- * @param {object} [options] Optional settings.
- * @param {string} [options.authSource] If the database authentication is dependent on another databaseName.
- * @param {(number|string)} [options.w] The write concern.
- * @param {number} [options.wtimeout] The write concern timeout.
- * @param {boolean} [options.j=false] Specify a journal write concern.
- * @param {boolean} [options.forceServerObjectId=false] Force server to assign _id values instead of driver.
- * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
- * @param {Boolean} [options.ignoreUndefined=false] Specify if the BSON serializer should ignore undefined fields.
- * @param {boolean} [options.raw=false] Return document results as raw BSON buffers.
- * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
- * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
- * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
- * @param {number} [options.bufferMaxEntries=-1] Sets a cap on how many operations the driver will buffer up before giving up on getting a working connection, default is -1 which is unlimited.
- * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys.
- * @param {object} [options.promiseLibrary] A Promise library class the application wishes to use such as Bluebird, must be ES6 compatible
- * @param {object} [options.readConcern] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
- * @param {ReadConcernLevel} [options.readConcern.level='local'] Specify a read concern level for the collection operations (only MongoDB 3.2 or higher supported)
- * @property {(Server|ReplSet|Mongos)} serverConfig Get the current db topology.
- * @property {number} bufferMaxEntries Current bufferMaxEntries value for the database
- * @property {string} databaseName The name of the database this instance represents.
- * @property {object} options The options associated with the db instance.
- * @property {boolean} native_parser The current value of the parameter native_parser.
- * @property {boolean} slaveOk The current slaveOk value for the db instance.
- * @property {object} writeConcern The current write concern values.
- * @property {object} topology Access the topology object (single server, replicaset or mongos).
- * @fires Db#close
- * @fires Db#reconnect
- * @fires Db#error
- * @fires Db#timeout
- * @fires Db#parseError
- * @fires Db#fullsetup
- * @return {Db} a Db instance.
- */
- function Db(databaseName, topology, options) {
- options = options || {};
- if (!(this instanceof Db)) return new Db(databaseName, topology, options);
- EventEmitter.call(this);
- // Get the promiseLibrary
- const promiseLibrary = options.promiseLibrary || Promise;
- // Filter the options
- options = filterOptions(options, legalOptionNames);
- // Ensure we put the promiseLib in the options
- options.promiseLibrary = promiseLibrary;
- // Internal state of the db object
- this.s = {
- // Database name
- databaseName: databaseName,
- // DbCache
- dbCache: {},
- // Children db's
- children: [],
- // Topology
- topology: topology,
- // Options
- options: options,
- // Logger instance
- logger: Logger('Db', options),
- // Get the bson parser
- bson: topology ? topology.bson : null,
- // Unpack read preference
- readPreference: options.readPreference,
- // Set buffermaxEntries
- bufferMaxEntries: typeof options.bufferMaxEntries === 'number' ? options.bufferMaxEntries : -1,
- // Parent db (if chained)
- parentDb: options.parentDb || null,
- // Set up the primary key factory or fallback to ObjectID
- pkFactory: options.pkFactory || ObjectID,
- // Get native parser
- nativeParser: options.nativeParser || options.native_parser,
- // Promise library
- promiseLibrary: promiseLibrary,
- // No listener
- noListener: typeof options.noListener === 'boolean' ? options.noListener : false,
- // ReadConcern
- readConcern: options.readConcern
- };
- // Ensure we have a valid db name
- validateDatabaseName(this.s.databaseName);
- // Add a read Only property
- getSingleProperty(this, 'serverConfig', this.s.topology);
- getSingleProperty(this, 'bufferMaxEntries', this.s.bufferMaxEntries);
- getSingleProperty(this, 'databaseName', this.s.databaseName);
- // This is a child db, do not register any listeners
- if (options.parentDb) return;
- if (this.s.noListener) return;
- // Add listeners
- topology.on('error', createListener(this, 'error', this));
- topology.on('timeout', createListener(this, 'timeout', this));
- topology.on('close', createListener(this, 'close', this));
- topology.on('parseError', createListener(this, 'parseError', this));
- topology.once('open', createListener(this, 'open', this));
- topology.once('fullsetup', createListener(this, 'fullsetup', this));
- topology.once('all', createListener(this, 'all', this));
- topology.on('reconnect', createListener(this, 'reconnect', this));
- }
- inherits(Db, EventEmitter);
- // Topology
- Object.defineProperty(Db.prototype, 'topology', {
- enumerable: true,
- get: function() {
- return this.s.topology;
- }
- });
- // Options
- Object.defineProperty(Db.prototype, 'options', {
- enumerable: true,
- get: function() {
- return this.s.options;
- }
- });
- // slaveOk specified
- Object.defineProperty(Db.prototype, 'slaveOk', {
- enumerable: true,
- get: function() {
- if (
- this.s.options.readPreference != null &&
- (this.s.options.readPreference !== 'primary' ||
- this.s.options.readPreference.mode !== 'primary')
- ) {
- return true;
- }
- return false;
- }
- });
- // get the write Concern
- Object.defineProperty(Db.prototype, 'writeConcern', {
- enumerable: true,
- get: function() {
- const ops = {};
- if (this.s.options.w != null) ops.w = this.s.options.w;
- if (this.s.options.j != null) ops.j = this.s.options.j;
- if (this.s.options.fsync != null) ops.fsync = this.s.options.fsync;
- if (this.s.options.wtimeout != null) ops.wtimeout = this.s.options.wtimeout;
- return ops;
- }
- });
- /**
- * Execute a command
- * @method
- * @param {object} command The command hash
- * @param {object} [options] Optional settings.
- * @param {(ReadPreference|string)} [options.readPreference] 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
- * @param {Db~resultCallback} [callback] The command result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.command = function(command, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = Object.assign({}, options);
- return executeOperation(this.s.topology, executeCommand, [this, command, options, callback]);
- };
- /**
- * Execute an aggregation framework pipeline against the database, needs MongoDB >= 3.6
- * @method
- * @param {object} [pipeline=[]] Array containing all the aggregation framework commands for the execution.
- * @param {object} [options] Optional settings.
- * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- * @param {object} [options.cursor] Return the query as cursor, on 2.6 > it returns as a real cursor on pre 2.6 it returns as an emulated cursor.
- * @param {number} [options.cursor.batchSize] The batchSize for the cursor
- * @param {boolean} [options.explain=false] Explain returns the aggregation execution plan (requires mongodb 2.6 >).
- * @param {boolean} [options.allowDiskUse=false] allowDiskUse lets the server know if it can use disk to store temporary results for the aggregation (requires mongodb 2.6 >).
- * @param {number} [options.maxTimeMS] maxTimeMS specifies a cumulative time limit in milliseconds for processing operations on the cursor. MongoDB interrupts the operation at the earliest following interrupt point.
- * @param {boolean} [options.bypassDocumentValidation=false] Allow driver to bypass schema validation in MongoDB 3.2 or higher.
- * @param {boolean} [options.raw=false] Return document results as raw BSON buffers.
- * @param {boolean} [options.promoteLongs=true] Promotes Long values to number if they fit inside the 53 bits resolution.
- * @param {boolean} [options.promoteValues=true] Promotes BSON values to native types where possible, set to false to only receive wrapper types.
- * @param {boolean} [options.promoteBuffers=false] Promotes Binary BSON values to native Node Buffers.
- * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
- * @param {string} [options.comment] Add a comment to an aggregation command
- * @param {string|object} [options.hint] Add an index selection hint to an aggregation command
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Database~aggregationCallback} callback The command result callback
- * @return {(null|AggregationCursor)}
- */
- Db.prototype.aggregate = function(pipeline, options, callback) {
- if (typeof options === 'function') {
- callback = options;
- options = {};
- }
- // If we have no options or callback we are doing
- // a cursor based aggregation
- if (options == null && callback == null) {
- options = {};
- }
- return aggregate(this, '1', pipeline, options, callback);
- };
- /**
- * Return the Admin db instance
- * @method
- * @return {Admin} return the new Admin db instance
- */
- Db.prototype.admin = function() {
- const Admin = require('./admin');
- return new Admin(this, this.s.topology, this.s.promiseLibrary);
- };
- /**
- * The callback format for the collection method, must be used if strict is specified
- * @callback Db~collectionResultCallback
- * @param {MongoError} error An error instance representing the error during the execution.
- * @param {Collection} collection The collection instance.
- */
- /**
- * The callback format for an aggregation call
- * @callback Database~aggregationCallback
- * @param {MongoError} error An error instance representing the error during the execution.
- * @param {AggregationCursor} cursor The cursor if the aggregation command was executed successfully.
- */
- const collectionKeys = [
- 'pkFactory',
- 'readPreference',
- 'serializeFunctions',
- 'strict',
- 'readConcern',
- 'ignoreUndefined',
- 'promoteValues',
- 'promoteBuffers',
- 'promoteLongs'
- ];
- /**
- * Fetch a specific collection (containing the actual collection information). If the application does not use strict mode you
- * can use it without a callback in the following way: `const collection = db.collection('mycollection');`
- *
- * @method
- * @param {string} name the collection name we wish to access.
- * @param {object} [options] Optional settings.
- * @param {(number|string)} [options.w] The write concern.
- * @param {number} [options.wtimeout] The write concern timeout.
- * @param {boolean} [options.j=false] Specify a journal write concern.
- * @param {boolean} [options.raw=false] Return document results as raw BSON buffers.
- * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys.
- * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
- * @param {boolean} [options.strict=false] Returns an error if the collection does not exist
- * @param {object} [options.readConcern] Specify a read concern for the collection. (only MongoDB 3.2 or higher supported)
- * @param {ReadConcernLevel} [options.readConcern.level='local'] Specify a read concern level for the collection operations (only MongoDB 3.2 or higher supported)
- * @param {Db~collectionResultCallback} [callback] The collection result callback
- * @return {Collection} return the new Collection instance if not in strict mode
- */
- Db.prototype.collection = function(name, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- options = Object.assign({}, options);
- // Set the promise library
- options.promiseLibrary = this.s.promiseLibrary;
- // If we have not set a collection level readConcern set the db level one
- options.readConcern = options.readConcern || this.s.readConcern;
- // Do we have ignoreUndefined set
- if (this.s.options.ignoreUndefined) {
- options.ignoreUndefined = this.s.options.ignoreUndefined;
- }
- // Merge in all needed options and ensure correct writeConcern merging from db level
- options = mergeOptionsAndWriteConcern(options, this.s.options, collectionKeys, true);
- // Execute
- if (options == null || !options.strict) {
- try {
- const collection = new Collection(
- this,
- this.s.topology,
- this.s.databaseName,
- name,
- this.s.pkFactory,
- options
- );
- if (callback) callback(null, collection);
- return collection;
- } catch (err) {
- if (err instanceof MongoError && callback) return callback(err);
- throw err;
- }
- }
- // Strict mode
- if (typeof callback !== 'function') {
- throw toError(`A callback is required in strict mode. While getting collection ${name}`);
- }
- // Did the user destroy the topology
- if (this.serverConfig && this.serverConfig.isDestroyed()) {
- return callback(new MongoError('topology was destroyed'));
- }
- const listCollectionOptions = Object.assign({}, options, { nameOnly: true });
- // Strict mode
- this.listCollections({ name: name }, listCollectionOptions).toArray((err, collections) => {
- if (err != null) return handleCallback(callback, err, null);
- if (collections.length === 0)
- return handleCallback(
- callback,
- toError(`Collection ${name} does not exist. Currently in strict mode.`),
- null
- );
- try {
- return handleCallback(
- callback,
- null,
- new Collection(this, this.s.topology, this.s.databaseName, name, this.s.pkFactory, options)
- );
- } catch (err) {
- return handleCallback(callback, err, null);
- }
- });
- };
- /**
- * Create a new collection on a server with the specified options. Use this to create capped collections.
- * More information about command options available at https://docs.mongodb.com/manual/reference/command/create/
- *
- * @method
- * @param {string} name the collection name we wish to access.
- * @param {object} [options] Optional settings.
- * @param {(number|string)} [options.w] The write concern.
- * @param {number} [options.wtimeout] The write concern timeout.
- * @param {boolean} [options.j=false] Specify a journal write concern.
- * @param {boolean} [options.raw=false] Return document results as raw BSON buffers.
- * @param {object} [options.pkFactory] A primary key factory object for generation of custom _id keys.
- * @param {(ReadPreference|string)} [options.readPreference] The preferred read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
- * @param {boolean} [options.serializeFunctions=false] Serialize functions on any object.
- * @param {boolean} [options.strict=false] Returns an error if the collection does not exist
- * @param {boolean} [options.capped=false] Create a capped collection.
- * @param {boolean} [options.autoIndexId=true] DEPRECATED: Create an index on the _id field of the document, True by default on MongoDB 2.6 - 3.0
- * @param {number} [options.size] The size of the capped collection in bytes.
- * @param {number} [options.max] The maximum number of documents in the capped collection.
- * @param {number} [options.flags] Optional. Available for the MMAPv1 storage engine only to set the usePowerOf2Sizes and the noPadding flag.
- * @param {object} [options.storageEngine] Allows users to specify configuration to the storage engine on a per-collection basis when creating a collection on MongoDB 3.0 or higher.
- * @param {object} [options.validator] Allows users to specify validation rules or expressions for the collection. For more information, see Document Validation on MongoDB 3.2 or higher.
- * @param {string} [options.validationLevel] Determines how strictly MongoDB applies the validation rules to existing documents during an update on MongoDB 3.2 or higher.
- * @param {string} [options.validationAction] Determines whether to error on invalid documents or just warn about the violations but allow invalid documents to be inserted on MongoDB 3.2 or higher.
- * @param {object} [options.indexOptionDefaults] Allows users to specify a default configuration for indexes when creating a collection on MongoDB 3.2 or higher.
- * @param {string} [options.viewOn] The name of the source collection or view from which to create the view. The name is not the full namespace of the collection or view; i.e. does not include the database name and implies the same database as the view to create on MongoDB 3.4 or higher.
- * @param {array} [options.pipeline] An array that consists of the aggregation pipeline stage. create creates the view by applying the specified pipeline to the viewOn collection or view on MongoDB 3.4 or higher.
- * @param {object} [options.collation] Specify collation (MongoDB 3.4 or higher) settings for update operation (see 3.4 documentation for available fields).
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~collectionResultCallback} [callback] The results callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.createCollection = deprecateOptions(
- {
- name: 'Db.createCollection',
- deprecatedOptions: ['autoIndexId'],
- optionsIndex: 1
- },
- function(name, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- options.promiseLibrary = options.promiseLibrary || this.s.promiseLibrary;
- return executeOperation(this.s.topology, createCollection, [this, name, options, callback]);
- }
- );
- /**
- * Get all the db statistics.
- *
- * @method
- * @param {object} [options] Optional settings.
- * @param {number} [options.scale] Divide the returned sizes by scale value.
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The collection result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.stats = function(options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- // Build command object
- const commandObject = { dbStats: true };
- // Check if we have the scale value
- if (options['scale'] != null) commandObject['scale'] = options['scale'];
- // If we have a readPreference set
- if (options.readPreference == null && this.s.readPreference) {
- options.readPreference = this.s.readPreference;
- }
- // Execute the command
- return this.command(commandObject, options, callback);
- };
- /**
- * Get the list of all collection information for the specified db.
- *
- * @method
- * @param {object} [filter={}] Query to filter collections by
- * @param {object} [options] 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] The batchSize for the returned command cursor or if pre 2.8 the systems batch collection
- * @param {(ReadPreference|string)} [options.readPreference] 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
- * @return {CommandCursor}
- */
- Db.prototype.listCollections = function(filter, options) {
- filter = filter || {};
- options = options || {};
- // Shallow clone the object
- options = Object.assign({}, options);
- // Set the promise library
- options.promiseLibrary = this.s.promiseLibrary;
- // Ensure valid readPreference
- options.readPreference = resolveReadPreference(options, {
- db: this,
- default: ReadPreference.primary
- });
- // Cursor options
- let cursor = options.batchSize ? { batchSize: options.batchSize } : {};
- // We have a list collections command
- if (this.serverConfig.capabilities().hasListCollectionsCommand) {
- const nameOnly = typeof options.nameOnly === 'boolean' ? options.nameOnly : false;
- // Build the command
- const command = { listCollections: true, filter, cursor, nameOnly };
- // Set the AggregationCursor constructor
- options.cursorFactory = CommandCursor;
- // Create the cursor
- cursor = this.s.topology.cursor(`${this.s.databaseName}.$cmd`, command, options);
- // Do we have a readPreference, apply it
- if (options.readPreference) {
- cursor.setReadPreference(options.readPreference);
- }
- // Return the cursor
- return cursor;
- }
- // We cannot use the listCollectionsCommand
- if (!this.serverConfig.capabilities().hasListCollectionsCommand) {
- // If we have legacy mode and have not provided a full db name filter it
- if (
- typeof filter.name === 'string' &&
- !new RegExp('^' + this.databaseName + '\\.').test(filter.name)
- ) {
- filter = Object.assign({}, filter);
- filter.name = `${this.s.databaseName}.${filter.name}`;
- }
- }
- // No filter, filter by current database
- if (filter == null) {
- filter.name = `/${this.s.databaseName}/`;
- }
- // Rewrite the filter to use $and to filter out indexes
- if (filter.name) {
- filter = { $and: [{ name: filter.name }, { name: /^((?!\$).)*$/ }] };
- } else {
- filter = { name: /^((?!\$).)*$/ };
- }
- // Return options
- const _options = { transforms: listCollectionsTransforms(this.s.databaseName) };
- // Get the cursor
- cursor = this.collection(CONSTANTS.SYSTEM_NAMESPACE_COLLECTION).find(filter, _options);
- // Do we have a readPreference, apply it
- if (options.readPreference) cursor.setReadPreference(options.readPreference);
- // Set the passed in batch size if one was provided
- if (options.batchSize) cursor = cursor.batchSize(options.batchSize);
- // We have a fallback mode using legacy systems collections
- return cursor;
- };
- /**
- * Evaluate JavaScript on the server
- *
- * @method
- * @param {Code} code JavaScript to execute on server.
- * @param {(object|array)} parameters The parameters for the call.
- * @param {object} [options] Optional settings.
- * @param {boolean} [options.nolock=false] Tell MongoDB not to block on the evaluation of the javascript.
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The results callback
- * @deprecated Eval is deprecated on MongoDB 3.2 and forward
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.eval = deprecate(function(code, parameters, options, callback) {
- const args = Array.prototype.slice.call(arguments, 1);
- callback = typeof args[args.length - 1] === 'function' ? args.pop() : undefined;
- parameters = args.length ? args.shift() : parameters;
- options = args.length ? args.shift() || {} : {};
- return executeOperation(this.s.topology, evaluate, [this, code, parameters, options, callback]);
- }, 'Db.eval is deprecated as of MongoDB version 3.2');
- /**
- * Rename a collection.
- *
- * @method
- * @param {string} fromCollection Name of current collection to rename.
- * @param {string} toCollection New name of of the collection.
- * @param {object} [options] Optional settings.
- * @param {boolean} [options.dropTarget=false] Drop the target name collection if it previously exists.
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~collectionResultCallback} [callback] The results callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.renameCollection = function(fromCollection, toCollection, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- // Add return new collection
- options.new_collection = true;
- const collection = this.collection(fromCollection);
- return executeOperation(this.s.topology, collection.rename.bind(collection), [
- toCollection,
- options,
- callback
- ]);
- };
- /**
- * Drop a collection from the database, removing it permanently. New accesses will create a new collection.
- *
- * @method
- * @param {string} name Name of collection to drop
- * @param {Object} [options] Optional settings
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The results callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.dropCollection = function(name, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- // Command to execute
- const cmd = { drop: name };
- // Decorate with write concern
- applyWriteConcern(cmd, { db: this }, options);
- // options
- const opts = Object.assign({}, this.s.options, { readPreference: ReadPreference.PRIMARY });
- if (options.session) opts.session = options.session;
- return executeOperation(this.s.topology, dropCollection, [this, cmd, opts, callback]);
- };
- /**
- * Drop a database, removing it permanently from the server.
- *
- * @method
- * @param {Object} [options] Optional settings
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The results callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.dropDatabase = function(options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- // Drop database command
- const cmd = { dropDatabase: 1 };
- // Decorate with write concern
- applyWriteConcern(cmd, { db: this }, options);
- // Ensure primary only
- const finalOptions = Object.assign({}, this.s.options, {
- readPreference: ReadPreference.PRIMARY
- });
- if (options.session) {
- finalOptions.session = options.session;
- }
- return executeOperation(this.s.topology, dropDatabase, [this, cmd, finalOptions, callback]);
- };
- /**
- * Fetch all collections for the current db.
- *
- * @method
- * @param {Object} [options] Optional settings
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~collectionsResultCallback} [callback] The results callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.collections = function(options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- return executeOperation(this.s.topology, collections, [this, options, callback]);
- };
- /**
- * Runs a command on the database as admin.
- * @method
- * @param {object} command The command hash
- * @param {object} [options] Optional settings.
- * @param {(ReadPreference|string)} [options.readPreference] 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
- * @param {Db~resultCallback} [callback] The command result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.executeDbAdminCommand = function(selector, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- options.readPreference = resolveReadPreference(options);
- return executeOperation(this.s.topology, executeDbAdminCommand, [
- this,
- selector,
- options,
- callback
- ]);
- };
- /**
- * Creates an index on the db and collection.
- * @method
- * @param {string} name Name of the collection to create the index on.
- * @param {(string|object)} fieldOrSpec Defines the index.
- * @param {object} [options] Optional settings.
- * @param {(number|string)} [options.w] The write concern.
- * @param {number} [options.wtimeout] The write concern timeout.
- * @param {boolean} [options.j=false] Specify a journal write concern.
- * @param {boolean} [options.unique=false] Creates an unique index.
- * @param {boolean} [options.sparse=false] Creates a sparse index.
- * @param {boolean} [options.background=false] Creates the index in the background, yielding whenever possible.
- * @param {boolean} [options.dropDups=false] A unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value
- * @param {number} [options.min] For geospatial indexes set the lower bound for the co-ordinates.
- * @param {number} [options.max] For geospatial indexes set the high bound for the co-ordinates.
- * @param {number} [options.v] Specify the format version of the indexes.
- * @param {number} [options.expireAfterSeconds] Allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher)
- * @param {number} [options.name] Override the autogenerated index name (useful if the resulting name is larger than 128 bytes)
- * @param {object} [options.partialFilterExpression] Creates a partial index based on the given filter object (MongoDB 3.2 or higher)
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The command result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.createIndex = function(name, fieldOrSpec, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options ? Object.assign({}, options) : {};
- return executeOperation(this.s.topology, createIndex, [
- this,
- name,
- fieldOrSpec,
- options,
- callback
- ]);
- };
- /**
- * Ensures that an index exists, if it does not it creates it
- * @method
- * @deprecated since version 2.0
- * @param {string} name The index name
- * @param {(string|object)} fieldOrSpec Defines the index.
- * @param {object} [options] Optional settings.
- * @param {(number|string)} [options.w] The write concern.
- * @param {number} [options.wtimeout] The write concern timeout.
- * @param {boolean} [options.j=false] Specify a journal write concern.
- * @param {boolean} [options.unique=false] Creates an unique index.
- * @param {boolean} [options.sparse=false] Creates a sparse index.
- * @param {boolean} [options.background=false] Creates the index in the background, yielding whenever possible.
- * @param {boolean} [options.dropDups=false] A unique index cannot be created on a key that has pre-existing duplicate values. If you would like to create the index anyway, keeping the first document the database indexes and deleting all subsequent documents that have duplicate value
- * @param {number} [options.min] For geospatial indexes set the lower bound for the co-ordinates.
- * @param {number} [options.max] For geospatial indexes set the high bound for the co-ordinates.
- * @param {number} [options.v] Specify the format version of the indexes.
- * @param {number} [options.expireAfterSeconds] Allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher)
- * @param {number} [options.name] Override the autogenerated index name (useful if the resulting name is larger than 128 bytes)
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The command result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.ensureIndex = deprecate(function(name, fieldOrSpec, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- return executeOperation(this.s.topology, ensureIndex, [
- this,
- name,
- fieldOrSpec,
- options,
- callback
- ]);
- }, 'Db.ensureIndex is deprecated as of MongoDB version 3.0 / driver version 2.0');
- Db.prototype.addChild = function(db) {
- if (this.s.parentDb) return this.s.parentDb.addChild(db);
- this.s.children.push(db);
- };
- /**
- * Add a user to the database.
- * @method
- * @param {string} username The username.
- * @param {string} password The password.
- * @param {object} [options] Optional settings.
- * @param {(number|string)} [options.w] The write concern.
- * @param {number} [options.wtimeout] The write concern timeout.
- * @param {boolean} [options.j=false] Specify a journal write concern.
- * @param {object} [options.customData] Custom data associated with the user (only Mongodb 2.6 or higher)
- * @param {object[]} [options.roles] Roles associated with the created user (only Mongodb 2.6 or higher)
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The command result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.addUser = function(username, password, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- return executeOperation(this.s.topology, addUser, [this, username, password, options, callback]);
- };
- /**
- * Remove a user from a database
- * @method
- * @param {string} username The username.
- * @param {object} [options] Optional settings.
- * @param {(number|string)} [options.w] The write concern.
- * @param {number} [options.wtimeout] The write concern timeout.
- * @param {boolean} [options.j=false] Specify a journal write concern.
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The command result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.removeUser = function(username, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- return executeOperation(this.s.topology, removeUser, [this, username, options, callback]);
- };
- /**
- * Set the current profiling level of MongoDB
- *
- * @param {string} level The new profiling level (off, slow_only, all).
- * @param {Object} [options] Optional settings
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The command result callback.
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.setProfilingLevel = function(level, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- return executeOperation(this.s.topology, setProfilingLevel, [this, level, options, callback]);
- };
- /**
- * Retrieve the current profiling information for MongoDB
- *
- * @param {Object} [options] Optional settings
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The command result callback.
- * @return {Promise} returns Promise if no callback passed
- * @deprecated Query the system.profile collection directly.
- */
- Db.prototype.profilingInfo = deprecate(function(options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- return executeOperation(this.s.topology, profilingInfo, [this, options, callback]);
- }, 'Db.profilingInfo is deprecated. Query the system.profile collection directly.');
- /**
- * Retrieve the current profiling Level for MongoDB
- *
- * @param {Object} [options] Optional settings
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @param {Db~resultCallback} [callback] The command result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.profilingLevel = function(options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- return executeOperation(this.s.topology, profilingLevel, [this, options, callback]);
- };
- /**
- * Retrieves this collections index info.
- * @method
- * @param {string} name The name of the collection.
- * @param {object} [options] Optional settings.
- * @param {boolean} [options.full=false] Returns the full raw index information.
- * @param {(ReadPreference|string)} [options.readPreference] 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
- * @param {Db~resultCallback} [callback] The command result callback
- * @return {Promise} returns Promise if no callback passed
- */
- Db.prototype.indexInformation = function(name, options, callback) {
- if (typeof options === 'function') (callback = options), (options = {});
- options = options || {};
- return executeOperation(this.s.topology, indexInformation, [this, name, options, callback]);
- };
- /**
- * Unref all sockets
- * @method
- */
- Db.prototype.unref = function() {
- this.s.topology.unref();
- };
- /**
- * Create a new Change Stream, watching for new changes (insertions, updates, replacements, deletions, and invalidations) in this database. Will ignore all changes to system collections.
- * @method
- * @since 3.1.0
- * @param {Array} [pipeline] An array of {@link https://docs.mongodb.com/manual/reference/operator/aggregation-pipeline/|aggregation pipeline stages} through which to pass change stream documents. This allows for filtering (using $match) and manipulating the change stream documents.
- * @param {object} [options] Optional settings
- * @param {string} [options.fullDocument='default'] Allowed values: ‘default’, ‘updateLookup’. When set to ‘updateLookup’, the change stream will include both a delta describing the changes to the document, as well as a copy of the entire document that was changed from some time after the change occurred.
- * @param {object} [options.resumeAfter] Specifies the logical starting point for the new change stream. This should be the _id field from a previously returned change stream document.
- * @param {number} [options.maxAwaitTimeMS] The maximum amount of time for the server to wait on new documents to satisfy a change stream query
- * @param {number} [options.batchSize] The number of documents to return per batch. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
- * @param {object} [options.collation] Specify collation settings for operation. See {@link https://docs.mongodb.com/manual/reference/command/aggregate|aggregation documentation}.
- * @param {ReadPreference} [options.readPreference] The read preference. Defaults to the read preference of the database. See {@link https://docs.mongodb.com/manual/reference/read-preference|read preference documentation}.
- * @param {Timestamp} [options.startAtClusterTime] receive change events that occur after the specified timestamp
- * @param {ClientSession} [options.session] optional session to use for this operation
- * @return {ChangeStream} a ChangeStream instance.
- */
- Db.prototype.watch = function(pipeline, options) {
- pipeline = pipeline || [];
- options = options || {};
- // Allow optionally not specifying a pipeline
- if (!Array.isArray(pipeline)) {
- options = pipeline;
- pipeline = [];
- }
- return new ChangeStream(this, pipeline, options);
- };
- /**
- * Return the db logger
- * @method
- * @return {Logger} return the db logger
- * @ignore
- */
- Db.prototype.getLogger = function() {
- return this.s.logger;
- };
- /**
- * Db close event
- *
- * Emitted after a socket closed against a single server or mongos proxy.
- *
- * @event Db#close
- * @type {MongoError}
- */
- /**
- * Db reconnect event
- *
- * * Server: Emitted when the driver has reconnected and re-authenticated.
- * * ReplicaSet: N/A
- * * Mongos: Emitted when the driver reconnects and re-authenticates successfully against a Mongos.
- *
- * @event Db#reconnect
- * @type {object}
- */
- /**
- * Db error event
- *
- * Emitted after an error occurred against a single server or mongos proxy.
- *
- * @event Db#error
- * @type {MongoError}
- */
- /**
- * Db timeout event
- *
- * Emitted after a socket timeout occurred against a single server or mongos proxy.
- *
- * @event Db#timeout
- * @type {MongoError}
- */
- /**
- * Db parseError event
- *
- * The parseError event is emitted if the driver detects illegal or corrupt BSON being received from the server.
- *
- * @event Db#parseError
- * @type {MongoError}
- */
- /**
- * Db fullsetup event, emitted when all servers in the topology have been connected to at start up time.
- *
- * * Server: Emitted when the driver has connected to the single server and has authenticated.
- * * ReplSet: Emitted after the driver has attempted to connect to all replicaset members.
- * * Mongos: Emitted after the driver has attempted to connect to all mongos proxies.
- *
- * @event Db#fullsetup
- * @type {Db}
- */
- // Constants
- Db.SYSTEM_NAMESPACE_COLLECTION = CONSTANTS.SYSTEM_NAMESPACE_COLLECTION;
- Db.SYSTEM_INDEX_COLLECTION = CONSTANTS.SYSTEM_INDEX_COLLECTION;
- Db.SYSTEM_PROFILE_COLLECTION = CONSTANTS.SYSTEM_PROFILE_COLLECTION;
- Db.SYSTEM_USER_COLLECTION = CONSTANTS.SYSTEM_USER_COLLECTION;
- Db.SYSTEM_COMMAND_COLLECTION = CONSTANTS.SYSTEM_COMMAND_COLLECTION;
- Db.SYSTEM_JS_COLLECTION = CONSTANTS.SYSTEM_JS_COLLECTION;
- module.exports = Db;
|