Socket
Socket
Sign inDemoInstall

mongodb

Package Overview
Dependencies
Maintainers
1
Versions
562
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mongodb - npm Package Compare versions

Comparing version 1.1.11 to 1.2.0

lib/mongodb/connection/base.js

34

lib/mongodb/admin.js

@@ -24,3 +24,3 @@ /*!

*
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from buildInfo or null if an error occured.
* @return {null} Returns no result

@@ -37,3 +37,3 @@ * @api public

*
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverInfo or null if an error occured.
* @return {null} Returns no result

@@ -52,3 +52,3 @@ * @api private

*
* @param {Function} callback returns the server status.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from serverStatus or null if an error occured.
* @return {null}

@@ -73,3 +73,3 @@ * @api public

*
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingLevel or null if an error occured.
* @return {null} Returns no result

@@ -99,3 +99,3 @@ * @api public

*
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from ping or null if an error occured.
* @return {null} Returns no result

@@ -117,3 +117,3 @@ * @api public

* @param {String} password The password for the authentication.
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from authenticate or null if an error occured.
* @return {null} Returns no result

@@ -132,3 +132,3 @@ * @api public

* @param {Object} [options] Optional parameters to the command.
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from logout or null if an error occured.
* @return {null} Returns no result

@@ -153,3 +153,3 @@ * @api public

* @param {Object} [options] additional options during update.
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from addUser or null if an error occured.
* @return {null} Returns no result

@@ -178,3 +178,3 @@ * @api public

* @param {Object} [options] additional options during update.
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from removeUser or null if an error occured.
* @return {null} Returns no result

@@ -199,3 +199,3 @@ * @api public

* @param {String} level The new profiling level (off, slow_only, all)
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from setProfilingLevel or null if an error occured.
* @return {null} Returns no result

@@ -234,3 +234,3 @@ * @api public

*
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from profilingInfo or null if an error occured.
* @return {null} Returns no result

@@ -241,5 +241,3 @@ * @api public

try {
new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, null, null, null
, null, null, null, null, null, null, null, null, null, null
, null, null, null, null, null, null, null, null, 'admin').toArray(function(err, items) {
new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, {}, {dbName: 'admin'}).toArray(function(err, items) {
return callback(err, items);

@@ -257,3 +255,3 @@ });

* @param {Object} [options] Optional parameters to the command.
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The command always return the whole result of the command as the second parameter.
* @return {null} Returns no result

@@ -280,3 +278,3 @@ * @api public

* @param {Object} [options] Optional parameters to the command.
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from validateCollection or null if an error occured.
* @return {null} Returns no result

@@ -321,3 +319,3 @@ * @api public

*
* @param {Function} callback Callback function of format `function(err, result) {}`.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from listDatabases or null if an error occured.
* @return {null} Returns no result

@@ -337,3 +335,3 @@ * @api public

*
* @param {Function} callback returns the replica set status (if available).
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the results from replSetGetStatus or null if an error occured.
* @return {null}

@@ -340,0 +338,0 @@ * @api public

var QueryCommand = require('./query_command').QueryCommand,
InsertCommand = require('./insert_command').InsertCommand,
inherits = require('util').inherits,
utils = require('../utils'),
crypto = require('crypto');

@@ -110,2 +111,7 @@

// Special case for w == 1, remove the w
if(1 == command.w) {
delete command.w;
}
// Execute command

@@ -131,14 +137,20 @@ return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command, null);

// Get all the fields accordingly
if (fieldOrSpec.constructor === String) { // 'type'
if('string' == typeof fieldOrSpec) {
// 'type'
indexes.push(fieldOrSpec + '_' + 1);
fieldHash[fieldOrSpec] = 1;
} else if (fieldOrSpec.constructor === Array) { // [{location:'2d'}, ...]
} else if(utils.isArray(fieldOrSpec)) {
fieldOrSpec.forEach(function(f) {
if (f.constructor === String) { // [{location:'2d'}, 'type']
if('string' == typeof f) {
// [{location:'2d'}, 'type']
indexes.push(f + '_' + 1);
fieldHash[f] = 1;
} else if (f.constructor === Array) { // [['location', '2d'],['type', 1]]
} else if(utils.isArray(f)) {
// [['location', '2d'],['type', 1]]
indexes.push(f[0] + '_' + (f[1] || 1));
fieldHash[f[0]] = f[1] || 1;
} else if (f.constructor === Object) { // [{location:'2d'}, {type:1}]
} else if(utils.isObject(f)) {
// [{location:'2d'}, {type:1}]
keys = Object.keys(f);

@@ -148,8 +160,10 @@ keys.forEach(function(k) {

fieldHash[k] = f[k];
});
});
} else {
// undefined
// undefined (ignore)
}
});
} else if (fieldOrSpec.constructor === Object) { // {location:'2d', type:1}
} else if(utils.isObject(fieldOrSpec)) {
// {location:'2d', type:1}
keys = Object.keys(fieldOrSpec);

@@ -163,14 +177,24 @@ keys.forEach(function(key) {

// Generate the index name
var indexName = typeof options.name == 'string' ? options.name : indexes.join("_");
// Build the selector
var selector = {'ns':(db.databaseName + "." + collectionName), 'key':fieldHash, 'name':indexName};
var indexName = typeof options.name == 'string'
? options.name
: indexes.join("_");
var selector = {
'ns': db.databaseName + "." + collectionName,
'key': fieldHash,
'name': indexName
}
// Ensure we have a correct finalUnique
var finalUnique = options == null || 'object' === typeof options ? false : options;
var finalUnique = options == null || 'object' === typeof options
? false
: options;
// Set up options
options = options == null || typeof options == 'boolean' ? {} : options;
options = options == null || typeof options == 'boolean'
? {}
: options;
// Add all the options
var keys = Object.keys(options);
// Add all the fields to the selector
for(var i = 0; i < keys.length; i++) {

@@ -180,6 +204,8 @@ selector[keys[i]] = options[keys[i]];

// If we don't have the unique property set on the selector
if(selector['unique'] == null) selector['unique'] = finalUnique;
// Create the insert command for the index and return the document
return new InsertCommand(db, db.databaseName + "." + DbCommand.SYSTEM_INDEX_COLLECTION, false).add(selector);
if(selector['unique'] == null)
selector['unique'] = finalUnique;
var name = db.databaseName + "." + DbCommand.SYSTEM_INDEX_COLLECTION;
var cmd = new InsertCommand(db, name, false);
return cmd.add(selector);
};

@@ -219,2 +245,2 @@

return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null, options);
};
};

@@ -142,3 +142,3 @@ var utils = require('./connection_utils'),

if(this.logger != null && this.logger.doDebug)
this.logger.debug("writing command to mongodb", binaryCommand);
this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command[i]});

@@ -153,3 +153,3 @@ var r = this.writeSteam.write(binaryCommand);

if(this.logger != null && this.logger.doDebug)
this.logger.debug("writing command to mongodb", binaryCommand);
this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command});

@@ -156,0 +156,0 @@ var r = this.writeSteam.write(binaryCommand);

@@ -1,2 +0,4 @@

var ReadPreference = require('./read_preference').ReadPreference;
var ReadPreference = require('./read_preference').ReadPreference
, Base = require('./base').Base
, inherits = require('util').inherits;

@@ -20,2 +22,5 @@ /**

// Set up event emitter
Base.call(this);
// Throw error on wrong setup

@@ -59,2 +64,7 @@ if(servers == null || !Array.isArray(servers) || servers.length == 0)

*/
inherits(Mongos, Base);
/**
* @ignore
*/
Mongos.prototype.isMongos = function() {

@@ -221,2 +231,3 @@ return true;

server.on("close", errorOrCloseHandler(server));
server.on("timeout", errorOrCloseHandler(server));
server.on("error", errorOrCloseHandler(server));

@@ -237,4 +248,10 @@ // Connect the instance

/**
* Always ourselves
* @ignore
*/
Mongos.prototype.setReadPreference = function() {}
/**
* @ignore
*/
Mongos.prototype.allRawConnections = function() {

@@ -245,3 +262,3 @@ // Neeed to build a complete list of all raw connections, start with master server

for(var i = 0; i < this.servers.length; i++) {
allConnections = allConnections.concat(this.servers[i].allRawConnections)
allConnections = allConnections.concat(this.servers[i].allRawConnections());
}

@@ -248,0 +265,0 @@

@@ -1,2 +0,2 @@

var Connection = require('./connection').Connection,
var Connection = require('./connection').Connection,
ReadPreference = require('./read_preference').ReadPreference,

@@ -6,3 +6,2 @@ DbCommand = require('../commands/db_command').DbCommand,

debug = require('util').debug,
EventEmitter = require('events').EventEmitter,
inherits = require('util').inherits,

@@ -12,3 +11,4 @@ inspect = require('util').inspect,

PingStrategy = require('./strategies/ping_strategy').PingStrategy,
StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy;
StatisticsStrategy = require('./strategies/statistics_strategy').StatisticsStrategy,
Base = require('./base').Base;

@@ -40,2 +40,3 @@ const STATE_STARTING_PHASE_1 = 0;

* - **connectArbiter** {Boolean, default:false}, sets if the driver should connect to arbiters or not.
* - **logger** {Object, default:null}, an object representing a logger that you want to use, needs to support functions debug, log, error **({error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}})**.
*

@@ -54,3 +55,3 @@ * @class Represents a Replicaset Configuration

// Set up event emitter
EventEmitter.call(this);
Base.call(this);

@@ -96,2 +97,4 @@ // Ensure no Mongos's

this.recordQueryStats = false;
// Update health try server
this.updateHealthServerTry = 0;

@@ -114,2 +117,8 @@ // Get the readPreference

// Ensure read_secondary is set correctly
if(!this.readSecondary)
this.readSecondary = this._readPreference == ReadPreference.PRIMARY
|| this._readPreference == false
|| this._readPreference == null ? false : true;
// Strategy for picking a secondary

@@ -124,3 +133,2 @@ this.secondaryAcceptableLatencyMS = this.options['secondaryAcceptableLatencyMS'] == null ? 15 : this.options['secondaryAcceptableLatencyMS'];

this.strategyInstance = new PingStrategy(this, this.secondaryAcceptableLatencyMS);
this.strategyInstance.start();
} else if(this.strategy == 'statistical') {

@@ -184,4 +192,8 @@ // Set strategy as statistical

this._replicasetTimeoutId = null;
// Connection timeout
this._connectTimeoutMS = 1000;
this._connectTimeoutMS = this.socketOptions.connectTimeoutMS
? this.socketOptions.connectTimeoutMS
: 1000;
// Current list of servers to test

@@ -197,3 +209,3 @@ this.pingCandidateServers = [];

*/
inherits(ReplSet, EventEmitter);
inherits(ReplSet, Base);

@@ -256,19 +268,7 @@ /**

* @ignore
**/
ReplSet.prototype._checkReplicaSet = function() {
if(!this.haEnabled) return false;
var currentTime = new Date().getTime();
if((currentTime - this.lastReplicaSetTime) >= this.replicasetStatusCheckInterval) {
this.lastReplicaSetTime = currentTime;
return true;
} else {
return false;
}
}
/**
* @ignore
*/
ReplSet.prototype.allServerInstances = function() {
var self = this;
// If no state yet return empty
if(!self._state) return [];
// Close all the servers (concatenate entire list of servers first for ease)

@@ -303,13 +303,58 @@ var allServers = self._state.master != null ? [self._state.master] : [];

/**
* Enables high availability pings.
*
* @ignore
*/
var __executeAllCallbacksWithError = function(dbInstance, error) {
var keys = Object.keys(dbInstance._callBackStore._notReplied);
// Iterate over all callbacks
for(var i = 0; i < keys.length; i++) {
// Delete info object
delete dbInstance._callBackStore._notReplied[keys[i]];
// Emit the error
dbInstance._callBackStore.emit(keys[i], error);
ReplSet.prototype._enableHA = function () {
var self = this;
return check();
function ping () {
if("disconnected" == self._serverState) return;
if(Object.keys(self._state.addresses).length == 0) return;
var selectedServer = self._state.addresses[Object.keys(self._state.addresses)[self.updateHealthServerTry++]];
if(self.updateHealthServerTry >= Object.keys(self._state.addresses).length) self.updateHealthServerTry = 0;
if(selectedServer == null) return check();
// If we have an active db instance
if(self.dbInstances.length > 0) {
var db = self.dbInstances[0];
// Create a new master connection
var _server = new Server(selectedServer.host, selectedServer.port, {
auto_reconnect: false,
returnIsMasterResults: true,
slaveOk: true,
socketOptions: { connectTimeoutMS: 1000}
});
// Connect using the new _server connection to not impact the driver
// behavior on any errors we could possibly run into
_server.connect(db, function(err, result, _server) {
if(err) {
if(_server.close) _server.close();
return check();
}
// Create is master command
var cmd = DbCommand.createIsMasterCommand(db);
// Execute is master command
db._executeQueryCommand(cmd, {failFast:true, connection: _server.checkoutReader()}, function(err, res) {
// Close the connection used
_server.close();
// If error let's set perform another check
if(err) return check();
// Validate the replicaset
self._validateReplicaset(res, db.auths, function() {
check();
});
});
});
}
}
function check () {
self._haTimer = setTimeout(ping, self.replicasetStatusCheckInterval);
}
}

@@ -320,133 +365,187 @@

*/
ReplSet.prototype._validateReplicaset = function(result, auths) {
ReplSet.prototype._validateReplicaset = function(result, auths, cb) {
var self = this;
// For each member we need to check if we have a new connection that needs to be established
var members = result['documents'][0]['members'];
// Get members
var members = Array.isArray(result['documents'][0]['members']) ? result['documents'][0]['members'] : [];
// The total members we check
var serversToConnectList = {};
var res = result.documents[0];
// Iterate over all the members and see if we need to reconnect
for(var i = 0, jlen = members.length; i < jlen; i++) {
var member = members[i];
// manage master node changes
if(res.primary && self._state.master && self._state.master.name != res.primary) {
// Delete master record so we can rediscover it
delete self._state.addresses[self._state.master.name];
if(member['health'] != 0
&& null == self._state['addresses'][member['name']]
&& null == serversToConnectList[member['name']]) {
if (member['stateStr'] == 'ARBITER' && self.connectArbiter != true) {
continue;
}
// Split the server string
var parts = member.name.split(/:/);
if(parts.length == 1) {
parts = [parts[0], Connection.DEFAULT_PORT];
}
// TODO existing issue? this seems to only work if
// we already have a connection to the new primary.
// Default empty socket options object
var socketOptions = {host:parts[0], port:parseInt(parts[1], 10)};
// If a socket option object exists clone it
if(self.socketOptions != null) {
var keys = Object.keys(self.socketOptions);
for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = self.socketOptions[keys[i]];
}
// Update information on new primary
// add as master, remove from secondary
var newMaster = self._state.addresses[res.primary];
newMaster.isMasterDoc.ismaster = true;
newMaster.isMasterDoc.secondary = false;
self._state.master = newMaster;
delete self._state.secondaries[res.primary];
}
// Create a new server instance
var newServer = new Server(parts[0], parseInt(parts[1], 10), {auto_reconnect:false, 'socketOptions':socketOptions
, logger:self.logger, ssl:self.ssl, poolSize:self.poolSize});
// Set the replicaset instance
newServer.replicasetInstance = self;
// discover new hosts
var hosts = [];
// Add handlers
newServer.on("close", _handler("close", self));
newServer.on("error", _handler("error", self));
newServer.on("timeout", _handler("timeout", self));
// Add to list of server connection target
serversToConnectList[member['name']] = newServer;
} else if(member['stateStr'] == 'PRIMARY' && self._state.master['name'] != member['name']) {
// Delete master record so we can rediscover it
delete self._state['addresses'][self._state.master['name']];
// Update inormation on new primary
var newMaster = self._state.addresses[member['name']];
newMaster.isMasterDoc.ismaster = true;
newMaster.isMasterDoc.secondary = false;
self._state.master = newMaster;
// Remove from secondaries
delete self._state.secondaries[member['name']];
newMaster = null;
for(var i = 0; i < res.hosts.length; ++i) {
var host = res.hosts[i];
if (host == res.me) continue;
if (!(self._state.addresses[host] || ~hosts.indexOf(host))) {
// we dont already have a connection to this host and aren't
// already planning on connecting.
hosts.push(host);
}
}
// All servers we want to connect to
var serverKeys = Object.keys(serversToConnectList);
// For all remaining servers on the list connect
while(serverKeys.length > 0) {
var _serverKey = serverKeys.pop();
// Fetch the server
var _server = serversToConnectList[_serverKey];
// Add a new server to the total number of servers that need to initialized before we are done
//var newServerCallback = self.connectionHandler(_server);
var newServerCallback = _connectHandler(self, null, _server)
// Connect To the new server
_server.connect(self.db, {returnIsMasterResults: true, eventReceiver:newServer}, function(err, result, _server) {
if(err == null && result != null) {
// Fetch the myState
var document = result.documents[0];
// Remove from list until
if(document.ismaster || document.secondary || document.arbiterOnly) {
process.nextTick(function() {
// Apply any auths
if(Array.isArray(auths) && auths.length > 0) {
// Get number of auths we need to execute
var numberOfAuths = auths.length;
// Apply all auths
for(var i = 0; i < auths.length; i++) {
self.db.authenticate(auths[i].username, auths[i].password, {'authdb':auths[i].authdb}, function(err, authenticated) {
numberOfAuths = numberOfAuths - 1;
// If we have no more authentications to replay
if(numberOfAuths == 0) {
newServerCallback(err, result, _server);
}
});
}
} else {
newServerCallback(err, result, _server);
}
});
} else {
_server.close();
connectTo(hosts, auths, self, cb);
}
/**
* Create connections to all `hosts` firing `cb` after
* connections are attempted for all `hosts`.
*
* @param {Array} hosts
* @param {Array} [auths]
* @param {ReplSet} replset
* @param {Function} cb
* @ignore
*/
function connectTo (hosts, auths, replset, cb) {
var pending = hosts.length;
if (!pending) return cb();
for(var i = 0; i < hosts.length; ++i) {
connectToHost(hosts[i], auths, replset, handle);
}
function handle () {
--pending;
if (0 === pending) cb();
}
}
/**
* Attempts connection to `host` and authenticates with optional `auth`
* for the given `replset` firing `cb` when finished.
*
* @param {String} host
* @param {Array} auths
* @param {ReplSet} replset
* @param {Function} cb
* @ignore
*/
function connectToHost (host, auths, replset, cb) {
var server = createServer(host, replset);
var options = {
returnIsMasterResults: true,
eventReceiver: server
}
server.connect(replset.db, options, function(err, result) {
var doc = result && result.documents && result.documents[0];
if (err || !doc) {
server.close();
return cb(err, result, server);
}
if(!(doc.ismaster || doc.secondary || doc.arbiterOnly)) {
server.close();
return cb(null, result, server);
}
// if host is an arbiter, disconnect if not configured for it
if(doc.arbiterOnly && !replset.connectArbiter) {
server.close();
return cb(null, result, server);
}
// create handler for successful connections
var handleConnect = _connectHandler(replset, null, server);
function complete () {
handleConnect(err, result);
cb();
}
// authenticate if necessary
if(!(Array.isArray(auths) && auths.length > 0)) {
return complete();
}
var pending = auths.length;
for(var i = 0; i < auths.length; i++) {
var auth = auths[i];
var options = { authdb: auth.authdb };
var username = auth.username;
var password = auth.password;
replset.db.authenticate(username, password, options, function() {
--pending;
if(0 === pending) {
return complete();
}
} else {
_server.close();
}
});
});
}
});
}
/**
* Creates a new server for the `replset` based on `host`.
*
* @param {String} host - host:port pair (localhost:27017)
* @param {ReplSet} replset - the ReplSet instance
* @return {Server}
* @ignore
*/
function createServer (host, replset) {
// copy existing socket options to new server
var socketOptions = {}
if(replset.socketOptions) {
var keys = Object.keys(replset.socketOptions);
for(var k = 0; k < keys.length; k++) {
socketOptions[keys[k]] = replset.socketOptions[keys[k]];
}
}
var parts = host.split(/:/);
if(1 === parts.length) {
parts[1] = Connection.DEFAULT_PORT;
}
socketOptions.host = parts[0];
socketOptions.port = parseInt(parts[1], 10);
var serverOptions = {
readPreference: replset._readPreference,
socketOptions: socketOptions,
poolSize: replset.poolSize,
logger: replset.logger,
auto_reconnect: false,
ssl: replset.ssl
}
var server = new Server(socketOptions.host, socketOptions.port, serverOptions);
server.replicasetInstance = replset;
server.on("close", _handler("close", replset));
server.on("error", _handler("error", replset));
server.on("timeout", _handler("timeout", replset));
return server;
}
var _handler = function(event, self) {
return function(err, server) {
// Check if we have a secondary server
if(self._state.master && self._state.master.name == server.name) {
// Force close
self.close();
// Error out all callbacks
__executeAllCallbacksWithError(self.db, err);
} else if(self._state.master
&& (self._state.secondaries[server.name] != null
|| self._state.arbiters[server.name] != null
|| self._state.passives[server.name] != null)) {
return function(err, server) {
// Execute all the callbacks with errors
self.__executeAllCallbacksWithError(err);
delete self._state.secondaries[server.name];
delete self._state.arbiters[server.name];
delete self._state.passives[server.name];
delete self._state.addresses[server.name];
// If we have app listeners on close event
if(self.db.listeners(event).length > 0) {
self.db.emit(event, err);
}
// If it's a primary we need to close the set to reconnect
if(self._state.master && self._state.master.host == server.host && self._state.master.port == server.port) {
// If we have app listeners on close event
if(self.db.listeners(event).length > 0) {
self.db.emit(event, err);
}
}
// Remove from all lists
delete self._state.secondaries[server.name];
delete self._state.arbiters[server.name];
delete self._state.passives[server.name];
delete self._state.addresses[server.name];
}

@@ -459,2 +558,3 @@ }

if(self._serverState == 'disconnected') return instanceServer.close();
// If no error handle isMaster

@@ -495,3 +595,6 @@ if(err == null && result.documents[0].hosts != null) {

if (self._state.addresses[me] && self._state.addresses[me] !== instanceServer) self._state.addresses[me].close();
if (self._state.addresses[me] && self._state.addresses[me] !== instanceServer) {
self._state.addresses[me].close();
}
self._state.addresses[me] = instanceServer;

@@ -516,2 +619,3 @@

instanceServer.tags = tags;
// Add the handlers to the instance

@@ -557,6 +661,12 @@ instanceServer.on("close", _handler("close", self));

var server = candidateServers.pop();
// Get server addresses
var addresses = self._state.addresses;
// Default empty socket options object
var socketOptions = {};
// Set fast connect timeout
socketOptions['connectTimeoutMS'] = self._connectTimeoutMS;
// If a socket option object exists clone it

@@ -567,6 +677,6 @@ if(self.socketOptions != null && typeof self.socketOptions === 'object') {

}
// If ssl is specified
if(self.ssl) serverConnections[i].ssl = true;
// Set fast connect timeout
socketOptions['connectTimeoutMS'] = self._connectTimeoutMS
// Add host information to socket options

@@ -599,2 +709,6 @@ socketOptions['host'] = server.host;

} else{
if (self.strategyInstance) {
self.strategyInstance.start();
}
self.emit("fullsetup", null, self.db, self);

@@ -608,4 +722,21 @@ self.emit("open", null, self.db, self);

/**
* Interval state object constructor
*
* @ignore
*/
ReplSet.State = function ReplSetState () {
this.errorMessages = [];
this.secondaries = {};
this.addresses = {};
this.arbiters = {};
this.passives = {};
this.members = [];
this.errors = {};
this.setName = null;
this.master = null;
}
/**
* @ignore
*/
ReplSet.prototype.connect = function(parent, options, callback) {

@@ -619,2 +750,3 @@ var self = this;

self.close();
// Set connecting status

@@ -624,6 +756,9 @@ this.db = parent;

this._callbackList = [];
this._state = {'master':null, 'secondaries':{}, 'arbiters':{}, 'passives':{}
, 'errors':{}, 'addresses':{}, 'setName':null, 'errorMessages':[], 'members':[]};
this._state = new ReplSet.State();
// Ensure parent can do a slave query if it's set
parent.slaveOk = this.slaveOk ? this.slaveOk : parent.slaveOk;
parent.slaveOk = this.slaveOk
? this.slaveOk
: parent.slaveOk;

@@ -636,7 +771,4 @@ // Remove any listeners

this.once("fullsetup", function() {
// Set state connected
self._serverState = 'connected';
// Emit the fullsetup and open event
parent.emit("open", null, self.db, self);
parent.emit("fullsetup", null, self.db, self);
self._handleOnFullSetup(parent);
// Callback

@@ -665,27 +797,9 @@ if(typeof callback == 'function') {

// Default empty socket options object
var socketOptions = {};
// If a socket option object exists clone it
if(this.socketOptions != null && typeof this.socketOptions === 'object') {
var keys = Object.keys(this.socketOptions);
for(var j = 0; j < keys.length;j++) socketOptions[keys[j]] = this.socketOptions[keys[j]];
}
// If ssl is specified
if(this.ssl) serverConnections[i].ssl = true;
// Set fast connect timeout
socketOptions['connectTimeoutMS'] = this._connectTimeoutMS
// De-duplicate any servers
var server;
var server, key;
for(var i = 0; i < this.servers.length; i++) {
server = this.servers[i];
// Add host information to socket options
socketOptions['host'] = server.host;
socketOptions['port'] = server.port;
server.socketOptions = socketOptions;
server.replicasetInstance = this;
server.enableRecordQueryStats(this.recordQueryStats);
// If server does not exist set it
if(addresses[server.host + ":" + server.port] == null) {
addresses[server.host + ":" + server.port] = server;
key = server.host + ":" + server.port;
if(null == addresses[key]) {
addresses[key] = server;
}

@@ -698,12 +812,46 @@ }

for(var i = 0; i < keys.length; i++) {
candidateServers.push(addresses[keys[i]]);
server = addresses[keys[i]];
server.assignReplicaSet(this);
candidateServers.push(server);
}
// Let's connect to the first one on the list
server = candidateServers.pop();
server.connect(parent, {returnIsMasterResults: true, eventReceiver:server}, _connectHandler(this, candidateServers, server));
var opts = {
returnIsMasterResults: true,
eventReceiver: server
}
server.connect(parent, opts, _connectHandler(this, candidateServers, server));
}
/**
* Handles the first `fullsetup` event of this ReplSet.
*
* @param {Db} parent
* @ignore
*/
ReplSet.prototype._handleOnFullSetup = function (parent) {
this._serverState = 'connected';
// Emit the fullsetup and open event
parent.emit("open", null, this.db, this);
parent.emit("fullsetup", null, this.db, this);
if(!this.haEnabled) return;
this._enableHA();
}
/**
* Disables high availability pings.
*
* @ignore
*/
ReplSet.prototype._disableHA = function () {
clearTimeout(this._haTimer);
this._haTimer = undefined;
}
/**
* @ignore
*/
ReplSet.prototype.checkoutWriter = function() {

@@ -721,3 +869,3 @@ // Establish connection

var keys = Object.keys(self._state.secondaries);
var connection = null;
var connection;

@@ -727,3 +875,3 @@ // Find first available reader if any

connection = self._state.secondaries[keys[i]].checkoutReader();
if(connection != null) break;
if(connection) return connection;
}

@@ -734,11 +882,11 @@

connection = self._state.master.checkoutReader();
if(connection) return connection;
}
if(connection == null) {
var preferenceName = self._readPreference == ReadPreference.SECONDARY_PREFERRED ? 'secondary' : self._readPreference;
return new Error("No replica set member available for query with ReadPreference " + preferenceName + " and tags " + JSON.stringify(tags));
}
var preferenceName = self._readPreference == ReadPreference.SECONDARY_PREFERRED
? 'secondary'
: self._readPreference;
// Return the connection
return connection;
return new Error("No replica set member available for query with ReadPreference "
+ preferenceName + " and tags " + JSON.stringify(tags));
}

@@ -842,10 +990,3 @@

} else {
// Pick a secondary using round robin
var keys = Object.keys(this._state.secondaries);
this._currentServerChoice = this._currentServerChoice % keys.length;
var key = keys[this._currentServerChoice++];
// Fetch a connectio
connection = this._state.secondaries[key] != null ? this._state.secondaries[key].checkoutReader() : null;
// If connection is null fallback to first available secondary
connection = connection == null ? pickFirstConnectedSecondary(this, tags) : connection;
connection = _roundRobin(this, tags);
}

@@ -866,10 +1007,3 @@ } else if(finalReadPreference == ReadPreference.PRIMARY_PREFERRED) {

} else {
// Pick a secondary using round robin
var keys = Object.keys(this._state.secondaries);
this._currentServerChoice = this._currentServerChoice % keys.length;
var key = keys[this._currentServerChoice++];
// Fetch a connectio
connection = this._state.secondaries[key] != null ? this._state.secondaries[key].checkoutReader() : null;
// If connection is null fallback to first available secondary
connection = connection == null ? pickFirstConnectedSecondary(this, tags) : connection;
connection = _roundRobin(this, tags);
}

@@ -921,4 +1055,25 @@ }

/**
* Pick a secondary using round robin
*
* @ignore
*/
function _roundRobin (replset, tags) {
var keys = Object.keys(replset._state.secondaries);
var key = keys[replset._currentServerChoice++ % keys.length];
var conn = null != replset._state.secondaries[key]
? replset._state.secondaries[key].checkoutReader()
: null;
// If connection is null fallback to first available secondary
if (null == conn) {
conn = pickFirstConnectedSecondary(replset, tags);
}
return conn;
}
/**
* @ignore
*/
ReplSet.prototype.allRawConnections = function() {

@@ -925,0 +1080,0 @@ // Neeed to build a complete list of all raw connections, start with master server

@@ -7,2 +7,4 @@ var Connection = require('./connection').Connection,

EventEmitter = require('events').EventEmitter,
Base = require('./base').Base,
utils = require('../utils'),
inherits = require('util').inherits;

@@ -29,6 +31,8 @@

function Server(host, port, options) {
// Set up event emitter
EventEmitter.call(this);
// Set up Server instance
if(!(this instanceof Server)) return new Server(host, port, options);
// Set up event emitter
Base.call(this);
// Ensure correct values

@@ -50,4 +54,5 @@ if(port != null && typeof port == 'object') {

this.ssl = this.options.ssl == null ? false : this.options.ssl;
this.slaveOk = this.options["slave_ok"];
this.slaveOk = this.options["slave_ok"] ? this.options["slave_ok"] : this.options["slaveOk"];
this._used = false;
this.replicasetInstance = null;

@@ -101,4 +106,3 @@ // Get the readPreference

*/
// Inherit simple event emitter
inherits(Server, EventEmitter);
inherits(Server, Base);

@@ -170,8 +174,44 @@ //

Server.prototype.isSetMember = function() {
return this['replicasetInstance'] != null || this['mongosInstance'] != null;
return this.replicasetInstance != null || this.mongosInstance != null;
}
/**
* Assigns a replica set to this `server`.
*
* @param {ReplSet} replset
* @ignore
*/
Server.prototype.assignReplicaSet = function (replset) {
this.replicasetInstance = replset;
this.inheritReplSetOptionsFrom(replset);
this.enableRecordQueryStats(replset.recordQueryStats);
}
/**
* Takes needed options from `replset` and overwrites
* our own options.
*
* @param {ReplSet} replset
* @ignore
*/
Server.prototype.inheritReplSetOptionsFrom = function (replset) {
this.socketOptions = {};
this.socketOptions.connectTimeoutMS = replset._connectTimeoutMS;
if(replset.ssl)
this.socketOptions.ssl = true;
// If a socket option object exists clone it
if(utils.isObject(replset.socketOptions)) {
var keys = Object.keys(replset.socketOptions);
for(var i = 0; i < keys.length; i++)
this.socketOptions[keys[i]] = replset.socketOptions[keys[i]];
}
}
/**
* Opens this server connection.
*
* @ignore
*/
Server.prototype.connect = function(dbInstance, options, callback) {

@@ -350,3 +390,3 @@ if('function' === typeof options) callback = options, options = {};

// Fire all callback errors
_fireCallbackErrors(server, new Error("connection closed due to parseError"));
server.__executeAllCallbacksWithError(new Error("connection closed due to parseError"));
// Emit error

@@ -364,2 +404,3 @@ _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);

var firstResult = mongoReply && mongoReply.documents;
// Check for an error, if we have one let's trigger the callback and clean up

@@ -422,3 +463,3 @@ // The chained callbacks

// Fire all callback errors
_fireCallbackErrors(server, new Error("connection closed due to parseError"));
server.__executeAllCallbacksWithError(new Error("connection closed due to parseError"));
// Emit error

@@ -472,3 +513,3 @@ _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);

// Fire all callback errors
_fireCallbackErrors(server, err);
server.__executeAllCallbacksWithError(err);
// Emit error

@@ -501,3 +542,3 @@ _emitAcrossAllDbInstances(server, eventReceiver, "timeout", err, server, true);

// Fire all callback errors
_fireCallbackErrors(server, new Error(message && message.err ? message.err : message));
server.__executeAllCallbacksWithError(new Error(message && message.err ? message.err : message));
// Emit error

@@ -530,3 +571,3 @@ _emitAcrossAllDbInstances(server, eventReceiver, "error", new Error(message && message.err ? message.err : message), server, true);

// Fire all callback errors
_fireCallbackErrors(server, new Error("connection closed"));
server.__executeAllCallbacksWithError(new Error("connection closed"));
// Emit error

@@ -560,3 +601,3 @@ _emitAcrossAllDbInstances(server, eventReceiver, "close", server, null, true);

// Fire all callback errors
_fireCallbackErrors(server, new Error("connection closed due to parseError"));
server.__executeAllCallbacksWithError(new Error("connection closed due to parseError"));
// Emit error

@@ -572,43 +613,4 @@ _emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);

/**
* Fire all the errors
* @ignore
*/
var _fireCallbackErrors = function(server, err) {
// Locate all the possible callbacks that need to return
for(var i = 0; i < server.dbInstances.length; i++) {
// Fetch the db Instance
var dbInstance = server.dbInstances[i];
// Check all callbacks
var keys = Object.keys(dbInstance._callBackStore._notReplied);
// For each key check if it's a callback that needs to be returned
for(var j = 0; j < keys.length; j++) {
var info = dbInstance._callBackStore._notReplied[keys[j]];
// Check if we have a chained command (findAndModify)
if(info && info['chained'] && Array.isArray(info['chained']) && info['chained'].length > 0) {
var chained = info['chained'];
// Only callback once and the last one is the right one
var finalCallback = chained.pop();
if(info.connection.socketOptions.host === server.host && info.connection.socketOptions.port === server.port) {
dbInstance._callBackStore.emit(finalCallback, err, null);
}
// Put back the final callback to ensure we don't call all commands in the chain
chained.push(finalCallback);
// Remove all chained callbacks
for(var i = 0; i < chained.length; i++) {
delete dbInstance._callBackStore._notReplied[chained[i]];
}
} else {
if(info && info.connection.socketOptions.host === server.host && info.connection.socketOptions.port === server.port) {
dbInstance._callBackStore.emit(keys[j], err, null);
}
}
}
}
}
/**
* @ignore
*/
var _emitAcrossAllDbInstances = function(server, filterDb, event, message, object, resetConnection) {

@@ -615,0 +617,0 @@ // Emit close event across all db instances sharing the sockets

@@ -147,3 +147,3 @@ var Server = require("../server").Server;

var server = new Server(serverInstance.host, serverInstance.port, options);
var db = new self.Db(self.replicaset.db.databaseName, server);
var db = new self.Db(self.replicaset.db.databaseName, server, { safe: true });

@@ -154,3 +154,3 @@ db.on("error", done);

db.open(function(err, _db) {
if(err) return done(_db);
if(err) return done(err, _db);

@@ -166,9 +166,9 @@ // Startup time of the command

done(_db);
done(null, _db);
})
})
function done (_db) {
function done (err, _db) {
// Close connection
_db.close(true);
if (_db) _db.close(true);

@@ -175,0 +175,0 @@ // Adjust the number of checks

@@ -10,3 +10,3 @@ // The Statistics strategy uses the measure of each end-start time for each

StatisticsStrategy.prototype.start = function(callback) {
callback(null, null);
callback && callback(null, null);
}

@@ -13,0 +13,0 @@

@@ -14,2 +14,28 @@ var QueryCommand = require('./commands/query_command').QueryCommand,

*
* Options
* - **skip** {Number} skip number of documents to skip.
* - **limit** {Number}, limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1.
* - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc.
* - **hint** {Object}, hint force the query to use a specific index.
* - **explain** {Boolean}, explain return the explaination of the query.
* - **snapshot** {Boolean}, snapshot Snapshot mode assures no duplicates are returned.
* - **timeout** {Boolean}, timeout allow the query to timeout.
* - **tailable** {Boolean}, tailable allow the cursor to be tailable.
* - **awaitdata** {Boolean}, awaitdata allow the cursor to wait for data, only applicable for tailable cursor.
* - **batchSize** {Number}, batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database.
* - **raw** {Boolean}, raw return all query documents as raw buffers (default false).
* - **read** {Boolean}, read specify override of read from source (primary/secondary).
* - **slaveOk** {Boolean}, slaveOk, sets the slaveOk flag on the query wire protocol for secondaries.
* - **returnKey** {Boolean}, returnKey only return the index key.
* - **maxScan** {Number}, maxScan limit the number of items to scan.
* - **min** {Number}, min set index bounds.
* - **max** {Number}, max set index bounds.
* - **showDiskLoc** {Boolean}, showDiskLoc show disk location of results.
* - **comment** {String}, comment you can put a $comment field on a query to make looking in the profiler logs simpler.
* - **numberOfRetries** {Number}, numberOfRetries if using awaidata specifies the number of times to retry on timeout.
* - **dbName** {String}, dbName override the default dbName.
* - **tailableRetryInterval** {Number}, tailableRetryInterval specify the miliseconds between getMores on tailable cursor.
* - **exhaust** {Boolean}, exhaust have the server send all the documents at once as getMore packets.
* - **partial** {Boolean}, partial have the sharded system return a partial result from mongos.
*
* @class Represents a Cursor.

@@ -20,29 +46,5 @@ * @param {Db} db the database object to work with.

* @param {Object} fields an object containing what fields to include or exclude from objects returned.
* @param {Number} skip number of documents to skip.
* @param {Number} limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1.
* @param {String|Array|Object} sort the required sorting for the query.
* @param {Object} hint force the query to use a specific index.
* @param {Boolean} explain return the explaination of the query.
* @param {Boolean} snapshot Snapshot mode assures no duplicates are returned.
* @param {Boolean} timeout allow the query to timeout.
* @param {Boolean} tailable allow the cursor to be tailable.
* @param {Boolean} awaitdata allow the cursor to wait for data, only applicable for tailable cursor.
* @param {Number} batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database.
* @param {Boolean} raw return all query documents as raw buffers (default false).
* @param {Boolean} read specify override of read from source (primary/secondary).
* @param {Boolean} returnKey only return the index key.
* @param {Number} maxScan limit the number of items to scan.
* @param {Number} min set index bounds.
* @param {Number} max set index bounds.
* @param {Boolean} showDiskLoc show disk location of results.
* @param {String} comment you can put a $comment field on a query to make looking in the profiler logs simpler.
* @param {Number} numberOfRetries if using awaidata specifies the number of times to retry on timeout.
* @param {String} dbName override the default dbName.
* @param {Number} tailableRetryInterval specify the miliseconds between getMores on tailable cursor.
* @param {Boolean} exhaust have the server send all the documents at once as getMore packets.
* @param {Boolean} partial have the sharded system return a partial result from mongos.
*/
function Cursor(db, collection, selector, fields, skip, limit
, sort, hint, explain, snapshot, timeout, tailable, batchSize, slaveOk, raw, read
, returnKey, maxScan, min, max, showDiskLoc, comment, awaitdata, numberOfRetries, dbName, tailableRetryInterval, exhaust, partial) {
* @param {Object} [options] additional options for the collection.
*/
function Cursor(db, collection, selector, fields, options) {
this.db = db;

@@ -52,26 +54,28 @@ this.collection = collection;

this.fields = fields;
this.skipValue = skip == null ? 0 : skip;
this.limitValue = limit == null ? 0 : limit;
this.sortValue = sort;
this.hint = hint;
this.explainValue = explain;
this.snapshot = snapshot;
this.timeout = timeout == null ? true : timeout;
this.tailable = tailable;
this.awaitdata = awaitdata;
this.numberOfRetries = numberOfRetries == null ? 5 : numberOfRetries;
options = !options ? {} : options;
this.skipValue = options.skip == null ? 0 : options.skip;
this.limitValue = options.limit == null ? 0 : options.limit;
this.sortValue = options.sort;
this.hint = options.hint;
this.explainValue = options.explain;
this.snapshot = options.snapshot;
this.timeout = options.timeout == null ? true : options.timeout;
this.tailable = options.tailable;
this.awaitdata = options.awaitdata;
this.numberOfRetries = options.numberOfRetries == null ? 5 : options.numberOfRetries;
this.currentNumberOfRetries = this.numberOfRetries;
this.batchSizeValue = batchSize == null ? 0 : batchSize;
this.slaveOk = slaveOk == null ? collection.slaveOk : slaveOk;
this.raw = raw == null ? false : raw;
this.read = read == null ? ReadPreference.PRIMARY : read;
this.returnKey = returnKey;
this.maxScan = maxScan;
this.min = min;
this.max = max;
this.showDiskLoc = showDiskLoc;
this.comment = comment;
this.tailableRetryInterval = tailableRetryInterval || 100;
this.exhaust = exhaust || false;
this.partial = partial || false;
this.batchSizeValue = options.batchSize == null ? 0 : options.batchSize;
this.slaveOk = options.slaveOk == null ? collection.slaveOk : options.slaveOk;
this.raw = options.raw == null ? false : options.raw;
this.read = options.read == null ? ReadPreference.PRIMARY : options.read;
this.returnKey = options.returnKey;
this.maxScan = options.maxScan;
this.min = options.min;
this.max = options.max;
this.showDiskLoc = options.showDiskLoc;
this.comment = options.comment;
this.tailableRetryInterval = options.tailableRetryInterval || 100;
this.exhaust = options.exhaust || false;
this.partial = options.partial || false;

@@ -83,3 +87,3 @@ this.totalNumberOfRecords = 0;

// This name
this.dbName = dbName;
this.dbName = options.dbName;

@@ -133,3 +137,3 @@ // State variables for the cursor

*
* @param {Function} callback This will be called after executing this method successfully. The first paramter will contain the Error object if an error occured, or null otherwise. The second paramter will contain an array of BSON deserialized objects as a result of the query.
* @param {Function} callback This will be called after executing this method successfully. The first parameter will contain the Error object if an error occured, or null otherwise. The second parameter will contain an array of BSON deserialized objects as a result of the query.
* @return {null}

@@ -176,3 +180,3 @@ * @api public

*
* @param {Function} callback this will be called for while iterating every document of the query result. The first paramter will contain the Error object if an error occured, or null otherwise. While the second paramter will contain the document.
* @param {Function} callback this will be called for while iterating every document of the query result. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the document.
* @return {null}

@@ -213,3 +217,3 @@ * @api public

*
* @param {Function} callback this will be after executing this method. The first paramter will contain the Error object if an error occured, or null otherwise. While the second paramter will contain the number of results or null if an error occured.
* @param {Function} callback this will be called after executing this method. The first parameter will contain the Error object if an error occured, or null otherwise. While the second parameter will contain the number of results or null if an error occured.
* @return {null}

@@ -657,7 +661,58 @@ * @api public

var limit = (-1)*Math.abs(this.limitValue);
// * - **skip** {Number} skip number of documents to skip.
// * - **limit** {Number}, limit the number of results to return. -1 has a special meaning and is used by Db.eval. A value of 1 will also be treated as if it were -1.
// * - **hint** {Object}, hint force the query to use a specific index.
// * - **explain** {Boolean}, explain return the explaination of the query.
// * - **slaveOk** {Boolean}, slaveOk, sets the slaveOk flag on the query wire protocol for secondaries.
// * - **snapshot** {Boolean}, snapshot Snapshot mode assures no duplicates are returned.
// * - **timeout** {Boolean}, timeout allow the query to timeout.
// * - **tailable** {Boolean}, tailable allow the cursor to be tailable.
// * - **awaitdata** {Boolean}, awaitdata allow the cursor to wait for data, only applicable for tailable cursor.
// * - **batchSize** {Number}, batchSize the number of the subset of results to request the database to return for every request. This should initially be greater than 1 otherwise the database will automatically close the cursor. The batch size can be set to 1 with cursorInstance.batchSize after performing the initial query to the database.
// * - **raw** {Boolean}, raw return all query documents as raw buffers (default false).
// * - **read** {Boolean}, read specify override of read from source (primary/secondary).
// * - **returnKey** {Boolean}, returnKey only return the index key.
// * - **maxScan** {Number}, maxScan limit the number of items to scan.
// * - **min** {Number}, min set index bounds.
// * - **max** {Number}, max set index bounds.
// * - **showDiskLoc** {Boolean}, showDiskLoc show disk location of results.
// * - **comment** {String}, comment you can put a $comment field on a query to make looking in the profiler logs simpler.
// * - **numberOfRetries** {Number}, numberOfRetries if using awaidata specifies the number of times to retry on timeout.
// * - **dbName** {String}, dbName override the default dbName.
// * - **tailableRetryInterval** {Number}, tailableRetryInterval specify the miliseconds between getMores on tailable cursor.
// * - **exhaust** {Boolean}, exhaust have the server send all the documents at once as getMore packets.
// * - **partial** {Boolean}, partial have the sharded system return a partial result from mongos.
// * - **sort** {Array | Object}, set to sort the documents coming back from the query. Array of indexes, [['a', 1]] etc.
// function Cursor(db, collection, selector, fields, skip, limit
// - , sort, hint, explain, snapshot, timeout, tailable, batchSize, slaveOk, raw, read
// - , returnKey, maxScan, min, max, showDiskLoc, comment, awaitdata, numberOfRetries, dbName, tailableRetry
// Create a new cursor and fetch the plan
var cursor = new Cursor(this.db, this.collection, this.selector, this.fields, this.skipValue, limit
, this.sortValue, this.hint, true, this.snapshot, this.timeout, this.tailable, this.batchSizeValue
, this.slaveOk, this.raw, this.read, this.returnKey, this.maxScan, this.min, this.max, this.showDiskLoc
, this.comment, this.awaitdata, this.numberOfRetries, this.dbName);
var cursor = new Cursor(this.db, this.collection, this.selector, this.fields, {
skip: this.skipValue
, limit:limit
, sort: this.sortValue
, hint: this.hint
, explain: true
, snapshot: this.snapshot
, timeout: this.timeout
, tailable: this.tailable
, batchSize: this.batchSizeValue
, slaveOk: this.slaveOk
, raw: this.raw
, read: this.read
, returnKey: this.returnKey
, maxScan: this.maxScan
, min: this.min
, max: this.max
, showDiskLoc: this.showDiskLoc
, comment: this.comment
, awaitdata: this.awaitdata
, numberOfRetries: this.numberOfRetries
, dbName: this.dbName
});
// Fetch the explaination document

@@ -772,3 +827,4 @@ cursor.nextObject(function(err, item) {

var command = new KillCursorCommand(this.db, [this.cursorId]);
this.db._executeQueryCommand(command, {read:self.read, raw:self.raw, connection:self.connection}, null);
// Added an empty callback to ensure we don't throw any null exceptions
this.db._executeQueryCommand(command, {read:self.read, raw:self.raw, connection:self.connection}, function() {});
} catch(err) {}

@@ -775,0 +831,0 @@ }

@@ -25,3 +25,3 @@ var GridStore = require('./gridstore').GridStore,

* @param {Object} [options] the options for the files.
* @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
* @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
* @return {null}

@@ -62,3 +62,3 @@ * @api public

* @param {ObjectID} id ObjectID for file.
* @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
* @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
* @return {null}

@@ -86,3 +86,3 @@ * @api public

* @param {ObjectID} id ObjectID for file.
* @callback {Function} this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
* @param {Function} callback this will be called after this method is executed. The first parameter will contain an Error object if an error occured or null otherwise. The second parameter will contain a reference to this object.
* @return {null}

@@ -89,0 +89,0 @@ * @api public

@@ -95,4 +95,2 @@ /**

this.internalChunkSize = this.options['chunkSize'] == null ? Chunk.DEFAULT_CHUNK_SIZE : this.options['chunkSize'];
// Previous chunk size
this.previousChunkSize = 0;
}

@@ -446,15 +444,15 @@

var buildMongoObject = function(self, callback) {
// Keeps the final chunk number
var chunkNumber = 0;
var previousChunkSize = self.previousChunkSize;
// Get the correct chunk Number, if we have an empty chunk return the previous chunk number
if(null != self.currentChunk && self.currentChunk.chunkNumber > 0 && self.currentChunk.position == 0) {
chunkNumber = self.currentChunk.chunkNumber - 1;
} else {
chunkNumber = self.currentChunk.chunkNumber;
previousChunkSize = self.currentChunk.position;
}
// // Keeps the final chunk number
// var chunkNumber = 0;
// var previousChunkSize = 0;
// // Get the correct chunk Number, if we have an empty chunk return the previous chunk number
// if(null != self.currentChunk && self.currentChunk.chunkNumber > 0 && self.currentChunk.position == 0) {
// chunkNumber = self.currentChunk.chunkNumber - 1;
// } else {
// chunkNumber = self.currentChunk.chunkNumber;
// previousChunkSize = self.currentChunk.position;
// }
// Calcuate the length
var length = self.currentChunk != null ? (chunkNumber * self.chunkSize + previousChunkSize) : 0;
// // Calcuate the length
// var length = self.currentChunk != null ? (chunkNumber * self.chunkSize + previousChunkSize) : 0;
var mongoObject = {

@@ -461,0 +459,0 @@ '_id': self.fileId,

@@ -9,10 +9,2 @@ try {

[ 'commands/base_command'
, 'commands/db_command'
, 'commands/delete_command'
, 'commands/get_more_command'
, 'commands/insert_command'
, 'commands/kill_cursor_command'
, 'commands/query_command'
, 'commands/update_command'
, 'responses/mongo_reply'
, 'admin'

@@ -25,4 +17,6 @@ , 'collection'

, 'connection/repl_set'
, 'mongo_client'
, 'cursor'
, 'db'
, 'mongo_client'
, 'gridfs/grid'

@@ -53,108 +47,26 @@ , 'gridfs/chunk'

exports.BSON = require('bson').BSONPure.BSON;
});
// Exports all the classes for the PURE JS BSON Parser
exports.pure = function() {
var classes = {};
// Map all the classes
[ 'commands/base_command'
, 'commands/db_command'
, 'commands/delete_command'
, 'commands/get_more_command'
, 'commands/insert_command'
, 'commands/kill_cursor_command'
, 'commands/query_command'
, 'commands/update_command'
, 'responses/mongo_reply'
, 'admin'
, 'collection'
, 'connection/read_preference'
, 'connection/connection'
, 'connection/server'
, 'connection/mongos'
, 'connection/repl_set'
, 'cursor'
, 'db'
, 'gridfs/grid'
, 'gridfs/chunk'
, 'gridfs/gridstore'].forEach(function (path) {
var module = require('./' + path);
for (var i in module) {
classes[i] = module[i];
}
});
// Get the Db object
var Db = require('./db').Db;
// Set up the connect function
var connect = Db.connect;
var obj = connect;
// Map all values to the exports value
for(var name in exports) {
obj[name] = exports[name];
}
// backwards compat
classes.ReplSetServers = exports.ReplSet;
// Add the pure and native backward compatible functions
exports.pure = exports.native = function() {
return obj;
}
// Add BSON Classes
classes.Binary = require('bson').Binary;
classes.Code = require('bson').Code;
classes.DBRef = require('bson').DBRef;
classes.Double = require('bson').Double;
classes.Long = require('bson').Long;
classes.MinKey = require('bson').MinKey;
classes.MaxKey = require('bson').MaxKey;
classes.ObjectID = require('bson').ObjectID;
classes.Symbol = require('bson').Symbol;
classes.Timestamp = require('bson').Timestamp;
// Add BSON Parser
classes.BSON = require('bson').BSONPure.BSON;
// Return classes list
return classes;
// Map all values to the exports value
for(var name in exports) {
connect[name] = exports[name];
}
// Exports all the classes for the PURE JS BSON Parser
exports.native = function() {
var classes = {};
// Map all the classes
[ 'commands/base_command'
, 'commands/db_command'
, 'commands/delete_command'
, 'commands/get_more_command'
, 'commands/insert_command'
, 'commands/kill_cursor_command'
, 'commands/query_command'
, 'commands/update_command'
, 'responses/mongo_reply'
, 'admin'
, 'collection'
, 'connection/read_preference'
, 'connection/connection'
, 'connection/server'
, 'connection/mongos'
, 'connection/repl_set'
, 'cursor'
, 'db'
, 'gridfs/grid'
, 'gridfs/chunk'
, 'gridfs/gridstore'].forEach(function (path) {
var module = require('./' + path);
for (var i in module) {
classes[i] = module[i];
}
});
// Add BSON Classes
classes.Binary = require('bson').Binary;
classes.Code = require('bson').Code;
classes.DBRef = require('bson').DBRef;
classes.Double = require('bson').Double;
classes.Long = require('bson').Long;
classes.MinKey = require('bson').MinKey;
classes.MaxKey = require('bson').MaxKey;
classes.ObjectID = require('bson').ObjectID;
classes.Symbol = require('bson').Symbol;
classes.Timestamp = require('bson').Timestamp;
// backwards compat
classes.ReplSetServers = exports.ReplSet;
// Add BSON Parser
classes.BSON = require('bson').BSONNative.BSON;
// Return classes list
return classes;
}
// Set our exports to be the connect function
module.exports = connect;

@@ -75,1 +75,24 @@ /**

}
/**
* Context insensitive type checks
*/
var toString = Object.prototype.toString;
exports.isObject = function (arg) {
return '[object Object]' == toString.call(arg)
}
exports.isArray = function (arg) {
return Array.isArray(arg) ||
'object' == typeof arg && '[object Array]' == toString.call(arg)
}
exports.isDate = function (arg) {
return 'object' == typeof arg && '[object Date]' == toString.call(arg)
}
exports.isRegExp = function (arg) {
return 'object' == typeof arg && '[object RegExp]' == toString.call(arg)
}
{ "name" : "mongodb"
, "description" : "A node.js driver for MongoDB"
, "keywords" : ["mongodb", "mongo", "driver", "db"]
, "version" : "1.1.11"
, "version" : "1.2.0"
, "author" : "Christian Amor Kvalheim <christkv@gmail.com>"

@@ -6,0 +6,0 @@ , "contributors" : [ "Aaron Heckmann",

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc