summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDwight <dmerriman@gmail.com>2008-09-15 15:30:53 -0400
committerDwight <dmerriman@gmail.com>2008-09-15 15:30:53 -0400
commit379a7562629ff0803cfb30e0abfcddcbee046a19 (patch)
tree3351844f2e8cf26f65af1318ee95297ac5d58345
parentf9fd02c198553a587cffbcb4a61d774d93998b38 (diff)
downloadmongo-379a7562629ff0803cfb30e0abfcddcbee046a19.tar.gz
copydb
-rw-r--r--db/cloner.cpp63
-rw-r--r--db/commands.cpp2
-rw-r--r--db/jsobj.h17
-rw-r--r--db/namespace.h6
-rw-r--r--db/pdfile.cpp24
-rw-r--r--dbgrid/database.h2
-rw-r--r--dbgrid/request.cpp2
7 files changed, 92 insertions, 24 deletions
diff --git a/db/cloner.cpp b/db/cloner.cpp
index cc1cd582dd0..8fe2b0c5f6f 100644
--- a/db/cloner.cpp
+++ b/db/cloner.cpp
@@ -30,15 +30,46 @@ bool userCreateNS(const char *ns, JSObj& j, string& err);
class Cloner: boost::noncopyable {
DBClientConnection conn;
- void copy(const char *from_ns, const char *to_ns);
+ void copy(const char *from_ns, const char *to_ns, bool isindex = false);
public:
Cloner() { }
bool go(const char *masterHost, string& errmsg, const string& fromdb);
};
-void Cloner::copy(const char *from_collection, const char *to_collection) {
-// cout << "COPY: " << from_collection << " -> " << to_collection << endl;
-// cout << " client: " << client->name << endl;
+/* for index info object:
+ { "name" : "name_1" , "ns" : "foo.index3" , "key" : { "name" : 1.0 } }
+ we need to fix up the value in the "ns" parameter.
+*/
+JSObj fixindex(JSObj o) {
+ JSObjBuilder b;
+ JSElemIter i(o);
+ while( i.more() ) {
+ Element e = i.next();
+ if( e.eoo() )
+ break;
+ if( string("ns") == e.fieldName() ) {
+ 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;
+ b.append("ns", newname);
+ }
+ else
+ b.append(e);
+ }
+ JSObj res= b.doneAndDecouple();
+
+/* if( mod ) {
+ cout << "before: " << o.toString() << endl;
+ o.dump();
+ cout << "after: " << res.toString() << endl;
+ res.dump();
+ }*/
+
+ return res;
+}
+
+void Cloner::copy(const char *from_collection, const char *to_collection, bool isindex) {
auto_ptr<DBClientCursor> c;
{
dbtemprelease r;
@@ -51,14 +82,20 @@ void Cloner::copy(const char *from_collection, const char *to_collection) {
if( !c->more() )
break;
}
- JSObj js = c->next();
+ JSObj tmp = c->next();
+ JSObj js = tmp;
+ if( isindex )
+ js = fixindex(tmp);
theDataFileMgr.insert(to_collection, (void*) js.objdata(), js.objsize());
}
}
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 ) {
+ stringstream a,b;
+ a << "localhost:" << port;
+ b << "127.0.0.1:" << port;
+ if( a.str() == masterHost || b.str() == masterHost ) {
if( fromdb == todb ) {
// guard against an "infinite" loop
/* if you are replicating, the local.sources config may be wrong if you get this */
@@ -94,18 +131,18 @@ bool Cloner::go(const char *masterHost, string& errmsg, const string& fromdb) {
assert( e.type() == String );
const char *from_name = e.valuestr();
if( strstr(from_name, ".system.") || strchr(from_name, '$') ) {
-// cout << "TEMP: skip " << from_name << endl;
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() ) {
+
+ //if( !options.isEmpty() )
{
string err;
-// cout << "TEMP: usercreatens " << to_name << " client:" << client->name << endl;
userCreateNS(to_name.c_str(), options, err);
}
copy(from_name, to_name.c_str());
@@ -114,7 +151,7 @@ bool Cloner::go(const char *masterHost, string& errmsg, const string& fromdb) {
// now build the indexes
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());
+ copy(system_indexes_from.c_str(), system_indexes_to.c_str(), true);
return true;
}
@@ -150,6 +187,12 @@ public:
virtual bool run(const char *ns, JSObj& cmdObj, string& errmsg, JSObjBuilder& result) {
string fromhost = cmdObj.getStringField("fromhost");
+ if( fromhost.empty() ) {
+ /* copy from self */
+ stringstream ss;
+ ss << "localhost:" << port;
+ fromhost = ss.str();
+ }
string fromdb = cmdObj.getStringField("fromdb");
string todb = cmdObj.getStringField("todb");
if( fromhost.empty() || todb.empty() || fromdb.empty() ) {
diff --git a/db/commands.cpp b/db/commands.cpp
index ce343e98924..89121c6e030 100644
--- a/db/commands.cpp
+++ b/db/commands.cpp
@@ -331,7 +331,7 @@ bool _runCommands(const char *ns, JSObj& jsobj, stringstream& ss, BufBuilder &b,
else if( e.type() == Number ) {
if( strcmp(e.fieldName(), "dropDatabase") == 0 ) {
if( 1 ) {
- cout << "dropDatabase " << ns << endl;
+ log() << "dropDatabase " << ns << endl;
valid = true;
int p = (int) e.number();
if( p != 1 ) {
diff --git a/db/jsobj.h b/db/jsobj.h
index a2b5e416aa5..6b328c63027 100644
--- a/db/jsobj.h
+++ b/db/jsobj.h
@@ -263,6 +263,18 @@ public:
int objsize() const { return details ? details->_objsize : 0; } // includes the embedded size field
bool isEmpty() const { return objsize() <= 5; }
+ void dump() {
+ cout << hex;
+ const char *p = objdata();
+ for( int i = 0; i < objsize(); i++ ) {
+ cout << i << '\t' << (unsigned) *p;
+ if( *p >= 'A' && *p <= 'z' )
+ cout << '\t' << *p;
+ cout << endl;
+ p++;
+ }
+ }
+
/* this is broken if elements aren't in the same order. */
bool operator<(const JSObj& r) const { return woCompare(r) < 0; }
@@ -342,7 +354,10 @@ public:
/* add all the fields from the object specified to this object */
void appendElements(JSObj x);
- void append(Element& e) { b.append((void*) e.rawdata(), e.size()); }
+ void append(Element& e) {
+ assert( !e.eoo() ); // do not append eoo, that would corrupt us. the builder auto appends when done() is called.
+ b.append((void*) e.rawdata(), e.size());
+ }
/* append an element but with a new name */
void appendAs(Element& e, const char *as) {
diff --git a/db/namespace.h b/db/namespace.h
index 96cbf3c9aa8..bc0809f05d4 100644
--- a/db/namespace.h
+++ b/db/namespace.h
@@ -315,4 +315,8 @@ inline void nsToClient(const char *ns, char *client) {
dbexit(60);
}
}
-
+inline string nsToClient(const char *ns) {
+ char buf[MaxClientLen];
+ nsToClient(ns, buf);
+ return buf;
+}
diff --git a/db/pdfile.cpp b/db/pdfile.cpp
index 9b71b73baa0..e6f8e68101f 100644
--- a/db/pdfile.cpp
+++ b/db/pdfile.cpp
@@ -705,7 +705,7 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god)
}
if( strstr(ns, ".system.") ) {
if( strstr(ns, ".system.indexes") )
- addIndex = true;
+ addIndex = true;
else if( !god ) {
cout << "ERROR: attempt to insert in system namespace " << ns << endl;
return DiskLoc();
@@ -726,27 +726,33 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god)
NamespaceDetails *tableToIndex = 0;
- const char *tabletoidxns = 0;
+ string tabletoidxns;
if( addIndex ) {
JSObj io((const char *) buf);
const char *name = io.getStringField("name"); // name of the index
tabletoidxns = io.getStringField("ns"); // table it indexes
+
+ if( client->name != nsToClient(tabletoidxns.c_str()) ) {
+ uassert("bad table to index name on add index attempt", false);
+ return DiskLoc();
+ }
+
JSObj key = io.getObjectField("key");
- if( *name == 0 || *tabletoidxns == 0 || key.isEmpty() || key.objsize() > 2048 ) {
+ if( *name == 0 || tabletoidxns.empty() || key.isEmpty() || key.objsize() > 2048 ) {
cout << "user warning: bad add index attempt name:" << (name?name:"") << "\n ns:" <<
- (tabletoidxns?tabletoidxns:"") << "\n ourns:" << ns;
+ tabletoidxns << "\n ourns:" << ns;
cout << "\n idxobj:" << io.toString() << endl;
return DiskLoc();
}
- tableToIndex = nsdetails(tabletoidxns);
+ tableToIndex = nsdetails(tabletoidxns.c_str());
if( tableToIndex == 0 ) {
// try to create it
string err;
- if( !userCreateNS(tabletoidxns, emptyObj, err) ) {
+ if( !userCreateNS(tabletoidxns.c_str(), emptyObj, err) ) {
problem() << "ERROR: failed to create collection while adding its index. " << tabletoidxns << endl;
return DiskLoc();
}
- tableToIndex = nsdetails(tabletoidxns);
+ tableToIndex = nsdetails(tabletoidxns.c_str());
log() << "info: creating collection " << tabletoidxns << " on add index\n";
assert( tableToIndex );
}
@@ -811,9 +817,9 @@ DiskLoc DataFileMgr::insert(const char *ns, const void *buf, int len, bool god)
IndexDetails& idxinfo = tableToIndex->indexes[tableToIndex->nIndexes];
idxinfo.info = loc;
idxinfo.head = BtreeBucket::addHead(idxinfo);
- tableToIndex->addingIndex(tabletoidxns, idxinfo);
+ tableToIndex->addingIndex(tabletoidxns.c_str(), idxinfo);
/* todo: index existing records here */
- addExistingToIndex(tabletoidxns, idxinfo);
+ addExistingToIndex(tabletoidxns.c_str(), idxinfo);
}
/* add this record to our indexes */
diff --git a/dbgrid/database.h b/dbgrid/database.h
index 85492ba3c71..c9b768b4021 100644
--- a/dbgrid/database.h
+++ b/dbgrid/database.h
@@ -1,4 +1,4 @@
-// database.h
+// cbgrid/database.h
/* we create a database object for each client database
*/
diff --git a/dbgrid/request.cpp b/dbgrid/request.cpp
index cd1b7bc8580..62b6f5bd38e 100644
--- a/dbgrid/request.cpp
+++ b/dbgrid/request.cpp
@@ -1,4 +1,4 @@
-// request.cpp
+// dbgrid/request.cpp
/**
* Copyright (C) 2008 10gen Inc.