diff --git a/client/dbclient.cpp b/client/dbclient.cpp
index d61707fa0ce..884c09a85e7 100644
--- a/client/dbclient.cpp
+++ b/client/dbclient.cpp
@@ -1,4 +1,4 @@
-// dbclient.cpp - connect to a Mongo database as a client, from C++
+// dbclient.cpp - connect to a Mongo database as a database, from C++
/**
* Copyright (C) 2008 10gen Inc.
diff --git a/client/dbclient.h b/client/dbclient.h
index b3582de8dfc..1c8ee02fb0f 100644
--- a/client/dbclient.h
+++ b/client/dbclient.h
@@ -1,4 +1,4 @@
-// dbclient.h - connect to a Mongo database as a client, from C++
+// dbclient.h - connect to a Mongo database as a database, from C++
/**
* Copyright (C) 2008 10gen Inc.
diff --git a/client/model.h b/client/model.h
index f56cf7b3a43..0e0e0917bb1 100644
--- a/client/model.h
+++ b/client/model.h
@@ -21,7 +21,7 @@
#include "dbclient.h"
/* Model is a base class for defining objects which are serializable to the Mongo
- database via the client driver.
+ database via the database driver.
*Definition*
Your serializable class should inherit from Model and implement the abstract methods
diff --git a/db/clientcursor.cpp b/db/clientcursor.cpp
index 55c525f6f4e..c8c81cd24bf 100644
--- a/db/clientcursor.cpp
+++ b/db/clientcursor.cpp
@@ -16,7 +16,7 @@
/* clientcursor.cpp
- ClientCursor is a wrapper that represents a cursorid from our client
+ ClientCursor is a wrapper that represents a cursorid from our database
application's perspective.
Cursor -- and its derived classes -- are our internal cursors.
diff --git a/db/clientcursor.h b/db/clientcursor.h
index 940a99ec301..5437d067cca 100644
--- a/db/clientcursor.h
+++ b/db/clientcursor.h
@@ -18,7 +18,7 @@
Cursor -- and its derived classes -- are our internal cursors.
- ClientCursor is a wrapper that represents a cursorid from our client
+ ClientCursor is a wrapper that represents a cursorid from our database
application's perspective.
*/
diff --git a/db/cloner.cpp b/db/cloner.cpp
index c2531583c25..7e02ef9f16b 100644
--- a/db/cloner.cpp
+++ b/db/cloner.cpp
@@ -51,7 +51,7 @@ BSONObj fixindex(BSONObj o) {
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 = client->name + p;
+ string newname = database->name + p;
b.append("ns", newname);
}
else
@@ -98,7 +98,7 @@ void Cloner::copy(const char *from_collection, const char *to_collection, bool i
}
bool Cloner::go(const char *masterHost, string& errmsg, const string& fromdb) {
- string todb = client->name;
+ string todb = database->name;
stringstream a,b;
a << "localhost:" << port;
b << "127.0.0.1:" << port;
@@ -180,7 +180,7 @@ public:
string from = cmdObj.getStringField("clone");
if( from.empty() )
return false;
- return cloneFrom(from.c_str(), errmsg, client->name);
+ return cloneFrom(from.c_str(), errmsg, database->name);
}
} cmdclone;
@@ -208,7 +208,7 @@ public:
}
setClient(todb.c_str());
bool res = cloneFrom(fromhost.c_str(), errmsg, fromdb);
- client = 0;
+ database = 0;
return res;
}
} cmdcopydb;
diff --git a/db/database.h b/db/database.h
new file mode 100644
index 00000000000..0bf1e485bac
--- /dev/null
+++ b/db/database.h
@@ -0,0 +1,127 @@
+// database.h
+
+/**
+* Copyright (C) 2008 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see .
+*/
+
+/* Database represents a database database
+ Each database database has its own set of files -- dbname.ns, dbname.0, dbname.1, ...
+*/
+
+class Database {
+public:
+ Database(const char *nm, bool& justCreated) : name(nm) {
+ justCreated = namespaceIndex.init(dbpath, nm);
+ profile = 0;
+ profileName = name + ".system.profile";
+ }
+ ~Database() {
+ int n = files.size();
+ for( int i = 0; i < n; i++ )
+ delete files[i];
+ }
+
+ PhysicalDataFile* getFile(int n) {
+ assert(this);
+
+ if( n < 0 || n >= DiskLoc::MaxFiles ) {
+ cout << "getFile(): n=" << n << endl;
+ assert( n >= 0 && n < DiskLoc::MaxFiles );
+ }
+ DEV {
+ if( n > 100 )
+ cout << "getFile(): n=" << n << "?" << endl;
+ }
+ while( n >= (int) files.size() )
+ files.push_back(0);
+ PhysicalDataFile* p = files[n];
+ if( p == 0 ) {
+ p = new PhysicalDataFile(n);
+ files[n] = p;
+ stringstream out;
+ out << dbpath << name << '.' << n;
+ p->open(n, out.str().c_str());
+ }
+ return p;
+ }
+
+ PhysicalDataFile* addAFile() {
+ int n = (int) files.size();
+ return getFile(n);
+ }
+
+ PhysicalDataFile* newestFile() {
+ int n = (int) files.size();
+ if( n > 0 ) n--;
+ return getFile(n);
+ }
+
+ void finishInit(); // ugly...
+
+ vector files;
+ string name; // "alleyinsider"
+ NamespaceIndex namespaceIndex;
+ int profile; // 0=off.
+ string profileName; // "alleyinsider.system.profile"
+ QueryOptimizer optimizer;
+
+ bool haveLogged() { return _haveLogged; }
+ void setHaveLogged();
+
+private:
+ // see dbinfo.h description. if true, we have logged to the replication log.
+ bool _haveLogged;
+};
+
+// tempish...move to TLS or pass all the way down as a parm
+extern map databases;
+extern Database *database;
+extern const char *curNs;
+extern int dbLocked;
+/* returns true if the database ("database") did not exist, and it was created on this call */
+inline bool setClient(const char *ns) {
+ /* we must be in critical section at this point as these are global
+ variables.
+ */
+ assert( dbLocked == 1 );
+
+ char cl[256];
+ curNs = ns;
+ nsToClient(ns, cl);
+ map::iterator it = databases.find(cl);
+ if( it != databases.end() ) {
+ database = it->second;
+ return false;
+ }
+ log() << "first operation for database " << cl << endl;
+ bool justCreated;
+ Database *c = new Database(cl, justCreated);
+ databases[cl] = c;
+ database = c;
+ database->finishInit();
+ return justCreated;
+}
+
+/* We normally keep around a curNs ptr -- if this ns is temporary,
+ use this instead so we don't have a bad ptr. we could have made a copy,
+ but trying to be fast as we call setClient this for every single operation.
+*/
+inline bool setClientTempNs(const char *ns) {
+ bool jc = setClient(ns);
+ curNs = "";
+ return jc;
+}
+
+#include "dbinfo.h"
diff --git a/db/db.cpp b/db/db.cpp
index 89aae55ef16..087cc1277aa 100644
--- a/db/db.cpp
+++ b/db/db.cpp
@@ -136,7 +136,7 @@ void receivedUpdate(Message& m, stringstream& ss) {
const char *ns = d.getns();
assert(*ns);
setClient(ns);
- //if( client->profile )
+ //if( database->profile )
ss << ns << ' ';
int flags = d.pullInt();
BSONObj query = d.nextJsObj();
@@ -234,13 +234,13 @@ void receivedQuery(DbResponse& dbresponse, /*AbstractMessagingPort& dbMsgPort, *
resp->setData(msgdata, true); // transport will free
dbresponse.response = resp;
dbresponse.responseTo = responseTo;
- if( client ) {
- if( client->profile )
+ if( database ) {
+ if( database->profile )
ss << " bytes:" << resp->data->dataLen();
}
else {
if( strstr(q.ns, "$cmd") == 0 ) // (this condition is normal for $cmd dropDatabase)
- log() << "ERROR: receiveQuery: client is null; ns=" << q.ns << endl;
+ log() << "ERROR: receiveQuery: database is null; ns=" << q.ns << endl;
}
// dbMsgPort.reply(m, resp, responseTo);
}
@@ -310,7 +310,7 @@ void testTheDb() {
}
cout << endl;
- client = 0;
+ database = 0;
}
int port = DBPort;
@@ -375,7 +375,7 @@ public:
*/
void jniCallback(Message& m, Message& out)
{
- Client *clientOld = client;
+ Database *clientOld = database;
JniMessagingPort jmp(out);
callDepth++;
@@ -446,8 +446,8 @@ void jniCallback(Message& m, Message& out)
ss << ' ' << t.millis() << "ms";
cout << ss.str().c_str() << endl;
}
- if( client && client->profile >= 1 ) {
- if( client->profile >= 2 || ms >= 100 ) {
+ if( database && database->profile >= 1 ) {
+ if( database->profile >= 2 || ms >= 100 ) {
// profile it
profile(ss.str().c_str()+20/*skip ts*/, ms);
}
@@ -462,13 +462,13 @@ void jniCallback(Message& m, Message& out)
curOp = curOpOld;
callDepth--;
- if( client != clientOld ) {
- client = clientOld;
+ if( database != clientOld ) {
+ database = clientOld;
wassert(false);
}
}
-/* we create one thread for each connection from an app server client.
+/* we create one thread for each connection from an app server database.
app server will open a pool of threads.
*/
void connThread()
@@ -499,7 +499,7 @@ void connThread()
{
dblock lk;
Timer t;
- client = 0;
+ database = 0;
curOp = 0;
int ms;
@@ -613,8 +613,8 @@ void connThread()
cout << ss.str().c_str() << endl;
}
//skip:
- if( client && client->profile >= 1 ) {
- if( client->profile >= 2 || ms >= 100 ) {
+ if( database && database->profile >= 1 ) {
+ if( database->profile >= 2 || ms >= 100 ) {
// profile it
profile(ss.str().c_str()+20/*skip ts*/, ms);
}
diff --git a/db/db.h b/db/db.h
index 896ec85d4db..856cc484cd7 100644
--- a/db/db.h
+++ b/db/db.h
@@ -51,8 +51,8 @@ struct temprelease {
struct dbtemprelease {
string clientname;
dbtemprelease() {
- if( client )
- clientname = client->name;
+ if( database )
+ clientname = database->name;
dbLocked--;
assert( dbLocked == 0 );
boost::detail::thread::lock_ops::unlock(dbMutex);
@@ -62,7 +62,7 @@ struct dbtemprelease {
dbLocked++;
assert( dbLocked == 1 );
if( clientname.empty() )
- client = 0;
+ database = 0;
else
setClient(clientname.c_str());
}
diff --git a/db/db.vcproj b/db/db.vcproj
index a648afcc9c7..51ccdd35bdc 100644
--- a/db/db.vcproj
+++ b/db/db.vcproj
@@ -1,1000 +1,1012 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/db/dbcommands.cpp b/db/dbcommands.cpp
index 48b7f74033a..2f7ebe0929c 100644
--- a/db/dbcommands.cpp
+++ b/db/dbcommands.cpp
@@ -282,14 +282,14 @@ bool _runCommands(const char *ns, BSONObj& jsobj, stringstream& ss, BufBuilder &
}
}
else if( strcmp(e.fieldName(), "profile") == 0 ) {
- anObjBuilder.append("was", (double) client->profile);
+ anObjBuilder.append("was", (double) database->profile);
int p = (int) e.number();
valid = true;
if( p == -1 )
ok = true;
else if( p >= 0 && p <= 2 ) {
ok = true;
- client->profile = p;
+ database->profile = p;
}
else {
ok = false;
@@ -348,7 +348,7 @@ bool _runCommands(const char *ns, BSONObj& jsobj, stringstream& ss, BufBuilder &
anObjBuilder.append("errmsg", "ns not found");
}
else if( d->nIndexes != 0 ) {
- // client is supposed to drop the indexes first
+ // database is supposed to drop the indexes first
anObjBuilder.append("errmsg", "ns has indexes (not permitted on drop)");
}
else {
@@ -364,7 +364,7 @@ bool _runCommands(const char *ns, BSONObj& jsobj, stringstream& ss, BufBuilder &
BSONObj cond = b.done(); // { name: "colltodropname" }
deleteObjects("system.namespaces", cond, false, true);
}
- client->namespaceIndex.kill(dropNs.c_str());
+ database->namespaceIndex.kill(dropNs.c_str());
*/
}
}
diff --git a/db/dbeval.cpp b/db/dbeval.cpp
index 8240ededbbd..40732a3c4c6 100644
--- a/db/dbeval.cpp
+++ b/db/dbeval.cpp
@@ -52,7 +52,7 @@ bool dbEval(const char *ns, BSONObj& cmd, BSONObjBuilder& result, string& errmsg
Scope s;
if ( e.type() == CodeWScope )
s.init( e.codeWScopeScopeData() );
- s.setString("$client", client->name.c_str());
+ s.setString("$database", database->name.c_str());
BSONElement args = cmd.findElement("args");
if( args.type() == Array ) {
BSONObj eo = args.embeddedObject();
diff --git a/db/dbinfo.cpp b/db/dbinfo.cpp
new file mode 100644
index 00000000000..df1be8817fb
--- /dev/null
+++ b/db/dbinfo.cpp
@@ -0,0 +1,45 @@
+// dbinfo.cpp
+
+/**
+* Copyright (C) 2008 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see .
+*/
+
+#include "stdafx.h"
+#include "db.h"
+
+void DBInfo::setHaveLogged() {
+ if( haveLogged() )
+ return;
+
+ NamespaceDetails *d = nsdetails(ns.c_str());
+ assert( d == 0 || d->nrecords == 0 );
+ BSONObjBuilder b;
+ b.appendBool("haveLogged", true);
+ BSONObj o = b.done();
+ theDataFileMgr.insert(ns.c_str(), (void *) o.objdata(), o.objsize());
+}
+
+int deleteObjects(const char *ns, BSONObj pattern, bool justOne, bool god);
+
+void DBInfo::dbDropped() {
+ BSONObj empty;
+ deleteObjects(ns.c_str(), empty, false, false);
+
+ /* do we also need to clear the info in 'dbs' in local.sources if we
+are a slave?
+ TODO if so. need to be careful not to mess up replications of dropDatabase().
+ */
+}
+
diff --git a/db/dbinfo.h b/db/dbinfo.h
new file mode 100644
index 00000000000..9a61677b15f
--- /dev/null
+++ b/db/dbinfo.h
@@ -0,0 +1,68 @@
+// dbinfo.h
+
+/**
+* Copyright (C) 2008 10gen Inc.
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU Affero General Public License, version 3,
+* as published by the Free Software Foundation.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU Affero General Public License for more details.
+*
+* You should have received a copy of the GNU Affero General Public License
+* along with this program. If not, see .
+*/
+
+/* this is an "accessor" class to data held in local.dbinfo.
+
+ system.dbinfo contains:
+
+ { haveLogged : true }
+
+ haveLogged -- if true, we have already logged events to the oplog for this
+ database. missing implies false.
+
+ other attributes will be added later.
+
+ Note that class Database caches the DBInfo::haveLogged() value to keep things fast.
+*/
+class DBInfo {
+ string ns;
+ Database *dbold;
+public:
+ ~DBInfo() { database = dbold; }
+ DBInfo(const char *db) {
+ dbold = database;
+ ns = string("local.dbinfo.") + db;
+ setClientTempNs(ns.c_str());
+ }
+
+ BSONObj getDbInfoObj() {
+ auto_ptr c = DataFileMgr::findAll(ns.c_str());
+ if( !c->ok() )
+ return BSONObj();
+ return c->current();
+ }
+
+ bool haveLogged() {
+ return getDbInfoObj().getBoolField("haveLogged");
+ }
+
+ void setHaveLogged();
+ void dbDropped();
+};
+
+inline void Database::setHaveLogged() {
+ if( _haveLogged ) return;
+ DBInfo i(name.c_str());
+ i.setHaveLogged();
+ _haveLogged = true;
+}
+
+inline void Database::finishInit() {
+ DBInfo i(name.c_str());
+ _haveLogged = i.haveLogged();
+}
diff --git a/db/dbmessage.h b/db/dbmessage.h
index 681f110e327..cd59b1a68db 100644
--- a/db/dbmessage.h
+++ b/db/dbmessage.h
@@ -18,7 +18,7 @@
#include "jsobj.h"
#include "namespace.h"
-/* For the client/server protocol, these objects and functions encapsulate
+/* For the database/server protocol, these objects and functions encapsulate
the various messages transmitted over the connection.
*/
@@ -91,7 +91,7 @@ private:
const char *theEnd;
};
-/* a request to run a query, received from the client */
+/* a request to run a query, received from the database */
class QueryMessage {
public:
const char *ns;
diff --git a/db/dbwebserver.cpp b/db/dbwebserver.cpp
index e519ec9e7da..0a3a5d6785d 100644
--- a/db/dbwebserver.cpp
+++ b/db/dbwebserver.cpp
@@ -25,13 +25,15 @@
extern int port;
extern string replInfo;
+time_t started = time(0);
+
class DbWebServer : public MiniWebServer {
public:
void doLockedStuff(stringstream& ss) {
dblock lk;
- ss << "# clients: " << clients.size() << '\n';
- if( client ) {
- ss << "curclient: " << client->name;
+ ss << "# databases: " << databases.size() << '\n';
+ if( database ) {
+ ss << "curclient: " << database->name;
ss << '\n';
}
ss << "\nreplication\n";
@@ -47,6 +49,7 @@ public:
void doUnlockedStuff(stringstream& ss) {
ss << "port: " << port << '\n';
ss << "dblocked: " << dbLocked << " (initial)\n";
+ ss << "uptime: " << time(0)-started << " seconds\n";
if( allDead )
ss << "replication allDead=" << allDead << "\n";
}
diff --git a/db/introspect.cpp b/db/introspect.cpp
index 599b9aee9be..bda75df05fd 100644
--- a/db/introspect.cpp
+++ b/db/introspect.cpp
@@ -50,6 +50,6 @@ void profile(const char *str,
b.append("info", str);
b.append("millis", (double) millis);
BSONObj p = b.done();
- theDataFileMgr.insert(client->profileName.c_str(),
+ theDataFileMgr.insert(database->profileName.c_str(),
p.objdata(), p.objsize(), true);
}
diff --git a/db/introspect.h b/db/introspect.h
index e1915050b0a..01cbbfce184 100644
--- a/db/introspect.h
+++ b/db/introspect.h
@@ -54,7 +54,7 @@ public:
};
/* --- profiling --------------------------------------------
- do when client->profile is set
+ do when database->profile is set
*/
void profile(const char *str,
diff --git a/db/jsobj.h b/db/jsobj.h
index e7254425fcf..ba2bfdd9970 100644
--- a/db/jsobj.h
+++ b/db/jsobj.h
@@ -498,8 +498,12 @@ private:
class BSONObjIterator {
public:
BSONObjIterator(const BSONObj& jso) {
+ int sz = jso.objsize();
+ if( sz == 0 ) {
+ pos = theend = 0; return;
+ }
pos = jso.objdata() + 4;
- theend = jso.objdata() + jso.objsize();
+ theend = jso.objdata() + sz;
}
bool more() { return pos < theend; }
BSONElement next() {
diff --git a/db/makefile b/db/makefile
index e8817359e55..2d5d241ec0b 100644
--- a/db/makefile
+++ b/db/makefile
@@ -11,7 +11,7 @@ DBGRID_LIBS = $(LIB_BOOST) -lstdc++
JVM_LIBS = -L/opt/java/lib/
-OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/mmap.o pdfile.o query.o jsobj.o introspect.o btree.o clientcursor.o ../util/util.o javajs.o tests.o json.o repl.o ../client/dbclient.o btreecursor.o cloner.o namespace.o commands.o matcher.o dbcommands.o dbeval.o ../util/background.o ../util/miniwebserver.o dbwebserver.o
+OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/mmap.o pdfile.o query.o jsobj.o introspect.o btree.o clientcursor.o ../util/util.o javajs.o tests.o json.o repl.o ../client/dbclient.o btreecursor.o cloner.o namespace.o commands.o matcher.o dbcommands.o dbeval.o ../util/background.o ../util/miniwebserver.o dbwebserver.o dbinfo.o
DBGRID_OBJS=../stdafx.o json.o ../util/sock.o ../grid/message.o ../util/util.o jsobj.o ../client/dbclient.o ../dbgrid/dbgrid.o ../dbgrid/request.o ../client/connpool.o ../dbgrid/gridconfig.o commands.o ../dbgrid/dbgrid_commands.o ../dbgrid/griddatabase.o ../client/model.o ../util/background.o ../dbgrid/shard.o
diff --git a/db/matcher.cpp b/db/matcher.cpp
index 0a8a191e949..51ca81d16bc 100644
--- a/db/matcher.cpp
+++ b/db/matcher.cpp
@@ -145,7 +145,7 @@ JSMatcher::JSMatcher(BSONObj &_jsobj, BSONObj indexKeyPattern) :
where = new Where();
uassert( "$where query, but jni is disabled", JavaJS );
where->scope = JavaJS->scopeCreate();
- JavaJS->scopeSetString(where->scope, "$client", client->name.c_str());
+ JavaJS->scopeSetString(where->scope, "$database", database->name.c_str());
if ( e.type() == CodeWScope ){
where->setFunc( e.codeWScopeCode() );
diff --git a/db/namespace.cpp b/db/namespace.cpp
index a63e3eae225..3a858299012 100644
--- a/db/namespace.cpp
+++ b/db/namespace.cpp
@@ -37,6 +37,33 @@ int bucketSizes[] = {
//NamespaceIndexMgr namespaceIndexMgr;
+ /* returns true if we created (did not exist) during init() */
+bool NamespaceIndex::init(const char *dir, const char *database) {
+ string path = dir;
+ path += database;
+ path += ".ns";
+
+ bool created = !boost::filesystem::exists(path);
+
+ /* if someone manually deleted the datafiels for a database,
+ we need to be sure to clear any cached info for the database in
+ local.*.
+ */
+ if( string("local") != database ) {
+ DBInfo i(database);
+ i.dbDropped();
+ }
+
+ const int LEN = 16 * 1024 * 1024;
+ void *p = f.map(path.c_str(), LEN);
+ if( p == 0 ) {
+ problem() << "couldn't open namespace.idx " << path.c_str() << " terminating" << endl;
+ exit(-3);
+ }
+ ht = new HashTable(p, LEN, "namespace index");
+ return created;
+}
+
void NamespaceDetails::addDeletedRec(DeletedRecord *d, DiskLoc dloc) {
{
// defensive code: try to make us notice if we reference a deleted record
@@ -338,9 +365,9 @@ void addNewNamespaceToCatalog(const char *ns, BSONObj *options = 0) {
if( options )
b.append("options", *options);
BSONObj j = b.done();
- char client[256];
- nsToClient(ns, client);
- string s = client;
+ char database[256];
+ nsToClient(ns, database);
+ string s = database;
s += ".system.namespaces";
theDataFileMgr.insert(s.c_str(), j.objdata(), j.objsize(), true);
}
diff --git a/db/namespace.h b/db/namespace.h
index b66e56111bc..4e2b42e78fb 100644
--- a/db/namespace.h
+++ b/db/namespace.h
@@ -99,7 +99,7 @@ public:
}
// returns name of this index's storage area
- // client.table.$index
+ // database.table.$index
string indexNamespace() {
BSONObj io = info.obj();
string s;
@@ -256,22 +256,7 @@ public:
NamespaceIndex() { }
/* returns true if we created (did not exist) during init() */
- bool init(const char *dir, const char *client) {
- string path = dir;
- path += client;
- path += ".ns";
-
- bool created = !boost::filesystem::exists(path);
-
- const int LEN = 16 * 1024 * 1024;
- void *p = f.map(path.c_str(), LEN);
- if( p == 0 ) {
- problem() << "couldn't open namespace.idx " << path.c_str() << " terminating" << endl;
- exit(-3);
- }
- ht = new HashTable(p, LEN, "namespace index");
- return created;
- }
+ bool init(const char *dir, const char *database);
void add(const char *ns, DiskLoc& loc) {
Namespace n(ns);
@@ -311,18 +296,18 @@ private:
extern const char *dbpath;
-// "client.a.b.c" -> "client"
+// "database.a.b.c" -> "database"
const int MaxClientLen = 256;
-inline void nsToClient(const char *ns, char *client) {
+inline void nsToClient(const char *ns, char *database) {
const char *p = ns;
- char *q = client;
+ char *q = database;
while( *p != '.' ) {
if( *p == 0 )
break;
*q++ = *p++;
}
*q = 0;
- if(q-client>=MaxClientLen) {
+ if(q-database>=MaxClientLen) {
problem() << "nsToClient: ns too long. terminating, buf overrun condition" << endl;
dbexit(60);
}
diff --git a/db/pdfile.cpp b/db/pdfile.cpp
index 36e54addf71..ae1d936bfc4 100644
--- a/db/pdfile.cpp
+++ b/db/pdfile.cpp
@@ -21,7 +21,7 @@ todo:
_ table scans must be sequential, not next/prev pointers
_ coalesce deleted
-_ disallow system* manipulations from the client.
+_ disallow system* manipulations from the database.
*/
#include "stdafx.h"
@@ -37,8 +37,8 @@ _ disallow system* manipulations from the client.
const char *dbpath = "/data/db/";
DataFileMgr theDataFileMgr;
-map clients;
-Client *client;
+map databases;
+Database *database;
const char *curNs = "";
int MAGIC = 0x1000;
int curOp = -2;
@@ -54,9 +54,9 @@ void sayDbContext(const char *errmsg) {
if( errmsg ) {
problem() << errmsg << endl;
}
- log() << " client: " << (client ? client->name.c_str() : "null")
+ log() << " database: " << (database ? database->name.c_str() : "null")
<< " op:" << curOp << ' ' << callDepth << '\n';
- if( client )
+ if( database )
log() << " ns: " << curNs << endl;
printStackTrace();
}
@@ -116,7 +116,7 @@ bool userCreateNS(const char *ns, BSONObj& j, string& err) {
if( ies > 1024 * 1024 * 1024 + 256 ) return false;
}
- client->newestFile()->newExtent(ns, ies);
+ database->newestFile()->newExtent(ns, ies);
NamespaceDetails *d = nsdetails(ns);
assert(d);
@@ -185,7 +185,7 @@ Extent* PhysicalDataFile::newExtent(const char *ns, int approxSize, int loops) {
cout << "warning: loops=" << loops << " fileno:" << fileNo << ' ' << ns << '\n';
}
log() << "newExtent: " << ns << " file " << fileNo << " full, adding a new file\n";
- return client->addAFile()->newExtent(ns, approxSize, loops+1);
+ return database->addAFile()->newExtent(ns, approxSize, loops+1);
}
int offset = header->unused.getOfs();
header->unused.setOfs( fileNo, offset + ExtentSize );
@@ -361,12 +361,12 @@ void dropNS(string& nsToDrop) {
BSONObjBuilder b;
b.append("name", nsToDrop.c_str());
BSONObj cond = b.done(); // { name: "colltodropname" }
- string system_namespaces = client->name + ".system.namespaces";
+ string system_namespaces = database->name + ".system.namespaces";
int n = deleteObjects(system_namespaces.c_str(), cond, false, true);
wassert( n == 1 );
}
// remove from the catalog hashtable
- client->namespaceIndex.kill(nsToDrop.c_str());
+ database->namespaceIndex.kill(nsToDrop.c_str());
}
/* delete this index. does NOT clean up the system catalog
@@ -381,13 +381,13 @@ void IndexDetails::kill() {
b.append("name", indexName().c_str());
b.append("ns", parentNS().c_str());
BSONObj cond = b.done(); // e.g.: { name: "ts_1", ns: "foo.coll" }
- string system_indexes = client->name + ".system.indexes";
+ string system_indexes = database->name + ".system.indexes";
int n = deleteObjects(system_indexes.c_str(), cond, false, true);
wassert( n == 1 );
}
dropNS(ns);
- // client->namespaceIndex.kill(ns.c_str());
+ // database->namespaceIndex.kill(ns.c_str());
head.setInvalid();
info.setInvalid();
}
@@ -565,7 +565,7 @@ void DataFileMgr::update(
}
d->paddingTooSmall();
- if( client->profile )
+ if( database->profile )
ss << " moved ";
deleteRecord(ns, toupdate, dl);
insert(ns, buf, len);
@@ -615,7 +615,7 @@ void DataFileMgr::update(
problem() << " caught assertion update index " << idxns.c_str() << endl;
}
}
- if( client->profile )
+ if( database->profile )
ss << "
" << added.size() << " key updates ";
}
@@ -687,7 +687,7 @@ void ensureHaveIdIndex(const char *ns) {
d->flags |= NamespaceDetails::Flag_HaveIdIndex;
- string system_indexes = client->name + ".system.indexes";
+ string system_indexes = database->name + ".system.indexes";
BSONObjBuilder b;
b.append("name", "id_");
@@ -704,7 +704,7 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god)
const char *sys = strstr(ns, "system.");
if( sys ) {
if( sys == ns ) {
- cout << "ERROR: attempt to insert for invalid client 'system': " << ns << endl;
+ cout << "ERROR: attempt to insert for invalid database 'system': " << ns << endl;
return DiskLoc();
}
if( strstr(ns, ".system.") ) {
@@ -723,7 +723,7 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god)
/* todo: shouldn't be in the namespace catalog until after the allocations here work.
also if this is an addIndex, those checks should happen before this!
*/
- client->newestFile()->newExtent(ns, initialExtentSize(len));
+ database->newestFile()->newExtent(ns, initialExtentSize(len));
d = nsdetails(ns);
}
d->paddingFits();
@@ -736,7 +736,7 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god)
const char *name = io.getStringField("name"); // name of the index
tabletoidxns = io.getStringField("ns"); // table it indexes
- if( client->name != nsToClient(tabletoidxns.c_str()) ) {
+ if( database->name != nsToClient(tabletoidxns.c_str()) ) {
uassert("bad table to index name on add index attempt", false);
return DiskLoc();
}
@@ -770,7 +770,7 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god)
}
//indexFullNS = tabletoidxns;
//indexFullNS += ".$";
- //indexFullNS += name; // client.table.$index -- note this doesn't contain jsobjs, it contains BtreeBuckets.
+ //indexFullNS += name; // database.table.$index -- note this doesn't contain jsobjs, it contains BtreeBuckets.
}
DiskLoc extentLoc;
@@ -787,7 +787,7 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god)
// out of space
if( d->capped == 0 ) { // size capped doesn't grow
DEV log() << "allocating new extent for " << ns << " padding:" << d->paddingFactor << endl;
- client->newestFile()->newExtent(ns, followupExtentSize(len, d->lastExtentSize));
+ database->newestFile()->newExtent(ns, followupExtentSize(len, d->lastExtentSize));
loc = d->alloc(ns, lenWHdr, extentLoc);
}
if( loc.isNull() ) {
@@ -888,15 +888,21 @@ void dropDatabase(const char *ns) {
char cl[256];
nsToClient(ns, cl);
problem() << "dropDatabase " << cl << endl;
- assert( client->name == cl );
+ assert( database->name == cl );
+
+ /* reset haveLogged in local.dbinfo */
+ if( string("local") != cl ) {
+ DBInfo i(cl);
+ i.dbDropped();
+ }
/* important: kill all open cursors on the database */
string prefix(cl);
prefix += '.';
ClientCursor::invalidate(prefix.c_str());
- clients.erase(cl);
- delete client; // closes files
- client = 0;
+ databases.erase(cl);
+ delete database; // closes files
+ database = 0;
_deleteDataFiles(cl);
}
diff --git a/db/pdfile.h b/db/pdfile.h
index 7bd4e5a5bed..caecee0a251 100644
--- a/db/pdfile.h
+++ b/db/pdfile.h
@@ -17,9 +17,9 @@
/* pdfile.h
Files:
- client.ns - namespace index
- client.1 - data files
- client.2
+ database.ns - namespace index
+ database.1 - data files
+ database.2
...
*/
@@ -307,106 +307,11 @@ inline BtreeBucket* DiskLoc::btree() const {
/*---------------------------------------------------------------------*/
-// A Client is a psuedonym for a database.
-
#include "queryoptimizer.h"
+#include "database.h"
-class Client {
-public:
- Client(const char *nm, bool& justCreated) : name(nm) {
- justCreated = namespaceIndex.init(dbpath, nm);
- profile = 0;
- profileName = name + ".system.profile";
- }
- ~Client() {
- int n = files.size();
- for( int i = 0; i < n; i++ )
- delete files[i];
- }
-
- PhysicalDataFile* getFile(int n) {
- assert(this);
-
- if( n < 0 || n >= DiskLoc::MaxFiles ) {
- cout << "getFile(): n=" << n << endl;
- assert( n >= 0 && n < DiskLoc::MaxFiles );
- }
- DEV {
- if( n > 100 )
- cout << "getFile(): n=" << n << "?" << endl;
- }
- while( n >= (int) files.size() )
- files.push_back(0);
- PhysicalDataFile* p = files[n];
- if( p == 0 ) {
- p = new PhysicalDataFile(n);
- files[n] = p;
- stringstream out;
- out << dbpath << name << '.' << n;
- p->open(n, out.str().c_str());
- }
- return p;
- }
-
- PhysicalDataFile* addAFile() {
- int n = (int) files.size();
- return getFile(n);
- }
-
- PhysicalDataFile* newestFile() {
- int n = (int) files.size();
- if( n > 0 ) n--;
- return getFile(n);
- }
-
- vector files;
- string name; // "alleyinsider"
- NamespaceIndex namespaceIndex;
- int profile; // 0=off.
- string profileName; // "alleyinsider.system.profile"
- QueryOptimizer optimizer;
-};
-
-// tempish...move to TLS or pass all the way down as a parm
-extern map clients;
-extern Client *client;
-extern const char *curNs;
-extern int dbLocked;
-/* returns true if the database ("client") did not exist, and it was created on this call */
-inline bool setClient(const char *ns) {
- /* we must be in critical section at this point as these are global
- variables.
- */
- assert( dbLocked == 1 );
-
- char cl[256];
- curNs = ns;
- nsToClient(ns, cl);
- map::iterator it = clients.find(cl);
- if( it != clients.end() ) {
- client = it->second;
- return false;
- }
- log() << "first operation for database " << cl << endl;
- bool justCreated;
- Client *c = new Client(cl, justCreated);
- clients[cl] = c;
- client = c;
- return justCreated;
-}
-
-/* We normally keep around a curNs ptr -- if this ns is temporary,
- use this instead so we don't have a bad ptr. we could have made a copy,
- but trying to be fast as we call setClient this for every single operation.
-*/
-inline bool setClientTempNs(const char *ns) {
- bool jc = setClient(ns);
- curNs = "";
- return jc;
-}
-
-inline void _deleteDataFiles(const char *client) {
- string c = client;
+inline void _deleteDataFiles(const char *database) {
+ string c = database;
c += '.';
boost::filesystem::path p(dbpath);
boost::filesystem::path q;
@@ -436,14 +341,14 @@ inline NamespaceIndex* nsindex(const char *ns) {
DEV {
char buf[256];
nsToClient(ns, buf);
- if( client->name != buf ) {
- cout << "ERROR: attempt to write to wrong database client\n";
+ if( database->name != buf ) {
+ cout << "ERROR: attempt to write to wrong database database\n";
cout << " ns:" << ns << '\n';
- cout << " client->name:" << client->name << endl;
- assert( client->name == buf );
+ cout << " database->name:" << database->name << endl;
+ assert( database->name == buf );
}
}
- return &client->namespaceIndex;
+ return &database->namespaceIndex;
}
inline NamespaceDetails* nsdetails(const char *ns) {
@@ -452,15 +357,15 @@ inline NamespaceDetails* nsdetails(const char *ns) {
inline PhysicalDataFile& DiskLoc::pdf() const {
assert( fileNo != -1 );
- return *client->getFile(fileNo);
+ return *database->getFile(fileNo);
}
inline Extent* DataFileMgr::getExtent(const DiskLoc& dl) {
assert( dl.a() != -1 );
- return client->getFile(dl.a())->getExtent(dl);
+ return database->getFile(dl.a())->getExtent(dl);
}
inline Record* DataFileMgr::getRecord(const DiskLoc& dl) {
assert( dl.a() != -1 );
- return client->getFile(dl.a())->recordAt(dl);
+ return database->getFile(dl.a())->recordAt(dl);
}
diff --git a/db/query.cpp b/db/query.cpp
index cf9af2a545b..f6d1d743180 100644
--- a/db/query.cpp
+++ b/db/query.cpp
@@ -210,7 +210,7 @@ fail:
return auto_ptr();
}
-/* ns: namespace, e.g. .
+/* ns: namespace, e.g. .
pattern: the "where" clause / criteria
justOne: stop after 1 match
*/
@@ -354,7 +354,7 @@ int _updateObjects(const char *ns, BSONObj updateobj, BSONObj pattern, bool upse
//cout << "TEMP BAD";
//lrutest.find(updateobj);
- int profile = client->profile;
+ int profile = database->profile;
// cout << "update ns:" << ns << " objsize:" << updateobj.objsize() << " queryobjsize:" <<
// pattern.objsize();
@@ -783,11 +783,11 @@ QueryResult* runQuery(Message& message, const char *ns, int ntoskip, int _ntoret
b.decouple();
int duration = t.millis();
- if( (client && client->profile) || duration >= 100 ) {
+ if( (database && database->profile) || duration >= 100 ) {
ss << " nscanned:" << nscanned << ' ';
if( ntoskip )
ss << " ntoskip:" << ntoskip;
- if( client && client->profile )
+ if( database && database->profile )
ss << "
query: ";
ss << jsobj.toString() << ' ';
}
diff --git a/db/queryoptimizer.h b/db/queryoptimizer.h
index d1aeeddbc57..40fca9e5ea1 100644
--- a/db/queryoptimizer.h
+++ b/db/queryoptimizer.h
@@ -36,7 +36,7 @@ public:
bool simpleKeyMatch;
};
-/* We put these objects inside the Client objects: that way later if we want to do
+/* We put these objects inside the Database objects: that way later if we want to do
stats, it's in the right place.
*/
class QueryOptimizer {
diff --git a/db/repl.cpp b/db/repl.cpp
index 2b3b17739d9..e54d2b688d2 100644
--- a/db/repl.cpp
+++ b/db/repl.cpp
@@ -296,7 +296,7 @@ void ReplSource::save() {
setClient("local.sources");
int u = _updateObjects("local.sources", o, pattern, true/*upsert for pair feature*/, ss);
assert( u == 1 || u == 4 );
- client = 0;
+ database = 0;
}
void ReplSource::cleanup(vector& v) {
@@ -366,7 +366,7 @@ void ReplSource::loadAll(vector& v) {
addSourceToList(v, tmp, old);
c->advance();
}
- client = 0;
+ database = 0;
if( !gotPairWith && replPair ) {
/* add the --pairwith server */
@@ -386,7 +386,7 @@ bool ReplSource::resync(string db) {
{
log() << "resync: dropping database " << db << endl;
string dummyns = db + ".";
- assert( client->name == db );
+ assert( database->name == db );
dropDatabase(dummyns.c_str());
setClientTempNs(dummyns.c_str());
}
@@ -395,7 +395,7 @@ bool ReplSource::resync(string db) {
log() << "resync: cloning database " << db << endl;
//Cloner c;
string errmsg;
- bool ok = cloneFrom(hostName.c_str(), errmsg, client->name);
+ bool ok = cloneFrom(hostName.c_str(), errmsg, database->name);
//bool ok = c.go(hostName.c_str(), errmsg);
if( !ok ) {
problem() << "resync of " << db << " from " << hostName << " failed " << errmsg << endl;
@@ -439,8 +439,10 @@ void ReplSource::sync_pullOpLog_applyOperation(BSONObj& op) {
dblock lk;
bool justCreated = setClientTempNs(ns);
- if( allDead )
+ if( allDead ) {
+ log() << "allDead, throwing SyncException\n";
throw SyncException();
+ }
// operation type -- see logOp() comments for types
const char *opType = op.getStringField("op");
@@ -448,7 +450,15 @@ void ReplSource::sync_pullOpLog_applyOperation(BSONObj& op) {
if( justCreated || /* datafiles were missing. so we need everything, no matter what sources object says */
newDb ) /* if not in dbs, we've never synced this database before, so we need everything */
{
- if( paired && !justCreated ) {
+ if( op.getBoolField("first") ) {
+ log() << "pull: got {first:true} op ns:" << ns << '\n';
+ /* this is the first thing in the oplog ever, so we don't need to resync(). */
+ if( newDb )
+ dbs.insert(clientName);
+ else
+ problem() << "warning: justCreated && !newDb in repl " << op.toString() << endl;
+ }
+ else if( paired && !justCreated ) {
if( strcmp(opType,"db") == 0 && strcmp(ns, "admin.") == 0 ) {
// "admin" is a special namespace we use for priviledged commands -- ok if it exists first on
// either side
@@ -469,7 +479,7 @@ void ReplSource::sync_pullOpLog_applyOperation(BSONObj& op) {
}
else {
nClonedThisPass++;
- resync(client->name);
+ resync(database->name);
}
addDbNextPass.erase(clientName);
}
@@ -518,7 +528,7 @@ void ReplSource::sync_pullOpLog_applyOperation(BSONObj& op) {
catch( UserAssertionException& e ) {
log() << "sync: caught user assertion " << e.msg << '\n';
}
- client = 0;
+ database = 0;
}
/* note: not yet in mutex at this point. */
@@ -701,7 +711,7 @@ bool ReplSource::sync() {
// cached copies of these...
NamespaceDetails *localOplogMainDetails = 0;
-Client *localOplogClient = 0;
+Database *localOplogClient = 0;
/* we write to local.opload.$main:
{ ts : ..., op: ..., ns: ..., o: ... }
@@ -715,18 +725,16 @@ Client *localOplogClient = 0;
bb:
if not null, specifies a boolean to pass along to the other side as b: param.
used for "justOne" or "upsert" flags on 'd', 'u'
+ first: true
+ when set, indicates this is the first thing we have logged for this database.
+ thus, the slave does not need to copy down all the data when it sees this.
*/
void _logOp(const char *opstr, const char *ns, BSONObj& obj, BSONObj *o2, bool *bb) {
if( strncmp(ns, "local.", 6) == 0 )
return;
- Client *oldClient = client;
- if( localOplogMainDetails == 0 ) {
- setClientTempNs("local.");
- localOplogClient = client;
- localOplogMainDetails = nsdetails("local.oplog.$main");
- }
- client = localOplogClient;
+ Database *oldClient = database;
+ bool haveLogged = database && database->haveLogged();
/* 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.
@@ -740,10 +748,22 @@ void _logOp(const char *opstr, const char *ns, BSONObj& obj, BSONObj *o2, bool *
b.appendBool("b", *bb);
if( o2 )
b.append("o2", *o2);
+ if( !haveLogged ) {
+ b.appendBool("first", true);
+ if( database ) // null on dropDatabase()'s logging.
+ database->setHaveLogged();
+ }
BSONObj partial = b.done();
int posz = partial.objsize();
int len = posz + obj.objsize() + 1 + 2 /*o:*/;
+ if( localOplogMainDetails == 0 ) {
+ setClientTempNs("local.");
+ localOplogClient = database;
+ localOplogMainDetails = nsdetails("local.oplog.$main");
+ }
+ database = localOplogClient;
+
Record *r = theDataFileMgr.fast_oplog_insert(localOplogMainDetails, "local.oplog.$main", len);
char *p = r->data;
@@ -757,7 +777,10 @@ void _logOp(const char *opstr, const char *ns, BSONObj& obj, BSONObj *o2, bool *
p += obj.objsize();
*p = EOO;
- client = oldClient;
+ //BSONObj temp(r);
+ //cout << "temp:" << temp.toString() << endl;
+
+ database = oldClient;
}
/* --------------------------------------------------------------*/
@@ -849,11 +872,14 @@ void logOurDbsPresence() {
*/
string dbname = string(f.c_str(), f.size() - 2);
if( dbname != "local." ) {
+ setClientTempNs(dbname.c_str());
logOp("db", dbname.c_str(), emptyObj);
}
}
i++;
}
+
+ database = 0;
}
/* we have to log the db presence periodically as that "advertisement" will roll out of the log
@@ -863,6 +889,14 @@ void logOurDbsPresence() {
*/
void replMasterThread() {
sleepsecs(15);
+ logOurDbsPresence();
+
+ // if you are testing, you might finish test and shutdown in less than 10
+ // minutes yet not have done something in first 15 -- this is to exercise
+ // this code some.
+ sleepsecs(90);
+ logOurDbsPresence();
+
while( 1 ) {
logOurDbsPresence();
sleepsecs(60 * 10);
@@ -891,7 +925,7 @@ void startReplication() {
string err;
BSONObj o = b.done();
userCreateNS("local.oplog.$main", o, err);
- client = 0;
+ database = 0;
}
boost::thread mt(replMasterThread);
diff --git a/db/replset.h b/db/replset.h
index 28a6175f0ec..fff28122036 100644
--- a/db/replset.h
+++ b/db/replset.h
@@ -46,20 +46,20 @@ public:
int remotePort;
string remoteHost;
string remote; // host:port if port specified.
- int date; // -1 not yet set; 0=slave; 1=master
+// int date; // -1 not yet set; 0=slave; 1=master
string getInfo() {
stringstream ss;
ss << " state: ";
- if( state == 1 ) ss << "1 State_Master";
- else if( state == 0 ) ss << "- State_Slave";
+ if( state == 1 ) ss << "1 State_Master ";
+ else if( state == 0 ) ss << "0 State_Slave";
else
ss << "" << state << "";
ss << '\n';
ss << " info: " << info << '\n';
ss << " arbhost: " << arbHost << '\n';
ss << " remote: " << remoteHost << ':' << remotePort << '\n';
- ss << " date: " << date << '\n';
+// ss << " date: " << date << '\n';
return ss.str();
}
@@ -98,13 +98,13 @@ extern ReplPair *replPair;
*/
inline bool isMaster() {
if( allDead ) {
- return client->name == "local";
+ return database->name == "local";
}
if( replPair == 0 || replPair->state == ReplPair::State_Master )
return true;
- return client->name == "local";
+ return database->name == "local";
}
inline ReplPair::ReplPair(const char *remoteEnd, const char *arb) {
diff --git a/dbgrid/dbgrid.cpp b/dbgrid/dbgrid.cpp
index 120291bee8e..479e4e1cf6e 100644
--- a/dbgrid/dbgrid.cpp
+++ b/dbgrid/dbgrid.cpp
@@ -25,7 +25,7 @@
string dashDashGridDb;
int port = 27017;
const char *curNs = "";
-Client *client = 0;
+Database *database = 0;
/* this is a good place to set a breakpoint when debugging, as lots of warning things
(assert, wassert) call it.
diff --git a/dbgrid/gridconfig.cpp b/dbgrid/gridconfig.cpp
index 57ca10a603e..63fa8cf45cd 100644
--- a/dbgrid/gridconfig.cpp
+++ b/dbgrid/gridconfig.cpp
@@ -33,12 +33,12 @@ map Machine::machines;
//static boost::mutex loc_mutex;
Grid grid;
-ClientConfig* GridConfig::getClientConfig(string client) {
- ClientConfig*& cc = clients[client];
+ClientConfig* GridConfig::getClientConfig(string database) {
+ ClientConfig*& cc = databases[database];
if( cc == 0 ) {
cc = new ClientConfig();
- if( !cc->loadByName(client.c_str()) ) {
- log() << "couldn't find client " << client << " in grid db" << endl;
+ if( !cc->loadByName(database.c_str()) ) {
+ log() << "couldn't find database " << database << " in grid db" << endl;
// note here that cc->primary == 0.
}
}
diff --git a/dbgrid/gridconfig.h b/dbgrid/gridconfig.h
index 128752087ab..00ae49b41d7 100644
--- a/dbgrid/gridconfig.h
+++ b/dbgrid/gridconfig.h
@@ -60,7 +60,7 @@ public:
ClientConfig() : primary(0), partitioned(false) { }
- virtual const char * getNS() { return "grid.db.client"; }
+ virtual const char * getNS() { return "grid.db.database"; }
virtual void serialize(BSONObjBuilder& to) {
to.append("name", name);
to.appendBool("partitioned", partitioned);
@@ -84,9 +84,9 @@ public:
};
class GridConfig {
- map clients;
+ map databases;
public:
- ClientConfig* getClientConfig(string client);
+ ClientConfig* getClientConfig(string database);
};
class Grid {
diff --git a/dbgrid/griddatabase.h b/dbgrid/griddatabase.h
index 85d29443c3e..f8d95f437b0 100644
--- a/dbgrid/griddatabase.h
+++ b/dbgrid/griddatabase.h
@@ -2,7 +2,7 @@
The grid database is where we get:
- name of each shard
- - "home" shard for each client
+ - "home" shard for each database
*/
/**
diff --git a/dbgrid/request.cpp b/dbgrid/request.cpp
index 79c58a11744..d105daacfa6 100644
--- a/dbgrid/request.cpp
+++ b/dbgrid/request.cpp
@@ -61,7 +61,7 @@ void getMore(Message& m, MessagingPort& p) {
bool runCommandAgainstRegistered(const char *ns, BSONObj& jsobj, BSONObjBuilder& anObjBuilder);
-/* got query operation from a client */
+/* got query operation from a database */
void queryOp(Message& m, MessagingPort& p) {
DbMessage d(m);
QueryMessage q(d);
diff --git a/grid/message.cpp b/grid/message.cpp
index eb58346ff04..687090f12a6 100644
--- a/grid/message.cpp
+++ b/grid/message.cpp
@@ -195,7 +195,7 @@ again:
if( len < 0 || len > 16000000 ) {
if( len == 0xffffffff ) {
- // Endian check from the client, after connecting, to see what mode server is running in.
+ // Endian check from the database, after connecting, to see what mode server is running in.
unsigned foo = 0x10203040;
int x = ::send(sock, (char *) &foo, 4, 0);
if( x <= 0 ) {
diff --git a/pcre-7.4/pcre.h b/pcre-7.4/pcre.h
index 58a83c369a6..ecc0f8db323 100644
--- a/pcre-7.4/pcre.h
+++ b/pcre-7.4/pcre.h
@@ -221,7 +221,7 @@ typedef struct pcre_extra {
/* The structure for passing out data via the pcre_callout_function. We use a
structure so that new fields can be added on the end in future versions,
-without changing the API of the function, thereby allowing old clients to work
+without changing the API of the function, thereby allowing old databases to work
without modification. */
typedef struct pcre_callout_block {
diff --git a/stdafx.h b/stdafx.h
index 41bfad1ec2b..909f6b092ed 100644
--- a/stdafx.h
+++ b/stdafx.h
@@ -162,8 +162,8 @@ typedef struct _OWS {
char string[400];
} *OWS;
-class Client;
-extern Client *client;
+class Database;
+extern Database *database;
extern const char *curNs;
/* for now, running on win32 means development not production --
diff --git a/util/log.h b/util/log.h
index 4c7941d3812..b552cc1ae3b 100644
--- a/util/log.h
+++ b/util/log.h
@@ -58,7 +58,7 @@ public:
time(&t);
string now(ctime(&t),0,20);
cout << now;
- if( withNs && client )
+ if( withNs && database )
cout << curNs << ' ';
return *this;
}