summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorDivjot Arora <divjot.arora@10gen.com>2019-03-04 12:03:47 -0500
committerDivjot Arora <divjot.arora@10gen.com>2019-03-07 16:07:56 -0500
commitf386c49be72744d88fbb0950c54d6621a9d242b8 (patch)
tree667898972de2a58ea65cdf0d35969756682fa67d /src/mongo/db
parentc6f1019c261b5bde912e720605ce7f74f3113270 (diff)
downloadmongo-f386c49be72744d88fbb0950c54d6621a9d242b8.tar.gz
SERVER-39505 Make ViewCatalog a decoration on Database.
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/catalog/capped_utils.cpp5
-rw-r--r--src/mongo/db/catalog/coll_mod.cpp4
-rw-r--r--src/mongo/db/catalog/database.h7
-rw-r--r--src/mongo/db/catalog/database_impl.cpp24
-rw-r--r--src/mongo/db/catalog/database_impl.h11
-rw-r--r--src/mongo/db/catalog/drop_collection.cpp2
-rw-r--r--src/mongo/db/catalog/drop_indexes.cpp3
-rw-r--r--src/mongo/db/catalog/rename_collection.cpp5
-rw-r--r--src/mongo/db/catalog_raii.cpp3
-rw-r--r--src/mongo/db/commands/compact.cpp3
-rw-r--r--src/mongo/db/commands/create_indexes.cpp4
-rw-r--r--src/mongo/db/commands/drop_indexes.cpp3
-rw-r--r--src/mongo/db/commands/list_collections.cpp2
-rw-r--r--src/mongo/db/commands/run_aggregate.cpp6
-rw-r--r--src/mongo/db/commands/validate.cpp3
-rw-r--r--src/mongo/db/query/find.cpp3
-rw-r--r--src/mongo/db/repl/do_txn.cpp3
-rw-r--r--src/mongo/db/repl/oplog.cpp5
-rw-r--r--src/mongo/db/s/set_shard_version_command.cpp3
-rw-r--r--src/mongo/db/views/durable_view_catalog.cpp3
-rw-r--r--src/mongo/db/views/view_catalog.cpp11
-rw-r--r--src/mongo/db/views/view_catalog.h9
-rw-r--r--src/mongo/db/views/view_catalog_test.cpp14
23 files changed, 77 insertions, 59 deletions
diff --git a/src/mongo/db/catalog/capped_utils.cpp b/src/mongo/db/catalog/capped_utils.cpp
index 5c7b0fe4a60..48d10844bf8 100644
--- a/src/mongo/db/catalog/capped_utils.cpp
+++ b/src/mongo/db/catalog/capped_utils.cpp
@@ -51,6 +51,7 @@
#include "mongo/db/query/plan_yield_policy.h"
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/util/scopeguard.h"
namespace mongo {
@@ -73,7 +74,7 @@ Status emptyCapped(OperationContext* opCtx, const NamespaceString& collectionNam
Collection* collection = db->getCollection(opCtx, collectionName);
uassert(ErrorCodes::CommandNotSupportedOnView,
str::stream() << "emptycapped not supported on view: " << collectionName.ns(),
- collection || !db->getViewCatalog()->lookup(opCtx, collectionName.ns()));
+ collection || !ViewCatalog::get(db)->lookup(opCtx, collectionName.ns()));
uassert(ErrorCodes::NamespaceNotFound, "no such collection", collection);
if (collectionName.isSystem() && !collectionName.isSystemDotProfile()) {
@@ -124,7 +125,7 @@ void cloneCollectionAsCapped(OperationContext* opCtx,
if (!fromCollection) {
uassert(ErrorCodes::CommandNotSupportedOnView,
str::stream() << "cloneCollectionAsCapped not supported for views: " << fromNss,
- !db->getViewCatalog()->lookup(opCtx, fromNss.ns()));
+ !ViewCatalog::get(db)->lookup(opCtx, fromNss.ns()));
uasserted(ErrorCodes::NamespaceNotFound,
str::stream() << "source collection " << fromNss << " does not exist");
diff --git a/src/mongo/db/catalog/coll_mod.cpp b/src/mongo/db/catalog/coll_mod.cpp
index d85562aa593..b28a7bbccdb 100644
--- a/src/mongo/db/catalog/coll_mod.cpp
+++ b/src/mongo/db/catalog/coll_mod.cpp
@@ -309,7 +309,7 @@ Status _collModInternal(OperationContext* opCtx,
// May also modify a view instead of a collection.
boost::optional<ViewDefinition> view;
if (db && !coll) {
- const auto sharedView = db->getViewCatalog()->lookup(opCtx, nss.ns());
+ const auto sharedView = ViewCatalog::get(db)->lookup(opCtx, nss.ns());
if (sharedView) {
// We copy the ViewDefinition as it is modified below to represent the requested state.
view = {*sharedView};
@@ -355,7 +355,7 @@ Status _collModInternal(OperationContext* opCtx,
if (!cmr.viewOn.empty())
view->setViewOn(NamespaceString(dbName, cmr.viewOn));
- ViewCatalog* catalog = db->getViewCatalog();
+ ViewCatalog* catalog = ViewCatalog::get(db);
BSONArrayBuilder pipeline;
for (auto& item : view->pipeline()) {
diff --git a/src/mongo/db/catalog/database.h b/src/mongo/db/catalog/database.h
index 5848b816e16..30648c41bd9 100644
--- a/src/mongo/db/catalog/database.h
+++ b/src/mongo/db/catalog/database.h
@@ -39,7 +39,6 @@
#include "mongo/db/catalog/collection_options.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/repl/optime.h"
-#include "mongo/db/views/view_catalog.h"
#include "mongo/util/string_map.h"
namespace mongo {
@@ -204,12 +203,6 @@ public:
virtual Collection* getCollection(OperationContext* opCtx, const NamespaceString& ns) const = 0;
- /**
- * Get the view catalog, which holds the definition for all views created on this database. You
- * must be holding a database lock to use this accessor.
- */
- virtual ViewCatalog* getViewCatalog() = 0;
-
virtual Collection* getOrCreateCollection(OperationContext* const opCtx,
const NamespaceString& nss) = 0;
diff --git a/src/mongo/db/catalog/database_impl.cpp b/src/mongo/db/catalog/database_impl.cpp
index f3f0f1505a5..b8b445649b5 100644
--- a/src/mongo/db/catalog/database_impl.cpp
+++ b/src/mongo/db/catalog/database_impl.cpp
@@ -263,9 +263,12 @@ DatabaseImpl::DatabaseImpl(const StringData name,
_dbEntry(dbEntry),
_epoch(epoch),
_profileName(_name + ".system.profile"),
- _viewsName(_name + "." + DurableViewCatalog::viewsCollectionName().toString()),
- _durableViews(DurableViewCatalogImpl(this)),
- _views(&_durableViews) {}
+ _viewsName(_name + "." + DurableViewCatalog::viewsCollectionName().toString()) {
+ auto durableViewCatalog = std::make_unique<DurableViewCatalogImpl>(this);
+ auto viewCatalog = std::make_unique<ViewCatalog>(std::move(durableViewCatalog));
+
+ ViewCatalog::set(this, std::move(viewCatalog));
+}
void DatabaseImpl::init(OperationContext* const opCtx) {
Status status = validateDBName(_name);
@@ -289,8 +292,9 @@ void DatabaseImpl::init(OperationContext* const opCtx) {
// system.views collection would be found. Now we're sufficiently initialized, signal a version
// change. Also force a reload, so if there are problems with the catalog contents as might be
// caused by incorrect mongod versions or similar, they are found right away.
- _views.invalidate();
- Status reloadStatus = _views.reloadIfNeeded(opCtx);
+ auto views = ViewCatalog::get(this);
+ views->invalidate();
+ Status reloadStatus = views->reloadIfNeeded(opCtx);
if (!reloadStatus.isOK()) {
warning() << "Unable to parse views: " << redact(reloadStatus)
@@ -417,7 +421,7 @@ void DatabaseImpl::getStats(OperationContext* opCtx, BSONObjBuilder* output, dou
indexSize += collection->getIndexSize(opCtx);
}
- getViewCatalog()->iterate(opCtx, [&](const ViewDefinition& view) { nViews += 1; });
+ ViewCatalog::get(this)->iterate(opCtx, [&](const ViewDefinition& view) { nViews += 1; });
output->appendNumber("collections", nCollections);
output->appendNumber("views", nViews);
@@ -449,7 +453,8 @@ void DatabaseImpl::getStats(OperationContext* opCtx, BSONObjBuilder* output, dou
}
Status DatabaseImpl::dropView(OperationContext* opCtx, StringData fullns) {
- Status status = _views.dropView(opCtx, NamespaceString(fullns));
+ auto views = ViewCatalog::get(this);
+ Status status = views->dropView(opCtx, NamespaceString(fullns));
Top::get(opCtx->getServiceContext()).collectionDropped(fullns);
return status;
}
@@ -785,7 +790,8 @@ Status DatabaseImpl::createView(OperationContext* opCtx,
return Status(ErrorCodes::InvalidNamespace,
str::stream() << "invalid namespace name for a view: " + nss.toString());
- return _views.createView(opCtx, nss, viewOnNss, BSONArray(options.pipeline), options.collation);
+ auto views = ViewCatalog::get(this);
+ return views->createView(opCtx, nss, viewOnNss, BSONArray(options.pipeline), options.collation);
}
Collection* DatabaseImpl::createCollection(OperationContext* opCtx,
@@ -1010,7 +1016,7 @@ Status DatabaseImpl::userCreateNS(OperationContext* opCtx,
return Status(ErrorCodes::NamespaceExists,
str::stream() << "a collection '" << fullns << "' already exists");
- if (getViewCatalog()->lookup(opCtx, fullns.ns()))
+ if (ViewCatalog::get(this)->lookup(opCtx, fullns.ns()))
return Status(ErrorCodes::NamespaceExists,
str::stream() << "a view '" << fullns << "' already exists");
diff --git a/src/mongo/db/catalog/database_impl.h b/src/mongo/db/catalog/database_impl.h
index b5ee0179b3a..31e04fb8476 100644
--- a/src/mongo/db/catalog/database_impl.h
+++ b/src/mongo/db/catalog/database_impl.h
@@ -116,14 +116,6 @@ public:
Collection* getCollection(OperationContext* opCtx, const NamespaceString& ns) const;
- /**
- * Get the view catalog, which holds the definition for all views created on this database. You
- * must be holding a database lock to use this accessor.
- */
- ViewCatalog* getViewCatalog() final {
- return &_views;
- }
-
Collection* getOrCreateCollection(OperationContext* opCtx, const NamespaceString& nss) final;
/**
@@ -223,9 +215,6 @@ private:
std::unique_ptr<PseudoRandom> _uniqueCollectionNamespacePseudoRandom;
CollectionMap _collections;
-
- DurableViewCatalogImpl _durableViews; // interface for system.views operations
- ViewCatalog _views; // in-memory representation of _durableViews
};
} // namespace mongo
diff --git a/src/mongo/db/catalog/drop_collection.cpp b/src/mongo/db/catalog/drop_collection.cpp
index 36058648978..594328bddfd 100644
--- a/src/mongo/db/catalog/drop_collection.cpp
+++ b/src/mongo/db/catalog/drop_collection.cpp
@@ -65,7 +65,7 @@ Status dropCollection(OperationContext* opCtx,
Database* const db = autoDb.getDb();
Collection* coll = db ? db->getCollection(opCtx, collectionName) : nullptr;
auto view =
- db && !coll ? db->getViewCatalog()->lookup(opCtx, collectionName.ns()) : nullptr;
+ db && !coll ? ViewCatalog::get(db)->lookup(opCtx, collectionName.ns()) : nullptr;
if (MONGO_FAIL_POINT(hangDuringDropCollection)) {
log() << "hangDuringDropCollection fail point enabled. Blocking until fail point is "
diff --git a/src/mongo/db/catalog/drop_indexes.cpp b/src/mongo/db/catalog/drop_indexes.cpp
index 4be12c0d674..03b21ef9801 100644
--- a/src/mongo/db/catalog/drop_indexes.cpp
+++ b/src/mongo/db/catalog/drop_indexes.cpp
@@ -44,6 +44,7 @@
#include "mongo/db/op_observer.h"
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/util/log.h"
namespace mongo {
@@ -217,7 +218,7 @@ Status dropIndexes(OperationContext* opCtx,
Database* db = autoDb.getDb();
Collection* collection = db ? db->getCollection(opCtx, nss) : nullptr;
if (!db || !collection) {
- if (db && db->getViewCatalog()->lookup(opCtx, nss.ns())) {
+ if (db && ViewCatalog::get(db)->lookup(opCtx, nss.ns())) {
return Status(ErrorCodes::CommandNotSupportedOnView,
str::stream() << "Cannot drop indexes on view " << nss);
}
diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp
index 88f9898ddfd..01dffe8848a 100644
--- a/src/mongo/db/catalog/rename_collection.cpp
+++ b/src/mongo/db/catalog/rename_collection.cpp
@@ -55,6 +55,7 @@
#include "mongo/db/s/database_sharding_state.h"
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
#include "mongo/util/scopeguard.h"
@@ -165,7 +166,7 @@ Status renameCollectionCommon(OperationContext* opCtx,
}
Collection* const sourceColl = sourceDB ? sourceDB->getCollection(opCtx, source) : nullptr;
if (!sourceColl) {
- if (sourceDB && sourceDB->getViewCatalog()->lookup(opCtx, source.ns()))
+ if (sourceDB && ViewCatalog::get(sourceDB)->lookup(opCtx, source.ns()))
return Status(ErrorCodes::CommandNotSupportedOnView,
str::stream() << "cannot rename view: " << source);
return Status(ErrorCodes::NamespaceNotFound, "source namespace does not exist");
@@ -239,7 +240,7 @@ Status renameCollectionCommon(OperationContext* opCtx,
return status;
targetColl = nullptr;
}
- } else if (targetDB->getViewCatalog()->lookup(opCtx, target.ns())) {
+ } else if (ViewCatalog::get(targetDB)->lookup(opCtx, target.ns())) {
return Status(ErrorCodes::NamespaceExists,
str::stream() << "a view already exists with that name: " << target);
}
diff --git a/src/mongo/db/catalog_raii.cpp b/src/mongo/db/catalog_raii.cpp
index a9a77a5e7e2..b3fafde57a8 100644
--- a/src/mongo/db/catalog_raii.cpp
+++ b/src/mongo/db/catalog_raii.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/catalog/database_holder.h"
#include "mongo/db/catalog/uuid_catalog.h"
#include "mongo/db/s/database_sharding_state.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/util/fail_point_service.h"
namespace mongo {
@@ -131,7 +132,7 @@ AutoGetCollection::AutoGetCollection(OperationContext* opCtx,
return;
}
- _view = db->getViewCatalog()->lookup(opCtx, _resolvedNss.ns());
+ _view = ViewCatalog::get(db)->lookup(opCtx, _resolvedNss.ns());
uassert(ErrorCodes::CommandNotSupportedOnView,
str::stream() << "Namespace " << _resolvedNss.ns() << " is a view, not a collection",
!_view || viewMode == kViewsPermitted);
diff --git a/src/mongo/db/commands/compact.cpp b/src/mongo/db/commands/compact.cpp
index 9ba9bf1b797..8e74b1d8e46 100644
--- a/src/mongo/db/commands/compact.cpp
+++ b/src/mongo/db/commands/compact.cpp
@@ -46,6 +46,7 @@
#include "mongo/db/index_builder.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/repl/replication_coordinator.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/util/log.h"
namespace mongo {
@@ -121,7 +122,7 @@ public:
Collection* collection = collDB ? collDB->getCollection(opCtx, nss) : nullptr;
auto view =
- collDB && !collection ? collDB->getViewCatalog()->lookup(opCtx, nss.ns()) : nullptr;
+ collDB && !collection ? ViewCatalog::get(collDB)->lookup(opCtx, nss.ns()) : nullptr;
// If db/collection does not exist, short circuit and return.
if (!collDB || !collection) {
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index 3ef74df70ef..5700ad537a1 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -305,7 +305,7 @@ bool runCreateIndexes(OperationContext* opCtx,
if (collection) {
result.appendBool("createdCollectionAutomatically", false);
} else {
- if (db->getViewCatalog()->lookup(opCtx, ns.ns())) {
+ if (ViewCatalog::get(db)->lookup(opCtx, ns.ns())) {
errmsg = "Cannot create indexes on a view";
uasserted(ErrorCodes::CommandNotSupportedOnView, errmsg);
}
@@ -562,7 +562,7 @@ bool runCreateIndexesWithCoordinator(OperationContext* opCtx,
// We would not reach this point if we were able to check existing indexes on the
// collection.
invariant(!collection);
- if (db->getViewCatalog()->lookup(opCtx, ns.ns())) {
+ if (ViewCatalog::get(db)->lookup(opCtx, ns.ns())) {
errmsg = str::stream() << "Cannot create indexes on a view: " << ns.ns();
uasserted(ErrorCodes::CommandNotSupportedOnView, errmsg);
}
diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp
index e25258e7fb6..3d189e8472a 100644
--- a/src/mongo/db/commands/drop_indexes.cpp
+++ b/src/mongo/db/commands/drop_indexes.cpp
@@ -52,6 +52,7 @@
#include "mongo/db/logical_clock.h"
#include "mongo/db/op_observer.h"
#include "mongo/db/service_context.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/util/log.h"
namespace mongo {
@@ -134,7 +135,7 @@ public:
Collection* collection = autoDb.getDb()->getCollection(opCtx, toReIndexNss);
if (!collection) {
- if (autoDb.getDb()->getViewCatalog()->lookup(opCtx, toReIndexNss.ns()))
+ if (ViewCatalog::get(autoDb.getDb())->lookup(opCtx, toReIndexNss.ns()))
uasserted(ErrorCodes::CommandNotSupportedOnView, "can't re-index a view");
else
uasserted(ErrorCodes::NamespaceNotFound, "collection does not exist");
diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp
index 4c7784f447a..854d0a32722 100644
--- a/src/mongo/db/commands/list_collections.cpp
+++ b/src/mongo/db/commands/list_collections.cpp
@@ -342,7 +342,7 @@ public:
SimpleBSONObjComparator::kInstance.evaluate(
filterElt.Obj() == ListCollectionsFilter::makeTypeCollectionFilter());
if (!skipViews) {
- db->getViewCatalog()->iterate(opCtx, [&](const ViewDefinition& view) {
+ ViewCatalog::get(db)->iterate(opCtx, [&](const ViewDefinition& view) {
BSONObj viewBson = buildViewBson(view, nameOnly);
if (!viewBson.isEmpty()) {
_addWorkingSetMember(
diff --git a/src/mongo/db/commands/run_aggregate.cpp b/src/mongo/db/commands/run_aggregate.cpp
index d2bd92e3036..f371ef7b1a0 100644
--- a/src/mongo/db/commands/run_aggregate.cpp
+++ b/src/mongo/db/commands/run_aggregate.cpp
@@ -230,7 +230,7 @@ StatusWith<StringMap<ExpressionContext::ResolvedNamespace>> resolveInvolvedNames
// 'resolvedNamespaces' because we won't re-resolve a view namespace we've already encountered.
AutoGetDb autoDb(opCtx, request.getNamespaceString().db(), MODE_IS);
Database* const db = autoDb.getDb();
- ViewCatalog* viewCatalog = db ? db->getViewCatalog() : nullptr;
+ ViewCatalog* viewCatalog = db ? ViewCatalog::get(db) : nullptr;
std::deque<NamespaceString> involvedNamespacesQueue(pipelineInvolvedNamespaces.begin(),
pipelineInvolvedNamespaces.end());
@@ -304,7 +304,7 @@ Status collatorCompatibleWithPipeline(OperationContext* opCtx,
continue;
}
- auto view = db->getViewCatalog()->lookup(opCtx, potentialViewNs.ns());
+ auto view = ViewCatalog::get(db)->lookup(opCtx, potentialViewNs.ns());
if (!view) {
continue;
}
@@ -504,7 +504,7 @@ Status runAggregate(OperationContext* opCtx,
}
auto resolvedView =
- uassertStatusOK(ctx->getDb()->getViewCatalog()->resolveView(opCtx, nss));
+ uassertStatusOK(ViewCatalog::get(ctx->getDb())->resolveView(opCtx, nss));
uassert(std::move(resolvedView),
"On sharded systems, resolved views must be executed by mongos",
!ShardingState::get(opCtx)->enabled());
diff --git a/src/mongo/db/commands/validate.cpp b/src/mongo/db/commands/validate.cpp
index 941f970deff..4ba5ca75025 100644
--- a/src/mongo/db/commands/validate.cpp
+++ b/src/mongo/db/commands/validate.cpp
@@ -38,6 +38,7 @@
#include "mongo/db/db_raii.h"
#include "mongo/db/query/internal_plans.h"
#include "mongo/db/storage/record_store.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
#include "mongo/util/scopeguard.h"
@@ -125,7 +126,7 @@ public:
auto collLk = stdx::make_unique<Lock::CollectionLock>(opCtx->lockState(), nss.ns(), MODE_X);
Collection* collection = ctx.getDb() ? ctx.getDb()->getCollection(opCtx, nss) : NULL;
if (!collection) {
- if (ctx.getDb() && ctx.getDb()->getViewCatalog()->lookup(opCtx, nss.ns())) {
+ if (ctx.getDb() && ViewCatalog::get(ctx.getDb())->lookup(opCtx, nss.ns())) {
uasserted(ErrorCodes::CommandNotSupportedOnView, "Cannot validate a view");
}
diff --git a/src/mongo/db/query/find.cpp b/src/mongo/db/query/find.cpp
index a4e02a58f47..5072509ffc3 100644
--- a/src/mongo/db/query/find.cpp
+++ b/src/mongo/db/query/find.cpp
@@ -59,6 +59,7 @@
#include "mongo/db/service_context.h"
#include "mongo/db/stats/top.h"
#include "mongo/db/storage/storage_options.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/s/chunk_version.h"
#include "mongo/s/stale_exception.h"
#include "mongo/stdx/memory.h"
@@ -296,7 +297,7 @@ Message getMore(OperationContext* opCtx,
Top::LockType::NotLocked,
AutoStatsTracker::LogMode::kUpdateTopAndCurop,
profilingLevel);
- auto view = autoDb.getDb() ? autoDb.getDb()->getViewCatalog()->lookup(opCtx, nss.ns())
+ auto view = autoDb.getDb() ? ViewCatalog::get(autoDb.getDb())->lookup(opCtx, nss.ns())
: nullptr;
uassert(
ErrorCodes::CommandNotSupportedOnView,
diff --git a/src/mongo/db/repl/do_txn.cpp b/src/mongo/db/repl/do_txn.cpp
index 8cf1ea35f32..fe1ce92052c 100644
--- a/src/mongo/db/repl/do_txn.cpp
+++ b/src/mongo/db/repl/do_txn.cpp
@@ -52,6 +52,7 @@
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/db/service_context.h"
#include "mongo/db/transaction_participant.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/util/fail_point_service.h"
#include "mongo/util/log.h"
@@ -147,7 +148,7 @@ Status _doTxn(OperationContext* opCtx,
// implicitly created on upserts. We detect both cases here and fail early with
// NamespaceNotFound.
// Additionally for inserts, we fail early on non-existent collections.
- if (!collection && db->getViewCatalog()->lookup(opCtx, nss.ns())) {
+ if (!collection && ViewCatalog::get(db)->lookup(opCtx, nss.ns())) {
uasserted(ErrorCodes::CommandNotSupportedOnView,
str::stream() << "doTxn not supported on a view: " << redact(opObj));
}
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 6838330d601..b588d7f0adc 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -86,6 +86,7 @@
#include "mongo/db/storage/storage_engine.h"
#include "mongo/db/storage/storage_options.h"
#include "mongo/db/transaction_participant.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/platform/random.h"
#include "mongo/scripting/engine.h"
#include "mongo/stdx/memory.h"
@@ -1469,7 +1470,7 @@ Status applyOperation_inlock(OperationContext* opCtx,
const bool haveWrappingWriteUnitOfWork = opCtx->lockState()->inAWriteUnitOfWork();
uassert(ErrorCodes::CommandNotSupportedOnView,
str::stream() << "applyOps not supported on view: " << requestNss.ns(),
- collection || !db->getViewCatalog()->lookup(opCtx, requestNss.ns()));
+ collection || !ViewCatalog::get(db)->lookup(opCtx, requestNss.ns()));
// This code must decide what timestamp the storage engine should make the upcoming writes
// visible with. The requirements and use-cases:
@@ -1884,7 +1885,7 @@ Status applyCommand_inlock(OperationContext* opCtx,
Lock::DBLock lock(opCtx, nss.db(), MODE_IS);
auto databaseHolder = DatabaseHolder::get(opCtx);
auto db = databaseHolder->getDb(opCtx, nss.ns());
- if (db && !db->getCollection(opCtx, nss) && db->getViewCatalog()->lookup(opCtx, nss.ns())) {
+ if (db && !db->getCollection(opCtx, nss) && ViewCatalog::get(db)->lookup(opCtx, nss.ns())) {
return {ErrorCodes::CommandNotSupportedOnView,
str::stream() << "applyOps not supported on view:" << nss.ns()};
}
diff --git a/src/mongo/db/s/set_shard_version_command.cpp b/src/mongo/db/s/set_shard_version_command.cpp
index 3e98c1e7088..2be706a5428 100644
--- a/src/mongo/db/s/set_shard_version_command.cpp
+++ b/src/mongo/db/s/set_shard_version_command.cpp
@@ -46,6 +46,7 @@
#include "mongo/db/s/shard_filtering_metadata_refresh.h"
#include "mongo/db/s/sharded_connection_info.h"
#include "mongo/db/s/sharding_state.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/s/client/shard_registry.h"
#include "mongo/s/grid.h"
#include "mongo/s/request_types/set_shard_version_request.h"
@@ -223,7 +224,7 @@ public:
// Views do not require a shard version check.
if (autoDb->getDb() && !autoDb->getDb()->getCollection(opCtx, nss) &&
- autoDb->getDb()->getViewCatalog()->lookup(opCtx, nss.ns())) {
+ ViewCatalog::get(autoDb->getDb())->lookup(opCtx, nss.ns())) {
return true;
}
diff --git a/src/mongo/db/views/durable_view_catalog.cpp b/src/mongo/db/views/durable_view_catalog.cpp
index e0f829b3922..24a23b928e9 100644
--- a/src/mongo/db/views/durable_view_catalog.cpp
+++ b/src/mongo/db/views/durable_view_catalog.cpp
@@ -44,6 +44,7 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/storage/record_data.h"
+#include "mongo/db/views/view_catalog.h"
#include "mongo/stdx/unordered_set.h"
#include "mongo/util/assert_util.h"
#include "mongo/util/log.h"
@@ -59,7 +60,7 @@ void DurableViewCatalog::onExternalChange(OperationContext* opCtx, const Namespa
auto db = databaseHolder->getDb(opCtx, name.db());
if (db) {
opCtx->recoveryUnit()->onCommit(
- [db](boost::optional<Timestamp>) { db->getViewCatalog()->invalidate(); });
+ [db](boost::optional<Timestamp>) { ViewCatalog::get(db)->invalidate(); });
}
}
diff --git a/src/mongo/db/views/view_catalog.cpp b/src/mongo/db/views/view_catalog.cpp
index 55b23bc09ef..08dba9ada81 100644
--- a/src/mongo/db/views/view_catalog.cpp
+++ b/src/mongo/db/views/view_catalog.cpp
@@ -39,6 +39,7 @@
#include "mongo/base/status_with.h"
#include "mongo/base/string_data.h"
#include "mongo/bson/util/builder.h"
+#include "mongo/db/catalog/database.h"
#include "mongo/db/commands/feature_compatibility_version_command_parser.h"
#include "mongo/db/namespace_string.h"
#include "mongo/db/operation_context.h"
@@ -57,7 +58,9 @@
#include "mongo/util/log.h"
namespace mongo {
+
namespace {
+auto getViewCatalog = Database::declareDecoration<std::unique_ptr<ViewCatalog>>();
StatusWith<std::unique_ptr<CollatorInterface>> parseCollator(OperationContext* opCtx,
BSONObj collationSpec) {
@@ -70,6 +73,14 @@ StatusWith<std::unique_ptr<CollatorInterface>> parseCollator(OperationContext* o
}
} // namespace
+ViewCatalog* ViewCatalog::get(Database* db) {
+ return getViewCatalog(db).get();
+}
+
+void ViewCatalog::set(Database* db, std::unique_ptr<ViewCatalog> catalog) {
+ getViewCatalog(db) = std::move(catalog);
+}
+
Status ViewCatalog::reloadIfNeeded(OperationContext* opCtx) {
stdx::lock_guard<stdx::mutex> lk(_mutex);
return _reloadIfNeeded(lk, opCtx);
diff --git a/src/mongo/db/views/view_catalog.h b/src/mongo/db/views/view_catalog.h
index ce0e84d7731..b2d13f97a26 100644
--- a/src/mongo/db/views/view_catalog.h
+++ b/src/mongo/db/views/view_catalog.h
@@ -50,6 +50,7 @@
namespace mongo {
class OperationContext;
+class Database;
/**
* In-memory data structure for view definitions. This data structure is thread-safe -- this is
@@ -65,7 +66,11 @@ public:
using ViewMap = StringMap<std::shared_ptr<ViewDefinition>>;
using ViewIteratorCallback = stdx::function<void(const ViewDefinition& view)>;
- explicit ViewCatalog(DurableViewCatalog* durable) : _durable(durable) {}
+ static ViewCatalog* get(Database* db);
+ static void set(Database* db, std::unique_ptr<ViewCatalog> catalog);
+
+ explicit ViewCatalog(std::unique_ptr<DurableViewCatalog> durable)
+ : _durable(std::move(durable)) {}
/**
* Iterates through the catalog, applying 'callback' to each view. This callback function
@@ -176,7 +181,7 @@ private:
stdx::mutex _mutex; // Protects all members, except for _valid.
ViewMap _viewMap;
- DurableViewCatalog* _durable;
+ std::unique_ptr<DurableViewCatalog> _durable;
AtomicWord<bool> _valid;
ViewGraph _viewGraph;
bool _viewGraphNeedsRefresh = true; // Defers initializing the graph until the first insert.
diff --git a/src/mongo/db/views/view_catalog_test.cpp b/src/mongo/db/views/view_catalog_test.cpp
index 5a705433e72..c005c2ff8ef 100644
--- a/src/mongo/db/views/view_catalog_test.cpp
+++ b/src/mongo/db/views/view_catalog_test.cpp
@@ -111,7 +111,7 @@ public:
ViewCatalogFixture()
: _queryServiceContext(stdx::make_unique<QueryTestServiceContext>()),
opCtx(_queryServiceContext->makeOperationContext()),
- viewCatalog(&durableViewCatalog) {}
+ viewCatalog(std::move(durableViewCatalogUnique)) {}
private:
std::unique_ptr<QueryTestServiceContext> _queryServiceContext;
@@ -121,7 +121,9 @@ protected:
return _queryServiceContext->getServiceContext();
}
- DurableViewCatalogDummy durableViewCatalog;
+ std::unique_ptr<DurableViewCatalogDummy> durableViewCatalogUnique =
+ std::make_unique<DurableViewCatalogDummy>();
+ DurableViewCatalogDummy* durableViewCatalog = durableViewCatalogUnique.get();
ServiceContext::UniqueOperationContext opCtx;
ViewCatalog viewCatalog;
const BSONArray emptyPipeline;
@@ -469,7 +471,7 @@ TEST_F(ViewCatalogFixture, ModifyTenTimes) {
ASSERT_OK(viewCatalog.modifyView(opCtx.get(), viewName, viewOn, emptyPipeline));
}
- ASSERT_EQ(10, durableViewCatalog.getUpsertCount());
+ ASSERT_EQ(10, durableViewCatalog->getUpsertCount());
}
TEST_F(ViewCatalogFixture, Iterate) {
@@ -567,14 +569,14 @@ TEST_F(ViewCatalogFixture, InvalidateThenReload) {
const NamespaceString viewOn("db.coll");
ASSERT_OK(viewCatalog.createView(opCtx.get(), viewName, viewOn, emptyPipeline, emptyCollation));
- ASSERT_EQ(1, durableViewCatalog.getIterateCount());
+ ASSERT_EQ(1, durableViewCatalog->getIterateCount());
ASSERT(viewCatalog.lookup(opCtx.get(), "db.view"_sd));
- ASSERT_EQ(1, durableViewCatalog.getIterateCount());
+ ASSERT_EQ(1, durableViewCatalog->getIterateCount());
viewCatalog.invalidate();
ASSERT_OK(viewCatalog.reloadIfNeeded(opCtx.get()));
- ASSERT_EQ(2, durableViewCatalog.getIterateCount());
+ ASSERT_EQ(2, durableViewCatalog->getIterateCount());
}
} // namespace
} // namespace mongo