diff options
author | Kyle Suarez <kyle.suarez@mongodb.com> | 2016-06-24 15:36:49 -0400 |
---|---|---|
committer | Kyle Suarez <kyle.suarez@mongodb.com> | 2016-07-07 10:35:40 -0400 |
commit | e39c46b27f4ae58f96b685dd625b0165761fee0d (patch) | |
tree | 147d97c8a4989f50e4fe40c0a82b765b4a14aa76 /src/mongo/db/views | |
parent | 21e0ff71b1693f42e1b44885a57de3b7b3cdacba (diff) | |
download | mongo-e39c46b27f4ae58f96b685dd625b0165761fee0d.tar.gz |
SERVER-24766 implement basic views library
Adds the basic infrastructure for read-only non-materialized views, as well as
the ability to create them (but not use them).
Views are disabled by default unless mongod is given the setParameter
enableViews=1.
Diffstat (limited to 'src/mongo/db/views')
-rw-r--r-- | src/mongo/db/views/SConscript | 15 | ||||
-rw-r--r-- | src/mongo/db/views/view.cpp | 46 | ||||
-rw-r--r-- | src/mongo/db/views/view.h | 79 | ||||
-rw-r--r-- | src/mongo/db/views/view_catalog.cpp | 80 | ||||
-rw-r--r-- | src/mongo/db/views/view_catalog.h | 88 |
5 files changed, 308 insertions, 0 deletions
diff --git a/src/mongo/db/views/SConscript b/src/mongo/db/views/SConscript new file mode 100644 index 00000000000..33e44ae68d8 --- /dev/null +++ b/src/mongo/db/views/SConscript @@ -0,0 +1,15 @@ +# -*- mode: python -*- + +Import("env") + +env.Library( + target='views', + source=[ + 'view.cpp', + 'view_catalog.cpp', + ], + LIBDEPS=[ + '$BUILD_DIR/mongo/base', + '$BUILD_DIR/mongo/db/server_parameters', + ] +) diff --git a/src/mongo/db/views/view.cpp b/src/mongo/db/views/view.cpp new file mode 100644 index 00000000000..380f5eeaed5 --- /dev/null +++ b/src/mongo/db/views/view.cpp @@ -0,0 +1,46 @@ +/** +* Copyright (C) 2016 MongoDB Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* As a special exception, the copyright holders give permission to link the +* code of portions of this program with the OpenSSL library under certain +* conditions as described in each individual source file and distribute +* linked combinations including the program with the OpenSSL library. You +* must comply with the GNU Affero General Public License in all respects for +* all of the code used other than as permitted herein. If you modify file(s) +* with this exception, you may extend this exception to your version of the +* file(s), but you are not obligated to do so. If you do not wish to do so, +* delete this exception statement from your version. If you delete this +* exception statement from all source files in the program, then also delete +* it in the license file. +*/ + +#include "mongo/platform/basic.h" + +#include "mongo/db/views/view.h" + +#include "mongo/base/string_data.h" + +namespace mongo { + +ViewDefinition::ViewDefinition(StringData dbName, + StringData viewName, + StringData viewOnName, + const BSONObj& pipeline) + : _viewNss(dbName, viewName), _viewOnNss(dbName, viewOnName) { + for (BSONElement e : pipeline) { + _pipeline.push_back(e.Obj().getOwned()); + } +} +} // namespace mongo diff --git a/src/mongo/db/views/view.h b/src/mongo/db/views/view.h new file mode 100644 index 00000000000..446d74dffe1 --- /dev/null +++ b/src/mongo/db/views/view.h @@ -0,0 +1,79 @@ +/** +* Copyright (C) 2016 MongoDB Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* As a special exception, the copyright holders give permission to link the +* code of portions of this program with the OpenSSL library under certain +* conditions as described in each individual source file and distribute +* linked combinations including the program with the OpenSSL library. You +* must comply with the GNU Affero General Public License in all respects for +* all of the code used other than as permitted herein. If you modify file(s) +* with this exception, you may extend this exception to your version of the +* file(s), but you are not obligated to do so. If you do not wish to do so, +* delete this exception statement from your version. If you delete this +* exception statement from all source files in the program, then also delete +* it in the license file. +*/ + +#pragma once + +#include <vector> + +#include "mongo/base/string_data.h" +#include "mongo/bson/bsonobj.h" +#include "mongo/db/namespace_string.h" + +namespace mongo { + +/** + * Represents a "view": a virtual collection defined by a query on a collection or another view. + */ +class ViewDefinition { +public: + /** + * Create a new view. + * + * @param dbName The name of the database owning the view. + * @param viewName The name of the view. Does not include the database name. + * @param viewOnName The name of the view or collection upon which this view is defined. Does + * not include the database name. + * @param pipeline A series of pipeline stages representing an aggregation on the `viewOn` + * namespace. + */ + ViewDefinition(StringData dbName, + StringData viewName, + StringData viewOnName, + const BSONObj& pipeline); + + /** + * @return The fully-qualified namespace of this view. + */ + const NamespaceString& name() const { + return _viewNss; + } + + /** + * @return The fully-qualified namespace of the view or collection upon which this view is + * based. + */ + const NamespaceString& viewOn() const { + return _viewOnNss; + } + +private: + NamespaceString _viewNss; + NamespaceString _viewOnNss; + std::vector<BSONObj> _pipeline; +}; +} // namespace mongo diff --git a/src/mongo/db/views/view_catalog.cpp b/src/mongo/db/views/view_catalog.cpp new file mode 100644 index 00000000000..65197745dd3 --- /dev/null +++ b/src/mongo/db/views/view_catalog.cpp @@ -0,0 +1,80 @@ +/** +* Copyright (C) 2016 MongoDB Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* As a special exception, the copyright holders give permission to link the +* code of portions of this program with the OpenSSL library under certain +* conditions as described in each individual source file and distribute +* linked combinations including the program with the OpenSSL library. You +* must comply with the GNU Affero General Public License in all respects for +* all of the code used other than as permitted herein. If you modify file(s) +* with this exception, you may extend this exception to your version of the +* file(s), but you are not obligated to do so. If you do not wish to do so, +* delete this exception statement from your version. If you delete this +* exception statement from all source files in the program, then also delete +* it in the license file. +*/ + +#include "mongo/platform/basic.h" + +#include "mongo/db/views/view_catalog.h" + +#include "mongo/base/string_data.h" +#include "mongo/db/namespace_string.h" +#include "mongo/db/operation_context.h" +#include "mongo/db/server_parameters.h" +#include "mongo/db/views/view.h" + +namespace { +bool enableViews = false; +} // namespace + +namespace mongo { +ExportedServerParameter<bool, ServerParameterType::kStartupOnly> enableViewsParameter( + ServerParameterSet::getGlobal(), "enableViews", &enableViews); + +const std::uint32_t ViewCatalog::kMaxViewDepth = 20; + +ViewCatalog::ViewCatalog(OperationContext* txn, Database* database) {} + +Status ViewCatalog::createView(OperationContext* txn, + const NamespaceString& viewName, + const NamespaceString& viewOn, + const BSONObj& pipeline) { + if (!enableViews) + return Status(ErrorCodes::CommandNotSupported, "View support not enabled"); + + if (lookup(StringData(viewName.ns()))) + return Status(ErrorCodes::NamespaceExists, "Namespace already exists"); + + if (viewName.db() != viewOn.db()) + return Status(ErrorCodes::BadValue, + "View must be created on a view or collection in the same database"); + + BSONObj ownedPipeline = pipeline.getOwned(); + txn->recoveryUnit()->onCommit([this, viewName, viewOn, ownedPipeline]() { + _viewMap[viewName.ns()] = std::make_shared<ViewDefinition>( + viewName.db(), viewName.coll(), viewOn.coll(), ownedPipeline); + }); + return Status::OK(); +} + +ViewDefinition* ViewCatalog::lookup(StringData ns) { + ViewMap::const_iterator it = _viewMap.find(ns); + if (it != _viewMap.end()) { + return it->second.get(); + } + return nullptr; +} +} // namespace mongo diff --git a/src/mongo/db/views/view_catalog.h b/src/mongo/db/views/view_catalog.h new file mode 100644 index 00000000000..0dd3f34a80e --- /dev/null +++ b/src/mongo/db/views/view_catalog.h @@ -0,0 +1,88 @@ +/** +* Copyright (C) 2016 MongoDB Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +* +* As a special exception, the copyright holders give permission to link the +* code of portions of this program with the OpenSSL library under certain +* conditions as described in each individual source file and distribute +* linked combinations including the program with the OpenSSL library. You +* must comply with the GNU Affero General Public License in all respects for +* all of the code used other than as permitted herein. If you modify file(s) +* with this exception, you may extend this exception to your version of the +* file(s), but you are not obligated to do so. If you do not wish to do so, +* delete this exception statement from your version. If you delete this +* exception statement from all source files in the program, then also delete +* it in the license file. +*/ + +#pragma once + +#include "mongo/db/views/view.h" +#include "mongo/util/string_map.h" + +namespace mongo { +class Database; +class NamespaceString; +class OperationContext; +class Status; +class StringData; + +/** + * In-memory data structure for view definitions. Note that this structure is not thread-safe; you + * must be holding a database lock to access a database's view catalog. + */ +class ViewCatalog { + MONGO_DISALLOW_COPYING(ViewCatalog); + +public: + // TODO(SERVER-23700): Make this a unique_ptr once StringMap supports move-only types. + using ViewMap = StringMap<std::shared_ptr<ViewDefinition>>; + static const std::uint32_t kMaxViewDepth; + + ViewCatalog(OperationContext* txn, Database* database); + + ViewMap::const_iterator begin() const { + return _viewMap.begin(); + } + + ViewMap::const_iterator end() const { + return _viewMap.end(); + } + + /** + * Create a new view. + * + * @param viewName The name of the view being created. + * @param viewOn The name of the view or collection upon which this view is defined. + * @param pipeline The aggregation pipeline that defines the aggregation on the backing + * namespace. + */ + Status createView(OperationContext* txn, + const NamespaceString& viewName, + const NamespaceString& viewOn, + const BSONObj& pipeline); + + /** + * Look up the namespace in the view catalog, returning a pointer to a View definition, or + * nullptr if it doesn't exist. Note that the caller does not own the pointer. + * + * @param ns The full namespace string of the view. + * @return A bare pointer to a view definition if ns is a valid view with a backing namespace. + */ + ViewDefinition* lookup(StringData ns); + +private: + ViewMap _viewMap; +}; +} // namespace mongo |