Update Node_modules
This commit is contained in:
+121
@@ -0,0 +1,121 @@
|
||||
'use strict';
|
||||
|
||||
const AggregationCursor = require('../aggregation_cursor');
|
||||
const applyWriteConcern = require('../utils').applyWriteConcern;
|
||||
const decorateWithCollation = require('../utils').decorateWithCollation;
|
||||
const decorateWithReadConcern = require('../utils').decorateWithReadConcern;
|
||||
const handleCallback = require('../utils').handleCallback;
|
||||
const MongoError = require('mongodb-core').MongoError;
|
||||
const resolveReadPreference = require('../utils').resolveReadPreference;
|
||||
const toError = require('../utils').toError;
|
||||
|
||||
const DB_AGGREGATE_COLLECTION = 1;
|
||||
|
||||
/**
|
||||
* Perform an aggregate operation. See Collection.prototype.aggregate or Db.prototype.aggregate for more information.
|
||||
*
|
||||
* @method
|
||||
* @param {Db} db A Db instance.
|
||||
* @param {Collection|string} coll A collection instance or the string '1', used for db.aggregate.
|
||||
* @param {object} [pipeline=[]] Array containing all the aggregation framework commands for the execution.
|
||||
* @param {object} [options] Optional settings. See Collection.prototype.aggregate or Db.prototype.aggregate for a list of options.
|
||||
* @param {Db~aggregationCallback|Collection~aggregationCallback} callback The command result callback
|
||||
*/
|
||||
function aggregate(db, coll, pipeline, options, callback) {
|
||||
const isDbAggregate = typeof coll === 'string';
|
||||
const target = isDbAggregate ? db : coll;
|
||||
const topology = target.s.topology;
|
||||
let hasOutStage = false;
|
||||
|
||||
if (typeof options.out === 'string') {
|
||||
pipeline = pipeline.concat({ $out: options.out });
|
||||
hasOutStage = true;
|
||||
} else if (pipeline.length > 0 && pipeline[pipeline.length - 1]['$out']) {
|
||||
hasOutStage = true;
|
||||
}
|
||||
|
||||
let command;
|
||||
let namespace;
|
||||
let optionSources;
|
||||
|
||||
if (isDbAggregate) {
|
||||
command = { aggregate: DB_AGGREGATE_COLLECTION, pipeline: pipeline };
|
||||
namespace = `${db.s.databaseName}.${DB_AGGREGATE_COLLECTION}`;
|
||||
|
||||
optionSources = { db };
|
||||
} else {
|
||||
command = { aggregate: coll.s.name, pipeline: pipeline };
|
||||
namespace = coll.s.namespace;
|
||||
|
||||
optionSources = { db: coll.s.db, collection: coll };
|
||||
}
|
||||
|
||||
const takesWriteConcern = topology.capabilities().commandsTakeWriteConcern;
|
||||
|
||||
if (!hasOutStage) {
|
||||
decorateWithReadConcern(command, target, options);
|
||||
}
|
||||
|
||||
if (pipeline.length > 0 && pipeline[pipeline.length - 1]['$out'] && takesWriteConcern) {
|
||||
applyWriteConcern(command, optionSources, options);
|
||||
}
|
||||
|
||||
try {
|
||||
decorateWithCollation(command, target, options);
|
||||
} catch (err) {
|
||||
if (typeof callback === 'function') return callback(err, null);
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (options.bypassDocumentValidation === true) {
|
||||
command.bypassDocumentValidation = options.bypassDocumentValidation;
|
||||
}
|
||||
|
||||
if (typeof options.allowDiskUse === 'boolean') command.allowDiskUse = options.allowDiskUse;
|
||||
if (typeof options.maxTimeMS === 'number') command.maxTimeMS = options.maxTimeMS;
|
||||
|
||||
if (options.hint) command.hint = options.hint;
|
||||
|
||||
options = Object.assign({}, options);
|
||||
|
||||
// Ensure we have the right read preference inheritance
|
||||
options.readPreference = resolveReadPreference(options, optionSources);
|
||||
|
||||
if (options.explain) {
|
||||
if (command.readConcern || command.writeConcern) {
|
||||
throw toError('"explain" cannot be used on an aggregate call with readConcern/writeConcern');
|
||||
}
|
||||
command.explain = options.explain;
|
||||
}
|
||||
|
||||
if (typeof options.comment === 'string') command.comment = options.comment;
|
||||
|
||||
// Validate that cursor options is valid
|
||||
if (options.cursor != null && typeof options.cursor !== 'object') {
|
||||
throw toError('cursor options must be an object');
|
||||
}
|
||||
|
||||
options.cursor = options.cursor || {};
|
||||
if (options.batchSize && !hasOutStage) options.cursor.batchSize = options.batchSize;
|
||||
command.cursor = options.cursor;
|
||||
|
||||
// promiseLibrary
|
||||
options.promiseLibrary = target.s.promiseLibrary;
|
||||
|
||||
// Set the AggregationCursor constructor
|
||||
options.cursorFactory = AggregationCursor;
|
||||
|
||||
if (typeof callback !== 'function') {
|
||||
if (!topology.capabilities()) {
|
||||
throw new MongoError('cannot connect to server');
|
||||
}
|
||||
|
||||
return topology.cursor(namespace, command, options);
|
||||
}
|
||||
|
||||
return handleCallback(callback, null, topology.cursor(namespace, command, options));
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
aggregate
|
||||
};
|
||||
+71
-4
@@ -22,6 +22,21 @@ const MongoError = require('mongodb-core').MongoError;
|
||||
const ReadPreference = require('mongodb-core').ReadPreference;
|
||||
const toError = require('../utils').toError;
|
||||
|
||||
let collection;
|
||||
function loadCollection() {
|
||||
if (!collection) {
|
||||
collection = require('../collection');
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
let db;
|
||||
function loadDb() {
|
||||
if (!db) {
|
||||
db = require('../db');
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
/**
|
||||
* Group function helper
|
||||
* @ignore
|
||||
@@ -66,7 +81,7 @@ const groupFunction =
|
||||
* @param {Collection~bulkWriteOpCallback} [callback] The command result callback
|
||||
*/
|
||||
function bulkWrite(coll, operations, options, callback) {
|
||||
// Add ignoreUndfined
|
||||
// Add ignoreUndefined
|
||||
if (coll.s.options.ignoreUndefined) {
|
||||
options = Object.assign({}, options);
|
||||
options.ignoreUndefined = coll.s.options.ignoreUndefined;
|
||||
@@ -210,7 +225,7 @@ function countDocuments(coll, query, options, callback) {
|
||||
pipeline.push({ $limit: limit });
|
||||
}
|
||||
|
||||
pipeline.push({ $group: { _id: null, n: { $sum: 1 } } });
|
||||
pipeline.push({ $group: { _id: 1, n: { $sum: 1 } } });
|
||||
|
||||
delete options.limit;
|
||||
delete options.skip;
|
||||
@@ -877,6 +892,57 @@ function insertOne(coll, doc, options, callback) {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts an array of documents into MongoDB. If documents passed in do not contain the **_id** field,
|
||||
* one will be added to each of the documents missing it by the driver, mutating the document. This behavior
|
||||
* can be overridden by setting the **forceServerObjectId** flag.
|
||||
*
|
||||
* @method
|
||||
* @param {Collection} a Collection instance.
|
||||
* @param {object[]} docs Documents to insert.
|
||||
* @param {number} [options] Optional settings. See Collection.prototype.insertMany for a list of options.
|
||||
* @param {Collection~insertWriteOpCallback} [callback] The command result callback
|
||||
*/
|
||||
function insertMany(coll, docs, options, callback) {
|
||||
if (!Array.isArray(docs)) {
|
||||
return callback(
|
||||
MongoError.create({ message: 'docs parameter must be an array of documents', driver: true })
|
||||
);
|
||||
}
|
||||
|
||||
// If keep going set unordered
|
||||
options['serializeFunctions'] = options['serializeFunctions'] || coll.s.serializeFunctions;
|
||||
|
||||
docs = prepareDocs(coll, docs, options);
|
||||
|
||||
// Generate the bulk write operations
|
||||
const operations = [
|
||||
{
|
||||
insertMany: docs
|
||||
}
|
||||
];
|
||||
|
||||
bulkWrite(coll, operations, options, (err, result) => {
|
||||
if (err) return callback(err, null);
|
||||
callback(null, mapInsertManyResults(docs, result));
|
||||
});
|
||||
}
|
||||
|
||||
function mapInsertManyResults(docs, r) {
|
||||
const finalResult = {
|
||||
result: { ok: 1, n: r.insertedCount },
|
||||
ops: docs,
|
||||
insertedCount: r.insertedCount,
|
||||
insertedIds: r.insertedIds
|
||||
};
|
||||
|
||||
if (r.getLastOp()) {
|
||||
finalResult.result.opTime = r.getLastOp();
|
||||
}
|
||||
|
||||
return finalResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether the collection is a capped collection.
|
||||
*
|
||||
@@ -987,7 +1053,7 @@ function mapReduce(coll, map, reduce, options, callback) {
|
||||
if (result.result != null && typeof result.result === 'object') {
|
||||
const doc = result.result;
|
||||
// Return a collection from another db
|
||||
const Db = require('../db');
|
||||
let Db = loadDb();
|
||||
collection = new Db(doc.db, coll.s.db.s.topology, coll.s.db.s.options).collection(
|
||||
doc.collection
|
||||
);
|
||||
@@ -1204,7 +1270,7 @@ function removeDocuments(coll, selector, options, callback) {
|
||||
* @param {Collection~collectionResultCallback} [callback] The results callback
|
||||
*/
|
||||
function rename(coll, newName, options, callback) {
|
||||
const Collection = require('../collection');
|
||||
let Collection = loadCollection();
|
||||
// Check the collection name
|
||||
checkCollectionName(newName);
|
||||
// Build the command
|
||||
@@ -1461,6 +1527,7 @@ module.exports = {
|
||||
indexes,
|
||||
indexExists,
|
||||
indexInformation,
|
||||
insertMany,
|
||||
insertOne,
|
||||
isCapped,
|
||||
mapReduce,
|
||||
|
||||
+12
-4
@@ -6,6 +6,14 @@ const handleCallback = require('../utils').handleCallback;
|
||||
const MongoError = require('mongodb-core').MongoError;
|
||||
const push = Array.prototype.push;
|
||||
|
||||
let cursor;
|
||||
function loadCursor() {
|
||||
if (!cursor) {
|
||||
cursor = require('../cursor');
|
||||
}
|
||||
return cursor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the count of documents for this cursor.
|
||||
*
|
||||
@@ -74,7 +82,7 @@ function count(cursor, applySkipLimit, opts, callback) {
|
||||
* @param {Cursor~resultCallback} callback The result callback.
|
||||
*/
|
||||
function each(cursor, callback) {
|
||||
const Cursor = require('../cursor');
|
||||
let Cursor = loadCursor();
|
||||
|
||||
if (!callback) throw MongoError.create({ message: 'callback is mandatory', driver: true });
|
||||
if (cursor.isNotified()) return;
|
||||
@@ -114,7 +122,7 @@ function each(cursor, callback) {
|
||||
* @param {Cursor~resultCallback} [callback] The result callback.
|
||||
*/
|
||||
function hasNext(cursor, callback) {
|
||||
const Cursor = require('../cursor');
|
||||
let Cursor = loadCursor();
|
||||
|
||||
if (cursor.s.currentDoc) {
|
||||
return callback(null, true);
|
||||
@@ -165,7 +173,7 @@ function next(cursor, callback) {
|
||||
|
||||
// Get the next available document from the cursor, returns null if no more documents are available.
|
||||
function nextObject(cursor, callback) {
|
||||
const Cursor = require('../cursor');
|
||||
let Cursor = loadCursor();
|
||||
|
||||
if (cursor.s.state === Cursor.CLOSED || (cursor.isDead && cursor.isDead()))
|
||||
return handleCallback(
|
||||
@@ -196,7 +204,7 @@ function nextObject(cursor, callback) {
|
||||
* @param {Cursor~toArrayResultCallback} [callback] The result callback.
|
||||
*/
|
||||
function toArray(cursor, callback) {
|
||||
const Cursor = require('../cursor');
|
||||
let Cursor = loadCursor();
|
||||
|
||||
const items = [];
|
||||
|
||||
|
||||
+32
-12
@@ -17,6 +17,21 @@ const findOne = require('./collection_ops').findOne;
|
||||
const remove = require('./collection_ops').remove;
|
||||
const updateOne = require('./collection_ops').updateOne;
|
||||
|
||||
let collection;
|
||||
function loadCollection() {
|
||||
if (!collection) {
|
||||
collection = require('../collection');
|
||||
}
|
||||
return collection;
|
||||
}
|
||||
let db;
|
||||
function loadDb() {
|
||||
if (!db) {
|
||||
db = require('../db');
|
||||
}
|
||||
return db;
|
||||
}
|
||||
|
||||
const debugFields = [
|
||||
'authSource',
|
||||
'w',
|
||||
@@ -64,7 +79,7 @@ const illegalCommandFields = [
|
||||
* @param {Db~resultCallback} [callback] The command result callback
|
||||
*/
|
||||
function addUser(db, username, password, options, callback) {
|
||||
const Db = require('../db');
|
||||
let Db = loadDb();
|
||||
|
||||
// Did the user destroy the topology
|
||||
if (db.serverConfig && db.serverConfig.isDestroyed())
|
||||
@@ -82,10 +97,10 @@ function addUser(db, username, password, options, callback) {
|
||||
const userPassword = md5.digest('hex');
|
||||
|
||||
// If we have another db set
|
||||
const db = options.dbName ? new Db(options.dbName, db.s.topology, db.s.options) : db;
|
||||
const dbToUse = options.dbName ? new Db(options.dbName, db.s.topology, db.s.options) : db;
|
||||
|
||||
// Fetch a user collection
|
||||
const collection = db.collection(CONSTANTS.SYSTEM_USER_COLLECTION);
|
||||
const collection = dbToUse.collection(CONSTANTS.SYSTEM_USER_COLLECTION);
|
||||
|
||||
// Check if we are inserting the first user
|
||||
count(collection, {}, finalOptions, (err, count) => {
|
||||
@@ -132,7 +147,7 @@ function addUser(db, username, password, options, callback) {
|
||||
* @param {Db~collectionsResultCallback} [callback] The results callback
|
||||
*/
|
||||
function collections(db, options, callback) {
|
||||
const Collection = require('../collection');
|
||||
let Collection = loadCollection();
|
||||
|
||||
options = Object.assign({}, options, { nameOnly: true });
|
||||
// Let's get the collection names
|
||||
@@ -172,7 +187,7 @@ function collections(db, options, callback) {
|
||||
* @param {Db~collectionResultCallback} [callback] The results callback
|
||||
*/
|
||||
function createCollection(db, name, options, callback) {
|
||||
const Collection = require('../collection');
|
||||
let Collection = loadCollection();
|
||||
|
||||
// Get the write concern options
|
||||
const finalOptions = applyWriteConcern(Object.assign({}, options), { db }, options);
|
||||
@@ -233,11 +248,16 @@ function createCollection(db, name, options, callback) {
|
||||
// Execute command
|
||||
executeCommand(db, cmd, finalOptions, err => {
|
||||
if (err) return handleCallback(callback, err);
|
||||
handleCallback(
|
||||
callback,
|
||||
null,
|
||||
new Collection(db, db.s.topology, db.s.databaseName, name, db.s.pkFactory, options)
|
||||
);
|
||||
|
||||
try {
|
||||
return handleCallback(
|
||||
callback,
|
||||
null,
|
||||
new Collection(db, db.s.topology, db.s.databaseName, name, db.s.pkFactory, options)
|
||||
);
|
||||
} catch (err) {
|
||||
return handleCallback(callback, err);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -581,7 +601,7 @@ function listCollectionsTransforms(databaseName) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrive the current profiling information for MongoDB
|
||||
* Retrieve the current profiling information for MongoDB
|
||||
*
|
||||
* @method
|
||||
* @param {Db} db The Db instance on which to retrieve the profiling info.
|
||||
@@ -632,7 +652,7 @@ function profilingLevel(db, options, callback) {
|
||||
* @param {Db~resultCallback} [callback] The command result callback
|
||||
*/
|
||||
function removeUser(db, username, options, callback) {
|
||||
const Db = require('../db');
|
||||
let Db = loadDb();
|
||||
|
||||
// Attempt to execute command
|
||||
executeAuthRemoveUserCommand(db, username, options, (err, result) => {
|
||||
|
||||
+152
-110
@@ -1,6 +1,5 @@
|
||||
'use strict';
|
||||
|
||||
const authenticate = require('../authenticate');
|
||||
const deprecate = require('util').deprecate;
|
||||
const Logger = require('mongodb-core').Logger;
|
||||
const MongoError = require('mongodb-core').MongoError;
|
||||
@@ -10,6 +9,16 @@ const ReadPreference = require('mongodb-core').ReadPreference;
|
||||
const ReplSet = require('../topologies/replset');
|
||||
const Server = require('../topologies/server');
|
||||
const ServerSessionPool = require('mongodb-core').Sessions.ServerSessionPool;
|
||||
const NativeTopology = require('../topologies/native_topology');
|
||||
const MongoCredentials = require('mongodb-core').MongoCredentials;
|
||||
|
||||
let client;
|
||||
function loadClient() {
|
||||
if (!client) {
|
||||
client = require('../mongo_client');
|
||||
}
|
||||
return client;
|
||||
}
|
||||
|
||||
const monitoringEvents = [
|
||||
'timeout',
|
||||
@@ -100,7 +109,10 @@ const validOptionNames = [
|
||||
'minSize',
|
||||
'monitorCommands',
|
||||
'retryWrites',
|
||||
'useNewUrlParser'
|
||||
'useNewUrlParser',
|
||||
'useUnifiedTopology',
|
||||
'serverSelectionTimeoutMS',
|
||||
'useRecoveryToken'
|
||||
];
|
||||
|
||||
function addListeners(mongoClient, topology) {
|
||||
@@ -117,7 +129,10 @@ function addListeners(mongoClient, topology) {
|
||||
|
||||
function assignTopology(client, topology) {
|
||||
client.topology = topology;
|
||||
topology.s.sessionPool = new ServerSessionPool(topology.s.coreTopology);
|
||||
topology.s.sessionPool =
|
||||
topology instanceof NativeTopology
|
||||
? new ServerSessionPool(topology)
|
||||
: new ServerSessionPool(topology.s.coreTopology);
|
||||
}
|
||||
|
||||
// Clear out all events
|
||||
@@ -127,7 +142,7 @@ function clearAllEvents(topology) {
|
||||
|
||||
// Collect all events in order from SDAM
|
||||
function collectEvents(mongoClient, topology) {
|
||||
const MongoClient = require('../mongo_client');
|
||||
let MongoClient = loadClient();
|
||||
const collectedEvents = [];
|
||||
|
||||
if (mongoClient instanceof MongoClient) {
|
||||
@@ -166,7 +181,7 @@ function connect(mongoClient, url, options, callback) {
|
||||
throw new Error('no callback function provided');
|
||||
}
|
||||
|
||||
// Get a logger for MongoClient
|
||||
let didRequestAuthentication = false;
|
||||
const logger = Logger('MongoClient', options);
|
||||
|
||||
// Did we pass in a Server/ReplSet/Mongos
|
||||
@@ -203,29 +218,34 @@ function connect(mongoClient, url, options, callback) {
|
||||
return callback(new Error('connection string must contain at least one seed host'));
|
||||
}
|
||||
|
||||
if (_finalOptions.auth && !_finalOptions.credentials) {
|
||||
try {
|
||||
didRequestAuthentication = true;
|
||||
_finalOptions.credentials = generateCredentials(
|
||||
mongoClient,
|
||||
_finalOptions.auth.user,
|
||||
_finalOptions.auth.password,
|
||||
_finalOptions
|
||||
);
|
||||
} catch (err) {
|
||||
return callback(err);
|
||||
}
|
||||
}
|
||||
|
||||
if (_finalOptions.useUnifiedTopology) {
|
||||
return createTopology(mongoClient, 'unified', _finalOptions, connectCallback);
|
||||
}
|
||||
|
||||
// Do we have a replicaset then skip discovery and go straight to connectivity
|
||||
if (_finalOptions.replicaSet || _finalOptions.rs_name) {
|
||||
return createTopology(
|
||||
mongoClient,
|
||||
'replicaset',
|
||||
_finalOptions,
|
||||
connectHandler(mongoClient, _finalOptions, connectCallback)
|
||||
);
|
||||
return createTopology(mongoClient, 'replicaset', _finalOptions, connectCallback);
|
||||
} else if (object.servers.length > 1) {
|
||||
return createTopology(
|
||||
mongoClient,
|
||||
'mongos',
|
||||
_finalOptions,
|
||||
connectHandler(mongoClient, _finalOptions, connectCallback)
|
||||
);
|
||||
return createTopology(mongoClient, 'mongos', _finalOptions, connectCallback);
|
||||
} else {
|
||||
return createServer(
|
||||
mongoClient,
|
||||
_finalOptions,
|
||||
connectHandler(mongoClient, _finalOptions, connectCallback)
|
||||
);
|
||||
return createServer(mongoClient, _finalOptions, connectCallback);
|
||||
}
|
||||
});
|
||||
|
||||
function connectCallback(err, topology) {
|
||||
const warningMessage = `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`;
|
||||
if (err && err.message === 'no mongos proxies found in seed list') {
|
||||
@@ -237,35 +257,15 @@ function connect(mongoClient, url, options, callback) {
|
||||
return callback(new MongoError(warningMessage));
|
||||
}
|
||||
|
||||
if (didRequestAuthentication) {
|
||||
mongoClient.emit('authenticated', null, true);
|
||||
}
|
||||
|
||||
// Return the error and db instance
|
||||
callback(err, topology);
|
||||
}
|
||||
}
|
||||
|
||||
function connectHandler(client, options, callback) {
|
||||
return (err, topology) => {
|
||||
if (err) {
|
||||
return handleConnectCallback(err, topology, callback);
|
||||
}
|
||||
|
||||
// No authentication just reconnect
|
||||
if (!options.auth) {
|
||||
return handleConnectCallback(err, topology, callback);
|
||||
}
|
||||
|
||||
// Authenticate
|
||||
authenticate(client, options.user, options.password, options, (err, success) => {
|
||||
if (success) {
|
||||
handleConnectCallback(null, topology, callback);
|
||||
} else {
|
||||
if (topology) topology.close();
|
||||
const authError = err ? err : new Error('Could not authenticate user ' + options.auth[0]);
|
||||
handleConnectCallback(authError, topology, callback);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to MongoDB using a url as documented at
|
||||
*
|
||||
@@ -306,27 +306,21 @@ function connectWithUrl(mongoClient, url, options, connectCallback) {
|
||||
);
|
||||
}
|
||||
|
||||
// Connect
|
||||
return url.connect(
|
||||
finalOptions,
|
||||
connectHandler(mongoClient, finalOptions, (err, topology) => {
|
||||
if (err) return connectCallback(err, topology);
|
||||
if (finalOptions.user || finalOptions.password || finalOptions.authMechanism) {
|
||||
return authenticate(
|
||||
mongoClient,
|
||||
finalOptions.user,
|
||||
finalOptions.password,
|
||||
finalOptions,
|
||||
err => {
|
||||
if (err) return connectCallback(err, topology);
|
||||
connectCallback(err, topology);
|
||||
}
|
||||
);
|
||||
}
|
||||
const isDoingAuth = finalOptions.user || finalOptions.password || finalOptions.authMechanism;
|
||||
if (isDoingAuth && !finalOptions.credentials) {
|
||||
try {
|
||||
finalOptions.credentials = generateCredentials(
|
||||
mongoClient,
|
||||
finalOptions.user,
|
||||
finalOptions.password,
|
||||
finalOptions
|
||||
);
|
||||
} catch (err) {
|
||||
return connectCallback(err, url);
|
||||
}
|
||||
}
|
||||
|
||||
connectCallback(err, topology);
|
||||
})
|
||||
);
|
||||
return url.connect(finalOptions, connectCallback);
|
||||
}
|
||||
|
||||
function createListener(mongoClient, event) {
|
||||
@@ -402,6 +396,8 @@ function createTopology(mongoClient, topologyType, options, callback) {
|
||||
topology = new Mongos(servers, options);
|
||||
} else if (topologyType === 'replicaset') {
|
||||
topology = new ReplSet(servers, options);
|
||||
} else if (topologyType === 'unified') {
|
||||
topology = new NativeTopology(options.servers, options);
|
||||
}
|
||||
|
||||
// Add listeners
|
||||
@@ -457,36 +453,10 @@ function createUnifiedOptions(finalOptions, options) {
|
||||
return finalOptions;
|
||||
}
|
||||
|
||||
function handleConnectCallback(err, topology, callback) {
|
||||
return process.nextTick(() => {
|
||||
try {
|
||||
callback(err, topology);
|
||||
} catch (err) {
|
||||
if (topology) topology.close();
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function legacyTransformUrlOptions(object) {
|
||||
return mergeOptions(createUnifiedOptions({}, object), object, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout user from server, fire off on all connections and remove all auth info.
|
||||
*
|
||||
* @method
|
||||
* @param {MongoClient} mongoClient The MongoClient instance on which to logout.
|
||||
* @param {object} [options] Optional settings. See MongoClient.prototype.logout for a list of options.
|
||||
* @param {Db~resultCallback} [callback] The command result callback
|
||||
*/
|
||||
function logout(mongoClient, dbName, callback) {
|
||||
mongoClient.topology.logout(dbName, err => {
|
||||
if (err) return callback(err);
|
||||
callback(null, true);
|
||||
});
|
||||
}
|
||||
|
||||
function mergeOptions(target, source, flatten) {
|
||||
for (const name in source) {
|
||||
if (source[name] && typeof source[name] === 'object' && flatten) {
|
||||
@@ -548,21 +518,17 @@ function transformUrlOptions(_object) {
|
||||
object[camelCaseName] = object[name];
|
||||
}
|
||||
}
|
||||
if (_object.auth) {
|
||||
const auth = _object.auth;
|
||||
for (let i in auth) {
|
||||
if (auth[i]) {
|
||||
object[i] = auth[i];
|
||||
}
|
||||
|
||||
const hasUsername = _object.auth && _object.auth.username;
|
||||
const hasAuthMechanism = _object.options && _object.options.authMechanism;
|
||||
if (hasUsername || hasAuthMechanism) {
|
||||
object.auth = Object.assign({}, _object.auth);
|
||||
if (object.auth.db) {
|
||||
object.authSource = object.authSource || object.auth.db;
|
||||
}
|
||||
|
||||
if (auth.username) {
|
||||
object.auth = auth;
|
||||
object.user = auth.username;
|
||||
}
|
||||
|
||||
if (auth.db) {
|
||||
object.authSource = object.authSource || auth.db;
|
||||
if (object.auth.username) {
|
||||
object.auth.user = object.auth.username;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -628,10 +594,12 @@ function validOptions(options) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (_validOptions.indexOf(name) === -1 && options.validateOptions) {
|
||||
return new MongoError(`option ${name} is not supported`);
|
||||
} else if (_validOptions.indexOf(name) === -1) {
|
||||
console.warn(`the options [${name}] is not supported`);
|
||||
if (_validOptions.indexOf(name) === -1) {
|
||||
if (options.validateOptions) {
|
||||
return new MongoError(`option ${name} is not supported`);
|
||||
} else {
|
||||
console.warn(`the options [${name}] is not supported`);
|
||||
}
|
||||
}
|
||||
|
||||
if (legacyOptionNames.indexOf(name) !== -1) {
|
||||
@@ -643,4 +611,78 @@ function validOptions(options) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { connectOp, logout, validOptions };
|
||||
const VALID_AUTH_MECHANISMS = new Set([
|
||||
'DEFAULT',
|
||||
'MONGODB-CR',
|
||||
'PLAIN',
|
||||
'MONGODB-X509',
|
||||
'SCRAM-SHA-1',
|
||||
'SCRAM-SHA-256',
|
||||
'GSSAPI'
|
||||
]);
|
||||
|
||||
const AUTH_MECHANISM_INTERNAL_MAP = {
|
||||
DEFAULT: 'default',
|
||||
'MONGODB-CR': 'mongocr',
|
||||
PLAIN: 'plain',
|
||||
'MONGODB-X509': 'x509',
|
||||
'SCRAM-SHA-1': 'scram-sha-1',
|
||||
'SCRAM-SHA-256': 'scram-sha-256'
|
||||
};
|
||||
|
||||
function generateCredentials(client, username, password, options) {
|
||||
options = Object.assign({}, options);
|
||||
|
||||
// the default db to authenticate against is 'self'
|
||||
// if authenticate is called from a retry context, it may be another one, like admin
|
||||
const source = options.authSource || options.authdb || options.dbName;
|
||||
|
||||
// authMechanism
|
||||
const authMechanismRaw = options.authMechanism || 'DEFAULT';
|
||||
const authMechanism = authMechanismRaw.toUpperCase();
|
||||
|
||||
if (!VALID_AUTH_MECHANISMS.has(authMechanism)) {
|
||||
throw MongoError.create({
|
||||
message: `authentication mechanism ${authMechanismRaw} not supported', options.authMechanism`,
|
||||
driver: true
|
||||
});
|
||||
}
|
||||
|
||||
if (authMechanism === 'GSSAPI') {
|
||||
return new MongoCredentials({
|
||||
mechanism: process.platform === 'win32' ? 'sspi' : 'gssapi',
|
||||
mechanismProperties: options,
|
||||
source,
|
||||
username,
|
||||
password
|
||||
});
|
||||
}
|
||||
|
||||
return new MongoCredentials({
|
||||
mechanism: AUTH_MECHANISM_INTERNAL_MAP[authMechanism],
|
||||
source,
|
||||
username,
|
||||
password
|
||||
});
|
||||
}
|
||||
|
||||
function closeOperation(client, force, callback) {
|
||||
const completeClose = err => {
|
||||
client.emit('close', client);
|
||||
for (const name in client.s.dbCache) {
|
||||
client.s.dbCache[name].emit('close', client);
|
||||
}
|
||||
|
||||
client.removeAllListeners('close');
|
||||
callback(err, null);
|
||||
};
|
||||
|
||||
if (client.topology == null) {
|
||||
completeClose();
|
||||
return;
|
||||
}
|
||||
|
||||
client.topology.close(force, completeClose);
|
||||
}
|
||||
|
||||
module.exports = { connectOp, validOptions, closeOperation };
|
||||
|
||||
Reference in New Issue
Block a user