diff options
author | James Wahlin <james.wahlin@10gen.com> | 2016-07-18 12:09:24 -0400 |
---|---|---|
committer | James Wahlin <james.wahlin@10gen.com> | 2016-07-19 10:10:43 -0400 |
commit | 97c43492de001c1bfd9426107c919ab50f1829ab (patch) | |
tree | 7825b00a90f53800cc46c67cd11b63298a944e66 /src/mongo/db/commands/list_collections.cpp | |
parent | 1b0320d123393e77f8ec0380dd8f9a725709cb1e (diff) | |
download | mongo-97c43492de001c1bfd9426107c919ab50f1829ab.tar.gz |
SERVER-24506 listCollections support for views
Diffstat (limited to 'src/mongo/db/commands/list_collections.cpp')
-rw-r--r-- | src/mongo/db/commands/list_collections.cpp | 72 |
1 files changed, 54 insertions, 18 deletions
diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index b38e3b07c3d..23cd2ff6845 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -48,6 +48,8 @@ #include "mongo/db/query/find_common.h" #include "mongo/db/service_context.h" #include "mongo/db/storage/storage_engine.h" +#include "mongo/db/storage/storage_options.h" +#include "mongo/db/views/view_catalog.h" #include "mongo/stdx/memory.h" namespace mongo { @@ -105,37 +107,56 @@ boost::optional<vector<StringData>> _getExactNameMatches(const MatchExpression* * Does not add any information about the system.namespaces collection, or non-existent collections. */ void _addWorkingSetMember(OperationContext* txn, - const Collection* collection, + const BSONObj& maybe, const MatchExpression* matcher, WorkingSet* ws, QueuedDataStage* root) { - if (!collection) { + if (matcher && !matcher->matchesBSON(maybe)) { return; } + WorkingSetID id = ws->allocate(); + WorkingSetMember* member = ws->get(id); + member->keyData.clear(); + member->recordId = RecordId(); + member->obj = Snapshotted<BSONObj>(SnapshotId(), maybe); + member->transitionToOwnedObj(); + root->pushBack(id); +} + +BSONObj buildViewBson(const ViewDefinition& view) { + BSONObjBuilder b; + b.append("name", view.name().coll()); + b.append("type", "view"); + BSONObj options = BSON("viewOn" << view.viewOn().coll() << "pipeline" << view.pipeline()); + b.append("options", options); + BSONObj info = BSON("readOnly" << true); + b.append("info", info); + return b.obj(); +} + +BSONObj buildCollectionBson(OperationContext* txn, const Collection* collection) { + + if (!collection) { + return {}; + } + StringData collectionName = collection->ns().coll(); if (collectionName == "system.namespaces") { - return; + return {}; } BSONObjBuilder b; b.append("name", collectionName); + b.append("type", "collection"); CollectionOptions options = collection->getCatalogEntry()->getCollectionOptions(txn); b.append("options", options.toBSON()); - BSONObj maybe = b.obj(); - if (matcher && !matcher->matchesBSON(maybe)) { - return; - } + BSONObj info = BSON("readOnly" << storageGlobalParams.readOnly); + b.append("info", info); - WorkingSetID id = ws->allocate(); - WorkingSetMember* member = ws->get(id); - member->keyData.clear(); - member->recordId = RecordId(); - member->obj = Snapshotted<BSONObj>(SnapshotId(), maybe); - member->transitionToOwnedObj(); - root->pushBack(id); + return b.obj(); } class CmdListCollections : public Command { @@ -212,7 +233,7 @@ public: ScopedTransaction scopedXact(txn, MODE_IS); AutoGetDb autoDb(txn, dbname, MODE_S); - const Database* db = autoDb.getDb(); + Database* db = autoDb.getDb(); auto ws = make_unique<WorkingSet>(); auto root = make_unique<QueuedDataStage>(txn, ws.get()); @@ -221,12 +242,27 @@ public: if (auto collNames = _getExactNameMatches(matcher.get())) { for (auto&& collName : *collNames) { auto nss = NamespaceString(db->name(), collName); - _addWorkingSetMember( - txn, db->getCollection(nss), matcher.get(), ws.get(), root.get()); + Collection* collection = db->getCollection(nss); + BSONObj collBson = buildCollectionBson(txn, collection); + if (!collBson.isEmpty()) { + _addWorkingSetMember(txn, collBson, matcher.get(), ws.get(), root.get()); + } } } else { for (auto&& collection : *db) { - _addWorkingSetMember(txn, collection, matcher.get(), ws.get(), root.get()); + BSONObj collBson = buildCollectionBson(txn, collection); + if (!collBson.isEmpty()) { + _addWorkingSetMember(txn, collBson, matcher.get(), ws.get(), root.get()); + } + } + } + auto viewCatalog = db->getViewCatalog(); + if (viewCatalog) { + for (auto& view : *viewCatalog) { + BSONObj viewBson = buildViewBson(*(view.second.get())); + if (!viewBson.isEmpty()) { + _addWorkingSetMember(txn, viewBson, matcher.get(), ws.get(), root.get()); + } } } } |