summaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
authorAntonin Kral <a.kral@bobek.cz>2010-08-11 12:38:57 +0200
committerAntonin Kral <a.kral@bobek.cz>2010-08-11 12:38:57 +0200
commit7645618fd3914cb8a20561625913c20d49504a49 (patch)
tree8370f846f58f6d71165b7a0e2eda04648584ec76 /shell
parent68c73c3c7608b4c87f07440dc3232801720b1168 (diff)
downloadmongodb-7645618fd3914cb8a20561625913c20d49504a49.tar.gz
Imported Upstream version 1.6.0
Diffstat (limited to 'shell')
-rw-r--r--shell/collection.js83
-rw-r--r--shell/db.js108
-rw-r--r--shell/dbshell.cpp190
-rw-r--r--shell/mongo.js5
-rw-r--r--shell/mongo_vstudio.cpp3295
-rwxr-xr-xshell/msvc/mongo.icobin0 -> 1078 bytes
-rw-r--r--shell/msvc/mongo.sln20
-rw-r--r--shell/msvc/mongo.vcxproj253
-rw-r--r--shell/msvc/mongo.vcxproj.filters262
-rw-r--r--shell/query.js77
-rw-r--r--shell/servers.js774
-rw-r--r--shell/shell_utils.cpp (renamed from shell/utils.cpp)298
-rw-r--r--shell/utils.js271
13 files changed, 3850 insertions, 1786 deletions
diff --git a/shell/collection.js b/shell/collection.js
index edb07ae..68ee03d 100644
--- a/shell/collection.js
+++ b/shell/collection.js
@@ -1,5 +1,6 @@
-// collection.js
-
+// collection.js - DBCollection support in the mongo shell
+// db.colName is a DBCollection object
+// or db["colName"]
if ( ( typeof DBCollection ) == "undefined" ){
DBCollection = function( mongo , db , shortName , fullName ){
@@ -26,39 +27,42 @@ DBCollection.prototype.getName = function(){
return this._shortName;
}
-DBCollection.prototype.help = function() {
+DBCollection.prototype.help = function () {
+ var shortName = this.getName();
print("DBCollection help");
- print("\tdb.foo.count()");
- print("\tdb.foo.dataSize()");
- print("\tdb.foo.distinct( key ) - eg. db.foo.distinct( 'x' )");
- print("\tdb.foo.drop() drop the collection");
- print("\tdb.foo.dropIndex(name)");
- print("\tdb.foo.dropIndexes()");
- print("\tdb.foo.ensureIndex(keypattern,options) - options should be an object with these possible fields: name, unique, dropDups");
- print("\tdb.foo.reIndex()");
- print("\tdb.foo.find( [query] , [fields]) - first parameter is an optional query filter. second parameter is optional set of fields to return.");
- print("\t e.g. db.foo.find( { x : 77 } , { name : 1 , x : 1 } )");
- print("\tdb.foo.find(...).count()");
- print("\tdb.foo.find(...).limit(n)");
- print("\tdb.foo.find(...).skip(n)");
- print("\tdb.foo.find(...).sort(...)");
- print("\tdb.foo.findOne([query])");
- print("\tdb.foo.findAndModify( { update : ... , remove : bool [, query: {}, sort: {}, 'new': false] } )");
- print("\tdb.foo.getDB() get DB object associated with collection");
- print("\tdb.foo.getIndexes()");
- print("\tdb.foo.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )");
- print("\tdb.foo.mapReduce( mapFunction , reduceFunction , <optional params> )");
- print("\tdb.foo.remove(query)");
- print("\tdb.foo.renameCollection( newName , <dropTarget> ) renames the collection.");
- print("\tdb.foo.runCommand( name , <options> ) runs a db command with the given name where the 1st param is the colleciton name" );
- print("\tdb.foo.save(obj)");
- print("\tdb.foo.stats()");
- print("\tdb.foo.storageSize() - includes free space allocated to this collection");
- print("\tdb.foo.totalIndexSize() - size in bytes of all the indexes");
- print("\tdb.foo.totalSize() - storage allocated for all data and indexes");
- print("\tdb.foo.update(query, object[, upsert_bool, multi_bool])");
- print("\tdb.foo.validate() - SLOW");
- print("\tdb.foo.getShardVersion() - only for use with sharding");
+ print("\tdb." + shortName + ".find().help() - show DBCursor help");
+ print("\tdb." + shortName + ".count()");
+ print("\tdb." + shortName + ".dataSize()");
+ print("\tdb." + shortName + ".distinct( key ) - eg. db." + shortName + ".distinct( 'x' )");
+ print("\tdb." + shortName + ".drop() drop the collection");
+ print("\tdb." + shortName + ".dropIndex(name)");
+ print("\tdb." + shortName + ".dropIndexes()");
+ print("\tdb." + shortName + ".ensureIndex(keypattern,options) - options should be an object with these possible fields: name, unique, dropDups");
+ print("\tdb." + shortName + ".reIndex()");
+ print("\tdb." + shortName + ".find( [query] , [fields]) - first parameter is an optional query filter. second parameter is optional set of fields to return.");
+ print("\t e.g. db." + shortName + ".find( { x : 77 } , { name : 1 , x : 1 } )");
+ print("\tdb." + shortName + ".find(...).count()");
+ print("\tdb." + shortName + ".find(...).limit(n)");
+ print("\tdb." + shortName + ".find(...).skip(n)");
+ print("\tdb." + shortName + ".find(...).sort(...)");
+ print("\tdb." + shortName + ".findOne([query])");
+ print("\tdb." + shortName + ".findAndModify( { update : ... , remove : bool [, query: {}, sort: {}, 'new': false] } )");
+ print("\tdb." + shortName + ".getDB() get DB object associated with collection");
+ print("\tdb." + shortName + ".getIndexes()");
+ print("\tdb." + shortName + ".group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )");
+ print("\tdb." + shortName + ".mapReduce( mapFunction , reduceFunction , <optional params> )");
+ print("\tdb." + shortName + ".remove(query)");
+ print("\tdb." + shortName + ".renameCollection( newName , <dropTarget> ) renames the collection.");
+ print("\tdb." + shortName + ".runCommand( name , <options> ) runs a db command with the given name where the first param is the collection name");
+ print("\tdb." + shortName + ".save(obj)");
+ print("\tdb." + shortName + ".stats()");
+ print("\tdb." + shortName + ".storageSize() - includes free space allocated to this collection");
+ print("\tdb." + shortName + ".totalIndexSize() - size in bytes of all the indexes");
+ print("\tdb." + shortName + ".totalSize() - storage allocated for all data and indexes");
+ print("\tdb." + shortName + ".update(query, object[, upsert_bool, multi_bool])");
+ print("\tdb." + shortName + ".validate() - SLOW");
+ print("\tdb." + shortName + ".getShardVersion() - only for use with sharding");
+ return __magicNoPrint;
}
DBCollection.prototype.getFullName = function(){
@@ -333,7 +337,7 @@ DBCollection.prototype.findAndModify = function(args){
var ret = this._db.runCommand( cmd );
if ( ! ret.ok ){
if (ret.errmsg == "No matching object found"){
- return {};
+ return null;
}
throw "findAndModifyFailed failed: " + tojson( ret.errmsg );
}
@@ -351,8 +355,10 @@ DBCollection.prototype.validate = function() {
res.valid = false;
- if ( res.result ){
- var str = "-" + tojson( res.result );
+ var raw = res.result || res.raw;
+
+ if ( raw ){
+ var str = "-" + tojson( raw );
res.valid = ! ( str.match( /exception/ ) || str.match( /corrupt/ ) );
var p = /lastExtentSize:(\d+)/;
@@ -572,6 +578,3 @@ DBCollection.prototype.toString = function(){
DBCollection.prototype.tojson = DBCollection.prototype.toString;
DBCollection.prototype.shellPrint = DBCollection.prototype.toString;
-
-
-
diff --git a/shell/db.js b/shell/db.js
index bdb1153..8299695 100644
--- a/shell/db.js
+++ b/shell/db.js
@@ -259,7 +259,7 @@ DB.prototype.help = function() {
print("\tdb.commandHelp(name) returns the help for the command");
print("\tdb.copyDatabase(fromdb, todb, fromhost)");
print("\tdb.createCollection(name, { size : ..., capped : ..., max : ... } )");
- print("\tdb.currentOp() displays the current operation in the db" );
+ print("\tdb.currentOp() displays the current operation in the db");
print("\tdb.dropDatabase()");
print("\tdb.eval(func, args) run code server-side");
print("\tdb.getCollection(cname) same as db['cname'] or db.cname");
@@ -271,10 +271,12 @@ DB.prototype.help = function() {
print("\tdb.getName()");
print("\tdb.getPrevError()");
print("\tdb.getProfilingLevel()");
- print("\tdb.getReplicationInfo()");
- print("\tdb.getSisterDB(name) get the db at the same server as this onew");
- print("\tdb.killOp(opid) kills the current operation in the db" );
- print("\tdb.printCollectionStats()" );
+ print("\tdb.getReplicationInfo()");
+ print("\tdb.getSisterDB(name) get the db at the same server as this one");
+ print("\tdb.isMaster() check replica primary status");
+ print("\tdb.killOp(opid) kills the current operation in the db");
+ print("\tdb.listCommands() lists all the db commands");
+ print("\tdb.printCollectionStats()");
print("\tdb.printReplicationInfo()");
print("\tdb.printSlaveReplicationInfo()");
print("\tdb.printShardingStatus()");
@@ -286,7 +288,10 @@ DB.prototype.help = function() {
print("\tdb.setProfilingLevel(level,<slowms>) 0=off 1=slow 2=all");
print("\tdb.shutdownServer()");
print("\tdb.stats()");
- print("\tdb.version() current version of the server" );
+ print("\tdb.version() current version of the server");
+ print("\tdb.getMongo().setSlaveOk() allow queries on a replication slave server");
+
+ return __magicNoPrint;
}
DB.prototype.printCollectionStats = function(){
@@ -309,9 +314,10 @@ DB.prototype.printCollectionStats = function(){
* <p>Levels :</p>
* <ul>
* <li>0=off</li>
- * <li>1=log very slow (>100ms) operations</li>
+ * <li>1=log very slow operations; optional argument slowms specifies slowness threshold</li>
* <li>2=log all</li>
* @param {String} level Desired level of profiling
+ * @param {String} slowms For slow logging, query duration that counts as slow (default 100ms)
* @return SOMETHING_FIXME or null on error
*/
DB.prototype.setProfilingLevel = function(level,slowms) {
@@ -471,14 +477,21 @@ DB.prototype.forceError = function(){
return this.runCommand( { forceerror : 1 } );
}
-DB.prototype.getLastError = function(){
- var res = this.runCommand( { getlasterror : 1 } );
+DB.prototype.getLastError = function( w , wtimeout ){
+ var res = this.getLastErrorObj( w , wtimeout );
if ( ! res.ok )
throw "getlasterror failed: " + tojson( res );
return res.err;
}
-DB.prototype.getLastErrorObj = function(){
- var res = this.runCommand( { getlasterror : 1 } );
+DB.prototype.getLastErrorObj = function( w , wtimeout ){
+ var cmd = { getlasterror : 1 };
+ if ( w ){
+ cmd.w = w;
+ if ( wtimeout )
+ cmd.wtimeout = wtimeout;
+ }
+ var res = this.runCommand( cmd );
+
if ( ! res.ok )
throw "getlasterror failed: " + tojson( res );
return res;
@@ -502,17 +515,17 @@ DB.prototype.getCollectionNames = function(){
var nsLength = this._name.length + 1;
- this.getCollection( "system.namespaces" ).find().sort({name:1}).forEach(
- function(z){
- var name = z.name;
-
- if ( name.indexOf( "$" ) >= 0 && name != "local.oplog.$main" )
- return;
-
- all.push( name.substring( nsLength ) );
- }
- );
- return all;
+ var c = this.getCollection( "system.namespaces" ).find();
+ while ( c.hasNext() ){
+ var name = c.next().name;
+
+ if ( name.indexOf( "$" ) >= 0 && name.indexOf( ".oplog.$" ) < 0 )
+ continue;
+
+ all.push( name.substring( nsLength ) );
+ }
+
+ return all.sort();
}
DB.prototype.tojson = function(){
@@ -521,7 +534,9 @@ DB.prototype.tojson = function(){
DB.prototype.toString = function(){
return this._name;
-}
+}
+
+DB.prototype.isMaster = function () { return this.runCommand("isMaster"); }
DB.prototype.currentOp = function(){
return db.$cmd.sys.inprog.findOne();
@@ -615,13 +630,19 @@ DB.prototype.printReplicationInfo = function() {
DB.prototype.printSlaveReplicationInfo = function() {
function g(x) {
+ assert( x , "how could this be null (printSlaveReplicationInfo gx)" )
print("source: " + x.host);
- var st = new Date( DB.tsToSeconds( x.syncedTo ) * 1000 );
- var now = new Date();
- print("syncedTo: " + st.toString() );
- var ago = (now-st)/1000;
- var hrs = Math.round(ago/36)/100;
- print(" = " + Math.round(ago) + "secs ago (" + hrs + "hrs)");
+ if ( x.syncedTo ){
+ var st = new Date( DB.tsToSeconds( x.syncedTo ) * 1000 );
+ var now = new Date();
+ print("\t syncedTo: " + st.toString() );
+ var ago = (now-st)/1000;
+ var hrs = Math.round(ago/36)/100;
+ print("\t\t = " + Math.round(ago) + "secs ago (" + hrs + "hrs)");
+ }
+ else {
+ print( "\t doing initial sync" );
+ }
}
var L = this.getSisterDB("local");
if( L.sources.count() == 0 ) {
@@ -639,10 +660,39 @@ DB.prototype.serverStatus = function(){
return this._adminCommand( "serverStatus" );
}
+DB.prototype.serverCmdLineOpts = function(){
+ return this._adminCommand( "getCmdLineOpts" );
+}
+
DB.prototype.version = function(){
return this.serverBuildInfo().version;
}
+DB.prototype.listCommands = function(){
+ var x = this.runCommand( "listCommands" );
+ for ( var name in x.commands ){
+ var c = x.commands[name];
+
+ var s = name + ": ";
+
+ switch ( c.lockType ){
+ case -1: s += "read-lock"; break;
+ case 0: s += "no-lock"; break;
+ case 1: s += "write-lock"; break;
+ default: s += c.lockType;
+ }
+
+ if (c.adminOnly) s += " adminOnly ";
+ if (c.adminOnly) s += " slaveOk ";
+
+ s += "\n ";
+ s += c.help.replace(/\n/g, '\n ');
+ s += "\n";
+
+ print( s );
+ }
+}
+
DB.prototype.printShardingStatus = function(){
printShardingStatus( this.getSisterDB( "config" ) );
}
diff --git a/shell/dbshell.cpp b/shell/dbshell.cpp
index cad3698..2bd8973 100644
--- a/shell/dbshell.cpp
+++ b/shell/dbshell.cpp
@@ -15,9 +15,15 @@
* limitations under the License.
*/
-
+#include "pch.h"
#include <stdio.h>
+#if defined(_WIN32)
+# if defined(USE_READLINE)
+# define USE_READLINE_STATIC
+# endif
+#endif
+
#ifdef USE_READLINE
#include <readline/readline.h>
#include <readline/history.h>
@@ -30,18 +36,87 @@ jmp_buf jbuf;
#include "../util/unittest.h"
#include "../db/cmdline.h"
#include "utils.h"
+#include "../util/password.h"
+#include "../util/version.h"
+#include "../util/goodies.h"
using namespace std;
using namespace boost::filesystem;
+using mongo::BSONObj;
+using mongo::BSONObjBuilder;
+using mongo::BSONObjIterator;
+using mongo::BSONElement;
+
string historyFile;
bool gotInterrupted = 0;
bool inMultiLine = 0;
+static volatile bool atPrompt = false; // can eval before getting to prompt
+bool autoKillOp = false;
+
-#if defined(USE_READLINE) && !defined(__freebsd__) && !defined(_WIN32)
+#if defined(USE_READLINE) && !defined(__freebsd__) && !defined(__openbsd__) && !defined(_WIN32)
#define CTRLC_HANDLE
#endif
+mongo::Scope * shellMainScope;
+
+void generateCompletions( const string& prefix , vector<string>& all ){
+ if ( prefix.find( '"' ) != string::npos )
+ return;
+ shellMainScope->exec( "shellAutocomplete( \"" + prefix + "\" );" , "autocomplete help" , false , true , false );
+
+ BSONObjBuilder b;
+ shellMainScope->append( b , "" , "__autocomplete__" );
+ BSONObj res = b.obj();
+ BSONObj arr = res.firstElement().Obj();
+
+ BSONObjIterator i(arr);
+ while ( i.more() ){
+ BSONElement e = i.next();
+ all.push_back( e.String() );
+ }
+
+}
+
+#ifdef USE_READLINE
+static char** completionHook(const char* text , int start ,int end ){
+ static map<string,string> m;
+
+ vector<string> all;
+
+ if ( start == 0 ){
+ generateCompletions( string(text,end) , all );
+ }
+
+ if ( all.size() == 0 ){
+ rl_bind_key('\t',0);
+ return 0;
+ }
+
+ string longest = all[0];
+ for ( vector<string>::iterator i=all.begin(); i!=all.end(); ++i ){
+ string s = *i;
+ for ( unsigned j=0; j<s.size(); j++ ){
+ if ( longest[j] == s[j] )
+ continue;
+ longest = longest.substr(0,j);
+ break;
+ }
+ }
+
+ char ** matches = (char**)malloc( sizeof(char*) * (all.size()+2) );
+ unsigned x=0;
+ matches[x++] = strdup( longest.c_str() );
+ for ( unsigned i=0; i<all.size(); i++ ){
+ matches[x++] = strdup( all[i].c_str() );
+ }
+ matches[x++] = 0;
+
+ return matches;
+}
+#endif
+
void shellHistoryInit(){
#ifdef USE_READLINE
stringstream ss;
@@ -53,9 +128,11 @@ void shellHistoryInit(){
using_history();
read_history( historyFile.c_str() );
-
+
+ rl_attempted_completion_function = completionHook;
+
#else
- cout << "type \"exit\" to exit" << endl;
+ //cout << "type \"exit\" to exit" << endl;
#endif
}
void shellHistoryDone(){
@@ -64,9 +141,16 @@ void shellHistoryDone(){
#endif
}
void shellHistoryAdd( const char * line ){
- if ( strlen(line) == 0 )
- return;
#ifdef USE_READLINE
+ if ( line[0] == '\0' )
+ return;
+
+ // dont record duplicate lines
+ static string lastLine;
+ if (lastLine == line)
+ return;
+ lastLine = line;
+
if ((strstr(line, ".auth")) == NULL)
add_history( line );
#endif
@@ -82,6 +166,22 @@ void intr( int sig ){
void killOps() {
if ( mongo::shellUtils::_nokillop || mongo::shellUtils::_allMyUris.size() == 0 )
return;
+
+ if ( atPrompt )
+ return;
+
+ if ( !autoKillOp ) {
+ cout << endl << "do you want to kill the current op on the server? (y/n): ";
+ cout.flush();
+
+ char yn;
+ cin >> yn;
+
+ if (yn != 'y' && yn != 'Y')
+ return;
+ }
+
+
vector< string > uris;
for( map< const void*, string >::iterator i = mongo::shellUtils::_allMyUris.begin(); i != mongo::shellUtils::_allMyUris.end(); ++i )
uris.push_back( i->second );
@@ -95,6 +195,7 @@ void killOps() {
}
void quitNicely( int sig ){
+ mongo::goingAway = true;
if ( sig == SIGINT && inMultiLine ){
gotInterrupted = 1;
return;
@@ -105,14 +206,28 @@ void quitNicely( int sig ){
shellHistoryDone();
exit(0);
}
+#else
+void quitNicely( int sig ){
+ mongo::goingAway = true;
+ //killOps();
+ shellHistoryDone();
+ exit(0);
+}
#endif
char * shellReadline( const char * prompt , int handlesigint = 0 ){
+ atPrompt = true;
#ifdef USE_READLINE
+ rl_bind_key('\t',rl_complete);
+
+
#ifdef CTRLC_HANDLE
- if ( ! handlesigint )
- return readline( prompt );
+ if ( ! handlesigint ){
+ char* ret = readline( prompt );
+ atPrompt = false;
+ return ret;
+ }
if ( setjmp( jbuf ) ){
gotInterrupted = 1;
sigrelse(SIGINT);
@@ -124,13 +239,16 @@ char * shellReadline( const char * prompt , int handlesigint = 0 ){
char * ret = readline( prompt );
signal( SIGINT , quitNicely );
+ atPrompt = false;
return ret;
#else
- printf("%s", prompt);
+ printf("%s", prompt); cout.flush();
char * buf = new char[1024];
char * l = fgets( buf , 1024 , stdin );
int len = strlen( buf );
- buf[len-1] = 0;
+ if ( len )
+ buf[len-1] = 0;
+ atPrompt = false;
return l;
#endif
}
@@ -173,8 +291,8 @@ string fixHost( string url , string host , string port ){
if ( url.find( "." ) != string::npos )
return url + "/test";
- if ( url.find( ":" ) != string::npos &&
- isdigit( url[url.find(":")+1] ) )
+ if ( url.rfind( ":" ) != string::npos &&
+ isdigit( url[url.rfind(":")+1] ) )
return url + "/test";
}
return url;
@@ -191,6 +309,10 @@ string fixHost( string url , string host , string port ){
string newurl = host;
if ( port.size() > 0 )
newurl += ":" + port;
+ else if (host.find(':') == string::npos){
+ // need to add port with IPv6 addresses
+ newurl += ":27017";
+ }
newurl += "/" + url;
@@ -283,7 +405,12 @@ bool fileExists( string file ){
}
}
+namespace mongo {
+ extern bool isShell;
+}
+
int _main(int argc, char* argv[]) {
+ mongo::isShell = true;
setupSignals();
mongo::shellUtils::RecordMyLocation( argv[ 0 ] );
@@ -314,15 +441,18 @@ int _main(int argc, char* argv[]) {
("host", po::value<string>(&dbhost), "server to connect to")
("eval", po::value<string>(&script), "evaluate javascript")
("username,u", po::value<string>(&username), "username for authentication")
- ("password,p", po::value<string>(&password), "password for authentication")
+ ("password,p", new mongo::PasswordValue(&password),
+ "password for authentication")
("help,h", "show this usage information")
("version", "show version information")
+ ("ipv6", "enable IPv6 support (disabled by default)")
;
hidden_options.add_options()
("dbaddress", po::value<string>(), "dbaddress")
("files", po::value< vector<string> >(), "files")
("nokillop", "nokillop") // for testing, kill op will also be disabled automatically if the tests starts a mongo program
+ ("autokillop", "autokillop") // for testing, will kill op without prompting
;
positional_options.add("dbaddress", 1);
@@ -350,6 +480,16 @@ int _main(int argc, char* argv[]) {
return mongo::EXIT_BADOPTIONS;
}
+ // hide password from ps output
+ for (int i=0; i < (argc-1); ++i){
+ if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--password")){
+ char* arg = argv[i+1];
+ while (*arg){
+ *arg++ = 'x';
+ }
+ }
+ }
+
if (params.count("shell")) {
runShell = true;
}
@@ -373,6 +513,9 @@ int _main(int argc, char* argv[]) {
if (params.count("nokillop")) {
mongo::shellUtils::_nokillop = true;
}
+ if (params.count("autokillop")) {
+ autoKillOp = true;
+ }
/* This is a bit confusing, here are the rules:
*
@@ -395,6 +538,9 @@ int _main(int argc, char* argv[]) {
}
}
}
+ if (params.count("ipv6")){
+ mongo::enableIPv6();
+ }
if ( ! mongo::cmdLine.quiet )
cout << "MongoDB shell version: " << mongo::versionString << endl;
@@ -402,7 +548,7 @@ int _main(int argc, char* argv[]) {
mongo::UnitTest::runTests();
if ( !nodb ) { // connect to db
- if ( ! mongo::cmdLine.quiet ) cout << "url: " << url << endl;
+ //if ( ! mongo::cmdLine.quiet ) cout << "url: " << url << endl;
stringstream ss;
if ( mongo::cmdLine.quiet )
@@ -411,6 +557,11 @@ int _main(int argc, char* argv[]) {
mongo::shellUtils::_dbConnect = ss.str();
+ if ( params.count( "password" )
+ && ( password.empty() ) ) {
+ password = mongo::askPassword();
+ }
+
if ( username.size() && password.size() ){
stringstream ss;
ss << "if ( ! db.auth( \"" << username << "\" , \"" << password << "\" ) ){ throw 'login failed'; }";
@@ -423,6 +574,10 @@ int _main(int argc, char* argv[]) {
mongo::ScriptEngine::setup();
mongo::globalScriptEngine->setScopeInitCallback( mongo::shellUtils::initScope );
auto_ptr< mongo::Scope > scope( mongo::globalScriptEngine->newScope() );
+ shellMainScope = scope.get();
+
+ if( runShell )
+ cout << "type \"help\" for help" << endl;
if ( !script.empty() ) {
mongo::shellUtils::MongoProgramScope s;
@@ -452,8 +607,6 @@ int _main(int argc, char* argv[]) {
shellHistoryInit();
- cout << "type \"help\" for help" << endl;
-
//v8::Handle<v8::Object> shellHelper = baseContext_->Global()->Get( v8::String::New( "shellHelper" ) )->ToObject();
while ( 1 ){
@@ -510,8 +663,8 @@ int _main(int argc, char* argv[]) {
if ( ! wascmd ){
try {
- scope->exec( code.c_str() , "(shell)" , false , true , false );
- scope->exec( "shellPrintHelper( __lastres__ );" , "(shell2)" , true , true , false );
+ if ( scope->exec( code.c_str() , "(shell)" , false , true , false ) )
+ scope->exec( "shellPrintHelper( __lastres__ );" , "(shell2)" , true , true , false );
}
catch ( std::exception& e ){
cout << "error:" << e.what() << endl;
@@ -525,6 +678,7 @@ int _main(int argc, char* argv[]) {
shellHistoryDone();
}
+ mongo::goingAway = true;
return 0;
}
diff --git a/shell/mongo.js b/shell/mongo.js
index acd028b..7353ca5 100644
--- a/shell/mongo.js
+++ b/shell/mongo.js
@@ -56,8 +56,9 @@ Mongo.prototype.getCollection = function(ns){
}
Mongo.prototype.toString = function(){
- return "mongo connection to " + this.host;
+ return "connection to " + this.host;
}
+Mongo.prototype.tojson = Mongo.prototype.toString;
connect = function( url , user , pass ){
chatty( "connecting to: " + url )
@@ -65,7 +66,7 @@ connect = function( url , user , pass ){
if ( user && ! pass )
throw "you specified a user and not a password. either you need a password, or you're using the old connect api";
- var idx = url.indexOf( "/" );
+ var idx = url.lastIndexOf( "/" );
var db;
diff --git a/shell/mongo_vstudio.cpp b/shell/mongo_vstudio.cpp
index f88b3c2..06384ca 100644
--- a/shell/mongo_vstudio.cpp
+++ b/shell/mongo_vstudio.cpp
@@ -1,1529 +1,1766 @@
-const char * jsconcatcode =
-"__quiet = false;\n"
- "chatty = function(s){\n"
- "if ( ! __quiet )\n"
- "print( s );}\n"
- "friendlyEqual = function( a , b ){\n"
- "if ( a == b )\n"
- "return true;\n"
- "if ( tojson( a ) == tojson( b ) )\n"
- "return true;\n"
- "return false;}\n"
- "doassert = function( msg ){\n"
- "print( \"assert: \" + msg );\n"
- "throw msg;}\n"
- "assert = function( b , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "if ( b )\n"
- "return;\n"
- "doassert( \"assert failed : \" + msg );}\n"
- "assert._debug = false;\n"
- "assert.eq = function( a , b , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "if ( a == b )\n"
- "return;\n"
- "if ( ( a != null && b != null ) && friendlyEqual( a , b ) )\n"
- "return;\n"
- "doassert( \"[\" + tojson( a ) + \"] != [\" + tojson( b ) + \"] are not equal : \" + msg );}\n"
- "assert.neq = function( a , b , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "if ( a != b )\n"
- "return;\n"
- "doassert( \"[\" + a + \"] != [\" + b + \"] are equal : \" + msg );}\n"
- "assert.soon = function( f, msg, timeout, interval ) {\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "var start = new Date();\n"
- "timeout = timeout || 30000;\n"
- "interval = interval || 200;\n"
- "var last;\n"
- "while( 1 ) {\n"
- "if ( typeof( f ) == \"string\" ){\n"
- "if ( eval( f ) )\n"
- "return;}\n"
- "else {\n"
- "if ( f() )\n"
- "return;}\n"
- "if ( ( new Date() ).getTime() - start.getTime() > timeout )\n"
- "doassert( \"assert.soon failed: \" + f + \", msg:\" + msg );\n"
- "sleep( interval );}}\n"
- "assert.throws = function( func , params , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "try {\n"
- "func.apply( null , params );}\n"
- "catch ( e ){\n"
- "return e;}\n"
- "doassert( \"did not throw exception: \" + msg );}\n"
- "assert.commandWorked = function( res , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "if ( res.ok == 1 )\n"
- "return;\n"
- "doassert( \"command failed: \" + tojson( res ) + \" : \" + msg );}\n"
- "assert.commandFailed = function( res , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "if ( res.ok == 0 )\n"
- "return;\n"
- "doassert( \"command worked when it should have failed: \" + tojson( res ) + \" : \" + msg );}\n"
- "assert.isnull = function( what , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "if ( what == null )\n"
- "return;\n"
- "doassert( \"supposed to null (\" + ( msg || \"\" ) + \") was: \" + tojson( what ) );}\n"
- "assert.lt = function( a , b , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "if ( a < b )\n"
- "return;\n"
- "doassert( a + \" is not less than \" + b + \" : \" + msg );}\n"
- "assert.gt = function( a , b , msg ){\n"
- "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
- "if ( a > b )\n"
- "return;\n"
- "doassert( a + \" is not greater than \" + b + \" : \" + msg );}\n"
- "assert.close = function( a , b , msg ){\n"
- "var diff = Math.abs( (a-b)/((a+b)/2) );\n"
- "if ( diff < .001 )\n"
- "return;\n"
- "doassert( a + \" is not close to \" + b + \" diff: \" + diff + \" : \" + msg );}\n"
- "Object.extend = function( dst , src , deep ){\n"
- "for ( var k in src ){\n"
- "var v = src[k];\n"
- "if ( deep && typeof(v) == \"object\" ){\n"
- "v = Object.extend( typeof ( v.length ) == \"number\" ? [] : {} , v , true );}\n"
- "dst[k] = v;}\n"
- "return dst;}\n"
- "argumentsToArray = function( a ){\n"
- "var arr = [];\n"
- "for ( var i=0; i<a.length; i++ )\n"
- "arr[i] = a[i];\n"
- "return arr;}\n"
- "isString = function( x ){\n"
- "return typeof( x ) == \"string\";}\n"
- "isNumber = function(x){\n"
- "return typeof( x ) == \"number\";}\n"
- "isObject = function( x ){\n"
- "return typeof( x ) == \"object\";}\n"
- "String.prototype.trim = function() {\n"
- "return this.replace(/^\\s+|\\s+$/g,\"\");}\n"
- "String.prototype.ltrim = function() {\n"
- "return this.replace(/^\\s+/,\"\");}\n"
- "String.prototype.rtrim = function() {\n"
- "return this.replace(/\\s+$/,\"\");}\n"
- "Date.timeFunc = function( theFunc , numTimes ){\n"
- "var start = new Date();\n"
- "numTimes = numTimes || 1;\n"
- "for ( var i=0; i<numTimes; i++ ){\n"
- "theFunc.apply( null , argumentsToArray( arguments ).slice( 2 ) );}\n"
- "return (new Date()).getTime() - start.getTime();}\n"
- "Date.prototype.tojson = function(){\n"
- "return \"\\\"\" + this.toString() + \"\\\"\";}\n"
- "RegExp.prototype.tojson = RegExp.prototype.toString;\n"
- "Array.contains = function( a , x ){\n"
- "for ( var i=0; i<a.length; i++ ){\n"
- "if ( a[i] == x )\n"
- "return true;}\n"
- "return false;}\n"
- "Array.unique = function( a ){\n"
- "var u = [];\n"
- "for ( var i=0; i<a.length; i++){\n"
- "var o = a[i];\n"
- "if ( ! Array.contains( u , o ) ){\n"
- "u.push( o );}}\n"
- "return u;}\n"
- "Array.shuffle = function( arr ){\n"
- "for ( var i=0; i<arr.length-1; i++ ){\n"
- "var pos = i+Random.randInt(arr.length-i);\n"
- "var save = arr[i];\n"
- "arr[i] = arr[pos];\n"
- "arr[pos] = save;}\n"
- "return arr;}\n"
- "Array.tojson = function( a , indent ){\n"
- "if (!indent)\n"
- "indent = \"\";\n"
- "if (a.length == 0) {\n"
- "return \"[ ]\";}\n"
- "var s = \"[\\n\";\n"
- "indent += \"\\t\";\n"
- "for ( var i=0; i<a.length; i++){\n"
- "s += indent + tojson( a[i], indent );\n"
- "if ( i < a.length - 1 ){\n"
- "s += \",\\n\";}}\n"
- "if ( a.length == 0 ) {\n"
- "s += indent;}\n"
- "indent = indent.substring(1);\n"
- "s += \"\\n\"+indent+\"]\";\n"
- "return s;}\n"
- "Array.fetchRefs = function( arr , coll ){\n"
- "var n = [];\n"
- "for ( var i=0; i<arr.length; i ++){\n"
- "var z = arr[i];\n"
- "if ( coll && coll != z.getCollection() )\n"
- "continue;\n"
- "n.push( z.fetch() );}\n"
- "return n;}\n"
- "Array.sum = function( arr ){\n"
- "if ( arr.length == 0 )\n"
- "return null;\n"
- "var s = arr[0];\n"
- "for ( var i=1; i<arr.length; i++ )\n"
- "s += arr[i];\n"
- "return s;}\n"
- "Array.avg = function( arr ){\n"
- "if ( arr.length == 0 )\n"
- "return null;\n"
- "return Array.sum( arr ) / arr.length;}\n"
- "Array.stdDev = function( arr ){\n"
- "var avg = Array.avg( arr );\n"
- "var sum = 0;\n"
- "for ( var i=0; i<arr.length; i++ ){\n"
- "sum += Math.pow( arr[i] - avg , 2 );}\n"
- "return Math.sqrt( sum / arr.length );}\n"
- "Object.keySet = function( o ) {\n"
- "var ret = new Array();\n"
- "for( i in o ) {\n"
- "if ( !( i in o.__proto__ && o[ i ] === o.__proto__[ i ] ) ) {\n"
- "ret.push( i );}}\n"
- "return ret;}\n"
- "if ( ! ObjectId.prototype )\n"
- "ObjectId.prototype = {}\n"
- "ObjectId.prototype.toString = function(){\n"
- "return this.str;}\n"
- "ObjectId.prototype.tojson = function(){\n"
- "return \"ObjectId(\\\"\" + this.str + \"\\\")\";}\n"
- "ObjectId.prototype.isObjectId = true;\n"
- "if ( typeof( DBPointer ) != \"undefined\" ){\n"
- "DBPointer.prototype.fetch = function(){\n"
- "assert( this.ns , \"need a ns\" );\n"
- "assert( this.id , \"need an id\" );\n"
- "return db[ this.ns ].findOne( { _id : this.id } );}\n"
- "DBPointer.prototype.tojson = function(indent){\n"
- "return tojson({\"ns\" : this.ns, \"id\" : this.id}, indent);}\n"
- "DBPointer.prototype.getCollection = function(){\n"
- "return this.ns;}\n"
- "DBPointer.prototype.toString = function(){\n"
- "return \"DBPointer \" + this.ns + \":\" + this.id;}}\n"
- "else {\n"
- "print( \"warning: no DBPointer\" );}\n"
- "if ( typeof( DBRef ) != \"undefined\" ){\n"
- "DBRef.prototype.fetch = function(){\n"
- "assert( this.$ref , \"need a ns\" );\n"
- "assert( this.$id , \"need an id\" );\n"
- "return db[ this.$ref ].findOne( { _id : this.$id } );}\n"
- "DBRef.prototype.tojson = function(indent){\n"
- "return tojson({\"$ref\" : this.$ref, \"$id\" : this.$id}, indent);}\n"
- "DBRef.prototype.getCollection = function(){\n"
- "return this.$ref;}\n"
- "DBRef.prototype.toString = function(){\n"
- "return this.tojson();}}\n"
- "else {\n"
- "print( \"warning: no DBRef\" );}\n"
- "if ( typeof( BinData ) != \"undefined\" ){\n"
- "BinData.prototype.tojson = function(){\n"
- "return \"BinData type: \" + this.type + \" len: \" + this.len;}}\n"
- "else {\n"
- "print( \"warning: no BinData\" );}\n"
- "if ( typeof _threadInject != \"undefined\" ){\n"
- "print( \"fork() available!\" );\n"
- "Thread = function(){\n"
- "this.init.apply( this, arguments );}\n"
- "_threadInject( Thread.prototype );\n"
- "ScopedThread = function() {\n"
- "this.init.apply( this, arguments );}\n"
- "ScopedThread.prototype = new Thread( function() {} );\n"
- "_scopedThreadInject( ScopedThread.prototype );\n"
- "fork = function() {\n"
- "var t = new Thread( function() {} );\n"
- "Thread.apply( t, arguments );\n"
- "return t;}\n"
- "EventGenerator = function( me, collectionName, mean ) {\n"
- "this.mean = mean;\n"
- "this.events = new Array( me, collectionName );}\n"
- "EventGenerator.prototype._add = function( action ) {\n"
- "this.events.push( [ Random.genExp( this.mean ), action ] );}\n"
- "EventGenerator.prototype.addInsert = function( obj ) {\n"
- "this._add( \"t.insert( \" + tojson( obj ) + \" )\" );}\n"
- "EventGenerator.prototype.addRemove = function( obj ) {\n"
- "this._add( \"t.remove( \" + tojson( obj ) + \" )\" );}\n"
- "EventGenerator.prototype.addUpdate = function( objOld, objNew ) {\n"
- "this._add( \"t.update( \" + tojson( objOld ) + \", \" + tojson( objNew ) + \" )\" );}\n"
- "EventGenerator.prototype.addCheckCount = function( count, query, shouldPrint, checkQuery ) {\n"
- "query = query || {};\n"
- "shouldPrint = shouldPrint || false;\n"
- "checkQuery = checkQuery || false;\n"
- "var action = \"assert.eq( \" + count + \", t.count( \" + tojson( query ) + \" ) );\"\n"
- "if ( checkQuery ) {\n"
- "action += \" assert.eq( \" + count + \", t.find( \" + tojson( query ) + \" ).toArray().length );\"}\n"
- "if ( shouldPrint ) {\n"
- "action += \" print( me + ' ' + \" + count + \" );\";}\n"
- "this._add( action );}\n"
- "EventGenerator.prototype.getEvents = function() {\n"
- "return this.events;}\n"
- "EventGenerator.dispatch = function() {\n"
- "var args = argumentsToArray( arguments );\n"
- "var me = args.shift();\n"
- "var collectionName = args.shift();\n"
- "var m = new Mongo( db.getMongo().host );\n"
- "var t = m.getDB( \"test\" )[ collectionName ];\n"
- "for( var i in args ) {\n"
- "sleep( args[ i ][ 0 ] );\n"
- "eval( args[ i ][ 1 ] );}}\n"
- "ParallelTester = function() {\n"
- "this.params = new Array();}\n"
- "ParallelTester.prototype.add = function( fun, args ) {\n"
- "args = args || [];\n"
- "args.unshift( fun );\n"
- "this.params.push( args );}\n"
- "ParallelTester.prototype.run = function( msg, newScopes ) {\n"
- "newScopes = newScopes || false;\n"
- "assert.parallelTests( this.params, msg, newScopes );}\n"
- "ParallelTester.createJstestsLists = function( n ) {\n"
- "var params = new Array();\n"
- "for( var i = 0; i < n; ++i ) {\n"
- "params.push( [] );}\n"
- "var makeKeys = function( a ) {\n"
- "var ret = {};\n"
- "for( var i in a ) {\n"
- "ret[ a[ i ] ] = 1;}\n"
- "return ret;}\n"
- "var skipTests = makeKeys( [ \"jstests/dbadmin.js\",\n"
- "\"jstests/repair.js\",\n"
- "\"jstests/cursor8.js\",\n"
- "\"jstests/recstore.js\",\n"
- "\"jstests/extent.js\",\n"
- "\"jstests/indexb.js\",\n"
- "\"jstests/profile1.js\",\n"
- "\"jstests/mr3.js\",\n"
- "\"jstests/apitest_db.js\"] );\n"
- "var serialTestsArr = [ \"jstests/fsync.js\",\n"
- "\"jstests/fsync2.js\" ];\n"
- "var serialTests = makeKeys( serialTestsArr );\n"
- "params[ 0 ] = serialTestsArr;\n"
- "var files = listFiles(\"jstests\");\n"
- "files = Array.shuffle( files );\n"
- "var i = 0;\n"
- "files.forEach(\n"
- "function(x) {\n"
- "if ( /_runner/.test(x.name) ||\n"
- "/_lodeRunner/.test(x.name) ||\n"
- "( x.name in skipTests ) ||\n"
- "( x.name in serialTests ) ||\n"
- "! /\\.js$/.test(x.name ) ){\n"
- "print(\" >>>>>>>>>>>>>>> skipping \" + x.name);\n"
- "return;}\n"
- "params[ i % n ].push( x.name );\n"
- "++i;}\n"
- ");\n"
- "params[ 0 ] = Array.shuffle( params[ 0 ] );\n"
- "for( var i in params ) {\n"
- "params[ i ].unshift( i );}\n"
- "return params;}\n"
- "ParallelTester.fileTester = function() {\n"
- "var args = argumentsToArray( arguments );\n"
- "var suite = args.shift();\n"
- "args.forEach(\n"
- "function( x ) {\n"
- "print(\" S\" + suite + \" Test : \" + x + \" ...\");\n"
- "var time = Date.timeFunc( function() { load(x); }, 1);\n"
- "print(\" S\" + suite + \" Test : \" + x + \" \" + time + \"ms\" );}\n"
- ");}\n"
- "assert.parallelTests = function( params, msg, newScopes ) {\n"
- "newScopes = newScopes || false;\n"
- "var wrapper = function( fun, argv ) {\n"
- "eval (\n"
- "\"var z = function() {\" +\n"
- "\"var __parallelTests__fun = \" + fun.toString() + \";\" +\n"
- "\"var __parallelTests__argv = \" + tojson( argv ) + \";\" +\n"
- "\"var __parallelTests__passed = false;\" +\n"
- "\"try {\" +\n"
- "\"__parallelTests__fun.apply( 0, __parallelTests__argv );\" +\n"
- "\"__parallelTests__passed = true;\" +\n"
- "\"} catch ( e ) {\" +\n"
- "\"print( e );\" +\n"
- "\"}\" +\n"
- "\"return __parallelTests__passed;\" +\n"
- "\"}\"\n"
- ");\n"
- "return z;}\n"
- "var runners = new Array();\n"
- "for( var i in params ) {\n"
- "var param = params[ i ];\n"
- "var test = param.shift();\n"
- "var t;\n"
- "if ( newScopes )\n"
- "t = new ScopedThread( wrapper( test, param ) );\n"
- "else\n"
- "t = new Thread( wrapper( test, param ) );\n"
- "runners.push( t );}\n"
- "runners.forEach( function( x ) { x.start(); } );\n"
- "var nFailed = 0;\n"
- "runners.forEach( function( x ) { if( !x.returnData() ) { ++nFailed; } } );\n"
- "assert.eq( 0, nFailed, msg );}}\n"
- "tojson = function( x, indent , nolint ){\n"
- "if ( x === null )\n"
- "return \"null\";\n"
- "if ( x === undefined )\n"
- "return \"undefined\";\n"
- "if (!indent)\n"
- "indent = \"\";\n"
- "switch ( typeof x ){\n"
- "case \"string\": {\n"
- "var s = \"\\\"\";\n"
- "for ( var i=0; i<x.length; i++ ){\n"
- "if ( x[i] == '\"' ){\n"
- "s += \"\\\\\\\"\";}\n"
- "else\n"
- "s += x[i];}\n"
- "return s + \"\\\"\";}\n"
- "case \"number\":\n"
- "case \"boolean\":\n"
- "return \"\" + x;\n"
- "case \"object\":{\n"
- "var s = tojsonObject( x, indent , nolint );\n"
- "if ( ( nolint == null || nolint == true ) && s.length < 80 && ( indent == null || indent.length == 0 ) ){\n"
- "s = s.replace( /[\\s\\r\\n ]+/gm , \" \" );}\n"
- "return s;}\n"
- "case \"function\":\n"
- "return x.toString();\n"
- "default:\n"
- "throw \"tojson can't handle type \" + ( typeof x );}}\n"
- "tojsonObject = function( x, indent , nolint ){\n"
- "var lineEnding = nolint ? \" \" : \"\\n\";\n"
- "var tabSpace = nolint ? \"\" : \"\\t\";\n"
- "assert.eq( ( typeof x ) , \"object\" , \"tojsonObject needs object, not [\" + ( typeof x ) + \"]\" );\n"
- "if (!indent)\n"
- "indent = \"\";\n"
- "if ( typeof( x.tojson ) == \"function\" && x.tojson != tojson ) {\n"
- "return x.tojson(indent,nolint);}\n"
- "if ( typeof( x.constructor.tojson ) == \"function\" && x.constructor.tojson != tojson ) {\n"
- "return x.constructor.tojson( x, indent , nolint );}\n"
- "if ( x.toString() == \"[object MaxKey]\" )\n"
- "return \"{ $maxKey : 1 }\";\n"
- "if ( x.toString() == \"[object MinKey]\" )\n"
- "return \"{ $minKey : 1 }\";\n"
- "var s = \"{\" + lineEnding;\n"
- "indent += tabSpace;\n"
- "var total = 0;\n"
- "for ( var k in x ) total++;\n"
- "if ( total == 0 ) {\n"
- "s += indent + lineEnding;}\n"
- "var keys = x;\n"
- "if ( typeof( x._simpleKeys ) == \"function\" )\n"
- "keys = x._simpleKeys();\n"
- "var num = 1;\n"
- "for ( var k in keys ){\n"
- "var val = x[k];\n"
- "if ( val == DB.prototype || val == DBCollection.prototype )\n"
- "continue;\n"
- "s += indent + \"\\\"\" + k + \"\\\" : \" + tojson( val, indent , nolint );\n"
- "if (num != total) {\n"
- "s += \",\";\n"
- "num++;}\n"
- "s += lineEnding;}\n"
- "indent = indent.substring(1);\n"
- "return s + indent + \"}\";}\n"
- "shellPrint = function( x ){\n"
- "it = x;\n"
- "if ( x != undefined )\n"
- "shellPrintHelper( x );\n"
- "if ( db ){\n"
- "var e = db.getPrevError();\n"
- "if ( e.err ) {\n"
- "if( e.nPrev <= 1 )\n"
- "print( \"error on last call: \" + tojson( e.err ) );\n"
- "else\n"
- "print( \"an error \" + tojson(e.err) + \" occurred \" + e.nPrev + \" operations back in the command invocation\" );}\n"
- "db.resetError();}}\n"
- "printjson = function(x){\n"
- "print( tojson( x ) );}\n"
- "shellPrintHelper = function( x ){\n"
- "if ( typeof( x ) == \"undefined\" ){\n"
- "if ( typeof( db ) != \"undefined\" && db.getLastError ){\n"
- "var e = db.getLastError();\n"
- "if ( e != null )\n"
- "print( e );}\n"
- "return;}\n"
- "if ( x == null ){\n"
- "print( \"null\" );\n"
- "return;}\n"
- "if ( typeof x != \"object\" )\n"
- "return print( x );\n"
- "var p = x.shellPrint;\n"
- "if ( typeof p == \"function\" )\n"
- "return x.shellPrint();\n"
- "var p = x.tojson;\n"
- "if ( typeof p == \"function\" )\n"
- "print( x.tojson() );\n"
- "else\n"
- "print( tojson( x ) );}\n"
- "shellHelper = function( command , rest , shouldPrint ){\n"
- "command = command.trim();\n"
- "var args = rest.trim().replace(/;$/,\"\").split( \"\\s+\" );\n"
- "if ( ! shellHelper[command] )\n"
- "throw \"no command [\" + command + \"]\";\n"
- "var res = shellHelper[command].apply( null , args );\n"
- "if ( shouldPrint ){\n"
- "shellPrintHelper( res );}\n"
- "return res;}\n"
- "help = shellHelper.help = function(){\n"
- "print( \"HELP\" );\n"
- "print( \"\\t\" + \"show dbs show database names\");\n"
- "print( \"\\t\" + \"show collections show collections in current database\");\n"
- "print( \"\\t\" + \"show users show users in current database\");\n"
- "print( \"\\t\" + \"show profile show most recent system.profile entries with time >= 1ms\");\n"
- "print( \"\\t\" + \"use <db name> set curent database to <db name>\" );\n"
- "print( \"\\t\" + \"db.help() help on DB methods\");\n"
- "print( \"\\t\" + \"db.foo.help() help on collection methods\");\n"
- "print( \"\\t\" + \"db.foo.find() list objects in collection foo\" );\n"
- "print( \"\\t\" + \"db.foo.find( { a : 1 } ) list objects in foo where a == 1\" );\n"
- "print( \"\\t\" + \"it result of the last line evaluated; use to further iterate\");}\n"
- "shellHelper.use = function( dbname ){\n"
- "db = db.getMongo().getDB( dbname );\n"
- "print( \"switched to db \" + db.getName() );}\n"
- "shellHelper.it = function(){\n"
- "if ( typeof( ___it___ ) == \"undefined\" || ___it___ == null ){\n"
- "print( \"no cursor\" );\n"
- "return;}\n"
- "shellPrintHelper( ___it___ );}\n"
- "shellHelper.show = function( what ){\n"
- "assert( typeof what == \"string\" );\n"
- "if( what == \"profile\" ) {\n"
- "if( db.system.profile.count() == 0 ) {\n"
- "print(\"db.system.profile is empty\");\n"
- "print(\"Use db.setProfilingLevel(2) will enable profiling\");\n"
- "print(\"Use db.system.profile.find() to show raw profile entries\");}\n"
- "else {\n"
- "print();\n"
- "db.system.profile.find({ millis : { $gt : 0 } }).sort({$natural:-1}).limit(5).forEach( function(x){print(\"\"+x.millis+\"ms \" + String(x.ts).substring(0,24)); print(x.info); print(\"\\n\");} )}\n"
- "return \"\";}\n"
- "if ( what == \"users\" ){\n"
- "db.system.users.find().forEach( printjson );\n"
- "return \"\";}\n"
- "if ( what == \"collections\" || what == \"tables\" ) {\n"
- "db.getCollectionNames().forEach( function(x){print(x)} );\n"
- "return \"\";}\n"
- "if ( what == \"dbs\" ) {\n"
- "db.getMongo().getDBNames().sort().forEach( function(x){print(x)} );\n"
- "return \"\";}\n"
- "throw \"don't know how to show [\" + what + \"]\";}\n"
- "if ( typeof( Map ) == \"undefined\" ){\n"
- "Map = function(){\n"
- "this._data = {};}}\n"
- "Map.hash = function( val ){\n"
- "if ( ! val )\n"
- "return val;\n"
- "switch ( typeof( val ) ){\n"
- "case 'string':\n"
- "case 'number':\n"
- "case 'date':\n"
- "return val.toString();\n"
- "case 'object':\n"
- "case 'array':\n"
- "var s = \"\";\n"
- "for ( var k in val ){\n"
- "s += k + val[k];}\n"
- "return s;}\n"
- "throw \"can't hash : \" + typeof( val );}\n"
- "Map.prototype.put = function( key , value ){\n"
- "var o = this._get( key );\n"
- "var old = o.value;\n"
- "o.value = value;\n"
- "return old;}\n"
- "Map.prototype.get = function( key ){\n"
- "return this._get( key ).value;}\n"
- "Map.prototype._get = function( key ){\n"
- "var h = Map.hash( key );\n"
- "var a = this._data[h];\n"
- "if ( ! a ){\n"
- "a = [];\n"
- "this._data[h] = a;}\n"
- "for ( var i=0; i<a.length; i++ ){\n"
- "if ( friendlyEqual( key , a[i].key ) ){\n"
- "return a[i];}}\n"
- "var o = { key : key , value : null };\n"
- "a.push( o );\n"
- "return o;}\n"
- "Map.prototype.values = function(){\n"
- "var all = [];\n"
- "for ( var k in this._data ){\n"
- "this._data[k].forEach( function(z){ all.push( z.value ); } );}\n"
- "return all;}\n"
- "if ( typeof( gc ) == \"undefined\" ){\n"
- "gc = function(){}}\n"
- "Math.sigFig = function( x , N ){\n"
- "if ( ! N ){\n"
- "N = 3;}\n"
- "var p = Math.pow( 10, N - Math.ceil( Math.log( Math.abs(x) ) / Math.log( 10 )) );\n"
- "return Math.round(x*p)/p;}\n"
- "Random = function() {}\n"
- "Random.srand = function( s ) { _srand( s ); }\n"
- "Random.rand = function() { return _rand(); }\n"
- "Random.randInt = function( n ) { return Math.floor( Random.rand() * n ); }\n"
- "Random.setRandomSeed = function( s ) {\n"
- "s = s || new Date().getTime();\n"
- "print( \"setting random seed: \" + s );\n"
- "Random.srand( s );}\n"
- "Random.genExp = function( mean ) {\n"
- "return -Math.log( Random.rand() ) * mean;}\n"
- "killWithUris = function( uris ) {\n"
- "var inprog = db.currentOp().inprog;\n"
- "for( var u in uris ) {\n"
- "for ( var i in inprog ) {\n"
- "if ( uris[ u ] == inprog[ i ].client ) {\n"
- "db.killOp( inprog[ i ].opid );}}}}\n"
- "if ( typeof DB == \"undefined\" ){\n"
- "DB = function( mongo , name ){\n"
- "this._mongo = mongo;\n"
- "this._name = name;}}\n"
- "DB.prototype.getMongo = function(){\n"
- "assert( this._mongo , \"why no mongo!\" );\n"
- "return this._mongo;}\n"
- "DB.prototype.getSisterDB = function( name ){\n"
- "return this.getMongo().getDB( name );}\n"
- "DB.prototype.getName = function(){\n"
- "return this._name;}\n"
- "DB.prototype.stats = function(){\n"
- "return this.runCommand( { dbstats : 1 } );}\n"
- "DB.prototype.getCollection = function( name ){\n"
- "return new DBCollection( this._mongo , this , name , this._name + \".\" + name );}\n"
- "DB.prototype.commandHelp = function( name ){\n"
- "var c = {};\n"
- "c[name] = 1;\n"
- "c.help = true;\n"
- "return this.runCommand( c ).help;}\n"
- "DB.prototype.runCommand = function( obj ){\n"
- "if ( typeof( obj ) == \"string\" ){\n"
- "var n = {};\n"
- "n[obj] = 1;\n"
- "obj = n;}\n"
- "return this.getCollection( \"$cmd\" ).findOne( obj );}\n"
- "DB.prototype._dbCommand = DB.prototype.runCommand;\n"
- "DB.prototype._adminCommand = function( obj ){\n"
- "if ( this._name == \"admin\" )\n"
- "return this.runCommand( obj );\n"
- "return this.getSisterDB( \"admin\" ).runCommand( obj );}\n"
- "DB.prototype.addUser = function( username , pass, readOnly ){\n"
- "readOnly = readOnly || false;\n"
- "var c = this.getCollection( \"system.users\" );\n"
- "var u = c.findOne( { user : username } ) || { user : username };\n"
- "u.readOnly = readOnly;\n"
- "u.pwd = hex_md5( username + \":mongo:\" + pass );\n"
- "print( tojson( u ) );\n"
- "c.save( u );}\n"
- "DB.prototype.removeUser = function( username ){\n"
- "this.getCollection( \"system.users\" ).remove( { user : username } );}\n"
- "DB.prototype.__pwHash = function( nonce, username, pass ) {\n"
- "return hex_md5( nonce + username + hex_md5( username + \":mongo:\" + pass ) );}\n"
- "DB.prototype.auth = function( username , pass ){\n"
- "var n = this.runCommand( { getnonce : 1 } );\n"
- "var a = this.runCommand(\n"
- "{\n"
- "authenticate : 1 ,\n"
- "user : username ,\n"
- "nonce : n.nonce ,\n"
- "key : this.__pwHash( n.nonce, username, pass )}\n"
- ");\n"
- "return a.ok;}\n"
- "\n"
- "DB.prototype.createCollection = function(name, opt) {\n"
- "var options = opt || {};\n"
- "var cmd = { create: name, capped: options.capped, size: options.size, max: options.max };\n"
- "var res = this._dbCommand(cmd);\n"
- "return res;}\n"
- "\n"
- "DB.prototype.getProfilingLevel = function() {\n"
- "var res = this._dbCommand( { profile: -1 } );\n"
- "return res ? res.was : null;}\n"
- "\n"
- "DB.prototype.dropDatabase = function() {\n"
- "if ( arguments.length )\n"
- "throw \"dropDatabase doesn't take arguments\";\n"
- "return this._dbCommand( { dropDatabase: 1 } );}\n"
- "DB.prototype.shutdownServer = function() {\n"
- "if( \"admin\" != this._name ){\n"
- "return \"shutdown command only works with the admin database; try 'use admin'\";}\n"
- "try {\n"
- "var res = this._dbCommand(\"shutdown\");\n"
- "if( res )\n"
- "throw \"shutdownServer failed: \" + res.errmsg;\n"
- "throw \"shutdownServer failed\";}\n"
- "catch ( e ){\n"
- "assert( tojson( e ).indexOf( \"error doing query: failed\" ) >= 0 , \"unexpected error: \" + tojson( e ) );\n"
- "print( \"server should be down...\" );}}\n"
- "\n"
- "DB.prototype.cloneDatabase = function(from) {\n"
- "assert( isString(from) && from.length );\n"
- "return this._dbCommand( { clone: from } );}\n"
- "\n"
- "DB.prototype.cloneCollection = function(from, collection, query) {\n"
- "assert( isString(from) && from.length );\n"
- "assert( isString(collection) && collection.length );\n"
- "collection = this._name + \".\" + collection;\n"
- "query = query || {};\n"
- "return this._dbCommand( { cloneCollection:collection, from:from, query:query } );}\n"
- "\n"
- "DB.prototype.copyDatabase = function(fromdb, todb, fromhost, username, password) {\n"
- "assert( isString(fromdb) && fromdb.length );\n"
- "assert( isString(todb) && todb.length );\n"
- "fromhost = fromhost || \"\";\n"
- "if ( username && password ) {\n"
- "var n = this._adminCommand( { copydbgetnonce : 1, fromhost:fromhost } );\n"
- "return this._adminCommand( { copydb:1, fromhost:fromhost, fromdb:fromdb, todb:todb, username:username, nonce:n.nonce, key:this.__pwHash( n.nonce, username, password ) } );\n"
- "} else {\n"
- "return this._adminCommand( { copydb:1, fromhost:fromhost, fromdb:fromdb, todb:todb } );}}\n"
- "\n"
- "DB.prototype.repairDatabase = function() {\n"
- "return this._dbCommand( { repairDatabase: 1 } );}\n"
- "DB.prototype.help = function() {\n"
- "print(\"DB methods:\");\n"
- "print(\"\\tdb.addUser(username, password[, readOnly=false])\");\n"
- "print(\"\\tdb.auth(username, password)\");\n"
- "print(\"\\tdb.cloneDatabase(fromhost)\");\n"
- "print(\"\\tdb.commandHelp(name) returns the help for the command\");\n"
- "print(\"\\tdb.copyDatabase(fromdb, todb, fromhost)\");\n"
- "print(\"\\tdb.createCollection(name, { size : ..., capped : ..., max : ... } )\");\n"
- "print(\"\\tdb.currentOp() displays the current operation in the db\" );\n"
- "print(\"\\tdb.dropDatabase()\");\n"
- "print(\"\\tdb.eval(func, args) run code server-side\");\n"
- "print(\"\\tdb.getCollection(cname) same as db['cname'] or db.cname\");\n"
- "print(\"\\tdb.getCollectionNames()\");\n"
- "print(\"\\tdb.getLastError() - just returns the err msg string\");\n"
- "print(\"\\tdb.getLastErrorObj() - return full status object\");\n"
- "print(\"\\tdb.getMongo() get the server connection object\");\n"
- "print(\"\\tdb.getMongo().setSlaveOk() allow this connection to read from the nonmaster member of a replica pair\");\n"
- "print(\"\\tdb.getName()\");\n"
- "print(\"\\tdb.getPrevError()\");\n"
- "print(\"\\tdb.getProfilingLevel()\");\n"
- "print(\"\\tdb.getReplicationInfo()\");\n"
- "print(\"\\tdb.getSisterDB(name) get the db at the same server as this onew\");\n"
- "print(\"\\tdb.killOp(opid) kills the current operation in the db\" );\n"
- "print(\"\\tdb.printCollectionStats()\" );\n"
- "print(\"\\tdb.printReplicationInfo()\");\n"
- "print(\"\\tdb.printSlaveReplicationInfo()\");\n"
- "print(\"\\tdb.printShardingStatus()\");\n"
- "print(\"\\tdb.removeUser(username)\");\n"
- "print(\"\\tdb.repairDatabase()\");\n"
- "print(\"\\tdb.resetError()\");\n"
- "print(\"\\tdb.runCommand(cmdObj) run a database command. if cmdObj is a string, turns it into { cmdObj : 1 }\");\n"
- "print(\"\\tdb.setProfilingLevel(level,<slowms>) 0=off 1=slow 2=all\");\n"
- "print(\"\\tdb.shutdownServer()\");\n"
- "print(\"\\tdb.stats()\");\n"
- "print(\"\\tdb.version() current version of the server\" );}\n"
- "DB.prototype.printCollectionStats = function(){\n"
- "var mydb = this;\n"
- "this.getCollectionNames().forEach(\n"
- "function(z){\n"
- "print( z );\n"
- "printjson( mydb.getCollection(z).stats() );\n"
- "print( \"---\" );}\n"
- ");}\n"
- "\n"
- "DB.prototype.setProfilingLevel = function(level,slowms) {\n"
- "if (level < 0 || level > 2) {\n"
- "throw { dbSetProfilingException : \"input level \" + level + \" is out of range [0..2]\" };}\n"
- "var cmd = { profile: level };\n"
- "if ( slowms )\n"
- "cmd[\"slowms\"] = slowms;\n"
- "return this._dbCommand( cmd );}\n"
- "\n"
- "DB.prototype.eval = function(jsfunction) {\n"
- "var cmd = { $eval : jsfunction };\n"
- "if ( arguments.length > 1 ) {\n"
- "cmd.args = argumentsToArray( arguments ).slice(1);}\n"
- "var res = this._dbCommand( cmd );\n"
- "if (!res.ok)\n"
- "throw tojson( res );\n"
- "return res.retval;}\n"
- "DB.prototype.dbEval = DB.prototype.eval;\n"
- "\n"
- "DB.prototype.groupeval = function(parmsObj) {\n"
- "var groupFunction = function() {\n"
- "var parms = args[0];\n"
- "var c = db[parms.ns].find(parms.cond||{});\n"
- "var map = new Map();\n"
- "var pks = parms.key ? Object.keySet( parms.key ) : null;\n"
- "var pkl = pks ? pks.length : 0;\n"
- "var key = {};\n"
- "while( c.hasNext() ) {\n"
- "var obj = c.next();\n"
- "if ( pks ) {\n"
- "for( var i=0; i<pkl; i++ ){\n"
- "var k = pks[i];\n"
- "key[k] = obj[k];}}\n"
- "else {\n"
- "key = parms.$keyf(obj);}\n"
- "var aggObj = map.get(key);\n"
- "if( aggObj == null ) {\n"
- "var newObj = Object.extend({}, key);\n"
- "aggObj = Object.extend(newObj, parms.initial)\n"
- "map.put( key , aggObj );}\n"
- "parms.$reduce(obj, aggObj);}\n"
- "return map.values();}\n"
- "return this.eval(groupFunction, this._groupFixParms( parmsObj ));}\n"
- "DB.prototype.groupcmd = function( parmsObj ){\n"
- "var ret = this.runCommand( { \"group\" : this._groupFixParms( parmsObj ) } );\n"
- "if ( ! ret.ok ){\n"
- "throw \"group command failed: \" + tojson( ret );}\n"
- "return ret.retval;}\n"
- "DB.prototype.group = DB.prototype.groupcmd;\n"
- "DB.prototype._groupFixParms = function( parmsObj ){\n"
- "var parms = Object.extend({}, parmsObj);\n"
- "if( parms.reduce ) {\n"
- "parms.$reduce = parms.reduce;\n"
- "delete parms.reduce;}\n"
- "if( parms.keyf ) {\n"
- "parms.$keyf = parms.keyf;\n"
- "delete parms.keyf;}\n"
- "return parms;}\n"
- "DB.prototype.resetError = function(){\n"
- "return this.runCommand( { reseterror : 1 } );}\n"
- "DB.prototype.forceError = function(){\n"
- "return this.runCommand( { forceerror : 1 } );}\n"
- "DB.prototype.getLastError = function(){\n"
- "var res = this.runCommand( { getlasterror : 1 } );\n"
- "if ( ! res.ok )\n"
- "throw \"getlasterror failed: \" + tojson( res );\n"
- "return res.err;}\n"
- "DB.prototype.getLastErrorObj = function(){\n"
- "var res = this.runCommand( { getlasterror : 1 } );\n"
- "if ( ! res.ok )\n"
- "throw \"getlasterror failed: \" + tojson( res );\n"
- "return res;}\n"
- "DB.prototype.getLastErrorCmd = DB.prototype.getLastErrorObj;\n"
- "/* Return the last error which has occurred, even if not the very last error.\n"
- "Returns:\n"
- "{ err : <error message>, nPrev : <how_many_ops_back_occurred>, ok : 1 }\n"
- "result.err will be null if no error has occurred.\n"
- "*/\n"
- "DB.prototype.getPrevError = function(){\n"
- "return this.runCommand( { getpreverror : 1 } );}\n"
- "DB.prototype.getCollectionNames = function(){\n"
- "var all = [];\n"
- "var nsLength = this._name.length + 1;\n"
- "this.getCollection( \"system.namespaces\" ).find().sort({name:1}).forEach(\n"
- "function(z){\n"
- "var name = z.name;\n"
- "if ( name.indexOf( \"$\" ) >= 0 && name != \"local.oplog.$main\" )\n"
- "return;\n"
- "all.push( name.substring( nsLength ) );}\n"
- ");\n"
- "return all;}\n"
- "DB.prototype.tojson = function(){\n"
- "return this._name;}\n"
- "DB.prototype.toString = function(){\n"
- "return this._name;}\n"
- "DB.prototype.currentOp = function(){\n"
- "return db.$cmd.sys.inprog.findOne();}\n"
- "DB.prototype.currentOP = DB.prototype.currentOp;\n"
- "DB.prototype.killOp = function(op) {\n"
- "if( !op )\n"
- "throw \"no opNum to kill specified\";\n"
- "return db.$cmd.sys.killop.findOne({'op':op});}\n"
- "DB.prototype.killOP = DB.prototype.killOp;\n"
- "DB.tsToSeconds = function(x){\n"
- "if ( x.t && x.i )\n"
- "return x.t / 1000;\n"
- "return x / 4294967296;}\n"
- "\n"
- "DB.prototype.getReplicationInfo = function() {\n"
- "var db = this.getSisterDB(\"local\");\n"
- "var result = { };\n"
- "var ol = db.system.namespaces.findOne({name:\"local.oplog.$main\"});\n"
- "if( ol && ol.options ) {\n"
- "result.logSizeMB = ol.options.size / 1000 / 1000;\n"
- "} else {\n"
- "result.errmsg = \"local.oplog.$main, or its options, not found in system.namespaces collection (not --master?)\";\n"
- "return result;}\n"
- "var firstc = db.oplog.$main.find().sort({$natural:1}).limit(1);\n"
- "var lastc = db.oplog.$main.find().sort({$natural:-1}).limit(1);\n"
- "if( !firstc.hasNext() || !lastc.hasNext() ) {\n"
- "result.errmsg = \"objects not found in local.oplog.$main -- is this a new and empty db instance?\";\n"
- "result.oplogMainRowCount = db.oplog.$main.count();\n"
- "return result;}\n"
- "var first = firstc.next();\n"
- "var last = lastc.next();\n"
- "{\n"
- "var tfirst = first.ts;\n"
- "var tlast = last.ts;\n"
- "if( tfirst && tlast ) {\n"
- "tfirst = DB.tsToSeconds( tfirst );\n"
- "tlast = DB.tsToSeconds( tlast );\n"
- "result.timeDiff = tlast - tfirst;\n"
- "result.timeDiffHours = Math.round(result.timeDiff / 36)/100;\n"
- "result.tFirst = (new Date(tfirst*1000)).toString();\n"
- "result.tLast = (new Date(tlast*1000)).toString();\n"
- "result.now = Date();}\n"
- "else {\n"
- "result.errmsg = \"ts element not found in oplog objects\";}}\n"
- "return result;}\n"
- "DB.prototype.printReplicationInfo = function() {\n"
- "var result = this.getReplicationInfo();\n"
- "if( result.errmsg ) {\n"
- "print(tojson(result));\n"
- "return;}\n"
- "print(\"configured oplog size: \" + result.logSizeMB + \"MB\");\n"
- "print(\"log length start to end: \" + result.timeDiff + \"secs (\" + result.timeDiffHours + \"hrs)\");\n"
- "print(\"oplog first event time: \" + result.tFirst);\n"
- "print(\"oplog last event time: \" + result.tLast);\n"
- "print(\"now: \" + result.now);}\n"
- "DB.prototype.printSlaveReplicationInfo = function() {\n"
- "function g(x) {\n"
- "print(\"source: \" + x.host);\n"
- "var st = new Date( DB.tsToSeconds( x.syncedTo ) * 1000 );\n"
- "var now = new Date();\n"
- "print(\"syncedTo: \" + st.toString() );\n"
- "var ago = (now-st)/1000;\n"
- "var hrs = Math.round(ago/36)/100;\n"
- "print(\" = \" + Math.round(ago) + \"secs ago (\" + hrs + \"hrs)\");}\n"
- "var L = this.getSisterDB(\"local\");\n"
- "if( L.sources.count() == 0 ) {\n"
- "print(\"local.sources is empty; is this db a --slave?\");\n"
- "return;}\n"
- "L.sources.find().forEach(g);}\n"
- "DB.prototype.serverBuildInfo = function(){\n"
- "return this._adminCommand( \"buildinfo\" );}\n"
- "DB.prototype.serverStatus = function(){\n"
- "return this._adminCommand( \"serverStatus\" );}\n"
- "DB.prototype.version = function(){\n"
- "return this.serverBuildInfo().version;}\n"
- "DB.prototype.printShardingStatus = function(){\n"
- "printShardingStatus( this.getSisterDB( \"config\" ) );}\n"
- "if ( typeof Mongo == \"undefined\" ){\n"
- "Mongo = function( host ){\n"
- "this.init( host );}}\n"
- "if ( ! Mongo.prototype ){\n"
- "throw \"Mongo.prototype not defined\";}\n"
- "if ( ! Mongo.prototype.find )\n"
- "Mongo.prototype.find = function( ns , query , fields , limit , skip ){ throw \"find not implemented\"; }\n"
- "if ( ! Mongo.prototype.insert )\n"
- "Mongo.prototype.insert = function( ns , obj ){ throw \"insert not implemented\"; }\n"
- "if ( ! Mongo.prototype.remove )\n"
- "Mongo.prototype.remove = function( ns , pattern ){ throw \"remove not implemented;\" }\n"
- "if ( ! Mongo.prototype.update )\n"
- "Mongo.prototype.update = function( ns , query , obj , upsert ){ throw \"update not implemented;\" }\n"
- "if ( typeof mongoInject == \"function\" ){\n"
- "mongoInject( Mongo.prototype );}\n"
- "Mongo.prototype.setSlaveOk = function() {\n"
- "this.slaveOk = true;}\n"
- "Mongo.prototype.getDB = function( name ){\n"
- "return new DB( this , name );}\n"
- "Mongo.prototype.getDBs = function(){\n"
- "var res = this.getDB( \"admin\" ).runCommand( { \"listDatabases\" : 1 } );\n"
- "assert( res.ok == 1 , \"listDatabases failed:\" + tojson( res ) );\n"
- "return res;}\n"
- "Mongo.prototype.getDBNames = function(){\n"
- "return this.getDBs().databases.map(\n"
- "function(z){\n"
- "return z.name;}\n"
- ");}\n"
- "Mongo.prototype.getCollection = function(ns){\n"
- "var idx = ns.indexOf( \".\" );\n"
- "if ( idx < 0 )\n"
- "throw \"need . in ns\";\n"
- "var db = ns.substring( 0 , idx );\n"
- "var c = ns.substring( idx + 1 );\n"
- "return this.getDB( db ).getCollection( c );}\n"
- "Mongo.prototype.toString = function(){\n"
- "return \"mongo connection to \" + this.host;}\n"
- "connect = function( url , user , pass ){\n"
- "chatty( \"connecting to: \" + url )\n"
- "if ( user && ! pass )\n"
- "throw \"you specified a user and not a password. either you need a password, or you're using the old connect api\";\n"
- "var idx = url.indexOf( \"/\" );\n"
- "var db;\n"
- "if ( idx < 0 )\n"
- "db = new Mongo().getDB( url );\n"
- "else\n"
- "db = new Mongo( url.substring( 0 , idx ) ).getDB( url.substring( idx + 1 ) );\n"
- "if ( user && pass ){\n"
- "if ( ! db.auth( user , pass ) ){\n"
- "throw \"couldn't login\";}}\n"
- "return db;}\n"
- "MR = {};\n"
- "MR.init = function(){\n"
- "$max = 0;\n"
- "$arr = [];\n"
- "emit = MR.emit;\n"
- "$numEmits = 0;\n"
- "$numReduces = 0;\n"
- "$numReducesToDB = 0;\n"
- "gc();}\n"
- "MR.cleanup = function(){\n"
- "MR.init();\n"
- "gc();}\n"
- "MR.emit = function(k,v){\n"
- "$numEmits++;\n"
- "var num = nativeHelper.apply( get_num_ , [ k ] );\n"
- "var data = $arr[num];\n"
- "if ( ! data ){\n"
- "data = { key : k , values : new Array(1000) , count : 0 };\n"
- "$arr[num] = data;}\n"
- "data.values[data.count++] = v;\n"
- "$max = Math.max( $max , data.count );}\n"
- "MR.doReduce = function( useDB ){\n"
- "$numReduces++;\n"
- "if ( useDB )\n"
- "$numReducesToDB++;\n"
- "$max = 0;\n"
- "for ( var i=0; i<$arr.length; i++){\n"
- "var data = $arr[i];\n"
- "if ( ! data )\n"
- "continue;\n"
- "if ( useDB ){\n"
- "var x = tempcoll.findOne( { _id : data.key } );\n"
- "if ( x ){\n"
- "data.values[data.count++] = x.value;}}\n"
- "var r = $reduce( data.key , data.values.slice( 0 , data.count ) );\n"
- "if ( r && r.length && r[0] ){\n"
- "data.values = r;\n"
- "data.count = r.length;}\n"
- "else{\n"
- "data.values[0] = r;\n"
- "data.count = 1;}\n"
- "$max = Math.max( $max , data.count );\n"
- "if ( useDB ){\n"
- "if ( data.count == 1 ){\n"
- "tempcoll.save( { _id : data.key , value : data.values[0] } );}\n"
- "else {\n"
- "tempcoll.save( { _id : data.key , value : data.values.slice( 0 , data.count ) } );}}}}\n"
- "MR.check = function(){\n"
- "if ( $max < 2000 && $arr.length < 1000 ){\n"
- "return 0;}\n"
- "MR.doReduce();\n"
- "if ( $max < 2000 && $arr.length < 1000 ){\n"
- "return 1;}\n"
- "MR.doReduce( true );\n"
- "$arr = [];\n"
- "$max = 0;\n"
- "reset_num();\n"
- "gc();\n"
- "return 2;}\n"
- "MR.finalize = function(){\n"
- "tempcoll.find().forEach(\n"
- "function(z){\n"
- "z.value = $finalize( z._id , z.value );\n"
- "tempcoll.save( z );}\n"
- ");}\n"
- "if ( typeof DBQuery == \"undefined\" ){\n"
- "DBQuery = function( mongo , db , collection , ns , query , fields , limit , skip , batchSize ){\n"
- "this._mongo = mongo;\n"
- "this._db = db;\n"
- "this._collection = collection;\n"
- "this._ns = ns;\n"
- "this._query = query || {};\n"
- "this._fields = fields;\n"
- "this._limit = limit || 0;\n"
- "this._skip = skip || 0;\n"
- "this._batchSize = batchSize || 0;\n"
- "this._cursor = null;\n"
- "this._numReturned = 0;\n"
- "this._special = false;}\n"
- "print( \"DBQuery probably won't have array access \" );}\n"
- "DBQuery.prototype.help = function(){\n"
- "print( \"DBQuery help\" );\n"
- "print( \"\\t.sort( {...} )\" )\n"
- "print( \"\\t.limit( n )\" )\n"
- "print( \"\\t.skip( n )\" )\n"
- "print( \"\\t.count() - total # of objects matching query, ignores skip,limit\" )\n"
- "print( \"\\t.size() - total # of objects cursor would return skip,limit effect this\" )\n"
- "print( \"\\t.explain()\" )\n"
- "print( \"\\t.forEach( func )\" )\n"
- "print( \"\\t.map( func )\" )}\n"
- "DBQuery.prototype.clone = function(){\n"
- "var q = new DBQuery( this._mongo , this._db , this._collection , this._ns ,\n"
- "this._query , this._fields ,\n"
- "this._limit , this._skip , this._batchSize );\n"
- "q._special = this._special;\n"
- "return q;}\n"
- "DBQuery.prototype._ensureSpecial = function(){\n"
- "if ( this._special )\n"
- "return;\n"
- "var n = { query : this._query };\n"
- "this._query = n;\n"
- "this._special = true;}\n"
- "DBQuery.prototype._checkModify = function(){\n"
- "if ( this._cursor )\n"
- "throw \"query already executed\";}\n"
- "DBQuery.prototype._exec = function(){\n"
- "if ( ! this._cursor ){\n"
- "assert.eq( 0 , this._numReturned );\n"
- "this._cursor = this._mongo.find( this._ns , this._query , this._fields , this._limit , this._skip , this._batchSize );\n"
- "this._cursorSeen = 0;}\n"
- "return this._cursor;}\n"
- "DBQuery.prototype.limit = function( limit ){\n"
- "this._checkModify();\n"
- "this._limit = limit;\n"
- "return this;}\n"
- "DBQuery.prototype.batchSize = function( batchSize ){\n"
- "this._checkModify();\n"
- "this._batchSize = batchSize;\n"
- "return this;}\n"
- "DBQuery.prototype.skip = function( skip ){\n"
- "this._checkModify();\n"
- "this._skip = skip;\n"
- "return this;}\n"
- "DBQuery.prototype.hasNext = function(){\n"
- "this._exec();\n"
- "if ( this._limit > 0 && this._cursorSeen >= this._limit )\n"
- "return false;\n"
- "var o = this._cursor.hasNext();\n"
- "return o;}\n"
- "DBQuery.prototype.next = function(){\n"
- "this._exec();\n"
- "var o = this._cursor.hasNext();\n"
- "if ( o )\n"
- "this._cursorSeen++;\n"
- "else\n"
- "throw \"error hasNext: \" + o;\n"
- "var ret = this._cursor.next();\n"
- "if ( ret.$err && this._numReturned == 0 && ! this.hasNext() )\n"
- "throw \"error: \" + tojson( ret );\n"
- "this._numReturned++;\n"
- "return ret;}\n"
- "DBQuery.prototype.toArray = function(){\n"
- "if ( this._arr )\n"
- "return this._arr;\n"
- "var a = [];\n"
- "while ( this.hasNext() )\n"
- "a.push( this.next() );\n"
- "this._arr = a;\n"
- "return a;}\n"
- "DBQuery.prototype.count = function( applySkipLimit ){\n"
- "var cmd = { count: this._collection.getName() };\n"
- "if ( this._query ){\n"
- "if ( this._special )\n"
- "cmd.query = this._query.query;\n"
- "else\n"
- "cmd.query = this._query;}\n"
- "cmd.fields = this._fields || {};\n"
- "if ( applySkipLimit ){\n"
- "if ( this._limit )\n"
- "cmd.limit = this._limit;\n"
- "if ( this._skip )\n"
- "cmd.skip = this._skip;}\n"
- "var res = this._db.runCommand( cmd );\n"
- "if( res && res.n != null ) return res.n;\n"
- "throw \"count failed: \" + tojson( res );}\n"
- "DBQuery.prototype.size = function(){\n"
- "return this.count( true );}\n"
- "DBQuery.prototype.countReturn = function(){\n"
- "var c = this.count();\n"
- "if ( this._skip )\n"
- "c = c - this._skip;\n"
- "if ( this._limit > 0 && this._limit < c )\n"
- "return this._limit;\n"
- "return c;}\n"
- "\n"
- "DBQuery.prototype.itcount = function(){\n"
- "var num = 0;\n"
- "while ( this.hasNext() ){\n"
- "num++;\n"
- "this.next();}\n"
- "return num;}\n"
- "DBQuery.prototype.length = function(){\n"
- "return this.toArray().length;}\n"
- "DBQuery.prototype._addSpecial = function( name , value ){\n"
- "this._ensureSpecial();\n"
- "this._query[name] = value;\n"
- "return this;}\n"
- "DBQuery.prototype.sort = function( sortBy ){\n"
- "return this._addSpecial( \"orderby\" , sortBy );}\n"
- "DBQuery.prototype.hint = function( hint ){\n"
- "return this._addSpecial( \"$hint\" , hint );}\n"
- "DBQuery.prototype.min = function( min ) {\n"
- "return this._addSpecial( \"$min\" , min );}\n"
- "DBQuery.prototype.max = function( max ) {\n"
- "return this._addSpecial( \"$max\" , max );}\n"
- "DBQuery.prototype.forEach = function( func ){\n"
- "while ( this.hasNext() )\n"
- "func( this.next() );}\n"
- "DBQuery.prototype.map = function( func ){\n"
- "var a = [];\n"
- "while ( this.hasNext() )\n"
- "a.push( func( this.next() ) );\n"
- "return a;}\n"
- "DBQuery.prototype.arrayAccess = function( idx ){\n"
- "return this.toArray()[idx];}\n"
- "DBQuery.prototype.explain = function(){\n"
- "var n = this.clone();\n"
- "n._ensureSpecial();\n"
- "n._query.$explain = true;\n"
- "n._limit = n._limit * -1;\n"
- "return n.next();}\n"
- "DBQuery.prototype.snapshot = function(){\n"
- "this._ensureSpecial();\n"
- "this._query.$snapshot = true;\n"
- "return this;}\n"
- "DBQuery.prototype.shellPrint = function(){\n"
- "try {\n"
- "var n = 0;\n"
- "while ( this.hasNext() && n < 20 ){\n"
- "var s = tojson( this.next() , \"\" , true );\n"
- "print( s );\n"
- "n++;}\n"
- "if ( this.hasNext() ){\n"
- "print( \"has more\" );\n"
- "___it___ = this;}\n"
- "else {\n"
- "___it___ = null;}}\n"
- "catch ( e ){\n"
- "print( e );}}\n"
- "DBQuery.prototype.toString = function(){\n"
- "return \"DBQuery: \" + this._ns + \" -> \" + tojson( this.query );}\n"
- "if ( ( typeof DBCollection ) == \"undefined\" ){\n"
- "DBCollection = function( mongo , db , shortName , fullName ){\n"
- "this._mongo = mongo;\n"
- "this._db = db;\n"
- "this._shortName = shortName;\n"
- "this._fullName = fullName;\n"
- "this.verify();}}\n"
- "DBCollection.prototype.verify = function(){\n"
- "assert( this._fullName , \"no fullName\" );\n"
- "assert( this._shortName , \"no shortName\" );\n"
- "assert( this._db , \"no db\" );\n"
- "assert.eq( this._fullName , this._db._name + \".\" + this._shortName , \"name mismatch\" );\n"
- "assert( this._mongo , \"no mongo in DBCollection\" );}\n"
- "DBCollection.prototype.getName = function(){\n"
- "return this._shortName;}\n"
- "DBCollection.prototype.help = function() {\n"
- "print(\"DBCollection help\");\n"
- "print(\"\\tdb.foo.count()\");\n"
- "print(\"\\tdb.foo.dataSize()\");\n"
- "print(\"\\tdb.foo.distinct( key ) - eg. db.foo.distinct( 'x' )\");\n"
- "print(\"\\tdb.foo.drop() drop the collection\");\n"
- "print(\"\\tdb.foo.dropIndex(name)\");\n"
- "print(\"\\tdb.foo.dropIndexes()\");\n"
- "print(\"\\tdb.foo.ensureIndex(keypattern,options) - options should be an object with these possible fields: name, unique, dropDups\");\n"
- "print(\"\\tdb.foo.reIndex()\");\n"
- "print(\"\\tdb.foo.find( [query] , [fields]) - first parameter is an optional query filter. second parameter is optional set of fields to return.\");\n"
- "print(\"\\t e.g. db.foo.find( { x : 77 } , { name : 1 , x : 1 } )\");\n"
- "print(\"\\tdb.foo.find(...).count()\");\n"
- "print(\"\\tdb.foo.find(...).limit(n)\");\n"
- "print(\"\\tdb.foo.find(...).skip(n)\");\n"
- "print(\"\\tdb.foo.find(...).sort(...)\");\n"
- "print(\"\\tdb.foo.findOne([query])\");\n"
- "print(\"\\tdb.foo.findAndModify( { update : ... , remove : bool [, query: {}, sort: {}, 'new': false] } )\");\n"
- "print(\"\\tdb.foo.getDB() get DB object associated with collection\");\n"
- "print(\"\\tdb.foo.getIndexes()\");\n"
- "print(\"\\tdb.foo.group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )\");\n"
- "print(\"\\tdb.foo.mapReduce( mapFunction , reduceFunction , <optional params> )\");\n"
- "print(\"\\tdb.foo.remove(query)\");\n"
- "print(\"\\tdb.foo.renameCollection( newName , <dropTarget> ) renames the collection.\");\n"
- "print(\"\\tdb.foo.runCommand( name , <options> ) runs a db command with the given name where the 1st param is the colleciton name\" );\n"
- "print(\"\\tdb.foo.save(obj)\");\n"
- "print(\"\\tdb.foo.stats()\");\n"
- "print(\"\\tdb.foo.storageSize() - includes free space allocated to this collection\");\n"
- "print(\"\\tdb.foo.totalIndexSize() - size in bytes of all the indexes\");\n"
- "print(\"\\tdb.foo.totalSize() - storage allocated for all data and indexes\");\n"
- "print(\"\\tdb.foo.update(query, object[, upsert_bool, multi_bool])\");\n"
- "print(\"\\tdb.foo.validate() - SLOW\");\n"
- "print(\"\\tdb.foo.getShardVersion() - only for use with sharding\");}\n"
- "DBCollection.prototype.getFullName = function(){\n"
- "return this._fullName;}\n"
- "DBCollection.prototype.getDB = function(){\n"
- "return this._db;}\n"
- "DBCollection.prototype._dbCommand = function( cmd , params ){\n"
- "if ( typeof( cmd ) == \"object\" )\n"
- "return this._db._dbCommand( cmd );\n"
- "var c = {};\n"
- "c[cmd] = this.getName();\n"
- "if ( params )\n"
- "Object.extend( c , params );\n"
- "return this._db._dbCommand( c );}\n"
- "DBCollection.prototype.runCommand = DBCollection.prototype._dbCommand;\n"
- "DBCollection.prototype._massageObject = function( q ){\n"
- "if ( ! q )\n"
- "return {};\n"
- "var type = typeof q;\n"
- "if ( type == \"function\" )\n"
- "return { $where : q };\n"
- "if ( q.isObjectId )\n"
- "return { _id : q };\n"
- "if ( type == \"object\" )\n"
- "return q;\n"
- "if ( type == \"string\" ){\n"
- "if ( q.length == 24 )\n"
- "return { _id : q };\n"
- "return { $where : q };}\n"
- "throw \"don't know how to massage : \" + type;}\n"
- "DBCollection.prototype._validateObject = function( o ){\n"
- "if ( o._ensureSpecial && o._checkModify )\n"
- "throw \"can't save a DBQuery object\";}\n"
- "DBCollection._allowedFields = { $id : 1 , $ref : 1 };\n"
- "DBCollection.prototype._validateForStorage = function( o ){\n"
- "this._validateObject( o );\n"
- "for ( var k in o ){\n"
- "if ( k.indexOf( \".\" ) >= 0 ) {\n"
- "throw \"can't have . in field names [\" + k + \"]\" ;}\n"
- "if ( k.indexOf( \"$\" ) == 0 && ! DBCollection._allowedFields[k] ) {\n"
- "throw \"field names cannot start with $ [\" + k + \"]\";}\n"
- "if ( o[k] !== null && typeof( o[k] ) === \"object\" ) {\n"
- "this._validateForStorage( o[k] );}}\n"
- "};\n"
- "DBCollection.prototype.find = function( query , fields , limit , skip ){\n"
- "return new DBQuery( this._mongo , this._db , this ,\n"
- "this._fullName , this._massageObject( query ) , fields , limit , skip );}\n"
- "DBCollection.prototype.findOne = function( query , fields ){\n"
- "var cursor = this._mongo.find( this._fullName , this._massageObject( query ) || {} , fields , -1 , 0 , 0 );\n"
- "if ( ! cursor.hasNext() )\n"
- "return null;\n"
- "var ret = cursor.next();\n"
- "if ( cursor.hasNext() ) throw \"findOne has more than 1 result!\";\n"
- "if ( ret.$err )\n"
- "throw \"error \" + tojson( ret );\n"
- "return ret;}\n"
- "DBCollection.prototype.insert = function( obj , _allow_dot ){\n"
- "if ( ! obj )\n"
- "throw \"no object passed to insert!\";\n"
- "if ( ! _allow_dot ) {\n"
- "this._validateForStorage( obj );}\n"
- "if ( typeof( obj._id ) == \"undefined\" ){\n"
- "var tmp = obj;\n"
- "obj = {_id: new ObjectId()};\n"
- "for (var key in tmp){\n"
- "obj[key] = tmp[key];}}\n"
- "this._mongo.insert( this._fullName , obj );\n"
- "return obj._id;}\n"
- "DBCollection.prototype.remove = function( t ){\n"
- "this._mongo.remove( this._fullName , this._massageObject( t ) );}\n"
- "DBCollection.prototype.update = function( query , obj , upsert , multi ){\n"
- "assert( query , \"need a query\" );\n"
- "assert( obj , \"need an object\" );\n"
- "this._validateObject( obj );\n"
- "this._mongo.update( this._fullName , query , obj , upsert ? true : false , multi ? true : false );}\n"
- "DBCollection.prototype.save = function( obj ){\n"
- "if ( obj == null || typeof( obj ) == \"undefined\" )\n"
- "throw \"can't save a null\";\n"
- "if ( typeof( obj._id ) == \"undefined\" ){\n"
- "obj._id = new ObjectId();\n"
- "return this.insert( obj );}\n"
- "else {\n"
- "return this.update( { _id : obj._id } , obj , true );}}\n"
- "DBCollection.prototype._genIndexName = function( keys ){\n"
- "var name = \"\";\n"
- "for ( var k in keys ){\n"
- "var v = keys[k];\n"
- "if ( typeof v == \"function\" )\n"
- "continue;\n"
- "if ( name.length > 0 )\n"
- "name += \"_\";\n"
- "name += k + \"_\";\n"
- "if ( typeof v == \"number\" )\n"
- "name += v;}\n"
- "return name;}\n"
- "DBCollection.prototype._indexSpec = function( keys, options ) {\n"
- "var ret = { ns : this._fullName , key : keys , name : this._genIndexName( keys ) };\n"
- "if ( ! options ){}\n"
- "else if ( typeof ( options ) == \"string\" )\n"
- "ret.name = options;\n"
- "else if ( typeof ( options ) == \"boolean\" )\n"
- "ret.unique = true;\n"
- "else if ( typeof ( options ) == \"object\" ){\n"
- "if ( options.length ){\n"
- "var nb = 0;\n"
- "for ( var i=0; i<options.length; i++ ){\n"
- "if ( typeof ( options[i] ) == \"string\" )\n"
- "ret.name = options[i];\n"
- "else if ( typeof( options[i] ) == \"boolean\" ){\n"
- "if ( options[i] ){\n"
- "if ( nb == 0 )\n"
- "ret.unique = true;\n"
- "if ( nb == 1 )\n"
- "ret.dropDups = true;}\n"
- "nb++;}}}\n"
- "else {\n"
- "Object.extend( ret , options );}}\n"
- "else {\n"
- "throw \"can't handle: \" + typeof( options );}\n"
- "/*\n"
- "return ret;\n"
- "var name;\n"
- "var nTrue = 0;\n"
- "if ( ! isObject( options ) ) {\n"
- "options = [ options ];}\n"
- "if ( options.length ){\n"
- "for( var i = 0; i < options.length; ++i ) {\n"
- "var o = options[ i ];\n"
- "if ( isString( o ) ) {\n"
- "ret.name = o;\n"
- "} else if ( typeof( o ) == \"boolean\" ) {\n"
- "if ( o ) {\n"
- "++nTrue;}}}\n"
- "if ( nTrue > 0 ) {\n"
- "ret.unique = true;}\n"
- "if ( nTrue > 1 ) {\n"
- "ret.dropDups = true;}}\n"
- "*/\n"
- "return ret;}\n"
- "DBCollection.prototype.createIndex = function( keys , options ){\n"
- "var o = this._indexSpec( keys, options );\n"
- "this._db.getCollection( \"system.indexes\" ).insert( o , true );}\n"
- "DBCollection.prototype.ensureIndex = function( keys , options ){\n"
- "var name = this._indexSpec( keys, options ).name;\n"
- "this._indexCache = this._indexCache || {};\n"
- "if ( this._indexCache[ name ] ){\n"
- "return;}\n"
- "this.createIndex( keys , options );\n"
- "if ( this.getDB().getLastError() == \"\" ) {\n"
- "this._indexCache[name] = true;}}\n"
- "DBCollection.prototype.resetIndexCache = function(){\n"
- "this._indexCache = {};}\n"
- "DBCollection.prototype.reIndex = function() {\n"
- "return this._db.runCommand({ reIndex: this.getName() });}\n"
- "DBCollection.prototype.dropIndexes = function(){\n"
- "this.resetIndexCache();\n"
- "var res = this._db.runCommand( { deleteIndexes: this.getName(), index: \"*\" } );\n"
- "assert( res , \"no result from dropIndex result\" );\n"
- "if ( res.ok )\n"
- "return res;\n"
- "if ( res.errmsg.match( /not found/ ) )\n"
- "return res;\n"
- "throw \"error dropping indexes : \" + tojson( res );}\n"
- "DBCollection.prototype.drop = function(){\n"
- "this.resetIndexCache();\n"
- "var ret = this._db.runCommand( { drop: this.getName() } );\n"
- "if ( ! ret.ok ){\n"
- "if ( ret.errmsg == \"ns not found\" )\n"
- "return false;\n"
- "throw \"drop failed: \" + tojson( ret );}\n"
- "return true;}\n"
- "DBCollection.prototype.findAndModify = function(args){\n"
- "var cmd = { findandmodify: this.getName() };\n"
- "for (var key in args){\n"
- "cmd[key] = args[key];}\n"
- "var ret = this._db.runCommand( cmd );\n"
- "if ( ! ret.ok ){\n"
- "if (ret.errmsg == \"No matching object found\"){\n"
- "return {};}\n"
- "throw \"findAndModifyFailed failed: \" + tojson( ret.errmsg );}\n"
- "return ret.value;}\n"
- "DBCollection.prototype.renameCollection = function( newName , dropTarget ){\n"
- "return this._db._adminCommand( { renameCollection : this._fullName ,\n"
- "to : this._db._name + \".\" + newName ,\n"
- "dropTarget : dropTarget } )}\n"
- "DBCollection.prototype.validate = function() {\n"
- "var res = this._db.runCommand( { validate: this.getName() } );\n"
- "res.valid = false;\n"
- "if ( res.result ){\n"
- "var str = \"-\" + tojson( res.result );\n"
- "res.valid = ! ( str.match( /exception/ ) || str.match( /corrupt/ ) );\n"
- "var p = /lastExtentSize:(\\d+)/;\n"
- "var r = p.exec( str );\n"
- "if ( r ){\n"
- "res.lastExtentSize = Number( r[1] );}}\n"
- "return res;}\n"
- "DBCollection.prototype.getShardVersion = function(){\n"
- "return this._db._adminCommand( { getShardVersion : this._fullName } );}\n"
- "DBCollection.prototype.getIndexes = function(){\n"
- "return this.getDB().getCollection( \"system.indexes\" ).find( { ns : this.getFullName() } ).toArray();}\n"
- "DBCollection.prototype.getIndices = DBCollection.prototype.getIndexes;\n"
- "DBCollection.prototype.getIndexSpecs = DBCollection.prototype.getIndexes;\n"
- "DBCollection.prototype.getIndexKeys = function(){\n"
- "return this.getIndexes().map(\n"
- "function(i){\n"
- "return i.key;}\n"
- ");}\n"
- "DBCollection.prototype.count = function( x ){\n"
- "return this.find( x ).count();}\n"
- "\n"
- "DBCollection.prototype.clean = function() {\n"
- "return this._dbCommand( { clean: this.getName() } );}\n"
- "\n"
- "DBCollection.prototype.dropIndex = function(index) {\n"
- "assert(index , \"need to specify index to dropIndex\" );\n"
- "if ( ! isString( index ) && isObject( index ) )\n"
- "index = this._genIndexName( index );\n"
- "var res = this._dbCommand( \"deleteIndexes\" ,{ index: index } );\n"
- "this.resetIndexCache();\n"
- "return res;}\n"
- "DBCollection.prototype.copyTo = function( newName ){\n"
- "return this.getDB().eval(\n"
- "function( collName , newName ){\n"
- "var from = db[collName];\n"
- "var to = db[newName];\n"
- "to.ensureIndex( { _id : 1 } );\n"
- "var count = 0;\n"
- "var cursor = from.find();\n"
- "while ( cursor.hasNext() ){\n"
- "var o = cursor.next();\n"
- "count++;\n"
- "to.save( o );}\n"
- "return count;\n"
- "} , this.getName() , newName\n"
- ");}\n"
- "DBCollection.prototype.getCollection = function( subName ){\n"
- "return this._db.getCollection( this._shortName + \".\" + subName );}\n"
- "DBCollection.prototype.stats = function( scale ){\n"
- "return this._db.runCommand( { collstats : this._shortName , scale : scale } );}\n"
- "DBCollection.prototype.dataSize = function(){\n"
- "return this.stats().size;}\n"
- "DBCollection.prototype.storageSize = function(){\n"
- "return this.stats().storageSize;}\n"
- "DBCollection.prototype.totalIndexSize = function( verbose ){\n"
- "var stats = this.stats();\n"
- "if (verbose){\n"
- "for (var ns in stats.indexSizes){\n"
- "print( ns + \"\\t\" + stats.indexSizes[ns] );}}\n"
- "return stats.totalIndexSize;}\n"
- "DBCollection.prototype.totalSize = function(){\n"
- "var total = this.storageSize();\n"
- "var mydb = this._db;\n"
- "var shortName = this._shortName;\n"
- "this.getIndexes().forEach(\n"
- "function( spec ){\n"
- "var coll = mydb.getCollection( shortName + \".$\" + spec.name );\n"
- "var mysize = coll.storageSize();\n"
- "total += coll.dataSize();}\n"
- ");\n"
- "return total;}\n"
- "DBCollection.prototype.convertToCapped = function( bytes ){\n"
- "if ( ! bytes )\n"
- "throw \"have to specify # of bytes\";\n"
- "return this._dbCommand( { convertToCapped : this._shortName , size : bytes } )}\n"
- "DBCollection.prototype.exists = function(){\n"
- "return this._db.system.namespaces.findOne( { name : this._fullName } );}\n"
- "DBCollection.prototype.isCapped = function(){\n"
- "var e = this.exists();\n"
- "return ( e && e.options && e.options.capped ) ? true : false;}\n"
- "DBCollection.prototype.distinct = function( keyString , query ){\n"
- "var res = this._dbCommand( { distinct : this._shortName , key : keyString , query : query || {} } );\n"
- "if ( ! res.ok )\n"
- "throw \"distinct failed: \" + tojson( res );\n"
- "return res.values;}\n"
- "DBCollection.prototype.group = function( params ){\n"
- "params.ns = this._shortName;\n"
- "return this._db.group( params );}\n"
- "DBCollection.prototype.groupcmd = function( params ){\n"
- "params.ns = this._shortName;\n"
- "return this._db.groupcmd( params );}\n"
- "MapReduceResult = function( db , o ){\n"
- "Object.extend( this , o );\n"
- "this._o = o;\n"
- "this._keys = Object.keySet( o );\n"
- "this._db = db;\n"
- "this._coll = this._db.getCollection( this.result );}\n"
- "MapReduceResult.prototype._simpleKeys = function(){\n"
- "return this._o;}\n"
- "MapReduceResult.prototype.find = function(){\n"
- "return DBCollection.prototype.find.apply( this._coll , arguments );}\n"
- "MapReduceResult.prototype.drop = function(){\n"
- "return this._coll.drop();}\n"
- "\n"
- "MapReduceResult.prototype.convertToSingleObject = function(){\n"
- "var z = {};\n"
- "this._coll.find().forEach( function(a){ z[a._id] = a.value; } );\n"
- "return z;}\n"
- "\n"
- "DBCollection.prototype.mapReduce = function( map , reduce , optional ){\n"
- "var c = { mapreduce : this._shortName , map : map , reduce : reduce };\n"
- "if ( optional )\n"
- "Object.extend( c , optional );\n"
- "var raw = this._db.runCommand( c );\n"
- "if ( ! raw.ok )\n"
- "throw \"map reduce failed: \" + tojson( raw );\n"
- "return new MapReduceResult( this._db , raw );}\n"
- "DBCollection.prototype.toString = function(){\n"
- "return this.getFullName();}\n"
- "DBCollection.prototype.toString = function(){\n"
- "return this.getFullName();}\n"
- "DBCollection.prototype.tojson = DBCollection.prototype.toString;\n"
- "DBCollection.prototype.shellPrint = DBCollection.prototype.toString;\n"
- ;
-
+const char * jsconcatcode =
+"__quiet = false;\n"
+ "__magicNoPrint = { __magicNoPrint : 1111 }\n"
+ "chatty = function(s){\n"
+ "if ( ! __quiet )\n"
+ "print( s );}\n"
+ "friendlyEqual = function( a , b ){\n"
+ "if ( a == b )\n"
+ "return true;\n"
+ "if ( tojson( a ) == tojson( b ) )\n"
+ "return true;\n"
+ "return false;}\n"
+ "doassert = function (msg) {\n"
+ "if (msg.indexOf(\"assert\") == 0)\n"
+ "print(msg);\n"
+ "else\n"
+ "print(\"assert: \" + msg);\n"
+ "throw msg;}\n"
+ "assert = function( b , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( b )\n"
+ "return;\n"
+ "doassert( msg == undefined ? \"assert failed\" : \"assert failed : \" + msg );}\n"
+ "assert.automsg = function( b ) {\n"
+ "assert( eval( b ), b );}\n"
+ "assert._debug = false;\n"
+ "assert.eq = function( a , b , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( a == b )\n"
+ "return;\n"
+ "if ( ( a != null && b != null ) && friendlyEqual( a , b ) )\n"
+ "return;\n"
+ "doassert( \"[\" + tojson( a ) + \"] != [\" + tojson( b ) + \"] are not equal : \" + msg );}\n"
+ "assert.eq.automsg = function( a, b ) {\n"
+ "assert.eq( eval( a ), eval( b ), \"[\" + a + \"] != [\" + b + \"]\" );}\n"
+ "assert.neq = function( a , b , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( a != b )\n"
+ "return;\n"
+ "doassert( \"[\" + a + \"] != [\" + b + \"] are equal : \" + msg );}\n"
+ "assert.repeat = function( f, msg, timeout, interval ) {\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "var start = new Date();\n"
+ "timeout = timeout || 30000;\n"
+ "interval = interval || 200;\n"
+ "var last;\n"
+ "while( 1 ) {\n"
+ "if ( typeof( f ) == \"string\" ){\n"
+ "if ( eval( f ) )\n"
+ "return;}\n"
+ "else {\n"
+ "if ( f() )\n"
+ "return;}\n"
+ "if ( ( new Date() ).getTime() - start.getTime() > timeout )\n"
+ "break;\n"
+ "sleep( interval );}}\n"
+ "assert.soon = function( f, msg, timeout, interval ) {\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "var start = new Date();\n"
+ "timeout = timeout || 30000;\n"
+ "interval = interval || 200;\n"
+ "var last;\n"
+ "while( 1 ) {\n"
+ "if ( typeof( f ) == \"string\" ){\n"
+ "if ( eval( f ) )\n"
+ "return;}\n"
+ "else {\n"
+ "if ( f() )\n"
+ "return;}\n"
+ "if ( ( new Date() ).getTime() - start.getTime() > timeout )\n"
+ "doassert( \"assert.soon failed: \" + f + \", msg:\" + msg );\n"
+ "sleep( interval );}}\n"
+ "assert.throws = function( func , params , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "try {\n"
+ "func.apply( null , params );}\n"
+ "catch ( e ){\n"
+ "return e;}\n"
+ "doassert( \"did not throw exception: \" + msg );}\n"
+ "assert.throws.automsg = function( func, params ) {\n"
+ "assert.throws( func, params, func.toString() );}\n"
+ "assert.commandWorked = function( res , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( res.ok == 1 )\n"
+ "return;\n"
+ "doassert( \"command failed: \" + tojson( res ) + \" : \" + msg );}\n"
+ "assert.commandFailed = function( res , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( res.ok == 0 )\n"
+ "return;\n"
+ "doassert( \"command worked when it should have failed: \" + tojson( res ) + \" : \" + msg );}\n"
+ "assert.isnull = function( what , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( what == null )\n"
+ "return;\n"
+ "doassert( \"supposed to null (\" + ( msg || \"\" ) + \") was: \" + tojson( what ) );}\n"
+ "assert.lt = function( a , b , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( a < b )\n"
+ "return;\n"
+ "doassert( a + \" is not less than \" + b + \" : \" + msg );}\n"
+ "assert.gt = function( a , b , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( a > b )\n"
+ "return;\n"
+ "doassert( a + \" is not greater than \" + b + \" : \" + msg );}\n"
+ "assert.lte = function( a , b , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( a <= b )\n"
+ "return;\n"
+ "doassert( a + \" is not less than or eq \" + b + \" : \" + msg );}\n"
+ "assert.gte = function( a , b , msg ){\n"
+ "if ( assert._debug && msg ) print( \"in assert for: \" + msg );\n"
+ "if ( a >= b )\n"
+ "return;\n"
+ "doassert( a + \" is not greater than or eq \" + b + \" : \" + msg );}\n"
+ "assert.close = function( a , b , msg , places ){\n"
+ "if (places === undefined) {\n"
+ "places = 4;}\n"
+ "if (Math.round((a - b) * Math.pow(10, places)) === 0) {\n"
+ "return;}\n"
+ "doassert( a + \" is not equal to \" + b + \" within \" + places +\n"
+ "\" places, diff: \" + (a-b) + \" : \" + msg );\n"
+ "};\n"
+ "Object.extend = function( dst , src , deep ){\n"
+ "for ( var k in src ){\n"
+ "var v = src[k];\n"
+ "if ( deep && typeof(v) == \"object\" ){\n"
+ "v = Object.extend( typeof ( v.length ) == \"number\" ? [] : {} , v , true );}\n"
+ "dst[k] = v;}\n"
+ "return dst;}\n"
+ "argumentsToArray = function( a ){\n"
+ "var arr = [];\n"
+ "for ( var i=0; i<a.length; i++ )\n"
+ "arr[i] = a[i];\n"
+ "return arr;}\n"
+ "isString = function( x ){\n"
+ "return typeof( x ) == \"string\";}\n"
+ "isNumber = function(x){\n"
+ "return typeof( x ) == \"number\";}\n"
+ "isObject = function( x ){\n"
+ "return typeof( x ) == \"object\";}\n"
+ "String.prototype.trim = function() {\n"
+ "return this.replace(/^\\s+|\\s+$/g,\"\");}\n"
+ "String.prototype.ltrim = function() {\n"
+ "return this.replace(/^\\s+/,\"\");}\n"
+ "String.prototype.rtrim = function() {\n"
+ "return this.replace(/\\s+$/,\"\");}\n"
+ "Date.timeFunc = function( theFunc , numTimes ){\n"
+ "var start = new Date();\n"
+ "numTimes = numTimes || 1;\n"
+ "for ( var i=0; i<numTimes; i++ ){\n"
+ "theFunc.apply( null , argumentsToArray( arguments ).slice( 2 ) );}\n"
+ "return (new Date()).getTime() - start.getTime();}\n"
+ "Date.prototype.tojson = function(){\n"
+ "return \"\\\"\" + this.toString() + \"\\\"\";}\n"
+ "RegExp.prototype.tojson = RegExp.prototype.toString;\n"
+ "Array.contains = function( a , x ){\n"
+ "for ( var i=0; i<a.length; i++ ){\n"
+ "if ( a[i] == x )\n"
+ "return true;}\n"
+ "return false;}\n"
+ "Array.unique = function( a ){\n"
+ "var u = [];\n"
+ "for ( var i=0; i<a.length; i++){\n"
+ "var o = a[i];\n"
+ "if ( ! Array.contains( u , o ) ){\n"
+ "u.push( o );}}\n"
+ "return u;}\n"
+ "Array.shuffle = function( arr ){\n"
+ "for ( var i=0; i<arr.length-1; i++ ){\n"
+ "var pos = i+Random.randInt(arr.length-i);\n"
+ "var save = arr[i];\n"
+ "arr[i] = arr[pos];\n"
+ "arr[pos] = save;}\n"
+ "return arr;}\n"
+ "Array.tojson = function( a , indent ){\n"
+ "if (!indent)\n"
+ "indent = \"\";\n"
+ "if (a.length == 0) {\n"
+ "return \"[ ]\";}\n"
+ "var s = \"[\\n\";\n"
+ "indent += \"\\t\";\n"
+ "for ( var i=0; i<a.length; i++){\n"
+ "s += indent + tojson( a[i], indent );\n"
+ "if ( i < a.length - 1 ){\n"
+ "s += \",\\n\";}}\n"
+ "if ( a.length == 0 ) {\n"
+ "s += indent;}\n"
+ "indent = indent.substring(1);\n"
+ "s += \"\\n\"+indent+\"]\";\n"
+ "return s;}\n"
+ "Array.fetchRefs = function( arr , coll ){\n"
+ "var n = [];\n"
+ "for ( var i=0; i<arr.length; i ++){\n"
+ "var z = arr[i];\n"
+ "if ( coll && coll != z.getCollection() )\n"
+ "continue;\n"
+ "n.push( z.fetch() );}\n"
+ "return n;}\n"
+ "Array.sum = function( arr ){\n"
+ "if ( arr.length == 0 )\n"
+ "return null;\n"
+ "var s = arr[0];\n"
+ "for ( var i=1; i<arr.length; i++ )\n"
+ "s += arr[i];\n"
+ "return s;}\n"
+ "Array.avg = function( arr ){\n"
+ "if ( arr.length == 0 )\n"
+ "return null;\n"
+ "return Array.sum( arr ) / arr.length;}\n"
+ "Array.stdDev = function( arr ){\n"
+ "var avg = Array.avg( arr );\n"
+ "var sum = 0;\n"
+ "for ( var i=0; i<arr.length; i++ ){\n"
+ "sum += Math.pow( arr[i] - avg , 2 );}\n"
+ "return Math.sqrt( sum / arr.length );}\n"
+ "Object.keySet = function( o ) {\n"
+ "var ret = new Array();\n"
+ "for( i in o ) {\n"
+ "if ( !( i in o.__proto__ && o[ i ] === o.__proto__[ i ] ) ) {\n"
+ "ret.push( i );}}\n"
+ "return ret;}\n"
+ "if ( ! NumberLong.prototype ) {\n"
+ "NumberLong.prototype = {}}\n"
+ "NumberLong.prototype.tojson = function() {\n"
+ "return this.toString();}\n"
+ "if ( ! ObjectId.prototype )\n"
+ "ObjectId.prototype = {}\n"
+ "ObjectId.prototype.toString = function(){\n"
+ "return this.str;}\n"
+ "ObjectId.prototype.tojson = function(){\n"
+ "return \"ObjectId(\\\"\" + this.str + \"\\\")\";}\n"
+ "ObjectId.prototype.isObjectId = true;\n"
+ "ObjectId.prototype.getTimestamp = function(){\n"
+ "return new Date(parseInt(this.toString().slice(0,8), 16)*1000);}\n"
+ "ObjectId.prototype.equals = function( other){\n"
+ "return this.str == other.str;}\n"
+ "if ( typeof( DBPointer ) != \"undefined\" ){\n"
+ "DBPointer.prototype.fetch = function(){\n"
+ "assert( this.ns , \"need a ns\" );\n"
+ "assert( this.id , \"need an id\" );\n"
+ "return db[ this.ns ].findOne( { _id : this.id } );}\n"
+ "DBPointer.prototype.tojson = function(indent){\n"
+ "return tojson({\"ns\" : this.ns, \"id\" : this.id}, indent);}\n"
+ "DBPointer.prototype.getCollection = function(){\n"
+ "return this.ns;}\n"
+ "DBPointer.prototype.toString = function(){\n"
+ "return \"DBPointer \" + this.ns + \":\" + this.id;}}\n"
+ "else {\n"
+ "print( \"warning: no DBPointer\" );}\n"
+ "if ( typeof( DBRef ) != \"undefined\" ){\n"
+ "DBRef.prototype.fetch = function(){\n"
+ "assert( this.$ref , \"need a ns\" );\n"
+ "assert( this.$id , \"need an id\" );\n"
+ "return db[ this.$ref ].findOne( { _id : this.$id } );}\n"
+ "DBRef.prototype.tojson = function(indent){\n"
+ "return tojson({\"$ref\" : this.$ref, \"$id\" : this.$id}, indent);}\n"
+ "DBRef.prototype.getCollection = function(){\n"
+ "return this.$ref;}\n"
+ "DBRef.prototype.toString = function(){\n"
+ "return this.tojson();}}\n"
+ "else {\n"
+ "print( \"warning: no DBRef\" );}\n"
+ "if ( typeof( BinData ) != \"undefined\" ){\n"
+ "BinData.prototype.tojson = function () {\n"
+ "//return \"BinData type: \" + this.type + \" len: \" + this.len;\n"
+ "return this.toString();}}\n"
+ "else {\n"
+ "print( \"warning: no BinData class\" );}\n"
+ "if ( typeof( UUID ) != \"undefined\" ){\n"
+ "UUID.prototype.tojson = function () {\n"
+ "return this.toString();}}\n"
+ "if ( typeof _threadInject != \"undefined\" ){\n"
+ "print( \"fork() available!\" );\n"
+ "Thread = function(){\n"
+ "this.init.apply( this, arguments );}\n"
+ "_threadInject( Thread.prototype );\n"
+ "ScopedThread = function() {\n"
+ "this.init.apply( this, arguments );}\n"
+ "ScopedThread.prototype = new Thread( function() {} );\n"
+ "_scopedThreadInject( ScopedThread.prototype );\n"
+ "fork = function() {\n"
+ "var t = new Thread( function() {} );\n"
+ "Thread.apply( t, arguments );\n"
+ "return t;}\n"
+ "EventGenerator = function( me, collectionName, mean ) {\n"
+ "this.mean = mean;\n"
+ "this.events = new Array( me, collectionName );}\n"
+ "EventGenerator.prototype._add = function( action ) {\n"
+ "this.events.push( [ Random.genExp( this.mean ), action ] );}\n"
+ "EventGenerator.prototype.addInsert = function( obj ) {\n"
+ "this._add( \"t.insert( \" + tojson( obj ) + \" )\" );}\n"
+ "EventGenerator.prototype.addRemove = function( obj ) {\n"
+ "this._add( \"t.remove( \" + tojson( obj ) + \" )\" );}\n"
+ "EventGenerator.prototype.addUpdate = function( objOld, objNew ) {\n"
+ "this._add( \"t.update( \" + tojson( objOld ) + \", \" + tojson( objNew ) + \" )\" );}\n"
+ "EventGenerator.prototype.addCheckCount = function( count, query, shouldPrint, checkQuery ) {\n"
+ "query = query || {};\n"
+ "shouldPrint = shouldPrint || false;\n"
+ "checkQuery = checkQuery || false;\n"
+ "var action = \"assert.eq( \" + count + \", t.count( \" + tojson( query ) + \" ) );\"\n"
+ "if ( checkQuery ) {\n"
+ "action += \" assert.eq( \" + count + \", t.find( \" + tojson( query ) + \" ).toArray().length );\"}\n"
+ "if ( shouldPrint ) {\n"
+ "action += \" print( me + ' ' + \" + count + \" );\";}\n"
+ "this._add( action );}\n"
+ "EventGenerator.prototype.getEvents = function() {\n"
+ "return this.events;}\n"
+ "EventGenerator.dispatch = function() {\n"
+ "var args = argumentsToArray( arguments );\n"
+ "var me = args.shift();\n"
+ "var collectionName = args.shift();\n"
+ "var m = new Mongo( db.getMongo().host );\n"
+ "var t = m.getDB( \"test\" )[ collectionName ];\n"
+ "for( var i in args ) {\n"
+ "sleep( args[ i ][ 0 ] );\n"
+ "eval( args[ i ][ 1 ] );}}\n"
+ "ParallelTester = function() {\n"
+ "this.params = new Array();}\n"
+ "ParallelTester.prototype.add = function( fun, args ) {\n"
+ "args = args || [];\n"
+ "args.unshift( fun );\n"
+ "this.params.push( args );}\n"
+ "ParallelTester.prototype.run = function( msg, newScopes ) {\n"
+ "newScopes = newScopes || false;\n"
+ "assert.parallelTests( this.params, msg, newScopes );}\n"
+ "ParallelTester.createJstestsLists = function( n ) {\n"
+ "var params = new Array();\n"
+ "for( var i = 0; i < n; ++i ) {\n"
+ "params.push( [] );}\n"
+ "var makeKeys = function( a ) {\n"
+ "var ret = {};\n"
+ "for( var i in a ) {\n"
+ "ret[ a[ i ] ] = 1;}\n"
+ "return ret;}\n"
+ "var skipTests = makeKeys( [ \"jstests/dbadmin.js\",\n"
+ "\"jstests/repair.js\",\n"
+ "\"jstests/cursor8.js\",\n"
+ "\"jstests/recstore.js\",\n"
+ "\"jstests/extent.js\",\n"
+ "\"jstests/indexb.js\",\n"
+ "\"jstests/profile1.js\",\n"
+ "\"jstests/mr3.js\",\n"
+ "\"jstests/indexh.js\",\n"
+ "\"jstests/apitest_db.js\",\n"
+ "\"jstests/evalb.js\"] );\n"
+ "var serialTestsArr = [ \"jstests/fsync.js\",\n"
+ "\"jstests/fsync2.js\" ];\n"
+ "var serialTests = makeKeys( serialTestsArr );\n"
+ "params[ 0 ] = serialTestsArr;\n"
+ "var files = listFiles(\"jstests\");\n"
+ "files = Array.shuffle( files );\n"
+ "var i = 0;\n"
+ "files.forEach(\n"
+ "function(x) {\n"
+ "if ( ( /[\\/\\\\]_/.test(x.name) ) ||\n"
+ "( ! /\\.js$/.test(x.name ) ) ||\n"
+ "( x.name in skipTests ) ||\n"
+ "( x.name in serialTests ) ||\n"
+ "! /\\.js$/.test(x.name ) ){\n"
+ "print(\" >>>>>>>>>>>>>>> skipping \" + x.name);\n"
+ "return;}\n"
+ "params[ i % n ].push( x.name );\n"
+ "++i;}\n"
+ ");\n"
+ "params[ 0 ] = Array.shuffle( params[ 0 ] );\n"
+ "for( var i in params ) {\n"
+ "params[ i ].unshift( i );}\n"
+ "return params;}\n"
+ "ParallelTester.fileTester = function() {\n"
+ "var args = argumentsToArray( arguments );\n"
+ "var suite = args.shift();\n"
+ "args.forEach(\n"
+ "function( x ) {\n"
+ "print(\" S\" + suite + \" Test : \" + x + \" ...\");\n"
+ "var time = Date.timeFunc( function() { load(x); }, 1);\n"
+ "print(\" S\" + suite + \" Test : \" + x + \" \" + time + \"ms\" );}\n"
+ ");}\n"
+ "assert.parallelTests = function( params, msg, newScopes ) {\n"
+ "newScopes = newScopes || false;\n"
+ "var wrapper = function( fun, argv ) {\n"
+ "eval (\n"
+ "\"var z = function() {\" +\n"
+ "\"var __parallelTests__fun = \" + fun.toString() + \";\" +\n"
+ "\"var __parallelTests__argv = \" + tojson( argv ) + \";\" +\n"
+ "\"var __parallelTests__passed = false;\" +\n"
+ "\"try {\" +\n"
+ "\"__parallelTests__fun.apply( 0, __parallelTests__argv );\" +\n"
+ "\"__parallelTests__passed = true;\" +\n"
+ "\"} catch ( e ) {\" +\n"
+ "\"print( e );\" +\n"
+ "\"}\" +\n"
+ "\"return __parallelTests__passed;\" +\n"
+ "\"}\"\n"
+ ");\n"
+ "return z;}\n"
+ "var runners = new Array();\n"
+ "for( var i in params ) {\n"
+ "var param = params[ i ];\n"
+ "var test = param.shift();\n"
+ "var t;\n"
+ "if ( newScopes )\n"
+ "t = new ScopedThread( wrapper( test, param ) );\n"
+ "else\n"
+ "t = new Thread( wrapper( test, param ) );\n"
+ "runners.push( t );}\n"
+ "runners.forEach( function( x ) { x.start(); } );\n"
+ "var nFailed = 0;\n"
+ "runners.forEach( function( x ) { if( !x.returnData() ) { ++nFailed; } } );\n"
+ "assert.eq( 0, nFailed, msg );}}\n"
+ "tojsononeline = function( x ){\n"
+ "return tojson( x , \" \" , true );}\n"
+ "tojson = function( x, indent , nolint ){\n"
+ "if ( x === null )\n"
+ "return \"null\";\n"
+ "if ( x === undefined )\n"
+ "return \"undefined\";\n"
+ "if (!indent)\n"
+ "indent = \"\";\n"
+ "switch ( typeof x ) {\n"
+ "case \"string\": {\n"
+ "var s = \"\\\"\";\n"
+ "for ( var i=0; i<x.length; i++ ){\n"
+ "switch (x[i]){\n"
+ "case '\"': s += '\\\\\"'; break;\n"
+ "case '\\\\': s += '\\\\\\\\'; break;\n"
+ "case '\\b': s += '\\\\b'; break;\n"
+ "case '\\f': s += '\\\\f'; break;\n"
+ "case '\\n': s += '\\\\n'; break;\n"
+ "case '\\r': s += '\\\\r'; break;\n"
+ "case '\\t': s += '\\\\t'; break;\n"
+ "default: {\n"
+ "var code = x.charCodeAt(i);\n"
+ "if (code < 0x20){\n"
+ "s += (code < 0x10 ? '\\\\u000' : '\\\\u00') + code.toString(16);\n"
+ "} else {\n"
+ "s += x[i];}}}}\n"
+ "return s + \"\\\"\";}\n"
+ "case \"number\":\n"
+ "case \"boolean\":\n"
+ "return \"\" + x;\n"
+ "case \"object\":{\n"
+ "var s = tojsonObject( x, indent , nolint );\n"
+ "if ( ( nolint == null || nolint == true ) && s.length < 80 && ( indent == null || indent.length == 0 ) ){\n"
+ "s = s.replace( /[\\s\\r\\n ]+/gm , \" \" );}\n"
+ "return s;}\n"
+ "case \"function\":\n"
+ "return x.toString();\n"
+ "default:\n"
+ "throw \"tojson can't handle type \" + ( typeof x );}}\n"
+ "tojsonObject = function( x, indent , nolint ){\n"
+ "var lineEnding = nolint ? \" \" : \"\\n\";\n"
+ "var tabSpace = nolint ? \"\" : \"\\t\";\n"
+ "assert.eq( ( typeof x ) , \"object\" , \"tojsonObject needs object, not [\" + ( typeof x ) + \"]\" );\n"
+ "if (!indent)\n"
+ "indent = \"\";\n"
+ "if ( typeof( x.tojson ) == \"function\" && x.tojson != tojson ) {\n"
+ "return x.tojson(indent,nolint);}\n"
+ "if ( x.constructor && typeof( x.constructor.tojson ) == \"function\" && x.constructor.tojson != tojson ) {\n"
+ "return x.constructor.tojson( x, indent , nolint );}\n"
+ "if ( x.toString() == \"[object MaxKey]\" )\n"
+ "return \"{ $maxKey : 1 }\";\n"
+ "if ( x.toString() == \"[object MinKey]\" )\n"
+ "return \"{ $minKey : 1 }\";\n"
+ "var s = \"{\" + lineEnding;\n"
+ "indent += tabSpace;\n"
+ "var total = 0;\n"
+ "for ( var k in x ) total++;\n"
+ "if ( total == 0 ) {\n"
+ "s += indent + lineEnding;}\n"
+ "var keys = x;\n"
+ "if ( typeof( x._simpleKeys ) == \"function\" )\n"
+ "keys = x._simpleKeys();\n"
+ "var num = 1;\n"
+ "for ( var k in keys ){\n"
+ "var val = x[k];\n"
+ "if ( val == DB.prototype || val == DBCollection.prototype )\n"
+ "continue;\n"
+ "s += indent + \"\\\"\" + k + \"\\\" : \" + tojson( val, indent , nolint );\n"
+ "if (num != total) {\n"
+ "s += \",\";\n"
+ "num++;}\n"
+ "s += lineEnding;}\n"
+ "indent = indent.substring(1);\n"
+ "return s + indent + \"}\";}\n"
+ "shellPrint = function( x ){\n"
+ "it = x;\n"
+ "if ( x != undefined )\n"
+ "shellPrintHelper( x );\n"
+ "if ( db ){\n"
+ "var e = db.getPrevError();\n"
+ "if ( e.err ) {\n"
+ "if( e.nPrev <= 1 )\n"
+ "print( \"error on last call: \" + tojson( e.err ) );\n"
+ "else\n"
+ "print( \"an error \" + tojson(e.err) + \" occurred \" + e.nPrev + \" operations back in the command invocation\" );}\n"
+ "db.resetError();}}\n"
+ "printjson = function(x){\n"
+ "print( tojson( x ) );}\n"
+ "printjsononeline = function(x){\n"
+ "print( tojsononeline( x ) );}\n"
+ "shellPrintHelper = function( x ){\n"
+ "if ( typeof( x ) == \"undefined\" ){\n"
+ "if ( typeof( db ) != \"undefined\" && db.getLastError ){\n"
+ "var e = db.getLastError();\n"
+ "if ( e != null )\n"
+ "print( e );}\n"
+ "return;}\n"
+ "if ( x == __magicNoPrint )\n"
+ "return;\n"
+ "if ( x == null ){\n"
+ "print( \"null\" );\n"
+ "return;}\n"
+ "if ( typeof x != \"object\" )\n"
+ "return print( x );\n"
+ "var p = x.shellPrint;\n"
+ "if ( typeof p == \"function\" )\n"
+ "return x.shellPrint();\n"
+ "var p = x.tojson;\n"
+ "if ( typeof p == \"function\" )\n"
+ "print( x.tojson() );\n"
+ "else\n"
+ "print( tojson( x ) );}\n"
+ "shellAutocomplete = function( prefix ){\n"
+ "var a = [];\n"
+ "//a.push( prefix + \"z\" )\n"
+ "//a.push( prefix + \"y\" )\n"
+ "__autocomplete__ = a;}\n"
+ "shellHelper = function( command , rest , shouldPrint ){\n"
+ "command = command.trim();\n"
+ "var args = rest.trim().replace(/;$/,\"\").split( \"\\s+\" );\n"
+ "if ( ! shellHelper[command] )\n"
+ "throw \"no command [\" + command + \"]\";\n"
+ "var res = shellHelper[command].apply( null , args );\n"
+ "if ( shouldPrint ){\n"
+ "shellPrintHelper( res );}\n"
+ "return res;}\n"
+ "shellHelper.use = function( dbname ){\n"
+ "db = db.getMongo().getDB( dbname );\n"
+ "print( \"switched to db \" + db.getName() );}\n"
+ "shellHelper.it = function(){\n"
+ "if ( typeof( ___it___ ) == \"undefined\" || ___it___ == null ){\n"
+ "print( \"no cursor\" );\n"
+ "return;}\n"
+ "shellPrintHelper( ___it___ );}\n"
+ "shellHelper.show = function( what ){\n"
+ "assert( typeof what == \"string\" );\n"
+ "if( what == \"profile\" ) {\n"
+ "if( db.system.profile.count() == 0 ) {\n"
+ "print(\"db.system.profile is empty\");\n"
+ "print(\"Use db.setProfilingLevel(2) will enable profiling\");\n"
+ "print(\"Use db.system.profile.find() to show raw profile entries\");}\n"
+ "else {\n"
+ "print();\n"
+ "db.system.profile.find({ millis : { $gt : 0 } }).sort({$natural:-1}).limit(5).forEach( function(x){print(\"\"+x.millis+\"ms \" + String(x.ts).substring(0,24)); print(x.info); print(\"\\n\");} )}\n"
+ "return \"\";}\n"
+ "if ( what == \"users\" ){\n"
+ "db.system.users.find().forEach( printjson );\n"
+ "return \"\";}\n"
+ "if ( what == \"collections\" || what == \"tables\" ) {\n"
+ "db.getCollectionNames().forEach( function(x){print(x)} );\n"
+ "return \"\";}\n"
+ "if ( what == \"dbs\" ) {\n"
+ "db.getMongo().getDBNames().sort().forEach( function(x){print(x)} );\n"
+ "return \"\";}\n"
+ "throw \"don't know how to show [\" + what + \"]\";}\n"
+ "if ( typeof( Map ) == \"undefined\" ){\n"
+ "Map = function(){\n"
+ "this._data = {};}}\n"
+ "Map.hash = function( val ){\n"
+ "if ( ! val )\n"
+ "return val;\n"
+ "switch ( typeof( val ) ){\n"
+ "case 'string':\n"
+ "case 'number':\n"
+ "case 'date':\n"
+ "return val.toString();\n"
+ "case 'object':\n"
+ "case 'array':\n"
+ "var s = \"\";\n"
+ "for ( var k in val ){\n"
+ "s += k + val[k];}\n"
+ "return s;}\n"
+ "throw \"can't hash : \" + typeof( val );}\n"
+ "Map.prototype.put = function( key , value ){\n"
+ "var o = this._get( key );\n"
+ "var old = o.value;\n"
+ "o.value = value;\n"
+ "return old;}\n"
+ "Map.prototype.get = function( key ){\n"
+ "return this._get( key ).value;}\n"
+ "Map.prototype._get = function( key ){\n"
+ "var h = Map.hash( key );\n"
+ "var a = this._data[h];\n"
+ "if ( ! a ){\n"
+ "a = [];\n"
+ "this._data[h] = a;}\n"
+ "for ( var i=0; i<a.length; i++ ){\n"
+ "if ( friendlyEqual( key , a[i].key ) ){\n"
+ "return a[i];}}\n"
+ "var o = { key : key , value : null };\n"
+ "a.push( o );\n"
+ "return o;}\n"
+ "Map.prototype.values = function(){\n"
+ "var all = [];\n"
+ "for ( var k in this._data ){\n"
+ "this._data[k].forEach( function(z){ all.push( z.value ); } );}\n"
+ "return all;}\n"
+ "if ( typeof( gc ) == \"undefined\" ){\n"
+ "gc = function(){\n"
+ "print( \"warning: using noop gc()\" );}}\n"
+ "Math.sigFig = function( x , N ){\n"
+ "if ( ! N ){\n"
+ "N = 3;}\n"
+ "var p = Math.pow( 10, N - Math.ceil( Math.log( Math.abs(x) ) / Math.log( 10 )) );\n"
+ "return Math.round(x*p)/p;}\n"
+ "Random = function() {}\n"
+ "Random.srand = function( s ) { _srand( s ); }\n"
+ "Random.rand = function() { return _rand(); }\n"
+ "Random.randInt = function( n ) { return Math.floor( Random.rand() * n ); }\n"
+ "Random.setRandomSeed = function( s ) {\n"
+ "s = s || new Date().getTime();\n"
+ "print( \"setting random seed: \" + s );\n"
+ "Random.srand( s );}\n"
+ "Random.genExp = function( mean ) {\n"
+ "return -Math.log( Random.rand() ) * mean;}\n"
+ "killWithUris = function( uris ) {\n"
+ "var inprog = db.currentOp().inprog;\n"
+ "for( var u in uris ) {\n"
+ "for ( var i in inprog ) {\n"
+ "if ( uris[ u ] == inprog[ i ].client ) {\n"
+ "db.killOp( inprog[ i ].opid );}}}}\n"
+ "Geo = {};\n"
+ "Geo.distance = function( a , b ){\n"
+ "var ax = null;\n"
+ "var ay = null;\n"
+ "var bx = null;\n"
+ "var by = null;\n"
+ "for ( var key in a ){\n"
+ "if ( ax == null )\n"
+ "ax = a[key];\n"
+ "else if ( ay == null )\n"
+ "ay = a[key];}\n"
+ "for ( var key in b ){\n"
+ "if ( bx == null )\n"
+ "bx = b[key];\n"
+ "else if ( by == null )\n"
+ "by = b[key];}\n"
+ "return Math.sqrt( Math.pow( by - ay , 2 ) +\n"
+ "Math.pow( bx - ax , 2 ) );}\n"
+ "rs = function () { return \"try rs.help()\"; }\n"
+ "rs.help = function () {\n"
+ "print(\"\\trs.status() { replSetGetStatus : 1 } checks repl set status\");\n"
+ "print(\"\\trs.initiate() { replSetInitiate : null } initiates set with default settings\");\n"
+ "print(\"\\trs.initiate(cfg) { replSetInitiate : cfg } initiates set with configuration cfg\");\n"
+ "print(\"\\trs.add(hostportstr) add a new member to the set with default attributes\");\n"
+ "print(\"\\trs.add(membercfgobj) add a new member to the set with extra attributes\");\n"
+ "print(\"\\trs.addArb(hostportstr) add a new member which is arbiterOnly:true\");\n"
+ "print(\"\\trs.stepDown() step down as primary (momentarily)\");\n"
+ "print(\"\\trs.conf() return configuration from local.system.replset\");\n"
+ "print(\"\\trs.slaveOk() shorthand for db.getMongo().setSlaveOk()\");\n"
+ "print();\n"
+ "print(\"\\tdb.isMaster() check who is primary\");\n"
+ "print();\n"
+ "print(\"\\tsee also http://<mongod_host>:28017/_replSet for additional diagnostic info\");}\n"
+ "rs.slaveOk = function () { return db.getMongo().setSlaveOk(); }\n"
+ "rs.status = function () { return db._adminCommand(\"replSetGetStatus\"); }\n"
+ "rs.isMaster = function () { return db.isMaster(); }\n"
+ "rs.initiate = function (c) { return db._adminCommand({ replSetInitiate: c }); }\n"
+ "rs.add = function (hostport, arb) {\n"
+ "var cfg = hostport;\n"
+ "var local = db.getSisterDB(\"local\");\n"
+ "assert(local.system.replset.count() <= 1, \"error: local.system.replset has unexpected contents\");\n"
+ "var c = local.system.replset.findOne();\n"
+ "assert(c, \"no config object retrievable from local.system.replset\");\n"
+ "c.version++;\n"
+ "var max = 0;\n"
+ "for (var i in c.members)\n"
+ "if (c.members[i]._id > max) max = c.members[i]._id;\n"
+ "if (isString(hostport)) {\n"
+ "cfg = { _id: max + 1, host: hostport };\n"
+ "if (arb)\n"
+ "cfg.arbiterOnly = true;}\n"
+ "c.members.push(cfg);\n"
+ "return db._adminCommand({ replSetReconfig: c });}\n"
+ "rs.stepDown = function () { return db._adminCommand({ replSetStepDown:true}); }\n"
+ "rs.addArb = function (hn) { return this.add(hn, true); }\n"
+ "rs.conf = function () { return db.getSisterDB(\"local\").system.replset.findOne(); }\n"
+ "help = shellHelper.help = function (x) {\n"
+ "if (x == \"connect\") {\n"
+ "print(\"\\nNormally one specifies the server on the mongo shell command line. Run mongo --help to see those options.\");\n"
+ "print(\"Additional connections may be opened:\\n\");\n"
+ "print(\" var x = new Mongo('host[:port]');\");\n"
+ "print(\" var mydb = x.getDB('mydb');\");\n"
+ "print(\" or\");\n"
+ "print(\" var mydb = connect('host[:port]/mydb');\");\n"
+ "print(\"\\nNote: the REPL prompt only auto-reports getLastError() for the shell command line connection.\\n\");\n"
+ "return;}\n"
+ "if (x == \"misc\") {\n"
+ "print(\"\\tb = new BinData(subtype,base64str) create a BSON BinData value\");\n"
+ "print(\"\\tb.subtype() the BinData subtype (0..255)\");\n"
+ "print(\"\\tb.length() length of the BinData data in bytes\");\n"
+ "print(\"\\tb.hex() the data as a hex encoded string\");\n"
+ "print(\"\\tb.base64() the data as a base 64 encoded string\");\n"
+ "print(\"\\tb.toString()\");\n"
+ "return;}\n"
+ "if (x == \"admin\") {\n"
+ "print(\"\\tls([path]) list files\");\n"
+ "print(\"\\tpwd() returns current directory\");\n"
+ "print(\"\\tlistFiles([path]) returns file list\");\n"
+ "print(\"\\thostname() returns name of this host\");\n"
+ "print(\"\\tcat(fname) returns contents of text file as a string\");\n"
+ "print(\"\\tremoveFile(f) delete a file\");\n"
+ "print(\"\\tload(jsfilename) load and execute a .js file\");\n"
+ "print(\"\\trun(program[, args...]) spawn a program and wait for its completion\");\n"
+ "print(\"\\tsleep(m) sleep m milliseconds\");\n"
+ "print(\"\\tgetMemInfo() diagnostic\");\n"
+ "return;}\n"
+ "if (x == \"test\") {\n"
+ "print(\"\\tstartMongodEmpty(args) DELETES DATA DIR and then starts mongod\");\n"
+ "print(\"\\t returns a connection to the new server\");\n"
+ "print(\"\\tstartMongodTest() DELETES DATA DIR\");\n"
+ "print(\"\\t automatically picks port #s starting at 27000 and increasing\");\n"
+ "print(\"\\t or you can specify the port as the first arg\");\n"
+ "print(\"\\t dir is /data/db/<port>/ if not specified as the 2nd arg\");\n"
+ "print(\"\\t returns a connection to the new server\");\n"
+ "return;}\n"
+ "print(\"\\t\" + \"db.help() help on db methods\");\n"
+ "print(\"\\t\" + \"db.mycoll.help() help on collection methods\");\n"
+ "print(\"\\t\" + \"rs.help() help on replica set methods\");\n"
+ "print(\"\\t\" + \"help connect connecting to a db help\");\n"
+ "print(\"\\t\" + \"help admin administrative help\");\n"
+ "print(\"\\t\" + \"help misc misc things to know\");\n"
+ "print();\n"
+ "print(\"\\t\" + \"show dbs show database names\");\n"
+ "print(\"\\t\" + \"show collections show collections in current database\");\n"
+ "print(\"\\t\" + \"show users show users in current database\");\n"
+ "print(\"\\t\" + \"show profile show most recent system.profile entries with time >= 1ms\");\n"
+ "print(\"\\t\" + \"use <db_name> set current database\");\n"
+ "print(\"\\t\" + \"db.foo.find() list objects in collection foo\");\n"
+ "print(\"\\t\" + \"db.foo.find( { a : 1 } ) list objects in foo where a == 1\");\n"
+ "print(\"\\t\" + \"it result of the last line evaluated; use to further iterate\");\n"
+ "print(\"\\t\" + \"exit quit the mongo shell\");}\n"
+ "if ( typeof DB == \"undefined\" ){\n"
+ "DB = function( mongo , name ){\n"
+ "this._mongo = mongo;\n"
+ "this._name = name;}}\n"
+ "DB.prototype.getMongo = function(){\n"
+ "assert( this._mongo , \"why no mongo!\" );\n"
+ "return this._mongo;}\n"
+ "DB.prototype.getSisterDB = function( name ){\n"
+ "return this.getMongo().getDB( name );}\n"
+ "DB.prototype.getName = function(){\n"
+ "return this._name;}\n"
+ "DB.prototype.stats = function(){\n"
+ "return this.runCommand( { dbstats : 1 } );}\n"
+ "DB.prototype.getCollection = function( name ){\n"
+ "return new DBCollection( this._mongo , this , name , this._name + \".\" + name );}\n"
+ "DB.prototype.commandHelp = function( name ){\n"
+ "var c = {};\n"
+ "c[name] = 1;\n"
+ "c.help = true;\n"
+ "return this.runCommand( c ).help;}\n"
+ "DB.prototype.runCommand = function( obj ){\n"
+ "if ( typeof( obj ) == \"string\" ){\n"
+ "var n = {};\n"
+ "n[obj] = 1;\n"
+ "obj = n;}\n"
+ "return this.getCollection( \"$cmd\" ).findOne( obj );}\n"
+ "DB.prototype._dbCommand = DB.prototype.runCommand;\n"
+ "DB.prototype._adminCommand = function( obj ){\n"
+ "if ( this._name == \"admin\" )\n"
+ "return this.runCommand( obj );\n"
+ "return this.getSisterDB( \"admin\" ).runCommand( obj );}\n"
+ "DB.prototype.addUser = function( username , pass, readOnly ){\n"
+ "readOnly = readOnly || false;\n"
+ "var c = this.getCollection( \"system.users\" );\n"
+ "var u = c.findOne( { user : username } ) || { user : username };\n"
+ "u.readOnly = readOnly;\n"
+ "u.pwd = hex_md5( username + \":mongo:\" + pass );\n"
+ "print( tojson( u ) );\n"
+ "c.save( u );}\n"
+ "DB.prototype.removeUser = function( username ){\n"
+ "this.getCollection( \"system.users\" ).remove( { user : username } );}\n"
+ "DB.prototype.__pwHash = function( nonce, username, pass ) {\n"
+ "return hex_md5( nonce + username + hex_md5( username + \":mongo:\" + pass ) );}\n"
+ "DB.prototype.auth = function( username , pass ){\n"
+ "var n = this.runCommand( { getnonce : 1 } );\n"
+ "var a = this.runCommand(\n"
+ "{\n"
+ "authenticate : 1 ,\n"
+ "user : username ,\n"
+ "nonce : n.nonce ,\n"
+ "key : this.__pwHash( n.nonce, username, pass )}\n"
+ ");\n"
+ "return a.ok;}\n"
+ "\n"
+ "DB.prototype.createCollection = function(name, opt) {\n"
+ "var options = opt || {};\n"
+ "var cmd = { create: name, capped: options.capped, size: options.size, max: options.max };\n"
+ "var res = this._dbCommand(cmd);\n"
+ "return res;}\n"
+ "\n"
+ "DB.prototype.getProfilingLevel = function() {\n"
+ "var res = this._dbCommand( { profile: -1 } );\n"
+ "return res ? res.was : null;}\n"
+ "\n"
+ "DB.prototype.dropDatabase = function() {\n"
+ "if ( arguments.length )\n"
+ "throw \"dropDatabase doesn't take arguments\";\n"
+ "return this._dbCommand( { dropDatabase: 1 } );}\n"
+ "DB.prototype.shutdownServer = function() {\n"
+ "if( \"admin\" != this._name ){\n"
+ "return \"shutdown command only works with the admin database; try 'use admin'\";}\n"
+ "try {\n"
+ "var res = this._dbCommand(\"shutdown\");\n"
+ "if( res )\n"
+ "throw \"shutdownServer failed: \" + res.errmsg;\n"
+ "throw \"shutdownServer failed\";}\n"
+ "catch ( e ){\n"
+ "assert( tojson( e ).indexOf( \"error doing query: failed\" ) >= 0 , \"unexpected error: \" + tojson( e ) );\n"
+ "print( \"server should be down...\" );}}\n"
+ "\n"
+ "DB.prototype.cloneDatabase = function(from) {\n"
+ "assert( isString(from) && from.length );\n"
+ "return this._dbCommand( { clone: from } );}\n"
+ "\n"
+ "DB.prototype.cloneCollection = function(from, collection, query) {\n"
+ "assert( isString(from) && from.length );\n"
+ "assert( isString(collection) && collection.length );\n"
+ "collection = this._name + \".\" + collection;\n"
+ "query = query || {};\n"
+ "return this._dbCommand( { cloneCollection:collection, from:from, query:query } );}\n"
+ "\n"
+ "DB.prototype.copyDatabase = function(fromdb, todb, fromhost, username, password) {\n"
+ "assert( isString(fromdb) && fromdb.length );\n"
+ "assert( isString(todb) && todb.length );\n"
+ "fromhost = fromhost || \"\";\n"
+ "if ( username && password ) {\n"
+ "var n = this._adminCommand( { copydbgetnonce : 1, fromhost:fromhost } );\n"
+ "return this._adminCommand( { copydb:1, fromhost:fromhost, fromdb:fromdb, todb:todb, username:username, nonce:n.nonce, key:this.__pwHash( n.nonce, username, password ) } );\n"
+ "} else {\n"
+ "return this._adminCommand( { copydb:1, fromhost:fromhost, fromdb:fromdb, todb:todb } );}}\n"
+ "\n"
+ "DB.prototype.repairDatabase = function() {\n"
+ "return this._dbCommand( { repairDatabase: 1 } );}\n"
+ "DB.prototype.help = function() {\n"
+ "print(\"DB methods:\");\n"
+ "print(\"\\tdb.addUser(username, password[, readOnly=false])\");\n"
+ "print(\"\\tdb.auth(username, password)\");\n"
+ "print(\"\\tdb.cloneDatabase(fromhost)\");\n"
+ "print(\"\\tdb.commandHelp(name) returns the help for the command\");\n"
+ "print(\"\\tdb.copyDatabase(fromdb, todb, fromhost)\");\n"
+ "print(\"\\tdb.createCollection(name, { size : ..., capped : ..., max : ... } )\");\n"
+ "print(\"\\tdb.currentOp() displays the current operation in the db\");\n"
+ "print(\"\\tdb.dropDatabase()\");\n"
+ "print(\"\\tdb.eval(func, args) run code server-side\");\n"
+ "print(\"\\tdb.getCollection(cname) same as db['cname'] or db.cname\");\n"
+ "print(\"\\tdb.getCollectionNames()\");\n"
+ "print(\"\\tdb.getLastError() - just returns the err msg string\");\n"
+ "print(\"\\tdb.getLastErrorObj() - return full status object\");\n"
+ "print(\"\\tdb.getMongo() get the server connection object\");\n"
+ "print(\"\\tdb.getMongo().setSlaveOk() allow this connection to read from the nonmaster member of a replica pair\");\n"
+ "print(\"\\tdb.getName()\");\n"
+ "print(\"\\tdb.getPrevError()\");\n"
+ "print(\"\\tdb.getProfilingLevel()\");\n"
+ "print(\"\\tdb.getReplicationInfo()\");\n"
+ "print(\"\\tdb.getSisterDB(name) get the db at the same server as this one\");\n"
+ "print(\"\\tdb.isMaster() check replica primary status\");\n"
+ "print(\"\\tdb.killOp(opid) kills the current operation in the db\");\n"
+ "print(\"\\tdb.listCommands() lists all the db commands\");\n"
+ "print(\"\\tdb.printCollectionStats()\");\n"
+ "print(\"\\tdb.printReplicationInfo()\");\n"
+ "print(\"\\tdb.printSlaveReplicationInfo()\");\n"
+ "print(\"\\tdb.printShardingStatus()\");\n"
+ "print(\"\\tdb.removeUser(username)\");\n"
+ "print(\"\\tdb.repairDatabase()\");\n"
+ "print(\"\\tdb.resetError()\");\n"
+ "print(\"\\tdb.runCommand(cmdObj) run a database command. if cmdObj is a string, turns it into { cmdObj : 1 }\");\n"
+ "print(\"\\tdb.serverStatus()\");\n"
+ "print(\"\\tdb.setProfilingLevel(level,<slowms>) 0=off 1=slow 2=all\");\n"
+ "print(\"\\tdb.shutdownServer()\");\n"
+ "print(\"\\tdb.stats()\");\n"
+ "print(\"\\tdb.version() current version of the server\");\n"
+ "print(\"\\tdb.getMongo().setSlaveOk() allow queries on a replication slave server\");\n"
+ "return __magicNoPrint;}\n"
+ "DB.prototype.printCollectionStats = function(){\n"
+ "var mydb = this;\n"
+ "this.getCollectionNames().forEach(\n"
+ "function(z){\n"
+ "print( z );\n"
+ "printjson( mydb.getCollection(z).stats() );\n"
+ "print( \"---\" );}\n"
+ ");}\n"
+ "\n"
+ "DB.prototype.setProfilingLevel = function(level,slowms) {\n"
+ "if (level < 0 || level > 2) {\n"
+ "throw { dbSetProfilingException : \"input level \" + level + \" is out of range [0..2]\" };}\n"
+ "var cmd = { profile: level };\n"
+ "if ( slowms )\n"
+ "cmd[\"slowms\"] = slowms;\n"
+ "return this._dbCommand( cmd );}\n"
+ "\n"
+ "DB.prototype.eval = function(jsfunction) {\n"
+ "var cmd = { $eval : jsfunction };\n"
+ "if ( arguments.length > 1 ) {\n"
+ "cmd.args = argumentsToArray( arguments ).slice(1);}\n"
+ "var res = this._dbCommand( cmd );\n"
+ "if (!res.ok)\n"
+ "throw tojson( res );\n"
+ "return res.retval;}\n"
+ "DB.prototype.dbEval = DB.prototype.eval;\n"
+ "\n"
+ "DB.prototype.groupeval = function(parmsObj) {\n"
+ "var groupFunction = function() {\n"
+ "var parms = args[0];\n"
+ "var c = db[parms.ns].find(parms.cond||{});\n"
+ "var map = new Map();\n"
+ "var pks = parms.key ? Object.keySet( parms.key ) : null;\n"
+ "var pkl = pks ? pks.length : 0;\n"
+ "var key = {};\n"
+ "while( c.hasNext() ) {\n"
+ "var obj = c.next();\n"
+ "if ( pks ) {\n"
+ "for( var i=0; i<pkl; i++ ){\n"
+ "var k = pks[i];\n"
+ "key[k] = obj[k];}}\n"
+ "else {\n"
+ "key = parms.$keyf(obj);}\n"
+ "var aggObj = map.get(key);\n"
+ "if( aggObj == null ) {\n"
+ "var newObj = Object.extend({}, key);\n"
+ "aggObj = Object.extend(newObj, parms.initial)\n"
+ "map.put( key , aggObj );}\n"
+ "parms.$reduce(obj, aggObj);}\n"
+ "return map.values();}\n"
+ "return this.eval(groupFunction, this._groupFixParms( parmsObj ));}\n"
+ "DB.prototype.groupcmd = function( parmsObj ){\n"
+ "var ret = this.runCommand( { \"group\" : this._groupFixParms( parmsObj ) } );\n"
+ "if ( ! ret.ok ){\n"
+ "throw \"group command failed: \" + tojson( ret );}\n"
+ "return ret.retval;}\n"
+ "DB.prototype.group = DB.prototype.groupcmd;\n"
+ "DB.prototype._groupFixParms = function( parmsObj ){\n"
+ "var parms = Object.extend({}, parmsObj);\n"
+ "if( parms.reduce ) {\n"
+ "parms.$reduce = parms.reduce;\n"
+ "delete parms.reduce;}\n"
+ "if( parms.keyf ) {\n"
+ "parms.$keyf = parms.keyf;\n"
+ "delete parms.keyf;}\n"
+ "return parms;}\n"
+ "DB.prototype.resetError = function(){\n"
+ "return this.runCommand( { reseterror : 1 } );}\n"
+ "DB.prototype.forceError = function(){\n"
+ "return this.runCommand( { forceerror : 1 } );}\n"
+ "DB.prototype.getLastError = function( w , wtimeout ){\n"
+ "var res = this.getLastErrorObj( w , wtimeout );\n"
+ "if ( ! res.ok )\n"
+ "throw \"getlasterror failed: \" + tojson( res );\n"
+ "return res.err;}\n"
+ "DB.prototype.getLastErrorObj = function( w , wtimeout ){\n"
+ "var cmd = { getlasterror : 1 };\n"
+ "if ( w ){\n"
+ "cmd.w = w;\n"
+ "if ( wtimeout )\n"
+ "cmd.wtimeout = wtimeout;}\n"
+ "var res = this.runCommand( cmd );\n"
+ "if ( ! res.ok )\n"
+ "throw \"getlasterror failed: \" + tojson( res );\n"
+ "return res;}\n"
+ "DB.prototype.getLastErrorCmd = DB.prototype.getLastErrorObj;\n"
+ "/* Return the last error which has occurred, even if not the very last error.\n"
+ "Returns:\n"
+ "{ err : <error message>, nPrev : <how_many_ops_back_occurred>, ok : 1 }\n"
+ "result.err will be null if no error has occurred.\n"
+ "*/\n"
+ "DB.prototype.getPrevError = function(){\n"
+ "return this.runCommand( { getpreverror : 1 } );}\n"
+ "DB.prototype.getCollectionNames = function(){\n"
+ "var all = [];\n"
+ "var nsLength = this._name.length + 1;\n"
+ "var c = this.getCollection( \"system.namespaces\" ).find();\n"
+ "while ( c.hasNext() ){\n"
+ "var name = c.next().name;\n"
+ "if ( name.indexOf( \"$\" ) >= 0 && name.indexOf( \".oplog.$\" ) < 0 )\n"
+ "continue;\n"
+ "all.push( name.substring( nsLength ) );}\n"
+ "return all.sort();}\n"
+ "DB.prototype.tojson = function(){\n"
+ "return this._name;}\n"
+ "DB.prototype.toString = function(){\n"
+ "return this._name;}\n"
+ "DB.prototype.isMaster = function () { return this.runCommand(\"isMaster\"); }\n"
+ "DB.prototype.currentOp = function(){\n"
+ "return db.$cmd.sys.inprog.findOne();}\n"
+ "DB.prototype.currentOP = DB.prototype.currentOp;\n"
+ "DB.prototype.killOp = function(op) {\n"
+ "if( !op )\n"
+ "throw \"no opNum to kill specified\";\n"
+ "return db.$cmd.sys.killop.findOne({'op':op});}\n"
+ "DB.prototype.killOP = DB.prototype.killOp;\n"
+ "DB.tsToSeconds = function(x){\n"
+ "if ( x.t && x.i )\n"
+ "return x.t / 1000;\n"
+ "return x / 4294967296;}\n"
+ "\n"
+ "DB.prototype.getReplicationInfo = function() {\n"
+ "var db = this.getSisterDB(\"local\");\n"
+ "var result = { };\n"
+ "var ol = db.system.namespaces.findOne({name:\"local.oplog.$main\"});\n"
+ "if( ol && ol.options ) {\n"
+ "result.logSizeMB = ol.options.size / 1000 / 1000;\n"
+ "} else {\n"
+ "result.errmsg = \"local.oplog.$main, or its options, not found in system.namespaces collection (not --master?)\";\n"
+ "return result;}\n"
+ "var firstc = db.oplog.$main.find().sort({$natural:1}).limit(1);\n"
+ "var lastc = db.oplog.$main.find().sort({$natural:-1}).limit(1);\n"
+ "if( !firstc.hasNext() || !lastc.hasNext() ) {\n"
+ "result.errmsg = \"objects not found in local.oplog.$main -- is this a new and empty db instance?\";\n"
+ "result.oplogMainRowCount = db.oplog.$main.count();\n"
+ "return result;}\n"
+ "var first = firstc.next();\n"
+ "var last = lastc.next();\n"
+ "{\n"
+ "var tfirst = first.ts;\n"
+ "var tlast = last.ts;\n"
+ "if( tfirst && tlast ) {\n"
+ "tfirst = DB.tsToSeconds( tfirst );\n"
+ "tlast = DB.tsToSeconds( tlast );\n"
+ "result.timeDiff = tlast - tfirst;\n"
+ "result.timeDiffHours = Math.round(result.timeDiff / 36)/100;\n"
+ "result.tFirst = (new Date(tfirst*1000)).toString();\n"
+ "result.tLast = (new Date(tlast*1000)).toString();\n"
+ "result.now = Date();}\n"
+ "else {\n"
+ "result.errmsg = \"ts element not found in oplog objects\";}}\n"
+ "return result;}\n"
+ "DB.prototype.printReplicationInfo = function() {\n"
+ "var result = this.getReplicationInfo();\n"
+ "if( result.errmsg ) {\n"
+ "print(tojson(result));\n"
+ "return;}\n"
+ "print(\"configured oplog size: \" + result.logSizeMB + \"MB\");\n"
+ "print(\"log length start to end: \" + result.timeDiff + \"secs (\" + result.timeDiffHours + \"hrs)\");\n"
+ "print(\"oplog first event time: \" + result.tFirst);\n"
+ "print(\"oplog last event time: \" + result.tLast);\n"
+ "print(\"now: \" + result.now);}\n"
+ "DB.prototype.printSlaveReplicationInfo = function() {\n"
+ "function g(x) {\n"
+ "assert( x , \"how could this be null (printSlaveReplicationInfo gx)\" )\n"
+ "print(\"source: \" + x.host);\n"
+ "if ( x.syncedTo ){\n"
+ "var st = new Date( DB.tsToSeconds( x.syncedTo ) * 1000 );\n"
+ "var now = new Date();\n"
+ "print(\"\\t syncedTo: \" + st.toString() );\n"
+ "var ago = (now-st)/1000;\n"
+ "var hrs = Math.round(ago/36)/100;\n"
+ "print(\"\\t\\t = \" + Math.round(ago) + \"secs ago (\" + hrs + \"hrs)\");}\n"
+ "else {\n"
+ "print( \"\\t doing initial sync\" );}}\n"
+ "var L = this.getSisterDB(\"local\");\n"
+ "if( L.sources.count() == 0 ) {\n"
+ "print(\"local.sources is empty; is this db a --slave?\");\n"
+ "return;}\n"
+ "L.sources.find().forEach(g);}\n"
+ "DB.prototype.serverBuildInfo = function(){\n"
+ "return this._adminCommand( \"buildinfo\" );}\n"
+ "DB.prototype.serverStatus = function(){\n"
+ "return this._adminCommand( \"serverStatus\" );}\n"
+ "DB.prototype.serverCmdLineOpts = function(){\n"
+ "return this._adminCommand( \"getCmdLineOpts\" );}\n"
+ "DB.prototype.version = function(){\n"
+ "return this.serverBuildInfo().version;}\n"
+ "DB.prototype.listCommands = function(){\n"
+ "var x = this.runCommand( \"listCommands\" );\n"
+ "for ( var name in x.commands ){\n"
+ "var c = x.commands[name];\n"
+ "var s = name + \": \";\n"
+ "switch ( c.lockType ){\n"
+ "case -1: s += \"read-lock\"; break;\n"
+ "case 0: s += \"no-lock\"; break;\n"
+ "case 1: s += \"write-lock\"; break;\n"
+ "default: s += c.lockType;}\n"
+ "if (c.adminOnly) s += \" adminOnly \";\n"
+ "if (c.adminOnly) s += \" slaveOk \";\n"
+ "s += \"\\n \";\n"
+ "s += c.help.replace(/\\n/g, '\\n ');\n"
+ "s += \"\\n\";\n"
+ "print( s );}}\n"
+ "DB.prototype.printShardingStatus = function(){\n"
+ "printShardingStatus( this.getSisterDB( \"config\" ) );}\n"
+ "if ( typeof Mongo == \"undefined\" ){\n"
+ "Mongo = function( host ){\n"
+ "this.init( host );}}\n"
+ "if ( ! Mongo.prototype ){\n"
+ "throw \"Mongo.prototype not defined\";}\n"
+ "if ( ! Mongo.prototype.find )\n"
+ "Mongo.prototype.find = function( ns , query , fields , limit , skip ){ throw \"find not implemented\"; }\n"
+ "if ( ! Mongo.prototype.insert )\n"
+ "Mongo.prototype.insert = function( ns , obj ){ throw \"insert not implemented\"; }\n"
+ "if ( ! Mongo.prototype.remove )\n"
+ "Mongo.prototype.remove = function( ns , pattern ){ throw \"remove not implemented;\" }\n"
+ "if ( ! Mongo.prototype.update )\n"
+ "Mongo.prototype.update = function( ns , query , obj , upsert ){ throw \"update not implemented;\" }\n"
+ "if ( typeof mongoInject == \"function\" ){\n"
+ "mongoInject( Mongo.prototype );}\n"
+ "Mongo.prototype.setSlaveOk = function() {\n"
+ "this.slaveOk = true;}\n"
+ "Mongo.prototype.getDB = function( name ){\n"
+ "return new DB( this , name );}\n"
+ "Mongo.prototype.getDBs = function(){\n"
+ "var res = this.getDB( \"admin\" ).runCommand( { \"listDatabases\" : 1 } );\n"
+ "assert( res.ok == 1 , \"listDatabases failed:\" + tojson( res ) );\n"
+ "return res;}\n"
+ "Mongo.prototype.getDBNames = function(){\n"
+ "return this.getDBs().databases.map(\n"
+ "function(z){\n"
+ "return z.name;}\n"
+ ");}\n"
+ "Mongo.prototype.getCollection = function(ns){\n"
+ "var idx = ns.indexOf( \".\" );\n"
+ "if ( idx < 0 )\n"
+ "throw \"need . in ns\";\n"
+ "var db = ns.substring( 0 , idx );\n"
+ "var c = ns.substring( idx + 1 );\n"
+ "return this.getDB( db ).getCollection( c );}\n"
+ "Mongo.prototype.toString = function(){\n"
+ "return \"connection to \" + this.host;}\n"
+ "Mongo.prototype.tojson = Mongo.prototype.toString;\n"
+ "connect = function( url , user , pass ){\n"
+ "chatty( \"connecting to: \" + url )\n"
+ "if ( user && ! pass )\n"
+ "throw \"you specified a user and not a password. either you need a password, or you're using the old connect api\";\n"
+ "var idx = url.lastIndexOf( \"/\" );\n"
+ "var db;\n"
+ "if ( idx < 0 )\n"
+ "db = new Mongo().getDB( url );\n"
+ "else\n"
+ "db = new Mongo( url.substring( 0 , idx ) ).getDB( url.substring( idx + 1 ) );\n"
+ "if ( user && pass ){\n"
+ "if ( ! db.auth( user , pass ) ){\n"
+ "throw \"couldn't login\";}}\n"
+ "return db;}\n"
+ "MR = {};\n"
+ "MR.init = function(){\n"
+ "$max = 0;\n"
+ "$arr = [];\n"
+ "emit = MR.emit;\n"
+ "$numEmits = 0;\n"
+ "$numReduces = 0;\n"
+ "$numReducesToDB = 0;\n"
+ "gc();}\n"
+ "MR.cleanup = function(){\n"
+ "MR.init();\n"
+ "gc();}\n"
+ "MR.emit = function(k,v){\n"
+ "$numEmits++;\n"
+ "var num = nativeHelper.apply( get_num_ , [ k ] );\n"
+ "var data = $arr[num];\n"
+ "if ( ! data ){\n"
+ "data = { key : k , values : new Array(1000) , count : 0 };\n"
+ "$arr[num] = data;}\n"
+ "data.values[data.count++] = v;\n"
+ "$max = Math.max( $max , data.count );}\n"
+ "MR.doReduce = function( useDB ){\n"
+ "$numReduces++;\n"
+ "if ( useDB )\n"
+ "$numReducesToDB++;\n"
+ "$max = 0;\n"
+ "for ( var i=0; i<$arr.length; i++){\n"
+ "var data = $arr[i];\n"
+ "if ( ! data )\n"
+ "continue;\n"
+ "if ( useDB ){\n"
+ "var x = tempcoll.findOne( { _id : data.key } );\n"
+ "if ( x ){\n"
+ "data.values[data.count++] = x.value;}}\n"
+ "var r = $reduce( data.key , data.values.slice( 0 , data.count ) );\n"
+ "if ( r && r.length && r[0] ){\n"
+ "data.values = r;\n"
+ "data.count = r.length;}\n"
+ "else{\n"
+ "data.values[0] = r;\n"
+ "data.count = 1;}\n"
+ "$max = Math.max( $max , data.count );\n"
+ "if ( useDB ){\n"
+ "if ( data.count == 1 ){\n"
+ "tempcoll.save( { _id : data.key , value : data.values[0] } );}\n"
+ "else {\n"
+ "tempcoll.save( { _id : data.key , value : data.values.slice( 0 , data.count ) } );}}}}\n"
+ "MR.check = function(){\n"
+ "if ( $max < 2000 && $arr.length < 1000 ){\n"
+ "return 0;}\n"
+ "MR.doReduce();\n"
+ "if ( $max < 2000 && $arr.length < 1000 ){\n"
+ "return 1;}\n"
+ "MR.doReduce( true );\n"
+ "$arr = [];\n"
+ "$max = 0;\n"
+ "reset_num();\n"
+ "gc();\n"
+ "return 2;}\n"
+ "MR.finalize = function(){\n"
+ "tempcoll.find().forEach(\n"
+ "function(z){\n"
+ "z.value = $finalize( z._id , z.value );\n"
+ "tempcoll.save( z );}\n"
+ ");}\n"
+ "if ( typeof DBQuery == \"undefined\" ){\n"
+ "DBQuery = function( mongo , db , collection , ns , query , fields , limit , skip , batchSize ){\n"
+ "this._mongo = mongo;\n"
+ "this._db = db;\n"
+ "this._collection = collection;\n"
+ "this._ns = ns;\n"
+ "this._query = query || {};\n"
+ "this._fields = fields;\n"
+ "this._limit = limit || 0;\n"
+ "this._skip = skip || 0;\n"
+ "this._batchSize = batchSize || 0;\n"
+ "this._cursor = null;\n"
+ "this._numReturned = 0;\n"
+ "this._special = false;\n"
+ "this._prettyShell = false;}\n"
+ "print( \"DBQuery probably won't have array access \" );}\n"
+ "DBQuery.prototype.help = function () {\n"
+ "print(\"find() modifiers\")\n"
+ "print(\"\\t.sort( {...} )\")\n"
+ "print(\"\\t.limit( n )\")\n"
+ "print(\"\\t.skip( n )\")\n"
+ "print(\"\\t.count() - total # of objects matching query, ignores skip,limit\")\n"
+ "print(\"\\t.size() - total # of objects cursor would return, honors skip,limit\")\n"
+ "print(\"\\t.explain([verbose])\")\n"
+ "print(\"\\t.hint(...)\")\n"
+ "print(\"\\t.showDiskLoc() - adds a $diskLoc field to each returned object\")\n"
+ "print(\"\\nCursor methods\");\n"
+ "print(\"\\t.forEach( func )\")\n"
+ "print(\"\\t.print() - output to console in full pretty format\")\n"
+ "print(\"\\t.map( func )\")\n"
+ "print(\"\\t.hasNext()\")\n"
+ "print(\"\\t.next()\")}\n"
+ "DBQuery.prototype.clone = function(){\n"
+ "var q = new DBQuery( this._mongo , this._db , this._collection , this._ns ,\n"
+ "this._query , this._fields ,\n"
+ "this._limit , this._skip , this._batchSize );\n"
+ "q._special = this._special;\n"
+ "return q;}\n"
+ "DBQuery.prototype._ensureSpecial = function(){\n"
+ "if ( this._special )\n"
+ "return;\n"
+ "var n = { query : this._query };\n"
+ "this._query = n;\n"
+ "this._special = true;}\n"
+ "DBQuery.prototype._checkModify = function(){\n"
+ "if ( this._cursor )\n"
+ "throw \"query already executed\";}\n"
+ "DBQuery.prototype._exec = function(){\n"
+ "if ( ! this._cursor ){\n"
+ "assert.eq( 0 , this._numReturned );\n"
+ "this._cursor = this._mongo.find( this._ns , this._query , this._fields , this._limit , this._skip , this._batchSize );\n"
+ "this._cursorSeen = 0;}\n"
+ "return this._cursor;}\n"
+ "DBQuery.prototype.limit = function( limit ){\n"
+ "this._checkModify();\n"
+ "this._limit = limit;\n"
+ "return this;}\n"
+ "DBQuery.prototype.batchSize = function( batchSize ){\n"
+ "this._checkModify();\n"
+ "this._batchSize = batchSize;\n"
+ "return this;}\n"
+ "DBQuery.prototype.skip = function( skip ){\n"
+ "this._checkModify();\n"
+ "this._skip = skip;\n"
+ "return this;}\n"
+ "DBQuery.prototype.hasNext = function(){\n"
+ "this._exec();\n"
+ "if ( this._limit > 0 && this._cursorSeen >= this._limit )\n"
+ "return false;\n"
+ "var o = this._cursor.hasNext();\n"
+ "return o;}\n"
+ "DBQuery.prototype.next = function(){\n"
+ "this._exec();\n"
+ "var o = this._cursor.hasNext();\n"
+ "if ( o )\n"
+ "this._cursorSeen++;\n"
+ "else\n"
+ "throw \"error hasNext: \" + o;\n"
+ "var ret = this._cursor.next();\n"
+ "if ( ret.$err && this._numReturned == 0 && ! this.hasNext() )\n"
+ "throw \"error: \" + tojson( ret );\n"
+ "this._numReturned++;\n"
+ "return ret;}\n"
+ "DBQuery.prototype.objsLeftInBatch = function(){\n"
+ "this._exec();\n"
+ "var ret = this._cursor.objsLeftInBatch();\n"
+ "if ( ret.$err )\n"
+ "throw \"error: \" + tojson( ret );\n"
+ "return ret;}\n"
+ "DBQuery.prototype.toArray = function(){\n"
+ "if ( this._arr )\n"
+ "return this._arr;\n"
+ "var a = [];\n"
+ "while ( this.hasNext() )\n"
+ "a.push( this.next() );\n"
+ "this._arr = a;\n"
+ "return a;}\n"
+ "DBQuery.prototype.count = function( applySkipLimit ){\n"
+ "var cmd = { count: this._collection.getName() };\n"
+ "if ( this._query ){\n"
+ "if ( this._special )\n"
+ "cmd.query = this._query.query;\n"
+ "else\n"
+ "cmd.query = this._query;}\n"
+ "cmd.fields = this._fields || {};\n"
+ "if ( applySkipLimit ){\n"
+ "if ( this._limit )\n"
+ "cmd.limit = this._limit;\n"
+ "if ( this._skip )\n"
+ "cmd.skip = this._skip;}\n"
+ "var res = this._db.runCommand( cmd );\n"
+ "if( res && res.n != null ) return res.n;\n"
+ "throw \"count failed: \" + tojson( res );}\n"
+ "DBQuery.prototype.size = function(){\n"
+ "return this.count( true );}\n"
+ "DBQuery.prototype.countReturn = function(){\n"
+ "var c = this.count();\n"
+ "if ( this._skip )\n"
+ "c = c - this._skip;\n"
+ "if ( this._limit > 0 && this._limit < c )\n"
+ "return this._limit;\n"
+ "return c;}\n"
+ "\n"
+ "DBQuery.prototype.itcount = function(){\n"
+ "var num = 0;\n"
+ "while ( this.hasNext() ){\n"
+ "num++;\n"
+ "this.next();}\n"
+ "return num;}\n"
+ "DBQuery.prototype.length = function(){\n"
+ "return this.toArray().length;}\n"
+ "DBQuery.prototype._addSpecial = function( name , value ){\n"
+ "this._ensureSpecial();\n"
+ "this._query[name] = value;\n"
+ "return this;}\n"
+ "DBQuery.prototype.sort = function( sortBy ){\n"
+ "return this._addSpecial( \"orderby\" , sortBy );}\n"
+ "DBQuery.prototype.hint = function( hint ){\n"
+ "return this._addSpecial( \"$hint\" , hint );}\n"
+ "DBQuery.prototype.min = function( min ) {\n"
+ "return this._addSpecial( \"$min\" , min );}\n"
+ "DBQuery.prototype.max = function( max ) {\n"
+ "return this._addSpecial( \"$max\" , max );}\n"
+ "DBQuery.prototype.showDiskLoc = function() {\n"
+ "return this._addSpecial( \"$showDiskLoc\" , true);}\n"
+ "DBQuery.prototype.forEach = function( func ){\n"
+ "while ( this.hasNext() )\n"
+ "func( this.next() );}\n"
+ "DBQuery.prototype.map = function( func ){\n"
+ "var a = [];\n"
+ "while ( this.hasNext() )\n"
+ "a.push( func( this.next() ) );\n"
+ "return a;}\n"
+ "DBQuery.prototype.arrayAccess = function( idx ){\n"
+ "return this.toArray()[idx];}\n"
+ "DBQuery.prototype.explain = function (verbose) {\n"
+ "/* verbose=true --> include allPlans, oldPlan fields */\n"
+ "var n = this.clone();\n"
+ "n._ensureSpecial();\n"
+ "n._query.$explain = true;\n"
+ "n._limit = n._limit * -1;\n"
+ "var e = n.next();\n"
+ "if (!verbose) {\n"
+ "delete e.allPlans;\n"
+ "delete e.oldPlan;}\n"
+ "return e;}\n"
+ "DBQuery.prototype.snapshot = function(){\n"
+ "this._ensureSpecial();\n"
+ "this._query.$snapshot = true;\n"
+ "return this;}\n"
+ "DBQuery.prototype.pretty = function(){\n"
+ "this._prettyShell = true;\n"
+ "return this;}\n"
+ "DBQuery.prototype.shellPrint = function(){\n"
+ "try {\n"
+ "var n = 0;\n"
+ "while ( this.hasNext() && n < DBQuery.shellBatchSize ){\n"
+ "var s = this._prettyShell ? tojson( this.next() ) : tojson( this.next() , \"\" , true );\n"
+ "print( s );\n"
+ "n++;}\n"
+ "if ( this.hasNext() ){\n"
+ "print( \"has more\" );\n"
+ "___it___ = this;}\n"
+ "else {\n"
+ "___it___ = null;}}\n"
+ "catch ( e ){\n"
+ "print( e );}}\n"
+ "DBQuery.prototype.toString = function(){\n"
+ "return \"DBQuery: \" + this._ns + \" -> \" + tojson( this.query );}\n"
+ "DBQuery.shellBatchSize = 20;\n"
+ "// or db[\"colName\"]\n"
+ "if ( ( typeof DBCollection ) == \"undefined\" ){\n"
+ "DBCollection = function( mongo , db , shortName , fullName ){\n"
+ "this._mongo = mongo;\n"
+ "this._db = db;\n"
+ "this._shortName = shortName;\n"
+ "this._fullName = fullName;\n"
+ "this.verify();}}\n"
+ "DBCollection.prototype.verify = function(){\n"
+ "assert( this._fullName , \"no fullName\" );\n"
+ "assert( this._shortName , \"no shortName\" );\n"
+ "assert( this._db , \"no db\" );\n"
+ "assert.eq( this._fullName , this._db._name + \".\" + this._shortName , \"name mismatch\" );\n"
+ "assert( this._mongo , \"no mongo in DBCollection\" );}\n"
+ "DBCollection.prototype.getName = function(){\n"
+ "return this._shortName;}\n"
+ "DBCollection.prototype.help = function () {\n"
+ "var shortName = this.getName();\n"
+ "print(\"DBCollection help\");\n"
+ "print(\"\\tdb.\" + shortName + \".find().help() - show DBCursor help\");\n"
+ "print(\"\\tdb.\" + shortName + \".count()\");\n"
+ "print(\"\\tdb.\" + shortName + \".dataSize()\");\n"
+ "print(\"\\tdb.\" + shortName + \".distinct( key ) - eg. db.\" + shortName + \".distinct( 'x' )\");\n"
+ "print(\"\\tdb.\" + shortName + \".drop() drop the collection\");\n"
+ "print(\"\\tdb.\" + shortName + \".dropIndex(name)\");\n"
+ "print(\"\\tdb.\" + shortName + \".dropIndexes()\");\n"
+ "print(\"\\tdb.\" + shortName + \".ensureIndex(keypattern,options) - options should be an object with these possible fields: name, unique, dropDups\");\n"
+ "print(\"\\tdb.\" + shortName + \".reIndex()\");\n"
+ "print(\"\\tdb.\" + shortName + \".find( [query] , [fields]) - first parameter is an optional query filter. second parameter is optional set of fields to return.\");\n"
+ "print(\"\\t e.g. db.\" + shortName + \".find( { x : 77 } , { name : 1 , x : 1 } )\");\n"
+ "print(\"\\tdb.\" + shortName + \".find(...).count()\");\n"
+ "print(\"\\tdb.\" + shortName + \".find(...).limit(n)\");\n"
+ "print(\"\\tdb.\" + shortName + \".find(...).skip(n)\");\n"
+ "print(\"\\tdb.\" + shortName + \".find(...).sort(...)\");\n"
+ "print(\"\\tdb.\" + shortName + \".findOne([query])\");\n"
+ "print(\"\\tdb.\" + shortName + \".findAndModify( { update : ... , remove : bool [, query: {}, sort: {}, 'new': false] } )\");\n"
+ "print(\"\\tdb.\" + shortName + \".getDB() get DB object associated with collection\");\n"
+ "print(\"\\tdb.\" + shortName + \".getIndexes()\");\n"
+ "print(\"\\tdb.\" + shortName + \".group( { key : ..., initial: ..., reduce : ...[, cond: ...] } )\");\n"
+ "print(\"\\tdb.\" + shortName + \".mapReduce( mapFunction , reduceFunction , <optional params> )\");\n"
+ "print(\"\\tdb.\" + shortName + \".remove(query)\");\n"
+ "print(\"\\tdb.\" + shortName + \".renameCollection( newName , <dropTarget> ) renames the collection.\");\n"
+ "print(\"\\tdb.\" + shortName + \".runCommand( name , <options> ) runs a db command with the given name where the first param is the collection name\");\n"
+ "print(\"\\tdb.\" + shortName + \".save(obj)\");\n"
+ "print(\"\\tdb.\" + shortName + \".stats()\");\n"
+ "print(\"\\tdb.\" + shortName + \".storageSize() - includes free space allocated to this collection\");\n"
+ "print(\"\\tdb.\" + shortName + \".totalIndexSize() - size in bytes of all the indexes\");\n"
+ "print(\"\\tdb.\" + shortName + \".totalSize() - storage allocated for all data and indexes\");\n"
+ "print(\"\\tdb.\" + shortName + \".update(query, object[, upsert_bool, multi_bool])\");\n"
+ "print(\"\\tdb.\" + shortName + \".validate() - SLOW\");\n"
+ "print(\"\\tdb.\" + shortName + \".getShardVersion() - only for use with sharding\");\n"
+ "return __magicNoPrint;}\n"
+ "DBCollection.prototype.getFullName = function(){\n"
+ "return this._fullName;}\n"
+ "DBCollection.prototype.getDB = function(){\n"
+ "return this._db;}\n"
+ "DBCollection.prototype._dbCommand = function( cmd , params ){\n"
+ "if ( typeof( cmd ) == \"object\" )\n"
+ "return this._db._dbCommand( cmd );\n"
+ "var c = {};\n"
+ "c[cmd] = this.getName();\n"
+ "if ( params )\n"
+ "Object.extend( c , params );\n"
+ "return this._db._dbCommand( c );}\n"
+ "DBCollection.prototype.runCommand = DBCollection.prototype._dbCommand;\n"
+ "DBCollection.prototype._massageObject = function( q ){\n"
+ "if ( ! q )\n"
+ "return {};\n"
+ "var type = typeof q;\n"
+ "if ( type == \"function\" )\n"
+ "return { $where : q };\n"
+ "if ( q.isObjectId )\n"
+ "return { _id : q };\n"
+ "if ( type == \"object\" )\n"
+ "return q;\n"
+ "if ( type == \"string\" ){\n"
+ "if ( q.length == 24 )\n"
+ "return { _id : q };\n"
+ "return { $where : q };}\n"
+ "throw \"don't know how to massage : \" + type;}\n"
+ "DBCollection.prototype._validateObject = function( o ){\n"
+ "if ( o._ensureSpecial && o._checkModify )\n"
+ "throw \"can't save a DBQuery object\";}\n"
+ "DBCollection._allowedFields = { $id : 1 , $ref : 1 };\n"
+ "DBCollection.prototype._validateForStorage = function( o ){\n"
+ "this._validateObject( o );\n"
+ "for ( var k in o ){\n"
+ "if ( k.indexOf( \".\" ) >= 0 ) {\n"
+ "throw \"can't have . in field names [\" + k + \"]\" ;}\n"
+ "if ( k.indexOf( \"$\" ) == 0 && ! DBCollection._allowedFields[k] ) {\n"
+ "throw \"field names cannot start with $ [\" + k + \"]\";}\n"
+ "if ( o[k] !== null && typeof( o[k] ) === \"object\" ) {\n"
+ "this._validateForStorage( o[k] );}}\n"
+ "};\n"
+ "DBCollection.prototype.find = function( query , fields , limit , skip ){\n"
+ "return new DBQuery( this._mongo , this._db , this ,\n"
+ "this._fullName , this._massageObject( query ) , fields , limit , skip );}\n"
+ "DBCollection.prototype.findOne = function( query , fields ){\n"
+ "var cursor = this._mongo.find( this._fullName , this._massageObject( query ) || {} , fields , -1 , 0 , 0 );\n"
+ "if ( ! cursor.hasNext() )\n"
+ "return null;\n"
+ "var ret = cursor.next();\n"
+ "if ( cursor.hasNext() ) throw \"findOne has more than 1 result!\";\n"
+ "if ( ret.$err )\n"
+ "throw \"error \" + tojson( ret );\n"
+ "return ret;}\n"
+ "DBCollection.prototype.insert = function( obj , _allow_dot ){\n"
+ "if ( ! obj )\n"
+ "throw \"no object passed to insert!\";\n"
+ "if ( ! _allow_dot ) {\n"
+ "this._validateForStorage( obj );}\n"
+ "if ( typeof( obj._id ) == \"undefined\" ){\n"
+ "var tmp = obj;\n"
+ "obj = {_id: new ObjectId()};\n"
+ "for (var key in tmp){\n"
+ "obj[key] = tmp[key];}}\n"
+ "this._mongo.insert( this._fullName , obj );\n"
+ "this._lastID = obj._id;}\n"
+ "DBCollection.prototype.remove = function( t ){\n"
+ "this._mongo.remove( this._fullName , this._massageObject( t ) );}\n"
+ "DBCollection.prototype.update = function( query , obj , upsert , multi ){\n"
+ "assert( query , \"need a query\" );\n"
+ "assert( obj , \"need an object\" );\n"
+ "this._validateObject( obj );\n"
+ "this._mongo.update( this._fullName , query , obj , upsert ? true : false , multi ? true : false );}\n"
+ "DBCollection.prototype.save = function( obj ){\n"
+ "if ( obj == null || typeof( obj ) == \"undefined\" )\n"
+ "throw \"can't save a null\";\n"
+ "if ( typeof( obj._id ) == \"undefined\" ){\n"
+ "obj._id = new ObjectId();\n"
+ "return this.insert( obj );}\n"
+ "else {\n"
+ "return this.update( { _id : obj._id } , obj , true );}}\n"
+ "DBCollection.prototype._genIndexName = function( keys ){\n"
+ "var name = \"\";\n"
+ "for ( var k in keys ){\n"
+ "var v = keys[k];\n"
+ "if ( typeof v == \"function\" )\n"
+ "continue;\n"
+ "if ( name.length > 0 )\n"
+ "name += \"_\";\n"
+ "name += k + \"_\";\n"
+ "if ( typeof v == \"number\" )\n"
+ "name += v;}\n"
+ "return name;}\n"
+ "DBCollection.prototype._indexSpec = function( keys, options ) {\n"
+ "var ret = { ns : this._fullName , key : keys , name : this._genIndexName( keys ) };\n"
+ "if ( ! options ){}\n"
+ "else if ( typeof ( options ) == \"string\" )\n"
+ "ret.name = options;\n"
+ "else if ( typeof ( options ) == \"boolean\" )\n"
+ "ret.unique = true;\n"
+ "else if ( typeof ( options ) == \"object\" ){\n"
+ "if ( options.length ){\n"
+ "var nb = 0;\n"
+ "for ( var i=0; i<options.length; i++ ){\n"
+ "if ( typeof ( options[i] ) == \"string\" )\n"
+ "ret.name = options[i];\n"
+ "else if ( typeof( options[i] ) == \"boolean\" ){\n"
+ "if ( options[i] ){\n"
+ "if ( nb == 0 )\n"
+ "ret.unique = true;\n"
+ "if ( nb == 1 )\n"
+ "ret.dropDups = true;}\n"
+ "nb++;}}}\n"
+ "else {\n"
+ "Object.extend( ret , options );}}\n"
+ "else {\n"
+ "throw \"can't handle: \" + typeof( options );}\n"
+ "/*\n"
+ "return ret;\n"
+ "var name;\n"
+ "var nTrue = 0;\n"
+ "if ( ! isObject( options ) ) {\n"
+ "options = [ options ];}\n"
+ "if ( options.length ){\n"
+ "for( var i = 0; i < options.length; ++i ) {\n"
+ "var o = options[ i ];\n"
+ "if ( isString( o ) ) {\n"
+ "ret.name = o;\n"
+ "} else if ( typeof( o ) == \"boolean\" ) {\n"
+ "if ( o ) {\n"
+ "++nTrue;}}}\n"
+ "if ( nTrue > 0 ) {\n"
+ "ret.unique = true;}\n"
+ "if ( nTrue > 1 ) {\n"
+ "ret.dropDups = true;}}\n"
+ "*/\n"
+ "return ret;}\n"
+ "DBCollection.prototype.createIndex = function( keys , options ){\n"
+ "var o = this._indexSpec( keys, options );\n"
+ "this._db.getCollection( \"system.indexes\" ).insert( o , true );}\n"
+ "DBCollection.prototype.ensureIndex = function( keys , options ){\n"
+ "var name = this._indexSpec( keys, options ).name;\n"
+ "this._indexCache = this._indexCache || {};\n"
+ "if ( this._indexCache[ name ] ){\n"
+ "return;}\n"
+ "this.createIndex( keys , options );\n"
+ "if ( this.getDB().getLastError() == \"\" ) {\n"
+ "this._indexCache[name] = true;}}\n"
+ "DBCollection.prototype.resetIndexCache = function(){\n"
+ "this._indexCache = {};}\n"
+ "DBCollection.prototype.reIndex = function() {\n"
+ "return this._db.runCommand({ reIndex: this.getName() });}\n"
+ "DBCollection.prototype.dropIndexes = function(){\n"
+ "this.resetIndexCache();\n"
+ "var res = this._db.runCommand( { deleteIndexes: this.getName(), index: \"*\" } );\n"
+ "assert( res , \"no result from dropIndex result\" );\n"
+ "if ( res.ok )\n"
+ "return res;\n"
+ "if ( res.errmsg.match( /not found/ ) )\n"
+ "return res;\n"
+ "throw \"error dropping indexes : \" + tojson( res );}\n"
+ "DBCollection.prototype.drop = function(){\n"
+ "this.resetIndexCache();\n"
+ "var ret = this._db.runCommand( { drop: this.getName() } );\n"
+ "if ( ! ret.ok ){\n"
+ "if ( ret.errmsg == \"ns not found\" )\n"
+ "return false;\n"
+ "throw \"drop failed: \" + tojson( ret );}\n"
+ "return true;}\n"
+ "DBCollection.prototype.findAndModify = function(args){\n"
+ "var cmd = { findandmodify: this.getName() };\n"
+ "for (var key in args){\n"
+ "cmd[key] = args[key];}\n"
+ "var ret = this._db.runCommand( cmd );\n"
+ "if ( ! ret.ok ){\n"
+ "if (ret.errmsg == \"No matching object found\"){\n"
+ "return null;}\n"
+ "throw \"findAndModifyFailed failed: \" + tojson( ret.errmsg );}\n"
+ "return ret.value;}\n"
+ "DBCollection.prototype.renameCollection = function( newName , dropTarget ){\n"
+ "return this._db._adminCommand( { renameCollection : this._fullName ,\n"
+ "to : this._db._name + \".\" + newName ,\n"
+ "dropTarget : dropTarget } )}\n"
+ "DBCollection.prototype.validate = function() {\n"
+ "var res = this._db.runCommand( { validate: this.getName() } );\n"
+ "res.valid = false;\n"
+ "var raw = res.result || res.raw;\n"
+ "if ( raw ){\n"
+ "var str = \"-\" + tojson( raw );\n"
+ "res.valid = ! ( str.match( /exception/ ) || str.match( /corrupt/ ) );\n"
+ "var p = /lastExtentSize:(\\d+)/;\n"
+ "var r = p.exec( str );\n"
+ "if ( r ){\n"
+ "res.lastExtentSize = Number( r[1] );}}\n"
+ "return res;}\n"
+ "DBCollection.prototype.getShardVersion = function(){\n"
+ "return this._db._adminCommand( { getShardVersion : this._fullName } );}\n"
+ "DBCollection.prototype.getIndexes = function(){\n"
+ "return this.getDB().getCollection( \"system.indexes\" ).find( { ns : this.getFullName() } ).toArray();}\n"
+ "DBCollection.prototype.getIndices = DBCollection.prototype.getIndexes;\n"
+ "DBCollection.prototype.getIndexSpecs = DBCollection.prototype.getIndexes;\n"
+ "DBCollection.prototype.getIndexKeys = function(){\n"
+ "return this.getIndexes().map(\n"
+ "function(i){\n"
+ "return i.key;}\n"
+ ");}\n"
+ "DBCollection.prototype.count = function( x ){\n"
+ "return this.find( x ).count();}\n"
+ "\n"
+ "DBCollection.prototype.clean = function() {\n"
+ "return this._dbCommand( { clean: this.getName() } );}\n"
+ "\n"
+ "DBCollection.prototype.dropIndex = function(index) {\n"
+ "assert(index , \"need to specify index to dropIndex\" );\n"
+ "if ( ! isString( index ) && isObject( index ) )\n"
+ "index = this._genIndexName( index );\n"
+ "var res = this._dbCommand( \"deleteIndexes\" ,{ index: index } );\n"
+ "this.resetIndexCache();\n"
+ "return res;}\n"
+ "DBCollection.prototype.copyTo = function( newName ){\n"
+ "return this.getDB().eval(\n"
+ "function( collName , newName ){\n"
+ "var from = db[collName];\n"
+ "var to = db[newName];\n"
+ "to.ensureIndex( { _id : 1 } );\n"
+ "var count = 0;\n"
+ "var cursor = from.find();\n"
+ "while ( cursor.hasNext() ){\n"
+ "var o = cursor.next();\n"
+ "count++;\n"
+ "to.save( o );}\n"
+ "return count;\n"
+ "} , this.getName() , newName\n"
+ ");}\n"
+ "DBCollection.prototype.getCollection = function( subName ){\n"
+ "return this._db.getCollection( this._shortName + \".\" + subName );}\n"
+ "DBCollection.prototype.stats = function( scale ){\n"
+ "return this._db.runCommand( { collstats : this._shortName , scale : scale } );}\n"
+ "DBCollection.prototype.dataSize = function(){\n"
+ "return this.stats().size;}\n"
+ "DBCollection.prototype.storageSize = function(){\n"
+ "return this.stats().storageSize;}\n"
+ "DBCollection.prototype.totalIndexSize = function( verbose ){\n"
+ "var stats = this.stats();\n"
+ "if (verbose){\n"
+ "for (var ns in stats.indexSizes){\n"
+ "print( ns + \"\\t\" + stats.indexSizes[ns] );}}\n"
+ "return stats.totalIndexSize;}\n"
+ "DBCollection.prototype.totalSize = function(){\n"
+ "var total = this.storageSize();\n"
+ "var mydb = this._db;\n"
+ "var shortName = this._shortName;\n"
+ "this.getIndexes().forEach(\n"
+ "function( spec ){\n"
+ "var coll = mydb.getCollection( shortName + \".$\" + spec.name );\n"
+ "var mysize = coll.storageSize();\n"
+ "//print( coll + \"\\t\" + mysize + \"\\t\" + tojson( coll.validate() ) );\n"
+ "total += coll.dataSize();}\n"
+ ");\n"
+ "return total;}\n"
+ "DBCollection.prototype.convertToCapped = function( bytes ){\n"
+ "if ( ! bytes )\n"
+ "throw \"have to specify # of bytes\";\n"
+ "return this._dbCommand( { convertToCapped : this._shortName , size : bytes } )}\n"
+ "DBCollection.prototype.exists = function(){\n"
+ "return this._db.system.namespaces.findOne( { name : this._fullName } );}\n"
+ "DBCollection.prototype.isCapped = function(){\n"
+ "var e = this.exists();\n"
+ "return ( e && e.options && e.options.capped ) ? true : false;}\n"
+ "DBCollection.prototype.distinct = function( keyString , query ){\n"
+ "var res = this._dbCommand( { distinct : this._shortName , key : keyString , query : query || {} } );\n"
+ "if ( ! res.ok )\n"
+ "throw \"distinct failed: \" + tojson( res );\n"
+ "return res.values;}\n"
+ "DBCollection.prototype.group = function( params ){\n"
+ "params.ns = this._shortName;\n"
+ "return this._db.group( params );}\n"
+ "DBCollection.prototype.groupcmd = function( params ){\n"
+ "params.ns = this._shortName;\n"
+ "return this._db.groupcmd( params );}\n"
+ "MapReduceResult = function( db , o ){\n"
+ "Object.extend( this , o );\n"
+ "this._o = o;\n"
+ "this._keys = Object.keySet( o );\n"
+ "this._db = db;\n"
+ "this._coll = this._db.getCollection( this.result );}\n"
+ "MapReduceResult.prototype._simpleKeys = function(){\n"
+ "return this._o;}\n"
+ "MapReduceResult.prototype.find = function(){\n"
+ "return DBCollection.prototype.find.apply( this._coll , arguments );}\n"
+ "MapReduceResult.prototype.drop = function(){\n"
+ "return this._coll.drop();}\n"
+ "\n"
+ "MapReduceResult.prototype.convertToSingleObject = function(){\n"
+ "var z = {};\n"
+ "this._coll.find().forEach( function(a){ z[a._id] = a.value; } );\n"
+ "return z;}\n"
+ "\n"
+ "DBCollection.prototype.mapReduce = function( map , reduce , optional ){\n"
+ "var c = { mapreduce : this._shortName , map : map , reduce : reduce };\n"
+ "if ( optional )\n"
+ "Object.extend( c , optional );\n"
+ "var raw = this._db.runCommand( c );\n"
+ "if ( ! raw.ok )\n"
+ "throw \"map reduce failed: \" + tojson( raw );\n"
+ "return new MapReduceResult( this._db , raw );}\n"
+ "DBCollection.prototype.toString = function(){\n"
+ "return this.getFullName();}\n"
+ "DBCollection.prototype.toString = function(){\n"
+ "return this.getFullName();}\n"
+ "DBCollection.prototype.tojson = DBCollection.prototype.toString;\n"
+ "DBCollection.prototype.shellPrint = DBCollection.prototype.toString;\n"
+ ;
+
diff --git a/shell/msvc/mongo.ico b/shell/msvc/mongo.ico
new file mode 100755
index 0000000..1eba9ed
--- /dev/null
+++ b/shell/msvc/mongo.ico
Binary files differ
diff --git a/shell/msvc/mongo.sln b/shell/msvc/mongo.sln
new file mode 100644
index 0000000..01c9e1e
--- /dev/null
+++ b/shell/msvc/mongo.sln
@@ -0,0 +1,20 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mongo", "mongo.vcxproj", "{FE959BD8-8EE2-4555-AE59-9FA14FFD410E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FE959BD8-8EE2-4555-AE59-9FA14FFD410E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {FE959BD8-8EE2-4555-AE59-9FA14FFD410E}.Debug|Win32.Build.0 = Debug|Win32
+ {FE959BD8-8EE2-4555-AE59-9FA14FFD410E}.Release|Win32.ActiveCfg = Release|Win32
+ {FE959BD8-8EE2-4555-AE59-9FA14FFD410E}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/shell/msvc/mongo.vcxproj b/shell/msvc/mongo.vcxproj
new file mode 100644
index 0000000..b158b9e
--- /dev/null
+++ b/shell/msvc/mongo.vcxproj
@@ -0,0 +1,253 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{FE959BD8-8EE2-4555-AE59-9FA14FFD410E}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>mongo</RootNamespace>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <LibraryPath>\boost\lib\vs2010_32\;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib</LibraryPath>
+ <ExecutablePath>$(VCInstallDir)bin;$(WindowsSdkDir)bin\NETFX 4.0 Tools;$(WindowsSdkDir)bin;$(VSInstallDir)Common7\Tools\bin;$(VSInstallDir)Common7\tools;$(VSInstallDir)Common7\ide;$(ProgramFiles)\HTML Help Workshop;$(FrameworkSDKDir)\bin;$(MSBuildToolsPath32);$(VSInstallDir);$(SystemRoot)\SysWow64;$(FxCopDir);$(PATH);</ExecutablePath>
+ <IncludePath>..\..\..\readline\include;..\..\..\js\src\;..\..\pcre-7.4;..\..\;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include</IncludePath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <IncludePath>..\..\..\readline\include;..\..\..\js\src\;..\..\pcre-7.4;..\..\;$(VCInstallDir)include;$(VCInstallDir)atlmfc\include;$(WindowsSdkDir)include;$(FrameworkSDKDir)\include</IncludePath>
+ <LinkIncremental>false</LinkIncremental>
+ <LibraryPath>\boost\lib\vs2010_32\;$(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSdkDir)lib;$(FrameworkSDKDir)\lib</LibraryPath>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>USE_READLINE;XP_WIN;PCRE_STATIC;HAVE_CONFIG_H;OLDJS;MONGO_EXPOSE_MACROS;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>\boost\</AdditionalIncludeDirectories>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <DisableSpecificWarnings>4355;4800;4267;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>ws2_32.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>Use</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>USE_READLINE;XP_WIN;_WIN32;PCRE_STATIC;HAVE_CONFIG_H;OLDJS;MONGO_EXPOSE_MACROS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>\boost\</AdditionalIncludeDirectories>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+ <DisableSpecificWarnings>4355;4800;4267;4244;%(DisableSpecificWarnings)</DisableSpecificWarnings>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <AdditionalDependencies>ws2_32.lib;psapi.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\client\clientOnly.cpp" />
+ <ClCompile Include="..\..\client\connpool.cpp" />
+ <ClCompile Include="..\..\client\syncclusterconnection.cpp" />
+ <ClCompile Include="..\..\db\commands.cpp" />
+ <ClCompile Include="..\..\db\lasterror.cpp" />
+ <ClCompile Include="..\..\db\nonce.cpp" />
+ <ClCompile Include="..\..\pcre-7.4\pcrecpp.cc">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_compile.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_config.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_chartables.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_stringpiece.cc">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\scripting\engine_spidermonkey.cpp" />
+ <ClCompile Include="..\..\scripting\utils.cpp" />
+ <ClCompile Include="..\..\s\d_util.cpp" />
+ <ClCompile Include="..\..\s\shardconnection.cpp" />
+ <ClCompile Include="..\..\util\background.cpp" />
+ <ClCompile Include="..\..\util\log.cpp" />
+ <ClCompile Include="..\..\util\mmap.cpp" />
+ <ClCompile Include="..\..\util\password.cpp" />
+ <ClCompile Include="..\..\util\text.cpp" />
+ <ClCompile Include="..\..\util\mmap_win.cpp" />
+ <ClCompile Include="..\..\util\processinfo_win32.cpp" />
+ <ClCompile Include="..\..\util\sock.cpp" />
+ <ClCompile Include="..\..\util\message.cpp" />
+ <ClCompile Include="..\..\util\assert_util.cpp" />
+ <ClCompile Include="..\..\util\md5main.cpp" />
+ <ClCompile Include="..\..\util\md5.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\util\base64.cpp" />
+ <ClCompile Include="..\..\util\debug_util.cpp" />
+ <ClCompile Include="..\..\pcre-7.4\pcre_dfa_exec.c">
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_exec.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_fullinfo.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_get.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_globals.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_info.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_maketables.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_newline.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_ord2utf8.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_refcount.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_study.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_tables.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_try_flipped.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_ucp_searchfuncs.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_valid_utf8.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_version.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_xclass.c">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\..\client\dbclient.cpp" />
+ <ClCompile Include="..\..\client\dbclientcursor.cpp" />
+ <ClCompile Include="..\..\db\common.cpp" />
+ <ClCompile Include="..\..\db\jsobj.cpp" />
+ <ClCompile Include="..\..\db\json.cpp" />
+ <ClCompile Include="..\..\pch.cpp">
+ <PrecompiledHeader>Create</PrecompiledHeader>
+ <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
+ </ClCompile>
+ <ClCompile Include="..\..\scripting\engine.cpp" />
+ <ClCompile Include="..\..\util\concurrency\vars.cpp" />
+ <ClCompile Include="..\..\util\util.cpp" />
+ <ClCompile Include="..\..\util\version.cpp" />
+ <ClCompile Include="..\dbshell.cpp" />
+ <ClCompile Include="..\mongo-server.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\mongo_vstudio.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">NotUsing</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NotUsing</PrecompiledHeader>
+ </ClCompile>
+ <ClCompile Include="..\shell_utils.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\SConstruct" />
+ <None Include="..\collection.js" />
+ <None Include="..\db.js" />
+ <None Include="..\mongo.js" />
+ <None Include="..\mr.js" />
+ <None Include="..\query.js" />
+ <None Include="..\servers.js" />
+ <None Include="..\utils.js" />
+ </ItemGroup>
+ <ItemGroup>
+ <Library Include="..\..\..\js\js32d.lib">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+ </Library>
+ <Library Include="..\..\..\js\js32r.lib">
+ <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+ </Library>
+ <Library Include="..\..\..\readline\lib\readline.lib" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\db\lasterror.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\db\db.rc" />
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/shell/msvc/mongo.vcxproj.filters b/shell/msvc/mongo.vcxproj.filters
new file mode 100644
index 0000000..426a8b0
--- /dev/null
+++ b/shell/msvc/mongo.vcxproj.filters
@@ -0,0 +1,262 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ <Filter Include="util">
+ <UniqueIdentifier>{2a0d6120-434d-4732-ac31-2a7bf077f6ee}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="util\concurrency">
+ <UniqueIdentifier>{a1e59094-b70c-463a-8dc1-691efe337f14}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="scripting">
+ <UniqueIdentifier>{2d0fd975-0cc9-43dc-ac8e-53cb8c3a0040}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="bson">
+ <UniqueIdentifier>{a33442e2-39da-4c70-8310-6de9fa70cd71}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="db">
+ <UniqueIdentifier>{1044ce7b-72c4-4892-82c0-f46d8708a6ff}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="client">
+ <UniqueIdentifier>{fc0f6c1a-9627-4254-9b5e-0bcb8b3257f3}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="shared source files">
+ <UniqueIdentifier>{30b62472-d7a7-4b8a-8a07-d7d341bc6252}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="pcre">
+ <UniqueIdentifier>{291e0d72-13ca-42d7-b0fd-2e7b5f89639f}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="shell">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="_js files">
+ <UniqueIdentifier>{473e7192-9f2a-47c5-ad95-e5b75d4f48f9}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="shell\generated_from_js">
+ <UniqueIdentifier>{96e4c411-7ab4-4bcd-b7c6-a33059f5d492}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\dbshell.cpp">
+ <Filter>shell</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\version.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\concurrency\vars.cpp">
+ <Filter>util\concurrency</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\scripting\engine.cpp">
+ <Filter>scripting</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\db\jsobj.cpp">
+ <Filter>db</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\client\dbclient.cpp">
+ <Filter>client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\client\dbclientcursor.cpp">
+ <Filter>client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pch.cpp" />
+ <ClCompile Include="..\..\db\json.cpp">
+ <Filter>shared source files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\sock.cpp">
+ <Filter>shell</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\debug_util.cpp">
+ <Filter>shell</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\db\lasterror.cpp">
+ <Filter>shared source files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\db\nonce.cpp">
+ <Filter>shared source files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_xclass.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_version.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_valid_utf8.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_ucp_searchfuncs.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_try_flipped.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_tables.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_study.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_refcount.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_ord2utf8.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_newline.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_maketables.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_info.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_globals.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_get.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_fullinfo.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_exec.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_dfa_exec.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcrecpp.cc">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\client\connpool.cpp">
+ <Filter>client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\processinfo_win32.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\db\commands.cpp">
+ <Filter>db</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\scripting\utils.cpp">
+ <Filter>scripting</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\assert_util.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\background.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\base64.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\client\clientOnly.cpp">
+ <Filter>client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\mmap.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\md5main.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\message.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\util.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\client\syncclusterconnection.cpp">
+ <Filter>client</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_stringpiece.cc">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_config.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_compile.c">
+ <Filter>pcre</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\pcre-7.4\pcre_chartables.c">
+ <Filter>shell</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\md5.c">
+ <Filter>shell</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\mmap_win.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\text.cpp">
+ <Filter>shell</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\s\d_util.cpp">
+ <Filter>shared source files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\s\shardconnection.cpp">
+ <Filter>shared source files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\shell_utils.cpp">
+ <Filter>shell</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\scripting\engine_spidermonkey.cpp">
+ <Filter>scripting</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\password.cpp">
+ <Filter>util</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\db\common.cpp">
+ <Filter>db</Filter>
+ </ClCompile>
+ <ClCompile Include="..\mongo_vstudio.cpp">
+ <Filter>shell\generated_from_js</Filter>
+ </ClCompile>
+ <ClCompile Include="..\mongo-server.cpp">
+ <Filter>shell\generated_from_js</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\util\log.cpp">
+ <Filter>shared source files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="..\..\SConstruct" />
+ <None Include="..\collection.js">
+ <Filter>_js files</Filter>
+ </None>
+ <None Include="..\db.js">
+ <Filter>_js files</Filter>
+ </None>
+ <None Include="..\mongo.js">
+ <Filter>_js files</Filter>
+ </None>
+ <None Include="..\mr.js">
+ <Filter>_js files</Filter>
+ </None>
+ <None Include="..\query.js">
+ <Filter>_js files</Filter>
+ </None>
+ <None Include="..\servers.js">
+ <Filter>_js files</Filter>
+ </None>
+ <None Include="..\utils.js">
+ <Filter>_js files</Filter>
+ </None>
+ </ItemGroup>
+ <ItemGroup>
+ <Library Include="..\..\..\js\js32d.lib" />
+ <Library Include="..\..\..\js\js32r.lib" />
+ <Library Include="..\..\..\readline\lib\readline.lib" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\db\lasterror.h">
+ <Filter>db</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="..\..\db\db.rc">
+ <Filter>Resource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/shell/query.js b/shell/query.js
index 508fba2..ebd3a22 100644
--- a/shell/query.js
+++ b/shell/query.js
@@ -17,21 +17,27 @@ if ( typeof DBQuery == "undefined" ){
this._cursor = null;
this._numReturned = 0;
this._special = false;
+ this._prettyShell = false;
}
print( "DBQuery probably won't have array access " );
}
-DBQuery.prototype.help = function(){
- print( "DBQuery help" );
- print( "\t.sort( {...} )" )
- print( "\t.limit( n )" )
- print( "\t.skip( n )" )
- print( "\t.count() - total # of objects matching query, ignores skip,limit" )
- print( "\t.size() - total # of objects cursor would return skip,limit effect this" )
- print( "\t.explain()" )
- print( "\t.forEach( func )" )
- print( "\t.map( func )" )
-
+DBQuery.prototype.help = function () {
+ print("find() modifiers")
+ print("\t.sort( {...} )")
+ print("\t.limit( n )")
+ print("\t.skip( n )")
+ print("\t.count() - total # of objects matching query, ignores skip,limit")
+ print("\t.size() - total # of objects cursor would return, honors skip,limit")
+ print("\t.explain([verbose])")
+ print("\t.hint(...)")
+ print("\t.showDiskLoc() - adds a $diskLoc field to each returned object")
+ print("\nCursor methods");
+ print("\t.forEach( func )")
+ print("\t.print() - output to console in full pretty format")
+ print("\t.map( func )")
+ print("\t.hasNext()")
+ print("\t.next()")
}
DBQuery.prototype.clone = function(){
@@ -110,6 +116,16 @@ DBQuery.prototype.next = function(){
return ret;
}
+DBQuery.prototype.objsLeftInBatch = function(){
+ this._exec();
+
+ var ret = this._cursor.objsLeftInBatch();
+ if ( ret.$err )
+ throw "error: " + tojson( ret );
+
+ return ret;
+}
+
DBQuery.prototype.toArray = function(){
if ( this._arr )
return this._arr;
@@ -197,6 +213,10 @@ DBQuery.prototype.max = function( max ) {
return this._addSpecial( "$max" , max );
}
+DBQuery.prototype.showDiskLoc = function() {
+ return this._addSpecial( "$showDiskLoc" , true);
+}
+
DBQuery.prototype.forEach = function( func ){
while ( this.hasNext() )
func( this.next() );
@@ -213,12 +233,32 @@ DBQuery.prototype.arrayAccess = function( idx ){
return this.toArray()[idx];
}
-DBQuery.prototype.explain = function(){
+DBQuery.prototype.explain = function (verbose) {
+ /* verbose=true --> include allPlans, oldPlan fields */
var n = this.clone();
n._ensureSpecial();
n._query.$explain = true;
n._limit = n._limit * -1;
- return n.next();
+ var e = n.next();
+ if (!verbose) {
+ delete e.allPlans;
+ delete e.oldPlan;
+ if (e.shards){
+ for (var key in e.shards){
+ var s = e.shards[key];
+ if(s.length === undefined){
+ delete s.allPlans;
+ delete s.oldPlan;
+ } else {
+ for (var i=0; i < s.length; i++){
+ delete s[i].allPlans;
+ delete s[i].oldPlan;
+ }
+ }
+ }
+ }
+ }
+ return e;
}
DBQuery.prototype.snapshot = function(){
@@ -227,11 +267,16 @@ DBQuery.prototype.snapshot = function(){
return this;
}
+DBQuery.prototype.pretty = function(){
+ this._prettyShell = true;
+ return this;
+}
+
DBQuery.prototype.shellPrint = function(){
try {
var n = 0;
- while ( this.hasNext() && n < 20 ){
- var s = tojson( this.next() , "" , true );
+ while ( this.hasNext() && n < DBQuery.shellBatchSize ){
+ var s = this._prettyShell ? tojson( this.next() ) : tojson( this.next() , "" , true );
print( s );
n++;
}
@@ -252,3 +297,5 @@ DBQuery.prototype.shellPrint = function(){
DBQuery.prototype.toString = function(){
return "DBQuery: " + this._ns + " -> " + tojson( this.query );
}
+
+DBQuery.shellBatchSize = 20;
diff --git a/shell/servers.js b/shell/servers.js
index f681263..dc33de6 100644
--- a/shell/servers.js
+++ b/shell/servers.js
@@ -53,21 +53,31 @@ createMongoArgs = function( binaryName , args ){
return fullArgs;
}
-startMongodTest = function( port , dirname , restart ){
- var f = startMongod;
- if ( restart )
+__nextPort = 27000;
+startMongodTest = function (port, dirname, restart, extraOptions ) {
+ if (!port)
+ port = __nextPort++;
+ var f = startMongodEmpty;
+ if (restart)
f = startMongodNoReset;
- var conn = f.apply( null , [
- {
- port : port ,
- dbpath : "/data/db/" + dirname ,
- noprealloc : "" ,
- smallfiles : "" ,
- oplogSize : "2" ,
- nohttpinterface : ""
- }
- ]
- );
+ if (!dirname)
+ dirname = "" + port; // e.g., data/db/27000
+
+ var options =
+ {
+ port: port,
+ dbpath: "/data/db/" + dirname,
+ noprealloc: "",
+ smallfiles: "",
+ oplogSize: "2",
+ nohttpinterface: ""
+ };
+
+ if ( extraOptions )
+ Object.extend( options , extraOptions );
+
+ var conn = f.apply(null, [ options ] );
+
conn.name = "localhost:" + port;
return conn;
}
@@ -75,16 +85,18 @@ startMongodTest = function( port , dirname , restart ){
// Start a mongod instance and return a 'Mongo' object connected to it.
// This function's arguments are passed as command line arguments to mongod.
// The specified 'dbpath' is cleared if it exists, created if not.
-startMongod = function(){
+startMongodEmpty = function () {
+ var args = createMongoArgs("mongod", arguments);
- var args = createMongoArgs( "mongod" , arguments );
-
- var dbpath = _parsePath.apply( null, args );
- resetDbpath( dbpath );
+ var dbpath = _parsePath.apply(null, args);
+ resetDbpath(dbpath);
- return startMongoProgram.apply( null, args );
+ return startMongoProgram.apply(null, args);
+}
+startMongod = function () {
+ print("WARNING DELETES DATA DIRECTORY THIS IS FOR TESTING RENAME YOUR INVOCATION");
+ return startMongodEmpty.apply(null, arguments);
}
-
startMongodNoReset = function(){
var args = createMongoArgs( "mongod" , arguments );
return startMongoProgram.apply( null, args );
@@ -94,10 +106,11 @@ startMongos = function(){
return startMongoProgram.apply( null, createMongoArgs( "mongos" , arguments ) );
}
-// Start a mongo program instance (generally mongod or mongos) and return a
-// 'Mongo' object connected to it. This function's first argument is the
-// program name, and subsequent arguments to this function are passed as
-// command line arguments to the program.
+/* Start mongod or mongos and return a Mongo() object connected to there.
+ This function's first argument is "mongod" or "mongos" program name, \
+ and subsequent arguments to this function are passed as
+ command line arguments to the program.
+*/
startMongoProgram = function(){
var port = _parsePort.apply( null, arguments );
@@ -132,35 +145,69 @@ myPort = function() {
return 27017;
}
-ShardingTest = function( testName , numServers , verboseLevel , numMongos , otherParams ){
+ShardingTest = function( testName , numShards , verboseLevel , numMongos , otherParams ){
+ this._testName = testName;
+
if ( ! otherParams )
otherParams = {}
this._connections = [];
- if ( otherParams.sync && numServers < 3 )
+ if ( otherParams.sync && numShards < 3 )
throw "if you want sync, you need at least 3 servers";
- for ( var i=0; i<numServers; i++){
- var conn = startMongodTest( 30000 + i , testName + i );
- this._connections.push( conn );
- }
+ var localhost = "localhost";
+
+ this._alldbpaths = []
- if ( otherParams.sync ){
- this._configDB = "localhost:30000,localhost:30001,localhost:30002";
+
+ if ( otherParams.rs ){
+ localhost = getHostName();
+ // start replica sets
+ this._rs = []
+ for ( var i=0; i<numShards; i++){
+ var rs = new ReplSetTest( { name : testName + "-rs" + i , nodes : 3 , startPort : 31100 + ( i * 100 ) } );
+ this._rs[i] = { test : rs , nodes : rs.startSet( { oplogSize:40 } ) , url : rs.getURL() };
+ rs.initiate();
+ rs.getMaster().getDB( "admin" ).foo.save( { x : 1 } )
+ rs.awaitReplication();
+ this._connections.push( new Mongo( rs.getURL() ) );
+ }
+
+ this._configServers = []
+ for ( var i=0; i<3; i++ ){
+ var conn = startMongodTest( 30000 + i , testName + "-config" + i );
+ this._alldbpaths.push( testName + "-config" + i )
+ this._configServers.push( conn );
+ }
+
+ this._configDB = localhost + ":30000," + localhost + ":30001," + localhost + ":30002";
this._configConnection = new Mongo( this._configDB );
this._configConnection.getDB( "config" ).settings.insert( { _id : "chunksize" , value : otherParams.chunksize || 50 } );
}
else {
- this._configDB = "localhost:30000";
- this._connections[0].getDB( "config" ).settings.insert( { _id : "chunksize" , value : otherParams.chunksize || 50 } );
+ for ( var i=0; i<numShards; i++){
+ var conn = startMongodTest( 30000 + i , testName + i );
+ this._alldbpaths.push( testName +i )
+ this._connections.push( conn );
+ }
+
+ if ( otherParams.sync ){
+ this._configDB = "localhost:30000,localhost:30001,localhost:30002";
+ this._configConnection = new Mongo( this._configDB );
+ this._configConnection.getDB( "config" ).settings.insert( { _id : "chunksize" , value : otherParams.chunksize || 50 } );
+ }
+ else {
+ this._configDB = "localhost:30000";
+ this._connections[0].getDB( "config" ).settings.insert( { _id : "chunksize" , value : otherParams.chunksize || 50 } );
+ }
}
-
+
this._mongos = [];
var startMongosPort = 31000;
for ( var i=0; i<(numMongos||1); i++ ){
var myPort = startMongosPort - i;
var conn = startMongos( { port : startMongosPort - i , v : verboseLevel || 0 , configdb : this._configDB } );
- conn.name = "localhost:" + myPort;
+ conn.name = localhost + ":" + myPort;
this._mongos.push( conn );
if ( i == 0 )
this.s = conn;
@@ -169,11 +216,21 @@ ShardingTest = function( testName , numServers , verboseLevel , numMongos , othe
var admin = this.admin = this.s.getDB( "admin" );
this.config = this.s.getDB( "config" );
- this._connections.forEach(
- function(z){
- admin.runCommand( { addshard : z.name , allowLocal : true } );
- }
- );
+ if ( ! otherParams.manualAddShard ){
+ this._connections.forEach(
+ function(z){
+ var n = z.name;
+ if ( ! n ){
+ n = z.host;
+ if ( ! n )
+ n = z;
+ }
+ print( "going to add shard: " + n )
+ x = admin.runCommand( { addshard : n } );
+ printjson( x )
+ }
+ );
+ }
}
ShardingTest.prototype.getDB = function( name ){
@@ -181,24 +238,64 @@ ShardingTest.prototype.getDB = function( name ){
}
ShardingTest.prototype.getServerName = function( dbname ){
- return this.config.databases.findOne( { name : dbname } ).primary;
+ var x = this.config.databases.findOne( { _id : dbname } );
+ if ( x )
+ return x.primary;
+ this.config.databases.find().forEach( printjson );
+ throw "couldn't find dbname: " + dbname + " total: " + this.config.databases.count();
+}
+
+
+ShardingTest.prototype.getNonPrimaries = function( dbname ){
+ var x = this.config.databases.findOne( { _id : dbname } );
+ if ( ! x ){
+ this.config.databases.find().forEach( printjson );
+ throw "couldn't find dbname: " + dbname + " total: " + this.config.databases.count();
+ }
+
+ return this.config.shards.find( { _id : { $ne : x.primary } } ).map( function(z){ return z._id; } )
+}
+
+
+ShardingTest.prototype.getConnNames = function(){
+ var names = [];
+ for ( var i=0; i<this._connections.length; i++ ){
+ names.push( this._connections[i].name );
+ }
+ return names;
}
ShardingTest.prototype.getServer = function( dbname ){
var name = this.getServerName( dbname );
+
+ var x = this.config.shards.findOne( { _id : name } );
+ if ( x )
+ name = x.host;
+
for ( var i=0; i<this._connections.length; i++ ){
var c = this._connections[i];
if ( name == c.name )
return c;
}
+
throw "can't find server for: " + dbname + " name:" + name;
}
+ShardingTest.prototype.normalize = function( x ){
+ var z = this.config.shards.findOne( { host : x } );
+ if ( z )
+ return z._id;
+ return x;
+}
+
ShardingTest.prototype.getOther = function( one ){
if ( this._connections.length != 2 )
throw "getOther only works with 2 servers";
+ if ( one._mongo )
+ one = one._mongo
+
if ( this._connections[0] == one )
return this._connections[1];
return this._connections[0];
@@ -219,6 +316,18 @@ ShardingTest.prototype.stop = function(){
for ( var i=0; i<this._connections.length; i++){
stopMongod( 30000 + i );
}
+ if ( this._rs ){
+ for ( var i=0; i<this._rs.length; i++ ){
+ this._rs[i].test.stopSet( 15 );
+ }
+ }
+ if ( this._alldbpaths ){
+ for( i=0; i<this._alldbpaths.length; i++ ){
+ resetDbpath( "/data/db/" + this._alldbpaths[i] );
+ }
+ }
+
+ print('*** ' + this._testName + " completed successfully ***");
}
ShardingTest.prototype.adminCommand = function(cmd){
@@ -229,11 +338,47 @@ ShardingTest.prototype.adminCommand = function(cmd){
throw "command " + tojson( cmd ) + " failed: " + tojson( res );
}
+ShardingTest.prototype._rangeToString = function(r){
+ return tojsononeline( r.min ) + " -> " + tojsononeline( r.max );
+}
+
+ShardingTest.prototype.printChangeLog = function(){
+ var s = this;
+ this.config.changelog.find().forEach(
+ function(z){
+ var msg = z.server + "\t" + z.time + "\t" + z.what;
+ for ( i=z.what.length; i<15; i++ )
+ msg += " ";
+ msg += " " + z.ns + "\t";
+ if ( z.what == "split" ){
+ msg += s._rangeToString( z.details.before ) + " -->> (" + s._rangeToString( z.details.left ) + "),(" + s._rangeToString( z.details.right ) + ")";
+ }
+ else if (z.what == "multi-split" ){
+ msg += s._rangeToString( z.details.before ) + " -->> (" + z.details.number + "/" + z.details.of + " " + s._rangeToString( z.details.chunk ) + ")";
+ }
+ else {
+ msg += tojsononeline( z.details );
+ }
+
+ print( msg )
+ }
+ );
+
+}
+
ShardingTest.prototype.getChunksString = function( ns ){
var q = {}
if ( ns )
q.ns = ns;
- return Array.tojson( this.config.chunks.find( q ).toArray() , "\n" );
+
+ var s = "";
+ this.config.chunks.find( q ).sort( { ns : 1 , min : 1 } ).forEach(
+ function(z){
+ s += " " + z._id + "\t" + z.lastmod.t + "|" + z.lastmod.i + "\t" + tojson(z.min) + " -> " + tojson(z.max) + " " + z.shard + " " + z.ns + "\n";
+ }
+ );
+
+ return s;
}
ShardingTest.prototype.printChunks = function( ns ){
@@ -258,10 +403,14 @@ ShardingTest.prototype.printCollectionInfo = function( ns , msg ){
out += " mongos " + c + " " + tojson( c.getCollection( ns ).getShardVersion() , " " , true ) + "\n";
}
+ out += this.getChunksString( ns );
+
print( out );
}
printShardingStatus = function( configDB ){
+ if (configDB === undefined)
+ configDB = db.getSisterDB('config')
var version = configDB.getCollection( "version" ).findOne();
if ( version == null ){
@@ -285,17 +434,81 @@ printShardingStatus = function( configDB ){
output( " databases:" );
configDB.databases.find().sort( { name : 1 } ).forEach(
+ function(db){
+ output( "\t" + tojson(db,"",true) );
+
+ if (db.partitioned){
+ configDB.collections.find( { _id : new RegExp( "^" + db._id + "\." ) } ).sort( { _id : 1 } ).forEach(
+ function( coll ){
+ output("\t\t" + coll._id + " chunks:");
+ configDB.chunks.find( { "ns" : coll._id } ).sort( { min : 1 } ).forEach(
+ function(chunk){
+ output( "\t\t\t" + tojson( chunk.min ) + " -->> " + tojson( chunk.max ) +
+ " on : " + chunk.shard + " " + tojson( chunk.lastmod ) );
+ }
+ );
+ }
+ )
+ }
+ }
+ );
+
+ print( raw );
+}
+
+printShardingSizes = function(){
+ configDB = db.getSisterDB('config')
+
+ var version = configDB.getCollection( "version" ).findOne();
+ if ( version == null ){
+ print( "not a shard db!" );
+ return;
+ }
+
+ var raw = "";
+ var output = function(s){
+ raw += s + "\n";
+ }
+ output( "--- Sharding Status --- " );
+ output( " sharding version: " + tojson( configDB.getCollection( "version" ).findOne() ) );
+
+ output( " shards:" );
+ var shards = {};
+ configDB.shards.find().forEach(
function(z){
- output( "\t" + tojson(z,"",true) );
+ shards[z._id] = new Mongo(z.host);
+ output( " " + tojson(z) );
+ }
+ );
+
+ var saveDB = db;
+ output( " databases:" );
+ configDB.databases.find().sort( { name : 1 } ).forEach(
+ function(db){
+ output( "\t" + tojson(db,"",true) );
- output( "\t\tmy chunks" );
-
- configDB.chunks.find( { "ns" : new RegExp( "^" + z.name ) } ).sort( { ns : 1 } ).forEach(
- function(z){
- output( "\t\t\t" + z.ns + " " + tojson( z.min ) + " -->> " + tojson( z.max ) +
- " on : " + z.shard + " " + tojson( z.lastmod ) );
- }
- );
+ if (db.partitioned){
+ configDB.collections.find( { _id : new RegExp( "^" + db._id + "\." ) } ).sort( { _id : 1 } ).forEach(
+ function( coll ){
+ output("\t\t" + coll._id + " chunks:");
+ configDB.chunks.find( { "ns" : coll._id } ).sort( { min : 1 } ).forEach(
+ function(chunk){
+ var mydb = shards[chunk.shard].getDB(db._id)
+ var out = mydb.runCommand({dataSize: coll._id,
+ keyPattern: coll.key,
+ min: chunk.min,
+ max: chunk.max });
+ delete out.millis;
+ delete out.ok;
+
+ output( "\t\t\t" + tojson( chunk.min ) + " -->> " + tojson( chunk.max ) +
+ " on : " + chunk.shard + " " + tojson( out ) );
+
+ }
+ );
+ }
+ )
+ }
}
);
@@ -316,6 +529,38 @@ ShardingTest.prototype.onNumShards = function( collName , dbName ){
return num;
}
+
+ShardingTest.prototype.shardCounts = function( collName , dbName ){
+ this.sync(); // we should sync since we're going directly to mongod here
+ dbName = dbName || "test";
+ var counts = {}
+ for ( var i=0; i<this._connections.length; i++ )
+ counts[i] = this._connections[i].getDB( dbName ).getCollection( collName ).count();
+ return counts;
+}
+
+ShardingTest.prototype.chunkCounts = function( collName , dbName ){
+ dbName = dbName || "test";
+ var x = {}
+
+ s.config.shards.find().forEach(
+ function(z){
+ x[z._id] = 0;
+ }
+ );
+
+ s.config.chunks.find( { ns : dbName + "." + collName } ).forEach(
+ function(z){
+ if ( x[z.shard] )
+ x[z.shard]++
+ else
+ x[z.shard] = 1;
+ }
+ );
+ return x;
+
+}
+
ShardingTest.prototype.shardGo = function( collName , key , split , move , dbName ){
split = split || key;
move = move || split;
@@ -375,6 +620,7 @@ MongodRunner.prototype.port = function() { return this.port_; }
MongodRunner.prototype.toString = function() { return [ this.port_, this.dbpath_, this.peer_, this.arbiter_ ].toString(); }
+
ReplPair = function( left, right, arbiter ) {
this.left_ = left;
this.leftC_ = null;
@@ -474,7 +720,7 @@ ReplPair.prototype.waitForSteadyState = function( state, expectedMasterHost, two
var leftValues = {};
var rightValues = {};
assert.soon( function() { return rp.checkSteadyState( state, expectedMasterHost, twoMasterOk, leftValues, rightValues, debug ); },
- "rp (" + rp + ") failed to reach expected steady state (" + state + ")" );
+ "rp (" + rp + ") failed to reach expected steady state (" + state + ")" , 60000 );
}
ReplPair.prototype.master = function() { return this.master_; }
@@ -522,7 +768,6 @@ ReplPair.prototype.toString = function() {
return ret;
}
-
ToolTest = function( name ){
this.name = name;
this.port = allocatePorts(1)[0];
@@ -550,6 +795,8 @@ ToolTest.prototype.stop = function(){
stopMongod( this.port );
this.m = null;
this.db = null;
+
+ print('*** ' + this.name + " completed successfully ***");
}
ToolTest.prototype.runTool = function(){
@@ -592,7 +839,6 @@ ReplTest.prototype.getPath = function( master ){
return p;
}
-
ReplTest.prototype.getOptions = function( master , extra , putBinaryFirst, norepl ){
if ( ! extra )
@@ -638,6 +884,8 @@ ReplTest.prototype.start = function( master , options , restart, norepl ){
var lockFile = this.getPath( master ) + "/mongod.lock";
removeFile( lockFile );
var o = this.getOptions( master , options , restart, norepl );
+
+
if ( restart )
return startMongoProgram.apply( null , o );
else
@@ -650,23 +898,26 @@ ReplTest.prototype.stop = function( master , signal ){
this.stop( false );
return;
}
+
+ print('*** ' + this.name + " completed successfully ***");
return stopMongod( this.getPort( master ) , signal || 15 );
}
-allocatePorts = function( n ) {
+allocatePorts = function( n , startPort ) {
var ret = [];
- for( var i = 31000; i < 31000 + n; ++i )
+ var start = startPort || 31000;
+ for( var i = start; i < start + n; ++i )
ret.push( i );
return ret;
}
-SyncCCTest = function( testName ){
+SyncCCTest = function( testName , extraMongodOptions ){
this._testName = testName;
this._connections = [];
for ( var i=0; i<3; i++ ){
- this._connections.push( startMongodTest( 30000 + i , testName + i ) );
+ this._connections.push( startMongodTest( 30000 + i , testName + i , false, extraMongodOptions ) );
}
this.url = this._connections.map( function(z){ return z.name; } ).join( "," );
@@ -677,6 +928,8 @@ SyncCCTest.prototype.stop = function(){
for ( var i=0; i<this._connections.length; i++){
stopMongod( 30000 + i );
}
+
+ print('*** ' + this._testName + " completed successfully ***");
}
SyncCCTest.prototype.checkHashes = function( dbname , msg ){
@@ -700,3 +953,404 @@ SyncCCTest.prototype.tempStart = function( num ){
num = num || 0;
this._connections[num] = startMongodTest( 30000 + num , this._testName + num , true );
}
+
+
+function startParallelShell( jsCode ){
+ var x = startMongoProgramNoConnect( "mongo" , "--eval" , jsCode , db ? db.getMongo().host : null );
+ return function(){
+ waitProgram( x );
+ };
+}
+
+var testingReplication = false;
+
+function skipIfTestingReplication(){
+ if (testingReplication) {
+ print( "skipping" );
+ quit(0);
+ }
+}
+
+// ReplSetTest
+ReplSetTest = function( opts ){
+ this.name = opts.name || "testReplSet";
+ this.host = opts.host || getHostName();
+ this.numNodes = opts.nodes || 0;
+ this.useSeedList = opts.useSeedList || false;
+
+ this.bridged = opts.bridged || false;
+ this.ports = [];
+
+ this.startPort = opts.startPort || 31000;
+
+ if(this.bridged) {
+ this.bridgePorts = [];
+
+ var allPorts = allocatePorts( this.numNodes * 2 , this.startPort );
+ for(var i=0; i < this.numNodes; i++) {
+ this.ports[i] = allPorts[i*2];
+ this.bridgePorts[i] = allPorts[i*2 + 1];
+ }
+
+ this.initBridges();
+ }
+ else {
+ this.ports = allocatePorts( this.numNodes , this.startPort );
+ }
+
+ this.nodes = [];
+ this.nodeIds = {};
+ this.initLiveNodes();
+}
+
+ReplSetTest.prototype.initBridges = function() {
+ for(var i=0; i<this.ports.length; i++) {
+ startMongoProgram( "mongobridge", "--port", this.bridgePorts[i], "--dest", this.host + ":" + this.ports[i] );
+ }
+}
+
+// List of nodes as host:port strings.
+ReplSetTest.prototype.nodeList = function() {
+ var list = [];
+ for(var i=0; i<this.ports.length; i++) {
+ list.push( this.host + ":" + this.ports[i]);
+ }
+
+ return list;
+}
+
+// Here we store a reference to all reachable nodes.
+ReplSetTest.prototype.initLiveNodes = function(){
+ this.liveNodes = {master: null, slaves: []};
+ this.nodeIds = {};
+}
+
+ReplSetTest.prototype.getNodeId = function(node) {
+ return this.nodeIds[node];
+}
+
+ReplSetTest.prototype.getPort = function( n ){
+ return this.ports[ n ];
+}
+
+ReplSetTest.prototype.getPath = function( n ){
+ var p = "/data/db/" + this.name + "-";
+ p += n.toString();
+ if ( ! this._alldbpaths )
+ this._alldbpaths = [ p ];
+ else
+ this._alldbpaths.push( p );
+ return p;
+}
+
+ReplSetTest.prototype.getReplSetConfig = function() {
+ var cfg = {};
+
+ cfg['_id'] = this.name;
+ cfg.members = [];
+
+ for(i=0; i<this.ports.length; i++) {
+ member = {};
+ member['_id'] = i;
+
+ if(this.bridged)
+ var port = this.bridgePorts[i];
+ else
+ var port = this.ports[i];
+
+ member['host'] = this.host + ":" + port;
+ cfg.members.push(member);
+ }
+
+ return cfg;
+}
+
+ReplSetTest.prototype.getURL = function(){
+ var hosts = [];
+
+ for(i=0; i<this.ports.length; i++) {
+
+ // Don't include this node in the replica set list
+ if(this.bridged && this.ports[i] == this.ports[n]) {
+ continue;
+ }
+
+ var port;
+ // Connect on the right port
+ if(this.bridged) {
+ port = this.bridgePorts[i];
+ }
+ else {
+ port = this.ports[i];
+ }
+
+ var str = this.host + ":" + port;
+ hosts.push(str);
+ }
+
+ return this.name + "/" + hosts.join(",");
+}
+
+ReplSetTest.prototype.getOptions = function( n , extra , putBinaryFirst ){
+
+ if ( ! extra )
+ extra = {};
+
+ if ( ! extra.oplogSize )
+ extra.oplogSize = "2";
+
+ var a = []
+
+
+ if ( putBinaryFirst )
+ a.push( "mongod" )
+
+ a.push( "--replSet" );
+
+
+ a.push( this.getURL() )
+
+ a.push( "--noprealloc", "--smallfiles" );
+
+ a.push( "--rest" );
+
+ a.push( "--port" );
+ a.push( this.getPort( n ) );
+
+ a.push( "--dbpath" );
+ a.push( this.getPath( n ) );
+
+ for ( var k in extra ){
+ var v = extra[k];
+ a.push( "--" + k );
+ if ( v != null )
+ a.push( v );
+ }
+
+ return a;
+}
+
+ReplSetTest.prototype.startSet = function(options) {
+ var nodes = [];
+ print( "Starting Set" );
+
+ for(n=0; n<this.ports.length; n++) {
+ node = this.start(n, options);
+ nodes.push(node);
+ }
+
+ this.nodes = nodes;
+ return this.nodes;
+}
+
+ReplSetTest.prototype.callIsMaster = function() {
+ var master = null;
+ this.initLiveNodes();
+ for(var i=0; i<this.nodes.length; i++) {
+
+ try {
+ var n = this.nodes[i].getDB('admin').runCommand({ismaster:1});
+
+ if(n['ismaster'] == true) {
+ master = this.nodes[i];
+ this.liveNodes.master = master;
+ this.nodeIds[master] = i;
+ }
+ else {
+ this.nodes[i].setSlaveOk();
+ this.liveNodes.slaves.push(this.nodes[i]);
+ this.nodeIds[this.nodes[i]] = i;
+ }
+
+ }
+ catch(err) {
+ print("Could not call ismaster on node " + i);
+ }
+ }
+
+ return master || false;
+}
+
+ReplSetTest.prototype.getMaster = function( timeout ) {
+ var tries = 0;
+ var sleepTime = 500;
+ var t = timeout || 000;
+ var master = null;
+
+ master = this.attempt({context: this, timeout: 60000, desc: "Finding master"}, this.callIsMaster);
+ return master;
+}
+
+// Add a node to the test set
+ReplSetTest.prototype.add = function( config ) {
+ if(this.ports.length == 0) {
+ var nextPort = allocatePorts( 1, this.startPort )[0];
+ }
+ else {
+ var nextPort = this.ports[this.ports.length-1] + 1;
+ }
+ print("Next port: " + nextPort);
+ this.ports.push(nextPort);
+ printjson(this.ports);
+
+ var nextId = this.nodes.length;
+ printjson(this.nodes);
+ print(nextId);
+ var newNode = this.start(nextId);
+ this.nodes.push(newNode);
+
+ return newNode;
+}
+
+ReplSetTest.prototype.remove = function( nodeId ) {
+ this.nodes.splice( nodeId, 1 );
+ this.ports.splice( nodeId, 1 );
+}
+
+// Pass this method a function to call repeatedly until
+// that function returns true. Example:
+// attempt({timeout: 20000, desc: "get master"}, function() { // return false until success })
+ReplSetTest.prototype.attempt = function( opts, func ) {
+ var timeout = opts.timeout || 1000;
+ var tries = 0;
+ var sleepTime = 500;
+ var result = null;
+ var context = opts.context || this;
+
+ while((result = func.apply(context)) == false) {
+ tries += 1;
+ sleep(sleepTime);
+ if( tries * sleepTime > timeout) {
+ throw('[' + opts['desc'] + ']' + " timed out");
+ }
+ }
+
+ return result;
+}
+
+ReplSetTest.prototype.initiate = function( cfg , initCmd , timeout ) {
+ var master = this.nodes[0].getDB("admin");
+ var config = cfg || this.getReplSetConfig();
+ var cmd = {};
+ var cmdKey = initCmd || 'replSetInitiate';
+ var timeout = timeout || 30000;
+ cmd[cmdKey] = config;
+ printjson(cmd);
+
+ this.attempt({timeout: timeout, desc: "Initiate replica set"}, function() {
+ var result = master.runCommand(cmd);
+ printjson(result);
+ return result['ok'] == 1;
+ });
+}
+
+ReplSetTest.prototype.reInitiate = function() {
+ var master = this.nodes[0];
+ var c = master.getDB("local")['system.replset'].findOne();
+ var config = this.getReplSetConfig();
+ config.version = c.version + 1;
+ this.initiate( config , 'replSetReconfig' );
+}
+
+ReplSetTest.prototype.awaitReplication = function() {
+ this.getMaster();
+
+ latest = this.liveNodes.master.getDB("local")['oplog.rs'].find({}).sort({'$natural': -1}).limit(1).next()['ts']
+ print(latest);
+
+ this.attempt({context: this, timeout: 30000, desc: "awaiting replication"},
+ function() {
+ var synced = true;
+ for(var i=0; i<this.liveNodes.slaves.length; i++) {
+ var slave = this.liveNodes.slaves[i];
+
+ // Continue if we're connected to an arbiter
+ if(res = slave.getDB("admin").runCommand({replSetGetStatus: 1})) {
+ if(res.myState == 7) {
+ continue;
+ }
+ }
+
+ slave.getDB("admin").getMongo().setSlaveOk();
+ var log = slave.getDB("local")['oplog.rs'];
+ if(log.find({}).sort({'$natural': -1}).limit(1).hasNext()) {
+ var entry = log.find({}).sort({'$natural': -1}).limit(1).next();
+ printjson( entry );
+ var ts = entry['ts'];
+ print("TS for " + slave + " is " + ts + " and latest is " + latest);
+ print("Oplog size for " + slave + " is " + log.count());
+ synced = (synced && friendlyEqual(latest,ts))
+ }
+ else {
+ synced = false;
+ }
+ }
+
+ if(synced) {
+ print("Synced = " + synced);
+ }
+ return synced;
+ });
+}
+
+ReplSetTest.prototype.getHashes = function( db ){
+ this.getMaster();
+ var res = {};
+ res.master = this.liveNodes.master.getDB( db ).runCommand( "dbhash" )
+ res.slaves = this.liveNodes.slaves.map( function(z){ return z.getDB( db ).runCommand( "dbhash" ); } )
+ return res;
+}
+
+/**
+ * Starts up a server.
+ *
+ * @param {int} n server number (0, 1, 2, ...)
+ * @param {object} [options]
+ * @param {boolean} [restart] If false, the data directory will be cleared
+ * before the server starts. Defaults to false.
+ */
+ReplSetTest.prototype.start = function( n , options , restart ){
+ var lockFile = this.getPath( n ) + "/mongod.lock";
+ removeFile( lockFile );
+ var o = this.getOptions( n , options , restart );
+
+ print("Starting....");
+ print( o );
+ if ( restart ) {
+ this.nodes[n] = startMongoProgram.apply( null , o );
+ printjson(this.nodes);
+ return this.nodes[n];
+ }
+ else {
+ return startMongod.apply( null , o );
+ }
+}
+
+/**
+ * Restarts a db without clearing the data directory. If the server is not
+ * stopped first, this function will not work.
+ *
+ * @param {int} n server number (0, 1, 2, ...)
+ */
+ReplSetTest.prototype.restart = function( n , options ){
+ return this.start( n , options , true );
+}
+
+ReplSetTest.prototype.stop = function( n , signal ){
+ var port = this.getPort( n );
+ print('*** Shutting down mongod in port ' + port + ' ***');
+ return stopMongod( port , signal || 15 );
+}
+
+ReplSetTest.prototype.stopSet = function( signal , forRestart ) {
+ for(i=0; i < this.ports.length; i++) {
+ this.stop( i, signal );
+ }
+ if ( ! forRestart && this._alldbpaths ){
+ for( i=0; i<this._alldbpaths.length; i++ ){
+ resetDbpath( this._alldbpaths[i] );
+ }
+ }
+
+ print('*** Shut down repl set - test worked ****' )
+}
diff --git a/shell/utils.cpp b/shell/shell_utils.cpp
index b10c93d..e968d73 100644
--- a/shell/utils.cpp
+++ b/shell/shell_utils.cpp
@@ -15,8 +15,7 @@
* limitations under the License.
*/
-
-#include "../stdafx.h"
+#include "pch.h"
#include <boost/thread/xtime.hpp>
@@ -44,6 +43,8 @@
#include "../client/dbclient.h"
#include "../util/processinfo.h"
#include "utils.h"
+#include "../util/text.h"
+#include "../util/md5.hpp"
extern const char * jsconcatcode_server;
@@ -51,11 +52,12 @@ namespace mongo {
#ifdef _WIN32
inline int close(int fd) { return _close(fd); }
inline int read(int fd, void* buf, size_t size) { return _read(fd, buf, size); }
-
- inline int pipe(int fds[2]) { return _pipe(fds, 1024, _O_TEXT | _O_NOINHERIT); }
+ inline int pipe(int fds[2]) { return _pipe(fds, 4096, _O_TEXT | _O_NOINHERIT); }
#endif
namespace shellUtils {
+
+ Scope* theScope = 0;
std::string _dbConnect;
std::string _dbAuth;
@@ -75,38 +77,25 @@ namespace mongo {
BSONObj encapsulate( const BSONObj &obj ) {
return BSON( "" << obj );
}
-
- void sleepms( int ms ) {
- boost::xtime xt;
- boost::xtime_get(&xt, boost::TIME_UTC);
- xt.sec += ( ms / 1000 );
- xt.nsec += ( ms % 1000 ) * 1000000;
- if ( xt.nsec >= 1000000000 ) {
- xt.nsec -= 1000000000;
- xt.sec++;
- }
- boost::thread::sleep(xt);
- }
// real methods
-
-
mongo::BSONObj JSSleep(const mongo::BSONObj &args){
assert( args.nFields() == 1 );
assert( args.firstElement().isNumber() );
int ms = int( args.firstElement().number() );
{
auto_ptr< ScriptEngine::Unlocker > u = globalScriptEngine->newThreadUnlocker();
- sleepms( ms );
+ sleepmillis( ms );
}
return undefined_;
}
-
+ void goingAwaySoon();
BSONObj Quit(const BSONObj& args) {
// If not arguments are given first element will be EOO, which
// converts to the integer value 0.
+ goingAwaySoon();
int exit_code = int( args.firstElement().number() );
::exit(exit_code);
return undefined_;
@@ -129,7 +118,10 @@ namespace mongo {
#ifndef MONGO_SAFE_SHELL
- BSONObj listFiles(const BSONObj& args){
+ BSONObj listFiles(const BSONObj& _args){
+ static BSONObj cd = BSON( "0" << "." );
+ BSONObj args = _args.isEmpty() ? cd : _args;
+
uassert( 10257 , "need to specify 1 argument to listFiles" , args.nFields() == 1 );
BSONObjBuilder lst;
@@ -163,7 +155,7 @@ namespace mongo {
stringstream ss;
ss << num;
string name = ss.str();
- lst.append( name.c_str(), b.done() );
+ lst.append( name, b.done() );
num++;
i++;
}
@@ -173,10 +165,98 @@ namespace mongo {
return ret.obj();
}
+ BSONObj ls(const BSONObj& args) {
+ BSONObj o = listFiles(args);
+ if( !o.isEmpty() ) {
+ for( BSONObj::iterator i = o.firstElement().Obj().begin(); i.more(); ) {
+ BSONObj f = i.next().Obj();
+ cout << f["name"].String();
+ if( f["isDirectory"].trueValue() ) cout << '/';
+ cout << '\n';
+ }
+ cout.flush();
+ }
+ return BSONObj();
+ }
+
+ BSONObj cd(const BSONObj& args) {
+#if defined(_WIN32)
+ std::wstring dir = toWideString( args.firstElement().String().c_str() );
+ if( SetCurrentDirectory(dir.c_str()) )
+ return BSONObj();
+#else
+ string dir = args.firstElement().String();
+/* if( chdir(dir.c_str) ) == 0 )
+ return BSONObj();
+ */
+ if( 1 ) return BSON(""<<"implementation not done for posix");
+#endif
+ return BSON( "" << "change directory failed" );
+ }
+
+ BSONObj pwd(const BSONObj&) {
+ boost::filesystem::path p = boost::filesystem::current_path();
+ return BSON( "" << p.string() );
+ }
+
+ BSONObj hostname(const BSONObj&) {
+ return BSON( "" << getHostName() );
+ }
+
+ static BSONElement oneArg(const BSONObj& args) {
+ uassert( 12597 , "need to specify 1 argument" , args.nFields() == 1 );
+ return args.firstElement();
+ }
+
+ const int CANT_OPEN_FILE = 13300;
+
+ BSONObj cat(const BSONObj& args){
+ BSONElement e = oneArg(args);
+ stringstream ss;
+ ifstream f(e.valuestrsafe());
+ uassert(CANT_OPEN_FILE, "couldn't open file", f.is_open() );
+
+ streamsize sz = 0;
+ while( 1 ) {
+ char ch = 0;
+ // slow...maybe change one day
+ f.get(ch);
+ if( ch == 0 ) break;
+ ss << ch;
+ sz += 1;
+ uassert(13301, "cat() : file to big to load as a variable", sz < 1024 * 1024 * 16);
+ }
+ return BSON( "" << ss.str() );
+ }
+
+ BSONObj md5sumFile(const BSONObj& args){
+ BSONElement e = oneArg(args);
+ stringstream ss;
+ FILE* f = fopen(e.valuestrsafe(), "rb");
+ uassert(CANT_OPEN_FILE, "couldn't open file", f );
+
+ md5digest d;
+ md5_state_t st;
+ md5_init(&st);
+
+ enum {BUFLEN = 4*1024};
+ char buffer[BUFLEN];
+ int bytes_read;
+ while( (bytes_read = fread(buffer, 1, BUFLEN, f)) ) {
+ md5_append( &st , (const md5_byte_t*)(buffer) , bytes_read );
+ }
+
+ md5_finish(&st, d);
+ return BSON( "" << digestToString( d ) );
+ }
+
+ BSONObj mkdir(const BSONObj& args){
+ boost::filesystem::create_directories(args.firstElement().String());
+ return BSON( "" << true );
+ }
BSONObj removeFile(const BSONObj& args){
- uassert( 12597 , "need to specify 1 argument to listFiles" , args.nFields() == 1 );
-
+ BSONElement e = oneArg(args);
bool found = false;
path root( args.firstElement().valuestrsafe() );
@@ -195,11 +275,17 @@ namespace mongo {
map< pid_t, HANDLE > handles;
#endif
- mongo::mutex mongoProgramOutputMutex;
+ mongo::mutex mongoProgramOutputMutex("mongoProgramOutputMutex");
stringstream mongoProgramOutput_;
+ void goingAwaySoon() {
+ mongo::mutex::scoped_lock lk( mongoProgramOutputMutex );
+ mongo::goingAway = true;
+ }
+
void writeMongoProgramOutputLine( int port, int pid, const char *line ) {
mongo::mutex::scoped_lock lk( mongoProgramOutputMutex );
+ if( mongo::goingAway ) throw "program is terminating";
stringstream buf;
if ( port > 0 )
buf << "m" << port << "| " << line;
@@ -232,20 +318,60 @@ namespace mongo {
pid_t pid_;
public:
pid_t pid() const { return pid_; }
+ int port() const { return port_; }
+
+ boost::filesystem::path find(string prog) {
+ boost::filesystem::path p = prog;
+#ifdef _WIN32
+ p = change_extension(p, ".exe");
+#endif
+
+ if( boost::filesystem::exists(p) ){
+#ifndef _WIN32
+ p = boost::filesystem::initial_path() / p;
+#endif
+ return p;
+ }
+
+ {
+ boost::filesystem::path t = boost::filesystem::current_path() / p;
+ if( boost::filesystem::exists(t) ) return t;
+ }
+ try {
+ if( theScope->type("_path") == String ) {
+ string path = theScope->getString("_path");
+ if( !path.empty() ) {
+ boost::filesystem::path t = boost::filesystem::path(path) / p;
+ if( boost::filesystem::exists(t) ) return t;
+ }
+ }
+ } catch(...) { }
+ {
+ boost::filesystem::path t = boost::filesystem::initial_path() / p;
+ if( boost::filesystem::exists(t) ) return t;
+ }
+ return p; // not found; might find via system path
+ }
+
ProgramRunner( const BSONObj &args , bool isMongoProgram=true)
{
assert( !args.isEmpty() );
string program( args.firstElement().valuestrsafe() );
assert( !program.empty() );
- boost::filesystem::path programPath = program;
+ boost::filesystem::path programPath = find(program);
if (isMongoProgram){
- programPath = boost::filesystem::initial_path() / programPath;
-#ifdef _WIN32
- programPath = change_extension(programPath, ".exe");
+#if 0
+ if (program == "mongos") {
+ argv_.push_back("valgrind");
+ argv_.push_back("--log-file=/tmp/mongos-%p.valgrind");
+ argv_.push_back("--leak-check=yes");
+ argv_.push_back("--suppressions=valgrind.suppressions");
+ //argv_.push_back("--error-exitcode=1");
+ argv_.push_back("--");
+ }
#endif
- massert( 10435 , "couldn't find " + programPath.native_file_string(), boost::filesystem::exists( programPath ) );
}
argv_.push_back( programPath.native_file_string() );
@@ -274,8 +400,11 @@ namespace mongo {
if ( program != "mongod" && program != "mongos" && program != "mongobridge" )
port_ = 0;
- else
+ else {
+ if ( port_ <= 0 )
+ cout << "error: a port number is expected when running mongod (etc.) from the shell" << endl;
assert( port_ > 0 );
+ }
if ( port_ > 0 && dbs.count( port_ ) != 0 ){
cerr << "count for port: " << port_ << " is not 0 is: " << dbs.count( port_ ) << endl;
assert( dbs.count( port_ ) == 0 );
@@ -289,10 +418,14 @@ namespace mongo {
fflush( 0 );
launch_process(pipeEnds[1]); //sets pid_
- cout << "shell: started mongo program";
- for (unsigned i=0; i < argv_.size(); i++)
- cout << " " << argv_[i];
- cout << endl;
+ {
+ stringstream ss;
+ ss << "shell: started program";
+ for (unsigned i=0; i < argv_.size(); i++)
+ ss << " " << argv_[i];
+ ss << '\n';
+ cout << ss.str(); cout.flush();
+ }
if ( port_ > 0 )
dbs.insert( make_pair( port_, make_pair( pid_, pipeEnds[ 1 ] ) ) );
@@ -303,14 +436,19 @@ namespace mongo {
// Continue reading output
void operator()() {
+ try {
// This assumes there aren't any 0's in the mongo program output.
// Hope that's ok.
- char buf[ 1024 ];
- char temp[ 1024 ];
+ const unsigned bufSize = 8192;
+ char buf[ bufSize ];
+ char temp[ bufSize ];
char *start = buf;
while( 1 ) {
- int lenToRead = 1023 - ( start - buf );
+ int lenToRead = ( bufSize - 1 ) - ( start - buf );
+ assert( lenToRead > 0 );
int ret = read( pipe_, (void *)start, lenToRead );
+ if( mongo::goingAway )
+ break;
assert( ret != -1 );
start[ ret ] = '\0';
if ( strlen( start ) != unsigned( ret ) )
@@ -330,15 +468,17 @@ namespace mongo {
strcpy( temp, last );
strcpy( buf, temp );
} else {
- assert( strlen( buf ) <= 1023 );
+ assert( strlen( buf ) < bufSize );
}
start = buf + strlen( buf );
- }
+ }
+ } catch(...) {
+ }
}
void launch_process(int child_stdout){
#ifdef _WIN32
stringstream ss;
- for (int i=0; i < argv_.size(); i++){
+ for( unsigned i=0; i < argv_.size(); i++ ){
if (i) ss << ' ';
if (argv_[i].find(' ') == string::npos)
ss << argv_[i];
@@ -349,8 +489,10 @@ namespace mongo {
string args = ss.str();
boost::scoped_array<TCHAR> args_tchar (new TCHAR[args.size() + 1]);
- for (size_t i=0; i < args.size()+1; i++)
+ size_t i;
+ for(i=0; i < args.size(); i++)
args_tchar[i] = args[i];
+ args_tchar[i] = 0;
HANDLE h = (HANDLE)_get_osfhandle(child_stdout);
assert(h != INVALID_HANDLE_VALUE);
@@ -366,14 +508,18 @@ namespace mongo {
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
- bool success = CreateProcess( NULL, args_tchar.get(), NULL, NULL, true, 0, NULL, NULL, &si, &pi);
- assert(success);
+ bool success = CreateProcess( NULL, args_tchar.get(), NULL, NULL, true, 0, NULL, NULL, &si, &pi) != 0;
+ {
+ stringstream ss;
+ ss << "couldn't start process " << argv_[0];
+ uassert(13294, ss.str(), success);
+ }
CloseHandle(pi.hThread);
pid_ = pi.dwProcessId;
handles.insert( make_pair( pid_, pi.hProcess ) );
-
+
#else
pid_ = fork();
@@ -391,13 +537,13 @@ namespace mongo {
if ( dup2( child_stdout, STDOUT_FILENO ) == -1 ||
dup2( child_stdout, STDERR_FILENO ) == -1 )
{
- cout << "Unable to dup2 child output: " << OUTPUT_ERRNO << endl;
+ cout << "Unable to dup2 child output: " << errnoWithDescription() << endl;
::_Exit(-1); //do not pass go, do not call atexit handlers
}
execvp( argv[ 0 ], const_cast<char**>(argv) );
- cout << "Unable to start program: " << OUTPUT_ERRNO << endl;
+ cout << "Unable to start program " << argv[0] << ' ' << errnoWithDescription() << endl;
::_Exit(-1);
}
@@ -433,6 +579,14 @@ namespace mongo {
#endif
}
+
+ BSONObj WaitProgram( const BSONObj& a ){
+ int pid = a.firstElement().numberInt();
+ BSONObj x = BSON( "" << wait_for_pid( pid ) );
+ shells.erase( pid );
+ return x;
+ }
+
BSONObj StartMongoProgram( const BSONObj &a ) {
_nokillop = true;
ProgramRunner r( a );
@@ -445,9 +599,14 @@ namespace mongo {
ProgramRunner r( a );
r.start();
boost::thread t( r );
- wait_for_pid(r.pid());
- shells.erase( r.pid() );
- return BSON( string( "" ) << int( r.pid() ) );
+ int exit_code;
+ wait_for_pid( r.pid(), true, &exit_code );
+ if ( r.port() > 0 ) {
+ dbs.erase( r.port() );
+ } else {
+ shells.erase( r.pid() );
+ }
+ return BSON( string( "" ) << exit_code );
}
BSONObj RunProgram(const BSONObj &a) {
@@ -518,10 +677,18 @@ namespace mongo {
}
}
#else
- assert( 0 == kill( pid, sig ) );
+ int x = kill( pid, sig );
+ if ( x ){
+ if ( errno == ESRCH ){
+ }
+ else {
+ cout << "killFailed: " << errnoWithDescription() << endl;
+ assert( x == 0 );
+ }
+ }
+
#endif
- }
-
+ }
int killDb( int port, pid_t _pid, int signal ) {
pid_t pid;
@@ -549,7 +716,7 @@ namespace mongo {
}
if(wait_for_pid(pid, false, &exitCode))
break;
- sleepms( 1000 );
+ sleepmillis( 1000 );
}
if ( i == 65 ) {
char now[64];
@@ -567,7 +734,7 @@ namespace mongo {
shells.erase( pid );
}
if ( i > 4 || signal == SIGKILL ) {
- sleepms( 4000 ); // allow operating system to reclaim resources
+ sleepmillis( 4000 ); // allow operating system to reclaim resources
}
return exitCode;
@@ -654,8 +821,18 @@ namespace mongo {
return BSON( "" << false );
#endif
}
+
+ BSONObj getHostName(const BSONObj& a){
+ uassert( 13411, "getHostName accepts no arguments", a.nFields() == 0 );
+ char buf[260]; // HOST_NAME_MAX is usually 255
+ assert(gethostname(buf, 260) == 0);
+ buf[259] = '\0';
+ return BSON("" << buf);
+
+ }
void installShellUtils( Scope& scope ){
+ theScope = &scope;
scope.injectNative( "sleep" , JSSleep );
scope.injectNative( "quit", Quit );
scope.injectNative( "getMemInfo" , JSGetMemInfo );
@@ -667,18 +844,27 @@ namespace mongo {
//can't launch programs
scope.injectNative( "_startMongoProgram", StartMongoProgram );
scope.injectNative( "runProgram", RunProgram );
+ scope.injectNative( "run", RunProgram );
scope.injectNative( "runMongoProgram", RunMongoProgram );
scope.injectNative( "stopMongod", StopMongoProgram );
scope.injectNative( "stopMongoProgram", StopMongoProgram );
scope.injectNative( "stopMongoProgramByPid", StopMongoProgramByPid );
scope.injectNative( "rawMongoProgramOutput", RawMongoProgramOutput );
scope.injectNative( "clearRawMongoProgramOutput", ClearRawMongoProgramOutput );
+ scope.injectNative( "waitProgram" , WaitProgram );
- //can't access filesystem
+ scope.injectNative( "getHostName" , getHostName );
scope.injectNative( "removeFile" , removeFile );
scope.injectNative( "listFiles" , listFiles );
+ scope.injectNative( "ls" , ls );
+ scope.injectNative( "pwd", pwd );
+ scope.injectNative( "cd", cd );
+ scope.injectNative( "cat", cat );
+ scope.injectNative( "hostname", hostname);
scope.injectNative( "resetDbpath", ResetDbpath );
scope.injectNative( "copyDbpath", CopyDbpath );
+ scope.injectNative( "md5sumFile", md5sumFile );
+ scope.injectNative( "mkdir" , mkdir );
#endif
}
diff --git a/shell/utils.js b/shell/utils.js
index 027ba0d..de26403 100644
--- a/shell/utils.js
+++ b/shell/utils.js
@@ -1,5 +1,5 @@
-
__quiet = false;
+__magicNoPrint = { __magicNoPrint : 1111 }
chatty = function(s){
if ( ! __quiet )
@@ -16,9 +16,11 @@ friendlyEqual = function( a , b ){
return false;
}
-
-doassert = function( msg ){
- print( "assert: " + msg );
+doassert = function (msg) {
+ if (msg.indexOf("assert") == 0)
+ print(msg);
+ else
+ print("assert: " + msg);
throw msg;
}
@@ -28,7 +30,11 @@ assert = function( b , msg ){
if ( b )
return;
- doassert( "assert failed : " + msg );
+ doassert( msg == undefined ? "assert failed" : "assert failed : " + msg );
+}
+
+assert.automsg = function( b ) {
+ assert( eval( b ), b );
}
assert._debug = false;
@@ -45,6 +51,10 @@ assert.eq = function( a , b , msg ){
doassert( "[" + tojson( a ) + "] != [" + tojson( b ) + "] are not equal : " + msg );
}
+assert.eq.automsg = function( a, b ) {
+ assert.eq( eval( a ), eval( b ), "[" + a + "] != [" + b + "]" );
+}
+
assert.neq = function( a , b , msg ){
if ( assert._debug && msg ) print( "in assert for: " + msg );
if ( a != b )
@@ -53,6 +63,30 @@ assert.neq = function( a , b , msg ){
doassert( "[" + a + "] != [" + b + "] are equal : " + msg );
}
+assert.repeat = function( f, msg, timeout, interval ) {
+ if ( assert._debug && msg ) print( "in assert for: " + msg );
+
+ var start = new Date();
+ timeout = timeout || 30000;
+ interval = interval || 200;
+ var last;
+ while( 1 ) {
+
+ if ( typeof( f ) == "string" ){
+ if ( eval( f ) )
+ return;
+ }
+ else {
+ if ( f() )
+ return;
+ }
+
+ if ( ( new Date() ).getTime() - start.getTime() > timeout )
+ break;
+ sleep( interval );
+ }
+}
+
assert.soon = function( f, msg, timeout, interval ) {
if ( assert._debug && msg ) print( "in assert for: " + msg );
@@ -89,6 +123,10 @@ assert.throws = function( func , params , msg ){
doassert( "did not throw exception: " + msg );
}
+assert.throws.automsg = function( func, params ) {
+ assert.throws( func, params, func.toString() );
+}
+
assert.commandWorked = function( res , msg ){
if ( assert._debug && msg ) print( "in assert for: " + msg );
@@ -132,6 +170,23 @@ assert.gt = function( a , b , msg ){
doassert( a + " is not greater than " + b + " : " + msg );
}
+assert.lte = function( a , b , msg ){
+ if ( assert._debug && msg ) print( "in assert for: " + msg );
+
+ if ( a <= b )
+ return;
+ doassert( a + " is not less than or eq " + b + " : " + msg );
+}
+
+assert.gte = function( a , b , msg ){
+ if ( assert._debug && msg ) print( "in assert for: " + msg );
+
+ if ( a >= b )
+ return;
+ doassert( a + " is not greater than or eq " + b + " : " + msg );
+}
+
+
assert.close = function( a , b , msg , places ){
if (places === undefined) {
places = 4;
@@ -304,6 +359,14 @@ Object.keySet = function( o ) {
return ret;
}
+if ( ! NumberLong.prototype ) {
+ NumberLong.prototype = {}
+}
+
+NumberLong.prototype.tojson = function() {
+ return this.toString();
+}
+
if ( ! ObjectId.prototype )
ObjectId.prototype = {}
@@ -317,6 +380,14 @@ ObjectId.prototype.tojson = function(){
ObjectId.prototype.isObjectId = true;
+ObjectId.prototype.getTimestamp = function(){
+ return new Date(parseInt(this.toString().slice(0,8), 16)*1000);
+}
+
+ObjectId.prototype.equals = function( other){
+ return this.str == other.str;
+}
+
if ( typeof( DBPointer ) != "undefined" ){
DBPointer.prototype.fetch = function(){
assert( this.ns , "need a ns" );
@@ -366,12 +437,19 @@ else {
}
if ( typeof( BinData ) != "undefined" ){
- BinData.prototype.tojson = function(){
- return "BinData type: " + this.type + " len: " + this.len;
+ BinData.prototype.tojson = function () {
+ //return "BinData type: " + this.type + " len: " + this.len;
+ return this.toString();
}
}
else {
- print( "warning: no BinData" );
+ print( "warning: no BinData class" );
+}
+
+if ( typeof( UUID ) != "undefined" ){
+ UUID.prototype.tojson = function () {
+ return this.toString();
+ }
}
if ( typeof _threadInject != "undefined" ){
@@ -489,7 +567,9 @@ if ( typeof _threadInject != "undefined" ){
"jstests/indexb.js",
"jstests/profile1.js",
"jstests/mr3.js",
- "jstests/apitest_db.js"] );
+ "jstests/indexh.js",
+ "jstests/apitest_db.js",
+ "jstests/evalb.js"] );
// some tests can't be run in parallel with each other
var serialTestsArr = [ "jstests/fsync.js",
@@ -505,8 +585,8 @@ if ( typeof _threadInject != "undefined" ){
files.forEach(
function(x) {
- if ( /_runner/.test(x.name) ||
- /_lodeRunner/.test(x.name) ||
+ if ( ( /[\/\\]_/.test(x.name) ) ||
+ ( ! /\.js$/.test(x.name ) ) ||
( x.name in skipTests ) ||
( x.name in serialTests ) ||
! /\.js$/.test(x.name ) ){
@@ -587,6 +667,10 @@ if ( typeof _threadInject != "undefined" ){
}
}
+tojsononeline = function( x ){
+ return tojson( x , " " , true );
+}
+
tojson = function( x, indent , nolint ){
if ( x === null )
return "null";
@@ -597,24 +681,34 @@ tojson = function( x, indent , nolint ){
if (!indent)
indent = "";
- switch ( typeof x ){
-
+ switch ( typeof x ) {
case "string": {
var s = "\"";
for ( var i=0; i<x.length; i++ ){
- if ( x[i] == '"' ){
- s += "\\\"";
+ switch (x[i]){
+ case '"': s += '\\"'; break;
+ case '\\': s += '\\\\'; break;
+ case '\b': s += '\\b'; break;
+ case '\f': s += '\\f'; break;
+ case '\n': s += '\\n'; break;
+ case '\r': s += '\\r'; break;
+ case '\t': s += '\\t'; break;
+
+ default: {
+ var code = x.charCodeAt(i);
+ if (code < 0x20){
+ s += (code < 0x10 ? '\\u000' : '\\u00') + code.toString(16);
+ } else {
+ s += x[i];
+ }
+ }
}
- else
- s += x[i];
}
return s + "\"";
}
-
case "number":
case "boolean":
return "" + x;
-
case "object":{
var s = tojsonObject( x, indent , nolint );
if ( ( nolint == null || nolint == true ) && s.length < 80 && ( indent == null || indent.length == 0 ) ){
@@ -622,11 +716,8 @@ tojson = function( x, indent , nolint ){
}
return s;
}
-
case "function":
return x.toString();
-
-
default:
throw "tojson can't handle type " + ( typeof x );
}
@@ -646,7 +737,7 @@ tojsonObject = function( x, indent , nolint ){
return x.tojson(indent,nolint);
}
- if ( typeof( x.constructor.tojson ) == "function" && x.constructor.tojson != tojson ) {
+ if ( x.constructor && typeof( x.constructor.tojson ) == "function" && x.constructor.tojson != tojson ) {
return x.constructor.tojson( x, indent , nolint );
}
@@ -710,6 +801,10 @@ printjson = function(x){
print( tojson( x ) );
}
+printjsononeline = function(x){
+ print( tojsononeline( x ) );
+}
+
shellPrintHelper = function( x ){
if ( typeof( x ) == "undefined" ){
@@ -723,6 +818,9 @@ shellPrintHelper = function( x ){
return;
}
+ if ( x == __magicNoPrint )
+ return;
+
if ( x == null ){
print( "null" );
return;
@@ -742,6 +840,13 @@ shellPrintHelper = function( x ){
print( tojson( x ) );
}
+shellAutocomplete = function( prefix ){
+ var a = [];
+ //a.push( prefix + "z" )
+ //a.push( prefix + "y" )
+ __autocomplete__ = a;
+}
+
shellHelper = function( command , rest , shouldPrint ){
command = command.trim();
var args = rest.trim().replace(/;$/,"").split( "\s+" );
@@ -756,20 +861,6 @@ shellHelper = function( command , rest , shouldPrint ){
return res;
}
-help = shellHelper.help = function(){
- print( "HELP" );
- print( "\t" + "show dbs show database names");
- print( "\t" + "show collections show collections in current database");
- print( "\t" + "show users show users in current database");
- print( "\t" + "show profile show most recent system.profile entries with time >= 1ms");
- print( "\t" + "use <db name> set curent database to <db name>" );
- print( "\t" + "db.help() help on DB methods");
- print( "\t" + "db.foo.help() help on collection methods");
- print( "\t" + "db.foo.find() list objects in collection foo" );
- print( "\t" + "db.foo.find( { a : 1 } ) list objects in foo where a == 1" );
- print( "\t" + "it result of the last line evaluated; use to further iterate");
-}
-
shellHelper.use = function( dbname ){
db = db.getMongo().getDB( dbname );
print( "switched to db " + db.getName() );
@@ -884,6 +975,7 @@ Map.prototype.values = function(){
if ( typeof( gc ) == "undefined" ){
gc = function(){
+ print( "warning: using noop gc()" );
}
}
@@ -953,3 +1045,108 @@ Geo.distance = function( a , b ){
return Math.sqrt( Math.pow( by - ay , 2 ) +
Math.pow( bx - ax , 2 ) );
}
+
+rs = function () { return "try rs.help()"; }
+
+rs.help = function () {
+ print("\trs.status() { replSetGetStatus : 1 } checks repl set status");
+ print("\trs.initiate() { replSetInitiate : null } initiates set with default settings");
+ print("\trs.initiate(cfg) { replSetInitiate : cfg } initiates set with configuration cfg");
+ print("\trs.add(hostportstr) add a new member to the set with default attributes");
+ print("\trs.add(membercfgobj) add a new member to the set with extra attributes");
+ print("\trs.addArb(hostportstr) add a new member which is arbiterOnly:true");
+ print("\trs.stepDown() step down as primary (momentarily)");
+ print("\trs.conf() return configuration from local.system.replset");
+ print("\trs.slaveOk() shorthand for db.getMongo().setSlaveOk()");
+ print();
+ print("\tdb.isMaster() check who is primary");
+ print();
+ print("\tsee also http://<mongod_host>:28017/_replSet for additional diagnostic info");
+}
+rs.slaveOk = function () { return db.getMongo().setSlaveOk(); }
+rs.status = function () { return db._adminCommand("replSetGetStatus"); }
+rs.isMaster = function () { return db.isMaster(); }
+rs.initiate = function (c) { return db._adminCommand({ replSetInitiate: c }); }
+rs.add = function (hostport, arb) {
+ var cfg = hostport;
+
+ var local = db.getSisterDB("local");
+ assert(local.system.replset.count() <= 1, "error: local.system.replset has unexpected contents");
+ var c = local.system.replset.findOne();
+ assert(c, "no config object retrievable from local.system.replset");
+ c.version++;
+ var max = 0;
+ for (var i in c.members)
+ if (c.members[i]._id > max) max = c.members[i]._id;
+ if (isString(hostport)) {
+ cfg = { _id: max + 1, host: hostport };
+ if (arb)
+ cfg.arbiterOnly = true;
+ }
+ c.members.push(cfg);
+ return db._adminCommand({ replSetReconfig: c });
+}
+rs.stepDown = function () { return db._adminCommand({ replSetStepDown:true}); }
+rs.addArb = function (hn) { return this.add(hn, true); }
+rs.conf = function () { return db.getSisterDB("local").system.replset.findOne(); }
+
+help = shellHelper.help = function (x) {
+ if (x == "connect") {
+ print("\nNormally one specifies the server on the mongo shell command line. Run mongo --help to see those options.");
+ print("Additional connections may be opened:\n");
+ print(" var x = new Mongo('host[:port]');");
+ print(" var mydb = x.getDB('mydb');");
+ print(" or");
+ print(" var mydb = connect('host[:port]/mydb');");
+ print("\nNote: the REPL prompt only auto-reports getLastError() for the shell command line connection.\n");
+ return;
+ }
+ if (x == "misc") {
+ print("\tb = new BinData(subtype,base64str) create a BSON BinData value");
+ print("\tb.subtype() the BinData subtype (0..255)");
+ print("\tb.length() length of the BinData data in bytes");
+ print("\tb.hex() the data as a hex encoded string");
+ print("\tb.base64() the data as a base 64 encoded string");
+ print("\tb.toString()");
+ return;
+ }
+ if (x == "admin") {
+ print("\tls([path]) list files");
+ print("\tpwd() returns current directory");
+ print("\tlistFiles([path]) returns file list");
+ print("\thostname() returns name of this host");
+ print("\tcat(fname) returns contents of text file as a string");
+ print("\tremoveFile(f) delete a file");
+ print("\tload(jsfilename) load and execute a .js file");
+ print("\trun(program[, args...]) spawn a program and wait for its completion");
+ print("\tsleep(m) sleep m milliseconds");
+ print("\tgetMemInfo() diagnostic");
+ return;
+ }
+ if (x == "test") {
+ print("\tstartMongodEmpty(args) DELETES DATA DIR and then starts mongod");
+ print("\t returns a connection to the new server");
+ print("\tstartMongodTest() DELETES DATA DIR");
+ print("\t automatically picks port #s starting at 27000 and increasing");
+ print("\t or you can specify the port as the first arg");
+ print("\t dir is /data/db/<port>/ if not specified as the 2nd arg");
+ print("\t returns a connection to the new server");
+ return;
+ }
+ print("\t" + "db.help() help on db methods");
+ print("\t" + "db.mycoll.help() help on collection methods");
+ print("\t" + "rs.help() help on replica set methods");
+ print("\t" + "help connect connecting to a db help");
+ print("\t" + "help admin administrative help");
+ print("\t" + "help misc misc things to know");
+ print();
+ print("\t" + "show dbs show database names");
+ print("\t" + "show collections show collections in current database");
+ print("\t" + "show users show users in current database");
+ print("\t" + "show profile show most recent system.profile entries with time >= 1ms");
+ print("\t" + "use <db_name> set current database");
+ print("\t" + "db.foo.find() list objects in collection foo");
+ print("\t" + "db.foo.find( { a : 1 } ) list objects in foo where a == 1");
+ print("\t" + "it result of the last line evaluated; use to further iterate");
+ print("\t" + "exit quit the mongo shell");
+}