__quiet = false; __magicNoPrint = { __magicNoPrint : 1111 } chatty = function(s){ if ( ! __quiet ) print( s ); } friendlyEqual = function( a , b ){ if ( a == b ) return true; a = tojson(a,false,true); b = tojson(b,false,true); if ( a == b ) return true; var clean = function( s ){ s = s.replace( /NumberInt\((\-?\d+)\)/g , "$1" ); return s; } a = clean(a); b = clean(b); if ( a == b ) return true; return false; } printStackTrace = function(){ try{ throw new Error("Printing Stack Trace"); } catch (e) { print(e.stack); } } doassert = function (msg) { if (msg.indexOf("assert") == 0) print(msg); else print("assert: " + msg); printStackTrace(); throw msg; } assert = function( b , msg ){ if ( assert._debug && msg ) print( "in assert for: " + msg ); if ( b ) return; doassert( msg == undefined ? "assert failed" : "assert failed : " + msg ); } assert.automsg = function( b ) { assert( eval( b ), b ); } assert._debug = false; assert.eq = function( a , b , msg ){ if ( assert._debug && msg ) print( "in assert for: " + msg ); if ( a == b ) return; if ( ( a != null && b != null ) && friendlyEqual( a , b ) ) return; 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 ) return; doassert( "[" + a + "] != [" + b + "] are equal : " + msg ); } assert.contains = function( o, arr, msg ){ var wasIn = false if( ! arr.length ){ for( i in arr ){ wasIn = arr[i] == o || ( ( arr[i] != null && o != null ) && friendlyEqual( arr[i] , o ) ) return; if( wasIn ) break } } else { for( var i = 0; i < arr.length; i++ ){ wasIn = arr[i] == o || ( ( arr[i] != null && o != null ) && friendlyEqual( arr[i] , o ) ) if( wasIn ) break } } if( ! wasIn ) doassert( tojson( o ) + " was not in " + tojson( arr ) + " : " + 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 /*ms*/, 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 ) doassert( "assert.soon failed: " + f + ", msg:" + msg ); sleep( interval ); } } assert.throws = function( func , params , msg ){ if ( assert._debug && msg ) print( "in assert for: " + msg ); if ( params && typeof( params ) == "string" ) throw "2nd argument to assert.throws has to be an array" try { func.apply( null , params ); } catch ( e ){ return e; } 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 ); if ( res.ok == 1 ) return; doassert( "command failed: " + tojson( res ) + " : " + msg ); } assert.commandFailed = function( res , msg ){ if ( assert._debug && msg ) print( "in assert for: " + msg ); if ( res.ok == 0 ) return; doassert( "command worked when it should have failed: " + tojson( res ) + " : " + msg ); } assert.isnull = function( what , msg ){ if ( assert._debug && msg ) print( "in assert for: " + msg ); if ( what == null ) return; doassert( "supposed to null (" + ( msg || "" ) + ") was: " + tojson( what ) ); } assert.lt = function( a , b , msg ){ if ( assert._debug && msg ) print( "in assert for: " + msg ); if ( a < b ) return; doassert( a + " is not less than " + b + " : " + msg ); } assert.gt = function( a , b , msg ){ if ( assert._debug && msg ) print( "in assert for: " + msg ); if ( a > b ) return; 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.between = function( a, b, c, msg, inclusive ){ if ( assert._debug && msg ) print( "in assert for: " + msg ); if( ( inclusive == undefined || inclusive == true ) && a <= b && b <= c ) return; else if( a < b && b < c ) return; doassert( b + " is not between " + a + " and " + c + " : " + msg ); } assert.betweenIn = function( a, b, c, msg ){ assert.between( a, b, c, msg, true ) } assert.betweenEx = function( a, b, c, msg ){ assert.between( a, b, c, msg, false ) } assert.close = function( a , b , msg , places ){ if (places === undefined) { places = 4; } if (Math.round((a - b) * Math.pow(10, places)) === 0) { return; } doassert( a + " is not equal to " + b + " within " + places + " places, diff: " + (a-b) + " : " + msg ); }; Object.extend = function( dst , src , deep ){ for ( var k in src ){ var v = src[k]; if ( deep && typeof(v) == "object" ){ if ( "floatApprox" in v ) { // convert NumberLong properly eval( "v = " + tojson( v ) ); } else { v = Object.extend( typeof ( v.length ) == "number" ? [] : {} , v , true ); } } dst[k] = v; } return dst; } Object.merge = function( dst, src, deep ){ var clone = Object.extend( {}, dst, deep ) return Object.extend( clone, src, deep ) } argumentsToArray = function( a ){ var arr = []; for ( var i=0; i 0 ? '-' : '+'; // This is correct ofs += (ofsmin/60).zeroPad(2) ofs += (ofsmin%60).zeroPad(2) } } return 'ISODate("'+year+'-'+month+'-'+date+'T'+hour+':'+minute+':'+sec+ofs+'")'; } Date.printAsUTC = true; ISODate = function(isoDateStr){ if (!isoDateStr) return new Date(); var isoDateRegex = /(\d{4})-?(\d{2})-?(\d{2})([T ](\d{2})(:?(\d{2})(:?(\d{2}(\.\d+)?))?)?(Z|([+-])(\d{2}):?(\d{2})?)?)?/; var res = isoDateRegex.exec(isoDateStr); if (!res) throw "invalid ISO date"; var year = parseInt(res[1],10) || 1970; // this should always be present var month = (parseInt(res[2],10) || 1) - 1; var date = parseInt(res[3],10) || 0; var hour = parseInt(res[5],10) || 0; var min = parseInt(res[7],10) || 0; var sec = parseFloat(res[9]) || 0; var ms = Math.round((sec%1) * 1000) sec -= ms/1000 var time = Date.UTC(year, month, date, hour, min, sec, ms); if (res[11] && res[11] != 'Z'){ var ofs = 0; ofs += (parseInt(res[13],10) || 0) * 60*60*1000; // hours ofs += (parseInt(res[14],10) || 0) * 60*1000; // mins if (res[12] == '+') // if ahead subtract ofs *= -1; time += ofs } return new Date(time); } RegExp.prototype.tojson = RegExp.prototype.toString; Array.contains = function( a , x ){ for ( var i=0; i>>>>>>>>>>>>>> skipping " + x.name); return; } params[ i % n ].push( x.name ); ++i; } ); // randomize ordering of the serialTests params[ 0 ] = Array.shuffle( params[ 0 ] ); for( var i in params ) { params[ i ].unshift( i ); } return params; } // runs a set of test files // first argument is an identifier for this tester, remaining arguments are file names ParallelTester.fileTester = function() { var args = argumentsToArray( arguments ); var suite = args.shift(); args.forEach( function( x ) { print(" S" + suite + " Test : " + x + " ..."); var time = Date.timeFunc( function() { load(x); }, 1); print(" S" + suite + " Test : " + x + " " + time + "ms" ); } ); } // params: array of arrays, each element of which consists of a function followed // by zero or more arguments to that function. Each function and its arguments will // be called in a separate thread. // msg: failure message // newScopes: if true, each thread starts in a fresh scope assert.parallelTests = function( params, msg, newScopes ) { newScopes = newScopes || false; var wrapper = function( fun, argv ) { eval ( "var z = function() {" + "var __parallelTests__fun = " + fun.toString() + ";" + "var __parallelTests__argv = " + tojson( argv ) + ";" + "var __parallelTests__passed = false;" + "try {" + "__parallelTests__fun.apply( 0, __parallelTests__argv );" + "__parallelTests__passed = true;" + "} catch ( e ) {" + "print( '********** Parallel Test FAILED: ' + tojson(e) );" + "}" + "return __parallelTests__passed;" + "}" ); return z; } var runners = new Array(); for( var i in params ) { var param = params[ i ]; var test = param.shift(); var t; if ( newScopes ) t = new ScopedThread( wrapper( test, param ) ); else t = new Thread( wrapper( test, param ) ); runners.push( t ); } runners.forEach( function( x ) { x.start(); } ); var nFailed = 0; // v8 doesn't like it if we exit before all threads are joined (SERVER-529) runners.forEach( function( x ) { if( !x.returnData() ) { ++nFailed; } } ); assert.eq( 0, nFailed, msg ); } } tojsononeline = function( x ){ return tojson( x , " " , true ); } tojson = function( x, indent , nolint ){ if ( x === null ) return "null"; if ( x === undefined ) return "undefined"; if (!indent) indent = ""; switch ( typeof x ) { case "string": { var s = "\""; for ( var i=0; i 1) { print(n + "\t" + size[n] / 1024 / 1024 / 1024 + "GB"); } else { print(n + "\t(empty)"); } }); //db.getMongo().getDBNames().sort().forEach(function (x) { print(x) }); return ""; } if (what == "log" ) { var n = "global"; if ( args.length > 0 ) n = args[0] var res = db.adminCommand( { getLog : n } ) for ( var i=0; i= 1 || cross_prod <= -1){ // fun with floats assert( Math.abs(cross_prod)-1 < 1e-6 ); return cross_prod > 0 ? 0 : Math.PI; } return Math.acos(cross_prod); } 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.conf() get the current configuration object from local.system.replset"); print("\trs.reconfig(cfg) updates the configuration of a running replica set with cfg (disconnects)"); print("\trs.add(hostportstr) add a new member to the set with default attributes (disconnects)"); print("\trs.add(membercfgobj) add a new member to the set with extra attributes (disconnects)"); print("\trs.addArb(hostportstr) add a new member which is arbiterOnly:true (disconnects)"); print("\trs.stepDown([secs]) step down as primary (momentarily) (disconnects)"); print("\trs.freeze(secs) make a node ineligible to become primary for the time specified"); print("\trs.remove(hostportstr) remove a host from the replica set (disconnects)"); print("\trs.slaveOk() shorthand for db.getMongo().setSlaveOk()"); print(); print("\tdb.isMaster() check who is primary"); print(); print("\treconfiguration helpers disconnect from the database so the shell will display"); print("\tan error, even if the command succeeds."); print("\tsee also http://: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._runCmd = function (c) { // after the command, catch the disconnect and reconnect if necessary var res = null; try { res = db.adminCommand(c); } catch (e) { if (("" + e).indexOf("error doing query") >= 0) { // closed connection. reconnect. db.getLastErrorObj(); var o = db.getLastErrorObj(); if (o.ok) { print("reconnected to server after rs command (which is normal)"); } else { printjson(o); } } else { print("shell got exception during repl set operation: " + e); print("in some circumstances, the primary steps down and closes connections on a reconfig"); } return ""; } return res; } rs.reconfig = function (cfg, options) { cfg.version = rs.conf().version + 1; cmd = { replSetReconfig: cfg }; for (var i in options) { cmd[i] = options[i]; } return this._runCmd(cmd); } 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 this._runCmd({ replSetReconfig: c }); } rs.stepDown = function (secs) { return db._adminCommand({ replSetStepDown:(secs === undefined) ? 60:secs}); } rs.freeze = function (secs) { return db._adminCommand({replSetFreeze:secs}); } rs.addArb = function (hn) { return this.add(hn, true); } rs.conf = function () { return db.getSisterDB("local").system.replset.findOne(); } rs.config = function () { return rs.conf(); } rs.remove = function (hn) { 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++; for (var i in c.members) { if (c.members[i].host == hn) { c.members.splice(i, 1); return db._adminCommand({ replSetReconfig : c}); } } return "error: couldn't find "+hn+" in "+tojson(c.members); }; rs.debug = {}; rs.debug.nullLastOpWritten = function(primary, secondary) { var p = connect(primary+"/local"); var s = connect(secondary+"/local"); s.getMongo().setSlaveOk(); var secondToLast = s.oplog.rs.find().sort({$natural : -1}).limit(1).next(); var last = p.runCommand({findAndModify : "oplog.rs", query : {ts : {$gt : secondToLast.ts}}, sort : {$natural : 1}, update : {$set : {op : "n"}}}); if (!last.value.o || !last.value.o._id) { print("couldn't find an _id?"); } else { last.value.o = {_id : last.value.o._id}; } print("nulling out this op:"); printjson(last); }; rs.debug.getLastOpWritten = function(server) { var s = db.getSisterDB("local"); if (server) { s = connect(server+"/local"); } s.getMongo().setSlaveOk(); return s.oplog.rs.find().sort({$natural : -1}).limit(1).next(); }; help = shellHelper.help = function (x) { if (x == "mr") { print("\nSee also http://www.mongodb.org/display/DOCS/MapReduce"); print("\nfunction mapf() {"); print(" // 'this' holds current document to inspect"); print(" emit(key, value);"); print("}"); print("\nfunction reducef(key,value_array) {"); print(" return reduced_value;"); print("}"); print("\ndb.mycollection.mapReduce(mapf, reducef[, options])"); print("\noptions"); print("{[query : ]"); print(" [, sort : ]"); print(" [, limit : ]"); print(" [, out : ]"); print(" [, keeptemp: ]"); print(" [, finalize : ]"); print(" [, scope : ]"); print(" [, verbose : true]}\n"); return; } else 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; } else if (x == "keys") { print("Tab completion and command history is available at the command prompt.\n"); print("Some emacs keystrokes are available too:"); print(" Ctrl-A start of line"); print(" Ctrl-E end of line"); print(" Ctrl-K del to end of line"); print("\nMulti-line commands"); print("You can enter a multi line javascript expression. If parens, braces, etc. are not closed, you will see a new line "); print("beginning with '...' characters. Type the rest of your expression. Press Ctrl-C to abort the data entry if you"); print("get stuck.\n"); } else 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()"); print(); print("\tb = HexData(subtype,hexstr) create a BSON BinData value from a hex string"); print("\tb = UUID(hexstr) create a BSON BinData value of UUID subtype"); print("\tb = MD5(hexstr) create a BSON BinData value of MD5 subtype"); print(); print("\to = new ObjectId() create a new ObjectId"); print("\to.getTimestamp() return timestamp derived from first 32 bits of the OID"); print("\to.isObjectId()"); print("\to.toString()"); print("\to.equals(otherid)"); return; } else 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 or directory"); print("\tload(jsfilename) load and execute a .js file"); print("\trun(program[, args...]) spawn a program and wait for its completion"); print("\trunProgram(program[, args...]) same as run(), above"); print("\tsleep(m) sleep m milliseconds"); print("\tgetMemInfo() diagnostic"); return; } else if (x == "test") { print("\tstartMongodEmpty(args) DELETES DATA DIR and then starts mongod"); print("\t returns a connection to the new server"); print("\tstartMongodTest(port,dir,options)"); print("\t 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// if not specified as the 2nd arg"); print("\t returns a connection to the new server"); print("\tresetDbpath(dirpathstr) deletes everything under the dir specified including subdirs"); print("\tstopMongoProgram(port[, signal])"); return; } else if (x == "") { 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 admin administrative help"); print("\t" + "help connect connecting to a db help"); print("\t" + "help keys key shortcuts"); print("\t" + "help misc misc things to know"); print("\t" + "help mr mapreduce"); 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" + "show logs show the accessible logger names"); print("\t" + "show log [name] prints out the last segment of log in memory, 'global' is default"); print("\t" + "use 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" + "DBQuery.shellBatchSize = x set default number of items to display on shell"); print("\t" + "exit quit the mongo shell"); } else print("unknown help option"); }