diff options
47 files changed, 2443 insertions, 2312 deletions
diff --git a/client/dbclient.cpp b/client/dbclient.cpp index 7e68d35aac7..f740989103a 100644 --- a/client/dbclient.cpp +++ b/client/dbclient.cpp @@ -29,138 +29,143 @@ namespace mongo { /* --- dbclientcommands --- */ -inline bool DBClientWithCommands::isOk(const BSONObj& o) { - return o.getIntField("ok") == 1; +inline bool DBClientWithCommands::isOk(const BSONObj& o) { + return o.getIntField("ok") == 1; } -inline bool DBClientWithCommands::runCommand(const char *dbname, BSONObj cmd, BSONObj &info) { - string ns = string(dbname) + ".$cmd"; +inline bool DBClientWithCommands::runCommand(const char *dbname, BSONObj cmd, BSONObj &info) { + string ns = string(dbname) + ".$cmd"; info = findOne(ns.c_str(), cmd); - return isOk(info); + return isOk(info); } -/* note - we build a bson obj here -- for something that is super common like getlasterror you +/* note - we build a bson obj here -- for something that is super common like getlasterror you should have that object prebuilt as that would be faster. */ -bool DBClientWithCommands::simpleCommand(const char *dbname, BSONObj *info, const char *command) { - BSONObj o; - if( info == 0 ) - info = &o; - BSONObjBuilder b; - b.appendInt(command, 1); - return runCommand(dbname, b.done(), *info); +bool DBClientWithCommands::simpleCommand(const char *dbname, BSONObj *info, const char *command) { + BSONObj o; + if ( info == 0 ) + info = &o; + BSONObjBuilder b; + b.appendInt(command, 1); + return runCommand(dbname, b.done(), *info); } BSONObj ismastercmdobj = fromjson("{\"ismaster\":1}"); bool DBClientWithCommands::isMaster(bool& isMaster, BSONObj *info) { - BSONObj o; if( info == 0 ) info = &o; - bool ok = runCommand("admin", ismastercmdobj, *info); + BSONObj o; + if ( info == 0 ) info = &o; + bool ok = runCommand("admin", ismastercmdobj, *info); isMaster = (info->getIntField("ismaster") == 1); - return ok; -} - -bool DBClientWithCommands::createCollection(const char *ns, unsigned size, bool capped, int max, BSONObj *info) { - BSONObj o; if( info == 0 ) info = &o; - BSONObjBuilder b; - b.append("create", ns); - if( size ) b.append("size", size); - if( capped ) b.append("capped", true); - if( max ) b.append("max", max); - string db = nsToClient(ns); - return runCommand(db.c_str(), b.done(), *info); -} - -bool DBClientWithCommands::copyDatabase(const char *fromdb, const char *todb, const char *fromhost, BSONObj *info) { - assert( *fromdb && *todb ); - BSONObj o; if( info == 0 ) info = &o; - BSONObjBuilder b; - b.append("copydb", 1); - b.append("fromhost", fromhost); - b.append("fromdb", fromdb); - b.append("todb", todb); - return runCommand("admin", b.done(), *info); -} - -bool DBClientWithCommands::setDbProfilingLevel(const char *dbname, ProfilingLevel level, BSONObj *info ) { - BSONObj o; if( info == 0 ) info = &o; - - if( level ) { - // Create system.profile collection. If it already exists this does nothing. - // TODO: move this into the db instead of here so that all - // drivers don't have to do this. - string ns = string(dbname) + ".system.profile"; - createCollection(ns.c_str(), 1024 * 1024, true, 0, info); + return ok; +} + +bool DBClientWithCommands::createCollection(const char *ns, unsigned size, bool capped, int max, BSONObj *info) { + BSONObj o; + if ( info == 0 ) info = &o; + BSONObjBuilder b; + b.append("create", ns); + if ( size ) b.append("size", size); + if ( capped ) b.append("capped", true); + if ( max ) b.append("max", max); + string db = nsToClient(ns); + return runCommand(db.c_str(), b.done(), *info); +} + +bool DBClientWithCommands::copyDatabase(const char *fromdb, const char *todb, const char *fromhost, BSONObj *info) { + assert( *fromdb && *todb ); + BSONObj o; + if ( info == 0 ) info = &o; + BSONObjBuilder b; + b.append("copydb", 1); + b.append("fromhost", fromhost); + b.append("fromdb", fromdb); + b.append("todb", todb); + return runCommand("admin", b.done(), *info); +} + +bool DBClientWithCommands::setDbProfilingLevel(const char *dbname, ProfilingLevel level, BSONObj *info ) { + BSONObj o; + if ( info == 0 ) info = &o; + + if ( level ) { + // Create system.profile collection. If it already exists this does nothing. + // TODO: move this into the db instead of here so that all + // drivers don't have to do this. + string ns = string(dbname) + ".system.profile"; + createCollection(ns.c_str(), 1024 * 1024, true, 0, info); } - BSONObjBuilder b; - b.append("profile", (int) level); - return runCommand(dbname, b.done(), *info); + BSONObjBuilder b; + b.append("profile", (int) level); + return runCommand(dbname, b.done(), *info); } BSONObj getprofilingcmdobj = fromjson("{\"profile\":-1}"); -bool DBClientWithCommands::getDbProfilingLevel(const char *dbname, ProfilingLevel& level, BSONObj *info) { - BSONObj o; if( info == 0 ) info = &o; - if( runCommand(dbname, getprofilingcmdobj, *info) ) { - level = (ProfilingLevel) info->getIntField("was"); - return true; - } - return false; +bool DBClientWithCommands::getDbProfilingLevel(const char *dbname, ProfilingLevel& level, BSONObj *info) { + BSONObj o; + if ( info == 0 ) info = &o; + if ( runCommand(dbname, getprofilingcmdobj, *info) ) { + level = (ProfilingLevel) info->getIntField("was"); + return true; + } + return false; } -bool DBClientWithCommands::eval(const char *dbname, const char *jscode, BSONObj& info, BSONElement& retValue, BSONObj *args) { - BSONObjBuilder b; - b.appendCode("$eval", jscode); - if( args ) - b.appendArray("args", *args); - bool ok = runCommand(dbname, b.done(), info); - if( ok ) - retValue = info.getField("retval"); - return ok; +bool DBClientWithCommands::eval(const char *dbname, const char *jscode, BSONObj& info, BSONElement& retValue, BSONObj *args) { + BSONObjBuilder b; + b.appendCode("$eval", jscode); + if ( args ) + b.appendArray("args", *args); + bool ok = runCommand(dbname, b.done(), info); + if ( ok ) + retValue = info.getField("retval"); + return ok; } -bool DBClientWithCommands::eval(const char *dbname, const char *jscode) { - BSONObj info; - BSONElement retValue; - return eval(dbname, jscode, info, retValue); +bool DBClientWithCommands::eval(const char *dbname, const char *jscode) { + BSONObj info; + BSONElement retValue; + return eval(dbname, jscode, info, retValue); } /* TODO: unit tests should run this? */ -void testDbEval() { - DBClientConnection c; - string err; - if( !c.connect("localhost", err) ) { - cout << "can't connect to server " << err << endl; - return; - } - BSONObj info; - BSONElement retValue; - BSONObjBuilder b; - b.append("0", 99); - BSONObj args = b.done(); - bool ok = c.eval("dwight", "function() { return args[0]; }", info, retValue, &args); - cout << "eval ok=" << ok << endl; - cout << "retvalue=" << retValue.toString() << endl; - cout << "info=" << info.toString() << endl; - - cout << endl; - - int x = 3; - assert( c.eval("dwight", "function() { return 3; }", x) ); - - cout << "***\n"; - - BSONObj foo = fromjson("{\"x\":7}"); - cout << foo.toString() << endl; - int res=0; - ok = c.eval("dwight", "function(parm1) { return parm1.x; }", foo, res); - cout << ok << " retval:" << res << endl; -} - -int test2() { - testDbEval(); - return 0; +void testDbEval() { + DBClientConnection c; + string err; + if ( !c.connect("localhost", err) ) { + cout << "can't connect to server " << err << endl; + return; + } + BSONObj info; + BSONElement retValue; + BSONObjBuilder b; + b.append("0", 99); + BSONObj args = b.done(); + bool ok = c.eval("dwight", "function() { return args[0]; }", info, retValue, &args); + cout << "eval ok=" << ok << endl; + cout << "retvalue=" << retValue.toString() << endl; + cout << "info=" << info.toString() << endl; + + cout << endl; + + int x = 3; + assert( c.eval("dwight", "function() { return 3; }", x) ); + + cout << "***\n"; + + BSONObj foo = fromjson("{\"x\":7}"); + cout << foo.toString() << endl; + int res=0; + ok = c.eval("dwight", "function(parm1) { return parm1.x; }", foo, res); + cout << ok << " retval:" << res << endl; +} + +int test2() { + testDbEval(); + return 0; } /* --- dbclientconnection --- */ @@ -240,90 +245,90 @@ auto_ptr<DBClientCursor> DBClientBase::query(const char *ns, BSONObj query, int return auto_ptr< DBClientCursor >( 0 ); } -void DBClientBase::insert( const char * ns , BSONObj obj ){ +void DBClientBase::insert( const char * ns , BSONObj obj ) { Message toSend; - + BufBuilder b; int opts = 0; b.append( opts ); b.append( ns ); obj.appendSelfToBufBuilder( b ); - + toSend.setData( dbInsert , b.buf() , b.len() ); say( toSend ); } -void DBClientBase::remove( const char * ns , BSONObj obj , bool justOne ){ +void DBClientBase::remove( const char * ns , BSONObj obj , bool justOne ) { Message toSend; - + BufBuilder b; int opts = 0; b.append( opts ); b.append( ns ); - + int flags = 0; if ( justOne || obj.hasField( "_id" ) ) flags &= 1; b.append( flags ); obj.appendSelfToBufBuilder( b ); - + toSend.setData( dbDelete , b.buf() , b.len() ); say( toSend ); } -void DBClientBase::update( const char * ns , BSONObj query , BSONObj obj , bool upsert ){ - +void DBClientBase::update( const char * ns , BSONObj query , BSONObj obj , bool upsert ) { + BufBuilder b; b.append( (int)0 ); // reserverd b.append( ns ); - + b.append( (int)upsert ); - + query.appendSelfToBufBuilder( b ); obj.appendSelfToBufBuilder( b ); Message toSend; toSend.setData( dbUpdate , b.buf() , b.len() ); - say( toSend ); + say( toSend ); } -bool DBClientBase::ensureIndex( const char * ns , BSONObj keys , const char * name ){ +bool DBClientBase::ensureIndex( const char * ns , BSONObj keys , const char * name ) { BSONObjBuilder toSave; toSave.append( "ns" , ns ); toSave.append( "key" , keys ); - + string cacheKey(ns); cacheKey += "--"; - - if ( name ){ + + if ( name ) { toSave.append( "name" , name ); cacheKey += name; } else { stringstream ss; - + bool first = 1; - for ( BSONObjIterator i(keys); i.more(); ){ + for ( BSONObjIterator i(keys); i.more(); ) { BSONElement f = i.next(); if ( f.eoo() ) break; - + if ( first ) first = 0; else ss << "_"; - + ss << f.fieldName() << "_"; - + if ( f.type() == NumberInt ) ss << (int)(f.number() ); else if ( f.type() == NumberDouble ) ss << f.number(); - + } toSave.append( "name" , ss.str() ); @@ -338,7 +343,7 @@ bool DBClientBase::ensureIndex( const char * ns , BSONObj keys , const char * na return 1; } -void DBClientBase::resetIndexCache(){ +void DBClientBase::resetIndexCache() { _seenIndexes.clear(); } @@ -459,19 +464,19 @@ BSONObj DBClientCursor::next() { return o; } -DBClientCursor::~DBClientCursor(){ - if ( cursorId ){ +DBClientCursor::~DBClientCursor() { + if ( cursorId ) { BufBuilder b; b.append( (int)0 ); // reserved b.append( (int)1 ); // number b.append( cursorId ); - + Message m; m.setData( dbKillCursors , b.buf() , b.len() ); - + connector->sayPiggyBack( m ); } - + } /* ------------------------------------------------------ */ @@ -549,7 +554,7 @@ void DBClientPaired::_checkMaster() { try { bool im; BSONObj o; - c.isMaster(im, &o); + c.isMaster(im, &o); if ( retry ) log() << "checkmaster: " << c.toString() << ' ' << o.toString() << '\n'; if ( im ) { diff --git a/client/dbclient.h b/client/dbclient.h index 10075497850..6135a595bc8 100644 --- a/client/dbclient.h +++ b/client/dbclient.h @@ -156,7 +156,7 @@ public: virtual BSONObj findOne(const char *ns, BSONObj query, BSONObj *fieldsToReturn = 0, int queryOptions = 0) = 0; - + virtual void insert( const char * ns , BSONObj obj ) = 0; }; @@ -164,137 +164,141 @@ public: basically just invocations of connection.$cmd.findOne({...}); */ class DBClientWithCommands : public DBClientInterface { - bool isOk(const BSONObj&); - bool simpleCommand(const char *dbname, BSONObj *info, const char *command); + bool isOk(const BSONObj&); + bool simpleCommand(const char *dbname, BSONObj *info, const char *command); public: - /* Run a database command. Database commands are represented as BSON objects. Common database - commands have prebuilt helper functions -- see below. If a helper is not available you can - directly call runCommand. + /* Run a database command. Database commands are represented as BSON objects. Common database + commands have prebuilt helper functions -- see below. If a helper is not available you can + directly call runCommand. - dbname - database name. Use "admin" for global administrative commands. + dbname - database name. Use "admin" for global administrative commands. cmd - the command object to execute. For example, { ismaster : 1 } - info - the result object the database returns. Typically has { ok : ..., errmsg : ... } fields - set. + info - the result object the database returns. Typically has { ok : ..., errmsg : ... } fields + set. returns: true if the command returned "ok". - */ - bool runCommand(const char *dbname, BSONObj cmd, BSONObj &info); + */ + bool runCommand(const char *dbname, BSONObj cmd, BSONObj &info); + + /* returns true in isMaster parm if this db is the current master + of a replica pair. - /* returns true in isMaster parm if this db is the current master - of a replica pair. - - pass in info for more details e.g.: + pass in info for more details e.g.: { "ismaster" : 1.0 , "msg" : "not paired" , "ok" : 1.0 } - returns true if command invoked successfully. + returns true if command invoked successfully. */ - virtual bool isMaster(bool& isMaster, BSONObj *info=0); + virtual bool isMaster(bool& isMaster, BSONObj *info=0); /* - Create a new collection in the database. Normally, collection creation is automatic. You would - use this function if you wish to specify special options on creation. + Create a new collection in the database. Normally, collection creation is automatic. You would + use this function if you wish to specify special options on creation. - If the collection already exists, no action occurs. + If the collection already exists, no action occurs. - ns: fully qualified collection name - size: desired initial extent size for the collection. - Must be <= 1000000000 for normal collections. - For fixed size (capped) collections, this size is the total/max size of the - collection. - capped: if true, this is a fixed size collection (where old data rolls out). - max: maximum number of objects if capped (optional). + ns: fully qualified collection name + size: desired initial extent size for the collection. + Must be <= 1000000000 for normal collections. + For fixed size (capped) collections, this size is the total/max size of the + collection. + capped: if true, this is a fixed size collection (where old data rolls out). + max: maximum number of objects if capped (optional). - returns true if successful. - */ - bool createCollection(const char *ns, unsigned size = 0, bool capped = false, int max = 0, BSONObj *info = 0); + returns true if successful. + */ + bool createCollection(const char *ns, unsigned size = 0, bool capped = false, int max = 0, BSONObj *info = 0); - /* Erase / drop an entire database */ - bool dropDatabase(const char *dbname, BSONObj *info = 0) { return simpleCommand(dbname, info, "dropDatabase"); } + /* Erase / drop an entire database */ + bool dropDatabase(const char *dbname, BSONObj *info = 0) { + return simpleCommand(dbname, info, "dropDatabase"); + } - /* Perform a repair and compaction of the specified database. May take a long time to run. Disk space - must be available equal to the size of the database while repairing. - */ - bool repairDatabase(const char *dbname, BSONObj *info = 0) { return simpleCommand(dbname, info, "repairDatabase"); } + /* Perform a repair and compaction of the specified database. May take a long time to run. Disk space + must be available equal to the size of the database while repairing. + */ + bool repairDatabase(const char *dbname, BSONObj *info = 0) { + return simpleCommand(dbname, info, "repairDatabase"); + } - /* Copy database from one server or name to another server or name. + /* Copy database from one server or name to another server or name. - Generally, you should dropDatabase() first as otherwise the copied information will MERGE - into whatever data is already present in this database. + Generally, you should dropDatabase() first as otherwise the copied information will MERGE + into whatever data is already present in this database. - For security reasons this function only works when you are authorized to access the "admin" db. However, - if you have access to said db, you can copy any database from one place to another. - TODO: this needs enhancement to be more flexible in terms of security. + For security reasons this function only works when you are authorized to access the "admin" db. However, + if you have access to said db, you can copy any database from one place to another. + TODO: this needs enhancement to be more flexible in terms of security. - This method provides a way to "rename" a database by copying it to a new db name and - location. The copy is "repaired" and compacted. + This method provides a way to "rename" a database by copying it to a new db name and + location. The copy is "repaired" and compacted. - fromdb database name from which to copy. - todb database name to copy to. - fromhost hostname of the database (and optionally, ":port") from which to - copy the data. copies from self if "". + fromdb database name from which to copy. + todb database name to copy to. + fromhost hostname of the database (and optionally, ":port") from which to + copy the data. copies from self if "". + + returns true if successful + */ + bool copyDatabase(const char *fromdb, const char *todb, const char *fromhost = "", BSONObj *info = 0); - returns true if successful + /* The Mongo database provides built-in performance profiling capabilities. Uset setDbProfilingLevel() + to enable. Profiling information is then written to the system.profiling collection, which one can + then query. */ - bool copyDatabase(const char *fromdb, const char *todb, const char *fromhost = "", BSONObj *info = 0); - - /* The Mongo database provides built-in performance profiling capabilities. Uset setDbProfilingLevel() - to enable. Profiling information is then written to the system.profiling collection, which one can - then query. - */ - enum ProfilingLevel { - ProfileOff = 0, - ProfileSlow = 1, // log very slow (>100ms) operations - ProfileAll = 2 - }; - bool setDbProfilingLevel(const char *dbname, ProfilingLevel level, BSONObj *info = 0); - bool getDbProfilingLevel(const char *dbname, ProfilingLevel& level, BSONObj *info = 0); - - /* Run javascript code on the database server. - dbname database context in which the code runs. The javascript variable 'db' will be assigned - to this database when the function is invoked. - jscode source code for a javascript function. - info the command object which contains any information on the invocation result including - the return value and other information. If an error occurs running the jscode, error - information will be in info. (try "cout << info.toString()") - retValue return value from the jscode function. - args args to pass to the jscode function. when invoked, the 'args' variable will be defined - for use by the jscode. - - returns true if runs ok. - - See testDbEval() in dbclient.cpp for an example of usage. - */ - bool eval(const char *dbname, const char *jscode, BSONObj& info, BSONElement& retValue, BSONObj *args = 0); - - /* The following helpers are simply more convenient forms of eval() for certain common cases */ - - /* invocation with no return value of interest -- with or without one simple parameter */ - bool eval(const char *dbname, const char *jscode); - template< class T > - bool eval(const char *dbname, const char *jscode, T parm1) { - BSONObj info; - BSONElement retValue; - BSONObjBuilder b; - b.append("0", parm1); - BSONObj args = b.done(); - return eval(dbname, jscode, info, retValue, &args); - } - - /* invocation with one parm to server and one numeric field (either int or double) returned */ - template< class T, class NumType > - bool eval(const char *dbname, const char *jscode, T parm1, NumType& ret) { - BSONObj info; - BSONElement retValue; - BSONObjBuilder b; - b.append("0", parm1); - BSONObj args = b.done(); - if( !eval(dbname, jscode, info, retValue, &args) ) - return false; - ret = (NumType) retValue.number(); - return true; - } - - virtual string toString() = 0; + enum ProfilingLevel { + ProfileOff = 0, + ProfileSlow = 1, // log very slow (>100ms) operations + ProfileAll = 2 + }; + bool setDbProfilingLevel(const char *dbname, ProfilingLevel level, BSONObj *info = 0); + bool getDbProfilingLevel(const char *dbname, ProfilingLevel& level, BSONObj *info = 0); + + /* Run javascript code on the database server. + dbname database context in which the code runs. The javascript variable 'db' will be assigned + to this database when the function is invoked. + jscode source code for a javascript function. + info the command object which contains any information on the invocation result including + the return value and other information. If an error occurs running the jscode, error + information will be in info. (try "cout << info.toString()") + retValue return value from the jscode function. + args args to pass to the jscode function. when invoked, the 'args' variable will be defined + for use by the jscode. + + returns true if runs ok. + + See testDbEval() in dbclient.cpp for an example of usage. + */ + bool eval(const char *dbname, const char *jscode, BSONObj& info, BSONElement& retValue, BSONObj *args = 0); + + /* The following helpers are simply more convenient forms of eval() for certain common cases */ + + /* invocation with no return value of interest -- with or without one simple parameter */ + bool eval(const char *dbname, const char *jscode); + template< class T > + bool eval(const char *dbname, const char *jscode, T parm1) { + BSONObj info; + BSONElement retValue; + BSONObjBuilder b; + b.append("0", parm1); + BSONObj args = b.done(); + return eval(dbname, jscode, info, retValue, &args); + } + + /* invocation with one parm to server and one numeric field (either int or double) returned */ + template< class T, class NumType > + bool eval(const char *dbname, const char *jscode, T parm1, NumType& ret) { + BSONObj info; + BSONElement retValue; + BSONObjBuilder b; + b.append("0", parm1); + BSONObj args = b.done(); + if ( !eval(dbname, jscode, info, retValue, &args) ) + return false; + ret = (NumType) retValue.number(); + return true; + } + + virtual string toString() = 0; }; class DBClientBase : public DBClientWithCommands, public DBConnector { @@ -310,7 +314,7 @@ public: fieldsToReturn: optional template of which fields to select. if unspecified, returns all fields queryOptions: see options enum at top of this file - + returns: cursor. 0 if error (connection failure) */ @@ -322,7 +326,7 @@ public: /*throws AssertionException*/ virtual BSONObj findOne(const char *ns, BSONObj query, BSONObj *fieldsToReturn = 0, int queryOptions = 0); - + virtual void insert( const char * ns , BSONObj obj ); virtual void remove( const char * ns , BSONObj obj , bool justOne = 0 ); @@ -429,7 +433,7 @@ public: virtual void insert( const char * ns , BSONObj obj ) { assert( false ); } - + string toString(); /* notification that we got a "not master" error. diff --git a/client/examples/clientTest.cpp b/client/examples/clientTest.cpp index baff71aaa26..c625f9d8f35 100644 --- a/client/examples/clientTest.cpp +++ b/client/examples/clientTest.cpp @@ -11,66 +11,66 @@ using namespace std; using namespace mongo; -int main(){ +int main() { DBClientConnection conn; string errmsg; - if ( ! conn.connect( "127.0.0.1" , errmsg ) ){ + if ( ! conn.connect( "127.0.0.1" , errmsg ) ) { cout << "couldn't connect : " << errmsg << endl; throw -11; } - + const char * ns = "test.test1"; // clean up old data from any previous tests conn.remove( ns, BSONObjBuilder().doneAndDecouple() ); assert( conn.findOne( ns , BSONObjBuilder().doneAndDecouple() ).isEmpty() ); - + // test insert conn.insert( ns ,BSONObjBuilder().append( "name" , "eliot" ).append( "num" , 1 ).doneAndDecouple() ); assert( ! conn.findOne( ns , BSONObjBuilder().doneAndDecouple() ).isEmpty() ); - + // test remove conn.remove( ns, BSONObjBuilder().doneAndDecouple() ); - assert( conn.findOne( ns , BSONObjBuilder().doneAndDecouple() ).isEmpty() ); - - + assert( conn.findOne( ns , BSONObjBuilder().doneAndDecouple() ).isEmpty() ); + + // insert, findOne testing - conn.insert( ns , BSONObjBuilder().append( "name" , "eliot" ).append( "num" , 1 ).doneAndDecouple() ); + conn.insert( ns , BSONObjBuilder().append( "name" , "eliot" ).append( "num" , 1 ).doneAndDecouple() ); { BSONObj res = conn.findOne( ns , BSONObjBuilder().doneAndDecouple() ); assert( strstr( res.getStringField( "name" ) , "eliot" ) ); assert( ! strstr( res.getStringField( "name2" ) , "eliot" ) ); assert( 1 == res.getIntField( "num" ) ); } - - + + // cursor - conn.insert( ns ,BSONObjBuilder().append( "name" , "sara" ).append( "num" , 2 ).doneAndDecouple() ); + conn.insert( ns ,BSONObjBuilder().append( "name" , "sara" ).append( "num" , 2 ).doneAndDecouple() ); { auto_ptr<DBClientCursor> cursor = conn.query( ns , BSONObjBuilder().doneAndDecouple() ); int count = 0; - while ( cursor->more() ){ + while ( cursor->more() ) { count++; BSONObj obj = cursor->next(); } assert( count == 2 ); } - + { auto_ptr<DBClientCursor> cursor = conn.query( ns , BSONObjBuilder().append( "num" , 1 ).doneAndDecouple() ); int count = 0; - while ( cursor->more() ){ + while ( cursor->more() ) { count++; BSONObj obj = cursor->next(); } assert( count == 1 ); } - + { auto_ptr<DBClientCursor> cursor = conn.query( ns , BSONObjBuilder().append( "num" , 3 ).doneAndDecouple() ); int count = 0; - while ( cursor->more() ){ + while ( cursor->more() ) { count++; BSONObj obj = cursor->next(); } @@ -81,24 +81,24 @@ int main(){ { BSONObj res = conn.findOne( ns , BSONObjBuilder().append( "name" , "eliot" ).doneAndDecouple() ); assert( ! strstr( res.getStringField( "name2" ) , "eliot" ) ); - + BSONObj after = BSONObjBuilder().appendElements( res ).append( "name2" , "h" ).doneAndDecouple(); - + conn.update( ns , BSONObjBuilder().append( "name" , "eliot2" ).doneAndDecouple() , after ); res = conn.findOne( ns , BSONObjBuilder().append( "name" , "eliot" ).doneAndDecouple() ); assert( ! strstr( res.getStringField( "name2" ) , "eliot" ) ); assert( conn.findOne( ns , BSONObjBuilder().append( "name" , "eliot2" ).doneAndDecouple() ).isEmpty() ); - + conn.update( ns , BSONObjBuilder().append( "name" , "eliot" ).doneAndDecouple() , after ); res = conn.findOne( ns , BSONObjBuilder().append( "name" , "eliot" ).doneAndDecouple() ); assert( strstr( res.getStringField( "name" ) , "eliot" ) ); assert( strstr( res.getStringField( "name2" ) , "h" ) ); - assert( conn.findOne( ns , BSONObjBuilder().append( "name" , "eliot2" ).doneAndDecouple() ).isEmpty() ); + assert( conn.findOne( ns , BSONObjBuilder().append( "name" , "eliot2" ).doneAndDecouple() ).isEmpty() ); // upsert conn.update( ns , BSONObjBuilder().append( "name" , "eliot2" ).doneAndDecouple() , after , 1 ); - assert( ! conn.findOne( ns , BSONObjBuilder().append( "name" , "eliot" ).doneAndDecouple() ).isEmpty() ); - + assert( ! conn.findOne( ns , BSONObjBuilder().append( "name" , "eliot" ).doneAndDecouple() ).isEmpty() ); + } { // ensure index diff --git a/client/examples/first.cpp b/client/examples/first.cpp index 3d2dd32f0b0..0adcef4446c 100644 --- a/client/examples/first.cpp +++ b/client/examples/first.cpp @@ -11,18 +11,18 @@ using namespace std; using namespace mongo; -void insert( DBClientConnection & conn , const char * name , int num ){ +void insert( DBClientConnection & conn , const char * name , int num ) { BSONObjBuilder obj; obj.append( "name" , name ); obj.append( "num" , num ); conn.insert( "test.people" , obj.doneAndDecouple() ); } -int main(){ +int main() { DBClientConnection conn; string errmsg; - if ( ! conn.connect( "127.0.0.1" , errmsg ) ){ + if ( ! conn.connect( "127.0.0.1" , errmsg ) ) { cout << "couldn't connect : " << errmsg << endl; throw -11; } @@ -31,21 +31,21 @@ int main(){ BSONObjBuilder query; conn.remove( "test.people" , query.doneAndDecouple() ); } - + insert( conn , "eliot" , 15 ); insert( conn , "sara" , 23 ); - + { BSONObjBuilder query; auto_ptr<DBClientCursor> cursor = conn.query( "test.people" , query.doneAndDecouple() ); cout << "using cursor" << endl; - while ( cursor->more() ){ + while ( cursor->more() ) { BSONObj obj = cursor->next(); cout << "\t" << obj.jsonString() << endl; } - + } - + { BSONObjBuilder query; query.append( "name" , "eliot" ); @@ -59,6 +59,6 @@ int main(){ BSONObj res = conn.findOne( "test.people" , query.doneAndDecouple() ); cout << res.isEmpty() << "\t" << res.jsonString() << endl; } - + } diff --git a/client/examples/second.cpp b/client/examples/second.cpp index e1bd8d4737f..f5802eec30a 100644 --- a/client/examples/second.cpp +++ b/client/examples/second.cpp @@ -7,11 +7,11 @@ using namespace std; using namespace mongo; -int main(){ +int main() { DBClientConnection conn; string errmsg; - if ( ! conn.connect( "127.0.0.1" , errmsg ) ){ + if ( ! conn.connect( "127.0.0.1" , errmsg ) ) { cout << "couldn't connect : " << errmsg << endl; throw -11; } @@ -19,13 +19,13 @@ int main(){ const char * ns = "test.second"; conn.remove( ns , emptyObj ); - + conn.insert( ns , BUILDOBJ( "name" << "eliot" << "num" << 17 ) ); conn.insert( ns , BUILDOBJ( "name" << "sara" << "num" << 24 ) ); auto_ptr<DBClientCursor> cursor = conn.query( ns , emptyObj ); cout << "using cursor" << endl; - while ( cursor->more() ){ + while ( cursor->more() ) { BSONObj obj = cursor->next(); cout << "\t" << obj.jsonString() << endl; } diff --git a/db/btreecursor.cpp b/db/btreecursor.cpp index 18ce967af97..b141cc24c36 100644 --- a/db/btreecursor.cpp +++ b/db/btreecursor.cpp @@ -69,8 +69,8 @@ void BtreeCursor::findExtremeKeys( const BSONObj &query ) { for ( set<string>::iterator i = fields.begin(); i != fields.end(); ++i ) { const char * field = i->c_str(); BSONElement k = indexDetails.keyPattern().getFieldDotted( field ); - int number = (int) k.number(); // returns 0.0 if not numeric - bool forward = ( ( number >= 0 ? 1 : -1 ) * direction > 0 ); + int number = (int) k.number(); // returns 0.0 if not numeric + bool forward = ( ( number >= 0 ? 1 : -1 ) * direction > 0 ); BSONElement lowest = minKey.firstElement(); BSONElement highest = maxKey.firstElement(); BSONElement e = query.getFieldDotted( field ); diff --git a/db/cloner.cpp b/db/cloner.cpp index 3f406f614a9..ddde078313e 100644 --- a/db/cloner.cpp +++ b/db/cloner.cpp @@ -137,7 +137,7 @@ bool Cloner::go(const char *masterHost, string& errmsg, const string& fromdb, bo dbtemprelease r; if ( !masterSameProcess ) { auto_ptr< DBClientConnection > c( new DBClientConnection() ); - if( !c->connect( masterHost, errmsg ) ) + if ( !c->connect( masterHost, errmsg ) ) return false; conn = c; } else { diff --git a/db/cursor.cpp b/db/cursor.cpp index ff0d132800a..3223195f412 100644 --- a/db/cursor.cpp +++ b/db/cursor.cpp @@ -30,8 +30,12 @@ class Reverse : public AdvanceStrategy { } } _reverse; -AdvanceStrategy *forward() { return &_forward; } -AdvanceStrategy *reverse() { return &_reverse; } +AdvanceStrategy *forward() { + return &_forward; +} +AdvanceStrategy *reverse() { + return &_reverse; +} DiskLoc nextLoop( NamespaceDetails *nsd, const DiskLoc &prev ) { assert( nsd->capLooped() ); @@ -50,8 +54,8 @@ DiskLoc prevLoop( NamespaceDetails *nsd, const DiskLoc &curr ) { } ForwardCappedCursor::ForwardCappedCursor( NamespaceDetails *_nsd ) : - BasicCursor( DiskLoc(), this ), - nsd( _nsd ) { + BasicCursor( DiskLoc(), this ), + nsd( _nsd ) { if ( !nsd ) return; DiskLoc start; @@ -79,18 +83,18 @@ DiskLoc ForwardCappedCursor::next( const DiskLoc &prev ) const { i = nextLoop( nsd, i ); // If we become capFirstNewRecord from same extent, advance to next extent. if ( i == nsd->capFirstNewRecord && - i != nsd->capExtent.ext()->firstRecord ) + i != nsd->capExtent.ext()->firstRecord ) i = nextLoop( nsd, nsd->capExtent.ext()->lastRecord ); // If we have just gotten to beginning of capExtent, skip to capFirstNewRecord if ( i == nsd->capExtent.ext()->firstRecord ) i = nsd->capFirstNewRecord; - + return i; } ReverseCappedCursor::ReverseCappedCursor( NamespaceDetails *_nsd ) : - BasicCursor( DiskLoc(), this ), - nsd( _nsd ) { + BasicCursor( DiskLoc(), this ), + nsd( _nsd ) { if ( !nsd ) return; DiskLoc start; @@ -105,7 +109,7 @@ DiskLoc ReverseCappedCursor::next( const DiskLoc &prev ) const { assert( nsd ); if ( !nsd->capLooped() ) return reverse()->next( prev ); - + DiskLoc i = prev; // Last record if ( nsd->capFirstNewRecord == nsd->capExtent.ext()->firstRecord ) { diff --git a/db/database.h b/db/database.h index 32e92bb76a9..47bffbd62a6 100644 --- a/db/database.h +++ b/db/database.h @@ -28,7 +28,7 @@ class Database { public: Database(const char *nm, bool& justCreated, const char *_path = dbpath) : name(nm), - path(_path) + path(_path) { { int L = strlen(nm); diff --git a/db/db.cpp b/db/db.cpp index cce208374fa..47d66601806 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -143,7 +143,7 @@ public: } // namespace mongo #include "lasterror.h" -#include "security.h" +#include "security.h" namespace mongo { @@ -196,7 +196,7 @@ void connThread() problem() << "Uncaught AssertionException, terminating" << endl; exit(15); } - catch( std::exception &e ) { + catch ( std::exception &e ) { problem() << "Uncaught std::exception: " << e.what() << ", terminating" << endl; exit( 15 ); } @@ -254,7 +254,7 @@ void repairDatabases() { dblock lk; vector< string > dbNames; getDatabaseNames( dbNames ); - for( vector< string >::iterator i = dbNames.begin(); i != dbNames.end(); ++i ) { + for ( vector< string >::iterator i = dbNames.begin(); i != dbNames.end(); ++i ) { string dbName = *i; assert( !setClientTempNs( dbName.c_str() ) ); PhysicalDataFile *p = database->getFile( 0 ); @@ -262,7 +262,7 @@ void repairDatabases() { if ( !h->currentVersion() ) { // QUESTION: Repair even if file format is higher version than code? log() << "repairing database " << dbName << " with pdfile version " << h->version << "." << h->versionMinor << ", " - << "new version: " << VERSION << "." << VERSION_MINOR << endl; + << "new version: " << VERSION << "." << VERSION_MINOR << endl; string errmsg; assert( repairDatabase( dbName.c_str(), errmsg ) ); } else { @@ -274,12 +274,12 @@ void repairDatabases() { void clearTmpFiles() { boost::filesystem::path path( dbpath ); for ( boost::filesystem::directory_iterator i( path ); - i != boost::filesystem::directory_iterator(); ++i ) { + i != boost::filesystem::directory_iterator(); ++i ) { string fileName = i->leaf(); if ( boost::filesystem::is_directory( *i ) && - fileName.length() > 2 && fileName.substr( 0, 3 ) == "tmp" ) + fileName.length() > 2 && fileName.substr( 0, 3 ) == "tmp" ) boost::filesystem::remove_all( *i ); - } + } } Timer startupSrandTimer; @@ -287,7 +287,7 @@ Timer startupSrandTimer; void segvhandler(int x); void initAndListen(int listenPort, const char *appserverLoc = null) { clearTmpFiles(); - + if ( opLogging ) log() << "opLogging = " << opLogging << endl; _oplog.init(); @@ -336,7 +336,7 @@ int main(int argc, char* argv[], char *envp[] ) { srand(curTimeMillis()); boost::filesystem::path::default_name_check( boost::filesystem::no_check ); - + { unsigned x = 0x12345678; unsigned char& b = (unsigned char&) x; @@ -439,8 +439,8 @@ int main(int argc, char* argv[], char *envp[] ) goto usage; else if ( s == "--quiet" ) quiet = true; - else if( s == "--cpu" ) - cpu = true; + else if ( s == "--cpu" ) + cpu = true; else if ( s == "--verbose" ) verbose = true; else if ( s == "--quota" ) @@ -497,7 +497,7 @@ usage: cout << " --port <portno> specify port number, default is 27017\n"; cout << " --dbpath <root> directory for datafiles, default is /data/db/\n"; cout << " --quiet quieter output\n"; - cout << " --cpu show cpu+iowait utilization periodically\n"; + cout << " --cpu show cpu+iowait utilization periodically\n"; cout << " --verbose\n"; cout << " --objcheck inspect client data for validity on receipt\n"; cout << " --quota enable db quota management\n"; diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp index dc6f7dcb206..a466db6256e 100644 --- a/db/dbcommands.cpp +++ b/db/dbcommands.cpp @@ -182,14 +182,18 @@ string validateNS(const char *ns, NamespaceDetails *d) { /* reset any errors so that getlasterror comes back clean. - useful before performing a long series of operations where we want to - see if any of the operations triggered an error, but don't want to check + useful before performing a long series of operations where we want to + see if any of the operations triggered an error, but don't want to check after each op as that woudl be a client/server turnaround. */ -class CmdResetError : public Command { +class CmdResetError : public Command { public: - virtual bool logTheOp() { return false; } - virtual bool slaveOk() { return true; } + virtual bool logTheOp() { + return false; + } + virtual bool slaveOk() { + return true; + } CmdResetError() : Command("reseterror") {} bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { LastError *le = lastError.get(); @@ -199,16 +203,20 @@ public: } } cmdResetError; -class CmdGetLastError : public Command { +class CmdGetLastError : public Command { public: - virtual bool logTheOp() { return false; } - virtual bool slaveOk() { return true; } + virtual bool logTheOp() { + return false; + } + virtual bool slaveOk() { + return true; + } CmdGetLastError() : Command("getlasterror") {} bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { LastError *le = lastError.get(); assert( le ); le->nPrev--; // we don't count as an operation - if( le->nPrev != 1 || !le->haveError() ) { + if ( le->nPrev != 1 || !le->haveError() ) { result.appendNull("err"); return true; } @@ -218,10 +226,14 @@ public: } cmdGetLastError; /* for testing purposes only */ -class CmdForceError : public Command { +class CmdForceError : public Command { public: - virtual bool logTheOp() { return false; } - virtual bool slaveOk() { return true; } + virtual bool logTheOp() { + return false; + } + virtual bool slaveOk() { + return true; + } CmdForceError() : Command("forceerror") {} bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { uassert("forced error", false); @@ -229,16 +241,20 @@ public: } } cmdForceError; -class CmdGetPrevError : public Command { +class CmdGetPrevError : public Command { public: - virtual bool logTheOp() { return false; } - virtual bool slaveOk() { return true; } + virtual bool logTheOp() { + return false; + } + virtual bool slaveOk() { + return true; + } CmdGetPrevError() : Command("getpreverror") {} bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { LastError *le = lastError.get(); assert( le ); le->nPrev--; // we don't count as an operation - if( !le->haveError() ) { + if ( !le->haveError() ) { result.appendNull("err"); result.append("nPrev", 1); return true; @@ -389,8 +405,8 @@ public: bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool) { opLogging = (int) cmdObj.findElement(name).number(); flushOpLog(); - if( !quiet ) - log() << "CMD: opLogging set to " << opLogging << endl; + if ( !quiet ) + log() << "CMD: opLogging set to " << opLogging << endl; return true; } } cmdoplogging; @@ -411,8 +427,8 @@ public: virtual bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool) { string nsToDrop = database->name + '.' + cmdObj.findElement(name).valuestr(); NamespaceDetails *d = nsdetails(nsToDrop.c_str()); - if( !quiet ) - log() << "CMD: drop " << nsToDrop << endl; + if ( !quiet ) + log() << "CMD: drop " << nsToDrop << endl; if ( d == 0 ) { errmsg = "ns not found"; return false; @@ -526,8 +542,8 @@ public: BSONElement e = jsobj.findElement(name.c_str()); string toDeleteNs = database->name + '.' + e.valuestr(); NamespaceDetails *d = nsdetails(toDeleteNs.c_str()); - if( !quiet ) - log() << "CMD: deleteIndexes " << toDeleteNs << endl; + if ( !quiet ) + log() << "CMD: deleteIndexes " << toDeleteNs << endl; if ( d ) { BSONElement f = jsobj.findElement("index"); if ( !f.eoo() ) { @@ -584,15 +600,21 @@ public: class CmdListDatabases : public Command { public: - virtual bool logTheOp() { return false; } - virtual bool slaveOk() { return true; } - virtual bool adminOnly() { return true; } + virtual bool logTheOp() { + return false; + } + virtual bool slaveOk() { + return true; + } + virtual bool adminOnly() { + return true; + } CmdListDatabases() : Command("listDatabases") {} bool run(const char *ns, BSONObj& jsobj, string& errmsg, BSONObjBuilder& result, bool /*fromRepl*/) { vector< string > dbNames; getDatabaseNames( dbNames ); vector< BSONObj > dbInfos; - for( vector< string >::iterator i = dbNames.begin(); i != dbNames.end(); ++i ) { + for ( vector< string >::iterator i = dbNames.begin(); i != dbNames.end(); ++i ) { BSONObjBuilder b; b.append( "name", i->c_str() ); b.append( "sizeOnDisk", (double) dbSize( i->c_str() ) ); @@ -613,8 +635,8 @@ extern map<string,Command*> *commands; returns true if ran a cmd */ bool _runCommands(const char *ns, BSONObj& _cmdobj, stringstream& ss, BufBuilder &b, BSONObjBuilder& anObjBuilder, bool fromRepl) { - if( verbose ) - log() << "run command " << ns << ' ' << _cmdobj.toString() << endl; + if ( verbose ) + log() << "run command " << ns << ' ' << _cmdobj.toString() << endl; const char *p = strchr(ns, '.'); if ( !p ) return false; @@ -674,8 +696,8 @@ bool _runCommands(const char *ns, BSONObj& _cmdobj, stringstream& ss, BufBuilder valid = true; string dropNs = us + '.' + e.valuestr(); NamespaceDetails *d = nsdetails(dropNs.c_str()); - if( !quiet ) - log() << "CMD: clean " << dropNs << endl; + if ( !quiet ) + log() << "CMD: clean " << dropNs << endl; if ( d ) { ok = true; anObjBuilder.append("ns", dropNs.c_str()); @@ -689,8 +711,8 @@ bool _runCommands(const char *ns, BSONObj& _cmdobj, stringstream& ss, BufBuilder valid = true; string toValidateNs = us + '.' + e.valuestr(); NamespaceDetails *d = nsdetails(toValidateNs.c_str()); - if( !quiet ) - log() << "CMD: validate " << toValidateNs << endl; + if ( !quiet ) + log() << "CMD: validate " << toValidateNs << endl; if ( d ) { ok = true; anObjBuilder.append("ns", toValidateNs.c_str()); diff --git a/db/dbeval.cpp b/db/dbeval.cpp index 3620211e6f7..de05394d10a 100644 --- a/db/dbeval.cpp +++ b/db/dbeval.cpp @@ -38,13 +38,18 @@ const int edebug=0; bool dbEval(const char *ns, BSONObj& cmd, BSONObjBuilder& result, string& errmsg) { BSONElement e = cmd.firstElement(); assert( e.type() == Code || e.type() == CodeWScope || e.type() == String ); - + const char *code = 0; - switch ( e.type() ){ - case String: - case Code: code = e.valuestr(); break; - case CodeWScope: code = e.codeWScopeCode(); break; - default: assert(0); + switch ( e.type() ) { + case String: + case Code: + code = e.valuestr(); + break; + case CodeWScope: + code = e.codeWScopeCode(); + break; + default: + assert(0); } assert( code ); @@ -80,7 +85,7 @@ bool dbEval(const char *ns, BSONObj& cmd, BSONObjBuilder& result, string& errmsg res = s.invoke(f); int m = t.millis(); if ( m > 100 ) { - stdcout() << "TEMP: dbeval too slow:" << endl; + stdcout() << "TEMP: dbeval too slow:" << endl; problem() << "dbeval time: " << dec << m << "ms " << ns << endl; OCCASIONALLY log() << code << endl; else if ( m >= 1000 ) log() << code << endl; @@ -92,7 +97,7 @@ bool dbEval(const char *ns, BSONObj& cmd, BSONObjBuilder& result, string& errmsg errmsg += s.getString( "error" ); return false; } - + int type = s.type("return"); if ( type == Object || type == Array ) result.append("retval", s.getObject("return")); diff --git a/db/dbmessage.h b/db/dbmessage.h index 9bbd989d2b1..2a5f78842d9 100644 --- a/db/dbmessage.h +++ b/db/dbmessage.h @@ -162,8 +162,8 @@ inline void replyToQuery(int queryResultFlags, BSONObj& responseObj) { replyToQuery(queryResultFlags, - p, requestMsg, - (void *) responseObj.objdata(), responseObj.objsize(), 1); + p, requestMsg, + (void *) responseObj.objdata(), responseObj.objsize(), 1); } } // namespace mongo diff --git a/db/dbwebserver.cpp b/db/dbwebserver.cpp index eaa7128cefd..26405150282 100644 --- a/db/dbwebserver.cpp +++ b/db/dbwebserver.cpp @@ -162,13 +162,13 @@ public: ) { //cout << "url [" << url << "]" << endl; - - if ( url.size() > 1 ){ + + if ( url.size() > 1 ) { handleRESTRequest( rq , url , responseMsg , responseCode , headers ); return; } - - + + responseCode = 200; stringstream ss; ss << "<html><head><title>"; @@ -204,33 +204,33 @@ public: ss << "</pre></body></html>"; responseMsg = ss.str(); } - + void handleRESTRequest( const char *rq, // the full request string url, string& responseMsg, int& responseCode, vector<string>& headers // if completely empty, content-type: text/html will be added - ){ - + ) { + string::size_type first = url.find( "/" , 1 ); - if ( first == string::npos ){ + if ( first == string::npos ) { responseCode = 400; return; } - + string method = parseMethod( rq ); string dbname = url.substr( 1 , first - 1 ); string coll = url.substr( first + 1 ); string action = ""; - + map<string,string> params; - if ( coll.find( "?" ) != string::npos ){ + if ( coll.find( "?" ) != string::npos ) { parseParams( params , coll.substr( coll.find( "?" ) + 1 ) ); coll = coll.substr( 0 , coll.find( "?" ) ); } - - string::size_type last = coll.find_last_of( "/" ); - if ( last == string::npos ){ + + string::size_type last = coll.find_last_of( "/" ); + if ( last == string::npos ) { action = coll; coll = "_defaultCollection"; } @@ -238,24 +238,24 @@ public: action = coll.substr( last + 1 ); coll = coll.substr( 0 , last ); } - + for ( string::size_type i=0; i<coll.size(); i++ ) if ( coll[i] == '/' ) coll[i] = '.'; - + string fullns = dbname + "." + coll; - + headers.push_back( (string)"x-action: " + action ); headers.push_back( (string)"x-ns: " + fullns ); headers.push_back( "Content-Type: text/plain;charset=utf-8" ); - + stringstream ss; - - if ( method == "GET" ){ + + if ( method == "GET" ) { responseCode = 200; handleRESTQuery( fullns , action , params , responseCode , ss ); } - else if ( method == "POST" ){ + else if ( method == "POST" ) { responseCode = 201; handlePost( fullns , body( rq ) , params , responseCode , ss ); } @@ -265,47 +265,47 @@ public: ss << "don't know how to handle a [" << method << "]"; cout << "don't know how to handle a [" << method << "]" << endl; } - + responseMsg = ss.str(); } - void handleRESTQuery( string ns , string action , map<string,string> & params , int & responseCode , stringstream & out ){ + void handleRESTQuery( string ns , string action , map<string,string> & params , int & responseCode , stringstream & out ) { Timer t; - + int skip = _getOption( params["skip"] , 0 ); int num = _getOption( params["limit"] , _getOption( params["count" ] , 1000 ) ); // count is old, limit is new int one = 0; - if ( params["one"].size() > 0 && tolower( params["one"][0] ) == 't' ){ + if ( params["one"].size() > 0 && tolower( params["one"][0] ) == 't' ) { num = 1; one = 1; } - + BSONObjBuilder queryBuilder; - - for ( map<string,string>::iterator i = params.begin(); i != params.end(); i++ ){ + + for ( map<string,string>::iterator i = params.begin(); i != params.end(); i++ ) { if ( ! i->first.find( "filter_" ) == 0 ) continue; - + const char * field = i->first.substr( 7 ).c_str(); const char * val = i->second.c_str(); char * temp; - + // TODO: this is how i guess if something is a number. pretty lame right now double number = strtod( val , &temp ); if ( temp != val ) queryBuilder.append( field , number ); - else + else queryBuilder.append( field , val ); } BSONObj query = queryBuilder.doneAndDecouple(); auto_ptr<DBClientCursor> cursor = db.query( ns.c_str() , query, num , skip ); - - if ( one ){ - if ( cursor->more() ){ + + if ( one ) { + if ( cursor->more() ) { BSONObj obj = cursor->next(); out << obj.jsonString() << "\n"; } @@ -318,17 +318,17 @@ public: out << "{\n"; out << " \"offset\" : " << skip << ",\n"; out << " \"rows\": [\n"; - + int howMany = 0; - while ( cursor->more() ){ + while ( cursor->more() ) { if ( howMany++ ) out << " ,\n"; BSONObj obj = cursor->next(); out << " " << obj.jsonString(); - + } out << "\n ]\n\n"; - + out << " \"total_rows\" : " << howMany << " ,\n"; out << " \"query\" : " << query.jsonString() << " ,\n"; out << " \"millis\" : " << t.millis() << " ,\n"; @@ -336,7 +336,7 @@ public: } // TODO Generate id and revision per couch POST spec - void handlePost( string ns, const char *body, map<string,string> & params, int & responseCode, stringstream & out ){ + void handlePost( string ns, const char *body, map<string,string> & params, int & responseCode, stringstream & out ) { try { BSONObj obj = fromjson( body ); db.insert( ns.c_str(), obj ); @@ -345,17 +345,17 @@ public: out << "{ \"ok\" : false }"; return; } - + responseCode = 201; out << "{ \"ok\" : true }"; } - int _getOption( string val , int def ){ + int _getOption( string val , int def ) { if ( val.size() == 0 ) return def; return atoi( val.c_str() ); } - + private: static DBDirectClient db; }; diff --git a/db/flushtest.cpp b/db/flushtest.cpp index 64911a7e9a3..1c153df5c8e 100644 --- a/db/flushtest.cpp +++ b/db/flushtest.cpp @@ -10,125 +10,129 @@ namespace mongo { #undef endl #if defined(F_FULLFSYNC) -void fullsync(int f) { fcntl( f, F_FULLFSYNC ); } +void fullsync(int f) { + fcntl( f, F_FULLFSYNC ); +} #else -void fullsync(int f) { fdatasync(f); } +void fullsync(int f) { + fdatasync(f); +} #endif int main(int argc, char* argv[], char *envp[] ) { - cout << "hello" << endl; + cout << "hello" << endl; + + FILE *f = fopen("/data/db/temptest", "a"); + + if ( f == 0 ) { + cout << "can't open file\n"; + return 1; + } - FILE *f = fopen("/data/db/temptest", "a"); + { + Timer t; + for ( int i = 0; i < 50000; i++ ) + fwrite("abc", 3, 1, f); + cout << "small writes: " << t.millis() << "ms" << endl; + } - if( f == 0 ) { - cout << "can't open file\n"; - return 1; - } + { + Timer t; + for ( int i = 0; i < 10000; i++ ) { + fwrite("abc", 3, 1, f); + fflush(f); + fsync( fileno( f ) ); + } + int ms = t.millis(); + cout << "flush: " << ms << "ms, " << ms / 10000.0 << "ms/request" << endl; + } - { - Timer t; - for( int i = 0; i < 50000; i++ ) - fwrite("abc", 3, 1, f); - cout << "small writes: " << t.millis() << "ms" << endl; - } - - { - Timer t; - for( int i = 0; i < 10000; i++ ) { - fwrite("abc", 3, 1, f); - fflush(f); - fsync( fileno( f ) ); - } - int ms = t.millis(); - cout << "flush: " << ms << "ms, " << ms / 10000.0 << "ms/request" << endl; - } + { + Timer t; + for ( int i = 0; i < 500; i++ ) { + fwrite("abc", 3, 1, f); + fflush(f); + fsync( fileno( f ) ); + sleepmillis(2); + } + int ms = t.millis() - 500 * 2; + cout << "flush with sleeps: " << ms << "ms, " << ms / 500.0 << "ms/request" << endl; + } - { - Timer t; - for( int i = 0; i < 500; i++ ) { - fwrite("abc", 3, 1, f); - fflush(f); - fsync( fileno( f ) ); - sleepmillis(2); - } - int ms = t.millis() - 500 * 2; - cout << "flush with sleeps: " << ms << "ms, " << ms / 500.0 << "ms/request" << endl; - } + char buf[8192]; + for ( int pass = 0; pass < 2; pass++ ) { + cout << "pass " << pass << endl; + { + Timer t; + int n = 500; + for ( int i = 0; i < n; i++ ) { + if ( pass == 0 ) + fwrite("abc", 3, 1, f); + else + fwrite(buf, 8192, 1, f); + buf[0]++; + fflush(f); + fullsync(fileno(f)); + } + int ms = t.millis(); + cout << "fullsync: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; + } - char buf[8192]; - for( int pass = 0; pass < 2; pass++ ) { - cout << "pass " << pass << endl; - { - Timer t; - int n = 500; - for( int i = 0; i < n; i++ ) { - if( pass == 0 ) - fwrite("abc", 3, 1, f); - else - fwrite(buf, 8192, 1, f); - buf[0]++; - fflush(f); - fullsync(fileno(f)); - } - int ms = t.millis(); - cout << "fullsync: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; - } + { + Timer t; + for ( int i = 0; i < 500; i++ ) { + if ( pass == 0 ) + fwrite("abc", 3, 1, f); + else + fwrite(buf, 8192, 1, f); + buf[0]++; + fflush(f); + fullsync(fileno(f)); + sleepmillis(2); + } + int ms = t.millis() - 2 * 500; + cout << "fullsync with sleeps: " << ms << "ms, " << ms / 500.0 << "ms/request" << endl; + } + } - { - Timer t; - for( int i = 0; i < 500; i++ ) { - if( pass == 0 ) - fwrite("abc", 3, 1, f); - else - fwrite(buf, 8192, 1, f); - buf[0]++; - fflush(f); - fullsync(fileno(f)); - sleepmillis(2); - } - int ms = t.millis() - 2 * 500; - cout << "fullsync with sleeps: " << ms << "ms, " << ms / 500.0 << "ms/request" << endl; - } - } + // without growing + { + fclose(f); + /* try from beginning of the file, where we aren't appending and changing the file length, + to see if this is faster as the directory entry then doesn't have to be flushed (if noatime in effect). + */ + f = fopen("/data/db/temptest", "r+"); + Timer t; + int n = 500; + for ( int i = 0; i < n; i++ ) { + fwrite("xyz", 3, 1, f); + fflush(f); + fullsync(fileno(f)); + } + int ms = t.millis(); + cout << "fullsync without growing: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; + } - // without growing - { - fclose(f); - /* try from beginning of the file, where we aren't appending and changing the file length, - to see if this is faster as the directory entry then doesn't have to be flushed (if noatime in effect). - */ - f = fopen("/data/db/temptest", "r+"); - Timer t; - int n = 500; - for( int i = 0; i < n; i++ ) { - fwrite("xyz", 3, 1, f); - fflush(f); - fullsync(fileno(f)); - } - int ms = t.millis(); - cout << "fullsync without growing: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; - } + // without growing, with delay + { + fclose(f); + /* try from beginning of the file, where we aren't appending and changing the file length, + to see if this is faster as the directory entry then doesn't have to be flushed (if noatime in effect). + */ + f = fopen("/data/db/temptest", "r+"); + Timer t; + int n = 500; + for ( int i = 0; i < n; i++ ) { + fwrite("xyz", 3, 1, f); + fflush(f); + fullsync(fileno(f)); + sleepmillis(2); + } + int ms = t.millis() - 2 * 500; + cout << "fullsync without growing with sleeps: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; + } - // without growing, with delay - { - fclose(f); - /* try from beginning of the file, where we aren't appending and changing the file length, - to see if this is faster as the directory entry then doesn't have to be flushed (if noatime in effect). - */ - f = fopen("/data/db/temptest", "r+"); - Timer t; - int n = 500; - for( int i = 0; i < n; i++ ) { - fwrite("xyz", 3, 1, f); - fflush(f); - fullsync(fileno(f)); - sleepmillis(2); - } - int ms = t.millis() - 2 * 500; - cout << "fullsync without growing with sleeps: " << ms << "ms, " << ms / ((double) n) << "ms/request" << endl; - } - - return 0; + return 0; } } // namespace mongo diff --git a/db/instance.cpp b/db/instance.cpp index d3a18daae2c..40cb435a288 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -488,14 +488,14 @@ void jniCallback(Message& m, Message& out) void getDatabaseNames( vector< string > &names ) { boost::filesystem::path path( dbpath ); for ( boost::filesystem::directory_iterator i( path ); - i != boost::filesystem::directory_iterator(); ++i ) { + i != boost::filesystem::directory_iterator(); ++i ) { string fileName = i->leaf(); if ( fileName.length() > 3 && fileName.substr( fileName.length() - 3, 3 ) == ".ns" ) names.push_back( fileName.substr( 0, fileName.length() - 3 ) ); } } -bool DBDirectClient::call( Message &toSend, Message &response, bool assertOk ){ +bool DBDirectClient::call( Message &toSend, Message &response, bool assertOk ) { DbResponse dbResponse; assembleResponse( toSend, dbResponse ); assert( dbResponse.response ); @@ -505,7 +505,7 @@ bool DBDirectClient::call( Message &toSend, Message &response, bool assertOk ){ void DBDirectClient::say( Message &toSend ) { DbResponse dbResponse; - assembleResponse( toSend, dbResponse ); + assembleResponse( toSend, dbResponse ); } /* not using log() herein in case we are called from segvhandler and we were already locked */ diff --git a/db/instance.h b/db/instance.h index 28f90171392..52bba249637 100644 --- a/db/instance.h +++ b/db/instance.h @@ -93,10 +93,12 @@ void getDatabaseNames( vector< string > &names ); // --- local client --- class DBDirectClient : public DBClientBase { - virtual string toString() { return "DBDirectClient"; } + virtual string toString() { + return "DBDirectClient"; + } virtual bool call( Message &toSend, Message &response, bool assertOk=true ); virtual void say( Message &toSend ); - virtual void sayPiggyBack( Message &toSend ){ + virtual void sayPiggyBack( Message &toSend ) { // don't need to piggy back when connected locally return say( toSend ); } diff --git a/db/javajs.cpp b/db/javajs.cpp index b508d8da7cc..97194359db2 100644 --- a/db/javajs.cpp +++ b/db/javajs.cpp @@ -115,50 +115,50 @@ JavaJSImpl::JavaJSImpl(const char *appserverPath) { _jvm = 0; _mainEnv = 0; _dbhook = 0; - + stringstream ss; string edTemp; - + const char * ed = 0; ss << "-Djava.class.path=."; - - if ( appserverPath ){ + + if ( appserverPath ) { ed = findEd(appserverPath); assert( ed ); ss << SYSTEM_COLON << ed << "/build/"; - + _addClassPath( ed , ss , "include" ); _addClassPath( ed , ss , "include/jython/" ); _addClassPath( ed , ss , "include/jython/javalib" ); } else { - + const char * jars = findJars(); _addClassPath( jars , ss , "jars" ); - + edTemp += (string)jars + "/jars/babble.jar"; ed = edTemp.c_str(); #if !defined(_WIN32) const char * otherEd = findEd(); - if ( otherEd ){ + if ( otherEd ) { log() << "found ed as well" << endl; ed = otherEd; ss << SYSTEM_COLON << ed << "/build/"; - + _addClassPath( ed , ss , "include" ); _addClassPath( ed , ss , "include/jython/" ); - _addClassPath( ed , ss , "include/jython/javalib" ); + _addClassPath( ed , ss , "include/jython/javalib" ); } - + #endif } - + #if defined(_WIN32) ss << SYSTEM_COLON << "C:\\Program Files\\Java\\jdk\\lib\\tools.jar"; #else @@ -217,13 +217,13 @@ JavaJSImpl::JavaJSImpl(const char *appserverPath) { _envs->reset( _mainEnv ); _dbhook = findClass( "ed/db/JSHook" ); - if ( _dbhook == 0 ){ + if ( _dbhook == 0 ) { log() << "using classpath: " << q << endl; printException(); } jassert( _dbhook ); - if ( ed ){ + if ( ed ) { jmethodID init = _mainEnv->GetStaticMethodID( _dbhook , "init" , "(Ljava/lang/String;)V" ); jassert( init ); _mainEnv->CallStaticVoidMethod( _dbhook , init , _getEnv()->NewStringUTF( ed ) ); @@ -562,14 +562,14 @@ const char * findEd() { #endif }; -const char * findJars(){ +const char * findJars() { static list<const char*> possible; if ( ! possible.size() ) { possible.push_back( "./" ); possible.push_back( "../" ); } - + for ( list<const char*>::iterator i = possible.begin() ; i != possible.end(); i++ ) { const char * temp = *i; const string jarDir = ((string)temp) + "jars/"; @@ -610,7 +610,7 @@ JNIEXPORT jint JNICALL java_native_call(JNIEnv * env , jclass, jobject outBuffer jniCallback( out , in ); curNs = 0; - + JNI_DEBUG( "in.data : " << in.data ); if ( in.data && in.data->len > 0 ) { JNI_DEBUG( "copying data of len :" << in.data->len ); diff --git a/db/jsobj.cpp b/db/jsobj.cpp index 9a4e7dcbc71..c97f316b13b 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -114,182 +114,182 @@ string BSONElement::toString() const { string escape( string s ) { stringstream ret; - for( string::iterator i = s.begin(); i != s.end(); ++i ) { - switch( *i ) { - case '"': - ret << "\\\""; - break; - case '\\': - ret << "\\\\"; - break; - case '/': - ret << "\\/"; - break; - case '\b': - ret << "\\b"; - break; - case '\f': - ret << "\\f"; - break; - case '\n': - ret << "\\n"; - break; - case '\r': - ret << "\\r"; - break; - case '\t': - ret << "\\t"; - break; - default: - if ( *i >= 0 && *i <= 0x1f ) { - ret << "\\u"; - ret << hex; - ret.width( 4 ); - ret.fill( '0' ); - ret << int( *i ); - } else { - ret << *i; - } + for ( string::iterator i = s.begin(); i != s.end(); ++i ) { + switch ( *i ) { + case '"': + ret << "\\\""; + break; + case '\\': + ret << "\\\\"; + break; + case '/': + ret << "\\/"; + break; + case '\b': + ret << "\\b"; + break; + case '\f': + ret << "\\f"; + break; + case '\n': + ret << "\\n"; + break; + case '\r': + ret << "\\r"; + break; + case '\t': + ret << "\\t"; + break; + default: + if ( *i >= 0 && *i <= 0x1f ) { + ret << "\\u"; + ret << hex; + ret.width( 4 ); + ret.fill( '0' ); + ret << int( *i ); + } else { + ret << *i; + } } } return ret.str(); } typedef boost::archive::iterators::base64_from_binary - < boost::archive::iterators::transform_width - < string::const_iterator, 6, 8 > - > base64_t; +< boost::archive::iterators::transform_width +< string::const_iterator, 6, 8 > +> base64_t; string BSONElement::jsonString( JsonStringFormat format, bool includeFieldNames ) const { stringstream s; if ( includeFieldNames ) - s << '"' << escape( fieldName() ) << "\" : "; + s << '"' << escape( fieldName() ) << "\" : "; switch ( type() ) { - case String: - case Symbol: - s << '"' << escape( valuestr() ) << '"'; - break; - case NumberInt: - case NumberDouble: - if ( number() >= -numeric_limits< double >::max() && + case String: + case Symbol: + s << '"' << escape( valuestr() ) << '"'; + break; + case NumberInt: + case NumberDouble: + if ( number() >= -numeric_limits< double >::max() && number() <= numeric_limits< double >::max() ) { - s.precision( 16 ); - s << number(); - } else { - stringstream ss; - ss << "Number " << number() << " cannot be represented in JSON"; - string message = ss.str(); - massert( message.c_str(), false ); - } - break; - case Bool: - s << ( boolean() ? "true" : "false" ); - break; - case jstNULL: - s << "null"; - break; - case Object: - s << embeddedObject().jsonString( format ); - break; - case Array: { - if ( embeddedObject().isEmpty() ) { - s << "[]"; - break; - } - s << "[ "; - BSONObjIterator i( embeddedObject() ); - BSONElement e = i.next(); - if ( !e.eoo() ) - while ( 1 ) { - s << e.jsonString( format, false ); - e = i.next(); - if ( e.eoo() ) - break; - s << ", "; - } - s << " ]"; - break; - } - case DBRef: { - OID *x = (OID *) (valuestr() + valuestrsize()); - if ( format == TenGen ) - s << "Dbref( "; - else - s << "{ \"$ns\" : "; - s << '"' << valuestr() << "\", "; - if ( format != TenGen ) - s << "\"$id\" : "; - s << '"' << *x << "\" "; - if ( format == TenGen ) - s << ')'; - else - s << '}'; - break; + s.precision( 16 ); + s << number(); + } else { + stringstream ss; + ss << "Number " << number() << " cannot be represented in JSON"; + string message = ss.str(); + massert( message.c_str(), false ); } - case jstOID: - if ( format == TenGen ) - s << "ObjectId( "; - s << '"' << oid() << '"'; - if ( format == TenGen ) - s << " )"; - break; - case BinData: { - int len = *(int *)( value() ); - BinDataType type = BinDataType( *(char *)( (int *)( value() ) + 1 ) ); - s << "{ \"$binary\" : \""; - char *start = ( char * )( value() ) + sizeof( int ) + 1; - string temp(start, len); - string base64 = string( base64_t( temp.begin() ), base64_t( temp.end() ) ); - s << base64; - int padding = ( 4 - ( base64.length() % 4 ) ) % 4; - for( int i = 0; i < padding; ++i ) - s << '='; - s << "\", \"$type\" : \"" << hex; - s.width( 2 ); - s.fill( '0' ); - s << type << dec; - s << "\" }"; + break; + case Bool: + s << ( boolean() ? "true" : "false" ); + break; + case jstNULL: + s << "null"; + break; + case Object: + s << embeddedObject().jsonString( format ); + break; + case Array: { + if ( embeddedObject().isEmpty() ) { + s << "[]"; break; } - case Date: - if ( format == Strict ) - s << "{ \"$date\" : "; - else - s << "Date( "; - s << date(); - if ( format == Strict ) - s << " }"; - else - s << " )"; - break; - case RegEx: - if ( format == Strict ) - s << "{ \"$regex\" : \""; - else - s << "/"; - s << escape( regex() ); - if ( format == Strict ) - s << "\", \"$options\" : \"" << regexFlags() << "\" }"; - else { - s << "/"; - // FIXME Worry about alpha order? - for( const char *f = regexFlags(); *f; ++f ) - switch( *f ) { - case 'g': - case 'i': - case 'm': - s << *f; - default: - break; - } + s << "[ "; + BSONObjIterator i( embeddedObject() ); + BSONElement e = i.next(); + if ( !e.eoo() ) + while ( 1 ) { + s << e.jsonString( format, false ); + e = i.next(); + if ( e.eoo() ) + break; + s << ", "; } - break; - default: - stringstream ss; - ss << "Cannot create a properly formatted JSON string with " - << "element: " << toString() << " of type: " << type(); - string message = ss.str(); - massert( message.c_str(), false ); + s << " ]"; + break; + } + case DBRef: { + OID *x = (OID *) (valuestr() + valuestrsize()); + if ( format == TenGen ) + s << "Dbref( "; + else + s << "{ \"$ns\" : "; + s << '"' << valuestr() << "\", "; + if ( format != TenGen ) + s << "\"$id\" : "; + s << '"' << *x << "\" "; + if ( format == TenGen ) + s << ')'; + else + s << '}'; + break; + } + case jstOID: + if ( format == TenGen ) + s << "ObjectId( "; + s << '"' << oid() << '"'; + if ( format == TenGen ) + s << " )"; + break; + case BinData: { + int len = *(int *)( value() ); + BinDataType type = BinDataType( *(char *)( (int *)( value() ) + 1 ) ); + s << "{ \"$binary\" : \""; + char *start = ( char * )( value() ) + sizeof( int ) + 1; + string temp(start, len); + string base64 = string( base64_t( temp.begin() ), base64_t( temp.end() ) ); + s << base64; + int padding = ( 4 - ( base64.length() % 4 ) ) % 4; + for ( int i = 0; i < padding; ++i ) + s << '='; + s << "\", \"$type\" : \"" << hex; + s.width( 2 ); + s.fill( '0' ); + s << type << dec; + s << "\" }"; + break; + } + case Date: + if ( format == Strict ) + s << "{ \"$date\" : "; + else + s << "Date( "; + s << date(); + if ( format == Strict ) + s << " }"; + else + s << " )"; + break; + case RegEx: + if ( format == Strict ) + s << "{ \"$regex\" : \""; + else + s << "/"; + s << escape( regex() ); + if ( format == Strict ) + s << "\", \"$options\" : \"" << regexFlags() << "\" }"; + else { + s << "/"; + // FIXME Worry about alpha order? + for ( const char *f = regexFlags(); *f; ++f ) + switch ( *f ) { + case 'g': + case 'i': + case 'm': + s << *f; + default: + break; + } + } + break; + default: + stringstream ss; + ss << "Cannot create a properly formatted JSON string with " + << "element: " << toString() << " of type: " << type(); + string message = ss.str(); + massert( message.c_str(), false ); } return s.str(); } @@ -518,7 +518,7 @@ string BSONObj::toString() const { string BSONObj::jsonString( JsonStringFormat format ) const { if ( isEmpty() ) return "{}"; - + stringstream s; s << "{ "; BSONObjIterator i(*this); @@ -555,7 +555,7 @@ int BSONObj::woCompare(const BSONObj &r, const BSONObj &idxKey, return 1; bool ordered = !idxKey.isEmpty(); - + BSONObjIterator i(*this); BSONObjIterator j(r); BSONObjIterator k(idxKey); @@ -878,22 +878,22 @@ struct BsonUnitTest : public UnitTest { -BSONObjBuilderValueStream::BSONObjBuilderValueStream( const char * fieldName , BSONObjBuilder * builder ){ +BSONObjBuilderValueStream::BSONObjBuilderValueStream( const char * fieldName , BSONObjBuilder * builder ) { _fieldName = fieldName; _builder = builder; } - -BSONObjBuilder& BSONObjBuilderValueStream::operator<<( const char * value ){ + +BSONObjBuilder& BSONObjBuilderValueStream::operator<<( const char * value ) { _builder->append( _fieldName , value ); return *_builder; } -BSONObjBuilder& BSONObjBuilderValueStream::operator<<( const int value ){ +BSONObjBuilder& BSONObjBuilderValueStream::operator<<( const int value ) { _builder->appendInt( _fieldName , value ); return *_builder; } -BSONObjBuilder& BSONObjBuilderValueStream::operator<<( const double value ){ +BSONObjBuilder& BSONObjBuilderValueStream::operator<<( const double value ) { _builder->append( _fieldName , value ); return *_builder; } diff --git a/db/jsobj.h b/db/jsobj.h index 8f9c8b0e261..f8af23835d2 100644 --- a/db/jsobj.h +++ b/db/jsobj.h @@ -77,7 +77,7 @@ public: s.width( 8 ); s << b; s << dec; - return s.str(); + return s.str(); } }; ostream& operator<<( ostream &s, const OID &o ); @@ -108,8 +108,8 @@ ostream& operator<<( ostream &s, const OID &o ); */ /* Formatting mode for generating a JSON from the 10gen representation. - Strict - strict RFC format - TenGen - 10gen format, which is close to JS format. This form is understandable by + Strict - strict RFC format + TenGen - 10gen format, which is close to JS format. This form is understandable by javascript running inside the Mongo server via eval() JS - Javascript JSON compatible */ @@ -120,7 +120,7 @@ enum JsonStringFormat { Strict, TenGen, JS }; /* BSONElement represents an "element" in a BSONObj. So for the object { a : 3, b : "abc" }, 'a : 3' is the first element (key+value). - The BSONElement object points into the BSONObj's data. Thus the BSONObj must stay in scope + The BSONElement object points into the BSONObj's data. Thus the BSONObj must stay in scope for the life of the BSONElement. <type><fieldName ><value> @@ -328,10 +328,10 @@ public: // Readable representation of a 10gen object. string toString() const; - + // Properly formatted JSON string. string jsonString( JsonStringFormat format = Strict ) const; - + /* note: addFields always adds _id even if not specified */ int addFields(BSONObj& from, set<string>& fields); /* returns n added */ @@ -353,7 +353,7 @@ public: BSONElement getFieldDottedOrArray(const char *&name) const; BSONElement getField(const string name) const { - return getField( name.c_str() ); + return getField( name.c_str() ); }; BSONElement getField(const char *name) const; /* return has eoo() true if no match */ @@ -514,7 +514,7 @@ typedef set< BSONObj, BSONObjCmpDefaultOrder > BSONObjSetDefaultOrder; class BSONObjBuilderValueStream { public: BSONObjBuilderValueStream( const char * fieldName , BSONObjBuilder * builder ); - + BSONObjBuilder& operator<<( const char * value ); BSONObjBuilder& operator<<( const int value ); BSONObjBuilder& operator<<( const double value ); @@ -551,10 +551,10 @@ public: b.append(fieldName); b.append((void *) subObj.objdata(), subObj.objsize()); } - - /* add a subobject as a member with type Array. Thus arr object should have "0", "1", ... - style fields in it. - */ + + /* add a subobject as a member with type Array. Thus arr object should have "0", "1", ... + style fields in it. + */ void appendArray(const char *fieldName, BSONObj subObj) { b.append((char) Array); b.append(fieldName); @@ -649,7 +649,7 @@ public: b.append( (char) type ); b.append( (void *) data, len ); } - + template < class T > void append( const char *fieldName, const vector< T >& vals ) { BSONObjBuilder arrBuilder; @@ -697,15 +697,15 @@ public: return o.str(); } - BSONObjBuilderValueStream operator<<(const char * name ){ + BSONObjBuilderValueStream operator<<(const char * name ) { return BSONObjBuilderValueStream( name , this ); } - BSONObjBuilderValueStream operator<<( string name ){ + BSONObjBuilderValueStream operator<<( string name ) { return BSONObjBuilderValueStream( name.c_str() , this ); } - + private: // Append the provided arr object as an array. void marshalArray( const char *fieldName, const BSONObj &arr ) { diff --git a/db/json.cpp b/db/json.cpp index 24ea7e8d16f..05cc669486e 100644 --- a/db/json.cpp +++ b/db/json.cpp @@ -25,9 +25,13 @@ using namespace boost::spirit; namespace mongo { struct ObjectBuilder { - BSONObjBuilder *back() { return builders.back().get(); } + BSONObjBuilder *back() { + return builders.back().get(); + } // Storage for field names of elements within builders.back(). - const char *fieldName() { return fieldNames.back().c_str(); } + const char *fieldName() { + return fieldNames.back().c_str(); + } void push() { boost::shared_ptr< BSONObjBuilder > b( new BSONObjBuilder() ); builders.push_back( b ); @@ -42,7 +46,7 @@ struct ObjectBuilder { return ret; } void nameFromIndex() { - fieldNames.back() = BSONObjBuilder::numStr( indexes.back() ); + fieldNames.back() = BSONObjBuilder::numStr( indexes.back() ); } string popString() { string ret = ss.str(); @@ -101,33 +105,33 @@ struct chE { chE( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char c ) const { char o = '\0'; - switch( c ) { - case '\"': - o = '\"'; - break; - case '\\': - o = '\\'; - break; - case '/': - o = '/'; - break; - case 'b': - o = '\b'; - break; - case 'f': - o = '\f'; - break; - case 'n': - o = '\n'; - break; - case 'r': - o = '\r'; - break; - case 't': - o = '\t'; - break; - default: - assert( false ); + switch ( c ) { + case '\"': + o = '\"'; + break; + case '\\': + o = '\\'; + break; + case '/': + o = '/'; + break; + case 'b': + o = '\b'; + break; + case 'f': + o = '\f'; + break; + case 'n': + o = '\n'; + break; + case 'r': + o = '\r'; + break; + case 't': + o = '\t'; + break; + default: + assert( false ); } b.ss << o; } @@ -135,19 +139,19 @@ struct chE { }; namespace hex { - int val( char c ) { - if ( '0' <= c && c <= '9' ) - return c - '0'; - if ( 'a' <= c && c <= 'f' ) - return c - 'a' + 10; - if ( 'A' <= c && c <= 'F' ) - return c - 'A' + 10; - assert( false ); - return 0xff; - } - char val( const char *c ) { - return ( val( c[ 0 ] ) << 4 ) | val( c[ 1 ] ); - } +int val( char c ) { + if ( '0' <= c && c <= '9' ) + return c - '0'; + if ( 'a' <= c && c <= 'f' ) + return c - 'a' + 10; + if ( 'A' <= c && c <= 'F' ) + return c - 'A' + 10; + assert( false ); + return 0xff; +} +char val( const char *c ) { + return ( val( c[ 0 ] ) << 4 ) | val( c[ 1 ] ); +} } // namespace hex struct chU { @@ -182,16 +186,16 @@ struct fieldNameEnd { void operator() ( const char *start, const char *end ) const { string name = b.popString(); massert( "Invalid use of reserved field name", - name != "$ns" && - name != "$id" && - name != "$binary" && - name != "$type" && - name != "$date" && - name != "$regex" && - name != "$options" ); + name != "$ns" && + name != "$id" && + name != "$binary" && + name != "$type" && + name != "$date" && + name != "$regex" && + name != "$options" ); b.fieldNames.back() = name; } - ObjectBuilder &b; + ObjectBuilder &b; }; struct stringEnd { @@ -264,7 +268,7 @@ struct dbrefNS { OID stringToOid( const char *s ) { OID oid; char *oidP = (char *)( &oid ); - for( int i = 0; i < 12; ++i ) + for ( int i = 0; i < 12; ++i ) oidP[ i ] = hex::val( s[ i * 2 ] ); return oid; } @@ -301,23 +305,23 @@ struct oidEnd { // boost's conversion. struct binDataBinary { typedef - boost::archive::iterators::transform_width - < boost::archive::iterators::binary_from_base64 - < string::const_iterator >, 8, 6 - > binary_t; + boost::archive::iterators::transform_width + < boost::archive::iterators::binary_from_base64 + < string::const_iterator >, 8, 6 + > binary_t; binDataBinary( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char *start, const char *end ) const { massert( "Badly formatted bindata", ( end - start ) % 4 == 0 ); string base64( start, end ); int len = base64.length(); int pad = 0; - for(; len - pad > 0 && base64[ len - 1 - pad ] == '='; ++pad ) + for (; len - pad > 0 && base64[ len - 1 - pad ] == '='; ++pad ) base64[ len - 1 - pad ] = 'A'; massert( "Badly formatted bindata", pad < 3 ); b.binData = string( binary_t( base64.begin() ), binary_t( base64.end() ) ); b.binData.resize( b.binData.length() - pad ); } - ObjectBuilder &b; + ObjectBuilder &b; }; struct binDataType { @@ -332,7 +336,7 @@ struct binDataEnd { binDataEnd( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char *start, const char *end ) const { b.back()->appendBinData( b.fieldName(), b.binData.length(), - b.binDataType, b.binData.data() ); + b.binDataType, b.binData.data() ); } ObjectBuilder &b; }; @@ -358,7 +362,7 @@ struct regexValue { void operator() ( const char *start, const char *end ) const { b.regex = b.popString(); } - ObjectBuilder &b; + ObjectBuilder &b; }; struct regexOptions { @@ -366,16 +370,16 @@ struct regexOptions { void operator() ( const char *start, const char *end ) const { b.regexOptions = string( start, end ); } - ObjectBuilder &b; + ObjectBuilder &b; }; struct regexEnd { regexEnd( ObjectBuilder &_b ) : b( _b ) {} void operator() ( const char *start, const char *end ) const { b.back()->appendRegex( b.fieldName(), b.regex.c_str(), - b.regexOptions.c_str() ); + b.regexOptions.c_str() ); } - ObjectBuilder &b; + ObjectBuilder &b; }; // One gotcha with this parsing library is probably best ilustrated with an @@ -395,7 +399,7 @@ struct regexEnd { struct JsonGrammar : public grammar< JsonGrammar > { public: JsonGrammar( ObjectBuilder &_b ) : b( _b ) {} - + template < typename ScannerT > struct definition { definition( JsonGrammar const &self ) { @@ -420,38 +424,38 @@ public: lexeme_d[ str_p( "null" ) ][ nullValue( self.b ) ]; // lexeme_d and rules don't mix well, so we have this mess str = lexeme_d[ ch_p( '"' )[ chClear( self.b ) ] >> - *( ( ch_p( '\\' ) >> - ( ch_p( '"' )[ chE( self.b ) ] | - ch_p( '\\' )[ chE( self.b ) ] | - ch_p( '/' )[ chE( self.b ) ] | - ch_p( 'b' )[ chE( self.b ) ] | - ch_p( 'f' )[ chE( self.b ) ] | - ch_p( 'n' )[ chE( self.b ) ] | - ch_p( 'r' )[ chE( self.b ) ] | - ch_p( 't' )[ chE( self.b ) ] | - ( ch_p( 'u' ) >> ( repeat_p( 4 )[ xdigit_p ][ chU( self.b ) ] ) ) ) ) | - ch_p( '\x7f' )[ ch( self.b ) ] | - ( ~cntrl_p & ~ch_p( '"' ) & ( ~ch_p( '\\' ) )[ ch( self.b ) ] ) ) >> '"' ]; + *( ( ch_p( '\\' ) >> + ( ch_p( '"' )[ chE( self.b ) ] | + ch_p( '\\' )[ chE( self.b ) ] | + ch_p( '/' )[ chE( self.b ) ] | + ch_p( 'b' )[ chE( self.b ) ] | + ch_p( 'f' )[ chE( self.b ) ] | + ch_p( 'n' )[ chE( self.b ) ] | + ch_p( 'r' )[ chE( self.b ) ] | + ch_p( 't' )[ chE( self.b ) ] | + ( ch_p( 'u' ) >> ( repeat_p( 4 )[ xdigit_p ][ chU( self.b ) ] ) ) ) ) | + ch_p( '\x7f' )[ ch( self.b ) ] | + ( ~cntrl_p & ~ch_p( '"' ) & ( ~ch_p( '\\' ) )[ ch( self.b ) ] ) ) >> '"' ]; // real_p accepts numbers with nonsignificant zero prefixes, which // aren't allowed in JSON. Oh well. number = real_p[ numberValue( self.b ) ]; dbref = dbrefS | dbrefT; dbrefS = ch_p( '{' ) >> "\"$ns\"" >> ':' >> - str[ dbrefNS( self.b ) ] >> ',' >> "\"$id\"" >> ':' >> quotedOid >> '}'; + str[ dbrefNS( self.b ) ] >> ',' >> "\"$id\"" >> ':' >> quotedOid >> '}'; dbrefT = str_p( "Dbref" ) >> '(' >> str[ dbrefNS( self.b ) ] >> ',' >> - quotedOid >> ')'; + quotedOid >> ')'; // FIXME Only object id if top level field? oid = oidS | oidT; oidS = str_p( "\"_id\"" ) >> ':' >> quotedOid; oidT = str_p( "\"_id\"" ) >> ':' >> "ObjectId" >> '(' >> quotedOid >> ')'; - + quotedOid = lexeme_d[ '"' >> ( repeat_p( 24 )[ xdigit_p ] )[ oidValue( self.b ) ] >> '"' ]; - + bindata = ch_p( '{' ) >> "\"$binary\"" >> ':' >> - lexeme_d[ '"' >> ( *( range_p( 'A', 'Z' ) | range_p( 'a', 'z' ) | range_p( '0', '9' ) | ch_p( '+' ) | ch_p( '/' ) ) >> *ch_p( '=' ) )[ binDataBinary( self.b ) ] >> '"' ] >> ',' >> "\"$type\"" >> ':' >> - lexeme_d[ '"' >> ( repeat_p( 2 )[ xdigit_p ] )[ binDataType( self.b ) ] >> '"' ] >> '}'; + lexeme_d[ '"' >> ( *( range_p( 'A', 'Z' ) | range_p( 'a', 'z' ) | range_p( '0', '9' ) | ch_p( '+' ) | ch_p( '/' ) ) >> *ch_p( '=' ) )[ binDataBinary( self.b ) ] >> '"' ] >> ',' >> "\"$type\"" >> ':' >> + lexeme_d[ '"' >> ( repeat_p( 2 )[ xdigit_p ] )[ binDataType( self.b ) ] >> '"' ] >> '}'; date = dateS | dateT; dateS = ch_p( '{' ) >> "\"$date\"" >> ':' >> uint_parser< unsigned long long >()[ dateValue( self.b ) ] >> '}'; @@ -461,24 +465,26 @@ public: regexS = ch_p( '{' ) >> "\"$regex\"" >> ':' >> str[ regexValue( self.b ) ] >> ',' >> "\"$options\"" >> ':' >> lexeme_d[ '"' >> ( *( alpha_p ) )[ regexOptions( self.b ) ] >> '"' ] >> '}'; // FIXME Obviously it would be nice to unify this with str. regexT = lexeme_d[ ch_p( '/' )[ chClear( self.b ) ] >> - *( ( ch_p( '\\' ) >> - ( ch_p( '"' )[ chE( self.b ) ] | - ch_p( '\\' )[ chE( self.b ) ] | - ch_p( '/' )[ chE( self.b ) ] | - ch_p( 'b' )[ chE( self.b ) ] | - ch_p( 'f' )[ chE( self.b ) ] | - ch_p( 'n' )[ chE( self.b ) ] | - ch_p( 'r' )[ chE( self.b ) ] | - ch_p( 't' )[ chE( self.b ) ] | - ( ch_p( 'u' ) >> ( repeat_p( 4 )[ xdigit_p ][ chU( self.b ) ] ) ) ) ) | - ch_p( '\x7f' )[ ch( self.b ) ] | - ( ~cntrl_p & ~ch_p( '/' ) & ( ~ch_p( '\\' ) )[ ch( self.b ) ] ) ) >> str_p( "/" )[ regexValue( self.b ) ] - >> ( *( ch_p( 'i' ) | ch_p( 'g' ) | ch_p( 'm' ) ) )[ regexOptions( self.b ) ] ]; + *( ( ch_p( '\\' ) >> + ( ch_p( '"' )[ chE( self.b ) ] | + ch_p( '\\' )[ chE( self.b ) ] | + ch_p( '/' )[ chE( self.b ) ] | + ch_p( 'b' )[ chE( self.b ) ] | + ch_p( 'f' )[ chE( self.b ) ] | + ch_p( 'n' )[ chE( self.b ) ] | + ch_p( 'r' )[ chE( self.b ) ] | + ch_p( 't' )[ chE( self.b ) ] | + ( ch_p( 'u' ) >> ( repeat_p( 4 )[ xdigit_p ][ chU( self.b ) ] ) ) ) ) | + ch_p( '\x7f' )[ ch( self.b ) ] | + ( ~cntrl_p & ~ch_p( '/' ) & ( ~ch_p( '\\' ) )[ ch( self.b ) ] ) ) >> str_p( "/" )[ regexValue( self.b ) ] + >> ( *( ch_p( 'i' ) | ch_p( 'g' ) | ch_p( 'm' ) ) )[ regexOptions( self.b ) ] ]; } rule< ScannerT > object, members, pair, array, elements, value, str, number, - dbref, dbrefS, dbrefT, oid, oidS, oidT, bindata, date, dateS, dateT, - regex, regexS, regexT, quotedOid; - const rule< ScannerT > &start() const { return object; } + dbref, dbrefS, dbrefT, oid, oidS, oidT, bindata, date, dateS, dateT, + regex, regexS, regexT, quotedOid; + const rule< ScannerT > &start() const { + return object; + } }; ObjectBuilder &b; }; diff --git a/db/lasterror.h b/db/lasterror.h index 8f5b59c55b0..d251a5971c2 100644 --- a/db/lasterror.h +++ b/db/lasterror.h @@ -1,6 +1,6 @@ // lasterror.h
-/** +/**
* Copyright (C) 2009 10gen Inc. * * This program is free software: you can redistribute it and/or modify @@ -15,34 +15,40 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -
-#pragma once
-
-#include <boost/thread/tss.hpp>
+ +#pragma once + +#include <boost/thread/tss.hpp> namespace mongo { -
-struct LastError {
- string msg;
- int nPrev;
- void raiseError(const char *_msg) {
- msg = _msg;
- nPrev = 1;
+ +struct LastError { + string msg; + int nPrev; + void raiseError(const char *_msg) { + msg = _msg; + nPrev = 1; + } + bool haveError() const { + return !msg.empty(); + } + void resetError() { + msg.clear(); + }
+ LastError() {
+ nPrev = 0;
}
- bool haveError() const { return !msg.empty(); }
- void resetError() { msg.clear(); }
- LastError() { nPrev = 0; }
};
extern boost::thread_specific_ptr<LastError> lastError;
inline void raiseError(const char *msg) {
LastError *le = lastError.get();
- if( le == 0 ) {
+ if ( le == 0 ) {
DEV log() << "warning: lastError==0 can't report:" << msg << '\n';
return;
}
le->raiseError(msg);
}
- -} // namespace mongo +
+} // namespace mongo
diff --git a/db/namespace.cpp b/db/namespace.cpp index 33ee30b9af3..54731757c7e 100644 --- a/db/namespace.cpp +++ b/db/namespace.cpp @@ -74,14 +74,14 @@ void NamespaceDetails::addDeletedRec(DeletedRecord *d, DiskLoc dloc) { dassert( dloc.drec() == d ); DEBUGGING cout << "TEMP: add deleted rec " << dloc.toString() << ' ' << hex << d->extentOfs << endl; if ( capped ) { - if( !deletedList[ 1 ].isValid() ) { + if ( !deletedList[ 1 ].isValid() ) { // Initial extent allocation. Insert at end. d->nextDeleted = DiskLoc(); if ( deletedList[ 0 ].isNull() ) deletedList[ 0 ] = dloc; else { DiskLoc i = deletedList[ 0 ]; - for(; !i.drec()->nextDeleted.isNull(); i = i.drec()->nextDeleted ); + for (; !i.drec()->nextDeleted.isNull(); i = i.drec()->nextDeleted ); i.drec()->nextDeleted = dloc; } } else { @@ -132,9 +132,9 @@ DiskLoc NamespaceDetails::alloc(const char *ns, int lenToAlloc, DiskLoc& extentL newDel->extentOfs = r->extentOfs; newDel->lengthWithHeaders = left; newDel->nextDeleted.Null(); - + addDeletedRec(newDel, newDelLoc); - + return loc; } @@ -241,15 +241,15 @@ void NamespaceDetails::dumpDeleted(set<DiskLoc> *extents) { */ void NamespaceDetails::compact() { assert(capped); - + list<DiskLoc> drecs; // Pull out capExtent's DRs from deletedList DiskLoc i = firstDeletedInCapExtent(); - for(; !i.isNull() && inCapExtent( i ); i = i.drec()->nextDeleted ) + for (; !i.isNull() && inCapExtent( i ); i = i.drec()->nextDeleted ) drecs.push_back( i ); firstDeletedInCapExtent() = i; - + // This is the O(n^2) part. drecs.sort(); @@ -282,8 +282,8 @@ void NamespaceDetails::compact() { } DiskLoc NamespaceDetails::firstRecord( const DiskLoc &startExtent ) const { - for(DiskLoc i = startExtent.isNull() ? firstExtent : startExtent; - !i.isNull(); i = i.ext()->xnext ) { + for (DiskLoc i = startExtent.isNull() ? firstExtent : startExtent; + !i.isNull(); i = i.ext()->xnext ) { if ( !i.ext()->firstRecord.isNull() ) return i.ext()->firstRecord; } @@ -291,8 +291,8 @@ DiskLoc NamespaceDetails::firstRecord( const DiskLoc &startExtent ) const { } DiskLoc NamespaceDetails::lastRecord( const DiskLoc &startExtent ) const { - for(DiskLoc i = startExtent.isNull() ? lastExtent : startExtent; - !i.isNull(); i = i.ext()->xprev ) { + for (DiskLoc i = startExtent.isNull() ? lastExtent : startExtent; + !i.isNull(); i = i.ext()->xprev ) { if ( !i.ext()->lastRecord.isNull() ) return i.ext()->lastRecord; } @@ -327,7 +327,7 @@ void NamespaceDetails::advanceCapExtent( const char *ns ) { deletedList[ 1 ] = DiskLoc(); else { DiskLoc i = firstDeletedInCapExtent(); - for(; !i.isNull() && nextIsInCapExtent( i ); i = i.drec()->nextDeleted ); + for (; !i.isNull() && nextIsInCapExtent( i ); i = i.drec()->nextDeleted ); deletedList[ 1 ] = i; } @@ -342,14 +342,14 @@ void NamespaceDetails::maybeComplain( const char *ns, int len ) const { if ( ++n_complaints_cap < 8 ) { cout << "couldn't make room for new record (len: " << len << ") in capped ns " << ns << '\n'; int i = 0; - for( DiskLoc e = firstExtent; !e.isNull(); e = e.ext()->xnext, ++i ) { + for ( DiskLoc e = firstExtent; !e.isNull(); e = e.ext()->xnext, ++i ) { cout << " Extent " << i; if ( e == capExtent ) cout << " (capExtent)"; cout << '\n'; cout << " magic: " << hex << e.ext()->magic << dec << " extent->ns: " << e.ext()->ns.buf << '\n'; cout << " fr: " << e.ext()->firstRecord.toString() << - " lr: " << e.ext()->lastRecord.toString() << " extent->len: " << e.ext()->length << '\n'; + " lr: " << e.ext()->lastRecord.toString() << " extent->len: " << e.ext()->length << '\n'; } assert( len * 5 > lastExtentSize ); // assume it is unusually large record; if not, something is broken } @@ -359,7 +359,7 @@ DiskLoc NamespaceDetails::__capAlloc( int len ) { DiskLoc prev = deletedList[ 1 ]; DiskLoc i = firstDeletedInCapExtent(); DiskLoc ret; - for(; !i.isNull() && inCapExtent( i ); prev = i, i = i.drec()->nextDeleted ) { + for (; !i.isNull() && inCapExtent( i ); prev = i, i = i.drec()->nextDeleted ) { // We need to keep at least one DR per extent in deletedList[ 0 ], // so make sure there's space to create a DR at the end. if ( i.drec()->lengthWithHeaders >= len + 24 ) { @@ -367,7 +367,7 @@ DiskLoc NamespaceDetails::__capAlloc( int len ) { break; } } - + /* unlink ourself from the deleted list */ if ( !ret.isNull() ) { if ( prev.isNull() ) @@ -387,21 +387,21 @@ void NamespaceDetails::checkMigrate() { capFirstNewRecord = DiskLoc(); capFirstNewRecord.setInvalid(); // put all the DeletedRecords in deletedList[ 0 ] - for( int i = 1; i < Buckets; ++i ) { + for ( int i = 1; i < Buckets; ++i ) { DiskLoc first = deletedList[ i ]; if ( first.isNull() ) continue; DiskLoc last = first; - for(; !last.drec()->nextDeleted.isNull(); last = last.drec()->nextDeleted ); + for (; !last.drec()->nextDeleted.isNull(); last = last.drec()->nextDeleted ); last.drec()->nextDeleted = deletedList[ 0 ]; deletedList[ 0 ] = first; deletedList[ i ] = DiskLoc(); } // NOTE deletedList[ 1 ] set to DiskLoc() in above - + // Last, in case we're killed before getting here capExtent = firstExtent; - } + } } /* alloc with capped table handling. */ @@ -410,7 +410,7 @@ DiskLoc NamespaceDetails::_alloc(const char *ns, int len) { return __stdAlloc(len); // capped. - + // signal done allocating new extents. if ( !deletedList[ 1 ].isValid() ) deletedList[ 1 ] = DiskLoc(); @@ -438,15 +438,15 @@ DiskLoc NamespaceDetails::_alloc(const char *ns, int len) { // else signal done with first iteration through extents. continue; } - + if ( !capFirstNewRecord.isNull() && - theCapExtent()->firstRecord == capFirstNewRecord ) { + theCapExtent()->firstRecord == capFirstNewRecord ) { // We've deleted all records that were allocated on the previous // iteration through this extent. advanceCapExtent( ns ); continue; } - + if ( theCapExtent()->firstRecord.isNull() ) { if ( firstEmptyExtent.isNull() ) firstEmptyExtent = capExtent; @@ -519,7 +519,7 @@ void NamespaceDetailsTransient::computeIndexKeys() { options: { capped : ..., size : ... } */ void addNewNamespaceToCatalog(const char *ns, BSONObj *options = 0) { - if( verbose ) + if ( verbose ) log() << "New namespace: " << ns << '\n'; if ( strstr(ns, "system.namespaces") ) { // system.namespaces holds all the others, so it is not explicitly listed in the catalog. diff --git a/db/namespace.h b/db/namespace.h index 3509133a8b9..76e73a57a13 100644 --- a/db/namespace.h +++ b/db/namespace.h @@ -68,7 +68,7 @@ public: /** ( foo.bar ).getSisterNS( "blah" ) == foo.blah */ - string getSisterNS( const char * local ){ + string getSisterNS( const char * local ) { assert( local && local[0] != '.' ); string old(buf); if ( old.find( "." ) != string::npos ) @@ -246,9 +246,9 @@ public: void dumpDeleted(set<DiskLoc> *extents = 0); bool capLooped() const { - return capped && capFirstNewRecord.isValid(); + return capped && capFirstNewRecord.isValid(); } - + // Start from firstExtent by default. DiskLoc firstRecord( const DiskLoc &startExtent = DiskLoc() ) const; @@ -258,16 +258,18 @@ public: bool inCapExtent( const DiskLoc &dl ) const; void checkMigrate(); - + private: - Extent *theCapExtent() const { return capExtent.ext(); } + Extent *theCapExtent() const { + return capExtent.ext(); + } void advanceCapExtent( const char *ns ); void maybeComplain( const char *ns, int len ) const; DiskLoc __stdAlloc(int len); DiskLoc __capAlloc(int len); DiskLoc _alloc(const char *ns, int len); void compact(); - + DiskLoc &firstDeletedInCapExtent(); bool nextIsInCapExtent( const DiskLoc &dl ) const; }; diff --git a/db/pdfile.cpp b/db/pdfile.cpp index ccf5806784c..fb8e09389c1 100644 --- a/db/pdfile.cpp +++ b/db/pdfile.cpp @@ -101,7 +101,7 @@ bool _userCreateNS(const char *ns, BSONObj& j, string& err) { return false; } - if( verbose ) + if ( verbose ) log() << "create collection " << ns << ' ' << j.toString() << '\n'; /* todo: do this only when we have allocated space successfully? or we could insert with a { ok: 0 } field @@ -127,17 +127,17 @@ bool _userCreateNS(const char *ns, BSONObj& j, string& err) { mx = (int) e.number(); } } - + // $nExtents just for debug/testing. We create '$nExtents' extents, // each of size 'size'. e = j.findElement( "$nExtents" ); int nExtents = int( e.number() ); if ( nExtents > 0 ) - for( int i = 0; i < nExtents; ++i ) { + for ( int i = 0; i < nExtents; ++i ) { database->suitableFile(size)->newExtent( ns, size, newCapped ); } else - while( size > 0 ) { + while ( size > 0 ) { int max = PhysicalDataFile::maxSize() - PDFHeader::headerSize(); int desiredExtentSize = size > max ? max : size; Extent *e = database->suitableFile( desiredExtentSize )->newExtent( ns, desiredExtentSize, newCapped ); @@ -149,7 +149,7 @@ bool _userCreateNS(const char *ns, BSONObj& j, string& err) { if ( mx > 0 ) d->max = mx; - + return true; } @@ -174,12 +174,12 @@ int PhysicalDataFile::maxSize() { int PhysicalDataFile::defaultSize( const char *filename ) const { int size; - + if ( fileNo <= 4 ) size = (64*1024*1024) << fileNo; else size = 0x7ff00000; - + if ( strstr(filename, "_hudsonSmall") ) { int mult = 1; if ( fileNo > 1 && fileNo < 1000 ) @@ -211,13 +211,13 @@ void PhysicalDataFile::open( const char *filename, int minSize ) { } int size = defaultSize( filename ); - while( size < minSize ) { + while ( size < minSize ) { if ( size < maxSize() / 2 ) - size *= 2; - else { - size = maxSize(); - break; - } + size *= 2; + else { + size = maxSize(); + break; + } } if ( size > maxSize() ) size = maxSize(); @@ -812,7 +812,7 @@ void ensureHaveIdIndex(const char *ns) { theDataFileMgr.insert(system_indexes.c_str(), o.objdata(), o.objsize()); } -DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god) { +DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god) { bool addIndex = false; const char *sys = strstr(ns, "system."); if ( sys ) { @@ -1069,15 +1069,19 @@ boost::intmax_t dbSize( const char *database ) { class SizeAccumulator : public FileOp { public: SizeAccumulator() : totalSize_( 0 ) {} - boost::intmax_t size() const { return totalSize_; } + boost::intmax_t size() const { + return totalSize_; + } private: virtual bool apply( const boost::filesystem::path &p ) { - if( !boost::filesystem::exists( p ) ) + if ( !boost::filesystem::exists( p ) ) return false; totalSize_ += boost::filesystem::file_size( p ); return true; } - virtual const char *op() const { return "checking size"; } + virtual const char *op() const { + return "checking size"; + } boost::intmax_t totalSize_; }; SizeAccumulator sa; @@ -1101,7 +1105,7 @@ boost::intmax_t freeSpace() { } bool repairDatabase( const char *ns, string &errmsg, - bool preserveClonedFilesOnFailure, bool backupOriginalFiles ) { + bool preserveClonedFilesOnFailure, bool backupOriginalFiles ) { stringstream ss; ss << "localhost:" << port; string localhost = ss.str(); @@ -1117,15 +1121,15 @@ bool repairDatabase( const char *ns, string &errmsg, if ( freeSize > -1 && freeSize < totalSize ) { stringstream ss; ss << "Cannot repair database " << dbName << " having size: " << totalSize - << " (bytes) because free disk space is: " << freeSize << " (bytes)"; + << " (bytes) because free disk space is: " << freeSize << " (bytes)"; errmsg = ss.str(); problem() << errmsg << endl; return false; } - + Path reservedPath = uniqueReservedPath( ( preserveClonedFilesOnFailure || backupOriginalFiles ) ? - "backup" : "tmp" ); + "backup" : "tmp" ); BOOST_CHECK_EXCEPTION( boost::filesystem::create_directory( reservedPath ) ); string reservedPathString = reservedPath.native_directory_string(); assert( setClient( dbName, reservedPathString.c_str() ) ); diff --git a/db/pdfile.h b/db/pdfile.h index 92186920f79..dbd7e893ddd 100644 --- a/db/pdfile.h +++ b/db/pdfile.h @@ -323,7 +323,7 @@ inline DiskLoc Record::getPrev(const DiskLoc& myLoc) { return DiskLoc(); return e->xprev.ext()->lastRecord; } - + inline Record* DiskLoc::rec() const { return DataFileMgr::getRecord(*this); } @@ -387,7 +387,7 @@ inline void _applyOpToDataFiles( const char *database, FileOp &fo, const char *p q = p / ss.str(); BOOST_CHECK_EXCEPTION( ok = fo.apply(q) ); if ( ok ) { - if( verbose || extra != 10 ) + if ( verbose || extra != 10 ) log() << fo.op() << " file " << q.string() << '\n'; if ( extra != 10 ) log() << " _applyOpToDataFiles() warning: extra == " << extra << endl; diff --git a/db/query.cpp b/db/query.cpp index f38fae6824c..dcfe4705ebd 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -50,7 +50,7 @@ int matchDirection( const BSONObj &index, const BSONObj &sort ) { int direction = 0; BSONObjIterator i( index ); BSONObjIterator s( sort ); - while( 1 ) { + while ( 1 ) { BSONElement ie = i.next(); BSONElement se = s.next(); if ( ie.eoo() ) { @@ -60,7 +60,7 @@ int matchDirection( const BSONObj &index, const BSONObj &sort ) { } if ( strcmp( ie.fieldName(), se.fieldName() ) != 0 ) return 0; - + int d = ie.number() == se.number() ? 1 : -1; if ( direction == 0 ) direction = d; @@ -274,7 +274,7 @@ int deleteObjects(const char *ns, BSONObj pattern, bool justOne, bool god) { c->checkLocation(); } } - + return nDeleted; } diff --git a/db/repl.cpp b/db/repl.cpp index 2a2b7e5f6b3..c516335547b 100644 --- a/db/repl.cpp +++ b/db/repl.cpp @@ -122,7 +122,7 @@ void ReplPair::arbitrate() { return; } - /* todo: make an arbitrate command we send to the arbiter instead of this */ + /* todo: make an arbitrate command we send to the arbiter instead of this */ bool is_master; bool ok = conn->isMaster(is_master); if ( !ok ) { @@ -584,12 +584,12 @@ void ReplSource::sync_pullOpLog_applyOperation(BSONObj& op) { dblock lk; bool justCreated; - try { - justCreated = setClientTempNs(ns); - } catch( AssertionException& ) { - problem() << "skipping bad(?) op in oplog, setClient() failed, ns: '" << ns << "'\n"; - addDbNextPass.erase(clientName); - return; + try { + justCreated = setClientTempNs(ns); + } catch ( AssertionException& ) { + problem() << "skipping bad(?) op in oplog, setClient() failed, ns: '" << ns << "'\n"; + addDbNextPass.erase(clientName); + return; } if ( allDead ) { @@ -1138,7 +1138,7 @@ void startReplication() { */ //boost::thread tempt(tempThread); - if( !slave && !master && !replPair ) + if ( !slave && !master && !replPair ) return; { diff --git a/db/replset.h b/db/replset.h index 7ba3978d43b..c08372aeb47 100644 --- a/db/replset.h +++ b/db/replset.h @@ -146,7 +146,7 @@ public: PairSync() { initialsynccomplete = -1; } - + /* call before using the class. from dbmutex */ void init() { BSONObj o; @@ -154,17 +154,17 @@ public: if ( getSingleton("local.pair.sync", o) ) initialsynccomplete = 1; } - + bool initialSyncCompleted() { return initialsynccomplete != 0; } - + void setInitialSyncCompleted() { BSONObj o = fromjson("{\"initialsynccomplete\":1}"); putSingleton("local.pair.sync", o); initialsynccomplete = 1; } - + void setInitialSyncCompletedLocking() { if ( initialsynccomplete == 1 ) return; diff --git a/db/security.cpp b/db/security.cpp index 3d78bfe6921..b8da6553d8b 100644 --- a/db/security.cpp +++ b/db/security.cpp @@ -2,20 +2,20 @@ #include "stdafx.h"
#include "security.h"
-#include "../util/md5.hpp" - -namespace mongo { - -extern "C" int do_md5_test(void); +#include "../util/md5.hpp"
+
+namespace mongo {
+
+extern "C" int do_md5_test(void);
boost::thread_specific_ptr<AuthenticationInfo> authInfo;
typedef unsigned long long nonce;
-struct Security {
+struct Security {
ifstream *devrandom;
- nonce getNonce() {
+ nonce getNonce() {
nonce n;
#if defined(__linux__)
devrandom->read((char*)&n, sizeof(n));
@@ -27,45 +27,53 @@ struct Security { }
Security()
- {
+ {
#if defined(__linux__)
devrandom = new ifstream("/dev/urandom", ios::binary|ios::in);
massert( "can't open dev/urandom", devrandom->is_open() );
#endif
assert( sizeof(nonce) == 8 );
- if( do_md5_test() ) - massert("md5 unit test fails", false); + if ( do_md5_test() )
+ massert("md5 unit test fails", false);
}
} security;
-} // namespace mongo - +} // namespace mongo
+
#include "commands.h"
#include "jsobj.h"
- -namespace mongo { -
-class CmdGetNonce : public Command { -public: - virtual bool logTheOp() { return false; } - virtual bool slaveOk() { return true; } - CmdGetNonce() : Command("getnonce") {} - bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { - result.append("nonce", (double) security.getNonce()); - return true; - } -} cmdGetNonce; - -class CmdAuthenticate : public Command { -public: - virtual bool logTheOp() { return false; } - virtual bool slaveOk() { return true; } - CmdAuthenticate() : Command("authenticate") {} - bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { - return false; - } -} cmdAuthenticate; - - -} // namespace mongo +
+namespace mongo {
+
+class CmdGetNonce : public Command {
+public:
+ virtual bool logTheOp() {
+ return false;
+ }
+ virtual bool slaveOk() {
+ return true;
+ }
+ CmdGetNonce() : Command("getnonce") {}
+ bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
+ result.append("nonce", (double) security.getNonce());
+ return true;
+ }
+} cmdGetNonce;
+
+class CmdAuthenticate : public Command {
+public:
+ virtual bool logTheOp() {
+ return false;
+ }
+ virtual bool slaveOk() {
+ return true;
+ }
+ CmdAuthenticate() : Command("authenticate") {}
+ bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) {
+ return false;
+ }
+} cmdAuthenticate;
+
+
+} // namespace mongo
diff --git a/db/security.h b/db/security.h index 9526a9af1ad..d827fc87624 100644 --- a/db/security.h +++ b/db/security.h @@ -1,6 +1,6 @@ // security.h
-/** +/**
* Copyright (C) 2009 10gen Inc. * * This program is free software: you can redistribute it and/or modify @@ -15,21 +15,21 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -
-#pragma once
-
-#include <boost/thread/tss.hpp>
+ +#pragma once + +#include <boost/thread/tss.hpp> namespace mongo { -
-class AuthenticationInfo : boost::noncopyable {
-public:
- AuthenticationInfo() { }
- ~AuthenticationInfo() {
-// cout << "TEMP: auth info was cleaned up ********************************************" << endl;
- }
-};
-
-extern boost::thread_specific_ptr<AuthenticationInfo> authInfo;
- } // namespace mongo +class AuthenticationInfo : boost::noncopyable { +public: + AuthenticationInfo() { } + ~AuthenticationInfo() { +// cout << "TEMP: auth info was cleaned up ********************************************" << endl; + } +}; + +extern boost::thread_specific_ptr<AuthenticationInfo> authInfo; + +} // namespace mongo diff --git a/dbgrid/dbgrid.cpp b/dbgrid/dbgrid.cpp index 06b519b5001..5d5cc6f4540 100644 --- a/dbgrid/dbgrid.cpp +++ b/dbgrid/dbgrid.cpp @@ -150,21 +150,21 @@ int main(int argc, char* argv[], char *envp[] ) { if ( s == "--port" ) { port = atoi(argv[++i]); } - else if( s == "--infer" ) { + else if ( s == "--infer" ) { dashDashInfer = true; } else if ( s == "--griddb" ) { assert( !dashDashInfer ); int n = 0; - while( ++i < argc ) { + while ( ++i < argc ) { dashDashGridDb.push_back(argv[i]); n++; } - if( n == 0 ) { + if ( n == 0 ) { cout << "error: no args for --griddb\n"; return 4; } - if( n > 2 ) { + if ( n > 2 ) { cout << "error: --griddb does not support more than 2 parameters yet\n"; return 5; } diff --git a/dbgrid/griddatabase.cpp b/dbgrid/griddatabase.cpp index dcb8c957ad9..d038a5f8691 100644 --- a/dbgrid/griddatabase.cpp +++ b/dbgrid/griddatabase.cpp @@ -34,11 +34,11 @@ string ourHostname; extern vector<string> dashDashGridDb; extern bool dashDashInfer; -GridDatabase::GridDatabase() { +GridDatabase::GridDatabase() { conn = 0; } -GridDatabase::~GridDatabase() { +GridDatabase::~GridDatabase() { delete conn; conn = 0; // defensive } @@ -70,7 +70,7 @@ void GridDatabase::init() { string hostLeft, hostRight; if ( dashDashGridDb.empty() ) { - if( !dashDashInfer ) { + if ( !dashDashInfer ) { cout << "--griddb or --infer required\n"; exit(7); } @@ -91,7 +91,7 @@ void GridDatabase::init() { sl << ":" << Port; left = sl.str(); - if( dashDashGridDb.size() > 1 ) { + if ( dashDashGridDb.size() > 1 ) { sr << dashDashGridDb[1]; hostRight = sr.str(); sr << ":" << Port; @@ -123,15 +123,17 @@ void GridDatabase::init() { l << "connecting to griddb "; bool ok; - if( !hostRight.empty() ) { + if ( !hostRight.empty() ) { // connect in paired mode - l << "L:" << left << " R:" << right << "..."; l.flush(); + l << "L:" << left << " R:" << right << "..."; + l.flush(); DBClientPaired *dbp = new DBClientPaired(); conn = dbp; ok = dbp->connect(left.c_str(),right.c_str()); } - else { - l << left << "..."; l.flush(); + else { + l << left << "..."; + l.flush(); DBClientConnection *dcc = new DBClientConnection(/*autoreconnect=*/true); conn = dcc; string errmsg; diff --git a/dbtests/jsobjtests.cpp b/dbtests/jsobjtests.cpp index c6d77ed19af..c3c0c2d6d7f 100644 --- a/dbtests/jsobjtests.cpp +++ b/dbtests/jsobjtests.cpp @@ -111,773 +111,775 @@ public: ASSERT( basic( "a", 1 ).woCompare( basic( "a", 2 ), basic( "a", -1 ) ) > 0 ); } }; - + namespace JsonStringTests { - class Empty { - public: - void run() { - BSONObjBuilder b; - ASSERT_EQUALS( "{}", b.done().jsonString( Strict ) ); - } - }; - - class SingleStringMember { - public: - void run() { - BSONObjBuilder b; - b.append( "a", "b" ); - ASSERT_EQUALS( "{ \"a\" : \"b\" }", b.done().jsonString( Strict ) ); - } - }; - - class EscapedCharacters { - public: - void run() { - BSONObjBuilder b; - b.append( "a", "\" \\ / \b \f \n \r \t" ); - ASSERT_EQUALS( "{ \"a\" : \"\\\" \\\\ \\/ \\b \\f \\n \\r \\t\" }", b.done().jsonString( Strict ) ); - } - }; - - // per http://www.ietf.org/rfc/rfc4627.txt, control characters are - // (U+0000 through U+001F). U+007F is not mentioned as a control character. - class AdditionalControlCharacters { - public: - void run() { - BSONObjBuilder b; - b.append( "a", "\x1 \x1f" ); - ASSERT_EQUALS( "{ \"a\" : \"\\u0001 \\u001f\" }", b.done().jsonString( Strict ) ); - } - }; - - class ExtendedAscii { - public: - void run() { - BSONObjBuilder b; - b.append( "a", "\x80" ); - ASSERT_EQUALS( "{ \"a\" : \"\x80\" }", b.done().jsonString( Strict ) ); - } - }; - - class EscapeFieldName { - public: - void run() { - BSONObjBuilder b; - b.append( "\t", "b" ); - ASSERT_EQUALS( "{ \"\\t\" : \"b\" }", b.done().jsonString( Strict ) ); - } - }; - - class SingleIntMember { - public: - void run() { - BSONObjBuilder b; - b.appendInt( "a", 1 ); - ASSERT_EQUALS( "{ \"a\" : 1 }", b.done().jsonString( Strict ) ); - } - }; - - class SingleNumberMember { - public: - void run() { - BSONObjBuilder b; - b.append( "a", 1.5 ); - ASSERT_EQUALS( "{ \"a\" : 1.5 }", b.done().jsonString( Strict ) ); - } - }; - - class InvalidNumbers { - public: - void run() { - BSONObjBuilder b; - b.append( "a", numeric_limits< double >::infinity() ); - ASSERT_EXCEPTION( b.done().jsonString( Strict ), AssertionException ); - - BSONObjBuilder c; - c.append( "a", numeric_limits< double >::quiet_NaN() ); - ASSERT_EXCEPTION( c.done().jsonString( Strict ), AssertionException ); - - BSONObjBuilder d; - d.append( "a", numeric_limits< double >::signaling_NaN() ); - ASSERT_EXCEPTION( d.done().jsonString( Strict ), AssertionException ); - } - }; - - class NumberPrecision { - public: - void run() { - BSONObjBuilder b; - b.append( "a", 123456789 ); - ASSERT_EQUALS( "{ \"a\" : 123456789 }", b.done().jsonString( Strict ) ); - } - }; - - class NegativeNumber { - public: - void run() { - BSONObjBuilder b; - b.append( "a", -1 ); - ASSERT_EQUALS( "{ \"a\" : -1 }", b.done().jsonString( Strict ) ); - } - }; - - class SingleBoolMember { - public: - void run() { - BSONObjBuilder b; - b.appendBool( "a", true ); - ASSERT_EQUALS( "{ \"a\" : true }", b.done().jsonString( Strict ) ); - - BSONObjBuilder c; - c.appendBool( "a", false ); - ASSERT_EQUALS( "{ \"a\" : false }", c.done().jsonString( Strict ) ); - } - }; - - class SingleNullMember { - public: - void run() { - BSONObjBuilder b; - b.appendNull( "a" ); - ASSERT_EQUALS( "{ \"a\" : null }", b.done().jsonString( Strict ) ); - } - }; - - class SingleObjectMember { - public: - void run() { - BSONObjBuilder b, c; - b.append( "a", c.done() ); - ASSERT_EQUALS( "{ \"a\" : {} }", b.done().jsonString( Strict ) ); - } - }; - - class TwoMembers { - public: - void run() { - BSONObjBuilder b; - b.append( "a", 1 ); - b.append( "b", 2 ); - ASSERT_EQUALS( "{ \"a\" : 1, \"b\" : 2 }", b.done().jsonString( Strict ) ); - } - }; - - class EmptyArray { - public: - void run() { - vector< int > arr; - BSONObjBuilder b; - b.append( "a", arr ); - ASSERT_EQUALS( "{ \"a\" : [] }", b.done().jsonString( Strict ) ); - } - }; - - class Array { - public: - void run() { - vector< int > arr; - arr.push_back( 1 ); - arr.push_back( 2 ); - BSONObjBuilder b; - b.append( "a", arr ); - ASSERT_EQUALS( "{ \"a\" : [ 1, 2 ] }", b.done().jsonString( Strict ) ); - } - }; - - class DBRef { - public: - void run() { - OID oid; - memset( &oid, 0xff, 12 ); - BSONObjBuilder b; - b.appendDBRef( "a", "namespace", oid ); - ASSERT_EQUALS( "{ \"a\" : { \"$ns\" : \"namespace\", \"$id\" : \"ffffffffffffffffffffffff\" } }", - b.done().jsonString( Strict ) ); - ASSERT_EQUALS( "{ \"a\" : { \"$ns\" : \"namespace\", \"$id\" : \"ffffffffffffffffffffffff\" } }", - b.done().jsonString( JS ) ); - ASSERT_EQUALS( "{ \"a\" : Dbref( \"namespace\", \"ffffffffffffffffffffffff\" ) }", - b.done().jsonString( TenGen ) ); - } - }; - - class DBRefZero { - public: - void run() { - OID oid; - memset( &oid, 0, 12 ); - BSONObjBuilder b; - b.appendDBRef( "a", "namespace", oid ); - ASSERT_EQUALS( "{ \"a\" : { \"$ns\" : \"namespace\", \"$id\" : \"000000000000000000000000\" } }", - b.done().jsonString( Strict ) ); - } - }; - - class ObjectId { - public: - void run() { - OID oid; - memset( &oid, 0xff, 12 ); - BSONObjBuilder b; - b.appendOID( "a", &oid ); - ASSERT_EQUALS( "{ \"a\" : \"ffffffffffffffffffffffff\" }", - b.done().jsonString( Strict ) ); - ASSERT_EQUALS( "{ \"a\" : ObjectId( \"ffffffffffffffffffffffff\" ) }", - b.done().jsonString( TenGen ) ); - } - }; - - class BinData { - public: - void run() { - char z[ 3 ]; - z[ 0 ] = 'a'; - z[ 1 ] = 'b'; - z[ 2 ] = 'c'; - BSONObjBuilder b; - b.appendBinData( "a", 3, ByteArray, z ); - ASSERT_EQUALS( "{ \"a\" : { \"$binary\" : \"YWJj\", \"$type\" : \"02\" } }", - b.done().jsonString( Strict ) ); - - BSONObjBuilder c; - c.appendBinData( "a", 2, ByteArray, z ); - ASSERT_EQUALS( "{ \"a\" : { \"$binary\" : \"YWI=\", \"$type\" : \"02\" } }", - c.done().jsonString( Strict ) ); - - BSONObjBuilder d; - d.appendBinData( "a", 1, ByteArray, z ); - ASSERT_EQUALS( "{ \"a\" : { \"$binary\" : \"YQ==\", \"$type\" : \"02\" } }", - d.done().jsonString( Strict ) ); - } - }; - - class Symbol { - public: - void run() { - BSONObjBuilder b; - b.appendSymbol( "a", "b" ); - ASSERT_EQUALS( "{ \"a\" : \"b\" }", b.done().jsonString( Strict ) ); - } - }; - - class Date { - public: - void run() { - BSONObjBuilder b; - b.appendDate( "a", 0 ); - ASSERT_EQUALS( "{ \"a\" : { \"$date\" : 0 } }", b.done().jsonString( Strict ) ); - ASSERT_EQUALS( "{ \"a\" : Date( 0 ) }", b.done().jsonString( TenGen ) ); - ASSERT_EQUALS( "{ \"a\" : Date( 0 ) }", b.done().jsonString( JS ) ); - } - }; - - class Regex { - public: - void run() { - BSONObjBuilder b; - b.appendRegex( "a", "abc", "i" ); - ASSERT_EQUALS( "{ \"a\" : { \"$regex\" : \"abc\", \"$options\" : \"i\" } }", - b.done().jsonString( Strict ) ); - ASSERT_EQUALS( "{ \"a\" : /abc/i }", b.done().jsonString( TenGen ) ); - ASSERT_EQUALS( "{ \"a\" : /abc/i }", b.done().jsonString( JS ) ); - } - }; - - class RegexEscape { - public: - void run() { - BSONObjBuilder b; - b.appendRegex( "a", "/\"", "i" ); - ASSERT_EQUALS( "{ \"a\" : { \"$regex\" : \"\\/\\\"\", \"$options\" : \"i\" } }", - b.done().jsonString( Strict ) ); - ASSERT_EQUALS( "{ \"a\" : /\\/\\\"/i }", b.done().jsonString( TenGen ) ); - ASSERT_EQUALS( "{ \"a\" : /\\/\\\"/i }", b.done().jsonString( JS ) ); - } - }; - - class RegexManyOptions { - public: - void run() { - BSONObjBuilder b; - b.appendRegex( "a", "z", "abcgimx" ); - ASSERT_EQUALS( "{ \"a\" : { \"$regex\" : \"z\", \"$options\" : \"abcgimx\" } }", - b.done().jsonString( Strict ) ); - ASSERT_EQUALS( "{ \"a\" : /z/gim }", b.done().jsonString( TenGen ) ); - ASSERT_EQUALS( "{ \"a\" : /z/gim }", b.done().jsonString( JS ) ); - } - }; - +class Empty { +public: + void run() { + BSONObjBuilder b; + ASSERT_EQUALS( "{}", b.done().jsonString( Strict ) ); + } +}; + +class SingleStringMember { +public: + void run() { + BSONObjBuilder b; + b.append( "a", "b" ); + ASSERT_EQUALS( "{ \"a\" : \"b\" }", b.done().jsonString( Strict ) ); + } +}; + +class EscapedCharacters { +public: + void run() { + BSONObjBuilder b; + b.append( "a", "\" \\ / \b \f \n \r \t" ); + ASSERT_EQUALS( "{ \"a\" : \"\\\" \\\\ \\/ \\b \\f \\n \\r \\t\" }", b.done().jsonString( Strict ) ); + } +}; + +// per http://www.ietf.org/rfc/rfc4627.txt, control characters are +// (U+0000 through U+001F). U+007F is not mentioned as a control character. +class AdditionalControlCharacters { +public: + void run() { + BSONObjBuilder b; + b.append( "a", "\x1 \x1f" ); + ASSERT_EQUALS( "{ \"a\" : \"\\u0001 \\u001f\" }", b.done().jsonString( Strict ) ); + } +}; + +class ExtendedAscii { +public: + void run() { + BSONObjBuilder b; + b.append( "a", "\x80" ); + ASSERT_EQUALS( "{ \"a\" : \"\x80\" }", b.done().jsonString( Strict ) ); + } +}; + +class EscapeFieldName { +public: + void run() { + BSONObjBuilder b; + b.append( "\t", "b" ); + ASSERT_EQUALS( "{ \"\\t\" : \"b\" }", b.done().jsonString( Strict ) ); + } +}; + +class SingleIntMember { +public: + void run() { + BSONObjBuilder b; + b.appendInt( "a", 1 ); + ASSERT_EQUALS( "{ \"a\" : 1 }", b.done().jsonString( Strict ) ); + } +}; + +class SingleNumberMember { +public: + void run() { + BSONObjBuilder b; + b.append( "a", 1.5 ); + ASSERT_EQUALS( "{ \"a\" : 1.5 }", b.done().jsonString( Strict ) ); + } +}; + +class InvalidNumbers { +public: + void run() { + BSONObjBuilder b; + b.append( "a", numeric_limits< double >::infinity() ); + ASSERT_EXCEPTION( b.done().jsonString( Strict ), AssertionException ); + + BSONObjBuilder c; + c.append( "a", numeric_limits< double >::quiet_NaN() ); + ASSERT_EXCEPTION( c.done().jsonString( Strict ), AssertionException ); + + BSONObjBuilder d; + d.append( "a", numeric_limits< double >::signaling_NaN() ); + ASSERT_EXCEPTION( d.done().jsonString( Strict ), AssertionException ); + } +}; + +class NumberPrecision { +public: + void run() { + BSONObjBuilder b; + b.append( "a", 123456789 ); + ASSERT_EQUALS( "{ \"a\" : 123456789 }", b.done().jsonString( Strict ) ); + } +}; + +class NegativeNumber { +public: + void run() { + BSONObjBuilder b; + b.append( "a", -1 ); + ASSERT_EQUALS( "{ \"a\" : -1 }", b.done().jsonString( Strict ) ); + } +}; + +class SingleBoolMember { +public: + void run() { + BSONObjBuilder b; + b.appendBool( "a", true ); + ASSERT_EQUALS( "{ \"a\" : true }", b.done().jsonString( Strict ) ); + + BSONObjBuilder c; + c.appendBool( "a", false ); + ASSERT_EQUALS( "{ \"a\" : false }", c.done().jsonString( Strict ) ); + } +}; + +class SingleNullMember { +public: + void run() { + BSONObjBuilder b; + b.appendNull( "a" ); + ASSERT_EQUALS( "{ \"a\" : null }", b.done().jsonString( Strict ) ); + } +}; + +class SingleObjectMember { +public: + void run() { + BSONObjBuilder b, c; + b.append( "a", c.done() ); + ASSERT_EQUALS( "{ \"a\" : {} }", b.done().jsonString( Strict ) ); + } +}; + +class TwoMembers { +public: + void run() { + BSONObjBuilder b; + b.append( "a", 1 ); + b.append( "b", 2 ); + ASSERT_EQUALS( "{ \"a\" : 1, \"b\" : 2 }", b.done().jsonString( Strict ) ); + } +}; + +class EmptyArray { +public: + void run() { + vector< int > arr; + BSONObjBuilder b; + b.append( "a", arr ); + ASSERT_EQUALS( "{ \"a\" : [] }", b.done().jsonString( Strict ) ); + } +}; + +class Array { +public: + void run() { + vector< int > arr; + arr.push_back( 1 ); + arr.push_back( 2 ); + BSONObjBuilder b; + b.append( "a", arr ); + ASSERT_EQUALS( "{ \"a\" : [ 1, 2 ] }", b.done().jsonString( Strict ) ); + } +}; + +class DBRef { +public: + void run() { + OID oid; + memset( &oid, 0xff, 12 ); + BSONObjBuilder b; + b.appendDBRef( "a", "namespace", oid ); + ASSERT_EQUALS( "{ \"a\" : { \"$ns\" : \"namespace\", \"$id\" : \"ffffffffffffffffffffffff\" } }", + b.done().jsonString( Strict ) ); + ASSERT_EQUALS( "{ \"a\" : { \"$ns\" : \"namespace\", \"$id\" : \"ffffffffffffffffffffffff\" } }", + b.done().jsonString( JS ) ); + ASSERT_EQUALS( "{ \"a\" : Dbref( \"namespace\", \"ffffffffffffffffffffffff\" ) }", + b.done().jsonString( TenGen ) ); + } +}; + +class DBRefZero { +public: + void run() { + OID oid; + memset( &oid, 0, 12 ); + BSONObjBuilder b; + b.appendDBRef( "a", "namespace", oid ); + ASSERT_EQUALS( "{ \"a\" : { \"$ns\" : \"namespace\", \"$id\" : \"000000000000000000000000\" } }", + b.done().jsonString( Strict ) ); + } +}; + +class ObjectId { +public: + void run() { + OID oid; + memset( &oid, 0xff, 12 ); + BSONObjBuilder b; + b.appendOID( "a", &oid ); + ASSERT_EQUALS( "{ \"a\" : \"ffffffffffffffffffffffff\" }", + b.done().jsonString( Strict ) ); + ASSERT_EQUALS( "{ \"a\" : ObjectId( \"ffffffffffffffffffffffff\" ) }", + b.done().jsonString( TenGen ) ); + } +}; + +class BinData { +public: + void run() { + char z[ 3 ]; + z[ 0 ] = 'a'; + z[ 1 ] = 'b'; + z[ 2 ] = 'c'; + BSONObjBuilder b; + b.appendBinData( "a", 3, ByteArray, z ); + ASSERT_EQUALS( "{ \"a\" : { \"$binary\" : \"YWJj\", \"$type\" : \"02\" } }", + b.done().jsonString( Strict ) ); + + BSONObjBuilder c; + c.appendBinData( "a", 2, ByteArray, z ); + ASSERT_EQUALS( "{ \"a\" : { \"$binary\" : \"YWI=\", \"$type\" : \"02\" } }", + c.done().jsonString( Strict ) ); + + BSONObjBuilder d; + d.appendBinData( "a", 1, ByteArray, z ); + ASSERT_EQUALS( "{ \"a\" : { \"$binary\" : \"YQ==\", \"$type\" : \"02\" } }", + d.done().jsonString( Strict ) ); + } +}; + +class Symbol { +public: + void run() { + BSONObjBuilder b; + b.appendSymbol( "a", "b" ); + ASSERT_EQUALS( "{ \"a\" : \"b\" }", b.done().jsonString( Strict ) ); + } +}; + +class Date { +public: + void run() { + BSONObjBuilder b; + b.appendDate( "a", 0 ); + ASSERT_EQUALS( "{ \"a\" : { \"$date\" : 0 } }", b.done().jsonString( Strict ) ); + ASSERT_EQUALS( "{ \"a\" : Date( 0 ) }", b.done().jsonString( TenGen ) ); + ASSERT_EQUALS( "{ \"a\" : Date( 0 ) }", b.done().jsonString( JS ) ); + } +}; + +class Regex { +public: + void run() { + BSONObjBuilder b; + b.appendRegex( "a", "abc", "i" ); + ASSERT_EQUALS( "{ \"a\" : { \"$regex\" : \"abc\", \"$options\" : \"i\" } }", + b.done().jsonString( Strict ) ); + ASSERT_EQUALS( "{ \"a\" : /abc/i }", b.done().jsonString( TenGen ) ); + ASSERT_EQUALS( "{ \"a\" : /abc/i }", b.done().jsonString( JS ) ); + } +}; + +class RegexEscape { +public: + void run() { + BSONObjBuilder b; + b.appendRegex( "a", "/\"", "i" ); + ASSERT_EQUALS( "{ \"a\" : { \"$regex\" : \"\\/\\\"\", \"$options\" : \"i\" } }", + b.done().jsonString( Strict ) ); + ASSERT_EQUALS( "{ \"a\" : /\\/\\\"/i }", b.done().jsonString( TenGen ) ); + ASSERT_EQUALS( "{ \"a\" : /\\/\\\"/i }", b.done().jsonString( JS ) ); + } +}; + +class RegexManyOptions { +public: + void run() { + BSONObjBuilder b; + b.appendRegex( "a", "z", "abcgimx" ); + ASSERT_EQUALS( "{ \"a\" : { \"$regex\" : \"z\", \"$options\" : \"abcgimx\" } }", + b.done().jsonString( Strict ) ); + ASSERT_EQUALS( "{ \"a\" : /z/gim }", b.done().jsonString( TenGen ) ); + ASSERT_EQUALS( "{ \"a\" : /z/gim }", b.done().jsonString( JS ) ); + } +}; + } // namespace JsonStringTests } // namespace BSONObjTests - + namespace FromJsonTests { - - class Base { - public: - void run() { - assertEquals( bson(), fromjson( json() ) ); - assertEquals( bson(), fromjson( bson().jsonString( Strict ) ) ); - assertEquals( bson(), fromjson( bson().jsonString( TenGen ) ) ); - assertEquals( bson(), fromjson( bson().jsonString( JS ) ) ); - } - protected: - virtual BSONObj bson() const = 0; - virtual string json() const = 0; - private: - static void assertEquals( const BSONObj &expected, const BSONObj &actual ) { - if ( expected.woCompare( actual ) ) { - cout << "Expected: " << expected.toString() - << ", got: " << actual.toString(); - } - ASSERT( !expected.woCompare( actual ) ); - } - }; - - class Bad { - public: - void run() { - ASSERT_EXCEPTION( fromjson( json() ), MsgAssertionException ); - } - protected: - virtual string json() const = 0; - }; - - class Empty : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - return b.doneAndDecouple(); - } - virtual string json() const { - return "{}"; - } - }; - class EmptyWithSpace : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ }"; - } - }; - - class SingleString : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "a", "b" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : \"b\" }"; - } - }; +class Base { +public: + void run() { + assertEquals( bson(), fromjson( json() ) ); + assertEquals( bson(), fromjson( bson().jsonString( Strict ) ) ); + assertEquals( bson(), fromjson( bson().jsonString( TenGen ) ) ); + assertEquals( bson(), fromjson( bson().jsonString( JS ) ) ); + } +protected: + virtual BSONObj bson() const = 0; + virtual string json() const = 0; +private: + static void assertEquals( const BSONObj &expected, const BSONObj &actual ) { + if ( expected.woCompare( actual ) ) { + cout << "Expected: " << expected.toString() + << ", got: " << actual.toString(); + } + ASSERT( !expected.woCompare( actual ) ); + } +}; - class EmptyStrings : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "", "" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"\" : \"\" }"; - } - }; - - class ReservedFieldName : public Bad { - virtual string json() const { - return "{ \"$ns\" : \"b\" }"; - } - }; - - class OkDollarFieldName : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "$where", 1 ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"$where\" : 1 }"; - } - }; - - class SingleNumber : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "a", 1 ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : 1 }"; - } - }; - - class FancyNumber { - public: - void run() { - ASSERT_EQUALS( bson().firstElement().number(), - fromjson( json() ).firstElement().number() ); - } - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "a", -4.4433e-2 ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : -4.4433e-2 }"; - } - }; - - class TwoElements : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "a", 1 ); - b.append( "b", "foo" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : 1, \"b\" : \"foo\" }"; - } - }; - - class Subobject : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "a", 1 ); - BSONObjBuilder c; - c.append( "z", b.done() ); - return c.doneAndDecouple(); - } - virtual string json() const { - return "{ \"z\" : { \"a\" : 1 } }"; - } - }; - - class ArrayEmpty : public Base { - virtual BSONObj bson() const { - vector< int > arr; - BSONObjBuilder b; - b.append( "a", arr ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : [] }"; - } - }; - - class Array : public Base { - virtual BSONObj bson() const { - vector< int > arr; - arr.push_back( 1 ); - arr.push_back( 2 ); - arr.push_back( 3 ); - BSONObjBuilder b; - b.append( "a", arr ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : [ 1, 2, 3 ] }"; - } - }; +class Bad { +public: + void run() { + ASSERT_EXCEPTION( fromjson( json() ), MsgAssertionException ); + } +protected: + virtual string json() const = 0; +}; - class True : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendBool( "a", true ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : true }"; - } - }; - - class False : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendBool( "a", false ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : false }"; - } - }; +class Empty : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + return b.doneAndDecouple(); + } + virtual string json() const { + return "{}"; + } +}; - class Null : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendNull( "a" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : null }"; - } - }; - - class EscapedCharacters : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "a", "\" \\ / \b \f \n \r \t" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : \"\\\" \\\\ \\/ \\b \\f \\n \\r \\t\" }"; - } - }; - - class AllowedControlCharacter : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "a", "\x7f" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : \"\x7f\" }"; - } - }; - - class EscapeFieldName : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.append( "\n", "b" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"\\n\" : \"b\" }"; - } - }; - - class EscapedUnicodeToUtf8 : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - char u[ 7 ]; - u[ 0 ] = 0xe0 | 0x0a; - u[ 1 ] = 0x80; - u[ 2 ] = 0x80; - u[ 3 ] = 0xe0 | 0x0a; - u[ 4 ] = 0x80; - u[ 5 ] = 0x80; - u[ 6 ] = 0; - b.append( "a", u ); - ASSERT_EQUALS( string( u ), b.done().firstElement().valuestr() ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : \"\\ua000\\uA000\" }"; - } - }; - - class Utf8AllOnes : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - char u[ 8 ]; - u[ 0 ] = 0x01; +class EmptyWithSpace : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ }"; + } +}; - u[ 1 ] = 0x7f; +class SingleString : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "a", "b" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : \"b\" }"; + } +}; - u[ 2 ] = 0xdf; - u[ 3 ] = 0xbf; +class EmptyStrings : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "", "" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"\" : \"\" }"; + } +}; - u[ 4 ] = 0xef; - u[ 5 ] = 0xbf; - u[ 6 ] = 0xbf; +class ReservedFieldName : public Bad { + virtual string json() const { + return "{ \"$ns\" : \"b\" }"; + } +}; - u[ 7 ] = 0; +class OkDollarFieldName : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "$where", 1 ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"$where\" : 1 }"; + } +}; - b.append( "a", u ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : \"\\u0001\\u007f\\u07ff\\uffff\" }"; - } - }; - - class Utf8FirstByteOnes : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - char u[ 6 ]; - u[ 0 ] = 0xdc; - u[ 1 ] = 0x80; - - u[ 2 ] = 0xef; - u[ 3 ] = 0xbc; - u[ 4 ] = 0x80; - - u[ 5 ] = 0; - - b.append( "a", u ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : \"\\u0700\\uff00\" }"; - } - }; - - class DBRef : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - OID o; - memset( &o, 0, 12 ); - b.appendDBRef( "a", "foo", o ); - return b.doneAndDecouple(); - } - // NOTE Testing other formats handled by by Base class. - virtual string json() const { - return "{ \"a\" : { \"$ns\" : \"foo\", \"$id\" : \"000000000000000000000000\" } }"; - } - }; +class SingleNumber : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "a", 1 ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : 1 }"; + } +}; + +class FancyNumber { +public: + void run() { + ASSERT_EQUALS( bson().firstElement().number(), + fromjson( json() ).firstElement().number() ); + } + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "a", -4.4433e-2 ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : -4.4433e-2 }"; + } +}; + +class TwoElements : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "a", 1 ); + b.append( "b", "foo" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : 1, \"b\" : \"foo\" }"; + } +}; + +class Subobject : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "a", 1 ); + BSONObjBuilder c; + c.append( "z", b.done() ); + return c.doneAndDecouple(); + } + virtual string json() const { + return "{ \"z\" : { \"a\" : 1 } }"; + } +}; + +class ArrayEmpty : public Base { + virtual BSONObj bson() const { + vector< int > arr; + BSONObjBuilder b; + b.append( "a", arr ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : [] }"; + } +}; + +class Array : public Base { + virtual BSONObj bson() const { + vector< int > arr; + arr.push_back( 1 ); + arr.push_back( 2 ); + arr.push_back( 3 ); + BSONObjBuilder b; + b.append( "a", arr ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : [ 1, 2, 3 ] }"; + } +}; + +class True : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendBool( "a", true ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : true }"; + } +}; + +class False : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendBool( "a", false ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : false }"; + } +}; + +class Null : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendNull( "a" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : null }"; + } +}; + +class EscapedCharacters : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "a", "\" \\ / \b \f \n \r \t" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : \"\\\" \\\\ \\/ \\b \\f \\n \\r \\t\" }"; + } +}; + +class AllowedControlCharacter : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "a", "\x7f" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : \"\x7f\" }"; + } +}; + +class EscapeFieldName : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.append( "\n", "b" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"\\n\" : \"b\" }"; + } +}; + +class EscapedUnicodeToUtf8 : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + char u[ 7 ]; + u[ 0 ] = 0xe0 | 0x0a; + u[ 1 ] = 0x80; + u[ 2 ] = 0x80; + u[ 3 ] = 0xe0 | 0x0a; + u[ 4 ] = 0x80; + u[ 5 ] = 0x80; + u[ 6 ] = 0; + b.append( "a", u ); + ASSERT_EQUALS( string( u ), b.done().firstElement().valuestr() ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : \"\\ua000\\uA000\" }"; + } +}; + +class Utf8AllOnes : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + char u[ 8 ]; + u[ 0 ] = 0x01; + + u[ 1 ] = 0x7f; + + u[ 2 ] = 0xdf; + u[ 3 ] = 0xbf; + + u[ 4 ] = 0xef; + u[ 5 ] = 0xbf; + u[ 6 ] = 0xbf; + + u[ 7 ] = 0; + + b.append( "a", u ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : \"\\u0001\\u007f\\u07ff\\uffff\" }"; + } +}; + +class Utf8FirstByteOnes : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + char u[ 6 ]; + u[ 0 ] = 0xdc; + u[ 1 ] = 0x80; + + u[ 2 ] = 0xef; + u[ 3 ] = 0xbc; + u[ 4 ] = 0x80; + + u[ 5 ] = 0; + + b.append( "a", u ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : \"\\u0700\\uff00\" }"; + } +}; + +class DBRef : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + OID o; + memset( &o, 0, 12 ); + b.appendDBRef( "a", "foo", o ); + return b.doneAndDecouple(); + } + // NOTE Testing other formats handled by by Base class. + virtual string json() const { + return "{ \"a\" : { \"$ns\" : \"foo\", \"$id\" : \"000000000000000000000000\" } }"; + } +}; + +class Oid : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendOID( "_id" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"_id\" : \"000000000000000000000000\" }"; + } +}; + +class BinData : public Base { + virtual BSONObj bson() const { + char z[ 3 ]; + z[ 0 ] = 'a'; + z[ 1 ] = 'b'; + z[ 2 ] = 'c'; + BSONObjBuilder b; + b.appendBinData( "a", 3, ByteArray, z ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$binary\" : \"YWJj\", \"$type\" : \"02\" } }"; + } +}; + +class BinDataPaddedSingle : public Base { + virtual BSONObj bson() const { + char z[ 2 ]; + z[ 0 ] = 'a'; + z[ 1 ] = 'b'; + BSONObjBuilder b; + b.appendBinData( "a", 2, ByteArray, z ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$binary\" : \"YWI=\", \"$type\" : \"02\" } }"; + } +}; + +class BinDataPaddedDouble : public Base { + virtual BSONObj bson() const { + char z[ 1 ]; + z[ 0 ] = 'a'; + BSONObjBuilder b; + b.appendBinData( "a", 1, ByteArray, z ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$binary\" : \"YQ==\", \"$type\" : \"02\" } }"; + } +}; + +class BinDataAllChars : public Base { + virtual BSONObj bson() const { + char z[] = { + 0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8B, 0x30, + 0xD3, 0x8F, 0x41, 0x14, 0x93, 0x51, 0x55, 0x97, 0x61, 0x96, + 0x9B, 0x71, 0xD7, 0x9F, 0x82, 0x18, 0xA3, 0x92, 0x59, 0xA7, + 0xA2, 0x9A, 0xAB, 0xB2, 0xDB, 0xAF, 0xC3, 0x1C, 0xB3, 0xD3, + 0x5D, 0xB7, 0xE3, 0x9E, 0xBB, 0xF3, 0xDF, 0xBF + }; + BSONObjBuilder b; + b.appendBinData( "a", 48, ByteArray, z ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$binary\" : \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\", \"$type\" : \"02\" } }"; + } +}; + +class Date : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendDate( "a", 0 ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$date\" : 0 } }"; + } +}; + +class DateNonzero : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendDate( "a", 100 ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$date\" : 100 } }"; + } +}; + +class DateTooLong : public Bad { + virtual string json() const { + stringstream ss; + ss << "{ \"a\" : { \"$date\" : " << ~(0LL) << "0" << " } }"; + return ss.str(); + } +}; + +class Regex : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendRegex( "a", "b", "i" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$regex\" : \"b\", \"$options\" : \"i\" } }"; + } +}; + +class RegexEscape : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendRegex( "a", "\t", "i" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : { \"$regex\" : \"\\t\", \"$options\" : \"i\" } }"; + } +}; + +class RegexWithQuotes : public Base { + virtual BSONObj bson() const { + BSONObjBuilder b; + b.appendRegex( "a", "\"", "" ); + return b.doneAndDecouple(); + } + virtual string json() const { + return "{ \"a\" : /\"/ }"; + } +}; + +class RegexInvalidOption : public Bad { + virtual string json() const { + return "{ \"a\" : { \"$regex\" : \"b\", \"$options\" : \"1\" } }"; + } +}; + +class RegexInvalidOption2 : public Bad { + virtual string json() const { + return "{ \"a\" : /b/c }"; + } +}; + +class Malformed : public Bad { + string json() const { + return "{"; + } +}; - class Oid : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendOID( "_id" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"_id\" : \"000000000000000000000000\" }"; - } - }; - - class BinData : public Base { - virtual BSONObj bson() const { - char z[ 3 ]; - z[ 0 ] = 'a'; - z[ 1 ] = 'b'; - z[ 2 ] = 'c'; - BSONObjBuilder b; - b.appendBinData( "a", 3, ByteArray, z ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : { \"$binary\" : \"YWJj\", \"$type\" : \"02\" } }"; - } - }; - - class BinDataPaddedSingle : public Base { - virtual BSONObj bson() const { - char z[ 2 ]; - z[ 0 ] = 'a'; - z[ 1 ] = 'b'; - BSONObjBuilder b; - b.appendBinData( "a", 2, ByteArray, z ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : { \"$binary\" : \"YWI=\", \"$type\" : \"02\" } }"; - } - }; - - class BinDataPaddedDouble : public Base { - virtual BSONObj bson() const { - char z[ 1 ]; - z[ 0 ] = 'a'; - BSONObjBuilder b; - b.appendBinData( "a", 1, ByteArray, z ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : { \"$binary\" : \"YQ==\", \"$type\" : \"02\" } }"; - } - }; - - class BinDataAllChars : public Base { - virtual BSONObj bson() const { - char z[] = { - 0x00, 0x10, 0x83, 0x10, 0x51, 0x87, 0x20, 0x92, 0x8B, 0x30, - 0xD3, 0x8F, 0x41, 0x14, 0x93, 0x51, 0x55, 0x97, 0x61, 0x96, - 0x9B, 0x71, 0xD7, 0x9F, 0x82, 0x18, 0xA3, 0x92, 0x59, 0xA7, - 0xA2, 0x9A, 0xAB, 0xB2, 0xDB, 0xAF, 0xC3, 0x1C, 0xB3, 0xD3, - 0x5D, 0xB7, 0xE3, 0x9E, 0xBB, 0xF3, 0xDF, 0xBF - }; - BSONObjBuilder b; - b.appendBinData( "a", 48, ByteArray, z ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : { \"$binary\" : \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\", \"$type\" : \"02\" } }"; - } - }; - - class Date : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendDate( "a", 0 ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : { \"$date\" : 0 } }"; - } - }; - - class DateNonzero : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendDate( "a", 100 ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : { \"$date\" : 100 } }"; - } - }; - - class DateTooLong : public Bad { - virtual string json() const { - stringstream ss; - ss << "{ \"a\" : { \"$date\" : " << ~(0LL) << "0" << " } }"; - return ss.str(); - } - }; - - class Regex : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendRegex( "a", "b", "i" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : { \"$regex\" : \"b\", \"$options\" : \"i\" } }"; - } - }; - - class RegexEscape : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendRegex( "a", "\t", "i" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : { \"$regex\" : \"\\t\", \"$options\" : \"i\" } }"; - } - }; - - class RegexWithQuotes : public Base { - virtual BSONObj bson() const { - BSONObjBuilder b; - b.appendRegex( "a", "\"", "" ); - return b.doneAndDecouple(); - } - virtual string json() const { - return "{ \"a\" : /\"/ }"; - } - }; - - class RegexInvalidOption : public Bad { - virtual string json() const { - return "{ \"a\" : { \"$regex\" : \"b\", \"$options\" : \"1\" } }"; - } - }; - - class RegexInvalidOption2 : public Bad { - virtual string json() const { - return "{ \"a\" : /b/c }"; - } - }; - - class Malformed : public Bad { - string json() const { return "{"; } - }; - } // namespace FromJsonTests - + class All : public UnitTest::Suite { public: All() { diff --git a/dbtests/namespacetests.cpp b/dbtests/namespacetests.cpp index 34b9d24b1f3..6bfbdaa77f6 100644 --- a/dbtests/namespacetests.cpp +++ b/dbtests/namespacetests.cpp @@ -91,7 +91,7 @@ protected: static void assertEquals( const BSONObj &a, const BSONObj &b ) { if ( a.woCompare( b ) != 0 ) { cout << "expected: " << a.toString() - << ", got: " << b.toString() << endl; + << ", got: " << b.toString() << endl; } ASSERT( a.woCompare( b ) == 0 ); } @@ -366,7 +366,7 @@ private: return aDotB(); } }; - + // TODO // array subelement complex // parallel arrays complex @@ -376,168 +376,170 @@ private: namespace NamespaceDetailsTests { - class Base { - public: - Base( const char *ns = "foo" ) : ns_( ns ) {} - ~Base() { - if ( !nsd() ) - return; - string s( ns() ); - dropNS( s ); - } - protected: - void create() { - dblock lk; - setClient( ns() ); - string err; - ASSERT( userCreateNS( ns(), fromjson( spec() ), err, false ) ); - } - virtual string spec() const { - return "{\"capped\":true,\"size\":512}"; - } - int nRecords() const { - int count = 0; - for( DiskLoc i = nsd()->firstExtent; !i.isNull(); i = i.ext()->xnext ) - for( DiskLoc j = i.ext()->firstRecord; !j.isNull(); +class Base { +public: + Base( const char *ns = "foo" ) : ns_( ns ) {} + ~Base() { + if ( !nsd() ) + return; + string s( ns() ); + dropNS( s ); + } +protected: + void create() { + dblock lk; + setClient( ns() ); + string err; + ASSERT( userCreateNS( ns(), fromjson( spec() ), err, false ) ); + } + virtual string spec() const { + return "{\"capped\":true,\"size\":512}"; + } + int nRecords() const { + int count = 0; + for ( DiskLoc i = nsd()->firstExtent; !i.isNull(); i = i.ext()->xnext ) + for ( DiskLoc j = i.ext()->firstRecord; !j.isNull(); j.setOfs( j.a(), j.rec()->nextOfs ) ) { - ++count; - } - ASSERT_EQUALS( count, nsd()->nrecords ); - return count; - } - int nExtents() const { - int count = 0; - for( DiskLoc i = nsd()->firstExtent; !i.isNull(); i = i.ext()->xnext ) ++count; - return count; - } - static int min( int a, int b ) { - return a < b ? a : b; - } - const char *ns() const { return ns_; } - NamespaceDetails *nsd() const { - return nsdetails( ns() ); - } - private: - const char *ns_; - }; - - class Create : public Base { - public: - void run() { - create(); - ASSERT( nsd() ); - ASSERT_EQUALS( 0, nRecords() ); - ASSERT( nsd()->firstExtent == nsd()->capExtent ); - DiskLoc initial = DiskLoc(); - initial.setInvalid(); - ASSERT( initial == nsd()->capFirstNewRecord ); - } - }; - - class SingleAlloc : public Base { - public: - void run() { - create(); - char ch[ 200 ]; - memset( ch, 0, 200 ); - ASSERT( !theDataFileMgr.insert( ns(), ch, 200 ).isNull() ); - ASSERT_EQUALS( 1, nRecords() ); - } - }; - - class Realloc : public Base { - public: - void run() { - create(); - char ch[ 200 ]; - - DiskLoc l[ 6 ]; - for( int i = 0; i < 6; ++i ) { - l[ i ] = theDataFileMgr.insert( ns(), ch, 200 ); - ASSERT( !l[ i ].isNull() ); - ASSERT_EQUALS( 1 + i % 2, nRecords() ); - if ( i > 1 ) - ASSERT( l[ i ] == l[ i - 2 ] ); } + ASSERT_EQUALS( count, nsd()->nrecords ); + return count; + } + int nExtents() const { + int count = 0; + for ( DiskLoc i = nsd()->firstExtent; !i.isNull(); i = i.ext()->xnext ) + ++count; + return count; + } + static int min( int a, int b ) { + return a < b ? a : b; + } + const char *ns() const { + return ns_; + } + NamespaceDetails *nsd() const { + return nsdetails( ns() ); + } +private: + const char *ns_; +}; + +class Create : public Base { +public: + void run() { + create(); + ASSERT( nsd() ); + ASSERT_EQUALS( 0, nRecords() ); + ASSERT( nsd()->firstExtent == nsd()->capExtent ); + DiskLoc initial = DiskLoc(); + initial.setInvalid(); + ASSERT( initial == nsd()->capFirstNewRecord ); + } +}; + +class SingleAlloc : public Base { +public: + void run() { + create(); + char ch[ 200 ]; + memset( ch, 0, 200 ); + ASSERT( !theDataFileMgr.insert( ns(), ch, 200 ).isNull() ); + ASSERT_EQUALS( 1, nRecords() ); + } +}; + +class Realloc : public Base { +public: + void run() { + create(); + char ch[ 200 ]; + + DiskLoc l[ 6 ]; + for ( int i = 0; i < 6; ++i ) { + l[ i ] = theDataFileMgr.insert( ns(), ch, 200 ); + ASSERT( !l[ i ].isNull() ); + ASSERT_EQUALS( 1 + i % 2, nRecords() ); + if ( i > 1 ) + ASSERT( l[ i ] == l[ i - 2 ] ); } - }; - - class TwoExtent : public Base { - public: - void run() { - create(); - ASSERT_EQUALS( 2, nExtents() ); - char ch[ 200 ]; - - DiskLoc l[ 8 ]; - for( int i = 0; i < 8; ++i ) { - l[ i ] = theDataFileMgr.insert( ns(), ch, 200 ); - ASSERT( !l[ i ].isNull() ); - ASSERT_EQUALS( i < 2 ? i + 1 : 3 + i % 2, nRecords() ); - if ( i > 3 ) - ASSERT( l[ i ] == l[ i - 4 ] ); - } - - // Too big - char ch2[ 800 ]; - ASSERT( theDataFileMgr.insert( ns(), ch2, 800 ).isNull() ); - ASSERT_EQUALS( 0, nRecords() ); - } - private: - virtual string spec() const { - return "{\"capped\":true,\"size\":512,\"$nExtents\":2}"; - } - }; - - class Migrate : public Base { - public: - void run() { - create(); - nsd()->deletedList[ 2 ] = nsd()->deletedList[ 0 ].drec()->nextDeleted.drec()->nextDeleted; - nsd()->deletedList[ 0 ].drec()->nextDeleted.drec()->nextDeleted = DiskLoc(); - NamespaceDetails *d = nsd(); - zero( &d->capExtent ); - zero( &d->capFirstNewRecord ); - - nsd(); - - ASSERT( nsd()->firstExtent == nsd()->capExtent ); - ASSERT( nsd()->capExtent.getOfs() != 0 ); - ASSERT( !nsd()->capFirstNewRecord.isValid() ); - int nDeleted = 0; - for( DiskLoc i = nsd()->deletedList[ 0 ]; !i.isNull(); i = i.drec()->nextDeleted, ++nDeleted ); - ASSERT_EQUALS( 10, nDeleted ); - ASSERT( nsd()->deletedList[ 1 ].isNull() ); - } - private: - static void zero( DiskLoc *d ) { - memset( d, 0, sizeof( DiskLoc ) ); - } - virtual string spec() const { - return "{\"capped\":true,\"size\":512,\"$nExtents\":10}"; - } - }; - - class BigCollection : public Base { - public: - BigCollection() : Base( "NamespaceDetailsTests_BigCollection" ) {} - void run() { - create(); - ASSERT_EQUALS( 2, nExtents() ); + } +}; + +class TwoExtent : public Base { +public: + void run() { + create(); + ASSERT_EQUALS( 2, nExtents() ); + char ch[ 200 ]; + + DiskLoc l[ 8 ]; + for ( int i = 0; i < 8; ++i ) { + l[ i ] = theDataFileMgr.insert( ns(), ch, 200 ); + ASSERT( !l[ i ].isNull() ); + ASSERT_EQUALS( i < 2 ? i + 1 : 3 + i % 2, nRecords() ); + if ( i > 3 ) + ASSERT( l[ i ] == l[ i - 4 ] ); } - private: - virtual string spec() const { - // NOTE 256 added to size in _userCreateNS() - long long big = PhysicalDataFile::maxSize() - PDFHeader::headerSize(); - stringstream ss; - ss << "{\"capped\":true,\"size\":" << big << "}"; - return ss.str(); - } - }; - + + // Too big + char ch2[ 800 ]; + ASSERT( theDataFileMgr.insert( ns(), ch2, 800 ).isNull() ); + ASSERT_EQUALS( 0, nRecords() ); + } +private: + virtual string spec() const { + return "{\"capped\":true,\"size\":512,\"$nExtents\":2}"; + } +}; + +class Migrate : public Base { +public: + void run() { + create(); + nsd()->deletedList[ 2 ] = nsd()->deletedList[ 0 ].drec()->nextDeleted.drec()->nextDeleted; + nsd()->deletedList[ 0 ].drec()->nextDeleted.drec()->nextDeleted = DiskLoc(); + NamespaceDetails *d = nsd(); + zero( &d->capExtent ); + zero( &d->capFirstNewRecord ); + + nsd(); + + ASSERT( nsd()->firstExtent == nsd()->capExtent ); + ASSERT( nsd()->capExtent.getOfs() != 0 ); + ASSERT( !nsd()->capFirstNewRecord.isValid() ); + int nDeleted = 0; + for ( DiskLoc i = nsd()->deletedList[ 0 ]; !i.isNull(); i = i.drec()->nextDeleted, ++nDeleted ); + ASSERT_EQUALS( 10, nDeleted ); + ASSERT( nsd()->deletedList[ 1 ].isNull() ); + } +private: + static void zero( DiskLoc *d ) { + memset( d, 0, sizeof( DiskLoc ) ); + } + virtual string spec() const { + return "{\"capped\":true,\"size\":512,\"$nExtents\":10}"; + } +}; + +class BigCollection : public Base { +public: + BigCollection() : Base( "NamespaceDetailsTests_BigCollection" ) {} + void run() { + create(); + ASSERT_EQUALS( 2, nExtents() ); + } +private: + virtual string spec() const { + // NOTE 256 added to size in _userCreateNS() + long long big = PhysicalDataFile::maxSize() - PDFHeader::headerSize(); + stringstream ss; + ss << "{\"capped\":true,\"size\":" << big << "}"; + return ss.str(); + } +}; + } // namespace NamespaceDetailsTests - + class All : public UnitTest::Suite { public: All() { @@ -556,7 +558,7 @@ public: add< NamespaceDetailsTests::Create >(); add< NamespaceDetailsTests::SingleAlloc >(); add< NamespaceDetailsTests::Realloc >(); - add< NamespaceDetailsTests::TwoExtent >(); + add< NamespaceDetailsTests::TwoExtent >(); add< NamespaceDetailsTests::Migrate >(); add< NamespaceDetailsTests::BigCollection >(); } diff --git a/dbtests/pairingtests.cpp b/dbtests/pairingtests.cpp index d61febb0d53..e55667d56e0 100644 --- a/dbtests/pairingtests.cpp +++ b/dbtests/pairingtests.cpp @@ -298,8 +298,12 @@ public: } private: class NegateCatchup : public DirectDBClientConnection::ConnectionCallback { - virtual void beforeCommand() { Base::flipSync(); } - virtual void afterCommand() { Base::flipSync(); } + virtual void beforeCommand() { + Base::flipSync(); + } + virtual void afterCommand() { + Base::flipSync(); + } }; virtual DirectDBClientConnection::ConnectionCallback *cc() { return &cc_; diff --git a/dbtests/pdfiletests.cpp b/dbtests/pdfiletests.cpp index ff5a4e69ad5..8739d54f7aa 100644 --- a/dbtests/pdfiletests.cpp +++ b/dbtests/pdfiletests.cpp @@ -26,217 +26,263 @@ namespace PdfileTests { - namespace ScanCapped { - - class Base { - public: - Base() { - dblock lk; - setClient( ns() ); - } - ~Base() { - if ( !nsd() ) - return; - string n( ns() ); - dropNS( n ); - } - void run() { - stringstream spec; - spec << "{\"capped\":true,\"size\":2000,\"$nExtents\":" << nExtents() << "}"; - string err; - ASSERT( userCreateNS( ns(), fromjson( spec.str() ), err, false ) ); - prepare(); - int j = 0; - for( auto_ptr< Cursor > i = theDataFileMgr.findAll( ns() ); - i->ok(); i->advance(), ++j ) - ASSERT_EQUALS( j, i->current().firstElement().number() ); - ASSERT_EQUALS( count(), j ); - - j = count() - 1; - for( auto_ptr< Cursor > i = +namespace ScanCapped { + +class Base { +public: + Base() { + dblock lk; + setClient( ns() ); + } + ~Base() { + if ( !nsd() ) + return; + string n( ns() ); + dropNS( n ); + } + void run() { + stringstream spec; + spec << "{\"capped\":true,\"size\":2000,\"$nExtents\":" << nExtents() << "}"; + string err; + ASSERT( userCreateNS( ns(), fromjson( spec.str() ), err, false ) ); + prepare(); + int j = 0; + for ( auto_ptr< Cursor > i = theDataFileMgr.findAll( ns() ); + i->ok(); i->advance(), ++j ) + ASSERT_EQUALS( j, i->current().firstElement().number() ); + ASSERT_EQUALS( count(), j ); + + j = count() - 1; + for ( auto_ptr< Cursor > i = findTableScan( ns(), fromjson( "{\"$natural\":-1}" ) ); - i->ok(); i->advance(), --j ) - ASSERT_EQUALS( j, i->current().firstElement().number() ); - ASSERT_EQUALS( -1, j ); - } - protected: - virtual void prepare() = 0; - virtual int count() const = 0; - virtual int nExtents() const { return 0; } - // bypass standard alloc/insert routines to use the extent we want. - static DiskLoc insert( DiskLoc ext, int i ) { - BSONObjBuilder b; - b.append( "a", i ); - BSONObj o = b.done(); - int len = o.objsize(); - Extent *e = ext.ext(); - int ofs; - if ( e->lastRecord.isNull() ) - ofs = ext.getOfs() + ( e->extentData - (char *)e ); - else - ofs = e->lastRecord.getOfs() + e->lastRecord.rec()->lengthWithHeaders; - DiskLoc dl( ext.a(), ofs ); - Record *r = dl.rec(); - r->lengthWithHeaders = Record::HeaderSize + len; - r->extentOfs = e->myLoc.getOfs(); - r->nextOfs = DiskLoc::NullOfs; - r->prevOfs = e->lastRecord.getOfs(); - memcpy( r->data, o.objdata(), len ); - if ( e->firstRecord.isNull() ) - e->firstRecord = dl; - else - e->lastRecord.rec()->nextOfs = ofs; - e->lastRecord = dl; - return dl; - } - static const char *ns() { return "ScanCapped"; } - static NamespaceDetails *nsd() { return nsdetails( ns() ); } - }; - - class Empty : public Base { - virtual void prepare() {} - virtual int count() const { return 0; } - }; - - class EmptyLooped : public Base { - virtual void prepare() { - nsd()->capFirstNewRecord = DiskLoc(); - } - virtual int count() const { return 0; } - }; - - class EmptyMultiExtentLooped : public Base { - virtual void prepare() { - nsd()->capFirstNewRecord = DiskLoc(); - } - virtual int count() const { return 0; } - virtual int nExtents() const { return 3; } - }; - - class Single : public Base { - virtual void prepare() { - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 0 ); - } - virtual int count() const { return 1; } - }; - - class NewCapFirst : public Base { - virtual void prepare() { - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 0 ); - insert( nsd()->capExtent, 1 ); - } - virtual int count() const { return 2; } - }; - - class NewCapLast : public Base { - virtual void prepare() { - insert( nsd()->capExtent, 0 ); - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 1 ); - } - virtual int count() const { return 2; } - }; - - class NewCapMiddle : public Base { - virtual void prepare() { - insert( nsd()->capExtent, 0 ); - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 1 ); - insert( nsd()->capExtent, 2 ); - } - virtual int count() const { return 3; } - }; - - class FirstExtent : public Base { - virtual void prepare() { - insert( nsd()->capExtent, 0 ); - insert( nsd()->lastExtent, 1 ); - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 2 ); - insert( nsd()->capExtent, 3 ); - } - virtual int count() const { return 4; } - virtual int nExtents() const { return 2; } - }; - - class LastExtent : public Base { - virtual void prepare() { - nsd()->capExtent = nsd()->lastExtent; - insert( nsd()->capExtent, 0 ); - insert( nsd()->firstExtent, 1 ); - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 2 ); - insert( nsd()->capExtent, 3 ); - } - virtual int count() const { return 4; } - virtual int nExtents() const { return 2; } - }; - - class MidExtent : public Base { - virtual void prepare() { - nsd()->capExtent = nsd()->firstExtent.ext()->xnext; - insert( nsd()->capExtent, 0 ); - insert( nsd()->lastExtent, 1 ); - insert( nsd()->firstExtent, 2 ); - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 3 ); - insert( nsd()->capExtent, 4 ); - } - virtual int count() const { return 5; } - virtual int nExtents() const { return 3; } - }; - - class AloneInExtent : public Base { - virtual void prepare() { - nsd()->capExtent = nsd()->firstExtent.ext()->xnext; - insert( nsd()->lastExtent, 0 ); - insert( nsd()->firstExtent, 1 ); - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 2 ); - } - virtual int count() const { return 3; } - virtual int nExtents() const { return 3; } - }; - - class FirstInExtent : public Base { - virtual void prepare() { - nsd()->capExtent = nsd()->firstExtent.ext()->xnext; - insert( nsd()->lastExtent, 0 ); - insert( nsd()->firstExtent, 1 ); - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 2 ); - insert( nsd()->capExtent, 3 ); - } - virtual int count() const { return 4; } - virtual int nExtents() const { return 3; } - }; - - class LastInExtent : public Base { - virtual void prepare() { - nsd()->capExtent = nsd()->firstExtent.ext()->xnext; - insert( nsd()->capExtent, 0 ); - insert( nsd()->lastExtent, 1 ); - insert( nsd()->firstExtent, 2 ); - nsd()->capFirstNewRecord = insert( nsd()->capExtent, 3 ); - } - virtual int count() const { return 4; } - virtual int nExtents() const { return 3; } - }; - - } // namespace ScanCapped - - class All : public UnitTest::Suite { - public: - All() { - add< ScanCapped::Empty >(); - add< ScanCapped::EmptyLooped >(); - add< ScanCapped::EmptyMultiExtentLooped >(); - add< ScanCapped::Single >(); - add< ScanCapped::NewCapFirst >(); - add< ScanCapped::NewCapLast >(); - add< ScanCapped::NewCapMiddle >(); - add< ScanCapped::FirstExtent >(); - add< ScanCapped::LastExtent >(); - add< ScanCapped::MidExtent >(); - add< ScanCapped::AloneInExtent >(); - add< ScanCapped::FirstInExtent >(); - add< ScanCapped::LastInExtent >(); - } - }; - + i->ok(); i->advance(), --j ) + ASSERT_EQUALS( j, i->current().firstElement().number() ); + ASSERT_EQUALS( -1, j ); + } +protected: + virtual void prepare() = 0; + virtual int count() const = 0; + virtual int nExtents() const { + return 0; + } + // bypass standard alloc/insert routines to use the extent we want. + static DiskLoc insert( DiskLoc ext, int i ) { + BSONObjBuilder b; + b.append( "a", i ); + BSONObj o = b.done(); + int len = o.objsize(); + Extent *e = ext.ext(); + int ofs; + if ( e->lastRecord.isNull() ) + ofs = ext.getOfs() + ( e->extentData - (char *)e ); + else + ofs = e->lastRecord.getOfs() + e->lastRecord.rec()->lengthWithHeaders; + DiskLoc dl( ext.a(), ofs ); + Record *r = dl.rec(); + r->lengthWithHeaders = Record::HeaderSize + len; + r->extentOfs = e->myLoc.getOfs(); + r->nextOfs = DiskLoc::NullOfs; + r->prevOfs = e->lastRecord.getOfs(); + memcpy( r->data, o.objdata(), len ); + if ( e->firstRecord.isNull() ) + e->firstRecord = dl; + else + e->lastRecord.rec()->nextOfs = ofs; + e->lastRecord = dl; + return dl; + } + static const char *ns() { + return "ScanCapped"; + } + static NamespaceDetails *nsd() { + return nsdetails( ns() ); + } +}; + +class Empty : public Base { + virtual void prepare() {} + virtual int count() const { + return 0; + } +}; + +class EmptyLooped : public Base { + virtual void prepare() { + nsd()->capFirstNewRecord = DiskLoc(); + } + virtual int count() const { + return 0; + } +}; + +class EmptyMultiExtentLooped : public Base { + virtual void prepare() { + nsd()->capFirstNewRecord = DiskLoc(); + } + virtual int count() const { + return 0; + } + virtual int nExtents() const { + return 3; + } +}; + +class Single : public Base { + virtual void prepare() { + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 0 ); + } + virtual int count() const { + return 1; + } +}; + +class NewCapFirst : public Base { + virtual void prepare() { + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 0 ); + insert( nsd()->capExtent, 1 ); + } + virtual int count() const { + return 2; + } +}; + +class NewCapLast : public Base { + virtual void prepare() { + insert( nsd()->capExtent, 0 ); + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 1 ); + } + virtual int count() const { + return 2; + } +}; + +class NewCapMiddle : public Base { + virtual void prepare() { + insert( nsd()->capExtent, 0 ); + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 1 ); + insert( nsd()->capExtent, 2 ); + } + virtual int count() const { + return 3; + } +}; + +class FirstExtent : public Base { + virtual void prepare() { + insert( nsd()->capExtent, 0 ); + insert( nsd()->lastExtent, 1 ); + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 2 ); + insert( nsd()->capExtent, 3 ); + } + virtual int count() const { + return 4; + } + virtual int nExtents() const { + return 2; + } +}; + +class LastExtent : public Base { + virtual void prepare() { + nsd()->capExtent = nsd()->lastExtent; + insert( nsd()->capExtent, 0 ); + insert( nsd()->firstExtent, 1 ); + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 2 ); + insert( nsd()->capExtent, 3 ); + } + virtual int count() const { + return 4; + } + virtual int nExtents() const { + return 2; + } +}; + +class MidExtent : public Base { + virtual void prepare() { + nsd()->capExtent = nsd()->firstExtent.ext()->xnext; + insert( nsd()->capExtent, 0 ); + insert( nsd()->lastExtent, 1 ); + insert( nsd()->firstExtent, 2 ); + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 3 ); + insert( nsd()->capExtent, 4 ); + } + virtual int count() const { + return 5; + } + virtual int nExtents() const { + return 3; + } +}; + +class AloneInExtent : public Base { + virtual void prepare() { + nsd()->capExtent = nsd()->firstExtent.ext()->xnext; + insert( nsd()->lastExtent, 0 ); + insert( nsd()->firstExtent, 1 ); + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 2 ); + } + virtual int count() const { + return 3; + } + virtual int nExtents() const { + return 3; + } +}; + +class FirstInExtent : public Base { + virtual void prepare() { + nsd()->capExtent = nsd()->firstExtent.ext()->xnext; + insert( nsd()->lastExtent, 0 ); + insert( nsd()->firstExtent, 1 ); + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 2 ); + insert( nsd()->capExtent, 3 ); + } + virtual int count() const { + return 4; + } + virtual int nExtents() const { + return 3; + } +}; + +class LastInExtent : public Base { + virtual void prepare() { + nsd()->capExtent = nsd()->firstExtent.ext()->xnext; + insert( nsd()->capExtent, 0 ); + insert( nsd()->lastExtent, 1 ); + insert( nsd()->firstExtent, 2 ); + nsd()->capFirstNewRecord = insert( nsd()->capExtent, 3 ); + } + virtual int count() const { + return 4; + } + virtual int nExtents() const { + return 3; + } +}; + +} // namespace ScanCapped + +class All : public UnitTest::Suite { +public: + All() { + add< ScanCapped::Empty >(); + add< ScanCapped::EmptyLooped >(); + add< ScanCapped::EmptyMultiExtentLooped >(); + add< ScanCapped::Single >(); + add< ScanCapped::NewCapFirst >(); + add< ScanCapped::NewCapLast >(); + add< ScanCapped::NewCapMiddle >(); + add< ScanCapped::FirstExtent >(); + add< ScanCapped::LastExtent >(); + add< ScanCapped::MidExtent >(); + add< ScanCapped::AloneInExtent >(); + add< ScanCapped::FirstInExtent >(); + add< ScanCapped::LastInExtent >(); + } +}; + } // namespace PdfileTests UnitTest::TestPtr pdfileTests() { diff --git a/grid/message.cpp b/grid/message.cpp index 1af556e1aac..543f5511932 100644 --- a/grid/message.cpp +++ b/grid/message.cpp @@ -71,44 +71,44 @@ void Listener::listen() { class PiggyBackData { public: - PiggyBackData( MessagingPort * port ){ + PiggyBackData( MessagingPort * port ) { _port = port; _buf = new char[1300]; _cur = _buf; } - - ~PiggyBackData(){ + + ~PiggyBackData() { flush(); delete( _cur ); } - void append( Message& m ){ + void append( Message& m ) { assert( m.data->len <= 1300 ); - + if ( len() + m.data->len > 1300 ) flush(); - + memcpy( _cur , m.data , m.data->len ); _cur += m.data->len; } - int flush(){ + int flush() { if ( _buf == _cur ) return 0; - + int x = ::send( _port->sock , _buf , len() , 0 ); _cur = _buf; return x; } - - int len(){ + + int len() { return _cur - _buf; } private: - + MessagingPort* _port; - + char * _buf; char * _cur; }; @@ -335,11 +335,11 @@ void MessagingPort::say(Message& toSend, int responseTo) { ++NextMsgId; toSend.data->id = msgid; toSend.data->responseTo = responseTo; - + int x = -100; - - if ( piggyBackData && piggyBackData->len() ){ - if ( ( piggyBackData->len() + toSend.data->len ) > 1300 ){ + + if ( piggyBackData && piggyBackData->len() ) { + if ( ( piggyBackData->len() + toSend.data->len ) > 1300 ) { // won't fit in a packet - so just send it off piggyBackData->flush(); } @@ -348,19 +348,19 @@ void MessagingPort::say(Message& toSend, int responseTo) { x = piggyBackData->flush(); } } - + if ( x == -100 ) x = ::send(sock, (char*)toSend.data, toSend.data->len , 0); - + if ( x <= 0 ) { log() << "MessagingPort say send() error " << errno << ' ' << farEnd.toString() << endl; } } -void MessagingPort::piggyBack( Message& toSend , int responseTo ){ - - if ( toSend.data->len > 1300 ){ +void MessagingPort::piggyBack( Message& toSend , int responseTo ) { + + if ( toSend.data->len > 1300 ) { // not worth saving because its almost an entire packet say( toSend ); return; @@ -371,7 +371,7 @@ void MessagingPort::piggyBack( Message& toSend , int responseTo ){ ++NextMsgId; toSend.data->id = msgid; toSend.data->responseTo = responseTo; - + if ( ! piggyBackData ) piggyBackData = new PiggyBackData( this ); diff --git a/grid/message.h b/grid/message.h index 47a9c201b34..3dc27408671 100644 --- a/grid/message.h +++ b/grid/message.h @@ -63,7 +63,7 @@ public: void reply(Message& received, Message& response); bool call(Message& toSend, Message& response); void say(Message& toSend, int responseTo = -1); - + void piggyBack( Message& toSend , int responseTo = -1 ); private: @@ -169,7 +169,7 @@ public: data = d; } - bool doIFreeIt(){ + bool doIFreeIt() { return freeIt; } diff --git a/tools/dump.cpp b/tools/dump.cpp index 92ad7059788..60bd926f6ce 100644 --- a/tools/dump.cpp +++ b/tools/dump.cpp @@ -26,87 +26,87 @@ namespace mongo { namespace po = boost::program_options; namespace dump { - - void doCollection( DBClientConnection & conn , const char * coll , path outputFile ){ - cout << "\t" << coll << " to " << outputFile.string() << endl; - - int out = open( outputFile.string().c_str() , O_WRONLY | O_CREAT | O_TRUNC , 0666 ); - assert( out ); - - BSONObjBuilder query; - auto_ptr<DBClientCursor> cursor = conn.query( coll , query.doneAndDecouple() ); - - int num = 0; - while ( cursor->more() ){ - BSONObj obj = cursor->next(); - write( out , obj.objdata() , obj.objsize() ); - num++; - } - - cout << "\t\t " << num << " objects" << endl; - close( out ); +void doCollection( DBClientConnection & conn , const char * coll , path outputFile ) { + cout << "\t" << coll << " to " << outputFile.string() << endl; + + int out = open( outputFile.string().c_str() , O_WRONLY | O_CREAT | O_TRUNC , 0666 ); + assert( out ); + + BSONObjBuilder query; + auto_ptr<DBClientCursor> cursor = conn.query( coll , query.doneAndDecouple() ); + + int num = 0; + while ( cursor->more() ) { + BSONObj obj = cursor->next(); + write( out , obj.objdata() , obj.objsize() ); + num++; } - - void go( DBClientConnection & conn , const char * db , const path outdir ){ - cout << "DATABASE: " << db << endl; - - create_directories( outdir ); - - string sns = db; - sns += ".system.namespaces"; - - BSONObjBuilder query; - auto_ptr<DBClientCursor> cursor = conn.query( sns.c_str() , query.doneAndDecouple() ); - while ( cursor->more() ){ - BSONObj obj = cursor->next(); - if ( obj.toString().find( ".$" ) != string::npos ) - continue; - - const string name = obj.getField( "name" ).valuestr(); - const string filename = name.substr( strlen( db ) + 1 ); - - doCollection( conn , name.c_str() , outdir / ( filename + ".bson" ) ); - } - + cout << "\t\t " << num << " objects" << endl; + + close( out ); +} + +void go( DBClientConnection & conn , const char * db , const path outdir ) { + cout << "DATABASE: " << db << endl; + + create_directories( outdir ); + + string sns = db; + sns += ".system.namespaces"; + + BSONObjBuilder query; + auto_ptr<DBClientCursor> cursor = conn.query( sns.c_str() , query.doneAndDecouple() ); + while ( cursor->more() ) { + BSONObj obj = cursor->next(); + if ( obj.toString().find( ".$" ) != string::npos ) + continue; + + const string name = obj.getField( "name" ).valuestr(); + const string filename = name.substr( strlen( db ) + 1 ); + + doCollection( conn , name.c_str() , outdir / ( filename + ".bson" ) ); + } - void go( const char * host , const char * db , const char * outdir ){ - DBClientConnection conn; - string errmsg; - if ( ! conn.connect( host , errmsg ) ){ - cout << "couldn't connect : " << errmsg << endl; - throw -11; - } - - path root(outdir); - - if ( strlen( db ) == 1 && db[0] == '*' ){ - cout << "all dbs" << endl; - - BSONObjBuilder query; - query.appendBool( "listDatabases" , 1 ); - - BSONObj res = conn.findOne( "admin.$cmd" , query.doneAndDecouple() ); - BSONObj dbs = res.getField( "databases" ).embeddedObjectUserCheck(); - set<string> keys; - dbs.getFieldNames( keys ); - for ( set<string>::iterator i = keys.begin() ; i != keys.end() ; i++ ){ - string key = *i; - - BSONObj db = dbs.getField( key ).embeddedObjectUserCheck(); - - const char * dbName = db.getField( "name" ).valuestr(); - if ( (string)dbName == "local" ) - continue; - go ( conn , dbName , root / dbName ); - } - } - else { - go( conn , db , root / db ); +} + +void go( const char * host , const char * db , const char * outdir ) { + DBClientConnection conn; + string errmsg; + if ( ! conn.connect( host , errmsg ) ) { + cout << "couldn't connect : " << errmsg << endl; + throw -11; + } + + path root(outdir); + + if ( strlen( db ) == 1 && db[0] == '*' ) { + cout << "all dbs" << endl; + + BSONObjBuilder query; + query.appendBool( "listDatabases" , 1 ); + + BSONObj res = conn.findOne( "admin.$cmd" , query.doneAndDecouple() ); + BSONObj dbs = res.getField( "databases" ).embeddedObjectUserCheck(); + set<string> keys; + dbs.getFieldNames( keys ); + for ( set<string>::iterator i = keys.begin() ; i != keys.end() ; i++ ) { + string key = *i; + + BSONObj db = dbs.getField( key ).embeddedObjectUserCheck(); + + const char * dbName = db.getField( "name" ).valuestr(); + if ( (string)dbName == "local" ) + continue; + go ( conn , dbName , root / dbName ); } } + else { + go( conn , db , root / db ); + } +} } // namespace dump @@ -114,23 +114,23 @@ namespace dump { using namespace mongo; -int main( int argc , char ** argv ){ +int main( int argc , char ** argv ) { boost::filesystem::path::default_name_check( boost::filesystem::no_check ); po::options_description options("dump parameters"); options.add_options() - ("help", "produce help message") - ("host,h", po::value<string>() , "mongo host to connect to") - ("db,d" , po::value<string>() , "database to dump" ) - ("out" , po::value<string>() , "output directory" ) - ; - - po::variables_map vm; + ("help", "produce help message") + ("host,h", po::value<string>() , "mongo host to connect to") + ("db,d" , po::value<string>() , "database to dump" ) + ("out" , po::value<string>() , "output directory" ) + ; + + po::variables_map vm; po::store(po::parse_command_line(argc, argv, options), vm); - po::notify(vm); - - if ( vm.count("help") ){ + po::notify(vm); + + if ( vm.count("help") ) { options.print( cerr ); return 1; } @@ -141,13 +141,13 @@ int main( int argc , char ** argv ){ if ( vm.count( "host" ) ) host = vm["host"].as<string>().c_str(); - + if ( vm.count( "db" ) ) db = vm["db"].as<string>().c_str(); - + if ( vm.count( "out" ) ) outdir = vm["out"].as<string>().c_str(); - + cout << "mongo dump" << endl; cout << "\t host \t" << host << endl; cout << "\t db \t" << db << endl; diff --git a/tools/import.cpp b/tools/import.cpp index a388060ff7f..69d3ffeaeae 100644 --- a/tools/import.cpp +++ b/tools/import.cpp @@ -29,114 +29,114 @@ namespace mongo { namespace po = boost::program_options; namespace import { - - void drillDown( DBClientConnection & conn , path root ){ - - if ( is_directory( root ) ){ - directory_iterator end; - directory_iterator i(root); - while ( i != end ){ - path p = *i; - drillDown( conn , p ); - i++; - } - return; - } - - if ( ! ( endsWith( root.string().c_str() , ".bson" ) || - endsWith( root.string().c_str() , ".bin" ) ) ){ - cerr << "don't know what to do with [" << root.string() << "]" << endl; - return; - } - - - cout << root.string() << endl; - - string ns; - { - string dir = root.branch_path().string(); - if ( dir.find( "/" ) == string::npos ) - ns += dir; - else - ns += dir.substr( dir.find_last_of( "/" ) + 1 ); - } - - { - string l = root.leaf(); - l = l.substr( 0 , l.find_last_of( "." ) ); - ns += "." + l; - } - - cout << "\t going into namespace [" << ns << "]" << endl; - - MemoryMappedFile mmf; - assert( mmf.map( root.string().c_str() ) ); - - char * data = (char*)mmf.viewOfs(); - int read = 0; - - int num = 0; - - while ( read < mmf.length() ){ - if ( ! *data ){ - cout << "\t ** got unexpected end of file ** continuing..." << endl; - break; - } - - BSONObj o( data ); - - conn.insert( ns.c_str() , o ); - - read += o.objsize(); - data += o.objsize(); - - if ( ! ( ++num % 1000 ) ) - cout << "read " << read << "/" << mmf.length() << " bytes so far. " << num << " objects" << endl; + +void drillDown( DBClientConnection & conn , path root ) { + + if ( is_directory( root ) ) { + directory_iterator end; + directory_iterator i(root); + while ( i != end ) { + path p = *i; + drillDown( conn , p ); + i++; } - - cout << "\t " << num << " objects" << endl; - + return; + } + + if ( ! ( endsWith( root.string().c_str() , ".bson" ) || + endsWith( root.string().c_str() , ".bin" ) ) ) { + cerr << "don't know what to do with [" << root.string() << "]" << endl; + return; + } + + + cout << root.string() << endl; + + string ns; + { + string dir = root.branch_path().string(); + if ( dir.find( "/" ) == string::npos ) + ns += dir; + else + ns += dir.substr( dir.find_last_of( "/" ) + 1 ); + } + + { + string l = root.leaf(); + l = l.substr( 0 , l.find_last_of( "." ) ); + ns += "." + l; } - - void go( const char * dbHost , const char * dirRoot ){ - DBClientConnection conn; - string errmsg; - if ( ! conn.connect( dbHost , errmsg ) ){ - cout << "couldn't connect : " << errmsg << endl; - throw -11; + cout << "\t going into namespace [" << ns << "]" << endl; + + MemoryMappedFile mmf; + assert( mmf.map( root.string().c_str() ) ); + + char * data = (char*)mmf.viewOfs(); + int read = 0; + + int num = 0; + + while ( read < mmf.length() ) { + if ( ! *data ) { + cout << "\t ** got unexpected end of file ** continuing..." << endl; + break; } - drillDown( conn , dirRoot ); + BSONObj o( data ); + + conn.insert( ns.c_str() , o ); + + read += o.objsize(); + data += o.objsize(); + + if ( ! ( ++num % 1000 ) ) + cout << "read " << read << "/" << mmf.length() << " bytes so far. " << num << " objects" << endl; + } + + cout << "\t " << num << " objects" << endl; + +} + + +void go( const char * dbHost , const char * dirRoot ) { + DBClientConnection conn; + string errmsg; + if ( ! conn.connect( dbHost , errmsg ) ) { + cout << "couldn't connect : " << errmsg << endl; + throw -11; } + + drillDown( conn , dirRoot ); +} } // namespace import } // namespace mongo using namespace mongo; -int main( int argc , char ** argv ){ +int main( int argc , char ** argv ) { boost::filesystem::path::default_name_check( boost::filesystem::no_check ); - + po::options_description options("import parameters"); options.add_options() - ("help", "produce help message") - ("host,h", po::value<string>() , "mongo host to connect to") - ("dir" , po::value<string>(), "directory to import from" ) - ; + ("help", "produce help message") + ("host,h", po::value<string>() , "mongo host to connect to") + ("dir" , po::value<string>(), "directory to import from" ) + ; po::positional_options_description argsOptions; argsOptions.add( "dir" , 1 ); - - po::variables_map vm; - + + po::variables_map vm; + po::store( po::command_line_parser( argc , argv ). options(options).positional(argsOptions).run(), vm ); - - po::notify(vm); - - if ( vm.count("help") ){ + + po::notify(vm); + + if ( vm.count("help") ) { options.print( cerr ); return 1; } @@ -146,7 +146,7 @@ int main( int argc , char ** argv ){ if ( vm.count( "host" ) ) host = vm["host"].as<string>().c_str(); - + if ( vm.count( "dir" ) ) dir = vm["dir"].as<string>().c_str(); diff --git a/util/log.h b/util/log.h index 6bcca584184..4024f49be7c 100644 --- a/util/log.h +++ b/util/log.h @@ -107,7 +107,9 @@ inline Logstream& log() { return logstream.prolog(); } -inline ostream& stdcout() { return cout; } +inline ostream& stdcout() { + return cout; +} #define cout logstream diff --git a/util/md5.h b/util/md5.h index 698c995d8f4..d00123414ae 100644 --- a/util/md5.h +++ b/util/md5.h @@ -71,18 +71,18 @@ typedef struct md5_state_s { } md5_state_t; #ifdef __cplusplus -extern "C" +extern "C" { #endif -/* Initialize the algorithm. */ -void md5_init(md5_state_t *pms); + /* Initialize the algorithm. */ + void md5_init(md5_state_t *pms); -/* Append a string to the message. */ -void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); + /* Append a string to the message. */ + void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); -/* Finish the message and return the digest. */ -void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); + /* Finish the message and return the digest. */ + void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); #ifdef __cplusplus } /* end extern "C" */ diff --git a/util/miniwebserver.cpp b/util/miniwebserver.cpp index 2c342aa7f11..b3b514bae3f 100644 --- a/util/miniwebserver.cpp +++ b/util/miniwebserver.cpp @@ -51,41 +51,41 @@ bool MiniWebServer::init(int port) { return true; } -string MiniWebServer::parseURL( const char * buf ){ +string MiniWebServer::parseURL( const char * buf ) { const char * urlStart = strstr( buf , " " ); if ( ! urlStart ) return "/"; - + urlStart++; - + const char * end = strstr( urlStart , " " ); - if ( ! end ){ + if ( ! end ) { end = strstr( urlStart , "\r" ); - if ( ! end ){ + if ( ! end ) { end = strstr( urlStart , "\n" ); } } - - if ( ! end ) + + if ( ! end ) return "/"; - + int diff = (int)(end-urlStart); if ( diff < 0 || diff > 255 ) return "/"; - + return string( urlStart , (int)(end-urlStart) ); } -void MiniWebServer::parseParams( map<string,string> & params , string query ){ +void MiniWebServer::parseParams( map<string,string> & params , string query ) { if ( query.size() == 0 ) return; - - while ( query.size() ){ - + + while ( query.size() ) { + string::size_type amp = query.find( "&" ); - + string cur; - if ( amp == string::npos ){ + if ( amp == string::npos ) { cur = query; query = ""; } @@ -97,13 +97,13 @@ void MiniWebServer::parseParams( map<string,string> & params , string query ){ string::size_type eq = cur.find( "=" ); if ( eq == string::npos ) continue; - + params[cur.substr(0,eq)] = cur.substr(eq+1); } return; } -string MiniWebServer::parseMethod( const char * headers ){ +string MiniWebServer::parseMethod( const char * headers ) { const char * end = strstr( headers , " " ); if ( ! end ) return "GET"; @@ -117,7 +117,7 @@ const char *MiniWebServer::body( const char *buf ) { bool MiniWebServer::fullReceive( const char *buf ) { const char *bod = body( buf ); - if( !bod ) + if ( !bod ) return false; const char *lenString = "Content-Length:"; const char *lengthLoc = strstr( buf, lenString ); @@ -133,7 +133,7 @@ bool MiniWebServer::fullReceive( const char *buf ) { void MiniWebServer::accepted(int s) { char buf[4096]; int len = 0; - while( 1 ) { + while ( 1 ) { int x = ::recv(s, buf + len, sizeof(buf) - 1 - len, 0); if ( x <= 0 ) { return; @@ -144,7 +144,7 @@ void MiniWebServer::accepted(int s) { break; } buf[len] = 0; - + string responseMsg; int responseCode = 599; vector<string> headers; diff --git a/util/miniwebserver.h b/util/miniwebserver.h index a101e63fa32..503655340f9 100644 --- a/util/miniwebserver.h +++ b/util/miniwebserver.h @@ -48,7 +48,7 @@ protected: private: void accepted(int s); static bool fullReceive( const char *buf ); - + int sock; }; diff --git a/util/mmap.cpp b/util/mmap.cpp index 447775cb2ad..2d0df61f3d9 100644 --- a/util/mmap.cpp +++ b/util/mmap.cpp @@ -181,9 +181,10 @@ void* MemoryMappedFile::map(const char *filename, int length) { } // Check for end of disk. lseek(fd, length - 1, SEEK_SET); - write(fd, "", 1); + write(fd, "", 1); Logstream &l = log(); - l << "new datafile " << filename << " filling with zeroes..."; l.flush(); + l << "new datafile " << filename << " filling with zeroes..."; + l.flush(); Timer t; int z = 8192; char buf[z]; diff --git a/util/mmap.h b/util/mmap.h index 07cc885be2f..bc89d7ef8e9 100644 --- a/util/mmap.h +++ b/util/mmap.h @@ -35,15 +35,15 @@ public: void* map(const char *filename, int length); void flush(bool sync); - + void* viewOfs() { return view; } - int length(){ - return len; + int length() { + return len; } - + void updateLength( const char *filename, int &length ) const; private: |