123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 |
- "use strict";
- var parse = require('./url_parser')
- , Server = require('./server')
- , Mongos = require('./mongos')
- , ReplSet = require('./replset')
- , Define = require('./metadata')
- , ReadPreference = require('./read_preference')
- , Logger = require('mongodb-core').Logger
- , MongoError = require('mongodb-core').MongoError
- , Db = require('./db')
- , f = require('util').format
- , shallowClone = require('./utils').shallowClone;
- function MongoClient() {
-
-
- this.connect = MongoClient.connect;
- }
- var define = MongoClient.define = new Define('MongoClient', MongoClient, false);
- MongoClient.connect = function(url, options, callback) {
- var args = Array.prototype.slice.call(arguments, 1);
- callback = typeof args[args.length - 1] == 'function' ? args.pop() : null;
- options = args.length ? args.shift() : null;
- options = options || {};
-
- var promiseLibrary = options.promiseLibrary;
-
- if(!promiseLibrary) {
- promiseLibrary = typeof global.Promise == 'function' ?
- global.Promise : require('es6-promise').Promise;
- }
-
- if(typeof callback != 'function') {
- return new promiseLibrary(function(resolve, reject) {
- connect(url, options, function(err, db) {
- if(err) return reject(err);
- resolve(db);
- });
- });
- }
-
- connect(url, options, callback);
- }
- define.staticMethod('connect', {callback: true, promise:true});
- var mergeOptions = function(target, source, flatten) {
- for(var name in source) {
- if(source[name] && typeof source[name] == 'object' && flatten) {
- target = mergeOptions(target, source[name], flatten);
- } else {
- target[name] = source[name];
- }
- }
- return target;
- }
- var createUnifiedOptions = function(finalOptions, options) {
- var childOptions = ['mongos', 'server', 'db'
- , 'replset', 'db_options', 'server_options', 'rs_options', 'mongos_options'];
- var noMerge = [];
- for(var name in options) {
- 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])) {
- finalOptions = mergeOptions(finalOptions, options[name], true);
- } else {
- finalOptions[name] = options[name];
- }
- }
- }
- return finalOptions;
- }
- function translateOptions(options) {
-
- if(typeof options.readPreference == 'string' || typeof options.read_preference == 'string') {
- options.readPreference = new ReadPreference(options.readPreference || options.read_preference);
- }
-
- if(options.readPreference && (options.readPreferenceTags || options.read_preference_tags)) {
- options.readPreference.tags = options.readPreferenceTags || options.read_preference_tags;
- }
-
- if(options.maxStalenessSeconds) {
- options.readPreference.maxStalenessSeconds = options.maxStalenessSeconds;
- }
-
- if(options.socketTimeoutMS == null) options.socketTimeoutMS = 30000;
- if(options.connectTimeoutMS == null) options.connectTimeoutMS = 30000;
-
- return options.servers.map(function(serverObj) {
- return serverObj.domain_socket ?
- new Server(serverObj.domain_socket, 27017, options)
- : new Server(serverObj.host, serverObj.port, options);
- });
- }
- function createReplicaset(options, callback) {
-
- var servers = translateOptions(options);
-
- new Db(options.dbName, new ReplSet(servers, options), options).open(callback);
- }
- function createMongos(options, callback) {
-
- var servers = translateOptions(options);
-
- new Db(options.dbName, new Mongos(servers, options), options).open(callback);
- }
- function createServer(options, callback) {
-
- var servers = translateOptions(options);
-
- new Db(options.dbName, servers[0], options).open(function(err, db) {
- if(err) return callback(err);
-
- var ismaster = db.serverConfig.lastIsMaster();
-
- if(ismaster && ismaster.msg == 'isdbgrid') {
-
- db.close();
-
- return createMongos(options, callback);
- }
-
- callback(err, db);
- });
- }
- function connectHandler(options, callback) {
- return function (err, db) {
- if(err) {
- return process.nextTick(function() {
- try {
- callback(err, null);
- } catch (err) {
- if(db) db.close();
- throw err
- }
- });
- }
-
- if(!options.auth) {
- return process.nextTick(function() {
- try {
- callback(err, db);
- } catch (err) {
- if(db) db.close();
- throw err
- }
- })
- }
-
- var authentication_db = db;
- if(options.authSource) {
- authentication_db = db.db(options.authSource);
- }
-
- authentication_db.authenticate(options.user, options.password, options, function(err, success){
- if(success){
- process.nextTick(function() {
- try {
- callback(null, db);
- } catch (err) {
- if(db) db.close();
- throw err
- }
- });
- } else {
- if(db) db.close();
- process.nextTick(function() {
- try {
- callback(err ? err : new Error('Could not authenticate user ' + options.auth[0]), null);
- } catch (err) {
- if(db) db.close();
- throw err
- }
- });
- }
- });
- }
- }
- var connect = function(url, options, callback) {
- options = options || {};
- options = shallowClone(options);
-
- if(callback == null) {
- throw new Error("no callback function provided");
- }
-
- var logger = Logger('MongoClient', options);
-
- var object = parse(url, options);
- var _finalOptions = createUnifiedOptions({}, object);
- _finalOptions = mergeOptions(_finalOptions, object, false);
- _finalOptions = createUnifiedOptions(_finalOptions, options);
-
- if(_finalOptions.socketTimeoutMS == null) _finalOptions.socketTimeoutMS = 30000;
- if(_finalOptions.connectTimeoutMS == null) _finalOptions.connectTimeoutMS = 30000;
-
- 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 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'));
- }
-
- callback(err, db);
- }
-
- if(_finalOptions.replicaSet || _finalOptions.rs_name) {
- return createReplicaset(_finalOptions, connectHandler(_finalOptions, connectCallback));
- } else if(object.servers.length > 1) {
- return createMongos(_finalOptions, connectHandler(_finalOptions, connectCallback));
- } else {
- return createServer(_finalOptions, connectHandler(_finalOptions, connectCallback));
- }
- }
- module.exports = MongoClient
|