mirror of
https://github.com/mgerb/mywebsite
synced 2026-01-13 19:12:49 +00:00
Added files
This commit is contained in:
339
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/admin.js
generated
vendored
Normal file
339
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/admin.js
generated
vendored
Normal file
@@ -0,0 +1,339 @@
|
||||
/*!
|
||||
* Module dependencies.
|
||||
*/
|
||||
var Collection = require('./collection').Collection,
|
||||
Cursor = require('./cursor').Cursor,
|
||||
DbCommand = require('./commands/db_command').DbCommand,
|
||||
utils = require('./utils');
|
||||
|
||||
/**
|
||||
* Allows the user to access the admin functionality of MongoDB
|
||||
*
|
||||
* @class Represents the Admin methods of MongoDB.
|
||||
* @param {Object} db Current db instance we wish to perform Admin operations on.
|
||||
* @return {Function} Constructor for Admin type.
|
||||
*/
|
||||
function Admin(db) {
|
||||
if(!(this instanceof Admin)) return new Admin(db);
|
||||
this.db = db;
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the server information for the current
|
||||
* instance of the db client
|
||||
*
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.buildInfo = function(callback) {
|
||||
this.serverInfo(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the server information for the current
|
||||
* instance of the db client
|
||||
*
|
||||
* @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
|
||||
* @api private
|
||||
*/
|
||||
Admin.prototype.serverInfo = function(callback) {
|
||||
this.db.executeDbAdminCommand({buildinfo:1}, function(err, doc) {
|
||||
if(err != null) return callback(err, null);
|
||||
return callback(null, doc.documents[0]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve this db's 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}
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.serverStatus = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.db.executeDbAdminCommand({serverStatus: 1}, function(err, doc) {
|
||||
if(err == null && doc.documents[0].ok === 1) {
|
||||
callback(null, doc.documents[0]);
|
||||
} else {
|
||||
if(err) return callback(err, false);
|
||||
return callback(utils.toError(doc.documents[0]), false);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrieve the current profiling Level for MongoDB
|
||||
*
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.profilingLevel = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.db.executeDbAdminCommand({profile:-1}, function(err, doc) {
|
||||
doc = doc.documents[0];
|
||||
|
||||
if(err == null && doc.ok === 1) {
|
||||
var was = doc.was;
|
||||
if(was == 0) return callback(null, "off");
|
||||
if(was == 1) return callback(null, "slow_only");
|
||||
if(was == 2) return callback(null, "all");
|
||||
return callback(new Error("Error: illegal profiling level value " + was), null);
|
||||
} else {
|
||||
err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Ping the MongoDB server and retrieve results
|
||||
*
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.ping = function(options, callback) {
|
||||
// Unpack calls
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
callback = args.pop();
|
||||
|
||||
this.db.executeDbAdminCommand({ping: 1}, callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate against MongoDB
|
||||
*
|
||||
* @param {String} username The user name for the authentication.
|
||||
* @param {String} password The password for the authentication.
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.authenticate = function(username, password, callback) {
|
||||
this.db.authenticate(username, password, {authdb: 'admin'}, function(err, doc) {
|
||||
return callback(err, doc);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Logout current authenticated user
|
||||
*
|
||||
* @param {Object} [options] Optional parameters to the command.
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.logout = function(callback) {
|
||||
this.db.logout({authdb: 'admin'}, function(err, doc) {
|
||||
return callback(err, doc);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a user to the MongoDB server, if the user exists it will
|
||||
* overwrite the current password
|
||||
*
|
||||
* Options
|
||||
* - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
|
||||
*
|
||||
* @param {String} username The user name for the authentication.
|
||||
* @param {String} password The password for the authentication.
|
||||
* @param {Object} [options] additional options during update.
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.addUser = function(username, password, options, callback) {
|
||||
var args = Array.prototype.slice.call(arguments, 2);
|
||||
callback = args.pop();
|
||||
options = args.length ? args.shift() : {};
|
||||
|
||||
options.dbName = 'admin';
|
||||
// Add user
|
||||
this.db.addUser(username, password, options, function(err, doc) {
|
||||
return callback(err, doc);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a user from the MongoDB server
|
||||
*
|
||||
* Options
|
||||
* - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
|
||||
*
|
||||
* @param {String} username The user name for the authentication.
|
||||
* @param {Object} [options] additional options during update.
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.removeUser = function(username, options, callback) {
|
||||
var self = this;
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
callback = args.pop();
|
||||
options = args.length ? args.shift() : {};
|
||||
options.dbName = 'admin';
|
||||
|
||||
this.db.removeUser(username, options, function(err, doc) {
|
||||
return callback(err, doc);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current profiling level of MongoDB
|
||||
*
|
||||
* @param {String} level The new profiling level (off, slow_only, all)
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.setProfilingLevel = function(level, callback) {
|
||||
var self = this;
|
||||
var command = {};
|
||||
var profile = 0;
|
||||
|
||||
if(level == "off") {
|
||||
profile = 0;
|
||||
} else if(level == "slow_only") {
|
||||
profile = 1;
|
||||
} else if(level == "all") {
|
||||
profile = 2;
|
||||
} else {
|
||||
return callback(new Error("Error: illegal profiling level value " + level));
|
||||
}
|
||||
|
||||
// Set up the profile number
|
||||
command['profile'] = profile;
|
||||
|
||||
this.db.executeDbAdminCommand(command, function(err, doc) {
|
||||
doc = doc.documents[0];
|
||||
|
||||
if(err == null && doc.ok === 1)
|
||||
return callback(null, level);
|
||||
return err != null ? callback(err, null) : callback(new Error("Error with profile command"), null);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Retrive the current profiling information for MongoDB
|
||||
*
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.profilingInfo = function(callback) {
|
||||
try {
|
||||
new Cursor(this.db, new Collection(this.db, DbCommand.SYSTEM_PROFILE_COLLECTION), {}, {}, {dbName: 'admin'}).toArray(function(err, items) {
|
||||
return callback(err, items);
|
||||
});
|
||||
} catch (err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Execute a db command against the Admin database
|
||||
*
|
||||
* @param {Object} command A command object `{ping:1}`.
|
||||
* @param {Object} [options] Optional parameters to the command.
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.command = function(command, options, callback) {
|
||||
var self = this;
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
callback = args.pop();
|
||||
options = args.length ? args.shift() : {};
|
||||
|
||||
// Execute a command
|
||||
this.db.executeDbAdminCommand(command, options, function(err, doc) {
|
||||
// Ensure change before event loop executes
|
||||
return callback != null ? callback(err, doc) : null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate an existing collection
|
||||
*
|
||||
* @param {String} collectionName The name of the collection to validate.
|
||||
* @param {Object} [options] Optional parameters to the command.
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.validateCollection = function(collectionName, options, callback) {
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
callback = args.pop();
|
||||
options = args.length ? args.shift() : {};
|
||||
|
||||
var self = this;
|
||||
var command = {validate: collectionName};
|
||||
var keys = Object.keys(options);
|
||||
|
||||
// Decorate command with extra options
|
||||
for(var i = 0; i < keys.length; i++) {
|
||||
if(options.hasOwnProperty(keys[i])) {
|
||||
command[keys[i]] = options[keys[i]];
|
||||
}
|
||||
}
|
||||
|
||||
this.db.executeDbCommand(command, function(err, doc) {
|
||||
if(err != null) return callback(err, null);
|
||||
doc = doc.documents[0];
|
||||
|
||||
if(doc.ok === 0)
|
||||
return callback(new Error("Error with validate command"), null);
|
||||
if(doc.result != null && doc.result.constructor != String)
|
||||
return callback(new Error("Error with validation data"), null);
|
||||
if(doc.result != null && doc.result.match(/exception|corrupt/) != null)
|
||||
return callback(new Error("Error: invalid collection " + collectionName), null);
|
||||
if(doc.valid != null && !doc.valid)
|
||||
return callback(new Error("Error: invalid collection " + collectionName), null);
|
||||
|
||||
return callback(null, doc);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* List the available databases
|
||||
*
|
||||
* @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
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.listDatabases = function(callback) {
|
||||
// Execute the listAllDatabases command
|
||||
this.db.executeDbAdminCommand({listDatabases:1}, {}, function(err, doc) {
|
||||
if(err != null) return callback(err, null);
|
||||
return callback(null, doc.documents[0]);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get ReplicaSet 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 replSetGetStatus or null if an error occured.
|
||||
* @return {null}
|
||||
* @api public
|
||||
*/
|
||||
Admin.prototype.replSetGetStatus = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.db.executeDbAdminCommand({replSetGetStatus:1}, function(err, doc) {
|
||||
if(err == null && doc.documents[0].ok === 1)
|
||||
return callback(null, doc.documents[0]);
|
||||
if(err) return callback(err, false);
|
||||
return callback(utils.toError(doc.documents[0]), false);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
exports.Admin = Admin;
|
||||
1762
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/collection.js
generated
vendored
Normal file
1762
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/collection.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
29
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/base_command.js
generated
vendored
Normal file
29
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/base_command.js
generated
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
Base object used for common functionality
|
||||
**/
|
||||
var BaseCommand = exports.BaseCommand = function BaseCommand() {
|
||||
};
|
||||
|
||||
var id = 1;
|
||||
BaseCommand.prototype.getRequestId = function getRequestId() {
|
||||
if (!this.requestId) this.requestId = id++;
|
||||
return this.requestId;
|
||||
};
|
||||
|
||||
BaseCommand.prototype.setMongosReadPreference = function setMongosReadPreference(readPreference, tags) {}
|
||||
|
||||
BaseCommand.prototype.updateRequestId = function() {
|
||||
this.requestId = id++;
|
||||
return this.requestId;
|
||||
};
|
||||
|
||||
// OpCodes
|
||||
BaseCommand.OP_REPLY = 1;
|
||||
BaseCommand.OP_MSG = 1000;
|
||||
BaseCommand.OP_UPDATE = 2001;
|
||||
BaseCommand.OP_INSERT = 2002;
|
||||
BaseCommand.OP_GET_BY_OID = 2003;
|
||||
BaseCommand.OP_QUERY = 2004;
|
||||
BaseCommand.OP_GET_MORE = 2005;
|
||||
BaseCommand.OP_DELETE = 2006;
|
||||
BaseCommand.OP_KILL_CURSORS = 2007;
|
||||
241
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/db_command.js
generated
vendored
Normal file
241
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/db_command.js
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
var QueryCommand = require('./query_command').QueryCommand,
|
||||
InsertCommand = require('./insert_command').InsertCommand,
|
||||
inherits = require('util').inherits,
|
||||
utils = require('../utils'),
|
||||
crypto = require('crypto');
|
||||
|
||||
/**
|
||||
Db Command
|
||||
**/
|
||||
var DbCommand = exports.DbCommand = function(dbInstance, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) {
|
||||
QueryCommand.call(this);
|
||||
this.collectionName = collectionName;
|
||||
this.queryOptions = queryOptions;
|
||||
this.numberToSkip = numberToSkip;
|
||||
this.numberToReturn = numberToReturn;
|
||||
this.query = query;
|
||||
this.returnFieldSelector = returnFieldSelector;
|
||||
this.db = dbInstance;
|
||||
|
||||
// Make sure we don't get a null exception
|
||||
options = options == null ? {} : options;
|
||||
// Let us defined on a command basis if we want functions to be serialized or not
|
||||
if(options['serializeFunctions'] != null && options['serializeFunctions']) {
|
||||
this.serializeFunctions = true;
|
||||
}
|
||||
};
|
||||
|
||||
inherits(DbCommand, QueryCommand);
|
||||
|
||||
// Constants
|
||||
DbCommand.SYSTEM_NAMESPACE_COLLECTION = "system.namespaces";
|
||||
DbCommand.SYSTEM_INDEX_COLLECTION = "system.indexes";
|
||||
DbCommand.SYSTEM_PROFILE_COLLECTION = "system.profile";
|
||||
DbCommand.SYSTEM_USER_COLLECTION = "system.users";
|
||||
DbCommand.SYSTEM_COMMAND_COLLECTION = "$cmd";
|
||||
DbCommand.SYSTEM_JS_COLLECTION = "system.js";
|
||||
|
||||
// New commands
|
||||
DbCommand.NcreateIsMasterCommand = function(db, databaseName) {
|
||||
return new DbCommand(db, databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null);
|
||||
};
|
||||
|
||||
// Provide constructors for different db commands
|
||||
DbCommand.createIsMasterCommand = function(db) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'ismaster':1}, null);
|
||||
};
|
||||
|
||||
DbCommand.createCollectionInfoCommand = function(db, selector) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_NAMESPACE_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, 0, selector, null);
|
||||
};
|
||||
|
||||
DbCommand.createGetNonceCommand = function(db, options) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getnonce':1}, null);
|
||||
};
|
||||
|
||||
DbCommand.createAuthenticationCommand = function(db, username, password, nonce, authdb) {
|
||||
// Use node md5 generator
|
||||
var md5 = crypto.createHash('md5');
|
||||
// Generate keys used for authentication
|
||||
md5.update(username + ":mongo:" + password);
|
||||
var hash_password = md5.digest('hex');
|
||||
// Final key
|
||||
md5 = crypto.createHash('md5');
|
||||
md5.update(nonce + username + hash_password);
|
||||
var key = md5.digest('hex');
|
||||
// Creat selector
|
||||
var selector = {'authenticate':1, 'user':username, 'nonce':nonce, 'key':key};
|
||||
// Create db command
|
||||
return new DbCommand(db, authdb + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NONE, 0, -1, selector, null);
|
||||
};
|
||||
|
||||
DbCommand.createLogoutCommand = function(db) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'logout':1}, null);
|
||||
};
|
||||
|
||||
DbCommand.createCreateCollectionCommand = function(db, collectionName, options) {
|
||||
var selector = {'create':collectionName};
|
||||
// Modify the options to ensure correct behaviour
|
||||
for(var name in options) {
|
||||
if(options[name] != null && options[name].constructor != Function) selector[name] = options[name];
|
||||
}
|
||||
// Execute the command
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, selector, null);
|
||||
};
|
||||
|
||||
DbCommand.createDropCollectionCommand = function(db, collectionName) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'drop':collectionName}, null);
|
||||
};
|
||||
|
||||
DbCommand.createRenameCollectionCommand = function(db, fromCollectionName, toCollectionName, options) {
|
||||
var renameCollection = db.databaseName + "." + fromCollectionName;
|
||||
var toCollection = db.databaseName + "." + toCollectionName;
|
||||
var dropTarget = options && options.dropTarget ? options.dropTarget : false;
|
||||
return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'renameCollection':renameCollection, 'to':toCollection, 'dropTarget':dropTarget}, null);
|
||||
};
|
||||
|
||||
DbCommand.createGetLastErrorCommand = function(options, db) {
|
||||
|
||||
if (typeof db === 'undefined') {
|
||||
db = options;
|
||||
options = {};
|
||||
}
|
||||
// Final command
|
||||
var command = {'getlasterror':1};
|
||||
// If we have an options Object let's merge in the fields (fsync/wtimeout/w)
|
||||
if('object' === typeof options) {
|
||||
for(var name in options) {
|
||||
command[name] = options[name]
|
||||
}
|
||||
}
|
||||
|
||||
// Special case for w == 1, remove the w
|
||||
if(1 == command.w) {
|
||||
delete command.w;
|
||||
}
|
||||
|
||||
// Execute command
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command, null);
|
||||
};
|
||||
|
||||
DbCommand.createGetLastStatusCommand = DbCommand.createGetLastErrorCommand;
|
||||
|
||||
DbCommand.createGetPreviousErrorsCommand = function(db) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'getpreverror':1}, null);
|
||||
};
|
||||
|
||||
DbCommand.createResetErrorHistoryCommand = function(db) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reseterror':1}, null);
|
||||
};
|
||||
|
||||
DbCommand.createCreateIndexCommand = function(db, collectionName, fieldOrSpec, options) {
|
||||
var fieldHash = {};
|
||||
var indexes = [];
|
||||
var keys;
|
||||
|
||||
// Get all the fields accordingly
|
||||
if('string' == typeof fieldOrSpec) {
|
||||
// 'type'
|
||||
indexes.push(fieldOrSpec + '_' + 1);
|
||||
fieldHash[fieldOrSpec] = 1;
|
||||
|
||||
} else if(utils.isArray(fieldOrSpec)) {
|
||||
|
||||
fieldOrSpec.forEach(function(f) {
|
||||
if('string' == typeof f) {
|
||||
// [{location:'2d'}, 'type']
|
||||
indexes.push(f + '_' + 1);
|
||||
fieldHash[f] = 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(utils.isObject(f)) {
|
||||
// [{location:'2d'}, {type:1}]
|
||||
keys = Object.keys(f);
|
||||
keys.forEach(function(k) {
|
||||
indexes.push(k + '_' + f[k]);
|
||||
fieldHash[k] = f[k];
|
||||
});
|
||||
} else {
|
||||
// undefined (ignore)
|
||||
}
|
||||
});
|
||||
|
||||
} else if(utils.isObject(fieldOrSpec)) {
|
||||
// {location:'2d', type:1}
|
||||
keys = Object.keys(fieldOrSpec);
|
||||
keys.forEach(function(key) {
|
||||
indexes.push(key + '_' + fieldOrSpec[key]);
|
||||
fieldHash[key] = fieldOrSpec[key];
|
||||
});
|
||||
}
|
||||
|
||||
// Generate the index name
|
||||
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;
|
||||
|
||||
// Set up options
|
||||
options = options == null || typeof options == 'boolean'
|
||||
? {}
|
||||
: options;
|
||||
|
||||
// Add all the options
|
||||
var keys = Object.keys(options);
|
||||
for(var i = 0; i < keys.length; i++) {
|
||||
selector[keys[i]] = options[keys[i]];
|
||||
}
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
DbCommand.logoutCommand = function(db, command_hash, options) {
|
||||
var dbName = options != null && options['authdb'] != null ? options['authdb'] : db.databaseName;
|
||||
// Create logout command
|
||||
return new DbCommand(db, dbName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null);
|
||||
}
|
||||
|
||||
DbCommand.createDropIndexCommand = function(db, collectionName, indexName) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'deleteIndexes':collectionName, 'index':indexName}, null);
|
||||
};
|
||||
|
||||
DbCommand.createReIndexCommand = function(db, collectionName) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'reIndex':collectionName}, null);
|
||||
};
|
||||
|
||||
DbCommand.createDropDatabaseCommand = function(db) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, {'dropDatabase':1}, null);
|
||||
};
|
||||
|
||||
DbCommand.createDbCommand = function(db, command_hash, options) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null, options);
|
||||
};
|
||||
|
||||
DbCommand.createAdminDbCommand = function(db, command_hash) {
|
||||
return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, command_hash, null);
|
||||
};
|
||||
|
||||
DbCommand.createAdminDbCommandSlaveOk = function(db, command_hash) {
|
||||
return new DbCommand(db, "admin." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null);
|
||||
};
|
||||
|
||||
DbCommand.createDbSlaveOkCommand = function(db, command_hash, options) {
|
||||
return new DbCommand(db, db.databaseName + "." + DbCommand.SYSTEM_COMMAND_COLLECTION, QueryCommand.OPTS_NO_CURSOR_TIMEOUT | QueryCommand.OPTS_SLAVE, 0, -1, command_hash, null, options);
|
||||
};
|
||||
114
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/delete_command.js
generated
vendored
Normal file
114
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/delete_command.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
var BaseCommand = require('./base_command').BaseCommand,
|
||||
inherits = require('util').inherits;
|
||||
|
||||
/**
|
||||
Insert Document Command
|
||||
**/
|
||||
var DeleteCommand = exports.DeleteCommand = function(db, collectionName, selector, flags) {
|
||||
BaseCommand.call(this);
|
||||
|
||||
// Validate correctness off the selector
|
||||
var object = selector;
|
||||
if(Buffer.isBuffer(object)) {
|
||||
var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
|
||||
if(object_size != object.length) {
|
||||
var error = new Error("delete raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
|
||||
error.name = 'MongoError';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
this.flags = flags;
|
||||
this.collectionName = collectionName;
|
||||
this.selector = selector;
|
||||
this.db = db;
|
||||
};
|
||||
|
||||
inherits(DeleteCommand, BaseCommand);
|
||||
|
||||
DeleteCommand.OP_DELETE = 2006;
|
||||
|
||||
/*
|
||||
struct {
|
||||
MsgHeader header; // standard message header
|
||||
int32 ZERO; // 0 - reserved for future use
|
||||
cstring fullCollectionName; // "dbname.collectionname"
|
||||
int32 ZERO; // 0 - reserved for future use
|
||||
mongo.BSON selector; // query object. See below for details.
|
||||
}
|
||||
*/
|
||||
DeleteCommand.prototype.toBinary = function() {
|
||||
// Calculate total length of the document
|
||||
var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.selector, false, true) + (4 * 4);
|
||||
// Let's build the single pass buffer command
|
||||
var _index = 0;
|
||||
var _command = new Buffer(totalLengthOfCommand);
|
||||
// Write the header information to the buffer
|
||||
_command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
|
||||
_command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
|
||||
_command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
|
||||
_command[_index] = totalLengthOfCommand & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write the request ID
|
||||
_command[_index + 3] = (this.requestId >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.requestId >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.requestId >> 8) & 0xff;
|
||||
_command[_index] = this.requestId & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
// Write the op_code for the command
|
||||
_command[_index + 3] = (DeleteCommand.OP_DELETE >> 24) & 0xff;
|
||||
_command[_index + 2] = (DeleteCommand.OP_DELETE >> 16) & 0xff;
|
||||
_command[_index + 1] = (DeleteCommand.OP_DELETE >> 8) & 0xff;
|
||||
_command[_index] = DeleteCommand.OP_DELETE & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
|
||||
// Write the collection name to the command
|
||||
_index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
|
||||
_command[_index - 1] = 0;
|
||||
|
||||
// Write the flags
|
||||
_command[_index + 3] = (this.flags >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.flags >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.flags >> 8) & 0xff;
|
||||
_command[_index] = this.flags & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Document binary length
|
||||
var documentLength = 0
|
||||
|
||||
// Serialize the selector
|
||||
// If we are passing a raw buffer, do minimal validation
|
||||
if(Buffer.isBuffer(this.selector)) {
|
||||
documentLength = this.selector.length;
|
||||
// Copy the data into the current buffer
|
||||
this.selector.copy(_command, _index);
|
||||
} else {
|
||||
documentLength = this.db.bson.serializeWithBufferAndIndex(this.selector, this.checkKeys, _command, _index) - _index + 1;
|
||||
}
|
||||
|
||||
// Write the length to the document
|
||||
_command[_index + 3] = (documentLength >> 24) & 0xff;
|
||||
_command[_index + 2] = (documentLength >> 16) & 0xff;
|
||||
_command[_index + 1] = (documentLength >> 8) & 0xff;
|
||||
_command[_index] = documentLength & 0xff;
|
||||
// Update index in buffer
|
||||
_index = _index + documentLength;
|
||||
// Add terminating 0 for the object
|
||||
_command[_index - 1] = 0;
|
||||
return _command;
|
||||
};
|
||||
83
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/get_more_command.js
generated
vendored
Normal file
83
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/get_more_command.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
var BaseCommand = require('./base_command').BaseCommand,
|
||||
inherits = require('util').inherits,
|
||||
binaryutils = require('../utils');
|
||||
|
||||
/**
|
||||
Get More Document Command
|
||||
**/
|
||||
var GetMoreCommand = exports.GetMoreCommand = function(db, collectionName, numberToReturn, cursorId) {
|
||||
BaseCommand.call(this);
|
||||
|
||||
this.collectionName = collectionName;
|
||||
this.numberToReturn = numberToReturn;
|
||||
this.cursorId = cursorId;
|
||||
this.db = db;
|
||||
};
|
||||
|
||||
inherits(GetMoreCommand, BaseCommand);
|
||||
|
||||
GetMoreCommand.OP_GET_MORE = 2005;
|
||||
|
||||
GetMoreCommand.prototype.toBinary = function() {
|
||||
// Calculate total length of the document
|
||||
var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 8 + (4 * 4);
|
||||
// Let's build the single pass buffer command
|
||||
var _index = 0;
|
||||
var _command = new Buffer(totalLengthOfCommand);
|
||||
// Write the header information to the buffer
|
||||
_command[_index++] = totalLengthOfCommand & 0xff;
|
||||
_command[_index++] = (totalLengthOfCommand >> 8) & 0xff;
|
||||
_command[_index++] = (totalLengthOfCommand >> 16) & 0xff;
|
||||
_command[_index++] = (totalLengthOfCommand >> 24) & 0xff;
|
||||
|
||||
// Write the request ID
|
||||
_command[_index++] = this.requestId & 0xff;
|
||||
_command[_index++] = (this.requestId >> 8) & 0xff;
|
||||
_command[_index++] = (this.requestId >> 16) & 0xff;
|
||||
_command[_index++] = (this.requestId >> 24) & 0xff;
|
||||
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
|
||||
// Write the op_code for the command
|
||||
_command[_index++] = GetMoreCommand.OP_GET_MORE & 0xff;
|
||||
_command[_index++] = (GetMoreCommand.OP_GET_MORE >> 8) & 0xff;
|
||||
_command[_index++] = (GetMoreCommand.OP_GET_MORE >> 16) & 0xff;
|
||||
_command[_index++] = (GetMoreCommand.OP_GET_MORE >> 24) & 0xff;
|
||||
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
|
||||
// Write the collection name to the command
|
||||
_index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
|
||||
_command[_index - 1] = 0;
|
||||
|
||||
// Number of documents to return
|
||||
_command[_index++] = this.numberToReturn & 0xff;
|
||||
_command[_index++] = (this.numberToReturn >> 8) & 0xff;
|
||||
_command[_index++] = (this.numberToReturn >> 16) & 0xff;
|
||||
_command[_index++] = (this.numberToReturn >> 24) & 0xff;
|
||||
|
||||
// Encode the cursor id
|
||||
var low_bits = this.cursorId.getLowBits();
|
||||
// Encode low bits
|
||||
_command[_index++] = low_bits & 0xff;
|
||||
_command[_index++] = (low_bits >> 8) & 0xff;
|
||||
_command[_index++] = (low_bits >> 16) & 0xff;
|
||||
_command[_index++] = (low_bits >> 24) & 0xff;
|
||||
|
||||
var high_bits = this.cursorId.getHighBits();
|
||||
// Encode high bits
|
||||
_command[_index++] = high_bits & 0xff;
|
||||
_command[_index++] = (high_bits >> 8) & 0xff;
|
||||
_command[_index++] = (high_bits >> 16) & 0xff;
|
||||
_command[_index++] = (high_bits >> 24) & 0xff;
|
||||
// Return command
|
||||
return _command;
|
||||
};
|
||||
147
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/insert_command.js
generated
vendored
Normal file
147
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/insert_command.js
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
var BaseCommand = require('./base_command').BaseCommand,
|
||||
inherits = require('util').inherits;
|
||||
|
||||
/**
|
||||
Insert Document Command
|
||||
**/
|
||||
var InsertCommand = exports.InsertCommand = function(db, collectionName, checkKeys, options) {
|
||||
BaseCommand.call(this);
|
||||
|
||||
this.collectionName = collectionName;
|
||||
this.documents = [];
|
||||
this.checkKeys = checkKeys == null ? true : checkKeys;
|
||||
this.db = db;
|
||||
this.flags = 0;
|
||||
this.serializeFunctions = false;
|
||||
|
||||
// Ensure valid options hash
|
||||
options = options == null ? {} : options;
|
||||
|
||||
// Check if we have keepGoing set -> set flag if it's the case
|
||||
if(options['keepGoing'] != null && options['keepGoing']) {
|
||||
// This will finish inserting all non-index violating documents even if it returns an error
|
||||
this.flags = 1;
|
||||
}
|
||||
|
||||
// Check if we have keepGoing set -> set flag if it's the case
|
||||
if(options['continueOnError'] != null && options['continueOnError']) {
|
||||
// This will finish inserting all non-index violating documents even if it returns an error
|
||||
this.flags = 1;
|
||||
}
|
||||
|
||||
// Let us defined on a command basis if we want functions to be serialized or not
|
||||
if(options['serializeFunctions'] != null && options['serializeFunctions']) {
|
||||
this.serializeFunctions = true;
|
||||
}
|
||||
};
|
||||
|
||||
inherits(InsertCommand, BaseCommand);
|
||||
|
||||
// OpCodes
|
||||
InsertCommand.OP_INSERT = 2002;
|
||||
|
||||
InsertCommand.prototype.add = function(document) {
|
||||
if(Buffer.isBuffer(document)) {
|
||||
var object_size = document[0] | document[1] << 8 | document[2] << 16 | document[3] << 24;
|
||||
if(object_size != document.length) {
|
||||
var error = new Error("insert raw message size does not match message header size [" + document.length + "] != [" + object_size + "]");
|
||||
error.name = 'MongoError';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
this.documents.push(document);
|
||||
return this;
|
||||
};
|
||||
|
||||
/*
|
||||
struct {
|
||||
MsgHeader header; // standard message header
|
||||
int32 ZERO; // 0 - reserved for future use
|
||||
cstring fullCollectionName; // "dbname.collectionname"
|
||||
BSON[] documents; // one or more documents to insert into the collection
|
||||
}
|
||||
*/
|
||||
InsertCommand.prototype.toBinary = function() {
|
||||
// Calculate total length of the document
|
||||
var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + (4 * 4);
|
||||
// var docLength = 0
|
||||
for(var i = 0; i < this.documents.length; i++) {
|
||||
if(Buffer.isBuffer(this.documents[i])) {
|
||||
totalLengthOfCommand += this.documents[i].length;
|
||||
} else {
|
||||
// Calculate size of document
|
||||
totalLengthOfCommand += this.db.bson.calculateObjectSize(this.documents[i], this.serializeFunctions, true);
|
||||
}
|
||||
}
|
||||
|
||||
// Let's build the single pass buffer command
|
||||
var _index = 0;
|
||||
var _command = new Buffer(totalLengthOfCommand);
|
||||
// Write the header information to the buffer
|
||||
_command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
|
||||
_command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
|
||||
_command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
|
||||
_command[_index] = totalLengthOfCommand & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write the request ID
|
||||
_command[_index + 3] = (this.requestId >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.requestId >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.requestId >> 8) & 0xff;
|
||||
_command[_index] = this.requestId & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
// Write the op_code for the command
|
||||
_command[_index + 3] = (InsertCommand.OP_INSERT >> 24) & 0xff;
|
||||
_command[_index + 2] = (InsertCommand.OP_INSERT >> 16) & 0xff;
|
||||
_command[_index + 1] = (InsertCommand.OP_INSERT >> 8) & 0xff;
|
||||
_command[_index] = InsertCommand.OP_INSERT & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write flags if any
|
||||
_command[_index + 3] = (this.flags >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.flags >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.flags >> 8) & 0xff;
|
||||
_command[_index] = this.flags & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write the collection name to the command
|
||||
_index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
|
||||
_command[_index - 1] = 0;
|
||||
|
||||
// Write all the bson documents to the buffer at the index offset
|
||||
for(var i = 0; i < this.documents.length; i++) {
|
||||
// Document binary length
|
||||
var documentLength = 0
|
||||
var object = this.documents[i];
|
||||
|
||||
// Serialize the selector
|
||||
// If we are passing a raw buffer, do minimal validation
|
||||
if(Buffer.isBuffer(object)) {
|
||||
documentLength = object.length;
|
||||
// Copy the data into the current buffer
|
||||
object.copy(_command, _index);
|
||||
} else {
|
||||
// Serialize the document straight to the buffer
|
||||
documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
|
||||
}
|
||||
|
||||
// Write the length to the document
|
||||
_command[_index + 3] = (documentLength >> 24) & 0xff;
|
||||
_command[_index + 2] = (documentLength >> 16) & 0xff;
|
||||
_command[_index + 1] = (documentLength >> 8) & 0xff;
|
||||
_command[_index] = documentLength & 0xff;
|
||||
// Update index in buffer
|
||||
_index = _index + documentLength;
|
||||
// Add terminating 0 for the object
|
||||
_command[_index - 1] = 0;
|
||||
}
|
||||
|
||||
return _command;
|
||||
};
|
||||
98
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js
generated
vendored
Normal file
98
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/kill_cursor_command.js
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
var BaseCommand = require('./base_command').BaseCommand,
|
||||
inherits = require('util').inherits,
|
||||
binaryutils = require('../utils');
|
||||
|
||||
/**
|
||||
Insert Document Command
|
||||
**/
|
||||
var KillCursorCommand = exports.KillCursorCommand = function(db, cursorIds) {
|
||||
BaseCommand.call(this);
|
||||
|
||||
this.cursorIds = cursorIds;
|
||||
this.db = db;
|
||||
};
|
||||
|
||||
inherits(KillCursorCommand, BaseCommand);
|
||||
|
||||
KillCursorCommand.OP_KILL_CURSORS = 2007;
|
||||
|
||||
/*
|
||||
struct {
|
||||
MsgHeader header; // standard message header
|
||||
int32 ZERO; // 0 - reserved for future use
|
||||
int32 numberOfCursorIDs; // number of cursorIDs in message
|
||||
int64[] cursorIDs; // array of cursorIDs to close
|
||||
}
|
||||
*/
|
||||
KillCursorCommand.prototype.toBinary = function() {
|
||||
// Calculate total length of the document
|
||||
var totalLengthOfCommand = 4 + 4 + (4 * 4) + (this.cursorIds.length * 8);
|
||||
// Let's build the single pass buffer command
|
||||
var _index = 0;
|
||||
var _command = new Buffer(totalLengthOfCommand);
|
||||
// Write the header information to the buffer
|
||||
_command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
|
||||
_command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
|
||||
_command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
|
||||
_command[_index] = totalLengthOfCommand & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write the request ID
|
||||
_command[_index + 3] = (this.requestId >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.requestId >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.requestId >> 8) & 0xff;
|
||||
_command[_index] = this.requestId & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
// Write the op_code for the command
|
||||
_command[_index + 3] = (KillCursorCommand.OP_KILL_CURSORS >> 24) & 0xff;
|
||||
_command[_index + 2] = (KillCursorCommand.OP_KILL_CURSORS >> 16) & 0xff;
|
||||
_command[_index + 1] = (KillCursorCommand.OP_KILL_CURSORS >> 8) & 0xff;
|
||||
_command[_index] = KillCursorCommand.OP_KILL_CURSORS & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
|
||||
// Number of cursors to kill
|
||||
var numberOfCursors = this.cursorIds.length;
|
||||
_command[_index + 3] = (numberOfCursors >> 24) & 0xff;
|
||||
_command[_index + 2] = (numberOfCursors >> 16) & 0xff;
|
||||
_command[_index + 1] = (numberOfCursors >> 8) & 0xff;
|
||||
_command[_index] = numberOfCursors & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Encode all the cursors
|
||||
for(var i = 0; i < this.cursorIds.length; i++) {
|
||||
// Encode the cursor id
|
||||
var low_bits = this.cursorIds[i].getLowBits();
|
||||
// Encode low bits
|
||||
_command[_index + 3] = (low_bits >> 24) & 0xff;
|
||||
_command[_index + 2] = (low_bits >> 16) & 0xff;
|
||||
_command[_index + 1] = (low_bits >> 8) & 0xff;
|
||||
_command[_index] = low_bits & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
var high_bits = this.cursorIds[i].getHighBits();
|
||||
// Encode high bits
|
||||
_command[_index + 3] = (high_bits >> 24) & 0xff;
|
||||
_command[_index + 2] = (high_bits >> 16) & 0xff;
|
||||
_command[_index + 1] = (high_bits >> 8) & 0xff;
|
||||
_command[_index] = high_bits & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
}
|
||||
|
||||
return _command;
|
||||
};
|
||||
261
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/query_command.js
generated
vendored
Normal file
261
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/query_command.js
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
||||
var BaseCommand = require('./base_command').BaseCommand,
|
||||
inherits = require('util').inherits;
|
||||
|
||||
/**
|
||||
Insert Document Command
|
||||
**/
|
||||
var QueryCommand = exports.QueryCommand = function(db, collectionName, queryOptions, numberToSkip, numberToReturn, query, returnFieldSelector, options) {
|
||||
BaseCommand.call(this);
|
||||
|
||||
// Validate correctness off the selector
|
||||
var object = query,
|
||||
object_size;
|
||||
if(Buffer.isBuffer(object)) {
|
||||
object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
|
||||
if(object_size != object.length) {
|
||||
var error = new Error("query selector raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
|
||||
error.name = 'MongoError';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
object = returnFieldSelector;
|
||||
if(Buffer.isBuffer(object)) {
|
||||
object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
|
||||
if(object_size != object.length) {
|
||||
var error = new Error("query fields raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
|
||||
error.name = 'MongoError';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we don't get a null exception
|
||||
options = options == null ? {} : options;
|
||||
// Set up options
|
||||
this.collectionName = collectionName;
|
||||
this.queryOptions = queryOptions;
|
||||
this.numberToSkip = numberToSkip;
|
||||
this.numberToReturn = numberToReturn;
|
||||
|
||||
// Ensure we have no null query
|
||||
query = query == null ? {} : query;
|
||||
// Wrap query in the $query parameter so we can add read preferences for mongos
|
||||
this.query = query;
|
||||
this.returnFieldSelector = returnFieldSelector;
|
||||
this.db = db;
|
||||
|
||||
// Let us defined on a command basis if we want functions to be serialized or not
|
||||
if(options['serializeFunctions'] != null && options['serializeFunctions']) {
|
||||
this.serializeFunctions = true;
|
||||
}
|
||||
};
|
||||
|
||||
inherits(QueryCommand, BaseCommand);
|
||||
|
||||
QueryCommand.OP_QUERY = 2004;
|
||||
|
||||
/*
|
||||
* Adds the read prefrence to the current command
|
||||
*/
|
||||
QueryCommand.prototype.setMongosReadPreference = function(readPreference, tags) {
|
||||
// If we have readPreference set to true set to secondary prefered
|
||||
if(readPreference == true) {
|
||||
readPreference = 'secondaryPreferred';
|
||||
} else if(readPreference == 'false') {
|
||||
readPreference = 'primary';
|
||||
}
|
||||
|
||||
// Force the slave ok flag to be set if we are not using primary read preference
|
||||
if(readPreference != false && readPreference != 'primary') {
|
||||
this.queryOptions |= QueryCommand.OPTS_SLAVE;
|
||||
}
|
||||
|
||||
// Backward compatibility, ensure $query only set on read preference so 1.8.X works
|
||||
if((readPreference != null || tags != null) && this.query['$query'] == null) {
|
||||
this.query = {'$query': this.query};
|
||||
}
|
||||
|
||||
// If we have no readPreference set and no tags, check if the slaveOk bit is set
|
||||
if(readPreference == null && tags == null) {
|
||||
// If we have a slaveOk bit set the read preference for MongoS
|
||||
if(this.queryOptions & QueryCommand.OPTS_SLAVE) {
|
||||
this.query['$readPreference'] = {mode: 'secondary'}
|
||||
} else {
|
||||
this.query['$readPreference'] = {mode: 'primary'}
|
||||
}
|
||||
}
|
||||
|
||||
// Build read preference object
|
||||
if(typeof readPreference == 'object' && readPreference['_type'] == 'ReadPreference') {
|
||||
this.query['$readPreference'] = readPreference.toObject();
|
||||
} else if(readPreference != null) {
|
||||
// Add the read preference
|
||||
this.query['$readPreference'] = {mode: readPreference};
|
||||
|
||||
// If we have tags let's add them
|
||||
if(tags != null) {
|
||||
this.query['$readPreference']['tags'] = tags;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
struct {
|
||||
MsgHeader header; // standard message header
|
||||
int32 opts; // query options. See below for details.
|
||||
cstring fullCollectionName; // "dbname.collectionname"
|
||||
int32 numberToSkip; // number of documents to skip when returning results
|
||||
int32 numberToReturn; // number of documents to return in the first OP_REPLY
|
||||
BSON query ; // query object. See below for details.
|
||||
[ BSON returnFieldSelector; ] // OPTIONAL : selector indicating the fields to return. See below for details.
|
||||
}
|
||||
*/
|
||||
QueryCommand.prototype.toBinary = function() {
|
||||
// Total length of the command
|
||||
var totalLengthOfCommand = 0;
|
||||
// Calculate total length of the document
|
||||
if(Buffer.isBuffer(this.query)) {
|
||||
totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.query.length + (4 * 4);
|
||||
} else {
|
||||
totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + 4 + this.db.bson.calculateObjectSize(this.query, this.serializeFunctions, true) + (4 * 4);
|
||||
}
|
||||
|
||||
// Calculate extra fields size
|
||||
if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) {
|
||||
if(Object.keys(this.returnFieldSelector).length > 0) {
|
||||
totalLengthOfCommand += this.db.bson.calculateObjectSize(this.returnFieldSelector, this.serializeFunctions, true);
|
||||
}
|
||||
} else if(Buffer.isBuffer(this.returnFieldSelector)) {
|
||||
totalLengthOfCommand += this.returnFieldSelector.length;
|
||||
}
|
||||
|
||||
// Let's build the single pass buffer command
|
||||
var _index = 0;
|
||||
var _command = new Buffer(totalLengthOfCommand);
|
||||
// Write the header information to the buffer
|
||||
_command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
|
||||
_command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
|
||||
_command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
|
||||
_command[_index] = totalLengthOfCommand & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write the request ID
|
||||
_command[_index + 3] = (this.requestId >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.requestId >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.requestId >> 8) & 0xff;
|
||||
_command[_index] = this.requestId & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
// Write the op_code for the command
|
||||
_command[_index + 3] = (QueryCommand.OP_QUERY >> 24) & 0xff;
|
||||
_command[_index + 2] = (QueryCommand.OP_QUERY >> 16) & 0xff;
|
||||
_command[_index + 1] = (QueryCommand.OP_QUERY >> 8) & 0xff;
|
||||
_command[_index] = QueryCommand.OP_QUERY & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Write the query options
|
||||
_command[_index + 3] = (this.queryOptions >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.queryOptions >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.queryOptions >> 8) & 0xff;
|
||||
_command[_index] = this.queryOptions & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Write the collection name to the command
|
||||
_index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
|
||||
_command[_index - 1] = 0;
|
||||
|
||||
// Write the number of documents to skip
|
||||
_command[_index + 3] = (this.numberToSkip >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.numberToSkip >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.numberToSkip >> 8) & 0xff;
|
||||
_command[_index] = this.numberToSkip & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Write the number of documents to return
|
||||
_command[_index + 3] = (this.numberToReturn >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.numberToReturn >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.numberToReturn >> 8) & 0xff;
|
||||
_command[_index] = this.numberToReturn & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Document binary length
|
||||
var documentLength = 0
|
||||
var object = this.query;
|
||||
|
||||
// Serialize the selector
|
||||
if(Buffer.isBuffer(object)) {
|
||||
documentLength = object.length;
|
||||
// Copy the data into the current buffer
|
||||
object.copy(_command, _index);
|
||||
} else {
|
||||
// Serialize the document straight to the buffer
|
||||
documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
|
||||
}
|
||||
|
||||
// Write the length to the document
|
||||
_command[_index + 3] = (documentLength >> 24) & 0xff;
|
||||
_command[_index + 2] = (documentLength >> 16) & 0xff;
|
||||
_command[_index + 1] = (documentLength >> 8) & 0xff;
|
||||
_command[_index] = documentLength & 0xff;
|
||||
// Update index in buffer
|
||||
_index = _index + documentLength;
|
||||
// Add terminating 0 for the object
|
||||
_command[_index - 1] = 0;
|
||||
|
||||
// Push field selector if available
|
||||
if(this.returnFieldSelector != null && !(Buffer.isBuffer(this.returnFieldSelector))) {
|
||||
if(Object.keys(this.returnFieldSelector).length > 0) {
|
||||
var documentLength = this.db.bson.serializeWithBufferAndIndex(this.returnFieldSelector, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
|
||||
// Write the length to the document
|
||||
_command[_index + 3] = (documentLength >> 24) & 0xff;
|
||||
_command[_index + 2] = (documentLength >> 16) & 0xff;
|
||||
_command[_index + 1] = (documentLength >> 8) & 0xff;
|
||||
_command[_index] = documentLength & 0xff;
|
||||
// Update index in buffer
|
||||
_index = _index + documentLength;
|
||||
// Add terminating 0 for the object
|
||||
_command[_index - 1] = 0;
|
||||
}
|
||||
} if(this.returnFieldSelector != null && Buffer.isBuffer(this.returnFieldSelector)) {
|
||||
// Document binary length
|
||||
var documentLength = 0
|
||||
var object = this.returnFieldSelector;
|
||||
|
||||
// Serialize the selector
|
||||
documentLength = object.length;
|
||||
// Copy the data into the current buffer
|
||||
object.copy(_command, _index);
|
||||
|
||||
// Write the length to the document
|
||||
_command[_index + 3] = (documentLength >> 24) & 0xff;
|
||||
_command[_index + 2] = (documentLength >> 16) & 0xff;
|
||||
_command[_index + 1] = (documentLength >> 8) & 0xff;
|
||||
_command[_index] = documentLength & 0xff;
|
||||
// Update index in buffer
|
||||
_index = _index + documentLength;
|
||||
// Add terminating 0 for the object
|
||||
_command[_index - 1] = 0;
|
||||
}
|
||||
|
||||
// Return finished command
|
||||
return _command;
|
||||
};
|
||||
|
||||
// Constants
|
||||
QueryCommand.OPTS_NONE = 0;
|
||||
QueryCommand.OPTS_TAILABLE_CURSOR = 2;
|
||||
QueryCommand.OPTS_SLAVE = 4;
|
||||
QueryCommand.OPTS_OPLOG_REPLY = 8;
|
||||
QueryCommand.OPTS_NO_CURSOR_TIMEOUT = 16;
|
||||
QueryCommand.OPTS_AWAIT_DATA = 32;
|
||||
QueryCommand.OPTS_EXHAUST = 64;
|
||||
QueryCommand.OPTS_PARTIAL = 128;
|
||||
174
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/update_command.js
generated
vendored
Normal file
174
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/commands/update_command.js
generated
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
var BaseCommand = require('./base_command').BaseCommand,
|
||||
inherits = require('util').inherits;
|
||||
|
||||
/**
|
||||
Update Document Command
|
||||
**/
|
||||
var UpdateCommand = exports.UpdateCommand = function(db, collectionName, spec, document, options) {
|
||||
BaseCommand.call(this);
|
||||
|
||||
var object = spec;
|
||||
if(Buffer.isBuffer(object)) {
|
||||
var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
|
||||
if(object_size != object.length) {
|
||||
var error = new Error("update spec raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
|
||||
error.name = 'MongoError';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
var object = document;
|
||||
if(Buffer.isBuffer(object)) {
|
||||
var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
|
||||
if(object_size != object.length) {
|
||||
var error = new Error("update document raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
|
||||
error.name = 'MongoError';
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
this.collectionName = collectionName;
|
||||
this.spec = spec;
|
||||
this.document = document;
|
||||
this.db = db;
|
||||
this.serializeFunctions = false;
|
||||
|
||||
// Generate correct flags
|
||||
var db_upsert = 0;
|
||||
var db_multi_update = 0;
|
||||
db_upsert = options != null && options['upsert'] != null ? (options['upsert'] == true ? 1 : 0) : db_upsert;
|
||||
db_multi_update = options != null && options['multi'] != null ? (options['multi'] == true ? 1 : 0) : db_multi_update;
|
||||
|
||||
// Flags
|
||||
this.flags = parseInt(db_multi_update.toString() + db_upsert.toString(), 2);
|
||||
// Let us defined on a command basis if we want functions to be serialized or not
|
||||
if(options['serializeFunctions'] != null && options['serializeFunctions']) {
|
||||
this.serializeFunctions = true;
|
||||
}
|
||||
};
|
||||
|
||||
inherits(UpdateCommand, BaseCommand);
|
||||
|
||||
UpdateCommand.OP_UPDATE = 2001;
|
||||
|
||||
/*
|
||||
struct {
|
||||
MsgHeader header; // standard message header
|
||||
int32 ZERO; // 0 - reserved for future use
|
||||
cstring fullCollectionName; // "dbname.collectionname"
|
||||
int32 flags; // bit vector. see below
|
||||
BSON spec; // the query to select the document
|
||||
BSON document; // the document data to update with or insert
|
||||
}
|
||||
*/
|
||||
UpdateCommand.prototype.toBinary = function() {
|
||||
// Calculate total length of the document
|
||||
var totalLengthOfCommand = 4 + Buffer.byteLength(this.collectionName) + 1 + 4 + this.db.bson.calculateObjectSize(this.spec, false, true) +
|
||||
this.db.bson.calculateObjectSize(this.document, this.serializeFunctions, true) + (4 * 4);
|
||||
|
||||
// Let's build the single pass buffer command
|
||||
var _index = 0;
|
||||
var _command = new Buffer(totalLengthOfCommand);
|
||||
// Write the header information to the buffer
|
||||
_command[_index + 3] = (totalLengthOfCommand >> 24) & 0xff;
|
||||
_command[_index + 2] = (totalLengthOfCommand >> 16) & 0xff;
|
||||
_command[_index + 1] = (totalLengthOfCommand >> 8) & 0xff;
|
||||
_command[_index] = totalLengthOfCommand & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write the request ID
|
||||
_command[_index + 3] = (this.requestId >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.requestId >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.requestId >> 8) & 0xff;
|
||||
_command[_index] = this.requestId & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
// Write the op_code for the command
|
||||
_command[_index + 3] = (UpdateCommand.OP_UPDATE >> 24) & 0xff;
|
||||
_command[_index + 2] = (UpdateCommand.OP_UPDATE >> 16) & 0xff;
|
||||
_command[_index + 1] = (UpdateCommand.OP_UPDATE >> 8) & 0xff;
|
||||
_command[_index] = UpdateCommand.OP_UPDATE & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Write zero
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
_command[_index++] = 0;
|
||||
|
||||
// Write the collection name to the command
|
||||
_index = _index + _command.write(this.collectionName, _index, 'utf8') + 1;
|
||||
_command[_index - 1] = 0;
|
||||
|
||||
// Write the update flags
|
||||
_command[_index + 3] = (this.flags >> 24) & 0xff;
|
||||
_command[_index + 2] = (this.flags >> 16) & 0xff;
|
||||
_command[_index + 1] = (this.flags >> 8) & 0xff;
|
||||
_command[_index] = this.flags & 0xff;
|
||||
// Adjust index
|
||||
_index = _index + 4;
|
||||
|
||||
// Document binary length
|
||||
var documentLength = 0
|
||||
var object = this.spec;
|
||||
|
||||
// Serialize the selector
|
||||
// If we are passing a raw buffer, do minimal validation
|
||||
if(Buffer.isBuffer(object)) {
|
||||
var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
|
||||
if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
|
||||
documentLength = object.length;
|
||||
// Copy the data into the current buffer
|
||||
object.copy(_command, _index);
|
||||
} else {
|
||||
documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, false) - _index + 1;
|
||||
}
|
||||
|
||||
// Write the length to the document
|
||||
_command[_index + 3] = (documentLength >> 24) & 0xff;
|
||||
_command[_index + 2] = (documentLength >> 16) & 0xff;
|
||||
_command[_index + 1] = (documentLength >> 8) & 0xff;
|
||||
_command[_index] = documentLength & 0xff;
|
||||
// Update index in buffer
|
||||
_index = _index + documentLength;
|
||||
// Add terminating 0 for the object
|
||||
_command[_index - 1] = 0;
|
||||
|
||||
// Document binary length
|
||||
var documentLength = 0
|
||||
var object = this.document;
|
||||
|
||||
// Serialize the document
|
||||
// If we are passing a raw buffer, do minimal validation
|
||||
if(Buffer.isBuffer(object)) {
|
||||
var object_size = object[0] | object[1] << 8 | object[2] << 16 | object[3] << 24;
|
||||
if(object_size != object.length) throw new Error("raw message size does not match message header size [" + object.length + "] != [" + object_size + "]");
|
||||
documentLength = object.length;
|
||||
// Copy the data into the current buffer
|
||||
object.copy(_command, _index);
|
||||
} else {
|
||||
documentLength = this.db.bson.serializeWithBufferAndIndex(object, this.checkKeys, _command, _index, this.serializeFunctions) - _index + 1;
|
||||
}
|
||||
|
||||
// Write the length to the document
|
||||
_command[_index + 3] = (documentLength >> 24) & 0xff;
|
||||
_command[_index + 2] = (documentLength >> 16) & 0xff;
|
||||
_command[_index + 1] = (documentLength >> 8) & 0xff;
|
||||
_command[_index] = documentLength & 0xff;
|
||||
// Update index in buffer
|
||||
_index = _index + documentLength;
|
||||
// Add terminating 0 for the object
|
||||
_command[_index - 1] = 0;
|
||||
|
||||
return _command;
|
||||
};
|
||||
|
||||
// Constants
|
||||
UpdateCommand.DB_UPSERT = 0;
|
||||
UpdateCommand.DB_MULTI_UPDATE = 1;
|
||||
169
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/base.js
generated
vendored
Normal file
169
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/base.js
generated
vendored
Normal file
@@ -0,0 +1,169 @@
|
||||
var EventEmitter = require('events').EventEmitter
|
||||
, inherits = require('util').inherits;
|
||||
|
||||
/**
|
||||
* Internal class for callback storage
|
||||
* @ignore
|
||||
*/
|
||||
var CallbackStore = function() {
|
||||
// Make class an event emitter
|
||||
EventEmitter.call(this);
|
||||
// Add a info about call variable
|
||||
this._notReplied = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
inherits(CallbackStore, EventEmitter);
|
||||
|
||||
var Base = function Base() {
|
||||
EventEmitter.call(this);
|
||||
|
||||
// Callback store is part of connection specification
|
||||
if(Base._callBackStore == null) {
|
||||
Base._callBackStore = new CallbackStore();
|
||||
}
|
||||
|
||||
// this._callBackStore = Base._callBackStore;
|
||||
this._callBackStore = new CallbackStore();
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
inherits(Base, EventEmitter);
|
||||
|
||||
/**
|
||||
* Fire all the errors
|
||||
* @ignore
|
||||
*/
|
||||
Base.prototype.__executeAllCallbacksWithError = function(err) {
|
||||
// Check all callbacks
|
||||
var keys = Object.keys(this._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 = this._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();
|
||||
// Emit only the last event
|
||||
this._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 this._callBackStore._notReplied[chained[i]];
|
||||
}
|
||||
} else {
|
||||
this._callBackStore.emit(keys[j], err, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a handler
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
Base.prototype._registerHandler = function(db_command, raw, connection, exhaust, callback) {
|
||||
// If we have an array of commands, chain them
|
||||
var chained = Array.isArray(db_command);
|
||||
|
||||
// Check if we have exhausted
|
||||
if(typeof exhaust == 'function') {
|
||||
callback = exhaust;
|
||||
exhaust = false;
|
||||
}
|
||||
|
||||
// If they are chained we need to add a special handler situation
|
||||
if(chained) {
|
||||
// List off chained id's
|
||||
var chainedIds = [];
|
||||
// Add all id's
|
||||
for(var i = 0; i < db_command.length; i++) chainedIds.push(db_command[i].getRequestId().toString());
|
||||
// Register all the commands together
|
||||
for(var i = 0; i < db_command.length; i++) {
|
||||
var command = db_command[i];
|
||||
// Add the callback to the store
|
||||
this._callBackStore.once(command.getRequestId(), callback);
|
||||
// Add the information about the reply
|
||||
this._callBackStore._notReplied[command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, chained:chainedIds, connection:connection, exhaust:false};
|
||||
}
|
||||
} else {
|
||||
// Add the callback to the list of handlers
|
||||
this._callBackStore.once(db_command.getRequestId(), callback);
|
||||
// Add the information about the reply
|
||||
this._callBackStore._notReplied[db_command.getRequestId().toString()] = {start: new Date().getTime(), 'raw': raw, connection:connection, exhaust:exhaust};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-Register a handler, on the cursor id f.ex
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
Base.prototype._reRegisterHandler = function(newId, object, callback) {
|
||||
// Add the callback to the list of handlers
|
||||
this._callBackStore.once(newId, object.callback.listener);
|
||||
// Add the information about the reply
|
||||
this._callBackStore._notReplied[newId] = object.info;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
Base.prototype._callHandler = function(id, document, err) {
|
||||
// If there is a callback peform it
|
||||
if(this._callBackStore.listeners(id).length >= 1) {
|
||||
// Get info object
|
||||
var info = this._callBackStore._notReplied[id];
|
||||
// Delete the current object
|
||||
delete this._callBackStore._notReplied[id];
|
||||
// Emit to the callback of the object
|
||||
this._callBackStore.emit(id, err, document, info.connection);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
Base.prototype._hasHandler = function(id) {
|
||||
// If there is a callback peform it
|
||||
return this._callBackStore.listeners(id).length >= 1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
Base.prototype._removeHandler = function(id) {
|
||||
// Remove the information
|
||||
if(this._callBackStore._notReplied[id] != null) delete this._callBackStore._notReplied[id];
|
||||
// Remove the callback if it's registered
|
||||
this._callBackStore.removeAllListeners(id);
|
||||
// Force cleanup _events, node.js seems to set it as a null value
|
||||
if(this._callBackStore._events != null) delete this._callBackStore._events[id];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
Base.prototype._findHandler = function(id) {
|
||||
var info = this._callBackStore._notReplied[id];
|
||||
// Return the callback
|
||||
return {info:info, callback:(this._callBackStore.listeners(id).length >= 1) ? this._callBackStore.listeners(id)[0] : null}
|
||||
}
|
||||
|
||||
exports.Base = Base;
|
||||
504
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/connection.js
generated
vendored
Normal file
504
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/connection.js
generated
vendored
Normal file
@@ -0,0 +1,504 @@
|
||||
var utils = require('./connection_utils'),
|
||||
inherits = require('util').inherits,
|
||||
net = require('net'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
inherits = require('util').inherits,
|
||||
binaryutils = require('../utils'),
|
||||
tls = require('tls');
|
||||
|
||||
var Connection = exports.Connection = function(id, socketOptions) {
|
||||
// Set up event emitter
|
||||
EventEmitter.call(this);
|
||||
// Store all socket options
|
||||
this.socketOptions = socketOptions ? socketOptions : {host:'localhost', port:27017, domainSocket:false};
|
||||
// Set keep alive default if not overriden
|
||||
if(this.socketOptions.keepAlive == null && (process.platform !== "sunos" || process.platform !== "win32")) this.socketOptions.keepAlive = 100;
|
||||
// Id for the connection
|
||||
this.id = id;
|
||||
// State of the connection
|
||||
this.connected = false;
|
||||
// Set if this is a domain socket
|
||||
this.domainSocket = this.socketOptions.domainSocket;
|
||||
|
||||
//
|
||||
// Connection parsing state
|
||||
//
|
||||
this.maxBsonSize = socketOptions.maxBsonSize ? socketOptions.maxBsonSize : Connection.DEFAULT_MAX_BSON_SIZE;
|
||||
this.maxMessageSizeBytes = socketOptions.maxMessageSizeBytes ? socketOptions.maxMessageSizeBytes : Connection.DEFAULT_MAX_MESSAGE_SIZE;
|
||||
// Contains the current message bytes
|
||||
this.buffer = null;
|
||||
// Contains the current message size
|
||||
this.sizeOfMessage = 0;
|
||||
// Contains the readIndex for the messaage
|
||||
this.bytesRead = 0;
|
||||
// Contains spill over bytes from additional messages
|
||||
this.stubBuffer = 0;
|
||||
|
||||
// Just keeps list of events we allow
|
||||
this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[], end:[]};
|
||||
|
||||
// Just keeps list of events we allow
|
||||
resetHandlers(this, false);
|
||||
}
|
||||
|
||||
// Set max bson size
|
||||
Connection.DEFAULT_MAX_BSON_SIZE = 1024 * 1024 * 4;
|
||||
// Set default to max bson to avoid overflow or bad guesses
|
||||
Connection.DEFAULT_MAX_MESSAGE_SIZE = Connection.DEFAULT_MAX_BSON_SIZE;
|
||||
|
||||
// Inherit event emitter so we can emit stuff wohoo
|
||||
inherits(Connection, EventEmitter);
|
||||
|
||||
Connection.prototype.start = function() {
|
||||
var self = this;
|
||||
|
||||
// If we have a normal connection
|
||||
if(this.socketOptions.ssl) {
|
||||
// Create new connection instance
|
||||
if(this.domainSocket) {
|
||||
this.connection = net.createConnection(this.socketOptions.host);
|
||||
} else {
|
||||
this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host);
|
||||
}
|
||||
if(this.logger != null && this.logger.doDebug){
|
||||
this.logger.debug("opened connection", this.socketOptions);
|
||||
}
|
||||
// Set options on the socket
|
||||
this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout);
|
||||
// Work around for 0.4.X
|
||||
if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay);
|
||||
// Set keep alive if defined
|
||||
if(process.version.indexOf("v0.4") == -1) {
|
||||
if(this.socketOptions.keepAlive > 0) {
|
||||
this.connection.setKeepAlive(true, this.socketOptions.keepAlive);
|
||||
} else {
|
||||
this.connection.setKeepAlive(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the driver should validate the certificate
|
||||
var validate_certificates = this.socketOptions.sslValidate == true ? true : false;
|
||||
|
||||
// Create options for the tls connection
|
||||
var tls_options = {
|
||||
socket: this.connection
|
||||
, rejectUnauthorized: false
|
||||
}
|
||||
|
||||
// If we wish to validate the certificate we have provided a ca store
|
||||
if(validate_certificates) {
|
||||
tls_options.ca = this.socketOptions.sslCA;
|
||||
}
|
||||
|
||||
// If we have a certificate to present
|
||||
if(this.socketOptions.sslCert) {
|
||||
tls_options.cert = this.socketOptions.sslCert;
|
||||
tls_options.key = this.socketOptions.sslKey;
|
||||
}
|
||||
|
||||
// If the driver has been provided a private key password
|
||||
if(this.socketOptions.sslPass) {
|
||||
tls_options.passphrase = this.socketOptions.sslPass;
|
||||
}
|
||||
|
||||
// Contains the cleartext stream
|
||||
var cleartext = null;
|
||||
// Attempt to establish a TLS connection to the server
|
||||
try {
|
||||
cleartext = tls.connect(this.socketOptions.port, this.socketOptions.host, tls_options, function() {
|
||||
// If we have a ssl certificate validation error return an error
|
||||
if(cleartext.authorizationError && validate_certificates) {
|
||||
// Emit an error
|
||||
return self.emit("error", cleartext.authorizationError, self, {ssl:true});
|
||||
}
|
||||
|
||||
// Connect to the server
|
||||
connectHandler(self)();
|
||||
})
|
||||
} catch(err) {
|
||||
return self.emit("error", "SSL connection failed", self, {ssl:true});
|
||||
}
|
||||
|
||||
// Save the output stream
|
||||
this.writeSteam = cleartext;
|
||||
|
||||
// Set up data handler for the clear stream
|
||||
cleartext.on("data", createDataHandler(this));
|
||||
// Do any handling of end event of the stream
|
||||
cleartext.on("end", endHandler(this));
|
||||
cleartext.on("error", errorHandler(this));
|
||||
|
||||
// Handle any errors
|
||||
this.connection.on("error", errorHandler(this));
|
||||
// Handle timeout
|
||||
this.connection.on("timeout", timeoutHandler(this));
|
||||
// Handle drain event
|
||||
this.connection.on("drain", drainHandler(this));
|
||||
// Handle the close event
|
||||
this.connection.on("close", closeHandler(this));
|
||||
} else {
|
||||
// Create new connection instance
|
||||
if(this.domainSocket) {
|
||||
this.connection = net.createConnection(this.socketOptions.host);
|
||||
} else {
|
||||
this.connection = net.createConnection(this.socketOptions.port, this.socketOptions.host);
|
||||
}
|
||||
if(this.logger != null && this.logger.doDebug){
|
||||
this.logger.debug("opened connection", this.socketOptions);
|
||||
}
|
||||
|
||||
// Set options on the socket
|
||||
this.connection.setTimeout(this.socketOptions.connectTimeoutMS != null ? this.socketOptions.connectTimeoutMS : this.socketOptions.timeout);
|
||||
// Work around for 0.4.X
|
||||
if(process.version.indexOf("v0.4") == -1) this.connection.setNoDelay(this.socketOptions.noDelay);
|
||||
// Set keep alive if defined
|
||||
if(process.version.indexOf("v0.4") == -1) {
|
||||
if(this.socketOptions.keepAlive > 0) {
|
||||
this.connection.setKeepAlive(true, this.socketOptions.keepAlive);
|
||||
} else {
|
||||
this.connection.setKeepAlive(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Set up write stream
|
||||
this.writeSteam = this.connection;
|
||||
// Add handlers
|
||||
this.connection.on("error", errorHandler(this));
|
||||
// Add all handlers to the socket to manage it
|
||||
this.connection.on("connect", connectHandler(this));
|
||||
// this.connection.on("end", endHandler(this));
|
||||
this.connection.on("data", createDataHandler(this));
|
||||
this.connection.on("timeout", timeoutHandler(this));
|
||||
this.connection.on("drain", drainHandler(this));
|
||||
this.connection.on("close", closeHandler(this));
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the sockets are live
|
||||
Connection.prototype.isConnected = function() {
|
||||
return this.connected && !this.connection.destroyed && this.connection.writable && this.connection.readable;
|
||||
}
|
||||
|
||||
// Write the data out to the socket
|
||||
Connection.prototype.write = function(command, callback) {
|
||||
try {
|
||||
// If we have a list off commands to be executed on the same socket
|
||||
if(Array.isArray(command)) {
|
||||
for(var i = 0; i < command.length; i++) {
|
||||
var binaryCommand = command[i].toBinary()
|
||||
|
||||
if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize)
|
||||
return callback(new Error("Document exceeds maximum allowed bson size of " + this.maxBsonSize + " bytes"));
|
||||
|
||||
if(this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxMessageSizeBytes) {
|
||||
return callback(new Error("Command exceeds maximum message size of " + this.maxMessageSizeBytes + " bytes"));
|
||||
}
|
||||
|
||||
if(this.logger != null && this.logger.doDebug)
|
||||
this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command[i]});
|
||||
|
||||
var r = this.writeSteam.write(binaryCommand);
|
||||
}
|
||||
} else {
|
||||
var binaryCommand = command.toBinary()
|
||||
|
||||
if(!this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxBsonSize)
|
||||
return callback(new Error("Document exceeds maximum allowed bson size of " + this.maxBsonSize + " bytes"));
|
||||
|
||||
if(this.socketOptions['disableDriverBSONSizeCheck'] && binaryCommand.length > this.maxMessageSizeBytes) {
|
||||
return callback(new Error("Command exceeds maximum message size of " + this.maxMessageSizeBytes + " bytes"));
|
||||
}
|
||||
|
||||
if(this.logger != null && this.logger.doDebug)
|
||||
this.logger.debug("writing command to mongodb", {binary: binaryCommand, json: command});
|
||||
|
||||
var r = this.writeSteam.write(binaryCommand);
|
||||
}
|
||||
} catch (err) {
|
||||
if(typeof callback === 'function') callback(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Force the closure of the connection
|
||||
Connection.prototype.close = function() {
|
||||
// clear out all the listeners
|
||||
resetHandlers(this, true);
|
||||
// Add a dummy error listener to catch any weird last moment errors (and ignore them)
|
||||
this.connection.on("error", function() {})
|
||||
// destroy connection
|
||||
this.connection.destroy();
|
||||
if(this.logger != null && this.logger.doDebug){
|
||||
this.logger.debug("closed connection", this.connection);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset all handlers
|
||||
var resetHandlers = function(self, clearListeners) {
|
||||
self.eventHandlers = {error:[], connect:[], close:[], end:[], timeout:[], parseError:[], message:[]};
|
||||
|
||||
// If we want to clear all the listeners
|
||||
if(clearListeners && self.connection != null) {
|
||||
var keys = Object.keys(self.eventHandlers);
|
||||
// Remove all listeners
|
||||
for(var i = 0; i < keys.length; i++) {
|
||||
self.connection.removeAllListeners(keys[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Handlers
|
||||
//
|
||||
|
||||
// Connect handler
|
||||
var connectHandler = function(self) {
|
||||
return function(data) {
|
||||
// Set connected
|
||||
self.connected = true;
|
||||
// Now that we are connected set the socket timeout
|
||||
self.connection.setTimeout(self.socketOptions.socketTimeoutMS != null ? self.socketOptions.socketTimeoutMS : self.socketOptions.timeout);
|
||||
// Emit the connect event with no error
|
||||
self.emit("connect", null, self);
|
||||
}
|
||||
}
|
||||
|
||||
var createDataHandler = exports.Connection.createDataHandler = function(self) {
|
||||
// We need to handle the parsing of the data
|
||||
// and emit the messages when there is a complete one
|
||||
return function(data) {
|
||||
// Parse until we are done with the data
|
||||
while(data.length > 0) {
|
||||
// If we still have bytes to read on the current message
|
||||
if(self.bytesRead > 0 && self.sizeOfMessage > 0) {
|
||||
// Calculate the amount of remaining bytes
|
||||
var remainingBytesToRead = self.sizeOfMessage - self.bytesRead;
|
||||
// Check if the current chunk contains the rest of the message
|
||||
if(remainingBytesToRead > data.length) {
|
||||
// Copy the new data into the exiting buffer (should have been allocated when we know the message size)
|
||||
data.copy(self.buffer, self.bytesRead);
|
||||
// Adjust the number of bytes read so it point to the correct index in the buffer
|
||||
self.bytesRead = self.bytesRead + data.length;
|
||||
|
||||
// Reset state of buffer
|
||||
data = new Buffer(0);
|
||||
} else {
|
||||
// Copy the missing part of the data into our current buffer
|
||||
data.copy(self.buffer, self.bytesRead, 0, remainingBytesToRead);
|
||||
// Slice the overflow into a new buffer that we will then re-parse
|
||||
data = data.slice(remainingBytesToRead);
|
||||
|
||||
// Emit current complete message
|
||||
try {
|
||||
var emitBuffer = self.buffer;
|
||||
// Reset state of buffer
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
// Emit the buffer
|
||||
self.emit("message", emitBuffer, self);
|
||||
} catch(err) {
|
||||
var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
|
||||
sizeOfMessage:self.sizeOfMessage,
|
||||
bytesRead:self.bytesRead,
|
||||
stubBuffer:self.stubBuffer}};
|
||||
if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Stub buffer is kept in case we don't get enough bytes to determine the
|
||||
// size of the message (< 4 bytes)
|
||||
if(self.stubBuffer != null && self.stubBuffer.length > 0) {
|
||||
|
||||
// If we have enough bytes to determine the message size let's do it
|
||||
if(self.stubBuffer.length + data.length > 4) {
|
||||
// Prepad the data
|
||||
var newData = new Buffer(self.stubBuffer.length + data.length);
|
||||
self.stubBuffer.copy(newData, 0);
|
||||
data.copy(newData, self.stubBuffer.length);
|
||||
// Reassign for parsing
|
||||
data = newData;
|
||||
|
||||
// Reset state of buffer
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
|
||||
} else {
|
||||
|
||||
// Add the the bytes to the stub buffer
|
||||
var newStubBuffer = new Buffer(self.stubBuffer.length + data.length);
|
||||
// Copy existing stub buffer
|
||||
self.stubBuffer.copy(newStubBuffer, 0);
|
||||
// Copy missing part of the data
|
||||
data.copy(newStubBuffer, self.stubBuffer.length);
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
}
|
||||
} else {
|
||||
if(data.length > 4) {
|
||||
// Retrieve the message size
|
||||
var sizeOfMessage = binaryutils.decodeUInt32(data, 0);
|
||||
// If we have a negative sizeOfMessage emit error and return
|
||||
if(sizeOfMessage < 0 || sizeOfMessage > self.maxBsonSize) {
|
||||
var errorObject = {err:"socketHandler", trace:'', bin:self.buffer, parseState:{
|
||||
sizeOfMessage: sizeOfMessage,
|
||||
bytesRead: self.bytesRead,
|
||||
stubBuffer: self.stubBuffer}};
|
||||
if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ensure that the size of message is larger than 0 and less than the max allowed
|
||||
if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage > data.length) {
|
||||
self.buffer = new Buffer(sizeOfMessage);
|
||||
// Copy all the data into the buffer
|
||||
data.copy(self.buffer, 0);
|
||||
// Update bytes read
|
||||
self.bytesRead = data.length;
|
||||
// Update sizeOfMessage
|
||||
self.sizeOfMessage = sizeOfMessage;
|
||||
// Ensure stub buffer is null
|
||||
self.stubBuffer = null;
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
|
||||
} else if(sizeOfMessage > 4 && sizeOfMessage < self.maxBsonSize && sizeOfMessage == data.length) {
|
||||
try {
|
||||
var emitBuffer = data;
|
||||
// Reset state of buffer
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
// Emit the message
|
||||
self.emit("message", emitBuffer, self);
|
||||
} catch (err) {
|
||||
var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
|
||||
sizeOfMessage:self.sizeOfMessage,
|
||||
bytesRead:self.bytesRead,
|
||||
stubBuffer:self.stubBuffer}};
|
||||
if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
}
|
||||
} else if(sizeOfMessage <= 4 || sizeOfMessage > self.maxBsonSize) {
|
||||
var errorObject = {err:"socketHandler", trace:null, bin:data, parseState:{
|
||||
sizeOfMessage:sizeOfMessage,
|
||||
bytesRead:0,
|
||||
buffer:null,
|
||||
stubBuffer:null}};
|
||||
if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
|
||||
// Clear out the state of the parser
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
|
||||
} else {
|
||||
try {
|
||||
var emitBuffer = data.slice(0, sizeOfMessage);
|
||||
// Reset state of buffer
|
||||
self.buffer = null;
|
||||
self.sizeOfMessage = 0;
|
||||
self.bytesRead = 0;
|
||||
self.stubBuffer = null;
|
||||
// Copy rest of message
|
||||
data = data.slice(sizeOfMessage);
|
||||
// Emit the message
|
||||
self.emit("message", emitBuffer, self);
|
||||
} catch (err) {
|
||||
var errorObject = {err:"socketHandler", trace:err, bin:self.buffer, parseState:{
|
||||
sizeOfMessage:sizeOfMessage,
|
||||
bytesRead:self.bytesRead,
|
||||
stubBuffer:self.stubBuffer}};
|
||||
if(self.logger != null && self.logger.doError) self.logger.error("parseError", errorObject);
|
||||
// We got a parse Error fire it off then keep going
|
||||
self.emit("parseError", errorObject, self);
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
// Create a buffer that contains the space for the non-complete message
|
||||
self.stubBuffer = new Buffer(data.length)
|
||||
// Copy the data to the stub buffer
|
||||
data.copy(self.stubBuffer, 0);
|
||||
// Exit parsing loop
|
||||
data = new Buffer(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var endHandler = function(self) {
|
||||
return function() {
|
||||
// Set connected to false
|
||||
self.connected = false;
|
||||
// Emit end event
|
||||
self.emit("end", {err: 'connection received Fin packet from [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
|
||||
}
|
||||
}
|
||||
|
||||
var timeoutHandler = function(self) {
|
||||
return function() {
|
||||
// Set connected to false
|
||||
self.connected = false;
|
||||
// Emit timeout event
|
||||
self.emit("timeout", {err: 'connection to [' + self.socketOptions.host + ':' + self.socketOptions.port + '] timed out'}, self);
|
||||
}
|
||||
}
|
||||
|
||||
var drainHandler = function(self) {
|
||||
return function() {
|
||||
}
|
||||
}
|
||||
|
||||
var errorHandler = function(self) {
|
||||
return function(err) {
|
||||
// Set connected to false
|
||||
self.connected = false;
|
||||
// Emit error
|
||||
self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
|
||||
}
|
||||
}
|
||||
|
||||
var closeHandler = function(self) {
|
||||
return function(hadError) {
|
||||
// If we have an error during the connection phase
|
||||
if(hadError && !self.connected) {
|
||||
// Set disconnected
|
||||
self.connected = false;
|
||||
// Emit error
|
||||
self.emit("error", {err: 'failed to connect to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
|
||||
} else {
|
||||
// Set disconnected
|
||||
self.connected = false;
|
||||
// Emit close
|
||||
self.emit("close", {err: 'connection closed to [' + self.socketOptions.host + ':' + self.socketOptions.port + ']'}, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Some basic defaults
|
||||
Connection.DEFAULT_PORT = 27017;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
293
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/connection_pool.js
generated
vendored
Normal file
293
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/connection_pool.js
generated
vendored
Normal file
@@ -0,0 +1,293 @@
|
||||
var utils = require('./connection_utils'),
|
||||
inherits = require('util').inherits,
|
||||
net = require('net'),
|
||||
timers = require('timers'),
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
inherits = require('util').inherits,
|
||||
MongoReply = require("../responses/mongo_reply").MongoReply,
|
||||
Connection = require("./connection").Connection;
|
||||
|
||||
// Set processor, setImmediate if 0.10 otherwise nextTick
|
||||
var processor = timers.setImmediate ? timers.setImmediate : process.nextTick;
|
||||
processor = process.nextTick
|
||||
|
||||
var ConnectionPool = exports.ConnectionPool = function(host, port, poolSize, bson, socketOptions) {
|
||||
if(typeof host !== 'string') {
|
||||
throw new Error("host must be specified [" + host + "]");
|
||||
}
|
||||
|
||||
// Set up event emitter
|
||||
EventEmitter.call(this);
|
||||
|
||||
// Keep all options for the socket in a specific collection allowing the user to specify the
|
||||
// Wished upon socket connection parameters
|
||||
this.socketOptions = typeof socketOptions === 'object' ? socketOptions : {};
|
||||
this.socketOptions.host = host;
|
||||
this.socketOptions.port = port;
|
||||
this.socketOptions.domainSocket = false;
|
||||
this.bson = bson;
|
||||
// PoolSize is always + 1 for special reserved "measurment" socket (like ping, stats etc)
|
||||
this.poolSize = poolSize;
|
||||
this.minPoolSize = Math.floor(this.poolSize / 2) + 1;
|
||||
|
||||
// Check if the host is a socket
|
||||
if(host.match(/^\//)) {
|
||||
this.socketOptions.domainSocket = true;
|
||||
} else if(typeof port === 'string') {
|
||||
try {
|
||||
port = parseInt(port, 10);
|
||||
} catch(err) {
|
||||
new Error("port must be specified or valid integer[" + port + "]");
|
||||
}
|
||||
} else if(typeof port !== 'number') {
|
||||
throw new Error("port must be specified [" + port + "]");
|
||||
}
|
||||
|
||||
// Set default settings for the socket options
|
||||
utils.setIntegerParameter(this.socketOptions, 'timeout', 0);
|
||||
// Delay before writing out the data to the server
|
||||
utils.setBooleanParameter(this.socketOptions, 'noDelay', true);
|
||||
// Delay before writing out the data to the server
|
||||
utils.setIntegerParameter(this.socketOptions, 'keepAlive', 0);
|
||||
// Set the encoding of the data read, default is binary == null
|
||||
utils.setStringParameter(this.socketOptions, 'encoding', null);
|
||||
// Allows you to set a throttling bufferSize if you need to stop overflows
|
||||
utils.setIntegerParameter(this.socketOptions, 'bufferSize', 0);
|
||||
|
||||
// Internal structures
|
||||
this.openConnections = [];
|
||||
// Assign connection id's
|
||||
this.connectionId = 0;
|
||||
|
||||
// Current index for selection of pool connection
|
||||
this.currentConnectionIndex = 0;
|
||||
// The pool state
|
||||
this._poolState = 'disconnected';
|
||||
// timeout control
|
||||
this._timeout = false;
|
||||
// Time to wait between connections for the pool
|
||||
this._timeToWait = 10;
|
||||
}
|
||||
|
||||
inherits(ConnectionPool, EventEmitter);
|
||||
|
||||
ConnectionPool.prototype.setMaxBsonSize = function(maxBsonSize) {
|
||||
if(maxBsonSize == null){
|
||||
maxBsonSize = Connection.DEFAULT_MAX_BSON_SIZE;
|
||||
}
|
||||
|
||||
for(var i = 0; i < this.openConnections.length; i++) {
|
||||
this.openConnections[i].maxBsonSize = maxBsonSize;
|
||||
}
|
||||
}
|
||||
|
||||
ConnectionPool.prototype.setMaxMessageSizeBytes = function(maxMessageSizeBytes) {
|
||||
if(maxMessageSizeBytes == null){
|
||||
maxMessageSizeBytes = Connection.DEFAULT_MAX_MESSAGE_SIZE;
|
||||
}
|
||||
|
||||
for(var i = 0; i < this.openConnections.length; i++) {
|
||||
this.openConnections[i].maxMessageSizeBytes = maxMessageSizeBytes;
|
||||
}
|
||||
}
|
||||
|
||||
// Start a function
|
||||
var _connect = function(_self) {
|
||||
// return new function() {
|
||||
// Create a new connection instance
|
||||
var connection = new Connection(_self.connectionId++, _self.socketOptions);
|
||||
// Set logger on pool
|
||||
connection.logger = _self.logger;
|
||||
// Connect handler
|
||||
connection.on("connect", function(err, connection) {
|
||||
// Add connection to list of open connections
|
||||
_self.openConnections.push(connection);
|
||||
// If the number of open connections is equal to the poolSize signal ready pool
|
||||
if(_self.openConnections.length === _self.poolSize && _self._poolState !== 'disconnected') {
|
||||
// Set connected
|
||||
_self._poolState = 'connected';
|
||||
// Emit pool ready
|
||||
_self.emit("poolReady");
|
||||
} else if(_self.openConnections.length < _self.poolSize) {
|
||||
// Wait a little bit of time to let the close event happen if the server closes the connection
|
||||
// so we don't leave hanging connections around
|
||||
if(typeof _self._timeToWait == 'number') {
|
||||
setTimeout(function() {
|
||||
// If we are still connecting (no close events fired in between start another connection)
|
||||
if(_self._poolState == 'connecting') {
|
||||
_connect(_self);
|
||||
}
|
||||
}, _self._timeToWait);
|
||||
} else {
|
||||
processor(function() {
|
||||
// If we are still connecting (no close events fired in between start another connection)
|
||||
if(_self._poolState == 'connecting') {
|
||||
_connect(_self);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var numberOfErrors = 0
|
||||
|
||||
// Error handler
|
||||
connection.on("error", function(err, connection, error_options) {
|
||||
numberOfErrors++;
|
||||
// If we are already disconnected ignore the event
|
||||
if(_self._poolState != 'disconnected' && _self.listeners("error").length > 0) {
|
||||
_self.emit("error", err, connection, error_options);
|
||||
}
|
||||
|
||||
// Close the connection
|
||||
connection.close();
|
||||
// Set pool as disconnected
|
||||
_self._poolState = 'disconnected';
|
||||
// Stop the pool
|
||||
_self.stop();
|
||||
});
|
||||
|
||||
// Close handler
|
||||
connection.on("close", function() {
|
||||
// If we are already disconnected ignore the event
|
||||
if(_self._poolState !== 'disconnected' && _self.listeners("close").length > 0) {
|
||||
_self.emit("close");
|
||||
}
|
||||
|
||||
// Set disconnected
|
||||
_self._poolState = 'disconnected';
|
||||
// Stop
|
||||
_self.stop();
|
||||
});
|
||||
|
||||
// Timeout handler
|
||||
connection.on("timeout", function(err, connection) {
|
||||
// If we are already disconnected ignore the event
|
||||
if(_self._poolState !== 'disconnected' && _self.listeners("timeout").length > 0) {
|
||||
_self.emit("timeout", err);
|
||||
}
|
||||
|
||||
// Close the connection
|
||||
connection.close();
|
||||
// Set disconnected
|
||||
_self._poolState = 'disconnected';
|
||||
_self.stop();
|
||||
});
|
||||
|
||||
// Parse error, needs a complete shutdown of the pool
|
||||
connection.on("parseError", function() {
|
||||
// If we are already disconnected ignore the event
|
||||
if(_self._poolState !== 'disconnected' && _self.listeners("parseError").length > 0) {
|
||||
_self.emit("parseError", new Error("parseError occured"));
|
||||
}
|
||||
|
||||
// Set disconnected
|
||||
_self._poolState = 'disconnected';
|
||||
_self.stop();
|
||||
});
|
||||
|
||||
connection.on("message", function(message) {
|
||||
_self.emit("message", message);
|
||||
});
|
||||
|
||||
// Start connection in the next tick
|
||||
connection.start();
|
||||
// }();
|
||||
}
|
||||
|
||||
|
||||
// Start method, will throw error if no listeners are available
|
||||
// Pass in an instance of the listener that contains the api for
|
||||
// finding callbacks for a given message etc.
|
||||
ConnectionPool.prototype.start = function() {
|
||||
var markerDate = new Date().getTime();
|
||||
var self = this;
|
||||
|
||||
if(this.listeners("poolReady").length == 0) {
|
||||
throw "pool must have at least one listener ready that responds to the [poolReady] event";
|
||||
}
|
||||
|
||||
// Set pool state to connecting
|
||||
this._poolState = 'connecting';
|
||||
this._timeout = false;
|
||||
|
||||
_connect(self);
|
||||
}
|
||||
|
||||
// Restart a connection pool (on a close the pool might be in a wrong state)
|
||||
ConnectionPool.prototype.restart = function() {
|
||||
// Close all connections
|
||||
this.stop(false);
|
||||
// Now restart the pool
|
||||
this.start();
|
||||
}
|
||||
|
||||
// Stop the connections in the pool
|
||||
ConnectionPool.prototype.stop = function(removeListeners) {
|
||||
removeListeners = removeListeners == null ? true : removeListeners;
|
||||
// Set disconnected
|
||||
this._poolState = 'disconnected';
|
||||
|
||||
// Clear all listeners if specified
|
||||
if(removeListeners) {
|
||||
this.removeAllEventListeners();
|
||||
}
|
||||
|
||||
// Close all connections
|
||||
for(var i = 0; i < this.openConnections.length; i++) {
|
||||
this.openConnections[i].close();
|
||||
}
|
||||
|
||||
// Clean up
|
||||
this.openConnections = [];
|
||||
}
|
||||
|
||||
// Check the status of the connection
|
||||
ConnectionPool.prototype.isConnected = function() {
|
||||
return this._poolState === 'connected';
|
||||
}
|
||||
|
||||
// Checkout a connection from the pool for usage, or grab a specific pool instance
|
||||
ConnectionPool.prototype.checkoutConnection = function(id) {
|
||||
var index = (this.currentConnectionIndex++ % (this.openConnections.length));
|
||||
var connection = this.openConnections[index];
|
||||
return connection;
|
||||
}
|
||||
|
||||
ConnectionPool.prototype.getAllConnections = function() {
|
||||
return this.openConnections;
|
||||
}
|
||||
|
||||
// Remove all non-needed event listeners
|
||||
ConnectionPool.prototype.removeAllEventListeners = function() {
|
||||
this.removeAllListeners("close");
|
||||
this.removeAllListeners("error");
|
||||
this.removeAllListeners("timeout");
|
||||
this.removeAllListeners("connect");
|
||||
this.removeAllListeners("end");
|
||||
this.removeAllListeners("parseError");
|
||||
this.removeAllListeners("message");
|
||||
this.removeAllListeners("poolReady");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
23
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/connection_utils.js
generated
vendored
Normal file
23
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/connection_utils.js
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
exports.setIntegerParameter = function(object, field, defaultValue) {
|
||||
if(object[field] == null) {
|
||||
object[field] = defaultValue;
|
||||
} else if(typeof object[field] !== "number" && object[field] !== parseInt(object[field], 10)) {
|
||||
throw "object field [" + field + "] must be a numeric integer value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
|
||||
}
|
||||
}
|
||||
|
||||
exports.setBooleanParameter = function(object, field, defaultValue) {
|
||||
if(object[field] == null) {
|
||||
object[field] = defaultValue;
|
||||
} else if(typeof object[field] !== "boolean") {
|
||||
throw "object field [" + field + "] must be a boolean value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
|
||||
}
|
||||
}
|
||||
|
||||
exports.setStringParameter = function(object, field, defaultValue) {
|
||||
if(object[field] == null) {
|
||||
object[field] = defaultValue;
|
||||
} else if(typeof object[field] !== "string") {
|
||||
throw "object field [" + field + "] must be a string value, attempted to set to [" + object[field] + "] type of [" + typeof object[field] + "]";
|
||||
}
|
||||
}
|
||||
357
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/mongos.js
generated
vendored
Normal file
357
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/mongos.js
generated
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
var ReadPreference = require('./read_preference').ReadPreference
|
||||
, Base = require('./base').Base
|
||||
, inherits = require('util').inherits;
|
||||
|
||||
/**
|
||||
* Mongos constructor provides a connection to a mongos proxy including failover to additional servers
|
||||
*
|
||||
* Options
|
||||
* - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number))
|
||||
* - **ha** {Boolean, default:true}, turn on high availability, attempts to reconnect to down proxies
|
||||
* - **haInterval** {Number, default:2000}, time between each replicaset status check.
|
||||
*
|
||||
* @class Represents a Mongos connection with failover to backup proxies
|
||||
* @param {Array} list of mongos server objects
|
||||
* @param {Object} [options] additional options for the mongos connection
|
||||
*/
|
||||
var Mongos = function Mongos(servers, options) {
|
||||
// Set up basic
|
||||
if(!(this instanceof Mongos))
|
||||
return new Mongos(servers, options);
|
||||
|
||||
// Set up event emitter
|
||||
Base.call(this);
|
||||
|
||||
// Throw error on wrong setup
|
||||
if(servers == null || !Array.isArray(servers) || servers.length == 0)
|
||||
throw new Error("At least one mongos proxy must be in the array");
|
||||
|
||||
// Ensure we have at least an empty options object
|
||||
this.options = options == null ? {} : options;
|
||||
// Set default connection pool options
|
||||
this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {};
|
||||
// Enabled ha
|
||||
this.haEnabled = this.options['ha'] == null ? true : this.options['ha'];
|
||||
// How often are we checking for new servers in the replicaset
|
||||
this.mongosStatusCheckInterval = this.options['haInterval'] == null ? 2000 : this.options['haInterval'];
|
||||
// Save all the server connections
|
||||
this.servers = servers;
|
||||
// Servers we need to attempt reconnect with
|
||||
this.downServers = [];
|
||||
// Just contains the current lowest ping time and server
|
||||
this.lowestPingTimeServer = null;
|
||||
this.lowestPingTime = 0;
|
||||
|
||||
// Connection timeout
|
||||
this._connectTimeoutMS = this.socketOptions.connectTimeoutMS
|
||||
? this.socketOptions.connectTimeoutMS
|
||||
: 1000;
|
||||
|
||||
// Add options to servers
|
||||
for(var i = 0; i < this.servers.length; i++) {
|
||||
var server = this.servers[i];
|
||||
server._callBackStore = this._callBackStore;
|
||||
// Default empty socket options object
|
||||
var socketOptions = {host: server.host, port: server.port};
|
||||
// If a socket option object exists clone it
|
||||
if(this.socketOptions != null) {
|
||||
var keys = Object.keys(this.socketOptions);
|
||||
for(var k = 0; k < keys.length;k++) socketOptions[keys[i]] = this.socketOptions[keys[i]];
|
||||
}
|
||||
// Set socket options
|
||||
server.socketOptions = socketOptions;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
inherits(Mongos, Base);
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Mongos.prototype.isMongos = function() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Mongos.prototype.connect = function(db, options, callback) {
|
||||
if('function' === typeof options) callback = options, options = {};
|
||||
if(options == null) options = {};
|
||||
if(!('function' === typeof callback)) callback = null;
|
||||
var self = this;
|
||||
|
||||
// Keep reference to parent
|
||||
this.db = db;
|
||||
// Set server state to connecting
|
||||
this._serverState = 'connecting';
|
||||
// Number of total servers that need to initialized (known servers)
|
||||
this._numberOfServersLeftToInitialize = this.servers.length;
|
||||
// Default to the first proxy server as the first one to use
|
||||
this._currentMongos = this.servers[0];
|
||||
|
||||
// Connect handler
|
||||
var connectHandler = function(_server) {
|
||||
return function(err, result) {
|
||||
self._numberOfServersLeftToInitialize = self._numberOfServersLeftToInitialize - 1;
|
||||
|
||||
if(self._numberOfServersLeftToInitialize == 0) {
|
||||
// Start ha function if it exists
|
||||
if(self.haEnabled) {
|
||||
// Setup the ha process
|
||||
self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval);
|
||||
}
|
||||
|
||||
// Set the mongos to connected
|
||||
self._serverState = "connected";
|
||||
// Emit the open event
|
||||
self.db.emit("open", null, self.db);
|
||||
// Callback
|
||||
callback(null, self.db);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Error handler
|
||||
var errorOrCloseHandler = function(_server) {
|
||||
return function(err, result) {
|
||||
// Create current mongos comparision
|
||||
var currentUrl = self._currentMongos.host + ":" + self._currentMongos.port;
|
||||
var serverUrl = this.host + ":" + this.port;
|
||||
// We need to check if the server that closed is the actual current proxy we are using, otherwise
|
||||
// just ignore
|
||||
if(currentUrl == serverUrl) {
|
||||
// Remove the server from the list
|
||||
if(self.servers.indexOf(_server) != -1) {
|
||||
self.servers.splice(self.servers.indexOf(_server), 1);
|
||||
}
|
||||
|
||||
// Pick the next one on the list if there is one
|
||||
for(var i = 0; i < self.servers.length; i++) {
|
||||
// Grab the server out of the array (making sure there is no servers in the list if none available)
|
||||
var server = self.servers[i];
|
||||
// Generate url for comparision
|
||||
var serverUrl = server.host + ":" + server.port;
|
||||
// It's not the current one and connected set it as the current db
|
||||
if(currentUrl != serverUrl && server.isConnected()) {
|
||||
self._currentMongos = server;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure we don't store the _server twice
|
||||
if(self.downServers.indexOf(_server) == -1) {
|
||||
// Add the server instances
|
||||
self.downServers.push(_server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mongo function
|
||||
this.mongosCheckFunction = function() {
|
||||
// If we have down servers let's attempt a reconnect
|
||||
if(self.downServers.length > 0) {
|
||||
var numberOfServersLeft = self.downServers.length;
|
||||
// Attempt to reconnect
|
||||
for(var i = 0; i < self.downServers.length; i++) {
|
||||
var downServer = self.downServers.pop();
|
||||
|
||||
// Configuration
|
||||
var options = {
|
||||
slaveOk: true,
|
||||
poolSize: 1,
|
||||
socketOptions: { connectTimeoutMS: self._connectTimeoutMS },
|
||||
returnIsMasterResults: true
|
||||
}
|
||||
|
||||
// Attemp to reconnect
|
||||
downServer.connect(self.db, options, function(_server) {
|
||||
// Return a function to check for the values
|
||||
return function(err, result) {
|
||||
// Adjust the number of servers left
|
||||
numberOfServersLeft = numberOfServersLeft - 1;
|
||||
|
||||
if(err != null) {
|
||||
self.downServers.push(_server);
|
||||
} else {
|
||||
// Add server event handlers
|
||||
_server.on("close", errorOrCloseHandler(_server));
|
||||
_server.on("error", errorOrCloseHandler(_server));
|
||||
// Add to list of servers
|
||||
self.servers.push(_server);
|
||||
}
|
||||
|
||||
if(numberOfServersLeft <= 0) {
|
||||
// Perfom another ha
|
||||
self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval);
|
||||
}
|
||||
}
|
||||
}(downServer));
|
||||
}
|
||||
} else if(self.servers.length > 0) {
|
||||
var numberOfServersLeft = self.servers.length;
|
||||
var _s = new Date().getTime()
|
||||
|
||||
// Else let's perform a ping command
|
||||
for(var i = 0; i < self.servers.length; i++) {
|
||||
var executePing = function(_server) {
|
||||
// Get a read connection
|
||||
var _connection = _server.checkoutReader();
|
||||
// Execute ping command
|
||||
self.db.command({ping:1}, {failFast:true, connection:_connection}, function(err, result) {
|
||||
var pingTime = new Date().getTime() - _s;
|
||||
// If no server set set the first one, otherwise check
|
||||
// the lowest ping time and assign the server if it's got a lower ping time
|
||||
if(self.lowestPingTimeServer == null) {
|
||||
self.lowestPingTimeServer = _server;
|
||||
self.lowestPingTime = pingTime;
|
||||
self._currentMongos = _server;
|
||||
} else if(self.lowestPingTime > pingTime
|
||||
&& (_server.host != self.lowestPingTimeServer.host || _server.port != self.lowestPingTimeServer.port)) {
|
||||
self.lowestPingTimeServer = _server;
|
||||
self.lowestPingTime = pingTime;
|
||||
self._currentMongos = _server;
|
||||
}
|
||||
|
||||
// Number of servers left
|
||||
numberOfServersLeft = numberOfServersLeft - 1;
|
||||
// All active mongos's pinged
|
||||
if(numberOfServersLeft == 0) {
|
||||
// Perfom another ha
|
||||
self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval);
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Execute the function
|
||||
executePing(self.servers[i]);
|
||||
}
|
||||
} else {
|
||||
self._replicasetTimeoutId = setTimeout(self.mongosCheckFunction, self.mongosStatusCheckInterval);
|
||||
}
|
||||
}
|
||||
|
||||
// Connect all the server instances
|
||||
for(var i = 0; i < this.servers.length; i++) {
|
||||
// Get the connection
|
||||
var server = this.servers[i];
|
||||
server.mongosInstance = this;
|
||||
// Add server event handlers
|
||||
server.on("close", errorOrCloseHandler(server));
|
||||
server.on("timeout", errorOrCloseHandler(server));
|
||||
server.on("error", errorOrCloseHandler(server));
|
||||
// Configuration
|
||||
var options = {
|
||||
slaveOk: true,
|
||||
poolSize: 1,
|
||||
socketOptions: { connectTimeoutMS: self._connectTimeoutMS },
|
||||
returnIsMasterResults: true
|
||||
}
|
||||
|
||||
// Connect the instance
|
||||
server.connect(self.db, options, connectHandler(server));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* Just return the currently picked active connection
|
||||
*/
|
||||
Mongos.prototype.allServerInstances = function() {
|
||||
return this.servers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Always ourselves
|
||||
* @ignore
|
||||
*/
|
||||
Mongos.prototype.setReadPreference = function() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Mongos.prototype.allRawConnections = function() {
|
||||
// Neeed to build a complete list of all raw connections, start with master server
|
||||
var allConnections = [];
|
||||
// Add all connections
|
||||
for(var i = 0; i < this.servers.length; i++) {
|
||||
allConnections = allConnections.concat(this.servers[i].allRawConnections());
|
||||
}
|
||||
|
||||
// Return all the conections
|
||||
return allConnections;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Mongos.prototype.isConnected = function() {
|
||||
return this._serverState == "connected";
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Mongos.prototype.checkoutWriter = function() {
|
||||
// No current mongo, just pick first server
|
||||
if(this._currentMongos == null && this.servers.length > 0) {
|
||||
return this.servers[0].checkoutWriter();
|
||||
}
|
||||
return this._currentMongos.checkoutWriter();
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Mongos.prototype.checkoutReader = function(read) {
|
||||
// If we have a read preference object unpack it
|
||||
if(typeof read == 'object' && read['_type'] == 'ReadPreference') {
|
||||
// Validate if the object is using a valid mode
|
||||
if(!read.isValid()) throw new Error("Illegal readPreference mode specified, " + read.mode);
|
||||
} else if(!ReadPreference.isValid(read)) {
|
||||
throw new Error("Illegal readPreference mode specified, " + read);
|
||||
}
|
||||
|
||||
// No current mongo, just pick first server
|
||||
if(this._currentMongos == null && this.servers.length > 0) {
|
||||
return this.servers[0].checkoutReader();
|
||||
}
|
||||
return this._currentMongos.checkoutReader();
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Mongos.prototype.close = function(callback) {
|
||||
var self = this;
|
||||
// Set server status as disconnected
|
||||
this._serverState = 'disconnected';
|
||||
// Number of connections to close
|
||||
var numberOfConnectionsToClose = self.servers.length;
|
||||
// If we have a ha process running kill it
|
||||
if(self._replicasetTimeoutId != null) clearTimeout(self._replicasetTimeoutId);
|
||||
// Close all proxy connections
|
||||
for(var i = 0; i < self.servers.length; i++) {
|
||||
self.servers[i].close(function(err, result) {
|
||||
numberOfConnectionsToClose = numberOfConnectionsToClose - 1;
|
||||
// Callback if we have one defined
|
||||
if(numberOfConnectionsToClose == 0 && typeof callback == 'function') {
|
||||
callback(null);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* Return the used state
|
||||
*/
|
||||
Mongos.prototype._isUsed = function() {
|
||||
return this._used;
|
||||
}
|
||||
|
||||
exports.Mongos = Mongos;
|
||||
66
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/read_preference.js
generated
vendored
Normal file
66
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/read_preference.js
generated
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* A class representation of the Read Preference.
|
||||
*
|
||||
* Read Preferences
|
||||
* - **ReadPreference.PRIMARY**, Read from primary only. All operations produce an error (throw an exception where applicable) if primary is unavailable. Cannot be combined with tags (This is the default.).
|
||||
* - **ReadPreference.PRIMARY_PREFERRED**, Read from primary if available, otherwise a secondary.
|
||||
* - **ReadPreference.SECONDARY**, Read from secondary if available, otherwise error.
|
||||
* - **ReadPreference.SECONDARY_PREFERRED**, Read from a secondary if available, otherwise read from the primary.
|
||||
* - **ReadPreference.NEAREST**, All modes read from among the nearest candidates, but unlike other modes, NEAREST will include both the primary and all secondaries in the random selection.
|
||||
*
|
||||
* @class Represents a Read Preference.
|
||||
* @param {String} the read preference type
|
||||
* @param {Object} tags
|
||||
* @return {ReadPreference}
|
||||
*/
|
||||
var ReadPreference = function(mode, tags) {
|
||||
if(!(this instanceof ReadPreference))
|
||||
return new ReadPreference(mode, tags);
|
||||
this._type = 'ReadPreference';
|
||||
this.mode = mode;
|
||||
this.tags = tags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
ReadPreference.isValid = function(_mode) {
|
||||
return (_mode == ReadPreference.PRIMARY || _mode == ReadPreference.PRIMARY_PREFERRED
|
||||
|| _mode == ReadPreference.SECONDARY || _mode == ReadPreference.SECONDARY_PREFERRED
|
||||
|| _mode == ReadPreference.NEAREST);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
ReadPreference.prototype.isValid = function(mode) {
|
||||
var _mode = typeof mode == 'string' ? mode : this.mode;
|
||||
return ReadPreference.isValid(_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
ReadPreference.prototype.toObject = function() {
|
||||
var object = {mode:this.mode};
|
||||
|
||||
if(this.tags != null) {
|
||||
object['tags'] = this.tags;
|
||||
}
|
||||
|
||||
return object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
ReadPreference.PRIMARY = 'primary';
|
||||
ReadPreference.PRIMARY_PREFERRED = 'primaryPreferred';
|
||||
ReadPreference.SECONDARY = 'secondary';
|
||||
ReadPreference.SECONDARY_PREFERRED = 'secondaryPreferred';
|
||||
ReadPreference.NEAREST = 'nearest'
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
exports.ReadPreference = ReadPreference;
|
||||
1471
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/repl_set.js
generated
vendored
Normal file
1471
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/repl_set.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
905
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/server.js
generated
vendored
Normal file
905
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/server.js
generated
vendored
Normal file
@@ -0,0 +1,905 @@
|
||||
var Connection = require('./connection').Connection,
|
||||
ReadPreference = require('./read_preference').ReadPreference,
|
||||
DbCommand = require('../commands/db_command').DbCommand,
|
||||
MongoReply = require('../responses/mongo_reply').MongoReply,
|
||||
ConnectionPool = require('./connection_pool').ConnectionPool,
|
||||
EventEmitter = require('events').EventEmitter,
|
||||
Base = require('./base').Base,
|
||||
utils = require('../utils'),
|
||||
timers = require('timers'),
|
||||
inherits = require('util').inherits;
|
||||
|
||||
// Set processor, setImmediate if 0.10 otherwise nextTick
|
||||
var processor = timers.setImmediate ? timers.setImmediate : process.nextTick;
|
||||
processor = process.nextTick
|
||||
|
||||
/**
|
||||
* Class representing a single MongoDB Server connection
|
||||
*
|
||||
* Options
|
||||
* - **readPreference** {String, default:null}, set's the read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST)
|
||||
* - **ssl** {Boolean, default:false}, use ssl connection (needs to have a mongod server with ssl support)
|
||||
* - **sslValidate** {Boolean, default:false}, validate mongod server certificate against ca (needs to have a mongod server with ssl support, 2.4 or higher)
|
||||
* - **sslCA** {Array, default:null}, Array of valid certificates either as Buffers or Strings (needs to have a mongod server with ssl support, 2.4 or higher)
|
||||
* - **sslCert** {Buffer/String, default:null}, String or buffer containing the certificate we wish to present (needs to have a mongod server with ssl support, 2.4 or higher)
|
||||
* - **sslKey** {Buffer/String, default:null}, String or buffer containing the certificate private key we wish to present (needs to have a mongod server with ssl support, 2.4 or higher)
|
||||
* - **sslPass** {Buffer/String, default:null}, String or buffer containing the certificate password (needs to have a mongod server with ssl support, 2.4 or higher)
|
||||
* - **poolSize** {Number, default:5}, number of connections in the connection pool, set to 5 as default for legacy reasons.
|
||||
* - **socketOptions** {Object, default:null}, an object containing socket options to use (noDelay:(boolean), keepAlive:(number), connectTimeoutMS:(number), socketTimeoutMS:(number))
|
||||
* - **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) {}})**.
|
||||
* - **auto_reconnect** {Boolean, default:false}, reconnect on error.
|
||||
* - **disableDriverBSONSizeCheck** {Boolean, default:false}, force the server to error if the BSON message is to big
|
||||
*
|
||||
* @class Represents a Server connection.
|
||||
* @param {String} host the server host
|
||||
* @param {Number} port the server port
|
||||
* @param {Object} [options] optional options for insert command
|
||||
*/
|
||||
function Server(host, port, options) {
|
||||
// Set up Server instance
|
||||
if(!(this instanceof Server)) return new Server(host, port, options);
|
||||
|
||||
// Set up event emitter
|
||||
Base.call(this);
|
||||
|
||||
// Ensure correct values
|
||||
if(port != null && typeof port == 'object') {
|
||||
options = port;
|
||||
port = Connection.DEFAULT_PORT;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.options = options == null ? {} : options;
|
||||
this.internalConnection;
|
||||
this.internalMaster = false;
|
||||
this.connected = false;
|
||||
this.poolSize = this.options.poolSize == null ? 5 : this.options.poolSize;
|
||||
this.disableDriverBSONSizeCheck = this.options.disableDriverBSONSizeCheck != null ? this.options.disableDriverBSONSizeCheck : false;
|
||||
this.slaveOk = this.options["slave_ok"] ? this.options["slave_ok"] : this.options["slaveOk"];
|
||||
this._used = false;
|
||||
this.replicasetInstance = null;
|
||||
|
||||
// Set ssl as connection method
|
||||
this.ssl = this.options.ssl == null ? false : this.options.ssl;
|
||||
// Set ssl validation
|
||||
this.sslValidate = this.options.sslValidate == null ? false : this.options.sslValidate;
|
||||
// Set the ssl certificate authority (array of Buffer/String keys)
|
||||
this.sslCA = Array.isArray(this.options.sslCA) ? this.options.sslCA : null;
|
||||
// Certificate to present to the server
|
||||
this.sslCert = this.options.sslCert;
|
||||
// Certificate private key if in separate file
|
||||
this.sslKey = this.options.sslKey;
|
||||
// Password to unlock private key
|
||||
this.sslPass = this.options.sslPass;
|
||||
|
||||
// Ensure we are not trying to validate with no list of certificates
|
||||
if(this.sslValidate && (!Array.isArray(this.sslCA) || this.sslCA.length == 0)) {
|
||||
throw new Error("The driver expects an Array of CA certificates in the sslCA parameter when enabling sslValidate");
|
||||
}
|
||||
|
||||
// Get the readPreference
|
||||
var readPreference = this.options['readPreference'];
|
||||
// If readPreference is an object get the mode string
|
||||
var validateReadPreference = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference;
|
||||
// Read preference setting
|
||||
if(validateReadPreference != null) {
|
||||
if(validateReadPreference != ReadPreference.PRIMARY && validateReadPreference != ReadPreference.SECONDARY && validateReadPreference != ReadPreference.NEAREST
|
||||
&& validateReadPreference != ReadPreference.SECONDARY_PREFERRED && validateReadPreference != ReadPreference.PRIMARY_PREFERRED) {
|
||||
throw new Error("Illegal readPreference mode specified, " + validateReadPreference);
|
||||
}
|
||||
|
||||
// Set read Preference
|
||||
this._readPreference = readPreference;
|
||||
} else {
|
||||
this._readPreference = null;
|
||||
}
|
||||
|
||||
// Contains the isMaster information returned from the server
|
||||
this.isMasterDoc;
|
||||
|
||||
// Set default connection pool options
|
||||
this.socketOptions = this.options.socketOptions != null ? this.options.socketOptions : {};
|
||||
if(this.disableDriverBSONSizeCheck) this.socketOptions.disableDriverBSONSizeCheck = this.disableDriverBSONSizeCheck;
|
||||
|
||||
// Set ssl up if it's defined
|
||||
if(this.ssl) {
|
||||
this.socketOptions.ssl = true;
|
||||
// Set ssl validation
|
||||
this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate;
|
||||
// Set the ssl certificate authority (array of Buffer/String keys)
|
||||
this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null;
|
||||
// Set certificate to present
|
||||
this.socketOptions.sslCert = this.sslCert;
|
||||
// Set certificate to present
|
||||
this.socketOptions.sslKey = this.sslKey;
|
||||
// Password to unlock private key
|
||||
this.socketOptions.sslPass = this.sslPass;
|
||||
}
|
||||
|
||||
// Set up logger if any set
|
||||
this.logger = this.options.logger != null
|
||||
&& (typeof this.options.logger.debug == 'function')
|
||||
&& (typeof this.options.logger.error == 'function')
|
||||
&& (typeof this.options.logger.log == 'function')
|
||||
? this.options.logger : {error:function(message, object) {}, log:function(message, object) {}, debug:function(message, object) {}};
|
||||
|
||||
// Just keeps list of events we allow
|
||||
this.eventHandlers = {error:[], parseError:[], poolReady:[], message:[], close:[], timeout:[]};
|
||||
// Internal state of server connection
|
||||
this._serverState = 'disconnected';
|
||||
// this._timeout = false;
|
||||
// Contains state information about server connection
|
||||
this._state = {'runtimeStats': {'queryStats':new RunningStats()}};
|
||||
// Do we record server stats or not
|
||||
this.recordQueryStats = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
inherits(Server, Base);
|
||||
|
||||
//
|
||||
// Deprecated, USE ReadPreferences class
|
||||
//
|
||||
Server.READ_PRIMARY = ReadPreference.PRIMARY;
|
||||
Server.READ_SECONDARY = ReadPreference.SECONDARY_PREFERRED;
|
||||
Server.READ_SECONDARY_ONLY = ReadPreference.SECONDARY;
|
||||
|
||||
/**
|
||||
* Always ourselves
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.setReadPreference = function() {}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.isMongos = function() {
|
||||
return this.isMasterDoc != null && this.isMasterDoc['msg'] == "isdbgrid" ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype._isUsed = function() {
|
||||
return this._used;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.close = function(callback) {
|
||||
// Remove all local listeners
|
||||
this.removeAllListeners();
|
||||
|
||||
if(this.connectionPool != null) {
|
||||
// Remove all the listeners on the pool so it does not fire messages all over the place
|
||||
this.connectionPool.removeAllEventListeners();
|
||||
// Close the connection if it's open
|
||||
this.connectionPool.stop(true);
|
||||
}
|
||||
|
||||
// Set server status as disconnected
|
||||
this._serverState = 'disconnected';
|
||||
// Peform callback if present
|
||||
if(typeof callback === 'function') callback(null);
|
||||
};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.isConnected = function() {
|
||||
return this._serverState == 'connected';
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.allServerInstances = function() {
|
||||
return [this];
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.isSetMember = function() {
|
||||
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) {
|
||||
// Set ssl on
|
||||
this.socketOptions.ssl = true;
|
||||
// Set ssl validation
|
||||
this.socketOptions.sslValidate = replset.sslValidate == null ? false : replset.sslValidate;
|
||||
// Set the ssl certificate authority (array of Buffer/String keys)
|
||||
this.socketOptions.sslCA = Array.isArray(replset.sslCA) ? replset.sslCA : null;
|
||||
// Set certificate to present
|
||||
this.socketOptions.sslCert = replset.sslCert;
|
||||
// Set certificate to present
|
||||
this.socketOptions.sslKey = replset.sslKey;
|
||||
// Password to unlock private key
|
||||
this.socketOptions.sslPass = replset.sslPass;
|
||||
}
|
||||
|
||||
// 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) {
|
||||
if('function' === typeof options) callback = options, options = {};
|
||||
if(options == null) options = {};
|
||||
if(!('function' === typeof callback)) callback = null;
|
||||
|
||||
// Currently needed to work around problems with multiple connections in a pool with ssl
|
||||
// TODO fix if possible
|
||||
if(this.ssl == true) {
|
||||
// Set up socket options for ssl
|
||||
this.socketOptions.ssl = true;
|
||||
// Set ssl validation
|
||||
this.socketOptions.sslValidate = this.sslValidate == null ? false : this.sslValidate;
|
||||
// Set the ssl certificate authority (array of Buffer/String keys)
|
||||
this.socketOptions.sslCA = Array.isArray(this.sslCA) ? this.sslCA : null;
|
||||
// Set certificate to present
|
||||
this.socketOptions.sslCert = this.sslCert;
|
||||
// Set certificate to present
|
||||
this.socketOptions.sslKey = this.sslKey;
|
||||
// Password to unlock private key
|
||||
this.socketOptions.sslPass = this.sslPass;
|
||||
}
|
||||
|
||||
// Let's connect
|
||||
var server = this;
|
||||
// Let's us override the main receiver of events
|
||||
var eventReceiver = options.eventReceiver != null ? options.eventReceiver : this;
|
||||
// Save reference to dbInstance
|
||||
this.db = dbInstance; // `db` property matches ReplSet and Mongos
|
||||
this.dbInstances = [dbInstance];
|
||||
|
||||
// Force connection pool if there is one
|
||||
if(server.connectionPool) server.connectionPool.stop();
|
||||
|
||||
// Set server state to connecting
|
||||
this._serverState = 'connecting';
|
||||
// Ensure dbInstance can do a slave query if it's set
|
||||
dbInstance.slaveOk = this.slaveOk ? this.slaveOk : dbInstance.slaveOk;
|
||||
// Create connection Pool instance with the current BSON serializer
|
||||
var connectionPool = new ConnectionPool(this.host, this.port, this.poolSize, dbInstance.bson, this.socketOptions);
|
||||
// If ssl is not enabled don't wait between the pool connections
|
||||
if(this.ssl == null || !this.ssl) connectionPool._timeToWait = null;
|
||||
// Set logger on pool
|
||||
connectionPool.logger = this.logger;
|
||||
|
||||
// Set up a new pool using default settings
|
||||
server.connectionPool = connectionPool;
|
||||
|
||||
// Set basic parameters passed in
|
||||
var returnIsMasterResults = options.returnIsMasterResults == null ? false : options.returnIsMasterResults;
|
||||
|
||||
// Create a default connect handler, overriden when using replicasets
|
||||
var connectCallback = function(err, reply) {
|
||||
// ensure no callbacks get called twice
|
||||
var internalCallback = callback;
|
||||
callback = null;
|
||||
// If something close down the connection and removed the callback before
|
||||
// proxy killed connection etc, ignore the erorr as close event was isssued
|
||||
if(err != null && internalCallback == null) return;
|
||||
// Internal callback
|
||||
if(err != null) return internalCallback(err, null, server);
|
||||
server.master = reply.documents[0].ismaster == 1 ? true : false;
|
||||
server.connectionPool.setMaxBsonSize(reply.documents[0].maxBsonObjectSize);
|
||||
server.connectionPool.setMaxMessageSizeBytes(reply.documents[0].maxMessageSizeBytes);
|
||||
// Set server as connected
|
||||
server.connected = true;
|
||||
// Save document returned so we can query it
|
||||
server.isMasterDoc = reply.documents[0];
|
||||
|
||||
// Emit open event
|
||||
_emitAcrossAllDbInstances(server, eventReceiver, "open", null, returnIsMasterResults ? reply : dbInstance, null);
|
||||
|
||||
// If we have it set to returnIsMasterResults
|
||||
if(returnIsMasterResults) {
|
||||
internalCallback(null, reply, server);
|
||||
} else {
|
||||
internalCallback(null, dbInstance, server);
|
||||
}
|
||||
};
|
||||
|
||||
// Let's us override the main connect callback
|
||||
var connectHandler = options.connectHandler == null ? connectCallback : options.connectHandler;
|
||||
|
||||
// Set up on connect method
|
||||
connectionPool.on("poolReady", function() {
|
||||
// Create db command and Add the callback to the list of callbacks by the request id (mapping outgoing messages to correct callbacks)
|
||||
var db_command = DbCommand.NcreateIsMasterCommand(dbInstance, dbInstance.databaseName);
|
||||
// Check out a reader from the pool
|
||||
var connection = connectionPool.checkoutConnection();
|
||||
// Set server state to connEcted
|
||||
server._serverState = 'connected';
|
||||
|
||||
// Register handler for messages
|
||||
server._registerHandler(db_command, false, connection, connectHandler);
|
||||
|
||||
// Write the command out
|
||||
connection.write(db_command);
|
||||
})
|
||||
|
||||
// Set up item connection
|
||||
connectionPool.on("message", function(message) {
|
||||
// Attempt to parse the message
|
||||
try {
|
||||
// Create a new mongo reply
|
||||
var mongoReply = new MongoReply()
|
||||
// Parse the header
|
||||
mongoReply.parseHeader(message, connectionPool.bson)
|
||||
|
||||
// If message size is not the same as the buffer size
|
||||
// something went terribly wrong somewhere
|
||||
if(mongoReply.messageLength != message.length) {
|
||||
// Emit the error
|
||||
if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", new Error("bson length is different from message length"), server);
|
||||
// Remove all listeners
|
||||
server.removeAllListeners();
|
||||
} else {
|
||||
var startDate = new Date().getTime();
|
||||
|
||||
// Callback instance
|
||||
var callbackInfo = server._findHandler(mongoReply.responseTo.toString());
|
||||
|
||||
// The command executed another request, log the handler again under that request id
|
||||
if(mongoReply.requestId > 0 && mongoReply.cursorId.toString() != "0"
|
||||
&& callbackInfo && callbackInfo.info && callbackInfo.info.exhaust) {
|
||||
server._reRegisterHandler(mongoReply.requestId, callbackInfo);
|
||||
}
|
||||
|
||||
// Only execute callback if we have a caller
|
||||
// chained is for findAndModify as it does not respect write concerns
|
||||
if(callbackInfo && callbackInfo.callback && callbackInfo.info && Array.isArray(callbackInfo.info.chained)) {
|
||||
// Check if callback has already been fired (missing chain command)
|
||||
var chained = callbackInfo.info.chained;
|
||||
var numberOfFoundCallbacks = 0;
|
||||
for(var i = 0; i < chained.length; i++) {
|
||||
if(server._hasHandler(chained[i])) numberOfFoundCallbacks++;
|
||||
}
|
||||
|
||||
// If we have already fired then clean up rest of chain and move on
|
||||
if(numberOfFoundCallbacks != chained.length) {
|
||||
for(var i = 0; i < chained.length; i++) {
|
||||
server._removeHandler(chained[i]);
|
||||
}
|
||||
|
||||
// Just return from function
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the body
|
||||
mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) {
|
||||
if(err != null) {
|
||||
// If pool connection is already closed
|
||||
if(server._serverState === 'disconnected') return;
|
||||
// Set server state to disconnected
|
||||
server._serverState = 'disconnected';
|
||||
// Remove all listeners and close the connection pool
|
||||
server.removeAllListeners();
|
||||
connectionPool.stop(true);
|
||||
|
||||
// If we have a callback return the error
|
||||
if(typeof callback === 'function') {
|
||||
// ensure no callbacks get called twice
|
||||
var internalCallback = callback;
|
||||
callback = null;
|
||||
// Perform callback
|
||||
internalCallback(new Error("connection closed due to parseError"), null, server);
|
||||
} else if(server.isSetMember()) {
|
||||
if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server);
|
||||
} else {
|
||||
if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server);
|
||||
}
|
||||
|
||||
// If we are a single server connection fire errors correctly
|
||||
if(!server.isSetMember()) {
|
||||
// Fire all callback errors
|
||||
server.__executeAllCallbacksWithError(new Error("connection closed due to parseError"));
|
||||
// Emit error
|
||||
_emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);
|
||||
}
|
||||
// Short cut
|
||||
return;
|
||||
}
|
||||
|
||||
// Fetch the callback
|
||||
var callbackInfo = server._findHandler(mongoReply.responseTo.toString());
|
||||
// If we have an error let's execute the callback and clean up all other
|
||||
// chained commands
|
||||
var firstResult = mongoReply && mongoReply.documents;
|
||||
|
||||
// Check for an error, if we have one let's trigger the callback and clean up
|
||||
// The chained callbacks
|
||||
if(firstResult[0].err != null || firstResult[0].errmsg != null) {
|
||||
// Trigger the callback for the error
|
||||
server._callHandler(mongoReply.responseTo, mongoReply, null);
|
||||
} else {
|
||||
var chainedIds = callbackInfo.info.chained;
|
||||
|
||||
if(chainedIds.length > 0 && chainedIds[chainedIds.length - 1] == mongoReply.responseTo) {
|
||||
// Cleanup all other chained calls
|
||||
chainedIds.pop();
|
||||
// Remove listeners
|
||||
for(var i = 0; i < chainedIds.length; i++) server._removeHandler(chainedIds[i]);
|
||||
// Call the handler
|
||||
server._callHandler(mongoReply.responseTo, callbackInfo.info.results.shift(), null);
|
||||
} else{
|
||||
// Add the results to all the results
|
||||
for(var i = 0; i < chainedIds.length; i++) {
|
||||
var handler = server._findHandler(chainedIds[i]);
|
||||
// Check if we have an object, if it's the case take the current object commands and
|
||||
// and add this one
|
||||
if(handler.info != null) {
|
||||
handler.info.results = Array.isArray(callbackInfo.info.results) ? callbackInfo.info.results : [];
|
||||
handler.info.results.push(mongoReply);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
} else if(callbackInfo && callbackInfo.callback && callbackInfo.info) {
|
||||
// Parse the body
|
||||
mongoReply.parseBody(message, connectionPool.bson, callbackInfo.info.raw, function(err) {
|
||||
if(err != null) {
|
||||
// If pool connection is already closed
|
||||
if(server._serverState === 'disconnected') return;
|
||||
// Set server state to disconnected
|
||||
server._serverState = 'disconnected';
|
||||
// Remove all listeners and close the connection pool
|
||||
server.removeAllListeners();
|
||||
connectionPool.stop(true);
|
||||
|
||||
// If we have a callback return the error
|
||||
if(typeof callback === 'function') {
|
||||
// ensure no callbacks get called twice
|
||||
var internalCallback = callback;
|
||||
callback = null;
|
||||
// Perform callback
|
||||
internalCallback(new Error("connection closed due to parseError"), null, server);
|
||||
} else if(server.isSetMember()) {
|
||||
if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server);
|
||||
} else {
|
||||
if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server);
|
||||
}
|
||||
|
||||
// If we are a single server connection fire errors correctly
|
||||
if(!server.isSetMember()) {
|
||||
// Fire all callback errors
|
||||
server.__executeAllCallbacksWithError(new Error("connection closed due to parseError"));
|
||||
// Emit error
|
||||
_emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);
|
||||
}
|
||||
// Short cut
|
||||
return;
|
||||
}
|
||||
|
||||
// Let's record the stats info if it's enabled
|
||||
if(server.recordQueryStats == true && server._state['runtimeStats'] != null
|
||||
&& server._state.runtimeStats['queryStats'] instanceof RunningStats) {
|
||||
// Add data point to the running statistics object
|
||||
server._state.runtimeStats.queryStats.push(new Date().getTime() - callbackInfo.info.start);
|
||||
}
|
||||
|
||||
server._callHandler(mongoReply.responseTo, mongoReply, null);
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
// Throw error in next tick
|
||||
processor(function() {
|
||||
throw err;
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
// Handle timeout
|
||||
connectionPool.on("timeout", function(err) {
|
||||
// If pool connection is already closed
|
||||
if(server._serverState === 'disconnected') return;
|
||||
// Set server state to disconnected
|
||||
server._serverState = 'disconnected';
|
||||
// If we have a callback return the error
|
||||
if(typeof callback === 'function') {
|
||||
// ensure no callbacks get called twice
|
||||
var internalCallback = callback;
|
||||
callback = null;
|
||||
// Perform callback
|
||||
internalCallback(err, null, server);
|
||||
} else if(server.isSetMember()) {
|
||||
if(server.listeners("timeout") && server.listeners("timeout").length > 0) server.emit("timeout", err, server);
|
||||
} else {
|
||||
if(eventReceiver.listeners("timeout") && eventReceiver.listeners("timeout").length > 0) eventReceiver.emit("timeout", err, server);
|
||||
}
|
||||
|
||||
// If we are a single server connection fire errors correctly
|
||||
if(!server.isSetMember()) {
|
||||
// Fire all callback errors
|
||||
server.__executeAllCallbacksWithError(err);
|
||||
// Emit error
|
||||
_emitAcrossAllDbInstances(server, eventReceiver, "timeout", err, server, true);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle errors
|
||||
connectionPool.on("error", function(message, connection, error_options) {
|
||||
// If pool connection is already closed
|
||||
if(server._serverState === 'disconnected') return;
|
||||
// Set server state to disconnected
|
||||
server._serverState = 'disconnected';
|
||||
// Error message
|
||||
var error_message = new Error(message && message.err ? message.err : message);
|
||||
// Error message coming from ssl
|
||||
if(error_options && error_options.ssl) error_message.ssl = true;
|
||||
// If we have a callback return the error
|
||||
if(typeof callback === 'function') {
|
||||
// ensure no callbacks get called twice
|
||||
var internalCallback = callback;
|
||||
callback = null;
|
||||
// Perform callback
|
||||
internalCallback(error_message, null, server);
|
||||
} else if(server.isSetMember()) {
|
||||
if(server.listeners("error") && server.listeners("error").length > 0) server.emit("error", error_message, server);
|
||||
} else {
|
||||
if(eventReceiver.listeners("error") && eventReceiver.listeners("error").length > 0) eventReceiver.emit("error", error_message, server);
|
||||
}
|
||||
|
||||
// If we are a single server connection fire errors correctly
|
||||
if(!server.isSetMember()) {
|
||||
// Fire all callback errors
|
||||
server.__executeAllCallbacksWithError(error_message);
|
||||
// Emit error
|
||||
_emitAcrossAllDbInstances(server, eventReceiver, "error", error_message, server, true);
|
||||
}
|
||||
});
|
||||
|
||||
// Handle close events
|
||||
connectionPool.on("close", function() {
|
||||
// If pool connection is already closed
|
||||
if(server._serverState === 'disconnected') return;
|
||||
// Set server state to disconnected
|
||||
server._serverState = 'disconnected';
|
||||
// If we have a callback return the error
|
||||
if(typeof callback == 'function') {
|
||||
// ensure no callbacks get called twice
|
||||
var internalCallback = callback;
|
||||
callback = null;
|
||||
// Perform callback
|
||||
internalCallback(new Error("connection closed"), null, server);
|
||||
} else if(server.isSetMember()) {
|
||||
if(server.listeners("close") && server.listeners("close").length > 0) server.emit("close", new Error("connection closed"), server);
|
||||
} else {
|
||||
if(eventReceiver.listeners("close") && eventReceiver.listeners("close").length > 0) eventReceiver.emit("close", new Error("connection closed"), server);
|
||||
}
|
||||
|
||||
// If we are a single server connection fire errors correctly
|
||||
if(!server.isSetMember()) {
|
||||
// Fire all callback errors
|
||||
server.__executeAllCallbacksWithError(new Error("connection closed"));
|
||||
// Emit error
|
||||
_emitAcrossAllDbInstances(server, eventReceiver, "close", server, null, true);
|
||||
}
|
||||
});
|
||||
|
||||
// If we have a parser error we are in an unknown state, close everything and emit
|
||||
// error
|
||||
connectionPool.on("parseError", function(message) {
|
||||
// If pool connection is already closed
|
||||
if(server._serverState === 'disconnected') return;
|
||||
// Set server state to disconnected
|
||||
server._serverState = 'disconnected';
|
||||
// If we have a callback return the error
|
||||
if(typeof callback === 'function') {
|
||||
// ensure no callbacks get called twice
|
||||
var internalCallback = callback;
|
||||
callback = null;
|
||||
// Perform callback
|
||||
internalCallback(new Error("connection closed due to parseError"), null, server);
|
||||
} else if(server.isSetMember()) {
|
||||
if(server.listeners("parseError") && server.listeners("parseError").length > 0) server.emit("parseError", new Error("connection closed due to parseError"), server);
|
||||
} else {
|
||||
if(eventReceiver.listeners("parseError") && eventReceiver.listeners("parseError").length > 0) eventReceiver.emit("parseError", new Error("connection closed due to parseError"), server);
|
||||
}
|
||||
|
||||
// If we are a single server connection fire errors correctly
|
||||
if(!server.isSetMember()) {
|
||||
// Fire all callback errors
|
||||
server.__executeAllCallbacksWithError(new Error("connection closed due to parseError"));
|
||||
// Emit error
|
||||
_emitAcrossAllDbInstances(server, eventReceiver, "parseError", server, null, true);
|
||||
}
|
||||
});
|
||||
|
||||
// Boot up connection poole, pass in a locator of callbacks
|
||||
connectionPool.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
var _emitAcrossAllDbInstances = function(server, filterDb, event, message, object, resetConnection) {
|
||||
// Emit close event across all db instances sharing the sockets
|
||||
var allServerInstances = server.allServerInstances();
|
||||
// Fetch the first server instance
|
||||
var serverInstance = allServerInstances[0];
|
||||
// For all db instances signal all db instances
|
||||
if(Array.isArray(serverInstance.dbInstances) && serverInstance.dbInstances.length >= 1) {
|
||||
for(var i = 0; i < serverInstance.dbInstances.length; i++) {
|
||||
var dbInstance = serverInstance.dbInstances[i];
|
||||
// Set the parent
|
||||
if(resetConnection && typeof dbInstance.openCalled != 'undefined')
|
||||
dbInstance.openCalled = false;
|
||||
// Check if it's our current db instance and skip if it is
|
||||
if(filterDb == null || filterDb.databaseName !== dbInstance.databaseName || filterDb.tag !== dbInstance.tag) {
|
||||
// Only emit if there is a listener
|
||||
if(dbInstance.listeners(event).length > 0)
|
||||
dbInstance.emit(event, message, object);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.allRawConnections = function() {
|
||||
return this.connectionPool.getAllConnections();
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a writer can be provided
|
||||
* @ignore
|
||||
*/
|
||||
var canCheckoutWriter = function(self, read) {
|
||||
// We cannot write to an arbiter or secondary server
|
||||
if(self.isMasterDoc['arbiterOnly'] == true) {
|
||||
return new Error("Cannot write to an arbiter");
|
||||
} if(self.isMasterDoc['secondary'] == true) {
|
||||
return new Error("Cannot write to a secondary");
|
||||
} else if(read == true && self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) {
|
||||
return new Error("Cannot read from primary when secondary only specified");
|
||||
}
|
||||
|
||||
// Return no error
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.checkoutWriter = function(read) {
|
||||
if(read == true) return this.connectionPool.checkoutConnection();
|
||||
// Check if are allowed to do a checkout (if we try to use an arbiter f.ex)
|
||||
var result = canCheckoutWriter(this, read);
|
||||
// If the result is null check out a writer
|
||||
if(result == null && this.connectionPool != null) {
|
||||
return this.connectionPool.checkoutConnection();
|
||||
} else if(result == null) {
|
||||
return null;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a reader can be provided
|
||||
* @ignore
|
||||
*/
|
||||
var canCheckoutReader = function(self) {
|
||||
// We cannot write to an arbiter or secondary server
|
||||
if(self.isMasterDoc && self.isMasterDoc['arbiterOnly'] == true) {
|
||||
return new Error("Cannot write to an arbiter");
|
||||
} else if(self._readPreference != null) {
|
||||
// If the read preference is Primary and the instance is not a master return an error
|
||||
if((self._readPreference == ReadPreference.PRIMARY) && self.isMasterDoc['ismaster'] != true) {
|
||||
return new Error("Read preference is Server.PRIMARY and server is not master");
|
||||
} else if(self._readPreference == ReadPreference.SECONDARY && self.isMasterDoc['ismaster'] == true) {
|
||||
return new Error("Cannot read from primary when secondary only specified");
|
||||
}
|
||||
}
|
||||
|
||||
// Return no error
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.checkoutReader = function() {
|
||||
// Check if are allowed to do a checkout (if we try to use an arbiter f.ex)
|
||||
var result = canCheckoutReader(this);
|
||||
// If the result is null check out a writer
|
||||
if(result == null && this.connectionPool != null) {
|
||||
return this.connectionPool.checkoutConnection();
|
||||
} else if(result == null) {
|
||||
return null;
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Server.prototype.enableRecordQueryStats = function(enable) {
|
||||
this.recordQueryStats = enable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal statistics object used for calculating average and standard devitation on
|
||||
* running queries
|
||||
* @ignore
|
||||
*/
|
||||
var RunningStats = function() {
|
||||
var self = this;
|
||||
this.m_n = 0;
|
||||
this.m_oldM = 0.0;
|
||||
this.m_oldS = 0.0;
|
||||
this.m_newM = 0.0;
|
||||
this.m_newS = 0.0;
|
||||
|
||||
// Define getters
|
||||
Object.defineProperty(this, "numDataValues", { enumerable: true
|
||||
, get: function () { return this.m_n; }
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "mean", { enumerable: true
|
||||
, get: function () { return (this.m_n > 0) ? this.m_newM : 0.0; }
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "variance", { enumerable: true
|
||||
, get: function () { return ((this.m_n > 1) ? this.m_newS/(this.m_n - 1) : 0.0); }
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "standardDeviation", { enumerable: true
|
||||
, get: function () { return Math.sqrt(this.variance); }
|
||||
});
|
||||
|
||||
Object.defineProperty(this, "sScore", { enumerable: true
|
||||
, get: function () {
|
||||
var bottom = this.mean + this.standardDeviation;
|
||||
if(bottom == 0) return 0;
|
||||
return ((2 * this.mean * this.standardDeviation)/(bottom));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
RunningStats.prototype.push = function(x) {
|
||||
// Update the number of samples
|
||||
this.m_n = this.m_n + 1;
|
||||
// See Knuth TAOCP vol 2, 3rd edition, page 232
|
||||
if(this.m_n == 1) {
|
||||
this.m_oldM = this.m_newM = x;
|
||||
this.m_oldS = 0.0;
|
||||
} else {
|
||||
this.m_newM = this.m_oldM + (x - this.m_oldM) / this.m_n;
|
||||
this.m_newS = this.m_oldS + (x - this.m_oldM) * (x - this.m_newM);
|
||||
|
||||
// set up for next iteration
|
||||
this.m_oldM = this.m_newM;
|
||||
this.m_oldS = this.m_newS;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Object.defineProperty(Server.prototype, "autoReconnect", { enumerable: true
|
||||
, get: function () {
|
||||
return this.options['auto_reconnect'] == null ? false : this.options['auto_reconnect'];
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Object.defineProperty(Server.prototype, "connection", { enumerable: true
|
||||
, get: function () {
|
||||
return this.internalConnection;
|
||||
}
|
||||
, set: function(connection) {
|
||||
this.internalConnection = connection;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Object.defineProperty(Server.prototype, "master", { enumerable: true
|
||||
, get: function () {
|
||||
return this.internalMaster;
|
||||
}
|
||||
, set: function(value) {
|
||||
this.internalMaster = value;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Object.defineProperty(Server.prototype, "primary", { enumerable: true
|
||||
, get: function () {
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Getter for query Stats
|
||||
* @ignore
|
||||
*/
|
||||
Object.defineProperty(Server.prototype, "queryStats", { enumerable: true
|
||||
, get: function () {
|
||||
return this._state.runtimeStats.queryStats;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Object.defineProperty(Server.prototype, "runtimeStats", { enumerable: true
|
||||
, get: function () {
|
||||
return this._state.runtimeStats;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Get Read Preference method
|
||||
* @ignore
|
||||
*/
|
||||
Object.defineProperty(Server.prototype, "readPreference", { enumerable: true
|
||||
, get: function () {
|
||||
if(this._readPreference == null && this.readSecondary) {
|
||||
return Server.READ_SECONDARY;
|
||||
} else if(this._readPreference == null && !this.readSecondary) {
|
||||
return Server.READ_PRIMARY;
|
||||
} else {
|
||||
return this._readPreference;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
exports.Server = Server;
|
||||
290
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js
generated
vendored
Normal file
290
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/strategies/ping_strategy.js
generated
vendored
Normal file
@@ -0,0 +1,290 @@
|
||||
var Server = require("../server").Server
|
||||
, format = require('util').format;
|
||||
|
||||
// The ping strategy uses pings each server and records the
|
||||
// elapsed time for the server so it can pick a server based on lowest
|
||||
// return time for the db command {ping:true}
|
||||
var PingStrategy = exports.PingStrategy = function(replicaset, secondaryAcceptableLatencyMS) {
|
||||
this.replicaset = replicaset;
|
||||
this.secondaryAcceptableLatencyMS = secondaryAcceptableLatencyMS;
|
||||
this.state = 'disconnected';
|
||||
this.pingInterval = 5000;
|
||||
// Class instance
|
||||
this.Db = require("../../db").Db;
|
||||
// Active db connections
|
||||
this.dbs = {};
|
||||
// Logger api
|
||||
this.Logger = null;
|
||||
}
|
||||
|
||||
// Starts any needed code
|
||||
PingStrategy.prototype.start = function(callback) {
|
||||
// already running?
|
||||
if ('connected' == this.state) return;
|
||||
|
||||
this.state = 'connected';
|
||||
|
||||
// Start ping server
|
||||
this._pingServer(callback);
|
||||
}
|
||||
|
||||
// Stops and kills any processes running
|
||||
PingStrategy.prototype.stop = function(callback) {
|
||||
// Stop the ping process
|
||||
this.state = 'disconnected';
|
||||
|
||||
// Stop all the server instances
|
||||
for(var key in this.dbs) {
|
||||
this.dbs[key].close();
|
||||
}
|
||||
|
||||
// optional callback
|
||||
callback && callback(null, null);
|
||||
}
|
||||
|
||||
PingStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) {
|
||||
// Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS
|
||||
// Create a list of candidat servers, containing the primary if available
|
||||
var candidateServers = [];
|
||||
var self = this;
|
||||
|
||||
// If we have not provided a list of candidate servers use the default setup
|
||||
if(!Array.isArray(secondaryCandidates)) {
|
||||
candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : [];
|
||||
// Add all the secondaries
|
||||
var keys = Object.keys(this.replicaset._state.secondaries);
|
||||
for(var i = 0; i < keys.length; i++) {
|
||||
candidateServers.push(this.replicaset._state.secondaries[keys[i]])
|
||||
}
|
||||
} else {
|
||||
candidateServers = secondaryCandidates;
|
||||
}
|
||||
|
||||
// Final list of eligable server
|
||||
var finalCandidates = [];
|
||||
|
||||
// If we have tags filter by tags
|
||||
if(tags != null && typeof tags == 'object') {
|
||||
// If we have an array or single tag selection
|
||||
var tagObjects = Array.isArray(tags) ? tags : [tags];
|
||||
// Iterate over all tags until we find a candidate server
|
||||
for(var _i = 0; _i < tagObjects.length; _i++) {
|
||||
// Grab a tag object
|
||||
var tagObject = tagObjects[_i];
|
||||
// Matching keys
|
||||
var matchingKeys = Object.keys(tagObject);
|
||||
// Remove any that are not tagged correctly
|
||||
for(var i = 0; i < candidateServers.length; i++) {
|
||||
var server = candidateServers[i];
|
||||
// If we have tags match
|
||||
if(server.tags != null) {
|
||||
var matching = true;
|
||||
|
||||
// Ensure we have all the values
|
||||
for(var j = 0; j < matchingKeys.length; j++) {
|
||||
if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
|
||||
matching = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a match add it to the list of matching servers
|
||||
if(matching) {
|
||||
finalCandidates.push(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Final array candidates
|
||||
var finalCandidates = candidateServers;
|
||||
}
|
||||
|
||||
// Sort by ping time
|
||||
finalCandidates.sort(function(a, b) {
|
||||
return a.runtimeStats['pingMs'] > b.runtimeStats['pingMs'];
|
||||
});
|
||||
|
||||
if(0 === finalCandidates.length)
|
||||
return new Error("No replica set members available for query");
|
||||
|
||||
// find lowest server with a ping time
|
||||
var lowest = finalCandidates.filter(function (server) {
|
||||
return undefined != server.runtimeStats.pingMs;
|
||||
})[0];
|
||||
|
||||
if(!lowest) {
|
||||
lowest = finalCandidates[0];
|
||||
}
|
||||
|
||||
// convert to integer
|
||||
var lowestPing = lowest.runtimeStats.pingMs | 0;
|
||||
|
||||
// determine acceptable latency
|
||||
var acceptable = lowestPing + this.secondaryAcceptableLatencyMS;
|
||||
|
||||
// remove any server responding slower than acceptable
|
||||
var len = finalCandidates.length;
|
||||
while(len--) {
|
||||
if(finalCandidates[len].runtimeStats['pingMs'] > acceptable) {
|
||||
finalCandidates.splice(len, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(self.logger && self.logger.debug) {
|
||||
self.logger.debug("Ping strategy selection order for tags", tags);
|
||||
finalCandidates.forEach(function(c) {
|
||||
self.logger.debug(format("%s:%s = %s ms", c.host, c.port, c.runtimeStats['pingMs']), null);
|
||||
})
|
||||
}
|
||||
|
||||
// If no candidates available return an error
|
||||
if(finalCandidates.length == 0)
|
||||
return new Error("No replica set members available for query");
|
||||
|
||||
// Pick a random acceptable server
|
||||
var connection = finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader();
|
||||
if(self.logger && self.logger.debug) {
|
||||
if(connection)
|
||||
self.logger.debug("picked server %s:%s", connection.socketOptions.host, connection.socketOptions.port);
|
||||
}
|
||||
return connection;
|
||||
}
|
||||
|
||||
PingStrategy.prototype._pingServer = function(callback) {
|
||||
var self = this;
|
||||
|
||||
// Ping server function
|
||||
var pingFunction = function() {
|
||||
if(self.state == 'disconnected') return;
|
||||
|
||||
// Create a list of all servers we can send the ismaster command to
|
||||
var allServers = self.replicaset._state.master != null ? [self.replicaset._state.master] : [];
|
||||
|
||||
// Secondary keys
|
||||
var keys = Object.keys(self.replicaset._state.secondaries);
|
||||
// Add all secondaries
|
||||
for(var i = 0; i < keys.length; i++) {
|
||||
allServers.push(self.replicaset._state.secondaries[keys[i]]);
|
||||
}
|
||||
|
||||
// Number of server entries
|
||||
var numberOfEntries = allServers.length;
|
||||
|
||||
// We got keys
|
||||
for(var i = 0; i < allServers.length; i++) {
|
||||
|
||||
// We got a server instance
|
||||
var server = allServers[i];
|
||||
|
||||
// Create a new server object, avoid using internal connections as they might
|
||||
// be in an illegal state
|
||||
new function(serverInstance) {
|
||||
var _db = self.dbs[serverInstance.host + ":" + serverInstance.port];
|
||||
// If we have a db
|
||||
if(_db != null) {
|
||||
// Startup time of the command
|
||||
var startTime = Date.now();
|
||||
|
||||
// Execute ping command in own scope
|
||||
var _ping = function(__db, __serverInstance) {
|
||||
// Execute ping on this connection
|
||||
__db.executeDbCommand({ping:1}, {failFast:true}, function(err) {
|
||||
if(err) {
|
||||
delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
|
||||
__db.close();
|
||||
return done();
|
||||
}
|
||||
|
||||
if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
|
||||
__serverInstance.runtimeStats['pingMs'] = Date.now() - startTime;
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
};
|
||||
// Ping
|
||||
_ping(_db, serverInstance);
|
||||
} else {
|
||||
// Create a new master connection
|
||||
var _server = new Server(serverInstance.host, serverInstance.port, {
|
||||
auto_reconnect: false,
|
||||
returnIsMasterResults: true,
|
||||
slaveOk: true,
|
||||
poolSize: 1,
|
||||
socketOptions: { connectTimeoutMS: self.replicaset._connectTimeoutMS },
|
||||
ssl: self.replicaset.ssl,
|
||||
sslValidate: self.replicaset.sslValidate,
|
||||
sslCA: self.replicaset.sslCA,
|
||||
sslCert: self.replicaset.sslCert,
|
||||
sslKey: self.replicaset.sslKey,
|
||||
sslPass: self.replicaset.sslPass
|
||||
});
|
||||
|
||||
// Create Db instance
|
||||
var _db = new self.Db(self.replicaset.db.databaseName, _server, { safe: true });
|
||||
_db.on("close", function() {
|
||||
delete self.dbs[this.serverConfig.host + ":" + this.serverConfig.port];
|
||||
})
|
||||
|
||||
var _ping = function(__db, __serverInstance) {
|
||||
if(self.state == 'disconnected') {
|
||||
self.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
__db.open(function(err, db) {
|
||||
if(self.state == 'disconnected' && __db != null) {
|
||||
return __db.close();
|
||||
}
|
||||
|
||||
if(err) {
|
||||
delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
|
||||
__db.close();
|
||||
return done();
|
||||
}
|
||||
|
||||
// Save instance
|
||||
self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port] = __db;
|
||||
|
||||
// Startup time of the command
|
||||
var startTime = Date.now();
|
||||
|
||||
// Execute ping on this connection
|
||||
__db.executeDbCommand({ping:1}, {failFast:true}, function(err) {
|
||||
if(err) {
|
||||
delete self.dbs[__db.serverConfig.host + ":" + __db.serverConfig.port];
|
||||
__db.close();
|
||||
return done();
|
||||
}
|
||||
|
||||
if(null != __serverInstance.runtimeStats && __serverInstance.isConnected()) {
|
||||
__serverInstance.runtimeStats['pingMs'] = Date.now() - startTime;
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
_ping(_db, serverInstance);
|
||||
}
|
||||
|
||||
function done() {
|
||||
// Adjust the number of checks
|
||||
numberOfEntries--;
|
||||
|
||||
// If we are done with all results coming back trigger ping again
|
||||
if(0 === numberOfEntries && 'connected' == self.state) {
|
||||
setTimeout(pingFunction, self.pingInterval);
|
||||
}
|
||||
}
|
||||
}(server);
|
||||
}
|
||||
}
|
||||
|
||||
// Start pingFunction
|
||||
pingFunction();
|
||||
|
||||
callback && callback(null);
|
||||
}
|
||||
80
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js
generated
vendored
Normal file
80
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/strategies/statistics_strategy.js
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// The Statistics strategy uses the measure of each end-start time for each
|
||||
// query executed against the db to calculate the mean, variance and standard deviation
|
||||
// and pick the server which the lowest mean and deviation
|
||||
var StatisticsStrategy = exports.StatisticsStrategy = function(replicaset) {
|
||||
this.replicaset = replicaset;
|
||||
// Logger api
|
||||
this.Logger = null;
|
||||
}
|
||||
|
||||
// Starts any needed code
|
||||
StatisticsStrategy.prototype.start = function(callback) {
|
||||
callback && callback(null, null);
|
||||
}
|
||||
|
||||
StatisticsStrategy.prototype.stop = function(callback) {
|
||||
callback && callback(null, null);
|
||||
}
|
||||
|
||||
StatisticsStrategy.prototype.checkoutConnection = function(tags, secondaryCandidates) {
|
||||
// Servers are picked based on the lowest ping time and then servers that lower than that + secondaryAcceptableLatencyMS
|
||||
// Create a list of candidat servers, containing the primary if available
|
||||
var candidateServers = [];
|
||||
|
||||
// If we have not provided a list of candidate servers use the default setup
|
||||
if(!Array.isArray(secondaryCandidates)) {
|
||||
candidateServers = this.replicaset._state.master != null ? [this.replicaset._state.master] : [];
|
||||
// Add all the secondaries
|
||||
var keys = Object.keys(this.replicaset._state.secondaries);
|
||||
for(var i = 0; i < keys.length; i++) {
|
||||
candidateServers.push(this.replicaset._state.secondaries[keys[i]])
|
||||
}
|
||||
} else {
|
||||
candidateServers = secondaryCandidates;
|
||||
}
|
||||
|
||||
// Final list of eligable server
|
||||
var finalCandidates = [];
|
||||
|
||||
// If we have tags filter by tags
|
||||
if(tags != null && typeof tags == 'object') {
|
||||
// If we have an array or single tag selection
|
||||
var tagObjects = Array.isArray(tags) ? tags : [tags];
|
||||
// Iterate over all tags until we find a candidate server
|
||||
for(var _i = 0; _i < tagObjects.length; _i++) {
|
||||
// Grab a tag object
|
||||
var tagObject = tagObjects[_i];
|
||||
// Matching keys
|
||||
var matchingKeys = Object.keys(tagObject);
|
||||
// Remove any that are not tagged correctly
|
||||
for(var i = 0; i < candidateServers.length; i++) {
|
||||
var server = candidateServers[i];
|
||||
// If we have tags match
|
||||
if(server.tags != null) {
|
||||
var matching = true;
|
||||
|
||||
// Ensure we have all the values
|
||||
for(var j = 0; j < matchingKeys.length; j++) {
|
||||
if(server.tags[matchingKeys[j]] != tagObject[matchingKeys[j]]) {
|
||||
matching = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a match add it to the list of matching servers
|
||||
if(matching) {
|
||||
finalCandidates.push(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Final array candidates
|
||||
var finalCandidates = candidateServers;
|
||||
}
|
||||
|
||||
// If no candidates available return an error
|
||||
if(finalCandidates.length == 0) return new Error("No replica set members available for query");
|
||||
// Pick a random server
|
||||
return finalCandidates[Math.round(Math.random(1000000) * (finalCandidates.length - 1))].checkoutReader();
|
||||
}
|
||||
225
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/url_parser.js
generated
vendored
Normal file
225
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/connection/url_parser.js
generated
vendored
Normal file
@@ -0,0 +1,225 @@
|
||||
var fs = require('fs'),
|
||||
ReadPreference = require('./read_preference').ReadPreference;
|
||||
|
||||
exports.parse = function(url, options) {
|
||||
// Ensure we have a default options object if none set
|
||||
options = options || {};
|
||||
// Variables
|
||||
var connection_part = '';
|
||||
var auth_part = '';
|
||||
var query_string_part = '';
|
||||
var dbName = 'admin';
|
||||
|
||||
// Must start with mongodb
|
||||
if(url.indexOf("mongodb://") != 0)
|
||||
throw Error("URL must be in the format mongodb://user:pass@host:port/dbname");
|
||||
// If we have a ? mark cut the query elements off
|
||||
if(url.indexOf("?") != -1) {
|
||||
query_string_part = url.substr(url.indexOf("?") + 1);
|
||||
connection_part = url.substring("mongodb://".length, url.indexOf("?"))
|
||||
} else {
|
||||
connection_part = url.substring("mongodb://".length);
|
||||
}
|
||||
|
||||
// Check if we have auth params
|
||||
if(connection_part.indexOf("@") != -1) {
|
||||
auth_part = connection_part.split("@")[0];
|
||||
connection_part = connection_part.split("@")[1];
|
||||
}
|
||||
|
||||
// Check if the connection string has a db
|
||||
if(connection_part.indexOf(".sock") != -1) {
|
||||
if(connection_part.indexOf(".sock/") != -1) {
|
||||
dbName = connection_part.split(".sock/")[1];
|
||||
connection_part = connection_part.split("/", connection_part.indexOf(".sock") + ".sock".length);
|
||||
}
|
||||
} else if(connection_part.indexOf("/") != -1) {
|
||||
dbName = connection_part.split("/")[1];
|
||||
connection_part = connection_part.split("/")[0];
|
||||
}
|
||||
|
||||
// Result object
|
||||
var object = {};
|
||||
|
||||
// Pick apart the authentication part of the string
|
||||
var authPart = auth_part || '';
|
||||
var auth = authPart.split(':', 2);
|
||||
if(options['uri_decode_auth']){
|
||||
auth[0] = decodeURIComponent(auth[0]);
|
||||
if(auth[1]){
|
||||
auth[1] = decodeURIComponent(auth[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// Add auth to final object if we have 2 elements
|
||||
if(auth.length == 2) object.auth = {user: auth[0], password: auth[1]};
|
||||
|
||||
// Variables used for temporary storage
|
||||
var hostPart;
|
||||
var urlOptions;
|
||||
var servers;
|
||||
var serverOptions = {socketOptions: {}};
|
||||
var dbOptions = {read_preference_tags: []};
|
||||
var replSetServersOptions = {socketOptions: {}};
|
||||
// Add server options to final object
|
||||
object.server_options = serverOptions;
|
||||
object.db_options = dbOptions;
|
||||
object.rs_options = replSetServersOptions;
|
||||
object.mongos_options = {};
|
||||
|
||||
// Let's check if we are using a domain socket
|
||||
if(url.match(/\.sock/)) {
|
||||
// Split out the socket part
|
||||
var domainSocket = url.substring(
|
||||
url.indexOf("mongodb://") + "mongodb://".length
|
||||
, url.lastIndexOf(".sock") + ".sock".length);
|
||||
// Clean out any auth stuff if any
|
||||
if(domainSocket.indexOf("@") != -1) domainSocket = domainSocket.split("@")[1];
|
||||
servers = [{domain_socket: domainSocket}];
|
||||
} else {
|
||||
// Split up the db
|
||||
hostPart = connection_part;
|
||||
// Parse all server results
|
||||
servers = hostPart.split(',').map(function(h) {
|
||||
var hostPort = h.split(':', 2);
|
||||
var _host = hostPort[0] || 'localhost';
|
||||
var _port = hostPort[1] != null ? parseInt(hostPort[1], 10) : 27017;
|
||||
// Check for localhost?safe=true style case
|
||||
if(_host.indexOf("?") != -1) _host = _host.split(/\?/)[0];
|
||||
|
||||
// Return the mapped object
|
||||
return {host: _host, port: _port};
|
||||
});
|
||||
}
|
||||
|
||||
// Get the db name
|
||||
object.dbName = dbName || 'admin';
|
||||
// Split up all the options
|
||||
urlOptions = (query_string_part || '').split(/[&;]/);
|
||||
// Ugh, we have to figure out which options go to which constructor manually.
|
||||
urlOptions.forEach(function(opt) {
|
||||
if(!opt) return;
|
||||
var splitOpt = opt.split('='), name = splitOpt[0], value = splitOpt[1];
|
||||
// Options implementations
|
||||
switch(name) {
|
||||
case 'slaveOk':
|
||||
case 'slave_ok':
|
||||
serverOptions.slave_ok = (value == 'true');
|
||||
break;
|
||||
case 'maxPoolSize':
|
||||
case 'poolSize':
|
||||
serverOptions.poolSize = parseInt(value, 10);
|
||||
replSetServersOptions.poolSize = parseInt(value, 10);
|
||||
break;
|
||||
case 'autoReconnect':
|
||||
case 'auto_reconnect':
|
||||
serverOptions.auto_reconnect = (value == 'true');
|
||||
break;
|
||||
case 'minPoolSize':
|
||||
throw new Error("minPoolSize not supported");
|
||||
case 'maxIdleTimeMS':
|
||||
throw new Error("maxIdleTimeMS not supported");
|
||||
case 'waitQueueMultiple':
|
||||
throw new Error("waitQueueMultiple not supported");
|
||||
case 'waitQueueTimeoutMS':
|
||||
throw new Error("waitQueueTimeoutMS not supported");
|
||||
case 'uuidRepresentation':
|
||||
throw new Error("uuidRepresentation not supported");
|
||||
case 'ssl':
|
||||
if(value == 'prefer') {
|
||||
serverOptions.ssl = value;
|
||||
replSetServersOptions.ssl = value;
|
||||
break;
|
||||
}
|
||||
serverOptions.ssl = (value == 'true');
|
||||
replSetServersOptions.ssl = (value == 'true');
|
||||
break;
|
||||
case 'replicaSet':
|
||||
case 'rs_name':
|
||||
replSetServersOptions.rs_name = value;
|
||||
break;
|
||||
case 'reconnectWait':
|
||||
replSetServersOptions.reconnectWait = parseInt(value, 10);
|
||||
break;
|
||||
case 'retries':
|
||||
replSetServersOptions.retries = parseInt(value, 10);
|
||||
break;
|
||||
case 'readSecondary':
|
||||
case 'read_secondary':
|
||||
replSetServersOptions.read_secondary = (value == 'true');
|
||||
break;
|
||||
case 'fsync':
|
||||
dbOptions.fsync = (value == 'true');
|
||||
break;
|
||||
case 'journal':
|
||||
dbOptions.journal = (value == 'true');
|
||||
break;
|
||||
case 'safe':
|
||||
dbOptions.safe = (value == 'true');
|
||||
break;
|
||||
case 'nativeParser':
|
||||
case 'native_parser':
|
||||
dbOptions.native_parser = (value == 'true');
|
||||
break;
|
||||
case 'connectTimeoutMS':
|
||||
serverOptions.socketOptions.connectTimeoutMS = parseInt(value, 10);
|
||||
replSetServersOptions.socketOptions.connectTimeoutMS = parseInt(value, 10);
|
||||
break;
|
||||
case 'socketTimeoutMS':
|
||||
serverOptions.socketOptions.socketTimeoutMS = parseInt(value, 10);
|
||||
replSetServersOptions.socketOptions.socketTimeoutMS = parseInt(value, 10);
|
||||
break;
|
||||
case 'w':
|
||||
dbOptions.w = parseInt(value, 10);
|
||||
break;
|
||||
case 'authSource':
|
||||
dbOptions.authSource = value;
|
||||
case 'wtimeoutMS':
|
||||
dbOptions.wtimeoutMS = parseInt(value, 10);
|
||||
break;
|
||||
case 'readPreference':
|
||||
if(!ReadPreference.isValid(value)) throw new Error("readPreference must be either primary/primaryPreferred/secondary/secondaryPreferred/nearest");
|
||||
dbOptions.read_preference = value;
|
||||
break;
|
||||
case 'readPreferenceTags':
|
||||
// Contains the tag object
|
||||
var tagObject = {};
|
||||
if(value == null || value == '') {
|
||||
dbOptions.read_preference_tags.push(tagObject);
|
||||
break;
|
||||
}
|
||||
|
||||
// Split up the tags
|
||||
var tags = value.split(/\,/);
|
||||
for(var i = 0; i < tags.length; i++) {
|
||||
var parts = tags[i].trim().split(/\:/);
|
||||
tagObject[parts[0]] = parts[1];
|
||||
}
|
||||
|
||||
// Set the preferences tags
|
||||
dbOptions.read_preference_tags.push(tagObject);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
// No tags: should be null (not [])
|
||||
if(dbOptions.read_preference_tags.length === 0) {
|
||||
dbOptions.read_preference_tags = null;
|
||||
}
|
||||
|
||||
// Validate if there are an invalid write concern combinations
|
||||
if((dbOptions.w == -1 || dbOptions.w == 0) && (
|
||||
dbOptions.journal == true
|
||||
|| dbOptions.fsync == true
|
||||
|| dbOptions.safe == true)) throw new Error("w set to -1 or 0 cannot be combined with safe/w/journal/fsync")
|
||||
|
||||
// If no read preference set it to primary
|
||||
if(!dbOptions.read_preference) dbOptions.read_preference = 'primary';
|
||||
|
||||
// Add servers to result
|
||||
object.servers = servers;
|
||||
// Returned parsed object
|
||||
return object;
|
||||
}
|
||||
988
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/cursor.js
generated
vendored
Normal file
988
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/cursor.js
generated
vendored
Normal file
@@ -0,0 +1,988 @@
|
||||
var QueryCommand = require('./commands/query_command').QueryCommand,
|
||||
GetMoreCommand = require('./commands/get_more_command').GetMoreCommand,
|
||||
KillCursorCommand = require('./commands/kill_cursor_command').KillCursorCommand,
|
||||
Long = require('bson').Long,
|
||||
ReadPreference = require('./connection/read_preference').ReadPreference,
|
||||
CursorStream = require('./cursorstream'),
|
||||
timers = require('timers'),
|
||||
utils = require('./utils');
|
||||
|
||||
// Set processor, setImmediate if 0.10 otherwise nextTick
|
||||
var processor = timers.setImmediate ? timers.setImmediate : process.nextTick;
|
||||
|
||||
/**
|
||||
* Constructor for a cursor object that handles all the operations on query result
|
||||
* using find. This cursor object is unidirectional and cannot traverse backwards. Clients should not be creating a cursor directly,
|
||||
* but use find to acquire a cursor. (INTERNAL TYPE)
|
||||
*
|
||||
* 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.
|
||||
* @param {Db} db the database object to work with.
|
||||
* @param {Collection} collection the collection to query.
|
||||
* @param {Object} selector the query selector.
|
||||
* @param {Object} fields an object containing what fields to include or exclude from objects returned.
|
||||
* @param {Object} [options] additional options for the collection.
|
||||
*/
|
||||
function Cursor(db, collection, selector, fields, options) {
|
||||
this.db = db;
|
||||
this.collection = collection;
|
||||
this.selector = selector;
|
||||
this.fields = fields;
|
||||
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 = 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;
|
||||
|
||||
this.totalNumberOfRecords = 0;
|
||||
this.items = [];
|
||||
this.cursorId = Long.fromInt(0);
|
||||
|
||||
// This name
|
||||
this.dbName = options.dbName;
|
||||
|
||||
// State variables for the cursor
|
||||
this.state = Cursor.INIT;
|
||||
// Keep track of the current query run
|
||||
this.queryRun = false;
|
||||
this.getMoreTimer = false;
|
||||
|
||||
// If we are using a specific db execute against it
|
||||
if(this.dbName != null) {
|
||||
this.collectionName = this.dbName + "." + this.collection.collectionName;
|
||||
} else {
|
||||
this.collectionName = (this.db.databaseName ? this.db.databaseName + "." : '') + this.collection.collectionName;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Resets this cursor to its initial state. All settings like the query string,
|
||||
* tailable, batchSizeValue, skipValue and limits are preserved.
|
||||
*
|
||||
* @return {Cursor} returns itself with rewind applied.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.rewind = function() {
|
||||
var self = this;
|
||||
|
||||
if (self.state != Cursor.INIT) {
|
||||
if (self.state != Cursor.CLOSED) {
|
||||
self.close(function() {});
|
||||
}
|
||||
|
||||
self.numberOfReturned = 0;
|
||||
self.totalNumberOfRecords = 0;
|
||||
self.items = [];
|
||||
self.cursorId = Long.fromInt(0);
|
||||
self.state = Cursor.INIT;
|
||||
self.queryRun = false;
|
||||
}
|
||||
|
||||
return self;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an array of documents. The caller is responsible for making sure that there
|
||||
* is enough memory to store the results. Note that the array only contain partial
|
||||
* results when this cursor had been previouly accessed. In that case,
|
||||
* cursor.rewind() can be used to reset the cursor.
|
||||
*
|
||||
* @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}
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.toArray = function(callback) {
|
||||
var self = this;
|
||||
|
||||
if(!callback) {
|
||||
throw new Error('callback is mandatory');
|
||||
}
|
||||
|
||||
if(this.tailable) {
|
||||
callback(new Error("Tailable cursor cannot be converted to array"), null);
|
||||
} else if(this.state != Cursor.CLOSED) {
|
||||
// return toArrayExhaust(self, callback);
|
||||
// If we are using exhaust we can't use the quick fire method
|
||||
if(self.exhaust) return toArrayExhaust(self, callback);
|
||||
// Quick fire using trampoline to avoid nextTick
|
||||
self.nextObject({noReturn: true}, function(err, result) {
|
||||
if(err) return callback(utils.toError(err), null);
|
||||
if(self.cursorId.toString() == "0") {
|
||||
self.state = Cursor.CLOSED;
|
||||
return callback(null, self.items);
|
||||
}
|
||||
|
||||
// Let's issue getMores until we have no more records waiting
|
||||
getAllByGetMore(self, function(err, done) {
|
||||
self.state = Cursor.CLOSED;
|
||||
if(err) return callback(utils.toError(err), null);
|
||||
callback(null, self.items);
|
||||
});
|
||||
})
|
||||
|
||||
} else {
|
||||
callback(new Error("Cursor is closed"), null);
|
||||
}
|
||||
}
|
||||
|
||||
var toArrayExhaust = function(self, callback) {
|
||||
var items = [];
|
||||
|
||||
self.each(function(err, item) {
|
||||
if(err != null) {
|
||||
return callback(utils.toError(err), null);
|
||||
}
|
||||
|
||||
if(item != null && Array.isArray(items)) {
|
||||
items.push(item);
|
||||
} else {
|
||||
var resultItems = items;
|
||||
items = null;
|
||||
self.items = [];
|
||||
callback(null, resultItems);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var getAllByGetMore = function(self, callback) {
|
||||
getMore(self, {noReturn: true}, function(err, result) {
|
||||
if(err) return callback(utils.toError(err));
|
||||
if(result == null) return callback(null, null);
|
||||
if(self.cursorId.toString() == "0") return callback(null, null);
|
||||
getAllByGetMore(self, callback);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates over all the documents for this cursor. As with **{cursor.toArray}**,
|
||||
* not all of the elements will be iterated if this cursor had been previouly accessed.
|
||||
* In that case, **{cursor.rewind}** can be used to reset the cursor. However, unlike
|
||||
* **{cursor.toArray}**, the cursor will only hold a maximum of batch size elements
|
||||
* at any given time if batch size is specified. Otherwise, the caller is responsible
|
||||
* for making sure that the entire result can fit the memory.
|
||||
*
|
||||
* @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}
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.each = function(callback) {
|
||||
var self = this;
|
||||
var fn;
|
||||
|
||||
if (!callback) {
|
||||
throw new Error('callback is mandatory');
|
||||
}
|
||||
|
||||
if(this.state != Cursor.CLOSED) {
|
||||
// If we are using exhaust we can't use the quick fire method
|
||||
if(self.exhaust) return eachExhaust(self, callback);
|
||||
// Quick fire using trampoline to avoid nextTick
|
||||
if(this.items.length > 0) {
|
||||
// Trampoline all the entries
|
||||
while(fn = loop(self, callback)) fn(self, callback);
|
||||
// Call each again
|
||||
self.each(callback);
|
||||
} else {
|
||||
self.nextObject(function(err, item) {
|
||||
|
||||
if(err) {
|
||||
self.state = Cursor.CLOSED;
|
||||
return callback(utils.toError(err), item);
|
||||
}
|
||||
|
||||
if(item == null) return callback(null, null);
|
||||
callback(null, item);
|
||||
self.each(callback);
|
||||
})
|
||||
}
|
||||
} else {
|
||||
callback(new Error("Cursor is closed"), null);
|
||||
}
|
||||
}
|
||||
|
||||
// Special for exhaust command as we don't initiate the actual result sets
|
||||
// the server just sends them as they arrive meaning we need to get the IO event
|
||||
// loop happen so we can receive more data from the socket or we return to early
|
||||
// after the first fetch and loose all the incoming getMore's automatically issued
|
||||
// from the server.
|
||||
var eachExhaust = function(self, callback) {
|
||||
//FIX: stack overflow (on deep callback) (cred: https://github.com/limp/node-mongodb-native/commit/27da7e4b2af02035847f262b29837a94bbbf6ce2)
|
||||
processor(function(){
|
||||
// Fetch the next object until there is no more objects
|
||||
self.nextObject(function(err, item) {
|
||||
if(err != null) return callback(err, null);
|
||||
if(item != null) {
|
||||
callback(null, item);
|
||||
eachExhaust(self, callback);
|
||||
} else {
|
||||
// Close the cursor if done
|
||||
self.state = Cursor.CLOSED;
|
||||
callback(err, null);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Trampoline emptying the number of retrieved items
|
||||
// without incurring a nextTick operation
|
||||
var loop = function(self, callback) {
|
||||
// No more items we are done
|
||||
if(self.items.length == 0) return;
|
||||
// Get the next document
|
||||
var doc = self.items.shift();
|
||||
// Callback
|
||||
callback(null, doc);
|
||||
// Loop
|
||||
return loop;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines how many result the query for this cursor will return
|
||||
*
|
||||
* @param {Boolean} applySkipLimit if set to true will apply the skip and limits set on the cursor. Defaults to false.
|
||||
* @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}
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.count = function(applySkipLimit, callback) {
|
||||
if(typeof applySkipLimit == 'function') {
|
||||
callback = applySkipLimit;
|
||||
applySkipLimit = false;
|
||||
}
|
||||
|
||||
var options = {};
|
||||
if(applySkipLimit) {
|
||||
if(typeof this.skipValue == 'number') options.skip = this.skipValue;
|
||||
if(typeof this.limitValue == 'number') options.limit = this.limitValue;
|
||||
}
|
||||
|
||||
// Call count command
|
||||
this.collection.count(this.selector, options, callback);
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the sort parameter of this cursor to the given value.
|
||||
*
|
||||
* This method has the following method signatures:
|
||||
* (keyOrList, callback)
|
||||
* (keyOrList, direction, callback)
|
||||
*
|
||||
* @param {String|Array|Object} keyOrList This can be a string or an array. If passed as a string, the string will be the field to sort. If passed an array, each element will represent a field to be sorted and should be an array that contains the format [string, direction].
|
||||
* @param {String|Number} direction this determines how the results are sorted. "asc", "ascending" or 1 for asceding order while "desc", "desceding or -1 for descending order. Note that the strings are case insensitive.
|
||||
* @param {Function} callback this will be called after executing this method. The first parameter will contain an error object when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
|
||||
* @return {Cursor} an instance of this object.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.sort = function(keyOrList, direction, callback) {
|
||||
callback = callback || function(){};
|
||||
if(typeof direction === "function") { callback = direction; direction = null; }
|
||||
|
||||
if(this.tailable) {
|
||||
callback(new Error("Tailable cursor doesn't support sorting"), null);
|
||||
} else if(this.queryRun == true || this.state == Cursor.CLOSED) {
|
||||
callback(new Error("Cursor is closed"), null);
|
||||
} else {
|
||||
var order = keyOrList;
|
||||
|
||||
if(direction != null) {
|
||||
order = [[keyOrList, direction]];
|
||||
}
|
||||
|
||||
this.sortValue = order;
|
||||
callback(null, this);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the limit parameter of this cursor to the given value.
|
||||
*
|
||||
* @param {Number} limit the new limit.
|
||||
* @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the limit given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
|
||||
* @return {Cursor} an instance of this object.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.limit = function(limit, callback) {
|
||||
if(this.tailable) {
|
||||
if(callback) {
|
||||
callback(new Error("Tailable cursor doesn't support limit"), null);
|
||||
} else {
|
||||
throw new Error("Tailable cursor doesn't support limit");
|
||||
}
|
||||
} else if(this.queryRun == true || this.state == Cursor.CLOSED) {
|
||||
if(callback) {
|
||||
callback(new Error("Cursor is closed"), null);
|
||||
} else {
|
||||
throw new Error("Cursor is closed");
|
||||
}
|
||||
} else {
|
||||
if(limit != null && limit.constructor != Number) {
|
||||
if(callback) {
|
||||
callback(new Error("limit requires an integer"), null);
|
||||
} else {
|
||||
throw new Error("limit requires an integer");
|
||||
}
|
||||
} else {
|
||||
this.limitValue = limit;
|
||||
if(callback) return callback(null, this);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the read preference for the cursor
|
||||
*
|
||||
* @param {String} the read preference for the cursor, one of Server.READ_PRIMARY, Server.READ_SECONDARY, Server.READ_SECONDARY_ONLY
|
||||
* @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the read preference given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
|
||||
* @return {Cursor} an instance of this object.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.setReadPreference = function(readPreference, tags, callback) {
|
||||
if(typeof tags == 'function') callback = tags;
|
||||
|
||||
var _mode = readPreference != null && typeof readPreference == 'object' ? readPreference.mode : readPreference;
|
||||
|
||||
if(this.queryRun == true || this.state == Cursor.CLOSED) {
|
||||
if(callback == null) throw new Error("Cannot change read preference on executed query or closed cursor");
|
||||
callback(new Error("Cannot change read preference on executed query or closed cursor"));
|
||||
} else if(_mode != null && _mode != 'primary'
|
||||
&& _mode != 'secondaryOnly' && _mode != 'secondary'
|
||||
&& _mode != 'nearest' && _mode != 'primaryPreferred' && _mode != 'secondaryPreferred') {
|
||||
if(callback == null) throw new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported");
|
||||
callback(new Error("only readPreference of primary, secondary, secondaryPreferred, primaryPreferred or nearest supported"));
|
||||
} else {
|
||||
this.read = readPreference;
|
||||
if(callback != null) callback(null, this);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the skip parameter of this cursor to the given value.
|
||||
*
|
||||
* @param {Number} skip the new skip value.
|
||||
* @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the skip value given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
|
||||
* @return {Cursor} an instance of this object.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.skip = function(skip, callback) {
|
||||
callback = callback || function(){};
|
||||
|
||||
if(this.tailable) {
|
||||
callback(new Error("Tailable cursor doesn't support skip"), null);
|
||||
} else if(this.queryRun == true || this.state == Cursor.CLOSED) {
|
||||
callback(new Error("Cursor is closed"), null);
|
||||
} else {
|
||||
if(skip != null && skip.constructor != Number) {
|
||||
callback(new Error("skip requires an integer"), null);
|
||||
} else {
|
||||
this.skipValue = skip;
|
||||
callback(null, this);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sets the batch size parameter of this cursor to the given value.
|
||||
*
|
||||
* @param {Number} batchSize the new batch size.
|
||||
* @param {Function} [callback] this optional callback will be called after executing this method. The first parameter will contain an error object when the batchSize given is not a valid number or when the cursor is already closed while the second parameter will contain a reference to this object upon successful execution.
|
||||
* @return {Cursor} an instance of this object.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.batchSize = function(batchSize, callback) {
|
||||
if(this.state == Cursor.CLOSED) {
|
||||
if(callback != null) {
|
||||
return callback(new Error("Cursor is closed"), null);
|
||||
} else {
|
||||
throw new Error("Cursor is closed");
|
||||
}
|
||||
} else if(batchSize != null && batchSize.constructor != Number) {
|
||||
if(callback != null) {
|
||||
return callback(new Error("batchSize requires an integer"), null);
|
||||
} else {
|
||||
throw new Error("batchSize requires an integer");
|
||||
}
|
||||
} else {
|
||||
this.batchSizeValue = batchSize;
|
||||
if(callback != null) return callback(null, this);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* The limit used for the getMore command
|
||||
*
|
||||
* @return {Number} The number of records to request per batch.
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
var limitRequest = function(self) {
|
||||
var requestedLimit = self.limitValue;
|
||||
var absLimitValue = Math.abs(self.limitValue);
|
||||
var absBatchValue = Math.abs(self.batchSizeValue);
|
||||
|
||||
if(absLimitValue > 0) {
|
||||
if (absBatchValue > 0) {
|
||||
requestedLimit = Math.min(absLimitValue, absBatchValue);
|
||||
}
|
||||
} else {
|
||||
requestedLimit = self.batchSizeValue;
|
||||
}
|
||||
|
||||
return requestedLimit;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Generates a QueryCommand object using the parameters of this cursor.
|
||||
*
|
||||
* @return {QueryCommand} The command object
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
var generateQueryCommand = function(self) {
|
||||
// Unpack the options
|
||||
var queryOptions = QueryCommand.OPTS_NONE;
|
||||
if(!self.timeout) {
|
||||
queryOptions |= QueryCommand.OPTS_NO_CURSOR_TIMEOUT;
|
||||
}
|
||||
|
||||
if(self.tailable != null) {
|
||||
queryOptions |= QueryCommand.OPTS_TAILABLE_CURSOR;
|
||||
self.skipValue = self.limitValue = 0;
|
||||
|
||||
// if awaitdata is set
|
||||
if(self.awaitdata != null) {
|
||||
queryOptions |= QueryCommand.OPTS_AWAIT_DATA;
|
||||
}
|
||||
}
|
||||
|
||||
if(self.exhaust) {
|
||||
queryOptions |= QueryCommand.OPTS_EXHAUST;
|
||||
}
|
||||
|
||||
if(self.slaveOk) {
|
||||
queryOptions |= QueryCommand.OPTS_SLAVE;
|
||||
}
|
||||
|
||||
if(self.partial) {
|
||||
queryOptions |= QueryCommand.OPTS_PARTIAL;
|
||||
}
|
||||
|
||||
// limitValue of -1 is a special case used by Db#eval
|
||||
var numberToReturn = self.limitValue == -1 ? -1 : limitRequest(self);
|
||||
|
||||
// Check if we need a special selector
|
||||
if(self.sortValue != null || self.explainValue != null || self.hint != null || self.snapshot != null
|
||||
|| self.returnKey != null || self.maxScan != null || self.min != null || self.max != null
|
||||
|| self.showDiskLoc != null || self.comment != null) {
|
||||
|
||||
// Build special selector
|
||||
var specialSelector = {'$query':self.selector};
|
||||
if(self.sortValue != null) specialSelector['orderby'] = utils.formattedOrderClause(self.sortValue);
|
||||
if(self.hint != null && self.hint.constructor == Object) specialSelector['$hint'] = self.hint;
|
||||
if(self.snapshot != null) specialSelector['$snapshot'] = true;
|
||||
if(self.returnKey != null) specialSelector['$returnKey'] = self.returnKey;
|
||||
if(self.maxScan != null) specialSelector['$maxScan'] = self.maxScan;
|
||||
if(self.min != null) specialSelector['$min'] = self.min;
|
||||
if(self.max != null) specialSelector['$max'] = self.max;
|
||||
if(self.showDiskLoc != null) specialSelector['$showDiskLoc'] = self.showDiskLoc;
|
||||
if(self.comment != null) specialSelector['$comment'] = self.comment;
|
||||
// If we have explain set only return a single document with automatic cursor close
|
||||
if(self.explainValue != null) {
|
||||
numberToReturn = (-1)*Math.abs(numberToReturn);
|
||||
specialSelector['$explain'] = true;
|
||||
}
|
||||
|
||||
// Return the query
|
||||
return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, specialSelector, self.fields);
|
||||
} else {
|
||||
return new QueryCommand(self.db, self.collectionName, queryOptions, self.skipValue, numberToReturn, self.selector, self.fields);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {Object} Returns an object containing the sort value of this cursor with
|
||||
* the proper formatting that can be used internally in this cursor.
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
Cursor.prototype.formattedOrderClause = function() {
|
||||
return utils.formattedOrderClause(this.sortValue);
|
||||
};
|
||||
|
||||
/**
|
||||
* Converts the value of the sort direction into its equivalent numerical value.
|
||||
*
|
||||
* @param sortDirection {String|number} Range of acceptable values:
|
||||
* 'ascending', 'descending', 'asc', 'desc', 1, -1
|
||||
*
|
||||
* @return {number} The equivalent numerical value
|
||||
* @throws Error if the given sortDirection is invalid
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
Cursor.prototype.formatSortValue = function(sortDirection) {
|
||||
return utils.formatSortValue(sortDirection);
|
||||
};
|
||||
|
||||
/**
|
||||
* Gets the next document from the cursor.
|
||||
*
|
||||
* @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.nextObject = function(options, callback) {
|
||||
var self = this;
|
||||
|
||||
if(typeof options == 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
if(self.state == Cursor.INIT) {
|
||||
var cmd;
|
||||
try {
|
||||
cmd = generateQueryCommand(self);
|
||||
} catch (err) {
|
||||
return callback(err, null);
|
||||
}
|
||||
|
||||
// Execute command
|
||||
var commandHandler = function(err, result) {
|
||||
self.state = Cursor.OPEN;
|
||||
if(err != null && result == null) return callback(utils.toError(err), null);
|
||||
|
||||
if(!err && result.documents[0] && result.documents[0]['$err']) {
|
||||
return self.close(function() {callback(utils.toError(result.documents[0]['$err']), null);});
|
||||
}
|
||||
|
||||
self.queryRun = true;
|
||||
self.state = Cursor.OPEN; // Adjust the state of the cursor
|
||||
self.cursorId = result.cursorId;
|
||||
self.totalNumberOfRecords = result.numberReturned;
|
||||
|
||||
// Add the new documents to the list of items, using forloop to avoid
|
||||
// new array allocations and copying
|
||||
for(var i = 0; i < result.documents.length; i++) {
|
||||
self.items.push(result.documents[i]);
|
||||
}
|
||||
|
||||
// If we have noReturn set just return (not modifying the internal item list)
|
||||
// used for toArray
|
||||
if(options.noReturn) {
|
||||
return callback(null, true);
|
||||
}
|
||||
|
||||
// Ignore callbacks until the cursor is dead for exhausted
|
||||
if(self.exhaust && result.cursorId.toString() == "0") {
|
||||
self.nextObject(callback);
|
||||
} else if(self.exhaust == false || self.exhaust == null) {
|
||||
self.nextObject(callback);
|
||||
}
|
||||
};
|
||||
|
||||
// If we have no connection set on this cursor check one out
|
||||
if(self.connection == null) {
|
||||
try {
|
||||
self.connection = this.read == null ? self.db.serverConfig.checkoutWriter() : self.db.serverConfig.checkoutReader(this.read);
|
||||
} catch(err) {
|
||||
return callback(utils.toError(err), null);
|
||||
}
|
||||
}
|
||||
|
||||
// Execute the command
|
||||
self.db._executeQueryCommand(cmd, {exhaust: self.exhaust, raw:self.raw, read:self.read, connection:self.connection}, commandHandler);
|
||||
// Set the command handler to null
|
||||
commandHandler = null;
|
||||
} else if(self.items.length) {
|
||||
callback(null, self.items.shift());
|
||||
} else if(self.cursorId.greaterThan(Long.fromInt(0))) {
|
||||
getMore(self, callback);
|
||||
} else {
|
||||
// Force cursor to stay open
|
||||
return self.close(function() {callback(null, null);});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets more results from the database if any.
|
||||
*
|
||||
* @param {Function} callback this will be called after executing this method. The first parameter will contain an error object on error while the second parameter will contain a document from the returned result or null if there are no more results.
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
var getMore = function(self, options, callback) {
|
||||
var limit = 0;
|
||||
|
||||
if(typeof options == 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
if(self.state == Cursor.GET_MORE) return callback(null, null);
|
||||
|
||||
// Set get more in progress
|
||||
self.state = Cursor.GET_MORE;
|
||||
|
||||
// Set options
|
||||
if (!self.tailable && self.limitValue > 0) {
|
||||
limit = self.limitValue - self.totalNumberOfRecords;
|
||||
if (limit < 1) {
|
||||
self.close(function() {callback(null, null);});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
var getMoreCommand = new GetMoreCommand(
|
||||
self.db
|
||||
, self.collectionName
|
||||
, limitRequest(self)
|
||||
, self.cursorId
|
||||
);
|
||||
|
||||
// Set up options
|
||||
var command_options = {read: self.read, raw: self.raw, connection:self.connection };
|
||||
|
||||
// Execute the command
|
||||
self.db._executeQueryCommand(getMoreCommand, command_options, function(err, result) {
|
||||
var cbValue;
|
||||
|
||||
// Get more done
|
||||
self.state = Cursor.OPEN;
|
||||
|
||||
if(err != null) {
|
||||
return callback(utils.toError(err), null);
|
||||
}
|
||||
|
||||
try {
|
||||
var isDead = 1 === result.responseFlag && result.cursorId.isZero();
|
||||
|
||||
self.cursorId = result.cursorId;
|
||||
self.totalNumberOfRecords += result.numberReturned;
|
||||
|
||||
// Determine if there's more documents to fetch
|
||||
if(result.numberReturned > 0) {
|
||||
if (self.limitValue > 0) {
|
||||
var excessResult = self.totalNumberOfRecords - self.limitValue;
|
||||
|
||||
if (excessResult > 0) {
|
||||
result.documents.splice(-1 * excessResult, excessResult);
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the tries for awaitdata if we are using it
|
||||
self.currentNumberOfRetries = self.numberOfRetries;
|
||||
// Get the documents
|
||||
for(var i = 0; i < result.documents.length; i++) {
|
||||
self.items.push(result.documents[i]);
|
||||
}
|
||||
|
||||
// Don's shift a document out as we need it for toArray
|
||||
if(options.noReturn) {
|
||||
cbValue = true;
|
||||
} else {
|
||||
cbValue = self.items.shift();
|
||||
}
|
||||
} else if(self.tailable && !isDead && self.awaitdata) {
|
||||
// Excute the tailable cursor once more, will timeout after ~4 sec if awaitdata used
|
||||
self.currentNumberOfRetries = self.currentNumberOfRetries - 1;
|
||||
if(self.currentNumberOfRetries == 0) {
|
||||
self.close(function() {
|
||||
callback(new Error("tailable cursor timed out"), null);
|
||||
});
|
||||
} else {
|
||||
getMore(self, callback);
|
||||
}
|
||||
} else if(self.tailable && !isDead) {
|
||||
self.getMoreTimer = setTimeout(function() { getMore(self, callback); }, self.tailableRetryInterval);
|
||||
} else {
|
||||
self.close(function() {callback(null, null); });
|
||||
}
|
||||
|
||||
result = null;
|
||||
} catch(err) {
|
||||
callback(utils.toError(err), null);
|
||||
}
|
||||
if (cbValue != null) callback(null, cbValue);
|
||||
});
|
||||
|
||||
getMoreCommand = null;
|
||||
} catch(err) {
|
||||
// Get more done
|
||||
self.state = Cursor.OPEN;
|
||||
|
||||
var handleClose = function() {
|
||||
callback(utils.toError(err), null);
|
||||
};
|
||||
|
||||
self.close(handleClose);
|
||||
handleClose = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a detailed information about how the query is performed on this cursor and how
|
||||
* long it took the database to process it.
|
||||
*
|
||||
* @param {Function} callback this will be called after executing this method. The first parameter will always be null while the second parameter will be an object containing the details.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.explain = function(callback) {
|
||||
var limit = (-1)*Math.abs(this.limitValue);
|
||||
|
||||
// Create a new cursor and fetch the plan
|
||||
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
|
||||
cursor.nextObject(function(err, item) {
|
||||
if(err != null) return callback(utils.toError(err), null);
|
||||
// close the cursor
|
||||
cursor.close(function(err, result) {
|
||||
if(err != null) return callback(utils.toError(err), null);
|
||||
callback(null, item);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
*/
|
||||
Cursor.prototype.streamRecords = function(options) {
|
||||
console.log("[WARNING] streamRecords method is deprecated, please use stream method which is much faster");
|
||||
var args = Array.prototype.slice.call(arguments, 0);
|
||||
options = args.length ? args.shift() : {};
|
||||
|
||||
var
|
||||
self = this,
|
||||
stream = new process.EventEmitter(),
|
||||
recordLimitValue = this.limitValue || 0,
|
||||
emittedRecordCount = 0,
|
||||
queryCommand = generateQueryCommand(self);
|
||||
|
||||
// see http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol
|
||||
queryCommand.numberToReturn = options.fetchSize ? options.fetchSize : 500;
|
||||
// Execute the query
|
||||
execute(queryCommand);
|
||||
|
||||
function execute(command) {
|
||||
self.db._executeQueryCommand(command, {exhaust: self.exhaust, read:self.read, raw:self.raw, connection:self.connection}, function(err,result) {
|
||||
if(err) {
|
||||
stream.emit('error', err);
|
||||
self.close(function(){});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!self.queryRun && result) {
|
||||
self.queryRun = true;
|
||||
self.cursorId = result.cursorId;
|
||||
self.state = Cursor.OPEN;
|
||||
self.getMoreCommand = new GetMoreCommand(self.db, self.collectionName, queryCommand.numberToReturn, result.cursorId);
|
||||
}
|
||||
|
||||
var resflagsMap = {
|
||||
CursorNotFound:1<<0,
|
||||
QueryFailure:1<<1,
|
||||
ShardConfigStale:1<<2,
|
||||
AwaitCapable:1<<3
|
||||
};
|
||||
|
||||
if(result.documents && result.documents.length && !(result.responseFlag & resflagsMap.QueryFailure)) {
|
||||
try {
|
||||
result.documents.forEach(function(doc){
|
||||
if(recordLimitValue && emittedRecordCount>=recordLimitValue) {
|
||||
throw("done");
|
||||
}
|
||||
emittedRecordCount++;
|
||||
stream.emit('data', doc);
|
||||
});
|
||||
} catch(err) {
|
||||
if (err != "done") { throw err; }
|
||||
else {
|
||||
self.close(function(){
|
||||
stream.emit('end', recordLimitValue);
|
||||
});
|
||||
self.close(function(){});
|
||||
return;
|
||||
}
|
||||
}
|
||||
// rinse & repeat
|
||||
execute(self.getMoreCommand);
|
||||
} else {
|
||||
self.close(function(){
|
||||
stream.emit('end', recordLimitValue);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return stream;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a Node ReadStream interface for this cursor.
|
||||
*
|
||||
* Options
|
||||
* - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting.
|
||||
*
|
||||
* @return {CursorStream} returns a stream object.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.stream = function stream(options) {
|
||||
return new CursorStream(this, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the cursor.
|
||||
*
|
||||
* @param {Function} callback this will be called after executing this method. The first parameter will always contain null while the second parameter will contain a reference to this cursor.
|
||||
* @return {null}
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.close = function(callback) {
|
||||
var self = this
|
||||
this.getMoreTimer && clearTimeout(this.getMoreTimer);
|
||||
// Close the cursor if not needed
|
||||
if(this.cursorId instanceof Long && this.cursorId.greaterThan(Long.fromInt(0))) {
|
||||
try {
|
||||
var command = new KillCursorCommand(this.db, [this.cursorId]);
|
||||
// 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) {}
|
||||
}
|
||||
|
||||
// Null out the connection
|
||||
self.connection = null;
|
||||
// Reset cursor id
|
||||
this.cursorId = Long.fromInt(0);
|
||||
// Set to closed status
|
||||
this.state = Cursor.CLOSED;
|
||||
|
||||
if(callback) {
|
||||
callback(null, self);
|
||||
self.items = [];
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Check if the cursor is closed or open.
|
||||
*
|
||||
* @return {Boolean} returns the state of the cursor.
|
||||
* @api public
|
||||
*/
|
||||
Cursor.prototype.isClosed = function() {
|
||||
return this.state == Cursor.CLOSED ? true : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Init state
|
||||
*
|
||||
* @classconstant INIT
|
||||
**/
|
||||
Cursor.INIT = 0;
|
||||
|
||||
/**
|
||||
* Cursor open
|
||||
*
|
||||
* @classconstant OPEN
|
||||
**/
|
||||
Cursor.OPEN = 1;
|
||||
|
||||
/**
|
||||
* Cursor closed
|
||||
*
|
||||
* @classconstant CLOSED
|
||||
**/
|
||||
Cursor.CLOSED = 2;
|
||||
|
||||
/**
|
||||
* Cursor performing a get more
|
||||
*
|
||||
* @classconstant OPEN
|
||||
**/
|
||||
Cursor.GET_MORE = 3;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
exports.Cursor = Cursor;
|
||||
164
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/cursorstream.js
generated
vendored
Normal file
164
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/cursorstream.js
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
var timers = require('timers');
|
||||
|
||||
// Set processor, setImmediate if 0.10 otherwise nextTick
|
||||
var processor = timers.setImmediate ? timers.setImmediate : process.nextTick;
|
||||
|
||||
/**
|
||||
* Module dependecies.
|
||||
*/
|
||||
var Stream = require('stream').Stream;
|
||||
|
||||
/**
|
||||
* CursorStream
|
||||
*
|
||||
* Returns a stream interface for the **cursor**.
|
||||
*
|
||||
* Options
|
||||
* - **transform** {Function} function of type function(object) { return transformed }, allows for transformation of data before emitting.
|
||||
*
|
||||
* Events
|
||||
* - **data** {function(item) {}} the data event triggers when a document is ready.
|
||||
* - **error** {function(err) {}} the error event triggers if an error happens.
|
||||
* - **close** {function() {}} the end event triggers when there is no more documents available.
|
||||
*
|
||||
* @class Represents a CursorStream.
|
||||
* @param {Cursor} cursor a cursor object that the stream wraps.
|
||||
* @return {Stream}
|
||||
*/
|
||||
function CursorStream(cursor, options) {
|
||||
if(!(this instanceof CursorStream)) return new CursorStream(cursor);
|
||||
options = options ? options : {};
|
||||
|
||||
Stream.call(this);
|
||||
|
||||
this.readable = true;
|
||||
this.paused = false;
|
||||
this._cursor = cursor;
|
||||
this._destroyed = null;
|
||||
this.options = options;
|
||||
|
||||
// give time to hook up events
|
||||
var self = this;
|
||||
process.nextTick(function() {
|
||||
self._init();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from Stream
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
CursorStream.prototype.__proto__ = Stream.prototype;
|
||||
|
||||
/**
|
||||
* Flag stating whether or not this stream is readable.
|
||||
*/
|
||||
CursorStream.prototype.readable;
|
||||
|
||||
/**
|
||||
* Flag stating whether or not this stream is paused.
|
||||
*/
|
||||
CursorStream.prototype.paused;
|
||||
|
||||
/**
|
||||
* Initialize the cursor.
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
CursorStream.prototype._init = function () {
|
||||
if (this._destroyed) return;
|
||||
this._next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the next document from the cursor.
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
CursorStream.prototype._next = function () {
|
||||
if(this.paused || this._destroyed) return;
|
||||
|
||||
var self = this;
|
||||
// Get the next object
|
||||
processor(function() {
|
||||
if(self.paused || self._destroyed) return;
|
||||
|
||||
self._cursor.nextObject(function (err, doc) {
|
||||
self._onNextObject(err, doc);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle each document as its returned from the cursor.
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
CursorStream.prototype._onNextObject = function (err, doc) {
|
||||
if(err) return this.destroy(err);
|
||||
|
||||
// when doc is null we hit the end of the cursor
|
||||
if(!doc && (this._cursor.state == 1 || this._cursor.state == 2)) {
|
||||
this.emit('end')
|
||||
return this.destroy();
|
||||
} else if(doc) {
|
||||
var data = typeof this.options.transform == 'function' ? this.options.transform(doc) : doc;
|
||||
this.emit('data', data);
|
||||
this._next();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pauses the stream.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
CursorStream.prototype.pause = function () {
|
||||
this.paused = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resumes the stream.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
CursorStream.prototype.resume = function () {
|
||||
var self = this;
|
||||
|
||||
// Don't do anything if we are not paused
|
||||
if(!this.paused) return;
|
||||
if(!this._cursor.state == 3) return;
|
||||
|
||||
process.nextTick(function() {
|
||||
self.paused = false;
|
||||
// Only trigger more fetching if the cursor is open
|
||||
self._next();
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroys the stream, closing the underlying
|
||||
* cursor. No more events will be emitted.
|
||||
*
|
||||
* @api public
|
||||
*/
|
||||
CursorStream.prototype.destroy = function (err) {
|
||||
if (this._destroyed) return;
|
||||
this._destroyed = true;
|
||||
this.readable = false;
|
||||
|
||||
this._cursor.close();
|
||||
|
||||
if(err) {
|
||||
this.emit('error', err);
|
||||
}
|
||||
|
||||
this.emit('close');
|
||||
}
|
||||
|
||||
// TODO - maybe implement the raw option to pass binary?
|
||||
//CursorStream.prototype.setEncoding = function () {
|
||||
//}
|
||||
|
||||
module.exports = exports = CursorStream;
|
||||
2147
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/db.js
generated
vendored
Normal file
2147
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/db.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
213
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/gridfs/chunk.js
generated
vendored
Normal file
213
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/gridfs/chunk.js
generated
vendored
Normal file
@@ -0,0 +1,213 @@
|
||||
var Binary = require('bson').Binary,
|
||||
ObjectID = require('bson').ObjectID;
|
||||
|
||||
/**
|
||||
* Class for representing a single chunk in GridFS.
|
||||
*
|
||||
* @class
|
||||
*
|
||||
* @param file {GridStore} The {@link GridStore} object holding this chunk.
|
||||
* @param mongoObject {object} The mongo object representation of this chunk.
|
||||
*
|
||||
* @throws Error when the type of data field for {@link mongoObject} is not
|
||||
* supported. Currently supported types for data field are instances of
|
||||
* {@link String}, {@link Array}, {@link Binary} and {@link Binary}
|
||||
* from the bson module
|
||||
*
|
||||
* @see Chunk#buildMongoObject
|
||||
*/
|
||||
var Chunk = exports.Chunk = function(file, mongoObject) {
|
||||
if(!(this instanceof Chunk)) return new Chunk(file, mongoObject);
|
||||
|
||||
this.file = file;
|
||||
var self = this;
|
||||
var mongoObjectFinal = mongoObject == null ? {} : mongoObject;
|
||||
|
||||
this.objectId = mongoObjectFinal._id == null ? new ObjectID() : mongoObjectFinal._id;
|
||||
this.chunkNumber = mongoObjectFinal.n == null ? 0 : mongoObjectFinal.n;
|
||||
this.data = new Binary();
|
||||
|
||||
if(mongoObjectFinal.data == null) {
|
||||
} else if(typeof mongoObjectFinal.data == "string") {
|
||||
var buffer = new Buffer(mongoObjectFinal.data.length);
|
||||
buffer.write(mongoObjectFinal.data, 'binary', 0);
|
||||
this.data = new Binary(buffer);
|
||||
} else if(Array.isArray(mongoObjectFinal.data)) {
|
||||
var buffer = new Buffer(mongoObjectFinal.data.length);
|
||||
buffer.write(mongoObjectFinal.data.join(''), 'binary', 0);
|
||||
this.data = new Binary(buffer);
|
||||
} else if(mongoObjectFinal.data instanceof Binary || Object.prototype.toString.call(mongoObjectFinal.data) == "[object Binary]") {
|
||||
this.data = mongoObjectFinal.data;
|
||||
} else if(Buffer.isBuffer(mongoObjectFinal.data)) {
|
||||
} else {
|
||||
throw Error("Illegal chunk format");
|
||||
}
|
||||
// Update position
|
||||
this.internalPosition = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Writes a data to this object and advance the read/write head.
|
||||
*
|
||||
* @param data {string} the data to write
|
||||
* @param callback {function(*, GridStore)} This will be called after executing
|
||||
* this method. The first parameter will contain null and the second one
|
||||
* will contain a reference to this object.
|
||||
*/
|
||||
Chunk.prototype.write = function(data, callback) {
|
||||
this.data.write(data, this.internalPosition);
|
||||
this.internalPosition = this.data.length();
|
||||
if(callback != null) return callback(null, this);
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads data and advances the read/write head.
|
||||
*
|
||||
* @param length {number} The length of data to read.
|
||||
*
|
||||
* @return {string} The data read if the given length will not exceed the end of
|
||||
* the chunk. Returns an empty String otherwise.
|
||||
*/
|
||||
Chunk.prototype.read = function(length) {
|
||||
// Default to full read if no index defined
|
||||
length = length == null || length == 0 ? this.length() : length;
|
||||
|
||||
if(this.length() - this.internalPosition + 1 >= length) {
|
||||
var data = this.data.read(this.internalPosition, length);
|
||||
this.internalPosition = this.internalPosition + length;
|
||||
return data;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
Chunk.prototype.readSlice = function(length) {
|
||||
if ((this.length() - this.internalPosition) >= length) {
|
||||
var data = null;
|
||||
if (this.data.buffer != null) { //Pure BSON
|
||||
data = this.data.buffer.slice(this.internalPosition, this.internalPosition + length);
|
||||
} else { //Native BSON
|
||||
data = new Buffer(length);
|
||||
length = this.data.readInto(data, this.internalPosition);
|
||||
}
|
||||
this.internalPosition = this.internalPosition + length;
|
||||
return data;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if the read/write head is at the end.
|
||||
*
|
||||
* @return {boolean} Whether the read/write head has reached the end of this
|
||||
* chunk.
|
||||
*/
|
||||
Chunk.prototype.eof = function() {
|
||||
return this.internalPosition == this.length() ? true : false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reads one character from the data of this chunk and advances the read/write
|
||||
* head.
|
||||
*
|
||||
* @return {string} a single character data read if the the read/write head is
|
||||
* not at the end of the chunk. Returns an empty String otherwise.
|
||||
*/
|
||||
Chunk.prototype.getc = function() {
|
||||
return this.read(1);
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears the contents of the data in this chunk and resets the read/write head
|
||||
* to the initial position.
|
||||
*/
|
||||
Chunk.prototype.rewind = function() {
|
||||
this.internalPosition = 0;
|
||||
this.data = new Binary();
|
||||
};
|
||||
|
||||
/**
|
||||
* Saves this chunk to the database. Also overwrites existing entries having the
|
||||
* same id as this chunk.
|
||||
*
|
||||
* @param callback {function(*, GridStore)} This will be called after executing
|
||||
* this method. The first parameter will contain null and the second one
|
||||
* will contain a reference to this object.
|
||||
*/
|
||||
Chunk.prototype.save = function(callback) {
|
||||
var self = this;
|
||||
|
||||
self.file.chunkCollection(function(err, collection) {
|
||||
if(err) return callback(err);
|
||||
|
||||
collection.remove({'_id':self.objectId}, {safe:true}, function(err, result) {
|
||||
if(err) return callback(err);
|
||||
|
||||
if(self.data.length() > 0) {
|
||||
self.buildMongoObject(function(mongoObject) {
|
||||
collection.insert(mongoObject, {safe:true}, function(err, collection) {
|
||||
callback(err, self);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
callback(null, self);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a mongoDB object representation of this chunk.
|
||||
*
|
||||
* @param callback {function(Object)} This will be called after executing this
|
||||
* method. The object will be passed to the first parameter and will have
|
||||
* the structure:
|
||||
*
|
||||
* <pre><code>
|
||||
* {
|
||||
* '_id' : , // {number} id for this chunk
|
||||
* 'files_id' : , // {number} foreign key to the file collection
|
||||
* 'n' : , // {number} chunk number
|
||||
* 'data' : , // {bson#Binary} the chunk data itself
|
||||
* }
|
||||
* </code></pre>
|
||||
*
|
||||
* @see <a href="http://www.mongodb.org/display/DOCS/GridFS+Specification#GridFSSpecification-{{chunks}}">MongoDB GridFS Chunk Object Structure</a>
|
||||
*/
|
||||
Chunk.prototype.buildMongoObject = function(callback) {
|
||||
var mongoObject = {'_id': this.objectId,
|
||||
'files_id': this.file.fileId,
|
||||
'n': this.chunkNumber,
|
||||
'data': this.data};
|
||||
callback(mongoObject);
|
||||
};
|
||||
|
||||
/**
|
||||
* @return {number} the length of the data
|
||||
*/
|
||||
Chunk.prototype.length = function() {
|
||||
return this.data.length();
|
||||
};
|
||||
|
||||
/**
|
||||
* The position of the read/write head
|
||||
* @name position
|
||||
* @lends Chunk#
|
||||
* @field
|
||||
*/
|
||||
Object.defineProperty(Chunk.prototype, "position", { enumerable: true
|
||||
, get: function () {
|
||||
return this.internalPosition;
|
||||
}
|
||||
, set: function(value) {
|
||||
this.internalPosition = value;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* The default chunk size
|
||||
* @constant
|
||||
*/
|
||||
Chunk.DEFAULT_CHUNK_SIZE = 1024 * 256;
|
||||
103
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/gridfs/grid.js
generated
vendored
Normal file
103
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/gridfs/grid.js
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
var GridStore = require('./gridstore').GridStore,
|
||||
ObjectID = require('bson').ObjectID;
|
||||
|
||||
/**
|
||||
* A class representation of a simple Grid interface.
|
||||
*
|
||||
* @class Represents the Grid.
|
||||
* @param {Db} db A database instance to interact with.
|
||||
* @param {String} [fsName] optional different root collection for GridFS.
|
||||
* @return {Grid}
|
||||
*/
|
||||
function Grid(db, fsName) {
|
||||
|
||||
if(!(this instanceof Grid)) return new Grid(db, fsName);
|
||||
|
||||
this.db = db;
|
||||
this.fsName = fsName == null ? GridStore.DEFAULT_ROOT_COLLECTION : fsName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts binary data to the grid
|
||||
*
|
||||
* Options
|
||||
* - **_id** {Any}, unique id for this file
|
||||
* - **root** {String}, root collection to use. Defaults to **{GridStore.DEFAULT_ROOT_COLLECTION}**.
|
||||
* - **content_type** {String}, mime type of the file. Defaults to **{GridStore.DEFAULT_CONTENT_TYPE}**.
|
||||
* - **chunk_size** {Number}, size for the chunk. Defaults to **{Chunk.DEFAULT_CHUNK_SIZE}**.
|
||||
* - **metadata** {Object}, arbitrary data the user wants to store.
|
||||
*
|
||||
* @param {Buffer} data buffer with Binary Data.
|
||||
* @param {Object} [options] the options for the files.
|
||||
* @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}
|
||||
* @api public
|
||||
*/
|
||||
Grid.prototype.put = function(data, options, callback) {
|
||||
var self = this;
|
||||
var args = Array.prototype.slice.call(arguments, 1);
|
||||
callback = args.pop();
|
||||
options = args.length ? args.shift() : {};
|
||||
// If root is not defined add our default one
|
||||
options['root'] = options['root'] == null ? this.fsName : options['root'];
|
||||
|
||||
// Return if we don't have a buffer object as data
|
||||
if(!(Buffer.isBuffer(data))) return callback(new Error("Data object must be a buffer object"), null);
|
||||
// Get filename if we are using it
|
||||
var filename = options['filename'] || null;
|
||||
// Get id if we are using it
|
||||
var id = options['_id'] || null;
|
||||
// Create gridstore
|
||||
var gridStore = new GridStore(this.db, id, filename, "w", options);
|
||||
gridStore.open(function(err, gridStore) {
|
||||
if(err) return callback(err, null);
|
||||
|
||||
gridStore.write(data, function(err, result) {
|
||||
if(err) return callback(err, null);
|
||||
|
||||
gridStore.close(function(err, result) {
|
||||
if(err) return callback(err, null);
|
||||
callback(null, result);
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get binary data to the grid
|
||||
*
|
||||
* @param {Any} id for file.
|
||||
* @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}
|
||||
* @api public
|
||||
*/
|
||||
Grid.prototype.get = function(id, callback) {
|
||||
// Create gridstore
|
||||
var gridStore = new GridStore(this.db, id, null, "r", {root:this.fsName});
|
||||
gridStore.open(function(err, gridStore) {
|
||||
if(err) return callback(err, null);
|
||||
|
||||
// Return the data
|
||||
gridStore.read(function(err, data) {
|
||||
return callback(err, data)
|
||||
});
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete file from grid
|
||||
*
|
||||
* @param {Any} id for file.
|
||||
* @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}
|
||||
* @api public
|
||||
*/
|
||||
Grid.prototype.delete = function(id, callback) {
|
||||
// Create gridstore
|
||||
GridStore.unlink(this.db, id, {root:this.fsName}, function(err, result) {
|
||||
if(err) return callback(err, false);
|
||||
return callback(null, true);
|
||||
});
|
||||
}
|
||||
|
||||
exports.Grid = Grid;
|
||||
1476
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js
generated
vendored
Normal file
1476
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/gridfs/gridstore.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
193
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/gridfs/readstream.js
generated
vendored
Normal file
193
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/gridfs/readstream.js
generated
vendored
Normal file
@@ -0,0 +1,193 @@
|
||||
var Stream = require('stream').Stream,
|
||||
timers = require('timers'),
|
||||
util = require('util');
|
||||
|
||||
// Set processor, setImmediate if 0.10 otherwise nextTick
|
||||
var processor = timers.setImmediate ? timers.setImmediate : process.nextTick;
|
||||
processor = process.nextTick
|
||||
|
||||
/**
|
||||
* ReadStream
|
||||
*
|
||||
* Returns a stream interface for the **file**.
|
||||
*
|
||||
* Events
|
||||
* - **data** {function(item) {}} the data event triggers when a document is ready.
|
||||
* - **end** {function() {}} the end event triggers when there is no more documents available.
|
||||
* - **close** {function() {}} the close event triggers when the stream is closed.
|
||||
* - **error** {function(err) {}} the error event triggers if an error happens.
|
||||
*
|
||||
* @class Represents a GridFS File Stream.
|
||||
* @param {Boolean} autoclose automatically close file when the stream reaches the end.
|
||||
* @param {GridStore} cursor a cursor object that the stream wraps.
|
||||
* @return {ReadStream}
|
||||
*/
|
||||
function ReadStream(autoclose, gstore) {
|
||||
if (!(this instanceof ReadStream)) return new ReadStream(autoclose, gstore);
|
||||
Stream.call(this);
|
||||
|
||||
this.autoclose = !!autoclose;
|
||||
this.gstore = gstore;
|
||||
|
||||
this.finalLength = gstore.length - gstore.position;
|
||||
this.completedLength = 0;
|
||||
this.currentChunkNumber = gstore.currentChunk.chunkNumber;
|
||||
|
||||
this.paused = false;
|
||||
this.readable = true;
|
||||
this.pendingChunk = null;
|
||||
this.executing = false;
|
||||
|
||||
// Calculate the number of chunks
|
||||
this.numberOfChunks = Math.ceil(gstore.length/gstore.chunkSize);
|
||||
|
||||
// This seek start position inside the current chunk
|
||||
this.seekStartPosition = gstore.position - (this.currentChunkNumber * gstore.chunkSize);
|
||||
|
||||
var self = this;
|
||||
processor(function() {
|
||||
self._execute();
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Inherit from Stream
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
ReadStream.prototype.__proto__ = Stream.prototype;
|
||||
|
||||
/**
|
||||
* Flag stating whether or not this stream is readable.
|
||||
*/
|
||||
ReadStream.prototype.readable;
|
||||
|
||||
/**
|
||||
* Flag stating whether or not this stream is paused.
|
||||
*/
|
||||
ReadStream.prototype.paused;
|
||||
|
||||
/**
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
ReadStream.prototype._execute = function() {
|
||||
if(this.paused === true || this.readable === false) {
|
||||
return;
|
||||
}
|
||||
|
||||
var gstore = this.gstore;
|
||||
var self = this;
|
||||
// Set that we are executing
|
||||
this.executing = true;
|
||||
|
||||
var last = false;
|
||||
var toRead = 0;
|
||||
|
||||
if(gstore.currentChunk.chunkNumber >= (this.numberOfChunks - 1)) {
|
||||
self.executing = false;
|
||||
last = true;
|
||||
}
|
||||
|
||||
// Data setup
|
||||
var data = null;
|
||||
|
||||
// Read a slice (with seek set if none)
|
||||
if(this.seekStartPosition > 0 && (gstore.currentChunk.length() - this.seekStartPosition) > 0) {
|
||||
data = gstore.currentChunk.readSlice(gstore.currentChunk.length() - this.seekStartPosition);
|
||||
this.seekStartPosition = 0;
|
||||
} else {
|
||||
data = gstore.currentChunk.readSlice(gstore.currentChunk.length());
|
||||
}
|
||||
|
||||
// Return the data
|
||||
if(data != null && gstore.currentChunk.chunkNumber == self.currentChunkNumber) {
|
||||
self.currentChunkNumber = self.currentChunkNumber + 1;
|
||||
self.completedLength += data.length;
|
||||
self.pendingChunk = null;
|
||||
self.emit("data", data);
|
||||
}
|
||||
|
||||
if(last === true) {
|
||||
self.readable = false;
|
||||
self.emit("end");
|
||||
|
||||
if(self.autoclose === true) {
|
||||
if(gstore.mode[0] == "w") {
|
||||
gstore.close(function(err, doc) {
|
||||
if (err) {
|
||||
self.emit("error", err);
|
||||
return;
|
||||
}
|
||||
self.readable = false;
|
||||
self.emit("close", doc);
|
||||
});
|
||||
} else {
|
||||
self.readable = false;
|
||||
self.emit("close");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
gstore._nthChunk(gstore.currentChunk.chunkNumber + 1, function(err, chunk) {
|
||||
if(err) {
|
||||
self.readable = false;
|
||||
self.emit("error", err);
|
||||
self.executing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
self.pendingChunk = chunk;
|
||||
if(self.paused === true) {
|
||||
self.executing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
gstore.currentChunk = self.pendingChunk;
|
||||
self._execute();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Pauses this stream, then no farther events will be fired.
|
||||
*
|
||||
* @ignore
|
||||
* @api public
|
||||
*/
|
||||
ReadStream.prototype.pause = function() {
|
||||
if(!this.executing) {
|
||||
this.paused = true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroys the stream, then no farther events will be fired.
|
||||
*
|
||||
* @ignore
|
||||
* @api public
|
||||
*/
|
||||
ReadStream.prototype.destroy = function() {
|
||||
this.readable = false;
|
||||
// Emit close event
|
||||
this.emit("close");
|
||||
};
|
||||
|
||||
/**
|
||||
* Resumes this stream.
|
||||
*
|
||||
* @ignore
|
||||
* @api public
|
||||
*/
|
||||
ReadStream.prototype.resume = function() {
|
||||
if(this.paused === false || !this.readable) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.paused = false;
|
||||
var self = this;
|
||||
processor(function() {
|
||||
self._execute();
|
||||
});
|
||||
};
|
||||
|
||||
exports.ReadStream = ReadStream;
|
||||
69
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/index.js
generated
vendored
Normal file
69
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/index.js
generated
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
try {
|
||||
exports.BSONPure = require('bson').BSONPure;
|
||||
exports.BSONNative = require('bson').BSONNative;
|
||||
} catch(err) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
[ 'commands/base_command'
|
||||
, 'admin'
|
||||
, 'collection'
|
||||
, 'connection/read_preference'
|
||||
, 'connection/connection'
|
||||
, 'connection/server'
|
||||
, 'connection/mongos'
|
||||
, 'connection/repl_set'
|
||||
, 'mongo_client'
|
||||
, 'cursor'
|
||||
, 'db'
|
||||
, 'mongo_client'
|
||||
, 'gridfs/grid'
|
||||
, 'gridfs/chunk'
|
||||
, 'gridfs/gridstore'].forEach(function (path) {
|
||||
var module = require('./' + path);
|
||||
for (var i in module) {
|
||||
exports[i] = module[i];
|
||||
}
|
||||
|
||||
// backwards compat
|
||||
exports.ReplSetServers = exports.ReplSet;
|
||||
|
||||
// Add BSON Classes
|
||||
exports.Binary = require('bson').Binary;
|
||||
exports.Code = require('bson').Code;
|
||||
exports.DBRef = require('bson').DBRef;
|
||||
exports.Double = require('bson').Double;
|
||||
exports.Long = require('bson').Long;
|
||||
exports.MinKey = require('bson').MinKey;
|
||||
exports.MaxKey = require('bson').MaxKey;
|
||||
exports.ObjectID = require('bson').ObjectID;
|
||||
exports.Symbol = require('bson').Symbol;
|
||||
exports.Timestamp = require('bson').Timestamp;
|
||||
|
||||
// Add BSON Parser
|
||||
exports.BSON = require('bson').BSONPure.BSON;
|
||||
|
||||
});
|
||||
|
||||
// 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];
|
||||
}
|
||||
|
||||
// Add the pure and native backward compatible functions
|
||||
exports.pure = exports.native = function() {
|
||||
return obj;
|
||||
}
|
||||
|
||||
// Map all values to the exports value
|
||||
for(var name in exports) {
|
||||
connect[name] = exports[name];
|
||||
}
|
||||
|
||||
// Set our exports to be the connect function
|
||||
module.exports = connect;
|
||||
116
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/mongo_client.js
generated
vendored
Normal file
116
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/mongo_client.js
generated
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
var Db = require('./db').Db;
|
||||
|
||||
/**
|
||||
* Create a new MongoClient instance.
|
||||
*
|
||||
* Options
|
||||
* - **w**, {Number/String, > -1 || 'majority' || tag name} the write concern for the operation where < 1 is no acknowlegement of write and w >= 1, w = 'majority' or tag acknowledges the write
|
||||
* - **wtimeout**, {Number, 0} set the timeout for waiting for write concern to finish (combines with w option)
|
||||
* - **fsync**, (Boolean, default:false) write waits for fsync before returning
|
||||
* - **journal**, (Boolean, default:false) write waits for journal sync before returning
|
||||
* - **readPreference** {String}, the prefered read preference (ReadPreference.PRIMARY, ReadPreference.PRIMARY_PREFERRED, ReadPreference.SECONDARY, ReadPreference.SECONDARY_PREFERRED, ReadPreference.NEAREST).
|
||||
* - **native_parser** {Boolean, default:false}, use c++ bson parser.
|
||||
* - **forceServerObjectId** {Boolean, default:false}, force server to create _id fields instead of client.
|
||||
* - **pkFactory** {Object}, object overriding the basic ObjectID primary key generation.
|
||||
* - **serializeFunctions** {Boolean, default:false}, serialize functions.
|
||||
* - **raw** {Boolean, default:false}, peform operations using raw bson buffers.
|
||||
* - **recordQueryStats** {Boolean, default:false}, record query statistics during execution.
|
||||
* - **retryMiliSeconds** {Number, default:5000}, number of miliseconds between retries.
|
||||
* - **numberOfRetries** {Number, default:5}, number of retries off connection.
|
||||
*
|
||||
* Deprecated Options
|
||||
* - **safe** {true | {w:n, wtimeout:n} | {fsync:true}, default:false}, executes with a getLastError command returning the results of the command on MongoDB.
|
||||
*
|
||||
* @class Represents a MongoClient
|
||||
* @param {Object} serverConfig server config object.
|
||||
* @param {Object} [options] additional options for the collection.
|
||||
*/
|
||||
function MongoClient(serverConfig, options) {
|
||||
options = options == null ? {} : options;
|
||||
// If no write concern is set set the default to w:1
|
||||
if(options != null && !options.journal && !options.w && !options.fsync) {
|
||||
options.w = 1;
|
||||
}
|
||||
|
||||
// The internal db instance we are wrapping
|
||||
this._db = new Db('test', serverConfig, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the database connection.
|
||||
*
|
||||
* @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 connected mongoclient or null if an error occured.
|
||||
* @return {null}
|
||||
* @api public
|
||||
*/
|
||||
MongoClient.prototype.open = function(callback) {
|
||||
// Self reference
|
||||
var self = this;
|
||||
|
||||
this._db.open(function(err, db) {
|
||||
if(err) return callback(err, null);
|
||||
callback(null, self);
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the current db connection, including all the child db instances. Emits close event if no callback is provided.
|
||||
*
|
||||
* @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 the close method or null if an error occured.
|
||||
* @return {null}
|
||||
* @api public
|
||||
*/
|
||||
MongoClient.prototype.close = function(callback) {
|
||||
this._db.close(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Db instance sharing the current socket connections.
|
||||
*
|
||||
* @param {String} dbName the name of the database we want to use.
|
||||
* @return {Db} a db instance using the new database.
|
||||
* @api public
|
||||
*/
|
||||
MongoClient.prototype.db = function(dbName) {
|
||||
return this._db.db(dbName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connect to MongoDB using a url as documented at
|
||||
*
|
||||
* docs.mongodb.org/manual/reference/connection-string/
|
||||
*
|
||||
* Options
|
||||
* - **uri_decode_auth** {Boolean, default:false} uri decode the user name and password for authentication
|
||||
* - **db** {Object, default: null} a hash off options to set on the db object, see **Db constructor**
|
||||
* - **server** {Object, default: null} a hash off options to set on the server objects, see **Server** constructor**
|
||||
* - **replSet** {Object, default: null} a hash off options to set on the replSet object, see **ReplSet** constructor**
|
||||
* - **mongos** {Object, default: null} a hash off options to set on the mongos object, see **Mongos** constructor**
|
||||
*
|
||||
* @param {String} url connection url for MongoDB.
|
||||
* @param {Object} [options] optional options for insert command
|
||||
* @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 initialized db object or null if an error occured.
|
||||
* @return {null}
|
||||
* @api public
|
||||
*/
|
||||
MongoClient.connect = function(url, options, callback) {
|
||||
if(typeof options == 'function') {
|
||||
callback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
Db.connect(url, options, function(err, db) {
|
||||
if(err) return callback(err, null);
|
||||
|
||||
if(db.options !== null && !db.options.safe && !db.options.journal
|
||||
&& !db.options.w && !db.options.fsync && typeof db.options.w != 'number'
|
||||
&& (db.options.safe == false && url.indexOf("safe=") == -1)) {
|
||||
db.options.w = 1;
|
||||
}
|
||||
|
||||
// Return the db
|
||||
callback(null, db);
|
||||
});
|
||||
}
|
||||
|
||||
exports.MongoClient = MongoClient;
|
||||
145
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js
generated
vendored
Normal file
145
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/responses/mongo_reply.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
var Long = require('bson').Long
|
||||
, timers = require('timers');
|
||||
|
||||
// Set processor, setImmediate if 0.10 otherwise nextTick
|
||||
var processor = timers.setImmediate ? timers.setImmediate : process.nextTick;
|
||||
processor = process.nextTick
|
||||
|
||||
/**
|
||||
Reply message from mongo db
|
||||
**/
|
||||
var MongoReply = exports.MongoReply = function() {
|
||||
this.documents = [];
|
||||
this.index = 0;
|
||||
};
|
||||
|
||||
MongoReply.prototype.parseHeader = function(binary_reply, bson) {
|
||||
// Unpack the standard header first
|
||||
this.messageLength = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
// Fetch the request id for this reply
|
||||
this.requestId = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
// Fetch the id of the request that triggered the response
|
||||
this.responseTo = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
// Skip op-code field
|
||||
this.index = this.index + 4 + 4;
|
||||
// Unpack the reply message
|
||||
this.responseFlag = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
// Unpack the cursor id (a 64 bit long integer)
|
||||
var low_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
var high_bits = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
this.cursorId = new Long(low_bits, high_bits);
|
||||
// Unpack the starting from
|
||||
this.startingFrom = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
// Unpack the number of objects returned
|
||||
this.numberReturned = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
this.index = this.index + 4;
|
||||
}
|
||||
|
||||
MongoReply.prototype.parseBody = function(binary_reply, bson, raw, callback) {
|
||||
raw = raw == null ? false : raw;
|
||||
// Just set a doc limit for deserializing
|
||||
var docLimitSize = 1024*20;
|
||||
|
||||
// If our message length is very long, let's switch to process.nextTick for messages
|
||||
if(this.messageLength > docLimitSize) {
|
||||
var batchSize = this.numberReturned;
|
||||
this.documents = new Array(this.numberReturned);
|
||||
|
||||
// Just walk down until we get a positive number >= 1
|
||||
for(var i = 50; i > 0; i--) {
|
||||
if((this.numberReturned/i) >= 1) {
|
||||
batchSize = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Actual main creator of the processFunction setting internal state to control the flow
|
||||
var parseFunction = function(_self, _binary_reply, _batchSize, _numberReturned) {
|
||||
var object_index = 0;
|
||||
// Internal loop process that will use nextTick to ensure we yield some time
|
||||
var processFunction = function() {
|
||||
// Adjust batchSize if we have less results left than batchsize
|
||||
if((_numberReturned - object_index) < _batchSize) {
|
||||
_batchSize = _numberReturned - object_index;
|
||||
}
|
||||
|
||||
// If raw just process the entries
|
||||
if(raw) {
|
||||
// Iterate over the batch
|
||||
for(var i = 0; i < _batchSize; i++) {
|
||||
// Are we done ?
|
||||
if(object_index <= _numberReturned) {
|
||||
// Read the size of the bson object
|
||||
var bsonObjectSize = _binary_reply[_self.index] | _binary_reply[_self.index + 1] << 8 | _binary_reply[_self.index + 2] << 16 | _binary_reply[_self.index + 3] << 24;
|
||||
// If we are storing the raw responses to pipe straight through
|
||||
_self.documents[object_index] = binary_reply.slice(_self.index, _self.index + bsonObjectSize);
|
||||
// Adjust binary index to point to next block of binary bson data
|
||||
_self.index = _self.index + bsonObjectSize;
|
||||
// Update number of docs parsed
|
||||
object_index = object_index + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
// Parse documents
|
||||
_self.index = bson.deserializeStream(binary_reply, _self.index, _batchSize, _self.documents, object_index);
|
||||
// Adjust index
|
||||
object_index = object_index + _batchSize;
|
||||
} catch (err) {
|
||||
return callback(err);
|
||||
}
|
||||
}
|
||||
|
||||
// If we hav more documents process NextTick
|
||||
if(object_index < _numberReturned) {
|
||||
processor(processFunction);
|
||||
} else {
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
|
||||
// Return the process function
|
||||
return processFunction;
|
||||
}(this, binary_reply, batchSize, this.numberReturned)();
|
||||
} else {
|
||||
try {
|
||||
// Let's unpack all the bson documents, deserialize them and store them
|
||||
for(var object_index = 0; object_index < this.numberReturned; object_index++) {
|
||||
// Read the size of the bson object
|
||||
var bsonObjectSize = binary_reply[this.index] | binary_reply[this.index + 1] << 8 | binary_reply[this.index + 2] << 16 | binary_reply[this.index + 3] << 24;
|
||||
// If we are storing the raw responses to pipe straight through
|
||||
if(raw) {
|
||||
// Deserialize the object and add to the documents array
|
||||
this.documents.push(binary_reply.slice(this.index, this.index + bsonObjectSize));
|
||||
} else {
|
||||
// Deserialize the object and add to the documents array
|
||||
this.documents.push(bson.deserialize(binary_reply.slice(this.index, this.index + bsonObjectSize)));
|
||||
}
|
||||
// Adjust binary index to point to next block of binary bson data
|
||||
this.index = this.index + bsonObjectSize;
|
||||
}
|
||||
} catch(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
// No error return
|
||||
callback(null);
|
||||
}
|
||||
}
|
||||
|
||||
MongoReply.prototype.is_error = function(){
|
||||
if(this.documents.length == 1) {
|
||||
return this.documents[0].ok == 1 ? false : true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
MongoReply.prototype.error_message = function() {
|
||||
return this.documents.length == 1 && this.documents[0].ok == 1 ? '' : this.documents[0].errmsg;
|
||||
};
|
||||
121
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/utils.js
generated
vendored
Normal file
121
mongoui/mongoui-master/node_modules/mongodb/lib/mongodb/utils.js
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
/**
|
||||
* Sort functions, Normalize and prepare sort parameters
|
||||
*/
|
||||
var formatSortValue = exports.formatSortValue = function(sortDirection) {
|
||||
var value = ("" + sortDirection).toLowerCase();
|
||||
|
||||
switch (value) {
|
||||
case 'ascending':
|
||||
case 'asc':
|
||||
case '1':
|
||||
return 1;
|
||||
case 'descending':
|
||||
case 'desc':
|
||||
case '-1':
|
||||
return -1;
|
||||
default:
|
||||
throw new Error("Illegal sort clause, must be of the form "
|
||||
+ "[['field1', '(ascending|descending)'], "
|
||||
+ "['field2', '(ascending|descending)']]");
|
||||
}
|
||||
};
|
||||
|
||||
var formattedOrderClause = exports.formattedOrderClause = function(sortValue) {
|
||||
var orderBy = {};
|
||||
|
||||
if (Array.isArray(sortValue)) {
|
||||
for(var i = 0; i < sortValue.length; i++) {
|
||||
if(sortValue[i].constructor == String) {
|
||||
orderBy[sortValue[i]] = 1;
|
||||
} else {
|
||||
orderBy[sortValue[i][0]] = formatSortValue(sortValue[i][1]);
|
||||
}
|
||||
}
|
||||
} else if(Object.prototype.toString.call(sortValue) === '[object Object]') {
|
||||
orderBy = sortValue;
|
||||
} else if (sortValue.constructor == String) {
|
||||
orderBy[sortValue] = 1;
|
||||
} else {
|
||||
throw new Error("Illegal sort clause, must be of the form " +
|
||||
"[['field1', '(ascending|descending)'], ['field2', '(ascending|descending)']]");
|
||||
}
|
||||
|
||||
return orderBy;
|
||||
};
|
||||
|
||||
exports.encodeInt = function(value) {
|
||||
var buffer = new Buffer(4);
|
||||
buffer[3] = (value >> 24) & 0xff;
|
||||
buffer[2] = (value >> 16) & 0xff;
|
||||
buffer[1] = (value >> 8) & 0xff;
|
||||
buffer[0] = value & 0xff;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
exports.encodeIntInPlace = function(value, buffer, index) {
|
||||
buffer[index + 3] = (value >> 24) & 0xff;
|
||||
buffer[index + 2] = (value >> 16) & 0xff;
|
||||
buffer[index + 1] = (value >> 8) & 0xff;
|
||||
buffer[index] = value & 0xff;
|
||||
}
|
||||
|
||||
exports.encodeCString = function(string) {
|
||||
var buf = new Buffer(string, 'utf8');
|
||||
return [buf, new Buffer([0])];
|
||||
}
|
||||
|
||||
exports.decodeUInt32 = function(array, index) {
|
||||
return array[index] | array[index + 1] << 8 | array[index + 2] << 16 | array[index + 3] << 24;
|
||||
}
|
||||
|
||||
// Decode the int
|
||||
exports.decodeUInt8 = function(array, index) {
|
||||
return array[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap a Mongo error document in an Error instance
|
||||
* @ignore
|
||||
* @api private
|
||||
*/
|
||||
exports.toError = function(error) {
|
||||
if (error instanceof Error) return error;
|
||||
|
||||
var msg = error.err || error.errmsg || error;
|
||||
var e = new Error(msg);
|
||||
e.name = 'MongoError';
|
||||
|
||||
// Get all object keys
|
||||
var keys = typeof error == 'object'
|
||||
? Object.keys(error)
|
||||
: [];
|
||||
|
||||
for(var i = 0; i < keys.length; i++) {
|
||||
e[keys[i]] = error[keys[i]];
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
Reference in New Issue
Block a user