summaryrefslogtreecommitdiff
path: root/src/mongo/db/cloner.cpp
diff options
context:
space:
mode:
authorJames Wahlin <james.wahlin@10gen.com>2016-08-30 16:57:35 -0400
committerJames Wahlin <james.wahlin@10gen.com>2016-08-31 19:00:59 -0400
commitbbc9748b355ae0ac07d6ac37db757712bc35af43 (patch)
tree770c7d6f0c71d2c515e4f0a1c2e7ca371776c803 /src/mongo/db/cloner.cpp
parentf5c9d27ca6f0f4e1e2673c64b84b628ac29493ec (diff)
downloadmongo-bbc9748b355ae0ac07d6ac37db757712bc35af43.tar.gz
SERVER-25796 copydb support for views + additional cloner tests
Diffstat (limited to 'src/mongo/db/cloner.cpp')
-rw-r--r--src/mongo/db/cloner.cpp35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/mongo/db/cloner.cpp b/src/mongo/db/cloner.cpp
index 3ea687fdd5d..9afef63d2e4 100644
--- a/src/mongo/db/cloner.cpp
+++ b/src/mongo/db/cloner.cpp
@@ -155,6 +155,8 @@ struct Cloner::Fun {
MONGO_WRITE_CONFLICT_RETRY_LOOP_END(txn, "createCollection", to_collection.ns());
}
+ const bool isSystemViewsClone = to_collection.isSystemDotViews();
+
while (i.moreInCurrentBatch()) {
if (numSeen % 128 == 127) {
time_t now = time(0);
@@ -198,6 +200,23 @@ struct Cloner::Fun {
BSONObj tmp = i.nextSafe();
+ // If copying the system.views collection to a database with a different name, then any
+ // view definitions must be modified to refer to the 'to' database.
+ if (isSystemViewsClone && from_collection.db() != to_collection.db()) {
+ BSONObjBuilder bob;
+ for (auto&& item : tmp) {
+ if (item.fieldNameStringData() == "_id") {
+ auto viewNss = NamespaceString(item.checkAndGetStringData());
+
+ bob.append("_id",
+ NamespaceString(to_collection.db(), viewNss.coll()).toString());
+ } else {
+ bob.append(item);
+ }
+ }
+ tmp = bob.obj();
+ }
+
/* assure object is valid. note this will slow us down a little. */
const Status status = validateBSON(tmp.objdata(), tmp.objsize());
if (!status.isOK()) {
@@ -396,6 +415,22 @@ bool Cloner::copyCollection(OperationContext* txn,
if (!collList.empty()) {
invariant(collList.size() <= 1);
BSONObj col = collList.front();
+
+ // Confirm that 'col' is not a view.
+ {
+ std::string namespaceType;
+ auto status = bsonExtractStringField(col, "type", &namespaceType);
+
+ uassert(ErrorCodes::InternalError,
+ str::stream() << "Collection 'type' expected to be a string: " << col,
+ ErrorCodes::TypeMismatch != status.code());
+
+ uassert(ErrorCodes::CommandNotSupportedOnView,
+ str::stream() << "copyCollection not supported for views. ns: "
+ << col["name"].valuestrsafe(),
+ !(status.isOK() && namespaceType == "view"));
+ }
+
if (col["options"].isABSONObj()) {
options = col["options"].Obj();
}