From 16f8b77c5efd9334e7ddf3bfa7c667e6218fa366 Mon Sep 17 00:00:00 2001 From: Dwight Date: Wed, 14 Oct 2009 14:34:38 -0400 Subject: [PATCH] move the var 'database' inside Client object --- db/btree.cpp | 3 +++ db/client.h | 11 ++++++++--- db/cloner.cpp | 10 +++++----- db/database.h | 2 -- db/db.cpp | 4 ++-- db/db.h | 17 ++++++++--------- db/dbcommands.cpp | 24 ++++++++++++------------ db/dbeval.cpp | 2 +- db/dbhelpers.cpp | 2 +- db/dbhelpers.h | 22 ++++++++++++++++------ db/dbinfo.h | 14 +++++++++----- db/dbwebserver.cpp | 4 ++-- db/instance.cpp | 17 +++++++++++------ db/instance.h | 4 ++-- db/introspect.cpp | 2 +- db/matcher.cpp | 2 +- db/pdfile.cpp | 38 ++++++++++++++++++++------------------ db/pdfile.h | 8 +++++--- db/query.cpp | 5 +++-- db/reccache.cpp | 2 +- db/repl.cpp | 25 ++++++++++++------------- db/replset.h | 1 + db/security.cpp | 2 +- db/security_commands.cpp | 15 +++++++++------ dbtests/cursortests.cpp | 2 +- dbtests/querytests.cpp | 4 ++-- 26 files changed, 137 insertions(+), 105 deletions(-) diff --git a/db/btree.cpp b/db/btree.cpp index 79b8e0051d6..66fda24fbe0 100644 --- a/db/btree.cpp +++ b/db/btree.cpp @@ -17,11 +17,14 @@ */ #include "stdafx.h" +#include "db.h" #include "btree.h" #include "pdfile.h" #include "../util/unittest.h" #include "json.h" #include "clientcursor.h" +#include "client.h" +#include "dbhelpers.h" namespace mongo { diff --git a/db/client.h b/db/client.h index 37c2375bb67..678333eff6e 100644 --- a/db/client.h +++ b/db/client.h @@ -29,20 +29,25 @@ namespace mongo { class AuthenticationInfo; + class Database; class Client { + Database* _database; Namespace _ns; - NamespaceString _nsstr; + //NamespaceString _nsstr; list _tempCollections; public: AuthenticationInfo *ai; + Database* database() { return _database; } const char *ns() { return _ns.buf; } - void setns(const char *ns) { + void setns(const char *ns, Database *db) { + _database = db; _ns = ns; - _nsstr = ns; + //_nsstr = ns; } + void clearns() { setns("", 0); } Client(); ~Client(); diff --git a/db/cloner.cpp b/db/cloner.cpp index 7d61f5c219b..4a662e4e5c2 100644 --- a/db/cloner.cpp +++ b/db/cloner.cpp @@ -67,7 +67,7 @@ namespace mongo { uassert("bad ns field for index during dbcopy", e.type() == String); const char *p = strchr(e.valuestr(), '.'); uassert("bad ns field for index during dbcopy [2]", p); - string newname = database->name + p; + string newname = cc().database()->name + p; b.append("ns", newname); } else @@ -139,13 +139,13 @@ namespace mongo { massert( "useReplAuth is not written to replication log", !useReplAuth || !logForRepl ); - string todb = database->name; + string todb = cc().database()->name; stringstream a,b; a << "localhost:" << cmdLine.port; b << "127.0.0.1:" << cmdLine.port; bool masterSameProcess = ( a.str() == masterHost || b.str() == masterHost ); if ( masterSameProcess ) { - if ( fromdb == todb && database->path == dbpath ) { + if ( fromdb == todb && cc().database()->path == dbpath ) { // guard against an "infinite" loop /* if you are replicating, the local.sources config may be wrong if you get this */ errmsg = "can't clone from self (localhost)."; @@ -384,7 +384,7 @@ namespace mongo { /* replication note: we must logOp() not the command, but the cloned data -- if the slave were to clone it would get a different point-in-time and not match. */ - return cloneFrom(from.c_str(), errmsg, database->name, + return cloneFrom(from.c_str(), errmsg, cc().database()->name, /*logForReplication=*/!fromRepl, /*slaveok*/false, /*usereplauth*/false, /*snapshot*/true); } } cmdclone; @@ -561,7 +561,7 @@ namespace mongo { } setClient(todb.c_str()); bool res = cloneFrom(fromhost.c_str(), errmsg, fromdb, /*logForReplication=*/!fromRepl, /*slaveok*/false, /*replauth*/false, /*snapshot*/true); - database = 0; + cc().clearns(); return res; } } cmdcopydb; diff --git a/db/database.h b/db/database.h index 972220a544a..8226594b0dd 100644 --- a/db/database.h +++ b/db/database.h @@ -147,6 +147,4 @@ namespace mongo { }; - extern Database *database; - } // namespace mongo diff --git a/db/db.cpp b/db/db.cpp index c4f59b6d18e..97c1087ce53 100644 --- a/db/db.cpp +++ b/db/db.cpp @@ -108,7 +108,7 @@ namespace mongo { } out() << endl; - database = 0; + cc().clearns(); } MessagingPort *grab = 0; @@ -326,7 +326,7 @@ namespace mongo { for ( vector< string >::iterator i = dbNames.begin(); i != dbNames.end(); ++i ) { string dbName = *i; assert( !setClient( dbName.c_str() ) ); - MongoDataFile *p = database->getFile( 0 ); + MongoDataFile *p = cc().database()->getFile( 0 ); MDFHeader *h = p->getHeader(); if ( !h->currentVersion() || forceRepair ) { log() << "****" << endl; diff --git a/db/db.h b/db/db.h index 28284a25b51..04d63078819 100644 --- a/db/db.h +++ b/db/db.h @@ -43,7 +43,6 @@ namespace mongo { // tempish...move to TLS or pass all the way down as a parm extern map databases; - extern Database *database; extern bool master; /* sometimes we deal with databases with the same name in different directories - thus this */ @@ -68,11 +67,10 @@ namespace mongo { Top::clientStart( ns ); - cc().setns(ns); string key = makeDbKeyStr( ns, path ); map::iterator it = databases.find(key); if ( it != databases.end() ) { - database = it->second; + cc().setns(ns, it->second); return false; } @@ -88,10 +86,10 @@ namespace mongo { char cl[256]; nsToClient(ns, cl); bool justCreated; - Database *c = new Database(cl, justCreated, path); - databases[key] = c; - database = c; - database->finishInit(); + Database *newdb = new Database(cl, justCreated, path); + databases[key] = newdb; + newdb->finishInit(); + cc().setns(ns, newdb); return justCreated; } @@ -107,13 +105,14 @@ namespace mongo { } inline bool clientIsEmpty() { - return !database->namespaceIndex.allocated(); + return !cc().database()->namespaceIndex.allocated(); } struct dbtemprelease { string clientname; string clientpath; dbtemprelease() { + Database *database = cc().database(); if ( database ) { clientname = database->name; clientpath = database->path; @@ -134,7 +133,7 @@ namespace mongo { #endif dbMutexInfo.entered(); if ( clientname.empty() ) - database = 0; + cc().setns("", 0); else setClient(clientname.c_str(), clientpath.c_str()); } diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp index 5f87f6d9def..2bf00c586bc 100644 --- a/db/dbcommands.cpp +++ b/db/dbcommands.cpp @@ -416,23 +416,23 @@ namespace mongo { CmdProfile() : Command("profile") {} bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { BSONElement e = cmdObj.findElement(name); - result.append("was", (double) database->profile); + result.append("was", (double) cc().database()->profile); int p = (int) e.number(); bool ok = false; if ( p == -1 ) ok = true; else if ( p >= 0 && p <= 2 ) { - if( p && nsdetails(database->profileName.c_str()) == 0 ) { + if( p && nsdetails(cc().database()->profileName.c_str()) == 0 ) { BSONObjBuilder spec; spec.appendBool( "capped", true ); spec.append( "size", 131072.0 ); - if ( !userCreateNS( database->profileName.c_str(), spec.done(), errmsg, true ) ) { + if ( !userCreateNS( cc().database()->profileName.c_str(), spec.done(), errmsg, true ) ) { return false; } } ok = true; - database->profile = p; + cc().database()->profile = p; } return ok; } @@ -640,7 +640,7 @@ namespace mongo { return false; } virtual bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool) { - string nsToDrop = database->name + '.' + cmdObj.findElement(name).valuestr(); + string nsToDrop = cc().database()->name + '.' + cmdObj.findElement(name).valuestr(); NamespaceDetails *d = nsdetails(nsToDrop.c_str()); if ( !cmdLine.quiet ) log() << "CMD: drop " << nsToDrop << endl; @@ -702,7 +702,7 @@ namespace mongo { return false; } virtual bool run(const char *_ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool) { - string ns = database->name + '.' + cmdObj.findElement(name).valuestr(); + string ns = cc().database()->name + '.' + cmdObj.findElement(name).valuestr(); string err; long long n = runCount(ns.c_str(), cmdObj, err); long long nn = n; @@ -739,7 +739,7 @@ namespace mongo { help << "create a collection"; } virtual bool run(const char *_ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool) { - string ns = database->name + '.' + cmdObj.findElement(name).valuestr(); + string ns = cc().database()->name + '.' + cmdObj.findElement(name).valuestr(); string err; bool ok = userCreateNS(ns.c_str(), cmdObj, err, true); if ( !ok && !err.empty() ) @@ -763,7 +763,7 @@ namespace mongo { bool run(const char *ns, BSONObj& jsobj, string& errmsg, BSONObjBuilder& anObjBuilder, bool /*fromRepl*/) { /* note: temp implementation. space not reclaimed! */ BSONElement e = jsobj.findElement(name.c_str()); - string toDeleteNs = database->name + '.' + e.valuestr(); + string toDeleteNs = cc().database()->name + '.' + e.valuestr(); NamespaceDetails *d = nsdetails(toDeleteNs.c_str()); if ( !cmdLine.quiet ) log() << "CMD: deleteIndexes " << toDeleteNs << endl; @@ -800,7 +800,7 @@ namespace mongo { static DBDirectClient db; BSONElement e = jsobj.findElement(name.c_str()); - string toDeleteNs = database->name + '.' + e.valuestr(); + string toDeleteNs = cc().database()->name + '.' + e.valuestr(); NamespaceDetails *d = nsdetails(toDeleteNs.c_str()); log() << "CMD: reIndex " << toDeleteNs << endl; @@ -1410,7 +1410,7 @@ namespace mongo { bool run(const char *dbname, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl ){ static DBDirectClient db; - string ns = database->name + '.' + cmdObj.findElement(name).valuestr(); + string ns = cc().database()->name + '.' + cmdObj.findElement(name).valuestr(); string key = cmdObj["key"].valuestrsafe(); BSONObj keyPattern = BSON( key << 1 ); @@ -1489,7 +1489,7 @@ namespace mongo { string errmsg; Command *c = i->second; AuthenticationInfo *ai = currentClient.get()->ai; - uassert("unauthorized", ai->isAuthorized(database->name.c_str()) || !c->requiresAuth()); + uassert("unauthorized", ai->isAuthorized(cc().database()->name.c_str()) || !c->requiresAuth()); bool admin = c->adminOnly(); if ( admin && !fromRepl && strncmp(ns, "admin", 5) != 0 ) { @@ -1524,7 +1524,7 @@ namespace mongo { } else if ( e.type() == String ) { AuthenticationInfo *ai = currentClient.get()->ai; - uassert("unauthorized", ai->isAuthorized(database->name.c_str())); + uassert("unauthorized", ai->isAuthorized(cc().database()->name.c_str())); /* { count: "collectionname"[, query: ] } */ string us(ns, p-ns); diff --git a/db/dbeval.cpp b/db/dbeval.cpp index 9a931b7b7eb..d4832d55e10 100644 --- a/db/dbeval.cpp +++ b/db/dbeval.cpp @@ -68,7 +68,7 @@ namespace mongo { if ( e.type() == CodeWScope ) s->init( e.codeWScopeScopeData() ); - s->localConnect( database->name.c_str() ); + s->localConnect( cc().database()->name.c_str() ); BSONObj args; { diff --git a/db/dbhelpers.cpp b/db/dbhelpers.cpp index a43e0a98947..76a71dc8509 100644 --- a/db/dbhelpers.cpp +++ b/db/dbhelpers.cpp @@ -40,7 +40,7 @@ namespace mongo { return; } - string system_indexes = database->name + ".system.indexes"; + string system_indexes = cc().database()->name + ".system.indexes"; BSONObjBuilder b; b.append("name", name); diff --git a/db/dbhelpers.h b/db/dbhelpers.h index 8904c23667a..b41fa4069ff 100644 --- a/db/dbhelpers.h +++ b/db/dbhelpers.h @@ -22,8 +22,6 @@ #pragma once -#include "db.h" - namespace mongo { struct Helpers { @@ -69,22 +67,34 @@ namespace mongo { }; + class Database; + /* Set database we want to use, then, restores when we finish (are out of scope) Note this is also helpful if an exception happens as the state if fixed up. */ class DBContext { - Database *old; + Database *olddb; + string oldns; public: DBContext(const char *ns) { - old = database; + olddb = cc().database(); + oldns = cc().ns(); setClient(ns); } DBContext(string ns) { - old = database; + olddb = cc().database(); + oldns = cc().ns(); setClient(ns.c_str()); } + + /* this version saves the context but doesn't yet set the new one: */ + DBContext() { + olddb = cc().database(); + oldns = cc().ns(); } + + ~DBContext() { - database = old; + cc().setns(oldns.c_str(), olddb); } }; diff --git a/db/dbinfo.h b/db/dbinfo.h index 71dee48fca1..e65ae746c40 100644 --- a/db/dbinfo.h +++ b/db/dbinfo.h @@ -18,8 +18,12 @@ #pragma once +#include "dbhelpers.h" + namespace mongo { + class DBContext; + /* this is an "accessor" class to data held in local.dbinfo. system.dbinfo contains: @@ -27,15 +31,15 @@ namespace mongo { */ class DBInfo { string ns; - Database *dbold; + DBContext *context; public: ~DBInfo() { - database = dbold; + delete context; } - DBInfo(const char *db) { - dbold = database; + DBInfo(const char *db) + { ns = string("local.dbinfo.") + db; - setClient(ns.c_str()); + context = new DBContext(ns); } BSONObj getDbInfoObj() { diff --git a/db/dbwebserver.cpp b/db/dbwebserver.cpp index 835fb57154b..75838847110 100644 --- a/db/dbwebserver.cpp +++ b/db/dbwebserver.cpp @@ -112,8 +112,8 @@ namespace mongo { void doLockedStuff(stringstream& ss) { ss << "currentOp: " << currentOp.infoNoauth() << "\n"; ss << "# databases: " << databases.size() << '\n'; - if ( database ) { - ss << "curclient: " << database->name; + if ( cc().database() ) { + ss << "curclient: " << cc().database()->name; ss << '\n'; } ss << bold(ClientCursor::byLocSize()>10000) << "Cursors byLoc.size(): " << ClientCursor::byLocSize() << bold() << '\n'; diff --git a/db/instance.cpp b/db/instance.cpp index c4cfbedb9fa..d148362555c 100644 --- a/db/instance.cpp +++ b/db/instance.cpp @@ -152,7 +152,7 @@ namespace mongo { ss << buf; Timer t; - database = 0; + cc().clearns(); int logThreshold = 100; int ms; @@ -268,6 +268,7 @@ namespace mongo { ss << ' ' << t.millis() << "ms"; out() << ss.str().c_str() << endl; } + Database *database = cc().database(); if ( database && database->profile >= 1 ) { if ( database->profile >= 2 || ms >= 100 ) { // profile it @@ -296,6 +297,7 @@ namespace mongo { path - db directory */ void closeClient( const char *cl, const string& path ) { + Database *database = cc().database(); assert( database ); assert( database->name == cl ); if ( string("local") != cl ) { @@ -312,7 +314,7 @@ namespace mongo { eraseDatabase( cl, path ); delete database; // closes files - database = 0; + cc().clearns(); } void receivedUpdate(Message& m, stringstream& ss) { @@ -421,6 +423,7 @@ namespace mongo { resp->setData(msgdata, true); // transport will free dbresponse.response = resp; dbresponse.responseTo = responseTo; + Database *database = cc().database(); if ( database ) { if ( database->profile ) ss << " bytes:" << resp->data->dataLen(); @@ -446,7 +449,7 @@ namespace mongo { QueryResult* msgdata; try { AuthenticationInfo *ai = currentClient.get()->ai; - uassert("unauthorized", ai->isAuthorized(database->name.c_str())); + uassert("unauthorized", ai->isAuthorized(cc().database()->name.c_str())); msgdata = getMore(ns, ntoreturn, cursorid); } catch ( AssertionException& e ) { @@ -511,7 +514,7 @@ namespace mongo { /* we should be in the same thread as the original request, so authInfo should be available. */ AuthenticationInfo *ai = currentClient.get()->ai; - Database *clientOld = database; + Database *clientOld = cc().database(); JniMessagingPort jmp(out); callDepth++; @@ -582,6 +585,7 @@ namespace mongo { ss << ' ' << t.millis() << "ms"; mongo::out() << ss.str().c_str() << endl; } + Database *database = cc().database(); if ( database && database->profile >= 1 ) { if ( database->profile >= 2 || ms >= 100 ) { // profile it @@ -598,9 +602,10 @@ namespace mongo { curOp = curOpOld; callDepth--; - if ( database != clientOld ) { + if ( cc().database() != clientOld ) { + assert(false);/* database = clientOld; - wassert(false); + wassert(false);*/ } } diff --git a/db/instance.h b/db/instance.h index b1089fed579..7539f5e1bb1 100644 --- a/db/instance.h +++ b/db/instance.h @@ -132,9 +132,9 @@ namespace mongo { public: SavedContext() { dblock lk; - if ( database ) - oldName = database->name; Client *c = currentClient.get(); + if ( c->database() ) + oldName = c->database()->name; oldAuth = c->ai; // careful, don't want to free this: c->ai = &always; diff --git a/db/introspect.cpp b/db/introspect.cpp index 4aeeda179c5..9cb477d1db5 100644 --- a/db/introspect.cpp +++ b/db/introspect.cpp @@ -34,7 +34,7 @@ namespace mongo { b.append("info", str); b.append("millis", (double) millis); BSONObj p = b.done(); - theDataFileMgr.insert(database->profileName.c_str(), + theDataFileMgr.insert(cc().database()->profileName.c_str(), p.objdata(), p.objsize(), true); } diff --git a/db/matcher.cpp b/db/matcher.cpp index ed4a79b5b08..f1b6c4d518e 100644 --- a/db/matcher.cpp +++ b/db/matcher.cpp @@ -109,7 +109,7 @@ namespace mongo { uassert( "$where query, but no script engine", globalScriptEngine ); where->scope = globalScriptEngine->getPooledScope( cc().ns() ); - where->scope->localConnect( database->name.c_str() ); + where->scope->localConnect( cc().database()->name.c_str() ); if ( e.type() == CodeWScope ) { where->setFunc( e.codeWScopeCode() ); diff --git a/db/pdfile.cpp b/db/pdfile.cpp index 8afa94aa68b..d3a41a2b85f 100644 --- a/db/pdfile.cpp +++ b/db/pdfile.cpp @@ -48,7 +48,6 @@ namespace mongo { DataFileMgr theDataFileMgr; map databases; - Database *database; int MAGIC = 0x1000; int curOp = -2; int callDepth = 0; @@ -64,6 +63,7 @@ namespace mongo { string getDbContext() { stringstream ss; + Database *database = cc().database(); if ( database ) { ss << database->name << ' '; ss << cc().ns() << ' '; @@ -128,6 +128,7 @@ namespace mongo { // each of size 'size'. e = j.findElement( "$nExtents" ); int nExtents = int( e.number() ); + Database *database = cc().database(); if ( nExtents > 0 ) { assert( size <= 0x7fffffff ); for ( int i = 0; i < nExtents; ++i ) { @@ -231,6 +232,7 @@ namespace mongo { something reasonable. */ string s = "db disk space quota exceeded "; + Database *database = cc().database(); if ( database ) s += database->name; uasserted(s); @@ -303,7 +305,7 @@ namespace mongo { out() << "warning: loops=" << loops << " fileno:" << fileNo << ' ' << ns << '\n'; } log() << "newExtent: " << ns << " file " << fileNo << " full, adding a new file\n"; - return database->addAFile( 0, true )->createExtent(ns, approxSize, newCapped, loops+1); + return cc().database()->addAFile( 0, true )->createExtent(ns, approxSize, newCapped, loops+1); } int offset = header->unused.getOfs(); header->unused.setOfs( fileNo, offset + ExtentSize ); @@ -320,7 +322,7 @@ namespace mongo { } Extent* MongoDataFile::allocExtent(const char *ns, int approxSize, bool capped) { - string s = database->name + ".$freelist"; + string s = cc().database()->name + ".$freelist"; NamespaceDetails *f = nsdetails(s.c_str()); if( f ) { int low, high; @@ -557,10 +559,10 @@ namespace mongo { uassert( (string)"ns not found: " + nsToDrop , d ); NamespaceString s(nsToDrop); - assert( s.db == database->name ); + assert( s.db == cc().database()->name ); if( s.isSystem() ) { if( s.coll == "system.profile" ) - uassert( "turn off profiling before dropping system.profile collection", database->profile == 0 ); + uassert( "turn off profiling before dropping system.profile collection", cc().database()->profile == 0 ); else uasserted( "can't drop system ns" ); } @@ -568,14 +570,14 @@ namespace mongo { { // remove from the system catalog BSONObj cond = BSON( "name" << nsToDrop ); // { name: "colltodropname" } - string system_namespaces = database->name + ".system.namespaces"; + string system_namespaces = cc().database()->name + ".system.namespaces"; /*int n = */ deleteObjects(system_namespaces.c_str(), cond, false, false, true); // no check of return code as this ns won't exist for some of the new storage engines } // free extents if( !d->firstExtent.isNull() ) { - string s = database->name + ".$freelist"; + string s = cc().database()->name + ".$freelist"; NamespaceDetails *freeExtents = nsdetails(s.c_str()); if( freeExtents == 0 ) { string err; @@ -600,7 +602,7 @@ namespace mongo { } // remove from the catalog hashtable - database->namespaceIndex.kill(nsToDrop.c_str()); + cc().database()->namespaceIndex.kill(nsToDrop.c_str()); } void dropCollection( const string &name, string &errmsg, BSONObjBuilder &result ) { @@ -648,7 +650,7 @@ namespace mongo { // clean up in system.indexes. we do this last on purpose. note we have // to make the cond object before the drop() above though. - string system_indexes = database->name + ".system.indexes"; + string system_indexes = cc().database()->name + ".system.indexes"; int n = deleteObjects(system_indexes.c_str(), cond, false, false, true); wassert( n == 1 ); } @@ -957,7 +959,7 @@ namespace mongo { // doesn't fit. reallocate ----------------------------------------------------- uassert("E10003 failing update: objects in a capped ns cannot grow", !(d && d->capped)); d->paddingTooSmall(); - if ( database->profile ) + if ( cc().database()->profile ) ss << " moved "; deleteRecord(ns, toupdate, dl); insert(ns, objNew.objdata(), objNew.objsize(), false); @@ -994,7 +996,7 @@ namespace mongo { out() << " caught assertion update index " << idx.indexNamespace() << '\n'; problem() << " caught assertion update index " << idx.indexNamespace() << endl; } - if ( database->profile ) + if ( cc().database()->profile ) ss << '\n' << changes[x].added.size() << " key updates "; } @@ -1250,7 +1252,7 @@ namespace mongo { if ( d->indexes[ i ].isIdIndex() ) return; - string system_indexes = database->name + ".system.indexes"; + string system_indexes = cc().database()->name + ".system.indexes"; BSONObjBuilder b; b.append("name", "_id_"); @@ -1335,7 +1337,7 @@ namespace mongo { also if this is an addIndex, those checks should happen before this! */ // This creates first file in the database. - database->newestFile()->allocExtent(ns, initialExtentSize(len)); + cc().database()->newestFile()->allocExtent(ns, initialExtentSize(len)); d = nsdetails(ns); if ( !god ) ensureIdIndexForNewNs(ns); @@ -1350,7 +1352,7 @@ namespace mongo { const char *name = io.getStringField("name"); // name of the index tabletoidxns = io.getStringField("ns"); // table it indexes - if ( database->name != nsToClient(tabletoidxns.c_str()) ) { + if ( cc().database()->name != nsToClient(tabletoidxns.c_str()) ) { uassert("bad table to index name on add index attempt", false); return DiskLoc(); } @@ -1435,13 +1437,13 @@ namespace mongo { // out of space if ( d->capped == 0 ) { // size capped doesn't grow log(1) << "allocating new extent for " << ns << " padding:" << d->paddingFactor << " lenWHdr: " << lenWHdr << endl; - database->newestFile()->allocExtent(ns, followupExtentSize(lenWHdr, d->lastExtentSize)); + cc().database()->newestFile()->allocExtent(ns, followupExtentSize(lenWHdr, d->lastExtentSize)); loc = d->alloc(ns, lenWHdr, extentLoc); if ( loc.isNull() ){ log() << "WARNING: alloc() failed after allocating new extent. lenWHdr: " << lenWHdr << " last extent size:" << d->lastExtentSize << "; trying again\n"; for ( int zzz=0; zzz<10 && lenWHdr > d->lastExtentSize; zzz++ ){ log() << "try #" << zzz << endl; - database->newestFile()->allocExtent(ns, followupExtentSize(len, d->lastExtentSize)); + cc().database()->newestFile()->allocExtent(ns, followupExtentSize(len, d->lastExtentSize)); loc = d->alloc(ns, lenWHdr, extentLoc); if ( ! loc.isNull() ) break; @@ -1591,7 +1593,7 @@ namespace mongo { char cl[256]; nsToClient(ns, cl); log(1) << "dropDatabase " << cl << endl; - assert( database->name == cl ); + assert( cc().database()->name == cl ); closeClient( cl ); _deleteDataFiles(cl); @@ -1699,7 +1701,7 @@ namespace mongo { char dbName[256]; nsToClient(ns, dbName); problem() << "repairDatabase " << dbName << endl; - assert( database->name == dbName ); + assert( cc().database()->name == dbName ); boost::intmax_t totalSize = dbSize( dbName ); boost::intmax_t freeSize = freeSpace(); diff --git a/db/pdfile.h b/db/pdfile.h index 173336804fc..e630e971cdf 100644 --- a/db/pdfile.h +++ b/db/pdfile.h @@ -30,6 +30,7 @@ #include "storage.h" #include "jsobjmanipulator.h" #include "namespace.h" +#include "client.h" namespace mongo { @@ -397,6 +398,7 @@ namespace mongo { boost::intmax_t dbSize( const char *database ); inline NamespaceIndex* nsindex(const char *ns) { + Database *database = cc().database(); DEV { char buf[256]; nsToClient(ns, buf); @@ -418,17 +420,17 @@ namespace mongo { inline MongoDataFile& DiskLoc::pdf() const { assert( fileNo != -1 ); - return *database->getFile(fileNo); + return *cc().database()->getFile(fileNo); } inline Extent* DataFileMgr::getExtent(const DiskLoc& dl) { assert( dl.a() != -1 ); - return database->getFile(dl.a())->getExtent(dl); + return cc().database()->getFile(dl.a())->getExtent(dl); } inline Record* DataFileMgr::getRecord(const DiskLoc& dl) { assert( dl.a() != -1 ); - return database->getFile(dl.a())->recordAt(dl); + return cc().database()->getFile(dl.a())->recordAt(dl); } void ensureHaveIdIndex(const char *ns); diff --git a/db/query.cpp b/db/query.cpp index df584751821..0d70a39a2d1 100644 --- a/db/query.cpp +++ b/db/query.cpp @@ -746,7 +746,7 @@ namespace mongo { }; int __updateObjects(const char *ns, BSONObj updateobj, BSONObj &pattern, bool upsert, stringstream& ss, bool logop=false) { - int profile = database->profile; + int profile = cc().database()->profile; uassert("cannot update reserved $ collection", strchr(ns, '$') == 0 ); if ( strstr(ns, ".system.") ) { @@ -1405,7 +1405,7 @@ namespace mongo { else { AuthenticationInfo *ai = currentClient.get()->ai; - uassert("unauthorized", ai->isAuthorized(database->name.c_str())); + uassert("unauthorized", ai->isAuthorized(cc().database()->name.c_str())); /* we allow queries to SimpleSlave's -- but not to the slave (nonmaster) member of a replica pair so that queries to a pair are realtime consistent as much as possible. use setSlaveOk() to @@ -1552,6 +1552,7 @@ namespace mongo { } int duration = t.millis(); + Database *database = cc().database(); if ( (database && database->profile) || duration >= 100 ) { ss << " nscanned:" << nscanned << ' '; if ( ntoskip ) diff --git a/db/reccache.cpp b/db/reccache.cpp index 4e6fb299066..5b8efce919d 100644 --- a/db/reccache.cpp +++ b/db/reccache.cpp @@ -74,7 +74,7 @@ inline static string unescape(const char *ns) { } string RecCache::directory() { - return database->path; + return cc().database()->path; } /* filename format is diff --git a/db/repl.cpp b/db/repl.cpp index a78f8663656..4327984b601 100644 --- a/db/repl.cpp +++ b/db/repl.cpp @@ -548,7 +548,7 @@ namespace mongo { setClient("local.sources"); int u = _updateObjects("local.sources", o, pattern, true/*upsert for pair feature*/, ss); assert( u == 1 || u == 4 ); - database = 0; + cc().clearns(); if ( replacing ) { /* if we were in "replace" mode, we now have synced up with the replacement, @@ -670,7 +670,7 @@ namespace mongo { addSourceToList(v, tmp, c->current(), old); c->advance(); } - database = 0; + cc().clearns(); if ( !gotPairWith && replPair ) { /* add the --pairwith server */ @@ -735,7 +735,7 @@ namespace mongo { log() << "resync: dropping database " << db << endl; string dummyns = string( db ) + "."; setClient(dummyns.c_str()); - assert( database->name == db ); + assert( cc().database()->name == db ); dropDatabase(dummyns.c_str()); return dummyns; } @@ -748,7 +748,7 @@ namespace mongo { log() << "resync: cloning database " << db << endl; ReplInfo r("resync: cloning a database"); string errmsg; - bool ok = cloneFrom(hostName.c_str(), errmsg, database->name, false, /*slaveok*/ true, /*replauth*/ true, /*snapshot*/false); + bool ok = cloneFrom(hostName.c_str(), errmsg, cc().database()->name, false, /*slaveok*/ true, /*replauth*/ true, /*snapshot*/false); if ( !ok ) { problem() << "resync of " << db << " from " << hostName << " failed " << errmsg << endl; throw SyncException(); @@ -881,7 +881,7 @@ namespace mongo { // this is a bit hacky -- the semantics of replication/commands aren't well specified if ( strcmp( clientName, "admin" ) == 0 && *op.getStringField( "op" ) == 'c' ) { applyOperation( op ); - database = 0; + cc().clearns(); return; } @@ -902,7 +902,7 @@ namespace mongo { save(); setClient( ns ); nClonedThisPass++; - resync(database->name); + resync(cc().database()->name); addDbNextPass.erase(clientName); incompleteCloneDbs.erase( clientName ); } @@ -926,7 +926,7 @@ namespace mongo { } addDbNextPass.erase( clientName ); } - database = 0; + cc().clearns(); } BSONObj ReplSource::idForOp( const BSONObj &op, bool &mod ) { @@ -1407,7 +1407,8 @@ namespace mongo { if ( strncmp(ns, "local.", 6) == 0 ) return; - Database *oldClient = database; + DBContext context; + /* we jump through a bunch of hoops here to avoid copying the obj buffer twice -- instead we do a single copy to the destination position in the memory mapped file. */ @@ -1428,10 +1429,10 @@ namespace mongo { if ( strncmp( logNS, "local.", 6 ) == 0 ) { // For now, assume this is olog main if ( localOplogMainDetails == 0 ) { setClient("local."); - localOplogClient = database; + localOplogClient = cc().database(); localOplogMainDetails = nsdetails(logNS); } - database = localOplogClient; + cc().setns("", localOplogClient); // database = localOplogClient; r = theDataFileMgr.fast_oplog_insert(localOplogMainDetails, logNS, len); } else { setClient( logNS ); @@ -1454,8 +1455,6 @@ namespace mongo { BSONObj temp(r); log( 6 ) << "logging op:" << temp << endl; } - - database = oldClient; } /* --------------------------------------------------------------*/ @@ -1655,7 +1654,7 @@ namespace mongo { BSONObj o = b.done(); userCreateNS(ns, o, err, false); logOp( "n", "dummy", BSONObj() ); - database = 0; + cc().clearns(); } void startReplication() { diff --git a/db/replset.h b/db/replset.h index 34d61cc8d7e..4840b19a23b 100644 --- a/db/replset.h +++ b/db/replset.h @@ -115,6 +115,7 @@ namespace mongo { return true; if ( !client ) { + Database *database = cc().database(); assert( database ); client = database->name.c_str(); } diff --git a/db/security.cpp b/db/security.cpp index ae975fbfde8..ae04a0819f1 100644 --- a/db/security.cpp +++ b/db/security.cpp @@ -25,7 +25,7 @@ namespace mongo { boost::thread_specific_ptr currentClient; - Client::Client() : _ns(""), _nsstr("") { + Client::Client() : _database(0), _ns("")/*, _nsstr("")*/ { ai = new AuthenticationInfo(); } diff --git a/db/security_commands.cpp b/db/security_commands.cpp index 366a3f52b33..4a801b24916 100644 --- a/db/security_commands.cpp +++ b/db/security_commands.cpp @@ -61,8 +61,9 @@ namespace mongo { CmdLogout() : Command("logout") {} bool run(const char *ns, BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result, bool fromRepl) { // database->name is the one we are logging out... - AuthenticationInfo *ai = currentClient.get()->ai; - ai->logout(database->name.c_str()); + Client& client = cc(); + AuthenticationInfo *ai = client.ai; + ai->logout(client.database()->name.c_str()); return true; } } cmdLogout; @@ -85,7 +86,9 @@ namespace mongo { string received_nonce = cmdObj.getStringField("nonce"); if( user.empty() || key.empty() || received_nonce.empty() ) { - log() << "field missing/wrong type in received authenticate command " << database->name << '\n'; log() << "field missing/wrong type in received authenticate command " << database->name << '\n'; + log() << "field missing/wrong type in received authenticate command " + << cc().database()->name + << '\n'; errmsg = "auth fails"; sleepmillis(10); return false; @@ -98,7 +101,7 @@ namespace mongo { digestBuilder << hex << *ln; if( ln == 0 || digestBuilder.str() != received_nonce ) { - log() << "auth: bad nonce received. could be a driver bug or a security attack. db:" << database->name << '\n'; log() << "field missing/wr " << database->name << '\n'; + log() << "auth: bad nonce received. could be a driver bug or a security attack. db:" << cc().database()->name << '\n'; errmsg = "auth fails"; sleepmillis(30); return false; @@ -106,7 +109,7 @@ namespace mongo { } static BSONObj userPattern = fromjson("{\"user\":1}"); - string systemUsers = database->name + ".system.users"; + string systemUsers = cc().database()->name + ".system.users"; OCCASIONALLY Helpers::ensureIndex(systemUsers.c_str(), userPattern, false, "user_1"); BSONObj userObj; @@ -143,7 +146,7 @@ namespace mongo { } AuthenticationInfo *ai = currentClient.get()->ai; - ai->authorize(database->name.c_str()); + ai->authorize(cc().database()->name.c_str()); return true; } } cmdAuthenticate; diff --git a/dbtests/cursortests.cpp b/dbtests/cursortests.cpp index 8915ff3148a..633532e5ad1 100644 --- a/dbtests/cursortests.cpp +++ b/dbtests/cursortests.cpp @@ -18,10 +18,10 @@ */ #include "stdafx.h" +#include "../db/db.h" #include "../db/clientcursor.h" #include "../db/instance.h" #include "../db/btree.h" - #include "dbtests.h" namespace CursorTests { diff --git a/dbtests/querytests.cpp b/dbtests/querytests.cpp index 784cf6a2fdd..79189ef177d 100644 --- a/dbtests/querytests.cpp +++ b/dbtests/querytests.cpp @@ -608,7 +608,7 @@ namespace QueryTests { dblock lk; setClient( "unittests.DirectLocking" ); client().remove( "a.b", BSONObj() ); - ASSERT_EQUALS( "unittests", database->name ); + ASSERT_EQUALS( "unittests", cc().database()->name ); } const char *ns; }; @@ -704,7 +704,7 @@ namespace QueryTests { } int count(){ - return client().count( ns() ); + return (int) client().count( ns() ); } void run(){