diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2016-03-29 15:23:52 -0400 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2016-03-30 10:16:17 -0400 |
commit | 064c45a6a0688700d7836038db8057cda559dbd6 (patch) | |
tree | 17ac22e471cc6bb143f57d970151e5035285505e | |
parent | 38b1b8a675993d2d12ffba5976c7344223b56640 (diff) | |
download | mongo-064c45a6a0688700d7836038db8057cda559dbd6.tar.gz |
SERVER-23407 Get rid of public fields in the Command class
-rw-r--r-- | src/mongo/db/SConscript | 4 | ||||
-rw-r--r-- | src/mongo/db/commands.cpp | 36 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 63 | ||||
-rw-r--r-- | src/mongo/db/commands/apply_ops_cmd.cpp (renamed from src/mongo/db/commands/apply_ops.cpp) | 68 | ||||
-rw-r--r-- | src/mongo/db/commands/create_indexes.cpp | 57 | ||||
-rw-r--r-- | src/mongo/db/commands/dbhash.cpp | 333 | ||||
-rw-r--r-- | src/mongo/db/commands/dbhash.h | 97 | ||||
-rw-r--r-- | src/mongo/db/commands/generic.cpp | 58 | ||||
-rw-r--r-- | src/mongo/db/commands/list_collections.cpp | 62 | ||||
-rw-r--r-- | src/mongo/db/commands/list_indexes.cpp | 76 | ||||
-rw-r--r-- | src/mongo/db/commands/parallel_collection_scan.cpp | 64 | ||||
-rw-r--r-- | src/mongo/db/commands/rename_collection_cmd.cpp (renamed from src/mongo/db/commands/rename_collection.cpp) | 62 | ||||
-rw-r--r-- | src/mongo/db/curop.cpp | 3 | ||||
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 3 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_user_management_commands.cpp | 42 | ||||
-rw-r--r-- | src/mongo/s/commands/commands_public.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/s_only.cpp | 4 |
17 files changed, 515 insertions, 519 deletions
diff --git a/src/mongo/db/SConscript b/src/mongo/db/SConscript index ce10e87b829..2efb14bf209 100644 --- a/src/mongo/db/SConscript +++ b/src/mongo/db/SConscript @@ -553,7 +553,7 @@ serverOnlyFiles = [ "catalog/rename_collection.cpp", "clientcursor.cpp", "cloner.cpp", - "commands/apply_ops.cpp", + "commands/apply_ops_cmd.cpp", "commands/clone.cpp", "commands/clone_collection.cpp", "commands/collection_to_capped.cpp", @@ -585,7 +585,7 @@ serverOnlyFiles = [ "commands/parallel_collection_scan.cpp", "commands/pipeline_command.cpp", "commands/plan_cache_commands.cpp", - "commands/rename_collection.cpp", + "commands/rename_collection_cmd.cpp", "commands/repair_cursor.cpp", "commands/snapshot_management.cpp", "commands/test_commands.cpp", diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index e346fbdffe2..82f533d629e 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -68,9 +68,11 @@ static ServerStatusMetricField<Counter64> displayUnknownCommands("commands.<UNKN &Command::unknownCommands); namespace { + ExportedServerParameter<bool, ServerParameterType::kStartupOnly> testCommandsParameter( ServerParameterSet::getGlobal(), "enableTestCommands", &Command::testCommandsEnabled); -} + +} // namespace Command::~Command() = default; @@ -130,10 +132,10 @@ void Command::htmlHelp(stringstream& ss) const { helpStr = h.str(); } ss << "\n<tr><td>"; - bool web = _webCommands->find(name) != _webCommands->end(); + bool web = _webCommands->find(getName()) != _webCommands->end(); if (web) - ss << "<a href=\"/" << name << "?text=1\">"; - ss << name; + ss << "<a href=\"/" << getName() << "?text=1\">"; + ss << getName(); if (web) ss << "</a>"; ss << "</td>\n"; @@ -190,10 +192,10 @@ void Command::htmlHelp(stringstream& ss) const { ss << "</tr>\n"; } -Command::Command(StringData _name, bool web, StringData oldName) - : name(_name.toString()), - _commandsExecutedMetric("commands." + _name.toString() + ".total", &_commandsExecuted), - _commandsFailedMetric("commands." + _name.toString() + ".failed", &_commandsFailed) { +Command::Command(StringData name, bool web, StringData oldName) + : _name(name.toString()), + _commandsExecutedMetric("commands." + _name + ".total", &_commandsExecuted), + _commandsFailedMetric("commands." + _name + ".failed", &_commandsFailed) { // register ourself. if (_commands == 0) _commands = new CommandMap(); @@ -219,6 +221,15 @@ void Command::help(stringstream& help) const { help << "no help defined"; } +Status Command::explain(OperationContext* txn, + const string& dbname, + const BSONObj& cmdObj, + ExplainCommon::Verbosity verbosity, + const rpc::ServerSelectionMetadata& serverSelectionMetadata, + BSONObjBuilder* out) const { + return {ErrorCodes::IllegalOperation, str::stream() << "Cannot explain cmd: " << getName()}; +} + Command* Command::findCommand(StringData name) { CommandMap::const_iterator i = _commands->find(name); if (i == _commands->end()) @@ -327,7 +338,8 @@ static Status _checkAuthorizationImpl(Command* c, namespace mmb = mutablebson; if (c->adminOnly() && dbname != "admin") { return Status(ErrorCodes::Unauthorized, - str::stream() << c->name << " may only be run against the admin database."); + str::stream() << c->getName() + << " may only be run against the admin database."); } if (AuthorizationSession::get(client)->getAuthorizationManager().isAuthEnabled()) { Status status = c->checkAuthForCommand(client, dbname, cmdObj); @@ -344,14 +356,14 @@ static Status _checkAuthorizationImpl(Command* c, } else if (c->adminOnly() && c->localHostOnlyIfNoAuth(cmdObj) && !client->getIsLocalHostConnection()) { return Status(ErrorCodes::Unauthorized, - str::stream() << c->name + str::stream() << c->getName() << " must run from localhost when running db without auth"); } return Status::OK(); } Status Command::_checkAuthorization(Command* c, - ClientBasic* client, + Client* client, const std::string& dbname, const BSONObj& cmdObj) { namespace mmb = mutablebson; @@ -375,7 +387,7 @@ void Command::generateHelpResponse(OperationContext* txn, const Command& command) { std::stringstream ss; BSONObjBuilder helpBuilder; - ss << "help for: " << command.name << " "; + ss << "help for: " << command.getName() << " "; command.help(ss); helpBuilder.append("help", ss.str()); diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index b9953e7cb3d..5d26450a01d 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -1,6 +1,5 @@ -// commands.h - -/* Copyright 2009 10gen Inc. +/** + * Copyright (C) 2009-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, @@ -50,8 +49,6 @@ namespace mongo { class BSONObj; class BSONObjBuilder; class Client; -class CurOp; -class Database; class OperationContext; class Timer; @@ -63,9 +60,9 @@ namespace rpc { class ServerSelectionMetadata; } // namespace rpc -/** mongodb "commands" (sent via db.$cmd.findOne(...)) - subclass to make a command. define a singleton object for it. - */ +/** + * Serves as a base for server commands. See the constructor for more details. + */ class Command { protected: // The type of the first field in 'cmdObj' must be mongo::String. The first field is @@ -79,10 +76,26 @@ protected: public: typedef StringMap<Command*> CommandMap; + /** + * Constructs a new command and causes it to be registered with the global commands list. It is + * not safe to construct commands other than when the server is starting up. + * + * @param webUI expose the command in the web ui as localhost:28017/<name> + * @param oldName an optional old, deprecated name for the command + */ + Command(StringData name, bool webUI = false, StringData oldName = StringData()); + // NOTE: Do not remove this declaration, or relocate it in this class. We // are using this method to control where the vtable is emitted. virtual ~Command(); + /** + * Returns the command's name. This value never changes for the lifetime of the command. + */ + const std::string& getName() const { + return _name; + } + // Return the namespace for the command. If the first field in 'cmdObj' is of type // mongo::String, then that field is interpreted as the collection name, and is // appended to 'dbname' after a '.' character. If the first field is not of type @@ -99,8 +112,6 @@ public: return 0u; } - const std::string name; - /* run the given command implement this... @@ -119,9 +130,9 @@ public: * Then we won't need to mutate the command object. At that point we can also make * this method virtual so commands can override it directly. */ - /*virtual*/ bool run(OperationContext* txn, - const rpc::RequestInterface& request, - rpc::ReplyBuilderInterface* replyBuilder); + bool run(OperationContext* txn, + const rpc::RequestInterface& request, + rpc::ReplyBuilderInterface* replyBuilder); /* Return true if only the admin ns has privileges to run this command. */ virtual bool adminOnly() const { @@ -183,9 +194,7 @@ public: const BSONObj& cmdObj, ExplainCommon::Verbosity verbosity, const rpc::ServerSelectionMetadata& serverSelectionMetadata, - BSONObjBuilder* out) const { - return Status(ErrorCodes::IllegalOperation, "Cannot explain cmd: " + name); - } + BSONObjBuilder* out) const; /** * Checks if the given client is authorized to run this command on database "dbname" @@ -242,11 +251,6 @@ public: return LogicalOp::opCommand; } - /** @param webUI expose the command in the web ui as localhost:28017/<name> - @param oldName an optional old, deprecated name for the command - */ - Command(StringData _name, bool webUI = false, StringData oldName = StringData()); - protected: /** * Appends to "*out" the privileges required to run this command on database "dbname" with @@ -268,14 +272,11 @@ protected: Counter64 _commandsExecuted; Counter64 _commandsFailed; - // Pointers to hold the metrics tree references - ServerStatusMetricField<Counter64> _commandsExecutedMetric; - ServerStatusMetricField<Counter64> _commandsFailedMetric; - public: static const CommandMap* commandsByBestName() { return _commandsByBestName; } + static const CommandMap* webCommands() { return _webCommands; } @@ -288,6 +289,7 @@ public: BSONObj& jsobj, BSONObjBuilder& anObjBuilder, int queryOptions = 0); + static Command* findCommand(StringData name); /** @@ -309,7 +311,7 @@ public: // of Client. This will happen as part of SERVER-18292 static void execCommandClientBasic(OperationContext* txn, Command* c, - ClientBasic& client, + Client& client, int queryOptions, const char* ns, BSONObj& cmdObj, @@ -435,9 +437,16 @@ private: * authorized. */ static Status _checkAuthorization(Command* c, - ClientBasic* client, + Client* client, const std::string& dbname, const BSONObj& cmdObj); + + // The full name of the command + const std::string _name; + + // Pointers to hold the metrics tree references + ServerStatusMetricField<Counter64> _commandsExecutedMetric; + ServerStatusMetricField<Counter64> _commandsFailedMetric; }; } // namespace mongo diff --git a/src/mongo/db/commands/apply_ops.cpp b/src/mongo/db/commands/apply_ops_cmd.cpp index 4b5e53e5225..2301916ef6c 100644 --- a/src/mongo/db/commands/apply_ops.cpp +++ b/src/mongo/db/commands/apply_ops_cmd.cpp @@ -1,36 +1,35 @@ /** -* Copyright (C) 2008 10gen 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. -*/ + * Copyright (C) 2008-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. + */ #define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand #include "mongo/platform/basic.h" -#include <sstream> #include <string> #include <vector> @@ -50,8 +49,7 @@ #include "mongo/db/service_context.h" #include "mongo/db/jsobj.h" #include "mongo/db/matcher/matcher.h" -#include "mongo/db/operation_context_impl.h" -#include "mongo/db/op_observer.h" +#include "mongo/db/operation_context.h" #include "mongo/db/repl/oplog.h" #include "mongo/db/repl/repl_client_info.h" #include "mongo/db/repl/replication_coordinator_global.h" @@ -64,23 +62,28 @@ namespace mongo { using std::string; using std::stringstream; +namespace { + class ApplyOpsCmd : public Command { public: + ApplyOpsCmd() : Command("applyOps") {} + virtual bool slaveOk() const { return false; } - ApplyOpsCmd() : Command("applyOps") {} virtual void help(stringstream& help) const { help << "internal (sharding)\n{ applyOps : [ ] , preCondition : [ { ns : ... , q : ... , " "res : ... } ] }"; } + virtual void addRequiredPrivileges(const std::string& dbname, const BSONObj& cmdObj, std::vector<Privilege>* out) { // applyOps can do pretty much anything, so require all privileges. RoleGraph::generateUniversalPrivileges(out); } + virtual bool run(OperationContext* txn, const string& dbname, BSONObj& cmdObj, @@ -195,5 +198,8 @@ private: } return true; } + } applyOpsCmd; -} + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp index 4ee3e3af167..cb1f09988d2 100644 --- a/src/mongo/db/commands/create_indexes.cpp +++ b/src/mongo/db/commands/create_indexes.cpp @@ -1,32 +1,30 @@ -// create_indexes.cpp - /** -* Copyright (C) 2013 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. -*/ + * Copyright (C) 2013-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" @@ -93,9 +91,8 @@ public: int options, string& errmsg, BSONObjBuilder& result) { - // --- parse + const NamespaceString ns(parseNs(dbname, cmdObj)); - NamespaceString ns(dbname, cmdObj[name].String()); Status status = userAllowedWriteNS(ns); if (!status.isOK()) return appendCommandStatus(result, status); diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp index 276c46c206f..dcb63a5936c 100644 --- a/src/mongo/db/commands/dbhash.cpp +++ b/src/mongo/db/commands/dbhash.cpp @@ -30,221 +30,234 @@ #define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand +#include "mongo/platform/basic.h" + #include "mongo/db/commands/dbhash.h" +#include <map> +#include <string> #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/database.h" #include "mongo/db/catalog/database_catalog_entry.h" -#include "mongo/db/client.h" #include "mongo/db/commands.h" #include "mongo/db/db_raii.h" #include "mongo/db/exec/working_set_common.h" #include "mongo/db/namespace_string.h" #include "mongo/db/query/internal_plans.h" +#include "mongo/stdx/mutex.h" #include "mongo/util/log.h" #include "mongo/util/md5.hpp" #include "mongo/util/timer.h" namespace mongo { -using std::endl; using std::list; using std::set; using std::string; using std::unique_ptr; using std::vector; -DBHashCmd dbhashCmd; - - -void logOpForDbHash(OperationContext* txn, const char* ns) { - NamespaceString nsString(ns); - dbhashCmd.wipeCacheForCollection(txn, nsString); -} - -// ---- - -DBHashCmd::DBHashCmd() : Command("dbHash", false, "dbhash") {} - -void DBHashCmd::addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) { - ActionSet actions; - actions.addAction(ActionType::dbHash); - out->push_back(Privilege(ResourcePattern::forDatabaseName(dbname), actions)); -} - -std::string DBHashCmd::hashCollection(OperationContext* opCtx, - Database* db, - const std::string& fullCollectionName, - bool* fromCache) { - stdx::unique_lock<stdx::mutex> cachedHashedLock(_cachedHashedMutex, stdx::defer_lock); +namespace { - NamespaceString ns(fullCollectionName); +class DBHashCmd : public Command { +public: + DBHashCmd() : Command("dbHash", false, "dbhash") {} - if (isCachable(ns)) { - cachedHashedLock.lock(); - string hash = _cachedHashed[ns.db().toString()][ns.coll().toString()]; - if (hash.size() > 0) { - *fromCache = true; - return hash; - } + virtual bool slaveOk() const { + return true; } - *fromCache = false; - Collection* collection = db->getCollection(fullCollectionName); - if (!collection) - return ""; - - IndexDescriptor* desc = collection->getIndexCatalog()->findIdIndex(opCtx); - - unique_ptr<PlanExecutor> exec; - if (desc) { - exec = InternalPlanner::indexScan(opCtx, - collection, - desc, - BSONObj(), - BSONObj(), - false, // endKeyInclusive - PlanExecutor::YIELD_MANUAL, - InternalPlanner::FORWARD, - InternalPlanner::IXSCAN_FETCH); - } else if (collection->isCapped()) { - exec = InternalPlanner::collectionScan( - opCtx, fullCollectionName, collection, PlanExecutor::YIELD_MANUAL); - } else { - log() << "can't find _id index for: " << fullCollectionName << endl; - return "no _id _index"; + virtual void addRequiredPrivileges(const std::string& dbname, + const BSONObj& cmdObj, + std::vector<Privilege>* out) { + ActionSet actions; + actions.addAction(ActionType::dbHash); + out->push_back(Privilege(ResourcePattern::forDatabaseName(dbname), actions)); } - md5_state_t st; - md5_init(&st); + virtual bool run(OperationContext* txn, + const string& dbname, + BSONObj& cmdObj, + int, + string& errmsg, + BSONObjBuilder& result) { + Timer timer; + + set<string> desiredCollections; + if (cmdObj["collections"].type() == Array) { + BSONObjIterator i(cmdObj["collections"].Obj()); + while (i.more()) { + BSONElement e = i.next(); + if (e.type() != String) { + errmsg = "collections entries have to be strings"; + return false; + } + desiredCollections.insert(e.String()); + } + } - long long n = 0; - PlanExecutor::ExecState state; - BSONObj c; - verify(NULL != exec.get()); - while (PlanExecutor::ADVANCED == (state = exec->getNext(&c, NULL))) { - md5_append(&st, (const md5_byte_t*)c.objdata(), c.objsize()); - n++; - } - if (PlanExecutor::IS_EOF != state) { - warning() << "error while hashing, db dropped? ns=" << fullCollectionName << endl; - uasserted(34371, - "Plan executor error while running dbHash command: " + - WorkingSetCommon::toStatusString(c)); - } - md5digest d; - md5_finish(&st, d); - string hash = digestToString(d); + list<string> colls; + const string ns = parseNs(dbname, cmdObj); + + // We lock the entire database in S-mode in order to ensure that the contents will not + // change for the snapshot. + ScopedTransaction scopedXact(txn, MODE_IS); + AutoGetDb autoDb(txn, ns, MODE_S); + Database* db = autoDb.getDb(); + if (db) { + db->getDatabaseCatalogEntry()->getCollectionNamespaces(&colls); + colls.sort(); + } - if (cachedHashedLock.owns_lock()) { - _cachedHashed[ns.db().toString()][ns.coll().toString()] = hash; - } + result.append("host", prettyHostName()); - return hash; -} + md5_state_t globalState; + md5_init(&globalState); + + vector<string> cached; -bool DBHashCmd::run(OperationContext* txn, - const string& dbname, - BSONObj& cmdObj, - int, - string& errmsg, - BSONObjBuilder& result) { - Timer timer; - - set<string> desiredCollections; - if (cmdObj["collections"].type() == Array) { - BSONObjIterator i(cmdObj["collections"].Obj()); - while (i.more()) { - BSONElement e = i.next(); - if (e.type() != String) { - errmsg = "collections entries have to be strings"; + BSONObjBuilder bb(result.subobjStart("collections")); + for (list<string>::iterator i = colls.begin(); i != colls.end(); i++) { + string fullCollectionName = *i; + if (fullCollectionName.size() - 1 <= dbname.size()) { + errmsg = str::stream() << "weird fullCollectionName [" << fullCollectionName << "]"; return false; } - desiredCollections.insert(e.String()); - } - } + string shortCollectionName = fullCollectionName.substr(dbname.size() + 1); - list<string> colls; - const string ns = parseNs(dbname, cmdObj); - - // We lock the entire database in S-mode in order to ensure that the contents will not - // change for the snapshot. - ScopedTransaction scopedXact(txn, MODE_IS); - AutoGetDb autoDb(txn, ns, MODE_S); - Database* db = autoDb.getDb(); - if (db) { - db->getDatabaseCatalogEntry()->getCollectionNamespaces(&colls); - colls.sort(); - } + if (shortCollectionName.find("system.") == 0) + continue; - result.append("host", prettyHostName()); + if (desiredCollections.size() > 0 && desiredCollections.count(shortCollectionName) == 0) + continue; - md5_state_t globalState; - md5_init(&globalState); + bool fromCache = false; + string hash = _hashCollection(txn, db, fullCollectionName, &fromCache); - vector<string> cached; + bb.append(shortCollectionName, hash); - BSONObjBuilder bb(result.subobjStart("collections")); - for (list<string>::iterator i = colls.begin(); i != colls.end(); i++) { - string fullCollectionName = *i; - if (fullCollectionName.size() - 1 <= dbname.size()) { - errmsg = str::stream() << "weird fullCollectionName [" << fullCollectionName << "]"; - return false; + md5_append(&globalState, (const md5_byte_t*)hash.c_str(), hash.size()); + if (fromCache) + cached.push_back(fullCollectionName); } - string shortCollectionName = fullCollectionName.substr(dbname.size() + 1); + bb.done(); - if (shortCollectionName.find("system.") == 0) - continue; + md5digest d; + md5_finish(&globalState, d); + string hash = digestToString(d); - if (desiredCollections.size() > 0 && desiredCollections.count(shortCollectionName) == 0) - continue; + result.append("md5", hash); + result.appendNumber("timeMillis", timer.millis()); - bool fromCache = false; - string hash = hashCollection(txn, db, fullCollectionName, &fromCache); + result.append("fromCache", cached); - bb.append(shortCollectionName, hash); + return 1; + } - md5_append(&globalState, (const md5_byte_t*)hash.c_str(), hash.size()); - if (fromCache) - cached.push_back(fullCollectionName); + void wipeCacheForCollection(OperationContext* txn, const NamespaceString& ns) { + if (!_isCachable(ns)) + return; + + txn->recoveryUnit()->onCommit([this, txn, ns] { + stdx::lock_guard<stdx::mutex> lk(_cachedHashedMutex); + if (ns.isCommand()) { + // The <dbName>.$cmd namespace can represent a command that + // modifies the entire database, e.g. dropDatabase, so we remove + // the cached entries for all collections in the database. + _cachedHashed.erase(ns.db().toString()); + } else { + _cachedHashed[ns.db().toString()].erase(ns.coll().toString()); + } + }); } - bb.done(); - md5digest d; - md5_finish(&globalState, d); - string hash = digestToString(d); +private: + bool _isCachable(const NamespaceString& ns) const { + return ns.isConfigDB(); + } - result.append("md5", hash); - result.appendNumber("timeMillis", timer.millis()); + std::string _hashCollection(OperationContext* opCtx, + Database* db, + const std::string& fullCollectionName, + bool* fromCache) { + stdx::unique_lock<stdx::mutex> cachedHashedLock(_cachedHashedMutex, stdx::defer_lock); - result.append("fromCache", cached); + NamespaceString ns(fullCollectionName); - return 1; -} + if (_isCachable(ns)) { + cachedHashedLock.lock(); + string hash = _cachedHashed[ns.db().toString()][ns.coll().toString()]; + if (hash.size() > 0) { + *fromCache = true; + return hash; + } + } -void DBHashCmd::wipeCacheForCollection(OperationContext* txn, const NamespaceString& ns) { - if (!isCachable(ns)) - return; - - txn->recoveryUnit()->onCommit([this, txn, ns] { - stdx::lock_guard<stdx::mutex> lk(_cachedHashedMutex); - if (ns.isCommand()) { - // The <dbName>.$cmd namespace can represent a command that - // modifies the entire database, e.g. dropDatabase, so we remove - // the cached entries for all collections in the database. - _cachedHashed.erase(ns.db().toString()); + *fromCache = false; + Collection* collection = db->getCollection(fullCollectionName); + if (!collection) + return ""; + + IndexDescriptor* desc = collection->getIndexCatalog()->findIdIndex(opCtx); + + unique_ptr<PlanExecutor> exec; + if (desc) { + exec = InternalPlanner::indexScan(opCtx, + collection, + desc, + BSONObj(), + BSONObj(), + false, // endKeyInclusive + PlanExecutor::YIELD_MANUAL, + InternalPlanner::FORWARD, + InternalPlanner::IXSCAN_FETCH); + } else if (collection->isCapped()) { + exec = InternalPlanner::collectionScan( + opCtx, fullCollectionName, collection, PlanExecutor::YIELD_MANUAL); } else { - _cachedHashed[ns.db().toString()].erase(ns.coll().toString()); + log() << "can't find _id index for: " << fullCollectionName; + return "no _id _index"; } + md5_state_t st; + md5_init(&st); - }); -} + long long n = 0; + PlanExecutor::ExecState state; + BSONObj c; + verify(NULL != exec.get()); + while (PlanExecutor::ADVANCED == (state = exec->getNext(&c, NULL))) { + md5_append(&st, (const md5_byte_t*)c.objdata(), c.objsize()); + n++; + } + if (PlanExecutor::IS_EOF != state) { + warning() << "error while hashing, db dropped? ns=" << fullCollectionName; + uasserted(34371, + "Plan executor error while running dbHash command: " + + WorkingSetCommon::toStatusString(c)); + } + md5digest d; + md5_finish(&st, d); + string hash = digestToString(d); -bool DBHashCmd::isCachable(const NamespaceString& ns) const { - return ns.isConfigDB(); -} + if (cachedHashedLock.owns_lock()) { + _cachedHashed[ns.db().toString()][ns.coll().toString()] = hash; + } + + return hash; + } + + stdx::mutex _cachedHashedMutex; + std::map<std::string, std::map<std::string, std::string>> _cachedHashed; + +} dbhashCmd; + +} // namespace + +void logOpForDbHash(OperationContext* txn, const char* ns) { + NamespaceString nsString(ns); + dbhashCmd.wipeCacheForCollection(txn, nsString); } + +} // namespace mongo diff --git a/src/mongo/db/commands/dbhash.h b/src/mongo/db/commands/dbhash.h index d496832f15a..2afc3efb454 100644 --- a/src/mongo/db/commands/dbhash.h +++ b/src/mongo/db/commands/dbhash.h @@ -1,78 +1,37 @@ -// dbhash.h - /** -* Copyright (C) 2013 10gen 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. -*/ + * Copyright (C) 2013-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/commands.h" -#include "mongo/stdx/mutex.h" - namespace mongo { -class NamespaceString; +class OperationContext; void logOpForDbHash(OperationContext* txn, const char* ns); -class DBHashCmd : public Command { -public: - DBHashCmd(); - - virtual bool slaveOk() const { - return true; - } - virtual void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out); - - virtual bool run(OperationContext* txn, - const std::string& dbname, - BSONObj& cmdObj, - int, - std::string& errmsg, - BSONObjBuilder& result); - - void wipeCacheForCollection(OperationContext* txn, const NamespaceString& ns); - -private: - /** - * RecoveryUnit::Change subclass used to commit work for dbhash logOp listener - */ - class DBHashLogOpHandler; - - bool isCachable(const NamespaceString& ns) const; - - std::string hashCollection(OperationContext* opCtx, - Database* db, - const std::string& fullCollectionName, - bool* fromCache); - - std::map<std::string, std::map<std::string, std::string>> _cachedHashed; - stdx::mutex _cachedHashedMutex; -}; -} +} // namespace mongo diff --git a/src/mongo/db/commands/generic.cpp b/src/mongo/db/commands/generic.cpp index c2459534f4d..9795e7f2b3e 100644 --- a/src/mongo/db/commands/generic.cpp +++ b/src/mongo/db/commands/generic.cpp @@ -1,30 +1,30 @@ /** -* Copyright (C) 2012 10gen 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. -*/ + * Copyright (C) 2012-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. + */ #define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kCommand @@ -259,16 +259,16 @@ public: std::vector<Command*> commands; for (CommandMap::const_iterator it = _commands->begin(); it != _commands->end(); ++it) { // don't show oldnames - if (it->first == it->second->name) + if (it->first == it->second->getName()) commands.push_back(it->second); } std::sort(commands.begin(), commands.end(), - [](Command* lhs, Command* rhs) { return (lhs->name) < (rhs->name); }); + [](Command* lhs, Command* rhs) { return (lhs->getName()) < (rhs->getName()); }); BSONObjBuilder b(result.subobjStart("commands")); for (const auto& c : commands) { - BSONObjBuilder temp(b.subobjStart(c->name)); + BSONObjBuilder temp(b.subobjStart(c->getName())); { stringstream help; diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index 7895de4510d..abd8302434f 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -1,32 +1,30 @@ -// list_collections.cpp - /** -* Copyright (C) 2014 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. -*/ + * Copyright (C) 2014-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" @@ -60,6 +58,7 @@ using std::vector; using stdx::make_unique; namespace { + /** * Determines if 'matcher' is an exact match on the "name" field. If so, returns a vector of all the * collection names it is matching against. Returns {} if there is no obvious exact match on name. @@ -138,7 +137,6 @@ void _addWorkingSetMember(OperationContext* txn, member->transitionToOwnedObj(); root->pushBack(id); } -} // namespace class CmdListCollections : public Command { public: @@ -227,7 +225,7 @@ public: } } - std::string cursorNamespace = str::stream() << dbname << ".$cmd." << name; + const std::string cursorNamespace = str::stream() << dbname << ".$cmd." << getName(); dassert(NamespaceString(cursorNamespace).isValid()); dassert(NamespaceString(cursorNamespace).isListCollectionsCursorNS()); @@ -274,4 +272,6 @@ public: return true; } } cmdListCollections; -} + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp index 1fb0fb8ffca..5d443e98e4b 100644 --- a/src/mongo/db/commands/list_indexes.cpp +++ b/src/mongo/db/commands/list_indexes.cpp @@ -1,32 +1,30 @@ -// list_indexes.cpp - /** -* Copyright (C) 2014 10gen 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. -*/ + * Copyright (C) 2014-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" @@ -56,6 +54,8 @@ using std::unique_ptr; using std::vector; using stdx::make_unique; +namespace { + /** * Lists the indexes for a given collection. * @@ -116,17 +116,7 @@ public: int, string& errmsg, BSONObjBuilder& result) { - BSONElement first = cmdObj.firstElement(); - uassert(28528, - str::stream() << "Argument to listIndexes must be of type String, not " - << typeName(first.type()), - first.type() == String); - StringData collectionName = first.valueStringData(); - uassert(28529, - str::stream() << "Argument to listIndexes must be a collection name, " - << "not the empty string", - !collectionName.empty()); - const NamespaceString ns(dbname, collectionName); + const NamespaceString ns(parseNs(dbname, cmdObj)); const long long defaultBatchSize = std::numeric_limits<long long>::max(); long long batchSize; @@ -176,8 +166,8 @@ public: root->pushBack(id); } - std::string cursorNamespace = str::stream() << dbname << ".$cmd." << name << "." - << ns.coll(); + const std::string cursorNamespace = str::stream() << dbname << ".$cmd." << getName() << "." + << ns.coll(); dassert(NamespaceString(cursorNamespace).isValid()); dassert(NamespaceString(cursorNamespace).isListIndexesCursorNS()); dassert(ns == NamespaceString(cursorNamespace).getTargetNSForListIndexes()); @@ -226,4 +216,6 @@ public: } } cmdListIndexes; -} + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/commands/parallel_collection_scan.cpp b/src/mongo/db/commands/parallel_collection_scan.cpp index 9acaca45d2f..4ca7a131f60 100644 --- a/src/mongo/db/commands/parallel_collection_scan.cpp +++ b/src/mongo/db/commands/parallel_collection_scan.cpp @@ -1,32 +1,30 @@ -// parallel_collection_scan.cpp - /** -* Copyright (C) 2014 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. -*/ + * Copyright (C) 2014-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" @@ -48,6 +46,8 @@ using std::unique_ptr; using std::string; using stdx::make_unique; +namespace { + class ParallelCollectionScanCmd : public Command { public: struct ExtentInfo { @@ -56,8 +56,6 @@ public: size_t size; }; - // ------------------------------------------------ - ParallelCollectionScanCmd() : Command("parallelCollectionScan") {} virtual bool slaveOk() const { @@ -85,7 +83,7 @@ public: int options, string& errmsg, BSONObjBuilder& result) { - NamespaceString ns(dbname, cmdObj[name].String()); + const NamespaceString ns(parseNs(dbname, cmdObj)); AutoGetCollectionForRead ctx(txn, ns.ns()); @@ -162,4 +160,6 @@ public: return true; } } parallelCollectionScanCmd; -} + +} // namespace +} // namespace mongo diff --git a/src/mongo/db/commands/rename_collection.cpp b/src/mongo/db/commands/rename_collection_cmd.cpp index 4e4eef26434..b2b12c5fed3 100644 --- a/src/mongo/db/commands/rename_collection.cpp +++ b/src/mongo/db/commands/rename_collection_cmd.cpp @@ -1,32 +1,32 @@ -// rename_collection.cpp - /** -* Copyright (C) 2013-2014 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. -*/ + * Copyright (C) 2013-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/client/dbclientcursor.h" #include "mongo/db/catalog/collection.h" @@ -56,6 +56,8 @@ using std::min; using std::string; using std::stringstream; +namespace { + class CmdRenameCollection : public Command { public: CmdRenameCollection() : Command("renameCollection") {} @@ -88,7 +90,7 @@ public: int, string& errmsg, BSONObjBuilder& result) { - string source = cmdObj.getStringField(name.c_str()); + string source = cmdObj.getStringField(getName()); string target = cmdObj.getStringField("to"); if (!NamespaceString::validCollectionComponent(target.c_str())) { @@ -142,6 +144,8 @@ public: cmdObj["dropTarget"].trueValue(), cmdObj["stayTemp"].trueValue())); } + } cmdrenamecollection; +} // namespace } // namespace mongo diff --git a/src/mongo/db/curop.cpp b/src/mongo/db/curop.cpp index 50d41952ec3..dc9f819dc73 100644 --- a/src/mongo/db/curop.cpp +++ b/src/mongo/db/curop.cpp @@ -467,6 +467,7 @@ StringData getProtoString(int op) { #define OPDEBUG_TOSTRING_HELP_BOOL(x) \ if (x) \ s << " " #x ":" << (x) + string OpDebug::report(const CurOp& curop, const SingleThreadedLockStats& lockStats) const { StringBuilder s; if (iscommand) @@ -484,7 +485,7 @@ string OpDebug::report(const CurOp& curop, const SingleThreadedLockStats& lockSt if (curCommand) { mutablebson::Document cmdToLog(query, mutablebson::Document::kInPlaceDisabled); curCommand->redactForLogging(&cmdToLog); - s << curCommand->name << " "; + s << curCommand->getName() << " "; s << cmdToLog.toString(); } else { // Should not happen but we need to handle curCommand == NULL gracefully s << query.toString(); diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index e216b9f7823..d3b665dbd95 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -1380,7 +1380,7 @@ bool Command::run(OperationContext* txn, auto result = appendCommandStatus( inPlaceReplyBob, {ErrorCodes::InvalidOptions, - str::stream() << "Command " << name << " does not support " + str::stream() << "Command " << getName() << " does not support " << repl::ReadConcernArgs::kReadConcernFieldName}); inPlaceReplyBob.doneFast(); replyBuilder->setMetadata(rpc::makeEmptyMetadata()); @@ -1459,7 +1459,6 @@ bool Command::run(OperationContext* txn, // run expects const db std::string (can't bind to temporary) const std::string db = request.getDatabase().toString(); - // TODO: remove queryOptions parameter from command's run method. bool result = this->run(txn, db, cmd, 0, errmsg, inPlaceReplyBob); appendCommandStatus(inPlaceReplyBob, result, errmsg); diff --git a/src/mongo/s/commands/cluster_user_management_commands.cpp b/src/mongo/s/commands/cluster_user_management_commands.cpp index 0f435706e56..505dc9225c6 100644 --- a/src/mongo/s/commands/cluster_user_management_commands.cpp +++ b/src/mongo/s/commands/cluster_user_management_commands.cpp @@ -52,6 +52,8 @@ using std::string; using std::stringstream; using std::vector; +namespace { + class CmdCreateUser : public Command { public: CmdCreateUser() : Command("createUser") {} @@ -78,7 +80,7 @@ public: string& errmsg, BSONObjBuilder& result) { return grid.catalogManager(txn) - ->runUserManagementWriteCommand(txn, this->name, dbname, cmdObj, &result); + ->runUserManagementWriteCommand(txn, getName(), dbname, cmdObj, &result); } virtual void redactForLogging(mutablebson::Document* cmdObj) { @@ -113,12 +115,12 @@ public: string& errmsg, BSONObjBuilder& result) { auth::CreateOrUpdateUserArgs args; - Status status = auth::parseCreateOrUpdateUserCommands(cmdObj, this->name, dbname, &args); + Status status = auth::parseCreateOrUpdateUserCommands(cmdObj, getName(), dbname, &args); if (!status.isOK()) { return appendCommandStatus(result, status); } const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -166,7 +168,7 @@ public: return appendCommandStatus(result, status); } const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -203,7 +205,7 @@ public: string& errmsg, BSONObjBuilder& result) { const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -243,12 +245,12 @@ public: vector<RoleName> roles; BSONObj unusedWriteConcern; Status status = auth::parseRolePossessionManipulationCommands( - cmdObj, this->name, dbname, &userNameString, &roles, &unusedWriteConcern); + cmdObj, getName(), dbname, &userNameString, &roles, &unusedWriteConcern); if (!status.isOK()) { return appendCommandStatus(result, status); } const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -288,12 +290,12 @@ public: vector<RoleName> unusedRoles; BSONObj unusedWriteConcern; Status status = auth::parseRolePossessionManipulationCommands( - cmdObj, this->name, dbname, &userNameString, &unusedRoles, &unusedWriteConcern); + cmdObj, getName(), dbname, &userNameString, &unusedRoles, &unusedWriteConcern); if (!status.isOK()) { return appendCommandStatus(result, status); } const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -364,7 +366,7 @@ public: string& errmsg, BSONObjBuilder& result) { return grid.catalogManager(txn) - ->runUserManagementWriteCommand(txn, this->name, dbname, cmdObj, &result); + ->runUserManagementWriteCommand(txn, getName(), dbname, cmdObj, &result); } } cmdCreateRole; @@ -395,7 +397,7 @@ public: string& errmsg, BSONObjBuilder& result) { const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -432,7 +434,7 @@ public: string& errmsg, BSONObjBuilder& result) { const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -469,7 +471,7 @@ public: string& errmsg, BSONObjBuilder& result) { const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -506,7 +508,7 @@ public: string& errmsg, BSONObjBuilder& result) { const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -543,7 +545,7 @@ public: string& errmsg, BSONObjBuilder& result) { const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -583,7 +585,7 @@ public: string& errmsg, BSONObjBuilder& result) { const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -624,7 +626,7 @@ public: string& errmsg, BSONObjBuilder& result) { const bool ok = grid.catalogManager(txn)->runUserManagementWriteCommand( - txn, this->name, dbname, cmdObj, &result); + txn, getName(), dbname, cmdObj, &result); AuthorizationManager* authzManager = getGlobalAuthorizationManager(); invariant(authzManager); @@ -746,7 +748,7 @@ public: string& errmsg, BSONObjBuilder& result) { return grid.catalogManager(txn) - ->runUserManagementWriteCommand(txn, this->name, dbname, cmdObj, &result); + ->runUserManagementWriteCommand(txn, getName(), dbname, cmdObj, &result); } } cmdMergeAuthzCollections; @@ -820,7 +822,7 @@ public: BSONObjBuilder& result) { // Run the authSchemaUpgrade command on the config servers if (!grid.catalogManager(txn) - ->runUserManagementWriteCommand(txn, this->name, dbname, cmdObj, &result)) { + ->runUserManagementWriteCommand(txn, getName(), dbname, cmdObj, &result)) { return false; } @@ -838,6 +840,8 @@ public: } return true; } + } cmdAuthSchemaUpgrade; +} // namespace } // namespace mongo diff --git a/src/mongo/s/commands/commands_public.cpp b/src/mongo/s/commands/commands_public.cpp index eea06d2a3b5..39b9efdca74 100644 --- a/src/mongo/s/commands/commands_public.cpp +++ b/src/mongo/s/commands/commands_public.cpp @@ -236,7 +236,7 @@ public: return appendCommandStatus( result, Status(ErrorCodes::IllegalOperation, - str::stream() << "can't do command: " << name << " on sharded collection")); + str::stream() << "can't do command: " << getName() << " on sharded collection")); } }; diff --git a/src/mongo/s/s_only.cpp b/src/mongo/s/s_only.cpp index 26c62a577e3..ce2e049f468 100644 --- a/src/mongo/s/s_only.cpp +++ b/src/mongo/s/s_only.cpp @@ -93,7 +93,7 @@ void Command::execCommand(OperationContext* txn, void Command::execCommandClientBasic(OperationContext* txn, Command* c, - ClientBasic& client, + Client& client, int queryOptions, const char* ns, BSONObj& cmdObj, @@ -102,7 +102,7 @@ void Command::execCommandClientBasic(OperationContext* txn, if (cmdObj.getBoolField("help")) { stringstream help; - help << "help for: " << c->name << " "; + help << "help for: " << c->getName() << " "; c->help(help); result.append("help", help.str()); appendCommandStatus(result, true, ""); |