summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVesselina Ratcheva <vesselina.ratcheva@mongodb.com>2019-10-17 17:24:51 +0000
committerevergreen <evergreen@mongodb.com>2019-10-17 17:24:51 +0000
commitfff3ebaaa26b97674d19234344ea30817ac6dd4e (patch)
treeeeb14aae7a936b0084136b21c161260a2c1f63a7 /src
parentd78ab05ea802c80e10ed81a177bc0f7ba5e643a4 (diff)
downloadmongo-fff3ebaaa26b97674d19234344ea30817ac6dd4e.tar.gz
SERVER-43272 Implement getDatabaseInfos method (listDatabases) in DBClient
Diffstat (limited to 'src')
-rw-r--r--src/mongo/client/dbclient_base.cpp36
-rw-r--r--src/mongo/client/dbclient_base.h10
-rw-r--r--src/mongo/dbtests/querytests.cpp57
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>();