diff options
-rw-r--r-- | db/cloner.cpp | 63 | ||||
-rw-r--r-- | db/commands.cpp | 2 | ||||
-rw-r--r-- | db/jsobj.h | 17 | ||||
-rw-r--r-- | db/namespace.h | 6 | ||||
-rw-r--r-- | db/pdfile.cpp | 24 | ||||
-rw-r--r-- | dbgrid/database.h | 2 | ||||
-rw-r--r-- | dbgrid/request.cpp | 2 |
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. |