summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDwight <dmerriman@gmail.com>2009-03-25 17:30:54 -0400
committerDwight <dmerriman@gmail.com>2009-03-25 17:30:54 -0400
commit724e71fa653d0064766cd9c515d0d1ce21f97f23 (patch)
treeec698e96685f547c301ee122560e903da59451bc
parentb2b5506629cb733392197d6c9f6d07ac463ec7e4 (diff)
parent265436b22df4830b711227c7cf9f441c7f7dc4dd (diff)
downloadmongo-724e71fa653d0064766cd9c515d0d1ce21f97f23.tar.gz
Merge branch 'master' of git@github.com:mongodb/mongo
-rw-r--r--SConstruct5
-rw-r--r--client/dbclient.cpp71
-rw-r--r--client/dbclient.h112
-rw-r--r--client/model.h6
-rw-r--r--db/instance.h5
-rw-r--r--db/jsobj.cpp2
-rw-r--r--db/jsobj.h7
-rw-r--r--dbtests/jsobjtests.cpp8
-rw-r--r--dbtests/mockdbclient.h8
-rw-r--r--jstests/repl/repl6.js76
-rw-r--r--mongo.xcodeproj/project.pbxproj2
-rw-r--r--shell/dbshell.cpp30
-rw-r--r--util/builder.h4
13 files changed, 238 insertions, 98 deletions
diff --git a/SConstruct b/SConstruct
index 9cc6a744477..24dfc86bc3b 100644
--- a/SConstruct
+++ b/SConstruct
@@ -162,6 +162,7 @@ allClientFiles = commonFiles + coreDbFiles + [ "client/clientOnly.cpp" , "client
onlyServer = len( COMMAND_LINE_TARGETS ) == 0 or ( len( COMMAND_LINE_TARGETS ) == 1 and str( COMMAND_LINE_TARGETS[0] ) == "mongod" )
nix = False
useJavaHome = False
+linux = False
linux64 = False
darwin = False
windows = False
@@ -231,6 +232,7 @@ if "darwin" == os.sys.platform:
env.Append( LIBPATH=["/sw/lib/", "/opt/local/lib"] )
elif "linux2" == os.sys.platform:
+ linux = True
useJavaHome = True
javaOS = "linux"
platform = "linux"
@@ -480,6 +482,9 @@ def doConfigure( myenv , needJava=True , needPcre=True , shell=False ):
else:
print( "WARNING: no readline, shell will be a bit ugly" )
+ if linux:
+ myCheckLib( "rt" , True )
+
# this will add it iff it exists and works
myCheckLib( "boost_system-mt" )
diff --git a/client/dbclient.cpp b/client/dbclient.cpp
index 2cfba890fa7..47c7bfc33bc 100644
--- a/client/dbclient.cpp
+++ b/client/dbclient.cpp
@@ -28,7 +28,7 @@
namespace mongo {
- Query& Query::where(const char *jscode, BSONObj scope) {
+ Query& Query::where(const string &jscode, BSONObj scope) {
/* use where() before sort() and hint() and explain(), else this will assert. */
assert( !obj.hasField("query") );
BSONObjBuilder b;
@@ -104,16 +104,16 @@ namespace mongo {
return o.getIntField("ok") == 1;
}
- inline bool DBClientWithCommands::runCommand(const char *dbname, const BSONObj& cmd, BSONObj &info) {
- string ns = string(dbname) + ".$cmd";
- info = findOne(ns.c_str(), cmd);
+ inline bool DBClientWithCommands::runCommand(const string &dbname, const BSONObj& cmd, BSONObj &info) {
+ string ns = dbname + ".$cmd";
+ info = findOne(ns, cmd);
return isOk(info);
}
/* 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) {
+ bool DBClientWithCommands::simpleCommand(const string &dbname, BSONObj *info, const string &command) {
BSONObj o;
if ( info == 0 )
info = &o;
@@ -122,7 +122,7 @@ namespace mongo {
return runCommand(dbname, b.done(), *info);
}
- unsigned long long DBClientWithCommands::count(const char *_ns, BSONObj query) {
+ unsigned long long DBClientWithCommands::count(const string &_ns, BSONObj query) {
NamespaceString ns(_ns);
BSONObj cmd = BSON( "count" << ns.coll << "query" << query );
BSONObj res;
@@ -152,20 +152,20 @@ namespace mongo {
BSONObj getnoncecmdobj = fromjson("{getnonce:1}");
- string DBClientWithCommands::createPasswordDigest( const char * username , const char * clearTextPassword ){
+ string DBClientWithCommands::createPasswordDigest( const string & username , const string & clearTextPassword ){
md5digest d;
{
md5_state_t st;
md5_init(&st);
- md5_append(&st, (const md5_byte_t *) username, strlen(username));
+ md5_append(&st, (const md5_byte_t *) username.data(), username.length());
md5_append(&st, (const md5_byte_t *) ":mongo:", 7 );
- md5_append(&st, (const md5_byte_t *) clearTextPassword, strlen(clearTextPassword));
+ md5_append(&st, (const md5_byte_t *) clearTextPassword.data(), clearTextPassword.length());
md5_finish(&st, d);
}
return digestToString( d );
}
- bool DBClientWithCommands::auth(const char *dbname, const char *username, const char *password_text, string& errmsg, bool digestPassword) {
+ bool DBClientWithCommands::auth(const string &dbname, const string &username, const string &password_text, string& errmsg, bool digestPassword) {
//cout << "TEMP AUTH " << toString() << dbname << ' ' << username << ' ' << password_text << ' ' << digestPassword << endl;
string password = password_text;
@@ -194,7 +194,7 @@ namespace mongo {
md5_state_t st;
md5_init(&st);
md5_append(&st, (const md5_byte_t *) nonce.c_str(), nonce.size() );
- md5_append(&st, (const md5_byte_t *) username, strlen(username));
+ md5_append(&st, (const md5_byte_t *) username.data(), username.length());
md5_append(&st, (const md5_byte_t *) password.c_str(), password.size() );
md5_finish(&st, d);
}
@@ -219,7 +219,7 @@ namespace mongo {
return ok;
}
- bool DBClientWithCommands::createCollection(const char *ns, unsigned size, bool capped, int max, BSONObj *info) {
+ bool DBClientWithCommands::createCollection(const string &ns, unsigned size, bool capped, int max, BSONObj *info) {
BSONObj o;
if ( info == 0 ) info = &o;
BSONObjBuilder b;
@@ -227,12 +227,11 @@ namespace mongo {
if ( size ) b.append("size", size);
if ( capped ) b.append("capped", true);
if ( max ) b.append("max", max);
- string db = nsToClient(ns);
+ string db = nsToClient(ns.c_str());
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 );
+ bool DBClientWithCommands::copyDatabase(const string &fromdb, const string &todb, const string &fromhost, BSONObj *info) {
BSONObj o;
if ( info == 0 ) info = &o;
BSONObjBuilder b;
@@ -243,7 +242,7 @@ namespace mongo {
return runCommand("admin", b.done(), *info);
}
- bool DBClientWithCommands::setDbProfilingLevel(const char *dbname, ProfilingLevel level, BSONObj *info ) {
+ bool DBClientWithCommands::setDbProfilingLevel(const string &dbname, ProfilingLevel level, BSONObj *info ) {
BSONObj o;
if ( info == 0 ) info = &o;
@@ -251,7 +250,7 @@ namespace mongo {
// 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";
+ string ns = dbname + ".system.profile";
createCollection(ns.c_str(), 1024 * 1024, true, 0, info);
}
@@ -262,7 +261,7 @@ namespace mongo {
BSONObj getprofilingcmdobj = fromjson("{\"profile\":-1}");
- bool DBClientWithCommands::getDbProfilingLevel(const char *dbname, ProfilingLevel& level, BSONObj *info) {
+ bool DBClientWithCommands::getDbProfilingLevel(const string &dbname, ProfilingLevel& level, BSONObj *info) {
BSONObj o;
if ( info == 0 ) info = &o;
if ( runCommand(dbname, getprofilingcmdobj, *info) ) {
@@ -272,9 +271,9 @@ namespace mongo {
return false;
}
- bool DBClientWithCommands::eval(const char *dbname, const char *jscode, BSONObj& info, BSONElement& retValue, BSONObj *args) {
+ bool DBClientWithCommands::eval(const string &dbname, const string &jscode, BSONObj& info, BSONElement& retValue, BSONObj *args) {
BSONObjBuilder b;
- b.appendCode("$eval", jscode);
+ b.appendCode("$eval", jscode.c_str());
if ( args )
b.appendArray("args", *args);
bool ok = runCommand(dbname, b.done(), info);
@@ -283,7 +282,7 @@ namespace mongo {
return ok;
}
- bool DBClientWithCommands::eval(const char *dbname, const char *jscode) {
+ bool DBClientWithCommands::eval(const string &dbname, const string &jscode) {
BSONObj info;
BSONElement retValue;
return eval(dbname, jscode, info, retValue);
@@ -349,7 +348,7 @@ namespace mongo {
/* --- dbclientconnection --- */
- bool DBClientConnection::auth(const char *dbname, const char *username, const char *password_text, string& errmsg, bool digestPassword) {
+ bool DBClientConnection::auth(const string &dbname, const string &username, const string &password_text, string& errmsg, bool digestPassword) {
string password = password_text;
if( digestPassword )
password = createPasswordDigest( username , password_text );
@@ -365,7 +364,7 @@ namespace mongo {
return DBClientBase::auth(dbname, username, password.c_str(), errmsg, false);
}
- BSONObj DBClientBase::findOne(const char *ns, Query query, BSONObj *fieldsToReturn, int queryOptions) {
+ BSONObj DBClientBase::findOne(const string &ns, Query query, BSONObj *fieldsToReturn, int queryOptions) {
auto_ptr<DBClientCursor> c =
this->query(ns, query, 1, 0, fieldsToReturn, queryOptions);
@@ -377,7 +376,7 @@ namespace mongo {
return c->next().copy();
}
- bool DBClientConnection::connect(const char *_serverAddress, string& errmsg) {
+ bool DBClientConnection::connect(const string &_serverAddress, string& errmsg) {
serverAddress = _serverAddress;
string ip;
@@ -436,7 +435,7 @@ namespace mongo {
}
}
- auto_ptr<DBClientCursor> DBClientBase::query(const char *ns, Query query, int nToReturn,
+ auto_ptr<DBClientCursor> DBClientBase::query(const string &ns, Query query, int nToReturn,
int nToSkip, BSONObj *fieldsToReturn, int queryOptions) {
auto_ptr<DBClientCursor> c( new DBClientCursor( this,
ns, query.obj, nToReturn, nToSkip,
@@ -446,14 +445,14 @@ namespace mongo {
return auto_ptr< DBClientCursor >( 0 );
}
- auto_ptr<DBClientCursor> DBClientBase::getMore( const char *ns, long long cursorId, int nToReturn, int options ) {
+ auto_ptr<DBClientCursor> DBClientBase::getMore( const string &ns, long long cursorId, int nToReturn, int options ) {
auto_ptr<DBClientCursor> c( new DBClientCursor( this, ns, cursorId, nToReturn, options ) );
if ( c->init() )
return c;
return auto_ptr< DBClientCursor >( 0 );
}
- void DBClientBase::insert( const char * ns , BSONObj obj ) {
+ void DBClientBase::insert( const string & ns , BSONObj obj ) {
Message toSend;
BufBuilder b;
@@ -467,7 +466,7 @@ namespace mongo {
say( toSend );
}
- void DBClientBase::insert( const char * ns , const vector< BSONObj > &v ) {
+ void DBClientBase::insert( const string & ns , const vector< BSONObj > &v ) {
Message toSend;
BufBuilder b;
@@ -482,7 +481,7 @@ namespace mongo {
say( toSend );
}
- void DBClientBase::remove( const char * ns , Query obj , bool justOne ) {
+ void DBClientBase::remove( const string & ns , Query obj , bool justOne ) {
Message toSend;
BufBuilder b;
@@ -502,7 +501,7 @@ namespace mongo {
say( toSend );
}
- void DBClientBase::update( const char * ns , Query query , BSONObj obj , bool upsert ) {
+ void DBClientBase::update( const string & ns , Query query , BSONObj obj , bool upsert ) {
BufBuilder b;
b.append( (int)0 ); // reserverd
@@ -519,7 +518,7 @@ namespace mongo {
say( toSend );
}
- bool DBClientBase::ensureIndex( const string &ns , BSONObj keys , const char * name ) {
+ bool DBClientBase::ensureIndex( const string &ns , BSONObj keys , const string & name ) {
BSONObjBuilder toSave;
toSave.append( "ns" , ns );
toSave.append( "key" , keys );
@@ -527,7 +526,7 @@ namespace mongo {
string cacheKey(ns);
cacheKey += "--";
- if ( name ) {
+ if ( name != "" ) {
toSave.append( "name" , name );
cacheKey += name;
}
@@ -840,7 +839,7 @@ again:
return master == Left ? left : right;
}
- bool DBClientPaired::connect(const char *serverHostname1, const char *serverHostname2) {
+ bool DBClientPaired::connect(const string &serverHostname1, const string &serverHostname2) {
string errmsg;
bool l = left.connect(serverHostname1, errmsg);
bool r = right.connect(serverHostname2, errmsg);
@@ -856,7 +855,7 @@ again:
return true;
}
- bool DBClientPaired::auth(const char *dbname, const char *username, const char *pwd, string& errmsg) {
+ bool DBClientPaired::auth(const string &dbname, const string &username, const string &pwd, string& errmsg) {
DBClientConnection& m = checkMaster();
if( !m.auth(dbname, username, pwd, errmsg) )
return false;
@@ -873,13 +872,13 @@ again:
return true;
}
- auto_ptr<DBClientCursor> DBClientPaired::query(const char *a, Query b, int c, int d,
+ auto_ptr<DBClientCursor> DBClientPaired::query(const string &a, Query b, int c, int d,
BSONObj *e, int f)
{
return checkMaster().query(a,b,c,d,e,f);
}
- BSONObj DBClientPaired::findOne(const char *a, Query b, BSONObj *c, int d) {
+ BSONObj DBClientPaired::findOne(const string &a, Query b, BSONObj *c, int d) {
return checkMaster().findOne(a,b,c,d);
}
diff --git a/client/dbclient.h b/client/dbclient.h
index ce65f44c495..a5b2374fc14 100644
--- a/client/dbclient.h
+++ b/client/dbclient.h
@@ -60,8 +60,8 @@ namespace mongo {
Query(const BSONObj& b) : obj(b) { }
Query(const string &json) :
obj(fromjson(json)) { }
- Query(const char *json) :
- obj(fromjson(json)) { }
+ Query(const char * json) :
+ obj(fromjson(json)) { }
/** Add a sort (ORDER BY) criteria to the query expression.
@param sortPattern the sort order template. For example to order by name ascending, time descending:
@@ -78,7 +78,7 @@ namespace mongo {
@param asc = 1 for ascending order
asc = -1 for descending order
*/
- Query& sort(const char *field, int asc = 1) { sort( BSON( field << asc ) ); return *this; }
+ Query& sort(const string &field, int asc = 1) { sort( BSON( field << asc ) ); return *this; }
/** Provide a hint to the query.
@param keyPattern Key pattern for the index to use.
@@ -86,7 +86,7 @@ namespace mongo {
hint("{ts:1}")
*/
Query& hint(BSONObj keyPattern);
- Query& hint(const char *jsonKeyPatt) { return hint(fromjson(jsonKeyPatt)); }
+ Query& hint(const string &jsonKeyPatt) { return hint(fromjson(jsonKeyPatt)); }
/** Return explain information about execution of this query instead of the actual query results.
Normally it is easier to use the mongo shell to run db.find(...).explain().
@@ -109,8 +109,8 @@ namespace mongo {
conn.findOne("test.coll", Query("{a:3}").where("this.b == 2 || this.c == 3"));
Query badBalance = Query().where("this.debits - this.credits < 0");
*/
- Query& where(const char *jscode, BSONObj scope);
- Query& where(const char *jscode) { return where(jscode, BSONObj()); }
+ Query& where(const string &jscode, BSONObj scope);
+ Query& where(const string &jscode) { return where(jscode, BSONObj()); }
/**
@@ -141,7 +141,7 @@ namespace mongo {
virtual bool call( Message &toSend, Message &response, bool assertOk=true ) = 0;
virtual void say( Message &toSend ) = 0;
virtual void sayPiggyBack( Message &toSend ) = 0;
- virtual void checkResponse( const char *data, int nReturned ) {}
+ virtual void checkResponse( const string &data, int nReturned ) {}
};
/** Queries return a cursor object */
@@ -181,7 +181,7 @@ namespace mongo {
bool init();
- DBClientCursor( DBConnector *_connector, const char * _ns, BSONObj _query, int _nToReturn,
+ DBClientCursor( DBConnector *_connector, const string &_ns, BSONObj _query, int _nToReturn,
int _nToSkip, BSONObj *_fieldsToReturn, int queryOptions ) :
connector(_connector),
ns(_ns),
@@ -198,7 +198,7 @@ namespace mongo {
ownCursor_( true ) {
}
- DBClientCursor( DBConnector *_connector, const char *_ns, long long _cursorId, int _nToReturn, int options ) :
+ DBClientCursor( DBConnector *_connector, const string &_ns, long long _cursorId, int _nToReturn, int options ) :
connector(_connector),
ns(_ns),
nToReturn( _nToReturn ),
@@ -241,20 +241,20 @@ namespace mongo {
*/
class DBClientInterface : boost::noncopyable {
public:
- virtual auto_ptr<DBClientCursor> query(const char *ns, Query query, int nToReturn = 0, int nToSkip = 0,
+ virtual auto_ptr<DBClientCursor> query(const string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
BSONObj *fieldsToReturn = 0, int queryOptions = 0) = 0;
- virtual auto_ptr<DBClientCursor> getMore( const char *ns, long long cursorId, int nToReturn = 0, int options = 0 ) = 0;
+ virtual auto_ptr<DBClientCursor> getMore( const string &ns, long long cursorId, int nToReturn = 0, int options = 0 ) = 0;
- virtual BSONObj findOne(const char *ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0) = 0;
+ virtual BSONObj findOne(const string &ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0) = 0;
- virtual void insert( const char * ns, BSONObj obj ) = 0;
+ virtual void insert( const string &ns, BSONObj obj ) = 0;
- virtual void insert( const char * ns, const vector< BSONObj >& v ) = 0;
+ virtual void insert( const string &ns, const vector< BSONObj >& v ) = 0;
- virtual void remove( const char * ns , Query query, bool justOne = 0 ) = 0;
+ virtual void remove( const string &ns , Query query, bool justOne = 0 ) = 0;
- virtual void update( const char * ns , Query query , BSONObj obj , bool upsert = 0 ) = 0;
+ virtual void update( const string &ns , Query query , BSONObj obj , bool upsert = 0 ) = 0;
virtual ~DBClientInterface() { }
};
@@ -265,7 +265,7 @@ namespace mongo {
*/
class DBClientWithCommands : public DBClientInterface {
bool isOk(const BSONObj&);
- bool simpleCommand(const char *dbname, BSONObj *info, const char *command);
+ bool simpleCommand(const string &dbname, BSONObj *info, const string &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
@@ -278,7 +278,7 @@ namespace mongo {
@return true if the command returned "ok".
*/
- bool runCommand(const char *dbname, const BSONObj& cmd, BSONObj &info);
+ bool runCommand(const string &dbname, const BSONObj& cmd, BSONObj &info);
/** Authorize access to a particular database.
Authentication is separate for each database on the server -- you may authenticate for any
@@ -288,14 +288,14 @@ namespace mongo {
@param digestPassword if password is plain text, set this to true. otherwise assumed to be pre-digested
@return true if successful
*/
- virtual bool auth(const char *dbname, const char *username, const char *pwd, string& errmsg, bool digestPassword = true);
+ virtual bool auth(const string &dbname, const string &username, const string &pwd, string& errmsg, bool digestPassword = true);
/** count number of objects in collection ns that match the query criteria specified
throws UserAssertion if database returns an error
*/
- unsigned long long count(const char *ns, BSONObj query = BSONObj());
+ unsigned long long count(const string &ns, BSONObj query = BSONObj());
- string createPasswordDigest( const char * username , const char * clearTextPassword );
+ string createPasswordDigest( const string &username , const string &clearTextPassword );
/** returns true in isMaster parm if this db is the current master
of a replica pair.
@@ -323,7 +323,7 @@ namespace mongo {
returns true if successful.
*/
- bool createCollection(const char *ns, unsigned size = 0, bool capped = false, int max = 0, BSONObj *info = 0);
+ bool createCollection(const string &ns, unsigned size = 0, bool capped = false, int max = 0, BSONObj *info = 0);
/** Get error result from the last operation on this connection.
@return error or empty string if no error.
@@ -345,7 +345,7 @@ namespace mongo {
bool resetError() { return simpleCommand("admin", 0, "reseterror"); }
/** Erase / drop an entire database */
- bool dropDatabase(const char *dbname, BSONObj *info = 0) {
+ bool dropDatabase(const string &dbname, BSONObj *info = 0) {
return simpleCommand(dbname, info, "dropDatabase");
}
@@ -364,7 +364,7 @@ namespace mongo {
/** 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) {
+ bool repairDatabase(const string &dbname, BSONObj *info = 0) {
return simpleCommand(dbname, info, "repairDatabase");
}
@@ -387,7 +387,7 @@ namespace mongo {
returns true if successful
*/
- bool copyDatabase(const char *fromdb, const char *todb, const char *fromhost = "", BSONObj *info = 0);
+ bool copyDatabase(const string &fromdb, const string &todb, const string &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
@@ -398,8 +398,8 @@ namespace mongo {
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);
+ bool setDbProfilingLevel(const string &dbname, ProfilingLevel level, BSONObj *info = 0);
+ bool getDbProfilingLevel(const string &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
@@ -416,12 +416,12 @@ namespace mongo {
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);
+ bool eval(const string &dbname, const string &jscode, BSONObj& info, BSONElement& retValue, BSONObj *args = 0);
/**
*/
- bool validate( const char * ns , bool scandata=true ){
+ bool validate( const string &ns , bool scandata=true ){
BSONObj cmd = BSON( "validate" << nsGetCollection( ns ) << "scandata" << scandata );
BSONObj info;
return runCommand( nsGetDB( ns ).c_str() , cmd , info );
@@ -430,9 +430,9 @@ namespace mongo {
/* 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);
+ bool eval(const string &dbname, const string &jscode);
template< class T >
- bool eval(const char *dbname, const char *jscode, T parm1) {
+ bool eval(const string &dbname, const string &jscode, T parm1) {
BSONObj info;
BSONElement retValue;
BSONObjBuilder b;
@@ -443,7 +443,7 @@ namespace mongo {
/** eval 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) {
+ bool eval(const string &dbname, const string &jscode, T parm1, NumType& ret) {
BSONObj info;
BSONElement retValue;
BSONObjBuilder b;
@@ -497,41 +497,41 @@ namespace mongo {
@return cursor. 0 if error (connection failure)
@throws AssertionException
*/
- virtual auto_ptr<DBClientCursor> query(const char *ns, Query query, int nToReturn = 0, int nToSkip = 0,
+ virtual auto_ptr<DBClientCursor> query(const string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
BSONObj *fieldsToReturn = 0, int queryOptions = 0);
/** @param cursorId id of cursor to retrieve
@return an handle to a previously allocated cursor
@throws AssertionException
*/
- virtual auto_ptr<DBClientCursor> getMore( const char *ns, long long cursorId, int nToReturn = 0, int options = 0 );
+ virtual auto_ptr<DBClientCursor> getMore( const string &ns, long long cursorId, int nToReturn = 0, int options = 0 );
/**
@return a single object that matches the query. if none do, then the object is empty
@throws AssertionException
*/
- virtual BSONObj findOne(const char *ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0);
+ virtual BSONObj findOne(const string &ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0);
/**
insert an object into the database
*/
- virtual void insert( const char * ns , BSONObj obj );
+ virtual void insert( const string &ns , BSONObj obj );
/**
insert a vector of objects into the database
*/
- virtual void insert( const char * ns, const vector< BSONObj >& v );
+ virtual void insert( const string &ns, const vector< BSONObj >& v );
/**
remove matching objects from the database
@param justOne if this true, then once a single match is found will stop
*/
- virtual void remove( const char * ns , Query q , bool justOne = 0 );
+ virtual void remove( const string &ns , Query q , bool justOne = 0 );
/**
updates objects matching query
*/
- virtual void update( const char * ns , Query query , BSONObj obj , bool upsert = 0 );
+ virtual void update( const string &ns , Query query , BSONObj obj , bool upsert = 0 );
/** Create an index if it does not already exist.
ensureIndex calls are remembered so it is safe/fast to call this function many
@@ -541,12 +541,14 @@ namespace mongo {
@return whether or not sent message to db.
should be true on first call, false on subsequent unless resetIndexCache was called
*/
- virtual bool ensureIndex( const string &ns , BSONObj keys , const char * name = 0 );
+ virtual bool ensureIndex( const string &ns , BSONObj keys , const string &name = "" );
/**
clears the index cache, so the subsequent call to ensureIndex for any index will go to the server
*/
virtual void resetIndexCache();
+
+ virtual string getServerAddress() const = 0;
private:
set<string> _seenIndexes;
@@ -592,7 +594,7 @@ namespace mongo {
@param errmsg any relevant error message will appended to the string
@return false if fails to connect.
*/
- virtual bool connect(const char *serverHostname, string& errmsg);
+ virtual bool connect(const string &serverHostname, string& errmsg);
/** Connect to a Mongo database server. Exception throwing version.
Throws a UserException if cannot connect.
@@ -608,9 +610,9 @@ namespace mongo {
throw ConnectException(string("can't connect ") + errmsg);
}
- virtual bool auth(const char *dbname, const char *username, const char *pwd, string& errmsg, bool digestPassword = true);
+ virtual bool auth(const string &dbname, const string &username, const string &pwd, string& errmsg, bool digestPassword = true);
- virtual auto_ptr<DBClientCursor> query(const char *ns, Query query, int nToReturn = 0, int nToSkip = 0,
+ virtual auto_ptr<DBClientCursor> query(const string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
BSONObj *fieldsToReturn = 0, int queryOptions = 0) {
checkConnection();
return DBClientBase::query( ns, query, nToReturn, nToSkip, fieldsToReturn, queryOptions );
@@ -639,6 +641,10 @@ namespace mongo {
string toString() {
return serverAddress;
}
+
+ string getServerAddress() const {
+ return serverAddress;
+ }
protected:
virtual bool call( Message &toSend, Message &response, bool assertOk = true );
@@ -673,7 +679,7 @@ namespace mongo {
when false returned, you can still try to use this connection object, it will
try reconnects.
*/
- bool connect(const char *serverHostname1, const char *serverHostname2);
+ bool connect(const string &serverHostname1, const string &serverHostname2);
/** Connect to a server pair using a host pair string of the form
hostname[:port],hostname[:port]
@@ -686,35 +692,35 @@ namespace mongo {
/** Authorize. Authorizes both sides of the pair as needed.
*/
- bool auth(const char *dbname, const char *username, const char *pwd, string& errmsg);
+ bool auth(const string &dbname, const string &username, const string &pwd, string& errmsg);
/** throws userassertion "no master found" */
virtual
- auto_ptr<DBClientCursor> query(const char *ns, Query query, int nToReturn = 0, int nToSkip = 0,
+ auto_ptr<DBClientCursor> query(const string &ns, Query query, int nToReturn = 0, int nToSkip = 0,
BSONObj *fieldsToReturn = 0, int queryOptions = 0);
/** throws userassertion "no master found" */
virtual
- BSONObj findOne(const char *ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0);
+ BSONObj findOne(const string &ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0);
/** insert */
- virtual void insert( const char * ns , BSONObj obj ) {
+ virtual void insert( const string &ns , BSONObj obj ) {
checkMaster().insert(ns, obj);
}
/** insert multiple objects. Note that single object insert is asynchronous, so this version
is only nominally faster and not worth a special effort to try to use. */
- virtual void insert( const char * ns, const vector< BSONObj >& v ) {
+ virtual void insert( const string &ns, const vector< BSONObj >& v ) {
checkMaster().insert(ns, v);
}
/** remove */
- virtual void remove( const char * ns , Query obj , bool justOne = 0 ) {
+ virtual void remove( const string &ns , Query obj , bool justOne = 0 ) {
checkMaster().remove(ns, obj, justOne);
}
/** update */
- virtual void update( const char * ns , Query query , BSONObj obj , bool upsert = 0 ) {
+ virtual void update( const string &ns , Query query , BSONObj obj , bool upsert = 0 ) {
return checkMaster().update(ns, query, obj, upsert);
}
@@ -726,6 +732,10 @@ namespace mongo {
master = ( ( master == Left ) ? NotSetR : NotSetL );
}
+ string getServerAddress() const {
+ return left.getServerAddress() + "," + right.getServerAddress();
+ }
+
/* TODO - not yet implemented. mongos may need these. */
virtual bool call( Message &toSend, Message &response, bool assertOk=true ) { assert(false); return false; }
virtual void say( Message &toSend ) { assert(false); }
diff --git a/client/model.h b/client/model.h
index f50bab2f98b..f0c57149e70 100644
--- a/client/model.h
+++ b/client/model.h
@@ -43,12 +43,12 @@ namespace mongo {
virtual void unserialize(const BSONObj& from) = 0;
virtual string modelServer() = 0;
-
+
/** Load a single object.
@return true if successful.
*/
- bool load(BSONObj& query);
- void save( bool check=false );
+ virtual bool load(BSONObj& query);
+ virtual void save( bool check=false );
private:
BSONObj _id;
diff --git a/db/instance.h b/db/instance.h
index 925cdb49ac3..4b45df78e33 100644
--- a/db/instance.h
+++ b/db/instance.h
@@ -99,11 +99,14 @@ namespace mongo {
// --- local client ---
-
+
class DBDirectClient : public DBClientBase {
virtual string toString() {
return "DBDirectClient";
}
+ virtual string getServerAddress() const{
+ return "localhost"; // TODO: should this have the port?
+ }
virtual bool call( Message &toSend, Message &response, bool assertOk=true );
virtual void say( Message &toSend );
virtual void sayPiggyBack( Message &toSend ) {
diff --git a/db/jsobj.cpp b/db/jsobj.cpp
index 5beda57f66c..e6588dc73cf 100644
--- a/db/jsobj.cpp
+++ b/db/jsobj.cpp
@@ -1056,7 +1056,7 @@ namespace mongo {
BSONElement::BSONElement() {
data = &js0.eoo;
fieldNameSize_ = 0;
- totalSize = 5;
+ totalSize = 1;
}
struct BsonUnitTest : public UnitTest {
diff --git a/db/jsobj.h b/db/jsobj.h
index b551b4bf828..b64535e3ee5 100644
--- a/db/jsobj.h
+++ b/db/jsobj.h
@@ -858,6 +858,10 @@ namespace mongo {
b.append(fieldName);
b.append(n);
}
+ /** Append a 32 bit integer element */
+ void append(const string &fieldName, int n) {
+ append( fieldName.c_str(), n );
+ }
void append(const char *fieldName, unsigned n) { append(fieldName, (int) n); }
/** Append a double element */
BSONObjBuilder& append(const char *fieldName, double n) {
@@ -1014,6 +1018,9 @@ namespace mongo {
void appendWhere( const char *code, const BSONObj &scope ){
appendCodeWScope( "$where" , code , scope );
}
+ void appendWhere( const string &code, const BSONObj &scope ){
+ appendWhere( code.c_str(), scope );
+ }
/** Append an array of values. */
template < class T >
diff --git a/dbtests/jsobjtests.cpp b/dbtests/jsobjtests.cpp
index 45ca4938143..fad6a181e69 100644
--- a/dbtests/jsobjtests.cpp
+++ b/dbtests/jsobjtests.cpp
@@ -25,6 +25,13 @@
#include "dbtests.h"
namespace JsobjTests {
+ class BSONElementBasic {
+ public:
+ void run() {
+ ASSERT_EQUALS( 1, BSONElement().size() );
+ }
+ };
+
namespace BSONObjTests {
class Create {
public:
@@ -567,6 +574,7 @@ namespace JsobjTests {
class All : public UnitTest::Suite {
public:
All() {
+ add< BSONElementBasic >();
add< BSONObjTests::Create >();
add< BSONObjTests::WoCompareBasic >();
add< BSONObjTests::NumericCompareBasic >();
diff --git a/dbtests/mockdbclient.h b/dbtests/mockdbclient.h
index 23ae226b4d2..be6c420e5f0 100644
--- a/dbtests/mockdbclient.h
+++ b/dbtests/mockdbclient.h
@@ -25,11 +25,11 @@ class MockDBClientConnection : public DBClientConnection {
public:
MockDBClientConnection() : connect_() {}
virtual
- BSONObj findOne(const char *ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0) {
+ BSONObj findOne(const string &ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0) {
return one_;
}
virtual
- bool connect(const char *serverHostname, string& errmsg) {
+ bool connect(const string &serverHostname, string& errmsg) {
return connect_;
}
virtual
@@ -62,7 +62,7 @@ public:
rp_( rp ),
cc_( cc ) {
}
- virtual BSONObj findOne(const char *ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0) {
+ virtual BSONObj findOne(const string &ns, Query query, BSONObj *fieldsToReturn = 0, int queryOptions = 0) {
if ( cc_ ) cc_->beforeCommand();
SetGlobalReplPair s( rp_ );
BSONObjBuilder result;
@@ -70,7 +70,7 @@ public:
if ( cc_ ) cc_->afterCommand();
return result.obj();
}
- virtual bool connect( const char *serverHostname, string& errmsg ) {
+ virtual bool connect( const string &serverHostname, string& errmsg ) {
return true;
}
private:
diff --git a/jstests/repl/repl6.js b/jstests/repl/repl6.js
new file mode 100644
index 00000000000..7d3f265f328
--- /dev/null
+++ b/jstests/repl/repl6.js
@@ -0,0 +1,76 @@
+// Test one master replicating to two slaves
+
+var baseName = "jstests_repl6test";
+
+soonCount = function( m, count ) {
+ assert.soon( function() {
+ // print( "check count" );
+ if ( -1 == m.getDBNames().indexOf( baseName ) )
+ return false;
+ if ( -1 == m.getDB( baseName ).getCollectionNames().indexOf( "a" ) )
+ return false;
+ // print( "count: " + s.getDB( baseName ).z.find().count() );
+ return m.getDB( baseName ).a.find().count() == count;
+ } );
+}
+
+doTest = function( signal ) {
+
+ // spec small oplog for fast startup on 64bit machines
+ m = startMongod( "--port", "27018", "--dbpath", "/data/db/" + baseName + "-master", "--master", "--oplogSize", "1" );
+ s1 = startMongod( "--port", "27019", "--dbpath", "/data/db/" + baseName + "-slave1", "--slave", "--source", "127.0.0.1:27018" );
+ s2 = startMongod( "--port", "27020", "--dbpath", "/data/db/" + baseName + "-slave2", "--slave", "--source", "127.0.0.1:27018" );
+
+ am = m.getDB( baseName ).a
+
+ for( i = 0; i < 1000; ++i )
+ am.save( { _id: new ObjectId(), i: i } );
+
+ soonCount( s1, 1000 );
+ soonCount( s2, 1000 );
+
+ check = function( as ) {
+ assert.eq( 1, as.find( { i: 0 } ).count() );
+ assert.eq( 1, as.find( { i: 999 } ).count() );
+ }
+
+ as = s1.getDB( baseName ).a
+ check( as );
+ as = s2.getDB( baseName ).a
+ check( as );
+
+ stopMongod( 27019, signal );
+ stopMongod( 27020, signal );
+
+ for( i = 1000; i < 1010; ++i )
+ am.save( { _id: new ObjectId(), i: i } );
+
+ s1 = startMongoProgram( "mongod", "--port", "27019", "--dbpath", "/data/db/" + baseName + "-slave1", "--slave", "--source", "127.0.0.1:27018" );
+ soonCount( s1, 1010 );
+ as = s1.getDB( baseName ).a
+ assert.eq( 1, as.find( { i: 1009 } ).count() );
+
+ stopMongod( 27018, signal );
+
+ m = startMongoProgram( "mongod", "--port", "27018", "--dbpath", "/data/db/" + baseName + "-master", "--master", "--oplogSize", "1" );
+ am = m.getDB( baseName ).a
+
+ for( i = 1010; i < 1020; ++i )
+ am.save( { _id: new ObjectId(), i: i } );
+
+ soonCount( s1, 1020 );
+ assert.eq( 1, as.find( { i: 1019 } ).count() );
+
+ s2 = startMongoProgram( "mongod", "--port", "27020", "--dbpath", "/data/db/" + baseName + "-slave2", "--slave", "--source", "127.0.0.1:27018" );
+ soonCount( s2, 1020 );
+ as = s2.getDB( baseName ).a
+ assert.eq( 1, as.find( { i: 1009 } ).count() );
+ assert.eq( 1, as.find( { i: 1019 } ).count() );
+
+ stopMongod( 27018 );
+ stopMongod( 27019 );
+ stopMongod( 27020 );
+}
+
+doTest( 15 ); // SIGTERM
+doTest( 9 ); // SIGKILL
diff --git a/mongo.xcodeproj/project.pbxproj b/mongo.xcodeproj/project.pbxproj
index e5deaeb86e8..37c7cd616b9 100644
--- a/mongo.xcodeproj/project.pbxproj
+++ b/mongo.xcodeproj/project.pbxproj
@@ -243,6 +243,7 @@
93D6BC9B0F266FC300FE5722 /* querytests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = querytests.cpp; sourceTree = "<group>"; };
93D941BF0F77D64F00C3C768 /* replacePeer1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = replacePeer1.js; sourceTree = "<group>"; };
93D941C00F77D64F00C3C768 /* replacePeer2.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = replacePeer2.js; sourceTree = "<group>"; };
+ 93D9469F0F7ABB0600C3C768 /* repl6.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = repl6.js; sourceTree = "<group>"; };
93E3C5310F704C9D0029011E /* repl4.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = repl4.js; sourceTree = "<group>"; };
93E3C5960F7149F40029011E /* repl5.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = repl5.js; sourceTree = "<group>"; };
93E727090F4B5B5B004F9B5D /* shardkey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shardkey.cpp; sourceTree = "<group>"; };
@@ -608,6 +609,7 @@
93A8D2040F37544800C92B85 /* repl */ = {
isa = PBXGroup;
children = (
+ 93D9469F0F7ABB0600C3C768 /* repl6.js */,
93D941BF0F77D64F00C3C768 /* replacePeer1.js */,
93D941C00F77D64F00C3C768 /* replacePeer2.js */,
93E3C5960F7149F40029011E /* repl5.js */,
diff --git a/shell/dbshell.cpp b/shell/dbshell.cpp
index edaa3d9625a..35860c370a8 100644
--- a/shell/dbshell.cpp
+++ b/shell/dbshell.cpp
@@ -46,18 +46,42 @@ char * shellReadline( const char * prompt ){
#endif
}
+#if !defined(_WIN32)
+#include <execinfo.h>
+#include <string.h>
+
void quitNicely( int sig ){
shellHistoryDone();
exit(0);
}
+/* use "addr2line -CFe <exe>" to parse. */
+inline void printStackTrace() {
+ void *b[20];
+ size_t size;
+ char **strings;
+ size_t i;
+
+ size = backtrace(b, 20);
+ strings = backtrace_symbols(b, size);
+
+ for (i = 0; i < size; i++)
+ cout << hex << b[i] << ' ';
+ cout << '\n';
+ for (i = 0; i < size; i++)
+ cout << ' ' << strings[i] << '\n';
+ cout << dec;
+ free (strings);
+}
+
void quitAbruptly( int sig ) {
+ cout << "mongo got signal" << sig << " (" << strsignal( sig ) << "), stack trace: " << endl;
+ printStackTrace();
KillMongoProgramInstances();
exit(14);
}
void setupSignals() {
-#ifndef _WIN32
signal( SIGINT , quitNicely );
signal( SIGTERM , quitNicely );
signal( SIGPIPE , quitNicely ); // Maybe just log and continue?
@@ -65,8 +89,10 @@ void setupSignals() {
signal( SIGSEGV , quitAbruptly );
signal( SIGBUS , quitAbruptly );
signal( SIGFPE , quitAbruptly );
-#endif
}
+#else
+inline void setupSignals() {}
+#endif
string fixHost( string url , string host , string port ){
if ( host.size() == 0 && port.size() == 0 ){
diff --git a/util/builder.h b/util/builder.h
index a637d5743b8..85e1c3639e5 100644
--- a/util/builder.h
+++ b/util/builder.h
@@ -83,6 +83,10 @@ namespace mongo {
void append(const char *str) {
append((void*) str, strlen(str)+1);
}
+
+ void append(const string &str) {
+ append( (void *)str.c_str(), str.length() + 1 );
+ }
int len() {
return l;