summaryrefslogtreecommitdiff
path: root/src/mongo/db/views
diff options
context:
space:
mode:
authorKyle Suarez <kyle.suarez@mongodb.com>2016-06-24 15:36:49 -0400
committerKyle Suarez <kyle.suarez@mongodb.com>2016-07-07 10:35:40 -0400
commite39c46b27f4ae58f96b685dd625b0165761fee0d (patch)
tree147d97c8a4989f50e4fe40c0a82b765b4a14aa76 /src/mongo/db/views
parent21e0ff71b1693f42e1b44885a57de3b7b3cdacba (diff)
downloadmongo-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/SConscript15
-rw-r--r--src/mongo/db/views/view.cpp46
-rw-r--r--src/mongo/db/views/view.h79
-rw-r--r--src/mongo/db/views/view_catalog.cpp80
-rw-r--r--src/mongo/db/views/view_catalog.h88
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