summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDianna Hohensee <dianna.hohensee@10gen.com>2016-04-06 11:06:10 -0400
committerDianna Hohensee <dianna.hohensee@10gen.com>2016-04-06 11:06:10 -0400
commit202fd419457c47650be27accb038a700134797ed (patch)
tree842d58673be0d3eaf992eca8566931fb1c77cc7e
parent36f3ff8da1f7ae3710ceacc4e13adfd4abdb99da (diff)
downloadmongo-202fd419457c47650be27accb038a700134797ed.tar.gz
Revert "SERVER-23445 create LocalClient class for local queries/writes, implement a find query interface"
This reverts commit 02779909333ff4333c316b54b9fbb2fdd635e15a.
-rw-r--r--src/mongo/db/SConscript24
-rw-r--r--src/mongo/db/dbhelpers.cpp6
-rw-r--r--src/mongo/db/dbhelpers.h25
-rw-r--r--src/mongo/db/local_client.cpp145
-rw-r--r--src/mongo/db/local_client.h135
-rw-r--r--src/mongo/db/local_client_test.cpp183
6 files changed, 17 insertions, 501 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript
index 2bd2e2403f0..deac8c6ec4c 100644
--- a/src/mongo/db/SConscript
+++ b/src/mongo/db/SConscript
@@ -114,30 +114,6 @@ env.CppUnitTest(
env.CppUnitTest('record_id_test', 'record_id_test.cpp', LIBDEPS=[])
env.Library(
- target='local_client',
- source=[
- 'local_client.cpp',
- ],
- LIBDEPS=[
- 'query/query',
- ]
-)
-
-env.CppUnitTest(
- target='local_client_test',
- source=[
- 'local_client_test.cpp',
- ],
- LIBDEPS=[
- 'local_client',
- 'repl/replmocks',
- 'serveronly',
- '$BUILD_DIR/mongo/util/ntservice_mock',
- ],
- NO_CRUTCH = True,
-)
-
-env.Library(
target='startup_warnings_common',
source=[
'startup_warnings_common.cpp',
diff --git a/src/mongo/db/dbhelpers.cpp b/src/mongo/db/dbhelpers.cpp
index 3b572eacbab..fa7824f0768 100644
--- a/src/mongo/db/dbhelpers.cpp
+++ b/src/mongo/db/dbhelpers.cpp
@@ -107,6 +107,9 @@ void Helpers::ensureIndex(OperationContext* txn,
wunit.commit();
}
+/* fetch a single object from collection ns that matches query
+ set your db SavedContext first
+*/
bool Helpers::findOne(OperationContext* txn,
Collection* collection,
const BSONObj& query,
@@ -119,6 +122,9 @@ bool Helpers::findOne(OperationContext* txn,
return true;
}
+/* fetch a single object from collection ns that matches query
+ set your db SavedContext first
+*/
RecordId Helpers::findOne(OperationContext* txn,
Collection* collection,
const BSONObj& query,
diff --git a/src/mongo/db/dbhelpers.h b/src/mongo/db/dbhelpers.h
index 334857bd10a..53d0839711b 100644
--- a/src/mongo/db/dbhelpers.h
+++ b/src/mongo/db/dbhelpers.h
@@ -69,26 +69,23 @@ struct Helpers {
bool unique,
const char* name);
- /**
- * Fetches a single BSONObj document from the given collection that matches query.
- *
- * @param collection - collection to be queried.
- * @param query - the query to perform. Note this is the low level portion of query so
- * "orderby : ..." won't work.
- * @param result - holds the found BSONObj document, if found.
- * @param requireIndex - if true, assert if no index for the query. A way to guard against
- * writing a slow query.
- * @return true if a document is found.
- */
+ /* fetch a single object from collection ns that matches query.
+ set your db SavedContext first.
+
+ @param query - the query to perform. note this is the low level portion of query so
+ "orderby : ..." won't work.
+
+ @param requireIndex if true, assert if no index for the query. a way to guard against
+ writing a slow query.
+
+ @return true if object found
+ */
static bool findOne(OperationContext* txn,
Collection* collection,
const BSONObj& query,
BSONObj& result,
bool requireIndex = false);
- /**
- * Fetches the RecordId location of a single object from collection ns that matches query.
- */
static RecordId findOne(OperationContext* txn,
Collection* collection,
const BSONObj& query,
diff --git a/src/mongo/db/local_client.cpp b/src/mongo/db/local_client.cpp
deleted file mode 100644
index f9aded6e30b..00000000000
--- a/src/mongo/db/local_client.cpp
+++ /dev/null
@@ -1,145 +0,0 @@
-/**
- * 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/local_client.h"
-
-#include "mongo/db/db_raii.h"
-#include "mongo/db/exec/working_set_common.h"
-#include "mongo/db/matcher/extensions_callback_real.h"
-#include "mongo/db/query/get_executor.h"
-
-namespace mongo {
-
-LocalClient::LocalClient(OperationContext* txn) : _txn(txn) {}
-
-StatusWith<LocalClient::LocalCursor> LocalClient::query(const NamespaceString& nss,
- const BSONObj& query,
- const BSONObj& sort) {
- LocalCursor localCursor(_txn, nss, query, sort);
- Status initStatus = localCursor._init();
- if (!initStatus.isOK()) {
- return initStatus;
- }
- return std::move(localCursor);
-}
-
-LocalClient::LocalCursor::LocalCursor(OperationContext* txn,
- const NamespaceString& nss,
- const BSONObj& query,
- const BSONObj& sort)
- : _txn(txn), _nss(nss), _query(query), _sort(sort) {}
-
-#if defined(_MSC_VER) && _MSC_VER < 1900
-LocalClient::LocalCursor::LocalCursor(LocalCursor&& other)
- : _txn(std::move(other._txn)),
- _nss(std::move(other._nss)),
- _query(std::move(other._query)),
- _sort(std::move(other._sort)),
- _exec(std::move(other._exec)) {}
-
-LocalClient::LocalCursor& LocalClient::LocalCursor::operator=(LocalCursor&& other) {
- _txn = std::move(other._txn);
- _nss = std::move(other._nss);
- _query = std::move(other._query);
- _sort = std::move(other._sort);
- _exec = std::move(other._exec);
- return *this;
-}
-#endif
-
-Status LocalClient::LocalCursor::_init() {
- // This function does its own locking, so the lock should not be held.
- invariant(!_txn->lockState()->isLocked());
-
- if (!_nss.isValid()) {
- return {ErrorCodes::InvalidNamespace,
- str::stream() << "Invalid collection name: '" << _nss.ns()};
- }
-
- auto lpq = LiteParsedQuery::makeAsFindCmd(_nss,
- _query,
- BSONObj(), // projection
- _sort);
- ExtensionsCallbackReal extensionsCallback(_txn, &_nss);
-
- auto canonicalQuery = CanonicalQuery::canonicalize(lpq.release(), extensionsCallback);
- if (!canonicalQuery.isOK()) {
- return canonicalQuery.getStatus();
- }
-
- AutoGetCollection ctx(_txn, _nss, MODE_IS);
- Collection* collection = ctx.getCollection();
-
- auto statusWithPlanExecutor = getExecutor(
- _txn, collection, std::move(canonicalQuery.getValue()), PlanExecutor::YIELD_AUTO);
- if (!statusWithPlanExecutor.isOK()) {
- return statusWithPlanExecutor.getStatus();
- }
- _exec = std::move(statusWithPlanExecutor.getValue());
- _exec->saveState();
-
- return Status::OK();
-}
-
-StatusWith<boost::optional<BSONObj>> LocalClient::LocalCursor::next() {
- // If _exec is not set, an error occurred or the cursor was exhausted on the previous call.
- invariant(_exec);
- // This function does its own locking, so the lock should not be held.
- invariant(!_txn->lockState()->isLocked());
- AutoGetCollection ctx(_txn, _nss, MODE_IS);
-
- if (!_exec->restoreState()) {
- _exec.reset();
- return {ErrorCodes::OperationFailed,
- str::stream()
- << "PlanExecutor could not be restored in LocalClient::LocalCursor::next()"};
- }
-
- BSONObj doc;
- PlanExecutor::ExecState state = _exec->getNext(&doc, NULL);
-
- if (state == PlanExecutor::IS_EOF) {
- _exec.reset();
- return {boost::none};
- }
-
- if (state != PlanExecutor::ADVANCED) {
- _exec.reset();
- return {ErrorCodes::OperationFailed,
- str::stream() << "PlanExecutor error: " << WorkingSetCommon::toStatusString(doc)};
- }
-
- doc = doc.getOwned();
- _exec->saveState();
-
- return {doc};
-}
-
-} // namespace mongo
diff --git a/src/mongo/db/local_client.h b/src/mongo/db/local_client.h
deleted file mode 100644
index 3b385f9fcee..00000000000
--- a/src/mongo/db/local_client.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/**
- * 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/base/disallow_copying.h"
-#include "mongo/base/status_with.h"
-#include "mongo/bson/bsonobj.h"
-#include "mongo/db/namespace_string.h"
-
-namespace mongo {
-
-class OperationContext;
-class PlanExecutor;
-
-/**
- * LocalClient handles local -- not over the network -- queries and writes. It acquires all
- * necessary collection locks: these locks should not be held by the caller.
- *
- * LocalClient is associated with a particular OperationContext and should not be passed between
- * threads.
- */
-class LocalClient {
- MONGO_DISALLOW_COPYING(LocalClient);
-
-public:
- class LocalCursor;
-
- LocalClient(OperationContext* txn);
-
- /**
- * Sets up a local find query. Returns a LocalCursor object from which to request the next
- * document that matches "query" in order "sort" from collection "nss".
- *
- * The caller should not hold the collection lock: locking is handled internally.
- */
- StatusWith<LocalCursor> query(const NamespaceString& nss,
- const BSONObj& query,
- const BSONObj& sort);
-
- /**
- * LocalCursor sets up and executes a local find query.
- *
- * Collection locking is handled internally. Lock is released between next() calls.
- *
- * The caller need only request the next document after instantiating the LocalCursor and
- * calling init().
- */
- class LocalCursor {
- public:
- friend class LocalClient;
-
-#if defined(_MSC_VER) && _MSC_VER < 1900
- LocalCursor(LocalCursor&& other);
- LocalCursor& operator=(LocalCursor&& other);
-#else
- LocalCursor(LocalCursor&& other) = default;
- LocalCursor& operator=(LocalCursor&& other) = default;
-#endif
-
- /**
- * Seeks the next document that matches the query. Returns an error Status or an optional
- * BSONObj. If optional is empty, there are no more documents that match "_query";
- * otherwise the next document is returned.
- *
- * ErrorCodes::OperationFailed is returned if the PlanExecutor encounters an unrecoverable
- * error or something happens to the collection -- such as an index or the collection
- * itself being dropped -- between calls or when the PlanExecutor yields.
- *
- * Locking is handled internally: expects the collection lock not to be held.
- */
- StatusWith<boost::optional<BSONObj>> next();
-
- private:
- /**
- * Instantiates a LocalCursor that returns documents from collection "nss" matching "query"
- * in the "sort" order.
- */
- LocalCursor(OperationContext* txn,
- const NamespaceString& nss,
- const BSONObj& query,
- const BSONObj& sort);
-
- /**
- * Attempts to set up the find query, returns a Status to indicate success or failure.
- *
- * Locking is handled internally: expects the collection lock not to be held.
- */
- Status _init();
-
- OperationContext* _txn;
-
- // The collection in which to search.
- NamespaceString _nss;
-
- // Contains the query that selects documents to return.
- BSONObj _query;
-
- // Contains the sort order information.
- BSONObj _sort;
-
- // Find query PlanExecutor from which to request the next document.
- std::unique_ptr<PlanExecutor> _exec;
- };
-
-private:
- OperationContext* const _txn;
-};
-
-} // namespace mongo
diff --git a/src/mongo/db/local_client_test.cpp b/src/mongo/db/local_client_test.cpp
deleted file mode 100644
index 3b77b81701b..00000000000
--- a/src/mongo/db/local_client_test.cpp
+++ /dev/null
@@ -1,183 +0,0 @@
-/**
- * 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/local_client.h"
-
-#include <boost/optional.hpp>
-
-#include "mongo/base/checked_cast.h"
-#include "mongo/db/client.h"
-#include "mongo/db/catalog/collection.h"
-#include "mongo/db/catalog/database_holder.h"
-#include "mongo/db/db_raii.h"
-#include "mongo/db/service_context.h"
-#include "mongo/db/service_context_d.h"
-#include "mongo/db/repl/replication_coordinator_global.h"
-#include "mongo/db/repl/replication_coordinator_mock.h"
-#include "mongo/unittest/temp_dir.h"
-#include "mongo/unittest/unittest.h"
-
-namespace mongo {
-namespace {
-
-using unittest::assertGet;
-
-class LocalClientTest : public unittest::Test {
-protected:
- ServiceContext::UniqueOperationContext _txn;
-
-private:
- void setUp() override;
- void tearDown() override;
-};
-
-void LocalClientTest::setUp() {
- ServiceContext* serviceContext = getGlobalServiceContext();
- if (!serviceContext->getGlobalStorageEngine()) {
- // When using the 'devnull' storage engine, it is fine for the temporary directory to
- // go away after the global storage engine is initialized.
- unittest::TempDir tempDir("local_client_test");
- storageGlobalParams.dbpath = tempDir.path();
- storageGlobalParams.dbpath = tempDir.path();
- storageGlobalParams.engine = "ephemeralForTest";
- storageGlobalParams.engineSetByUser = true;
- checked_cast<ServiceContextMongoD*>(getGlobalServiceContext())->createLockFile();
- serviceContext->initializeGlobalStorageEngine();
- }
- Client::initThreadIfNotAlready();
- _txn = serviceContext->makeOperationContext(&cc());
-
- const repl::ReplSettings replSettings = {};
- repl::setGlobalReplicationCoordinator(new repl::ReplicationCoordinatorMock(replSettings));
-}
-
-void LocalClientTest::tearDown() {
- {
- Lock::GlobalWrite globalLock(_txn->lockState());
- BSONObjBuilder unused;
- invariant(dbHolder().closeAll(_txn.get(), unused, false));
- }
- _txn.reset();
- repl::setGlobalReplicationCoordinator(nullptr);
-}
-
-/**
- * Sets up a collection "nss" and populates it with documents.
- */
-void setUpCollection(OperationContext* txn,
- const NamespaceString& nss,
- std::vector<BSONObj> documentVector) {
- AutoGetOrCreateDb autoDb(txn, nss.db(), MODE_X);
- WriteUnitOfWork wuow(txn);
- auto coll = autoDb.getDb()->getCollection(nss.ns());
- if (!coll) {
- coll = autoDb.getDb()->createCollection(txn, nss.ns());
- }
- ASSERT(coll);
- for (const BSONObj& doc : documentVector) {
- ASSERT_OK(coll->insertDocument(txn, doc, false));
- }
- wuow.commit();
-}
-
-/**
- * Drops collection "nss".
- */
-void dropCollection(OperationContext* txn, const NamespaceString& nss) {
- AutoGetOrCreateDb autoDb(txn, nss.db(), MODE_X);
- ASSERT_EQUALS(Status::OK(), autoDb.getDb()->dropCollection(txn, nss.ns()));
-}
-
-// Successful ordered find query.
-TEST_F(LocalClientTest, FindQuerySuccessful) {
- LocalClient localClient(_txn.get());
- NamespaceString nss("test.foo");
- BSONObj firstDocument = BSON("_id" << 1 << "v" << 2);
- BSONObj secondDocument = BSON("_id" << 4 << "v" << 2);
- std::vector<BSONObj> documentVector = {firstDocument, secondDocument};
- setUpCollection(_txn.get(), nss, documentVector);
-
- // Set up find query that matches documents in the collection.
- StatusWith<LocalClient::LocalCursor> localCursor =
- localClient.query(nss, BSON("v" << 2), BSON("_id" << 1));
- ASSERT_OK(localCursor.getStatus());
-
- // Retrieve the first document and check it.
- boost::optional<BSONObj> document = assertGet(localCursor.getValue().next());
- ASSERT_TRUE(document);
- ASSERT_EQUALS(*document, firstDocument);
-
- // Retrieve the second document and check it.
- document = assertGet(localCursor.getValue().next());
- ASSERT_TRUE(document);
- ASSERT_EQUALS(*document, secondDocument);
-
- // Check that the cursor is exhausted: no more documents to retrieve.
- document = assertGet(localCursor.getValue().next());
- ASSERT_FALSE(document);
-
- dropCollection(_txn.get(), nss);
-}
-
-// No documents match the find query.
-TEST_F(LocalClientTest, FindQueryNoDocumentsFound) {
- LocalClient localClient(_txn.get());
- NamespaceString nss("test.foo");
- std::vector<BSONObj> documentVector = {BSON("_id" << 1 << "v" << 2)};
- setUpCollection(_txn.get(), nss, documentVector);
-
- // Set up find query that does not match any documents in the collection.
- StatusWith<LocalClient::LocalCursor> localCursor =
- localClient.query(nss, BSON("v" << 4), BSON("_id" << 1));
- ASSERT_OK(localCursor.getStatus());
-
- // Request the next document and receive nothing, with no errors.
- boost::optional<BSONObj> document = assertGet(localCursor.getValue().next());
- ASSERT_FALSE(document);
-
- dropCollection(_txn.get(), nss);
-}
-
-// Collection being queried does not exist.
-TEST_F(LocalClientTest, FindQueryInitNoCollection) {
- LocalClient localClient(_txn.get());
-
- // Set up find query on a non-existent collection.
- StatusWith<LocalClient::LocalCursor> localCursor =
- localClient.query(NamespaceString("test.bam"), BSON("v" << 4), BSON("_id" << 1));
- ASSERT_OK(localCursor.getStatus());
-
- // Request the next document and receive nothing, with no errors.
- boost::optional<BSONObj> document = assertGet(localCursor.getValue().next());
- ASSERT_FALSE(document);
-}
-
-} // namespace
-} // namespace mongo