0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

Merge branch 'master' of git@github.com:mongodb/mongo

This commit is contained in:
Aaron 2009-03-24 18:15:58 -04:00
commit b850675fa9
6 changed files with 129 additions and 93 deletions

View File

@ -28,7 +28,7 @@
namespace mongo { 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. */ /* use where() before sort() and hint() and explain(), else this will assert. */
assert( !obj.hasField("query") ); assert( !obj.hasField("query") );
BSONObjBuilder b; BSONObjBuilder b;
@ -104,16 +104,16 @@ namespace mongo {
return o.getIntField("ok") == 1; return o.getIntField("ok") == 1;
} }
inline bool DBClientWithCommands::runCommand(const char *dbname, const BSONObj& cmd, BSONObj &info) { inline bool DBClientWithCommands::runCommand(const string &dbname, const BSONObj& cmd, BSONObj &info) {
string ns = string(dbname) + ".$cmd"; string ns = dbname + ".$cmd";
info = findOne(ns.c_str(), cmd); info = findOne(ns, 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. 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; BSONObj o;
if ( info == 0 ) if ( info == 0 )
info = &o; info = &o;
@ -122,7 +122,7 @@ namespace mongo {
return runCommand(dbname, b.done(), *info); 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); NamespaceString ns(_ns);
BSONObj cmd = BSON( "count" << ns.coll << "query" << query ); BSONObj cmd = BSON( "count" << ns.coll << "query" << query );
BSONObj res; BSONObj res;
@ -152,20 +152,20 @@ namespace mongo {
BSONObj getnoncecmdobj = fromjson("{getnonce:1}"); 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; md5digest d;
{ {
md5_state_t st; md5_state_t st;
md5_init(&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 *) ":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); md5_finish(&st, d);
} }
return digestToString( 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; //cout << "TEMP AUTH " << toString() << dbname << ' ' << username << ' ' << password_text << ' ' << digestPassword << endl;
string password = password_text; string password = password_text;
@ -194,7 +194,7 @@ namespace mongo {
md5_state_t st; md5_state_t st;
md5_init(&st); md5_init(&st);
md5_append(&st, (const md5_byte_t *) nonce.c_str(), nonce.size() ); 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_append(&st, (const md5_byte_t *) password.c_str(), password.size() );
md5_finish(&st, d); md5_finish(&st, d);
} }
@ -219,7 +219,7 @@ namespace mongo {
return ok; 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; BSONObj o;
if ( info == 0 ) info = &o; if ( info == 0 ) info = &o;
BSONObjBuilder b; BSONObjBuilder b;
@ -227,12 +227,11 @@ namespace mongo {
if ( size ) b.append("size", size); if ( size ) b.append("size", size);
if ( capped ) b.append("capped", true); if ( capped ) b.append("capped", true);
if ( max ) b.append("max", max); if ( max ) b.append("max", max);
string db = nsToClient(ns); string db = nsToClient(ns.c_str());
return runCommand(db.c_str(), b.done(), *info); return runCommand(db.c_str(), b.done(), *info);
} }
bool DBClientWithCommands::copyDatabase(const char *fromdb, const char *todb, const char *fromhost, BSONObj *info) { bool DBClientWithCommands::copyDatabase(const string &fromdb, const string &todb, const string &fromhost, BSONObj *info) {
assert( *fromdb && *todb );
BSONObj o; BSONObj o;
if ( info == 0 ) info = &o; if ( info == 0 ) info = &o;
BSONObjBuilder b; BSONObjBuilder b;
@ -243,7 +242,7 @@ namespace mongo {
return runCommand("admin", b.done(), *info); 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; BSONObj o;
if ( info == 0 ) info = &o; if ( info == 0 ) info = &o;
@ -251,7 +250,7 @@ namespace mongo {
// Create system.profile collection. If it already exists this does nothing. // Create system.profile collection. If it already exists this does nothing.
// TODO: move this into the db instead of here so that all // TODO: move this into the db instead of here so that all
// drivers don't have to do this. // 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); createCollection(ns.c_str(), 1024 * 1024, true, 0, info);
} }
@ -262,7 +261,7 @@ namespace mongo {
BSONObj getprofilingcmdobj = fromjson("{\"profile\":-1}"); 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; BSONObj o;
if ( info == 0 ) info = &o; if ( info == 0 ) info = &o;
if ( runCommand(dbname, getprofilingcmdobj, *info) ) { if ( runCommand(dbname, getprofilingcmdobj, *info) ) {
@ -272,9 +271,9 @@ namespace mongo {
return false; 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; BSONObjBuilder b;
b.appendCode("$eval", jscode); b.appendCode("$eval", jscode.c_str());
if ( args ) if ( args )
b.appendArray("args", *args); b.appendArray("args", *args);
bool ok = runCommand(dbname, b.done(), info); bool ok = runCommand(dbname, b.done(), info);
@ -283,7 +282,7 @@ namespace mongo {
return ok; return ok;
} }
bool DBClientWithCommands::eval(const char *dbname, const char *jscode) { bool DBClientWithCommands::eval(const string &dbname, const string &jscode) {
BSONObj info; BSONObj info;
BSONElement retValue; BSONElement retValue;
return eval(dbname, jscode, info, retValue); return eval(dbname, jscode, info, retValue);
@ -349,7 +348,7 @@ namespace mongo {
/* --- dbclientconnection --- */ /* --- 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; string password = password_text;
if( digestPassword ) if( digestPassword )
password = createPasswordDigest( username , password_text ); password = createPasswordDigest( username , password_text );
@ -365,7 +364,7 @@ namespace mongo {
return DBClientBase::auth(dbname, username, password.c_str(), errmsg, false); 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 = auto_ptr<DBClientCursor> c =
this->query(ns, query, 1, 0, fieldsToReturn, queryOptions); this->query(ns, query, 1, 0, fieldsToReturn, queryOptions);
@ -377,7 +376,7 @@ namespace mongo {
return c->next().copy(); return c->next().copy();
} }
bool DBClientConnection::connect(const char *_serverAddress, string& errmsg) { bool DBClientConnection::connect(const string &_serverAddress, string& errmsg) {
serverAddress = _serverAddress; serverAddress = _serverAddress;
string ip; 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) { int nToSkip, BSONObj *fieldsToReturn, int queryOptions) {
auto_ptr<DBClientCursor> c( new DBClientCursor( this, auto_ptr<DBClientCursor> c( new DBClientCursor( this,
ns, query.obj, nToReturn, nToSkip, ns, query.obj, nToReturn, nToSkip,
@ -446,14 +445,14 @@ namespace mongo {
return auto_ptr< DBClientCursor >( 0 ); 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 ) ); auto_ptr<DBClientCursor> c( new DBClientCursor( this, ns, cursorId, nToReturn, options ) );
if ( c->init() ) if ( c->init() )
return c; return c;
return auto_ptr< DBClientCursor >( 0 ); return auto_ptr< DBClientCursor >( 0 );
} }
void DBClientBase::insert( const char * ns , BSONObj obj ) { void DBClientBase::insert( const string & ns , BSONObj obj ) {
Message toSend; Message toSend;
BufBuilder b; BufBuilder b;
@ -467,7 +466,7 @@ namespace mongo {
say( toSend ); say( toSend );
} }
void DBClientBase::insert( const char * ns , const vector< BSONObj > &v ) { void DBClientBase::insert( const string & ns , const vector< BSONObj > &v ) {
Message toSend; Message toSend;
BufBuilder b; BufBuilder b;
@ -482,7 +481,7 @@ namespace mongo {
say( toSend ); say( toSend );
} }
void DBClientBase::remove( const char * ns , Query obj , bool justOne ) { void DBClientBase::remove( const string & ns , Query obj , bool justOne ) {
Message toSend; Message toSend;
BufBuilder b; BufBuilder b;
@ -502,7 +501,7 @@ namespace mongo {
say( toSend ); 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; BufBuilder b;
b.append( (int)0 ); // reserverd b.append( (int)0 ); // reserverd
@ -519,7 +518,7 @@ namespace mongo {
say( toSend ); 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; BSONObjBuilder toSave;
toSave.append( "ns" , ns ); toSave.append( "ns" , ns );
toSave.append( "key" , keys ); toSave.append( "key" , keys );
@ -527,7 +526,7 @@ namespace mongo {
string cacheKey(ns); string cacheKey(ns);
cacheKey += "--"; cacheKey += "--";
if ( name ) { if ( name != "" ) {
toSave.append( "name" , name ); toSave.append( "name" , name );
cacheKey += name; cacheKey += name;
} }
@ -840,7 +839,7 @@ again:
return master == Left ? left : right; 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; string errmsg;
bool l = left.connect(serverHostname1, errmsg); bool l = left.connect(serverHostname1, errmsg);
bool r = right.connect(serverHostname2, errmsg); bool r = right.connect(serverHostname2, errmsg);
@ -856,7 +855,7 @@ again:
return true; 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(); DBClientConnection& m = checkMaster();
if( !m.auth(dbname, username, pwd, errmsg) ) if( !m.auth(dbname, username, pwd, errmsg) )
return false; return false;
@ -873,13 +872,13 @@ again:
return true; 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) BSONObj *e, int f)
{ {
return checkMaster().query(a,b,c,d,e,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); return checkMaster().findOne(a,b,c,d);
} }

View File

@ -60,8 +60,8 @@ namespace mongo {
Query(const BSONObj& b) : obj(b) { } Query(const BSONObj& b) : obj(b) { }
Query(const string &json) : Query(const string &json) :
obj(fromjson(json)) { } obj(fromjson(json)) { }
Query(const char *json) : Query(const char * json) :
obj(fromjson(json)) { } obj(fromjson(json)) { }
/** Add a sort (ORDER BY) criteria to the query expression. /** 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: @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 @param asc = 1 for ascending order
asc = -1 for descending 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. /** Provide a hint to the query.
@param keyPattern Key pattern for the index to use. @param keyPattern Key pattern for the index to use.
@ -86,7 +86,7 @@ namespace mongo {
hint("{ts:1}") hint("{ts:1}")
*/ */
Query& hint(BSONObj keyPattern); 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. /** 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(). 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")); conn.findOne("test.coll", Query("{a:3}").where("this.b == 2 || this.c == 3"));
Query badBalance = Query().where("this.debits - this.credits < 0"); Query badBalance = Query().where("this.debits - this.credits < 0");
*/ */
Query& where(const char *jscode, BSONObj scope); Query& where(const string &jscode, BSONObj scope);
Query& where(const char *jscode) { return where(jscode, BSONObj()); } 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 bool call( Message &toSend, Message &response, bool assertOk=true ) = 0;
virtual void say( Message &toSend ) = 0; virtual void say( Message &toSend ) = 0;
virtual void sayPiggyBack( 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 */ /** Queries return a cursor object */
@ -181,7 +181,7 @@ namespace mongo {
bool init(); 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 ) : int _nToSkip, BSONObj *_fieldsToReturn, int queryOptions ) :
connector(_connector), connector(_connector),
ns(_ns), ns(_ns),
@ -198,7 +198,7 @@ namespace mongo {
ownCursor_( true ) { 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), connector(_connector),
ns(_ns), ns(_ns),
nToReturn( _nToReturn ), nToReturn( _nToReturn ),
@ -241,20 +241,20 @@ namespace mongo {
*/ */
class DBClientInterface : boost::noncopyable { class DBClientInterface : boost::noncopyable {
public: 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; 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() { } virtual ~DBClientInterface() { }
}; };
@ -265,7 +265,7 @@ namespace mongo {
*/ */
class DBClientWithCommands : public DBClientInterface { class DBClientWithCommands : public DBClientInterface {
bool isOk(const BSONObj&); 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: public:
/** Run a database command. Database commands are represented as BSON objects. Common database /** 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 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". @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. /** Authorize access to a particular database.
Authentication is separate for each database on the server -- you may authenticate for any 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 @param digestPassword if password is plain text, set this to true. otherwise assumed to be pre-digested
@return true if successful @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 /** count number of objects in collection ns that match the query criteria specified
throws UserAssertion if database returns an error 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 /** returns true in isMaster parm if this db is the current master
of a replica pair. of a replica pair.
@ -323,7 +323,7 @@ namespace mongo {
returns true if successful. 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. /** Get error result from the last operation on this connection.
@return error or empty string if no error. @return error or empty string if no error.
@ -345,7 +345,7 @@ namespace mongo {
bool resetError() { return simpleCommand("admin", 0, "reseterror"); } bool resetError() { return simpleCommand("admin", 0, "reseterror"); }
/** Erase / drop an entire database */ /** 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"); 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 /** 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. 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"); return simpleCommand(dbname, info, "repairDatabase");
} }
@ -387,7 +387,7 @@ namespace mongo {
returns true if successful 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() /** 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 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 ProfileSlow = 1, // log very slow (>100ms) operations
ProfileAll = 2 ProfileAll = 2
}; };
bool setDbProfilingLevel(const char *dbname, ProfilingLevel level, BSONObj *info = 0); bool setDbProfilingLevel(const string &dbname, ProfilingLevel level, BSONObj *info = 0);
bool getDbProfilingLevel(const char *dbname, ProfilingLevel& level, BSONObj *info = 0); bool getDbProfilingLevel(const string &dbname, ProfilingLevel& level, BSONObj *info = 0);
/** Run javascript code on the database server. /** Run javascript code on the database server.
dbname database context in which the code runs. The javascript variable 'db' will be assigned 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. 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 cmd = BSON( "validate" << nsGetCollection( ns ) << "scandata" << scandata );
BSONObj info; BSONObj info;
return runCommand( nsGetDB( ns ).c_str() , cmd , 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 */ /* 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 */ /* 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 > 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; BSONObj info;
BSONElement retValue; BSONElement retValue;
BSONObjBuilder b; BSONObjBuilder b;
@ -443,7 +443,7 @@ namespace mongo {
/** eval invocation with one parm to server and one numeric field (either int or double) returned */ /** eval invocation with one parm to server and one numeric field (either int or double) returned */
template< class T, class NumType > 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; BSONObj info;
BSONElement retValue; BSONElement retValue;
BSONObjBuilder b; BSONObjBuilder b;
@ -497,41 +497,41 @@ namespace mongo {
@return cursor. 0 if error (connection failure) @return cursor. 0 if error (connection failure)
@throws AssertionException @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); BSONObj *fieldsToReturn = 0, int queryOptions = 0);
/** @param cursorId id of cursor to retrieve /** @param cursorId id of cursor to retrieve
@return an handle to a previously allocated cursor @return an handle to a previously allocated cursor
@throws AssertionException @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 @return a single object that matches the query. if none do, then the object is empty
@throws AssertionException @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 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 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 remove matching objects from the database
@param justOne if this true, then once a single match is found will stop @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 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. /** Create an index if it does not already exist.
ensureIndex calls are remembered so it is safe/fast to call this function many ensureIndex calls are remembered so it is safe/fast to call this function many
@ -541,7 +541,7 @@ namespace mongo {
@return whether or not sent message to db. @return whether or not sent message to db.
should be true on first call, false on subsequent unless resetIndexCache was called 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 clears the index cache, so the subsequent call to ensureIndex for any index will go to the server
@ -592,7 +592,7 @@ namespace mongo {
@param errmsg any relevant error message will appended to the string @param errmsg any relevant error message will appended to the string
@return false if fails to connect. @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. /** Connect to a Mongo database server. Exception throwing version.
Throws a UserException if cannot connect. Throws a UserException if cannot connect.
@ -608,9 +608,9 @@ namespace mongo {
throw ConnectException(string("can't connect ") + errmsg); 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) { BSONObj *fieldsToReturn = 0, int queryOptions = 0) {
checkConnection(); checkConnection();
return DBClientBase::query( ns, query, nToReturn, nToSkip, fieldsToReturn, queryOptions ); return DBClientBase::query( ns, query, nToReturn, nToSkip, fieldsToReturn, queryOptions );
@ -673,7 +673,7 @@ namespace mongo {
when false returned, you can still try to use this connection object, it will when false returned, you can still try to use this connection object, it will
try reconnects. 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 /** Connect to a server pair using a host pair string of the form
hostname[:port],hostname[:port] hostname[:port],hostname[:port]
@ -686,35 +686,35 @@ namespace mongo {
/** Authorize. Authorizes both sides of the pair as needed. /** 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" */ /** throws userassertion "no master found" */
virtual 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); BSONObj *fieldsToReturn = 0, int queryOptions = 0);
/** throws userassertion "no master found" */ /** throws userassertion "no master found" */
virtual 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 */ /** insert */
virtual void insert( const char * ns , BSONObj obj ) { virtual void insert( const string &ns , BSONObj obj ) {
checkMaster().insert(ns, obj); checkMaster().insert(ns, obj);
} }
/** insert multiple objects. Note that single object insert is asynchronous, so this version /** 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. */ 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); checkMaster().insert(ns, v);
} }
/** remove */ /** 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); checkMaster().remove(ns, obj, justOne);
} }
/** update */ /** 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); return checkMaster().update(ns, query, obj, upsert);
} }

View File

@ -858,6 +858,10 @@ namespace mongo {
b.append(fieldName); b.append(fieldName);
b.append(n); 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); } void append(const char *fieldName, unsigned n) { append(fieldName, (int) n); }
/** Append a double element */ /** Append a double element */
BSONObjBuilder& append(const char *fieldName, double n) { BSONObjBuilder& append(const char *fieldName, double n) {
@ -1014,6 +1018,9 @@ namespace mongo {
void appendWhere( const char *code, const BSONObj &scope ){ void appendWhere( const char *code, const BSONObj &scope ){
appendCodeWScope( "$where" , code , scope ); appendCodeWScope( "$where" , code , scope );
} }
void appendWhere( const string &code, const BSONObj &scope ){
appendWhere( code.c_str(), scope );
}
/** Append an array of values. */ /** Append an array of values. */
template < class T > template < class T >

View File

@ -25,11 +25,11 @@ class MockDBClientConnection : public DBClientConnection {
public: public:
MockDBClientConnection() : connect_() {} MockDBClientConnection() : connect_() {}
virtual 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_; return one_;
} }
virtual virtual
bool connect(const char *serverHostname, string& errmsg) { bool connect(const string &serverHostname, string& errmsg) {
return connect_; return connect_;
} }
virtual virtual
@ -62,7 +62,7 @@ public:
rp_( rp ), rp_( rp ),
cc_( cc ) { 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(); if ( cc_ ) cc_->beforeCommand();
SetGlobalReplPair s( rp_ ); SetGlobalReplPair s( rp_ );
BSONObjBuilder result; BSONObjBuilder result;
@ -70,7 +70,7 @@ public:
if ( cc_ ) cc_->afterCommand(); if ( cc_ ) cc_->afterCommand();
return result.obj(); return result.obj();
} }
virtual bool connect( const char *serverHostname, string& errmsg ) { virtual bool connect( const string &serverHostname, string& errmsg ) {
return true; return true;
} }
private: private:

View File

@ -46,18 +46,42 @@ char * shellReadline( const char * prompt ){
#endif #endif
} }
#if !defined(_WIN32)
#include <execinfo.h>
#include <string.h>
void quitNicely( int sig ){ void quitNicely( int sig ){
shellHistoryDone(); shellHistoryDone();
exit(0); 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 ) { void quitAbruptly( int sig ) {
cout << "mongo got signal" << sig << " (" << strsignal( sig ) << "), stack trace: " << endl;
printStackTrace();
KillMongoProgramInstances(); KillMongoProgramInstances();
exit(14); exit(14);
} }
void setupSignals() { void setupSignals() {
#ifndef _WIN32
signal( SIGINT , quitNicely ); signal( SIGINT , quitNicely );
signal( SIGTERM , quitNicely ); signal( SIGTERM , quitNicely );
signal( SIGPIPE , quitNicely ); // Maybe just log and continue? signal( SIGPIPE , quitNicely ); // Maybe just log and continue?
@ -65,8 +89,10 @@ void setupSignals() {
signal( SIGSEGV , quitAbruptly ); signal( SIGSEGV , quitAbruptly );
signal( SIGBUS , quitAbruptly ); signal( SIGBUS , quitAbruptly );
signal( SIGFPE , quitAbruptly ); signal( SIGFPE , quitAbruptly );
#endif
} }
#else
inline void setupSignals() {}
#endif
string fixHost( string url , string host , string port ){ string fixHost( string url , string host , string port ){
if ( host.size() == 0 && port.size() == 0 ){ if ( host.size() == 0 && port.size() == 0 ){

View File

@ -83,6 +83,10 @@ namespace mongo {
void append(const char *str) { void append(const char *str) {
append((void*) str, strlen(str)+1); append((void*) str, strlen(str)+1);
} }
void append(const string &str) {
append( (void *)str.c_str(), str.length() + 1 );
}
int len() { int len() {
return l; return l;