summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDwight <dmerriman@gmail.com>2008-09-12 15:00:20 -0400
committerDwight <dmerriman@gmail.com>2008-09-12 15:00:20 -0400
commit3332989338a5815c30a039213bf2e4581759e8c8 (patch)
treea4d4ec9fc7ff17d1230c97ba1350b1960171a0c5
parent18e7e1fa40da60fe6670123c86e6eedc8bdc1dfb (diff)
downloadmongo-3332989338a5815c30a039213bf2e4581759e8c8.tar.gz
copydb - not yet done
-rw-r--r--db/cloner.cpp75
-rw-r--r--db/dbclient.h1
-rw-r--r--db/makefile2
-rw-r--r--db/pdfile.h3
-rw-r--r--db/repl.cpp3
-rw-r--r--db/repl.h2
-rw-r--r--dbgrid/dbgrid.cpp47
-rw-r--r--dbgrid/dbgrid.vcproj12
8 files changed, 121 insertions, 24 deletions
diff --git a/db/cloner.cpp b/db/cloner.cpp
index 9ce0eb7d0e3..cf2699a6295 100644
--- a/db/cloner.cpp
+++ b/db/cloner.cpp
@@ -29,34 +29,39 @@ bool userCreateNS(const char *ns, JSObj& j, string& err);
class Cloner: boost::noncopyable {
DBClientConnection conn;
- void copy(const char *collection);
+ void copy(const char *from_ns, const char *to_ns);
public:
Cloner() { }
- bool go(const char *masterHost, string& errmsg);
+ bool go(const char *masterHost, string& errmsg, const string& fromdb);
};
-void Cloner::copy(const char *collection) {
- auto_ptr<DBClientCursor> c( conn.query(collection, emptyObj) );
+void Cloner::copy(const char *from_collection, const char *to_collection) {
+ auto_ptr<DBClientCursor> c( conn.query(from_collection, emptyObj) );
assert( c.get() );
while( c->more() ) {
JSObj js = c->next();
- theDataFileMgr.insert(collection, (void*) js.objdata(), js.objsize());
+ theDataFileMgr.insert(to_collection, (void*) js.objdata(), js.objsize());
}
}
-bool Cloner::go(const char *masterHost, string& errmsg) {
+bool Cloner::go(const char *masterHost, string& errmsg, const string& fromdb) {
+ string todb = client->name;
if( (string("localhost") == masterHost || string("127.0.0.1") == masterHost) && port == DBPort ) {
- errmsg = "can't clone from self (localhost). sources configuration may be wrong.";
- return false;
+ if( fromdb == todb ) {
+ // 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).";
+ return false;
+ }
}
if( !conn.connect(masterHost, errmsg) )
return false;
- string ns = client->name + ".system.namespaces";
+ string ns = fromdb + ".system.namespaces";
auto_ptr<DBClientCursor> c( conn.query(ns.c_str(), emptyObj) );
if( c.get() == 0 ) {
- errmsg = "query failed system.namespaces";
+ errmsg = "query failed " + ns;
return false;
}
@@ -65,30 +70,38 @@ bool Cloner::go(const char *masterHost, string& errmsg) {
Element e = collection.findElement("name");
assert( !e.eoo() );
assert( e.type() == String );
- const char *name = e.valuestr();
- if( strstr(name, ".system.") || strchr(name, '$') )
+ const char *from_name = e.valuestr();
+ if( strstr(from_name, ".system.") || strchr(from_name, '$') )
continue;
JSObj options = collection.getObjectField("options");
+ /* change name "<fromdb>.collection" -> <todb>.collection */
+ const char *p = strchr(from_name, '.');
+ assert(p);
+ string to_name = todb + p;
if( !options.isEmpty() ) {
string err;
- userCreateNS(name, options, err);
+ userCreateNS(to_name.c_str(), options, err);
}
- copy(name);
+ copy(from_name, to_name.c_str());
}
// now build the indexes
- string system_indexes = client->name + ".system.indexes";
- copy(system_indexes.c_str());
+ string system_indexes_from = fromdb + ".system.indexes";
+ string system_indexes_to = todb + ".system.indexes";
+ copy(system_indexes_from.c_str(), system_indexes_to.c_str());
return true;
}
-bool cloneFrom(const char *masterHost, string& errmsg)
+bool cloneFrom(const char *masterHost, string& errmsg, const string& fromdb)
{
Cloner c;
- return c.go(masterHost, errmsg);
+ return c.go(masterHost, errmsg, fromdb);
}
+/* Usage:
+ mydb.$cmd.findOne( { clone: "fromhost" } );
+*/
class CmdClone : public Command {
public:
CmdClone() : Command("clone") { }
@@ -97,7 +110,31 @@ public:
string from = cmdObj.getStringField("clone");
if( from.empty() )
return false;
- return cloneFrom(from.c_str(), errmsg);
+ return cloneFrom(from.c_str(), errmsg, client->name);
}
} cmdclone;
+/* Usage:
+ admindb.$cmd.findOne( { copydb: 1, fromhost: <hostname>, fromdb: <db>, todb: <db> } );
+*/
+class CmdCopyDb : public Command {
+public:
+ CmdCopyDb() : Command("copydb") { }
+ virtual bool adminOnly() { return true; }
+
+ virtual bool run(const char *ns, JSObj& cmdObj, string& errmsg, JSObjBuilder& result) {
+ string fromhost = cmdObj.getStringField("fromhost");
+ string fromdb = cmdObj.getStringField("fromdb");
+ string todb = cmdObj.getStringField("todb");
+ if( fromhost.empty() || todb.empty() || fromdb.empty() ) {
+ errmsg = "parms missing - {copydb: 1, fromhost: <hostname>, fromdb: <db>, todb: <db>}";
+ return false;
+ }
+ string temp = todb + ".";
+ setClient(temp.c_str());
+ bool res = cloneFrom(fromhost.c_str(), errmsg, fromdb);
+ client = 0;
+ return res;
+ }
+} cmdcopydb;
+
diff --git a/db/dbclient.h b/db/dbclient.h
index d02dabc4d2b..3af4f544452 100644
--- a/db/dbclient.h
+++ b/db/dbclient.h
@@ -19,6 +19,7 @@
#pragma once
#include "../grid/message.h"
+#include "jsobj.h"
/* the query field 'options' can have these bits set: */
enum {
diff --git a/db/makefile b/db/makefile
index 89c6a590197..44adbad76cd 100644
--- a/db/makefile
+++ b/db/makefile
@@ -12,7 +12,7 @@ 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 dbclient.o btreecursor.o cloner.o namespace.o commands.o matcher.o
-DBGRID_OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/util.o jsobj.o dbclient.o ../dbgrid/dbgrid.o
+DBGRID_OBJS=../stdafx.o ../util/sock.o ../grid/message.o ../util/util.o jsobj.o dbclient.o ../dbgrid/dbgrid.o ../dbgrid/request.o ../dbgrid/database.o
GPP = g++
diff --git a/db/pdfile.h b/db/pdfile.h
index b97bb997e17..d0fb8dfc9ad 100644
--- a/db/pdfile.h
+++ b/db/pdfile.h
@@ -391,7 +391,8 @@ inline bool setClient(const char *ns) {
client = c;
return justCreated;
}
-/* we normally keep around a curNs ptr -- if this ns is temporary,
+
+/* 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.
*/
diff --git a/db/repl.cpp b/db/repl.cpp
index b5c456afbd6..23d07b0de26 100644
--- a/db/repl.cpp
+++ b/db/repl.cpp
@@ -40,7 +40,6 @@ auto_ptr<Cursor> findTableScan(const char *ns, JSObj& order);
bool userCreateNS(const char *ns, JSObj& j, string& err);
int _updateObjects(const char *ns, JSObj updateobj, JSObj pattern, bool upsert, stringstream& ss, bool logOp=false);
bool _runCommands(const char *ns, JSObj& jsobj, stringstream& ss, BufBuilder &b, JSObjBuilder& anObjBuilder);
-bool cloneFrom(const char *masterHost, string& errmsg);
void ensureHaveIdIndex(const char *ns);
#include "replset.h"
@@ -345,7 +344,7 @@ bool ReplSource::resync(string db) {
log() << "resync: cloning database " << db << endl;
//Cloner c;
string errmsg;
- bool ok = cloneFrom(hostName.c_str(), errmsg);
+ bool ok = cloneFrom(hostName.c_str(), errmsg, client->name);
//bool ok = c.go(hostName.c_str(), errmsg);
if( !ok ) {
problem() << "resync of " << db << " from " << hostName << " failed " << errmsg << endl;
diff --git a/db/repl.h b/db/repl.h
index 221c7c57b9e..d5d0763c369 100644
--- a/db/repl.h
+++ b/db/repl.h
@@ -33,7 +33,7 @@ class DBClientCursor;
extern bool slave;
extern bool master;
-bool cloneFrom(const char *masterHost, string& errmsg);
+bool cloneFrom(const char *masterHost, string& errmsg, const string& fromdb);
#pragma pack(push,4)
class OpTime {
diff --git a/dbgrid/dbgrid.cpp b/dbgrid/dbgrid.cpp
index 5efaa19c803..42e986beb5b 100644
--- a/dbgrid/dbgrid.cpp
+++ b/dbgrid/dbgrid.cpp
@@ -17,7 +17,9 @@
*/
#include "stdafx.h"
+#include "../grid/message.h"
#include "../util/unittest.h"
+#include "database.h"
const char *curNs = "";
Client *client = 0;
@@ -50,8 +52,53 @@ void usage() {
}
int port = 0;
+MessagingPort *grab = 0;
+void processRequest(Message&, MessagingPort&);
+
+void _dbGridConnThread() {
+ MessagingPort& dbMsgPort = *grab;
+ grab = 0;
+ Message m;
+ while( 1 ) {
+ m.reset();
+
+ if( !dbMsgPort.recv(m) ) {
+ log() << "end connection " << dbMsgPort.farEnd.toString() << endl;
+ dbMsgPort.shutdown();
+ break;
+ }
+
+ processRequest(m, dbMsgPort);
+ }
+
+}
+
+void dbGridConnThread() {
+ try {
+ _dbGridConnThread();
+ } catch( ... ) {
+ problem() << "uncaught exception in dbgridconnthread, terminating" << endl;
+ dbexit(15);
+ }
+}
+
+class DbGridListener : public Listener {
+public:
+ DbGridListener(int p) : Listener(p) { }
+ virtual void accepted(MessagingPort *mp) {
+ assert( grab == 0 );
+ grab = mp;
+ boost::thread thr(dbGridConnThread);
+ while( grab )
+ sleepmillis(1);
+ }
+};
void start() {
+ Database::load();
+ log() << "waiting for connections on port " << port << "..." << endl;
+ DbGridListener l(port);
+ l.listen();
}
int main(int argc, char* argv[], char *envp[] ) {
diff --git a/dbgrid/dbgrid.vcproj b/dbgrid/dbgrid.vcproj
index 9355686e9c9..99da4d063b7 100644
--- a/dbgrid/dbgrid.vcproj
+++ b/dbgrid/dbgrid.vcproj
@@ -174,9 +174,17 @@
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
+ RelativePath=".\database.cpp"
+ >
+ </File>
+ <File
RelativePath=".\dbgrid.cpp"
>
</File>
+ <File
+ RelativePath=".\request.cpp"
+ >
+ </File>
</Filter>
<Filter
Name="Header Files"
@@ -184,6 +192,10 @@
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
+ RelativePath=".\database.h"
+ >
+ </File>
+ <File
RelativePath="..\util\goodies.h"
>
</File>