diff options
| author | nanalelfe <nargiza.nosirova@mail.utoronto.ca> | 2016-08-14 10:13:55 +0000 |
|---|---|---|
| committer | nanalelfe <nargiza.nosirova@mail.utoronto.ca> | 2016-08-14 10:13:55 +0000 |
| commit | a532390f81e35f611fd02ad3d543f4d52217ca3c (patch) | |
| tree | 7bebb4f5614afb82c3103b6e9730a62f0b97a42d /node_modules/mongodb/lib | |
| parent | ef2674cfe13d2c425c5a3b312244c46f2531979d (diff) | |
Fixed signin and signup
Diffstat (limited to 'node_modules/mongodb/lib')
| -rw-r--r-- | node_modules/mongodb/lib/aggregation_cursor.js | 3 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/bulk/ordered.js | 2 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/collection.js | 146 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/command_cursor.js | 2 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/cursor.js | 18 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/db.js | 72 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/mongo_client.js | 41 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/mongos.js | 36 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/read_preference.js | 50 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/replset.js | 48 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/server.js | 37 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/topology_base.js | 9 | ||||
| -rw-r--r-- | node_modules/mongodb/lib/url_parser.js | 5 |
13 files changed, 390 insertions, 79 deletions
diff --git a/node_modules/mongodb/lib/aggregation_cursor.js b/node_modules/mongodb/lib/aggregation_cursor.js index 3a506c2..7546ee3 100644 --- a/node_modules/mongodb/lib/aggregation_cursor.js +++ b/node_modules/mongodb/lib/aggregation_cursor.js @@ -13,8 +13,7 @@ var inherits = require('util').inherits , Readable = require('stream').Readable || require('readable-stream').Readable , Define = require('./metadata') , CoreCursor = require('./cursor') - , Query = require('mongodb-core').Query - , CoreReadPreference = require('mongodb-core').ReadPreference; + , Query = require('mongodb-core').Query; /** * @fileOverview The **AggregationCursor** class is an internal class that embodies an aggregation cursor on MongoDB diff --git a/node_modules/mongodb/lib/bulk/ordered.js b/node_modules/mongodb/lib/bulk/ordered.js index a910689..762e861 100644 --- a/node_modules/mongodb/lib/bulk/ordered.js +++ b/node_modules/mongodb/lib/bulk/ordered.js @@ -318,6 +318,7 @@ OrderedBulkOperation.prototype.raw = function(op) { var multi = op.updateOne || op.replaceOne ? false : true; var operation = {q: op[key].filter, u: op[key].update || op[key].replacement, multi: multi} operation.upsert = op[key].upsert ? true: false; + if(op.collation) operation.collation = op.collation; return addToOperationsList(this, common.UPDATE, operation); } @@ -331,6 +332,7 @@ OrderedBulkOperation.prototype.raw = function(op) { if(op.deleteOne || op.deleteMany) { var limit = op.deleteOne ? 1 : 0; var operation = {q: op[key].filter, limit: limit} + if(op.collation) operation.collation = op.collation; return addToOperationsList(this, common.REMOVE, operation); } diff --git a/node_modules/mongodb/lib/collection.js b/node_modules/mongodb/lib/collection.js index bbe1e3b..5a94403 100644 --- a/node_modules/mongodb/lib/collection.js +++ b/node_modules/mongodb/lib/collection.js @@ -122,6 +122,8 @@ var Collection = function(db, topology, dbName, name, pkFactory, options) { , promiseLibrary: promiseLibrary // Read Concern , readConcern: options.readConcern + // Collation + , collation: options.collation } } @@ -280,6 +282,7 @@ Collection.prototype.find = function() { // Add read preference if needed newOptions = getReadPreference(this, newOptions, this.s.db, this); + // Set slave ok to true if read preference different from primary if(newOptions.readPreference != null && (newOptions.readPreference != 'primary' || newOptions.readPreference.mode != 'primary')) { @@ -351,6 +354,9 @@ Collection.prototype.find = function() { findCommand.readConcern = this.s.readConcern; } + // Decorate find command with collation options + decorateWithCollation(findCommand, this, options); + // Create the cursor if(typeof callback == 'function') return handleCallback(callback, null, this.s.topology.cursor(this.s.namespace, findCommand, newOptions)); return this.s.topology.cursor(this.s.namespace, findCommand, newOptions); @@ -507,9 +513,7 @@ Collection.prototype.insertMany = function(docs, options, callback) { // Return a Promise return new this.s.promiseLibrary(function(resolve, reject) { - // console.log("########## insertMany 0") bulkWrite(self, operations, options, function(err, r) { - // console.log("########## insertMany 1") if(err) return reject(err); resolve(mapInserManyResults(docs, r)); }); @@ -601,9 +605,25 @@ var bulkWrite = function(self, operations, options, callback) { // Create the bulk operation var bulk = options.ordered == true || options.ordered == null ? self.initializeOrderedBulkOp(options) : self.initializeUnorderedBulkOp(options); + // Do we have a collation + var collation = false; + // for each op go through and add to the bulk try { for(var i = 0; i < operations.length; i++) { + // Get the operation type + var key = Object.keys(operations[i])[0]; + // Check if we have a collation + if(operations[i][key].collation) { + collation = true; + } + + // // Have we specified collation, apply it + // decorateWithCollation(operations[i], self, options); + // console.log("================ bulkWrite") + // console.dir(operations[i]) + + // Pass to the raw bulk bulk.raw(operations[i]); } } catch(err) { @@ -613,6 +633,12 @@ var bulkWrite = function(self, operations, options, callback) { // Final options for write concern var finalOptions = writeConcern(shallowClone(options), self.s.db, self, options); var writeCon = finalOptions.writeConcern ? finalOptions.writeConcern : {}; + var capabilities = self.s.topology.capabilities(); + + // Did the user pass in a collation, check if our write server supports it + if(collation && capabilities && !capabilities.commandsTakeCollation) { + return callback(new MongoError(f('server/primary/mongos does not support collation'))); + } // Execute the bulk bulk.execute(writeCon, function(err, r) { @@ -623,11 +649,6 @@ var bulkWrite = function(self, operations, options, callback) { return callback(toError(r.getWriteErrorAt(0)), r); } - // console.log("!!!!!! BULK EXECUTE FINISHED") - // console.dir(err) - // console.dir(r) - - // if(err) return callback(err); r.insertedCount = r.nInserted; r.matchedCount = r.nMatched; r.modifiedCount = r.nModified || 0; @@ -1006,6 +1027,9 @@ var updateDocuments = function(self, selector, document, options, callback) { op.upsert = typeof options.upsert == 'boolean' ? options.upsert : false; op.multi = typeof options.multi == 'boolean' ? options.multi : false; + // Have we specified collation + decorateWithCollation(finalOptions, self, options); + // Update options self.s.topology.update(self.s.namespace, [op], finalOptions, function(err, result) { if(callback == null) return; @@ -1161,6 +1185,7 @@ Collection.prototype.deleteMany = function(filter, options, callback) { var deleteMany = function(self, filter, options, callback) { options.single = false; + removeDocuments(self, filter, options, function(err, r) { if(callback == null) return; if(err && callback) return callback(err); @@ -1192,6 +1217,9 @@ var removeDocuments = function(self, selector, options, callback) { var op = {q: selector, limit: 0}; if(options.single) op.limit = 1; + // Have we specified collation + decorateWithCollation(finalOptions, self, options); + // Execute the remove self.s.topology.remove(self.s.namespace, [op], finalOptions, function(err, result) { if(callback == null) return; @@ -1410,6 +1438,9 @@ var rename = function(self, newName, opt, callback) { var dropTarget = typeof opt.dropTarget == 'boolean' ? opt.dropTarget : false; var cmd = {'renameCollection':renameCollection, 'to':toCollection, 'dropTarget':dropTarget}; + // Decorate command with writeConcern if supported + decorateWithWriteConcern(cmd, self, opt); + // Execute against admin self.s.db.admin().command(cmd, opt, function(err, doc) { if(err) return handleCallback(callback, err, null); @@ -1436,10 +1467,10 @@ define.classMethod('rename', {callback: true, promise:true}); Collection.prototype.drop = function(options, callback) { var self = this; if(typeof options == 'function') callback = options, options = {}; - options = options | {}; + options = options || {}; // Execute using callback - if(typeof callback == 'function') return self.s.db.dropCollection(self.s.name, callback); + if(typeof callback == 'function') return self.s.db.dropCollection(self.s.name, options, callback); // Return a Promise return new this.s.promiseLibrary(function(resolve, reject) { self.s.db.dropCollection(self.s.name, options, function(err, r) { @@ -1589,11 +1620,18 @@ Collection.prototype.createIndexes = function(indexSpecs, callback) { } var createIndexes = function(self, indexSpecs, callback) { + var capabilities = self.s.topology.capabilities(); + // Ensure we generate the correct name if the parameter is not set for(var i = 0; i < indexSpecs.length; i++) { if(indexSpecs[i].name == null) { var keys = []; + // Did the user pass in a collation, check if our write server supports it + if(indexSpecs[i].collation && capabilities && !capabilities.commandsTakeCollation) { + return callback(new MongoError(f('server/primary/mongos does not support collation'))); + } + for(var name in indexSpecs[i].key) { keys.push(f('%s_%s', name, indexSpecs[i].key[name])); } @@ -1645,7 +1683,10 @@ Collection.prototype.dropIndex = function(indexName, options, callback) { var dropIndex = function(self, indexName, options, callback) { // Delete index command - var cmd = {'deleteIndexes':self.s.name, 'index':indexName}; + var cmd = {'dropIndexes':self.s.name, 'index':indexName}; + + // Decorate command with writeConcern if supported + decorateWithWriteConcern(cmd, self, options); // Execute command self.s.db.command(cmd, options, function(err, result) { @@ -1663,11 +1704,15 @@ define.classMethod('dropIndex', {callback: true, promise:true}); * @param {Collection~resultCallback} [callback] The command result callback * @return {Promise} returns Promise if no callback passed */ -Collection.prototype.dropIndexes = function(callback) { +Collection.prototype.dropIndexes = function(options, callback) { var self = this; + // Do we have options + if(typeof options == 'function') callback = options, options = {}; + options = options || {}; + // Execute using callback - if(typeof callback == 'function') return dropIndexes(self, callback); + if(typeof callback == 'function') return dropIndexes(self, options, callback); // Return a Promise return new this.s.promiseLibrary(function(resolve, reject) { @@ -1678,8 +1723,8 @@ Collection.prototype.dropIndexes = function(callback) { }); } -var dropIndexes = function(self, callback) { - self.dropIndex('*', function (err, result) { +var dropIndexes = function(self, options, callback) { + self.dropIndex('*', options, function(err, result) { if(err) return handleCallback(callback, err, false); handleCallback(callback, null, true); }); @@ -1726,6 +1771,9 @@ var reIndex = function(self, options, callback) { // Reindex var cmd = {'reIndex':self.s.name}; + // Decorate command with writeConcern if supported + decorateWithWriteConcern(cmd, self, options); + // Execute the command self.s.db.command(cmd, options, function(err, result) { if(callback == null) return; @@ -1760,25 +1808,20 @@ Collection.prototype.listIndexes = function(options) { throw new MongoError('cannot connect to server'); } - // console.log("!!!!!!!!!!!!!! HEY 0") // We have a list collections command if(this.s.topology.capabilities().hasListIndexesCommand) { - // console.log("!!!!!!!!!!!!!! HEY 0:1") // Cursor options var cursor = options.batchSize ? {batchSize: options.batchSize} : {} // Build the command var command = { listIndexes: this.s.name, cursor: cursor }; - // console.log("!!!!!!!!!!!!!! HEY 0:2") // Execute the cursor var cursor = this.s.topology.cursor(f('%s.$cmd', this.s.dbName), command, options); // Do we have a readPreference, apply it if(options.readPreference) cursor.setReadPreference(options.readPreference); - // console.log("!!!!!!!!!!!!!! HEY 0:3") // Return the cursor return cursor; } - // console.log("!!!!!!!!!!!!!! HEY 1") // Get the namespace var ns = f('%s.system.indexes', this.s.dbName); // Get the query @@ -1981,6 +2024,9 @@ var count = function(self, query, options, callback) { cmd.readConcern = self.s.readConcern; } + // Have we specified collation + decorateWithCollation(cmd, self, options); + // Execute command self.s.db.command(cmd, options, function(err, result) { if(err) return handleCallback(callback, err); @@ -2042,6 +2088,9 @@ var distinct = function(self, key, query, options, callback) { cmd.readConcern = self.s.readConcern; } + // Have we specified collation + decorateWithCollation(cmd, self, options); + // Execute the command self.s.db.command(cmd, options, function(err, result) { if(err) return handleCallback(callback, err); @@ -2400,6 +2449,9 @@ var findAndModify = function(self, query, sort, doc, options, callback) { queryObject.bypassDocumentValidation = finalOptions.bypassDocumentValidation; } + // Have we specified collation + decorateWithCollation(queryObject, self, options); + // Execute the command self.s.db.command(queryObject , options, function(err, result) { @@ -2452,6 +2504,35 @@ var findAndRemove = function(self, query, sort, options, callback) { define.classMethod('findAndRemove', {callback: true, promise:true}); +function decorateWithWriteConcern(command, self, options) { + // Do we support collation 3.4 and higher + var capabilities = self.s.topology.capabilities(); + // Do we support write concerns 3.4 and higher + if(capabilities && capabilities.commandsTakeWriteConcern) { + // Get the write concern settings + var finalOptions = writeConcern(shallowClone(options), self.s.db, self, options); + // Add the write concern to the command + if(finalOptions.writeConcern) { + command.writeConcern = finalOptions.writeConcern; + } + } +} + +function decorateWithCollation(command, self, options) { + // Do we support collation 3.4 and higher + var capabilities = self.s.topology.capabilities(); + // Do we support write concerns 3.4 and higher + if(capabilities && capabilities.commandsTakeCollation) { + if(options.collation && typeof options.collation == 'object') { + command.collation = options.collation; + } else if(self.s.collation && typeof self.s.collation == 'object') { + command.collation = self.s.collation; + } else if(self.s.db.s.collation && typeof self.s.db.s.collation == 'object') { + command.collation = self.s.db.s.collation; + } + } +} + /** * Execute an aggregation framework pipeline against the collection, needs MongoDB >= 2.2 * @method @@ -2469,6 +2550,7 @@ define.classMethod('findAndRemove', {callback: true, promise:true}); */ Collection.prototype.aggregate = function(pipeline, options, callback) { var self = this; + if(Array.isArray(pipeline)) { // Set up callback if one is provided if(typeof options == 'function') { @@ -2510,6 +2592,11 @@ Collection.prototype.aggregate = function(pipeline, options, callback) { // Build the command var command = { aggregate : this.s.name, pipeline : pipeline}; + // Decorate command with writeConcern if supported + decorateWithWriteConcern(command, self, options); + // Have we specified collation + decorateWithCollation(command, self, options); + // If we have bypassDocumentValidation set if(typeof options.bypassDocumentValidation == 'boolean') { command.bypassDocumentValidation = options.bypassDocumentValidation; @@ -2743,6 +2830,9 @@ var geoNear = function(self, x, y, point, options, callback) { commandObject.readConcern = self.s.readConcern; } + // Have we specified collation + decorateWithCollation(commandObject, self, options); + // Execute the command self.s.db.command(commandObject, options, function (err, res) { if(err) return handleCallback(callback, err); @@ -2952,6 +3042,9 @@ var group = function(self, keys, condition, initial, reduce, finalize, command, selector.readConcern = self.s.readConcern; } + // Have we specified collation + decorateWithCollation(selector, self, options); + // Execute command self.s.db.command(selector, options, function(err, result) { if(err) return handleCallback(callback, err, null); @@ -3085,7 +3178,10 @@ var mapReduce = function(self, map, reduce, options, callback) { // If we have a read preference and inline is not set as output fail hard if((options.readPreference != false && options.readPreference != 'primary') && options['out'] && (options['out'].inline != 1 && options['out'] != 'inline')) { + // Force readPreference to primary options.readPreference = 'primary'; + // Decorate command with writeConcern if supported + decorateWithWriteConcern(mapCommandHash, self, options); } else if(self.s.readConcern) { mapCommandHash.readConcern = self.s.readConcern; } @@ -3095,6 +3191,9 @@ var mapReduce = function(self, map, reduce, options, callback) { mapCommandHash.bypassDocumentValidation = options.bypassDocumentValidation; } + // Have we specified collation + decorateWithCollation(mapCommandHash, self, options); + // Execute command self.s.db.command(mapCommandHash, {readPreference:options.readPreference}, function (err, result) { if(err) return handleCallback(callback, err); @@ -3205,18 +3304,18 @@ var getReadPreference = function(self, options, db, coll) { r = options.readPreference } else if(self.s.readPreference) { r = self.s.readPreference - } else if(db.readPreference) { - r = db.readPreference; + } else if(db.s.readPreference) { + r = db.s.readPreference; } if(r instanceof ReadPreference) { - options.readPreference = new CoreReadPreference(r.mode, r.tags); + options.readPreference = new CoreReadPreference(r.mode, r.tags, {maxStalenessMS: r.maxStalenessMS}); } else if(typeof r == 'string') { options.readPreference = new CoreReadPreference(r); } else if(r && !(r instanceof ReadPreference) && typeof r == 'object') { var mode = r.mode || r.preference; if (mode && typeof mode == 'string') { - options.readPreference = new CoreReadPreference(mode, r.tags); + options.readPreference = new CoreReadPreference(mode, r.tags, {maxStalenessMS: r.maxStalenessMS}); } } @@ -3227,6 +3326,7 @@ var testForFields = { limit: 1, sort: 1, fields:1, skip: 1, hint: 1, explain: 1, snapshot: 1, timeout: 1, tailable: 1, tailableRetryInterval: 1 , numberOfRetries: 1, awaitdata: 1, awaitData: 1, exhaust: 1, batchSize: 1, returnKey: 1, maxScan: 1, min: 1, max: 1, showDiskLoc: 1 , comment: 1, raw: 1, readPreference: 1, partial: 1, read: 1, dbName: 1, oplogReplay: 1, connection: 1, maxTimeMS: 1, transforms: 1 + , collation: 1 } module.exports = Collection; diff --git a/node_modules/mongodb/lib/command_cursor.js b/node_modules/mongodb/lib/command_cursor.js index 94c5234..c0d86ca 100644 --- a/node_modules/mongodb/lib/command_cursor.js +++ b/node_modules/mongodb/lib/command_cursor.js @@ -163,7 +163,7 @@ CommandCursor.prototype.setReadPreference = function(r) { if(this.s.state != CommandCursor.INIT) throw MongoError.create({message: 'cannot change cursor readPreference after cursor has been accessed', driver:true}); if(r instanceof ReadPreference) { - this.s.options.readPreference = new CoreReadPreference(r.mode, r.tags); + this.s.options.readPreference = new CoreReadPreference(r.mode, r.tags, {maxStalenessMS: r.maxStalenessMS}); } else if(typeof r == 'string') { this.s.options.readPreference = new CoreReadPreference(r); } else if(r instanceof CoreReadPreference) { diff --git a/node_modules/mongodb/lib/cursor.js b/node_modules/mongodb/lib/cursor.js index 9000847..f62b6d6 100644 --- a/node_modules/mongodb/lib/cursor.js +++ b/node_modules/mongodb/lib/cursor.js @@ -579,6 +579,20 @@ Cursor.prototype.batchSize = function(value) { define.classMethod('batchSize', {callback: false, promise:false, returns: [Cursor]}); /** + * Set the collation options for the cursor. + * @method + * @param {object} value The cursor collation options + * @throws {MongoError} + * @return {Cursor} + */ +Cursor.prototype.collation = function(value) { + this.s.cmd.collation = value; + return this; +} + +define.classMethod('collation', {callback: false, promise:false, returns: [Cursor]}); + +/** * Set the limit for the cursor. * @method * @param {number} value The limit for the cursor query. @@ -779,7 +793,7 @@ define.classMethod('forEach', {callback: true, promise:false}); Cursor.prototype.setReadPreference = function(r) { if(this.s.state != Cursor.INIT) throw MongoError.create({message: 'cannot change cursor readPreference after cursor has been accessed', driver:true}); if(r instanceof ReadPreference) { - this.s.options.readPreference = new CoreReadPreference(r.mode, r.tags); + this.s.options.readPreference = new CoreReadPreference(r.mode, r.tags, {maxStalenessMS: r.maxStalenessMS}); } else if(typeof r == 'string'){ this.s.options.readPreference = new CoreReadPreference(r); } else if(r instanceof CoreReadPreference) { @@ -879,7 +893,7 @@ define.classMethod('toArray', {callback: true, promise:true}); /** * Get the count of documents for this cursor * @method - * @param {boolean} applySkipLimit Should the count command apply limit and skip settings on the cursor or in the passed in options. + * @param {boolean} [applySkipLimit=true] Should the count command apply limit and skip settings on the cursor or in the passed in options. * @param {object} [options=null] Optional settings. * @param {number} [options.skip=null] The number of documents to skip. * @param {number} [options.limit=null] The maximum amounts to count before aborting. diff --git a/node_modules/mongodb/lib/db.js b/node_modules/mongodb/lib/db.js index a51ca0b..e6eadc4 100644 --- a/node_modules/mongodb/lib/db.js +++ b/node_modules/mongodb/lib/db.js @@ -47,7 +47,7 @@ var debugFields = ['authSource', 'w', 'wtimeout', 'j', 'native_parser', 'forceSe var 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']; + , 'parentDb', 'noListener', 'loggerLevel', 'logger', 'collation']; /** * Creates a new Db instance @@ -143,6 +143,8 @@ var Db = function(databaseName, topology, options) { , noListener: typeof options.noListener == 'boolean' ? options.noListener : false // ReadConcern , readConcern: options.readConcern + // Collation + , collation: options.collation } // Ensure we have a valid db name @@ -262,11 +264,11 @@ var convertReadPreference = function(readPreference) { if(readPreference && typeof readPreference == 'string') { return new CoreReadPreference(readPreference); } else if(readPreference instanceof ReadPreference) { - return new CoreReadPreference(readPreference.mode, readPreference.tags); + return new CoreReadPreference(readPreference.mode, readPreference.tags, {maxStalenessMS: readPreference.maxStalenessMS}); } else if(readPreference && typeof readPreference == 'object') { var mode = readPreference.mode || readPreference.preference; if (mode && typeof mode == 'string') { - readPreference = new CoreReadPreference(mode, readPreference.tags); + readPreference = new CoreReadPreference(mode, readPreference.tags, {maxStalenessMS: readPreference.maxStalenessMS}); } } return readPreference; @@ -437,6 +439,11 @@ Db.prototype.collection = function(name, options, callback) { // If we have not set a collection level readConcern set the db level one options.readConcern = options.readConcern || this.s.readConcern; + // Do we have a db level collation but not one for the collection + if(!options.collation && this.s.collation && typeof this.s.collation == 'object') { + options.collation = this.s.collation; + } + // Do we have ignoreUndefined set if(this.s.options.ignoreUndefined) { options.ignoreUndefined = this.s.options.ignoreUndefined; @@ -479,6 +486,18 @@ Db.prototype.collection = function(name, options, callback) { define.classMethod('collection', {callback: true, promise:false, returns: [Collection]}); +function decorateWithWriteConcern(command, self, options) { + // Do we support write concerns 3.4 and higher + if(self.s.topology.capabilities().commandsTakeWriteConcern) { + // Get the write concern settings + var finalOptions = writeConcern(shallowClone(options), self, options); + // Add the write concern to the command + if(finalOptions.writeConcern) { + command.writeConcern = finalOptions.writeConcern; + } + } +} + var createCollection = function(self, name, options, callback) { // Get the write concern options var finalOptions = writeConcern(shallowClone(options), self, options); @@ -500,6 +519,9 @@ var createCollection = function(self, name, options, callback) { // Create collection command var cmd = {'create':name}; + // Decorate command with writeConcern if supported + decorateWithWriteConcern(cmd, self, options); + // Add all optional parameters for(var n in options) { if(options[n] != null && typeof options[n] != 'function') @@ -799,11 +821,14 @@ define.classMethod('renameCollection', {callback: true, promise:true}); Db.prototype.dropCollection = function(name, options, callback) { var self = this; if(typeof options == 'function') callback = options, options = {}; - options = options | {}; + options = options || {}; // Command to execute var cmd = {'drop':name} + // Decorate with write concern + decorateWithWriteConcern(cmd, self, options); + // options options = assign({}, this.s.options, {readPreference: ReadPreference.PRIMARY}); @@ -843,10 +868,15 @@ define.classMethod('dropCollection', {callback: true, promise:true}); * @param {Db~resultCallback} [callback] The results callback * @return {Promise} returns Promise if no callback passed */ -Db.prototype.dropDatabase = function(callback) { +Db.prototype.dropDatabase = function(options, callback) { var self = this; + if(typeof options == 'function') callback = options, options = {}; // Drop database command var cmd = {'dropDatabase':1}; + + // Decorate with write concern + decorateWithWriteConcern(cmd, self, options); + // Ensure primary only var options = assign({}, this.s.options, {readPreference: ReadPreference.PRIMARY}); @@ -1132,29 +1162,28 @@ Db.prototype.addChild = function(db) { */ Db.prototype.db = function(dbName, options) { options = options || {}; + // Copy the options and add out internal override of the not shared flag - for(var key in this.options) { - options[key] = this.options[key]; - } + var finalOptions = assign({}, this.options, options); // Do we have the db in the cache already - if(this.s.dbCache[dbName] && options.returnNonCachedInstance !== true) { + if(this.s.dbCache[dbName] && finalOptions.returnNonCachedInstance !== true) { return this.s.dbCache[dbName]; } // Add current db as parentDb - if(options.noListener == null || options.noListener == false) { - options.parentDb = this; + if(finalOptions.noListener == null || finalOptions.noListener == false) { + finalOptions.parentDb = this; } // Add promiseLibrary - options.promiseLibrary = this.s.promiseLibrary; + finalOptions.promiseLibrary = this.s.promiseLibrary; // Return the db object - var db = new Db(dbName, this.s.topology, options) + var db = new Db(dbName, this.s.topology, finalOptions) // Add as child - if(options.noListener == null || options.noListener == false) { + if(finalOptions.noListener == null || finalOptions.noListener == false) { this.addChild(db); } @@ -1700,9 +1729,24 @@ var createIndexUsingCreateIndexes = function(self, name, fieldOrSpec, options, c } } + // Get capabilities + var capabilities = self.s.topology.capabilities(); + + // Did the user pass in a collation, check if our write server supports it + if(indexes[0].collation && capabilities && !capabilities.commandsTakeCollation) { + // Create a new error + var error = new MongoError(f('server/primary/mongos does not support collation')); + error.code = 67; + // Return the error + return callback(error); + } + // Create command, apply write concern to command var cmd = writeConcern({createIndexes: name, indexes: indexes}, self, options); + // Decorate command with writeConcern if supported + decorateWithWriteConcern(cmd, self, options); + // ReadPreference primary options.readPreference = ReadPreference.PRIMARY; diff --git a/node_modules/mongodb/lib/mongo_client.js b/node_modules/mongodb/lib/mongo_client.js index 8017604..6de464d 100644 --- a/node_modules/mongodb/lib/mongo_client.js +++ b/node_modules/mongodb/lib/mongo_client.js @@ -7,9 +7,10 @@ var parse = require('./url_parser') , Define = require('./metadata') , ReadPreference = require('./read_preference') , Logger = require('mongodb-core').Logger + , MongoError = require('mongodb-core').MongoError , Db = require('./db') , dns = require('dns') - , f = require('util').format + , f = require('util').format , shallowClone = require('./utils').shallowClone; /** @@ -130,9 +131,12 @@ var mergeOptions = function(target, source, flatten) { var createUnifiedOptions = function(finalOptions, options) { var childOptions = ['mongos', 'server', 'db' , 'replset', 'db_options', 'server_options', 'rs_options', 'mongos_options']; + var noMerge = ['collation']; for(var name in options) { - if(childOptions.indexOf(name.toLowerCase()) != -1) { + if(noMerge.indexOf(name.toLowerCase()) != -1) { + finalOptions[name] = options[name]; + } else if(childOptions.indexOf(name.toLowerCase()) != -1) { finalOptions = mergeOptions(finalOptions, options[name], false); } else { if(options[name] && typeof options[name] == 'object' && !Buffer.isBuffer(options[name]) && !Array.isArray(options[name])) { @@ -157,9 +161,14 @@ function translateOptions(options) { options.readPreference.tags = options.readPreferenceTags || options.read_preference_tags; } + // Do we have maxStalenessMS + if(options.maxStalenessMS) { + options.readPreference.maxStalenessMS = options.maxStalenessMS; + } + // Set the socket and connection timeouts - if(!options.socketTimeoutMS) options.socketTimeoutMS = 30000; - if(!options.connectTimeoutMS) options.connectTimeoutMS = 30000; + if(!options.socketTimeoutMS == null) options.socketTimeoutMS = 30000; + if(!options.connectTimeoutMS == null) options.connectTimeoutMS = 30000; // Create server instances return options.servers.map(function(serverObj) { @@ -269,21 +278,35 @@ var connect = function(url, options, callback) { _finalOptions = createUnifiedOptions(_finalOptions, options); // Check if we have connection and socket timeout set - if(!_finalOptions.socketTimeoutMS) _finalOptions.socketTimeoutMS = 120000; - if(!_finalOptions.connectTimeoutMS) _finalOptions.connectTimeoutMS = 120000; + if(!_finalOptions.socketTimeoutMS == null) _finalOptions.socketTimeoutMS = 120000; + if(!_finalOptions.connectTimeoutMS == null) _finalOptions.connectTimeoutMS = 120000; // Failure modes if(object.servers.length == 0) { throw new Error("connection string must contain at least one seed host"); } + function connectCallback(err, db) { + if(err && err.message == 'no mongos proxies found in seed list') { + if(logger.isWarn()) { + logger.warn(f('seed list contains no mongos proxies, replicaset connections requires the parameter replicaSet to be supplied in the URI or options object, mongodb://server:port/db?replicaSet=name')); + } + + // Return a more specific error message for MongoClient.connect + return callback(new MongoError('seed list contains no mongos proxies, replicaset connections requires the parameter replicaSet to be supplied in the URI or options object, mongodb://server:port/db?replicaSet=name')); + } + + // Return the error and db instance + callback(err, db); + } + // Do we have a replicaset then skip discovery and go straight to connectivity if(_finalOptions.replicaSet || _finalOptions.rs_name) { - return createReplicaset(_finalOptions, connectHandler(_finalOptions, callback)); + return createReplicaset(_finalOptions, connectHandler(_finalOptions, connectCallback)); } else if(object.servers.length > 1) { - return createMongos(_finalOptions, connectHandler(_finalOptions, callback)); + return createMongos(_finalOptions, connectHandler(_finalOptions, connectCallback)); } else { - return createServer(_finalOptions, connectHandler(_finalOptions, callback)); + return createServer(_finalOptions, connectHandler(_finalOptions, connectCallback)); } } diff --git a/node_modules/mongodb/lib/mongos.js b/node_modules/mongodb/lib/mongos.js index 460f93f..b6e4635 100644 --- a/node_modules/mongodb/lib/mongos.js +++ b/node_modules/mongodb/lib/mongos.js @@ -17,7 +17,16 @@ var EventEmitter = require('events').EventEmitter , MAX_JS_INT = require('./utils').MAX_JS_INT , translateOptions = require('./utils').translateOptions , filterOptions = require('./utils').filterOptions - , mergeOptions = require('./utils').mergeOptions; + , mergeOptions = require('./utils').mergeOptions + , os = require('os'); + +// Get package.json variable +var driverVersion = require(__dirname + '/../package.json').version; +var nodejsversion = f('Node.js %s, %s', process.version, os.endianness()); +var type = os.type(); +var name = process.platform; +var architecture = process.arch; +var release = os.release(); /** * @fileOverview The **Mongos** class is a class that represents a Mongos Proxy topology and is @@ -44,7 +53,7 @@ var EventEmitter = require('events').EventEmitter , 'sslCA', 'sslCert', 'sslKey', 'sslPass', 'socketOptions', 'bufferMaxEntries' , 'store', 'auto_reconnect', 'autoReconnect', 'emitError' , 'keepAlive', 'noDelay', 'connectTimeoutMS', 'socketTimeoutMS' - , 'loggerLevel', 'logger', 'reconnectTries']; + , 'loggerLevel', 'logger', 'reconnectTries', 'appname', 'domainsEnabled']; /** * Creates a new Mongos instance @@ -68,6 +77,7 @@ var EventEmitter = require('events').EventEmitter * @param {number} [options.socketOptions.keepAlive=0] TCP KeepAlive on the socket with a X ms delay before start. * @param {number} [options.socketOptions.connectTimeoutMS=0] TCP Connection timeout setting * @param {number} [options.socketOptions.socketTimeoutMS=0] TCP Socket timeout setting + * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit. * @fires Mongos#connect * @fires Mongos#ha * @fires Mongos#joined @@ -139,6 +149,28 @@ var Mongos = function(servers, options) { clonedOptions.keepAlive = clonedOptions.keepAlive > 0; } + // Build default client information + this.clientInfo = { + driver: { + name: "nodejs", + version: driverVersion + }, + os: { + type: type, + name: name, + architecture: architecture, + version: release + }, + platform: nodejsversion + } + + // Build default client information + clonedOptions.clientInfo = this.clientInfo; + // Do we have an application specific string + if(options.appname) { + clonedOptions.clientInfo.application = { name: options.appname }; + } + // Create the Mongos var mongos = new CMongos(seedlist, clonedOptions) // Server capabilities diff --git a/node_modules/mongodb/lib/read_preference.js b/node_modules/mongodb/lib/read_preference.js index 73b253a..0c8da2b 100644 --- a/node_modules/mongodb/lib/read_preference.js +++ b/node_modules/mongodb/lib/read_preference.js @@ -3,7 +3,7 @@ /** * @fileOverview The **ReadPreference** class is a class that represents a MongoDB ReadPreference and is * used to construct connections. - * + * * @example * var Db = require('mongodb').Db, * ReplSet = require('mongodb').ReplSet, @@ -27,7 +27,7 @@ /** * Creates a new ReadPreference instance - * + * * Read Preferences * - **ReadPreference.PRIMARY**, Read from primary only. All operations produce an error (throw an exception where applicable) if primary is unavailable. Cannot be combined with tags (This is the default.). * - **ReadPreference.PRIMARY_PREFERRED**, Read from primary if available, otherwise a secondary. @@ -37,17 +37,34 @@ * * @class * @param {string} mode The ReadPreference mode as listed above. - * @param {object} tags An object representing read preference tags. + * @param {array} tags An object representing read preference tags. + * @param {object} [options] Additional read preference options + * @param {number} [options.maxStalenessMS] Max Secondary Read Stalleness in Miliseconds * @property {string} mode The ReadPreference mode. - * @property {object} tags The ReadPreference tags. + * @property {array} tags The ReadPreference tags. + * @property {object} options Additional read preference options + * @property {number} maxStalenessMS MaxStalenessMS value for the read preference * @return {ReadPreference} a ReadPreference instance. - */ -var ReadPreference = function(mode, tags) { - if(!(this instanceof ReadPreference)) - return new ReadPreference(mode, tags); + */ +var ReadPreference = function(mode, tags, options) { + if(!(this instanceof ReadPreference)) { + return new ReadPreference(mode, tags, options); + } + this._type = 'ReadPreference'; this.mode = mode; this.tags = tags; + this.options = options; + + // If no tags were passed in + if(tags && typeof tags == 'object') { + this.options = tags, this.tags = null; + } + + // Add the maxStalenessMS value to the read Preference + if(this.options && this.options.maxStalenessMS) { + this.maxStalenessMS = this.options.maxStalenessMS; + } } /** @@ -56,7 +73,7 @@ var ReadPreference = function(mode, tags) { * @method * @param {string} mode The string representing the read preference mode. * @return {boolean} - */ + */ ReadPreference.isValid = function(_mode) { return (_mode == ReadPreference.PRIMARY || _mode == ReadPreference.PRIMARY_PREFERRED || _mode == ReadPreference.SECONDARY || _mode == ReadPreference.SECONDARY_PREFERRED @@ -70,7 +87,7 @@ ReadPreference.isValid = function(_mode) { * @method * @param {string} mode The string representing the read preference mode. * @return {boolean} - */ + */ ReadPreference.prototype.isValid = function(mode) { var _mode = typeof mode == 'string' ? mode : this.mode; return ReadPreference.isValid(_mode); @@ -86,12 +103,23 @@ ReadPreference.prototype.toObject = function() { object['tags'] = this.tags; } + if(this.maxStalenessMS) { + object['maxStalenessMS'] = this.maxStalenessMS; + } + return object; } /** * @ignore */ +ReadPreference.prototype.toJSON = function() { + return this.toObject(); +} + +/** + * @ignore + */ ReadPreference.PRIMARY = 'primary'; ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred'; ReadPreference.SECONDARY = 'secondary'; @@ -101,4 +129,4 @@ ReadPreference.NEAREST = 'nearest' /** * @ignore */ -module.exports = ReadPreference;
\ No newline at end of file +module.exports = ReadPreference; diff --git a/node_modules/mongodb/lib/replset.js b/node_modules/mongodb/lib/replset.js index d740464..5bf6026 100644 --- a/node_modules/mongodb/lib/replset.js +++ b/node_modules/mongodb/lib/replset.js @@ -21,8 +21,8 @@ var EventEmitter = require('events').EventEmitter , MAX_JS_INT = require('./utils').MAX_JS_INT , translateOptions = require('./utils').translateOptions , filterOptions = require('./utils').filterOptions - , mergeOptions = require('./utils').mergeOptions; - + , mergeOptions = require('./utils').mergeOptions + , os = require('os'); /** * @fileOverview The **ReplSet** class is a class that represents a Replicaset topology and is * used to construct connections. @@ -48,7 +48,15 @@ var legalOptionNames = ['ha', 'haInterval', 'replicaSet', 'rs_name', 'secondaryA , 'sslCA', 'sslCert', 'sslKey', 'sslPass', 'socketOptions', 'bufferMaxEntries' , 'store', 'auto_reconnect', 'autoReconnect', 'emitError' , 'keepAlive', 'noDelay', 'connectTimeoutMS', 'socketTimeoutMS', 'strategy', 'debug' - , 'loggerLevel', 'logger', 'reconnectTries']; + , 'loggerLevel', 'logger', 'reconnectTries', 'appname', 'domainsEnabled']; + +// Get package.json variable +var driverVersion = require(__dirname + '/../package.json').version; +var nodejsversion = f('Node.js %s, %s', process.version, os.endianness()); +var type = os.type(); +var name = process.platform; +var architecture = process.arch; +var release = os.release(); /** * Creates a new ReplSet instance @@ -74,6 +82,7 @@ var legalOptionNames = ['ha', 'haInterval', 'replicaSet', 'rs_name', 'secondaryA * @param {number} [options.socketOptions.keepAlive=0] TCP KeepAlive on the socket with a X ms delay before start. * @param {number} [options.socketOptions.connectTimeoutMS=10000] TCP Connection timeout setting * @param {number} [options.socketOptions.socketTimeoutMS=0] TCP Socket timeout setting + * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit. * @fires ReplSet#connect * @fires ReplSet#ha * @fires ReplSet#joined @@ -117,13 +126,6 @@ var ReplSet = function(servers, options) { return {host: x.host, port: x.port} }); - // console.log("!!!!!!!!!!!!!!!!!!!!!!!!!! RECONNECT") - // console.dir(options) - - // // Get the reconnect option - // var reconnect = typeof options.auto_reconnect == 'boolean' ? options.auto_reconnect : false; - // reconnect = typeof options.autoReconnect == 'boolean' ? options.autoReconnect : reconnect; - // Clone options var clonedOptions = mergeOptions({}, { disconnectHandler: store, @@ -147,8 +149,28 @@ var ReplSet = function(servers, options) { clonedOptions.keepAlive = clonedOptions.keepAlive > 0; } - // console.log("=============== create CReplSet") - // console.dir(clonedOptions) + // Client info + this.clientInfo = { + driver: { + name: "nodejs", + version: driverVersion + }, + os: { + type: type, + name: name, + architecture: architecture, + version: release + }, + platform: nodejsversion + } + + // Build default client information + clonedOptions.clientInfo = this.clientInfo; + // Do we have an application specific string + if(options.appname) { + clonedOptions.clientInfo.application = { name: options.appname }; + } + // Create the ReplSet var replset = new CReplSet(seedlist, clonedOptions); // Server capabilities @@ -216,7 +238,7 @@ var translateReadPreference = function(options) { options.readPreference = new CoreReadPreference(options.readPreference); } else if(options.readPreference instanceof ReadPreference) { options.readPreference = new CoreReadPreference(options.readPreference.mode - , options.readPreference.tags); + , options.readPreference.tags, {maxStalenessMS: options.readPreference.maxStalenessMS}); } return options; diff --git a/node_modules/mongodb/lib/server.js b/node_modules/mongodb/lib/server.js index cf5ba5a..78684bb 100644 --- a/node_modules/mongodb/lib/server.js +++ b/node_modules/mongodb/lib/server.js @@ -15,7 +15,16 @@ var EventEmitter = require('events').EventEmitter , MAX_JS_INT = require('./utils').MAX_JS_INT , translateOptions = require('./utils').translateOptions , filterOptions = require('./utils').filterOptions - , mergeOptions = require('./utils').mergeOptions; + , mergeOptions = require('./utils').mergeOptions + , os = require('os'); + +// Get package.json variable +var driverVersion = require(__dirname + '/../package.json').version; +var nodejsversion = f('Node.js %s, %s', process.version, os.endianness()); +var type = os.type(); +var name = process.platform; +var architecture = process.arch; +var release = os.release(); /** * @fileOverview The **Server** class is a class that represents a single server topology and is @@ -40,7 +49,8 @@ var EventEmitter = require('events').EventEmitter , 'sslCA', 'sslCert', 'sslKey', 'sslPass', 'socketOptions', 'bufferMaxEntries' , 'store', 'auto_reconnect', 'autoReconnect', 'emitError' , 'keepAlive', 'noDelay', 'connectTimeoutMS', 'socketTimeoutMS' - , 'loggerLevel', 'logger', 'reconnectTries', 'reconnectInterval', 'monitoring']; + , 'loggerLevel', 'logger', 'reconnectTries', 'reconnectInterval', 'monitoring' + , 'appname', 'domainsEnabled']; /** * Creates a new Server instance @@ -67,6 +77,7 @@ var EventEmitter = require('events').EventEmitter * @param {number} [options.reconnectInterval=1000] Server will wait # milliseconds between retries * @param {number} [options.monitoring=true] Triggers the server instance to call ismaster * @param {number} [options.haInterval=10000] The interval of calling ismaster when monitoring is enabled. + * @param {boolean} [options.domainsEnabled=false] Enable the wrapping of the callback in the current domain, disabled by default to avoid perf hit. * @fires Server#connect * @fires Server#close * @fires Server#error @@ -130,6 +141,28 @@ var Server = function(host, port, options) { clonedOptions.keepAlive = clonedOptions.keepAlive > 0; } + // Build default client information + this.clientInfo = { + driver: { + name: "nodejs", + version: driverVersion + }, + os: { + type: type, + name: name, + architecture: architecture, + version: release + }, + platform: nodejsversion + } + + // Build default client information + clonedOptions.clientInfo = this.clientInfo; + // Do we have an application specific string + if(options.appname) { + clonedOptions.clientInfo.application = { name: options.appname }; + } + // Create an instance of a server instance from mongodb-core var server = new CServer(clonedOptions); // Server capabilities diff --git a/node_modules/mongodb/lib/topology_base.js b/node_modules/mongodb/lib/topology_base.js index cad8d85..2f5ac1f 100644 --- a/node_modules/mongodb/lib/topology_base.js +++ b/node_modules/mongodb/lib/topology_base.js @@ -113,6 +113,8 @@ var ServerCapabilities = function(ismaster) { var listCollections = false; var listIndexes = false; var maxNumberOfDocsInBatch = ismaster.maxWriteBatchSize || 1000; + var commandsTakeWriteConcern = false; + var commandsTakeCollation = false; if(ismaster.minWireVersion >= 0) { textSearch = true; @@ -132,6 +134,11 @@ var ServerCapabilities = function(ismaster) { listIndexes = true; } + if(ismaster.maxWireVersion >= 5) { + commandsTakeWriteConcern = true; + commandsTakeCollation = true; + } + // If no min or max wire version set to 0 if(ismaster.minWireVersion == null) { ismaster.minWireVersion = 0; @@ -151,6 +158,8 @@ var ServerCapabilities = function(ismaster) { setup_get_property(this, "minWireVersion", ismaster.minWireVersion); setup_get_property(this, "maxWireVersion", ismaster.maxWireVersion); setup_get_property(this, "maxNumberOfDocsInBatch", maxNumberOfDocsInBatch); + setup_get_property(this, "commandsTakeWriteConcern", commandsTakeWriteConcern); + setup_get_property(this, "commandsTakeCollation", commandsTakeCollation); } exports.Store = Store; diff --git a/node_modules/mongodb/lib/url_parser.js b/node_modules/mongodb/lib/url_parser.js index 0152612..663e5dc 100644 --- a/node_modules/mongodb/lib/url_parser.js +++ b/node_modules/mongodb/lib/url_parser.js @@ -223,6 +223,8 @@ module.exports = function(url, options) { serverOptions.poolSize = parseInt(value, 10); replSetServersOptions.poolSize = parseInt(value, 10); break; + case 'appname': + object.appname = decodeURIComponent(value); case 'autoReconnect': case 'auto_reconnect': serverOptions.auto_reconnect = (value == 'true'); @@ -353,6 +355,9 @@ module.exports = function(url, options) { if(!ReadPreference.isValid(value)) throw new Error("readPreference must be either primary/primaryPreferred/secondary/secondaryPreferred/nearest"); dbOptions.readPreference = value; break; + case 'maxStalenessMS': + dbOptions.maxStalenessMS = parseInt(value, 10); + break; case 'readPreferenceTags': // Decode the value value = decodeURIComponent(value); |
