diff options
author | Vesselina Ratcheva <vesselina.ratcheva@mongodb.com> | 2019-10-17 17:24:51 +0000 |
---|---|---|
committer | evergreen <evergreen@mongodb.com> | 2019-10-17 17:24:51 +0000 |
commit | fff3ebaaa26b97674d19234344ea30817ac6dd4e (patch) | |
tree | eeb14aae7a936b0084136b21c161260a2c1f63a7 /src | |
parent | d78ab05ea802c80e10ed81a177bc0f7ba5e643a4 (diff) | |
download | mongo-fff3ebaaa26b97674d19234344ea30817ac6dd4e.tar.gz |
SERVER-43272 Implement getDatabaseInfos method (listDatabases) in DBClient
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/client/dbclient_base.cpp | 36 | ||||
-rw-r--r-- | src/mongo/client/dbclient_base.h | 10 | ||||
-rw-r--r-- | src/mongo/dbtests/querytests.cpp | 57 |
3 files changed, 103 insertions, 0 deletions
diff --git a/src/mongo/client/dbclient_base.cpp b/src/mongo/client/dbclient_base.cpp index 2633a560298..7af010fa6b8 100644 --- a/src/mongo/client/dbclient_base.cpp +++ b/src/mongo/client/dbclient_base.cpp @@ -588,6 +588,42 @@ list<BSONObj> DBClientBase::getCollectionInfos(const string& db, const BSONObj& uasserted(18630, str::stream() << "listCollections failed: " << res); } +vector<BSONObj> DBClientBase::getDatabaseInfos(const BSONObj& filter, + const bool nameOnly, + const bool authorizedDatabases) { + vector<BSONObj> infos; + + BSONObjBuilder bob; + bob.append("listDatabases", 1); + bob.append("filter", filter); + + if (nameOnly) { + bob.append("nameOnly", 1); + } + if (authorizedDatabases) { + bob.append("authorizedDatabases", 1); + } + + BSONObj cmd = bob.done(); + + BSONObj res; + if (runCommand("admin", cmd, res, QueryOption_SlaveOk)) { + BSONObj dbs = res["databases"].Obj(); + BSONObjIterator it(dbs); + while (it.more()) { + BSONElement e = it.next(); + infos.push_back(e.Obj().getOwned()); + } + + return infos; + } + + uassertStatusOKWithContext(getStatusFromCommandResult(res), + str::stream() + << "Command 'listDatabases' failed. Full command: " << cmd); + MONGO_UNREACHABLE; +} + bool DBClientBase::exists(const string& ns) { BSONObj filter = BSON("name" << nsToCollectionSubstring(ns)); list<BSONObj> results = getCollectionInfos(nsToDatabase(ns), filter); diff --git a/src/mongo/client/dbclient_base.h b/src/mongo/client/dbclient_base.h index 13d0d50cc99..eb24295c5b6 100644 --- a/src/mongo/client/dbclient_base.h +++ b/src/mongo/client/dbclient_base.h @@ -462,6 +462,16 @@ public: */ std::list<BSONObj> getCollectionInfos(const std::string& db, const BSONObj& filter = BSONObj()); + /** + * Lists databases available on the server. + * @param filter A filter for the results + * @param nameOnly Only return the names of the databases + * @param authorizedDatabases Only return the databases the user is authorized on + */ + std::vector<BSONObj> getDatabaseInfos(const BSONObj& filter = BSONObj(), + const bool nameOnly = false, + const bool authorizedDatabases = false); + bool exists(const std::string& ns); /** Create an index on the collection 'ns' as described by the given keys. If you wish diff --git a/src/mongo/dbtests/querytests.cpp b/src/mongo/dbtests/querytests.cpp index 22cd9256808..97e8ee011db 100644 --- a/src/mongo/dbtests/querytests.cpp +++ b/src/mongo/dbtests/querytests.cpp @@ -1822,6 +1822,61 @@ public: } }; +class GetDatabaseInfosTest : public CollectionBase { +public: + GetDatabaseInfosTest() : CollectionBase("GetDatabaseInfosTest") {} + + void run() { + const char* ns1 = "unittestsdb1.querytests.coll1"; + { + Lock::GlobalWrite lk(&_opCtx); + OldClientContext context(&_opCtx, ns1); + WriteUnitOfWork wunit(&_opCtx); + context.db()->createCollection(&_opCtx, NamespaceString(ns1)); + wunit.commit(); + } + insert(ns1, BSON("a" << 1)); + auto dbInfos = _client.getDatabaseInfos(BSONObj(), true /*nameOnly*/); + checkNewDBInResults(dbInfos, 1); + + + const char* ns2 = "unittestsdb2.querytests.coll2"; + { + Lock::GlobalWrite lk(&_opCtx); + OldClientContext context(&_opCtx, ns2); + WriteUnitOfWork wunit(&_opCtx); + context.db()->createCollection(&_opCtx, NamespaceString(ns2)); + wunit.commit(); + } + insert(ns2, BSON("b" << 2)); + dbInfos = _client.getDatabaseInfos(BSONObj(), true /*nameOnly*/); + checkNewDBInResults(dbInfos, 2); + + + const char* ns3 = "unittestsdb3.querytests.coll3"; + { + Lock::GlobalWrite lk(&_opCtx); + OldClientContext context(&_opCtx, ns3); + WriteUnitOfWork wunit(&_opCtx); + context.db()->createCollection(&_opCtx, NamespaceString(ns3)); + wunit.commit(); + } + insert(ns3, BSON("c" << 3)); + dbInfos = _client.getDatabaseInfos(BSONObj(), true /*nameOnly*/); + checkNewDBInResults(dbInfos, 3); + } + + void checkNewDBInResults(const std::vector<BSONObj> results, const int dbNum) { + std::string target = "unittestsdb" + std::to_string(dbNum); + for (auto res : results) { + if (res["name"].str() == target) { + return; + } + } + ASSERT(false); // Should not hit this unless we failed to find the database. + } +}; + class CollectionInternalBase : public CollectionBase { public: CollectionInternalBase(const char* nsLeaf) @@ -1985,6 +2040,8 @@ public: add<WhatsMyUri>(); add<QueryByUuid>(); add<GetIndexSpecsByUUID>(); + add<CountByUUID>(); + add<GetDatabaseInfosTest>(); add<Exhaust>(); add<QueryReadsAll>(); add<queryobjecttests::names1>(); |