diff --git a/src/mongo/s/commands/SConscript b/src/mongo/s/commands/SConscript index d6fdfe45796..0a2f7b19a3c 100644 --- a/src/mongo/s/commands/SConscript +++ b/src/mongo/s/commands/SConscript @@ -8,6 +8,7 @@ env.Library( 'cluster_add_shard_cmd.cpp', 'cluster_commands_common.cpp', 'cluster_count_cmd.cpp', + 'cluster_drop_database_cmd.cpp', 'cluster_enable_sharding_cmd.cpp', 'cluster_explain_cmd.cpp', 'cluster_find_cmd.cpp', diff --git a/src/mongo/s/commands/cluster_drop_database_cmd.cpp b/src/mongo/s/commands/cluster_drop_database_cmd.cpp new file mode 100644 index 00000000000..92644cb1887 --- /dev/null +++ b/src/mongo/s/commands/cluster_drop_database_cmd.cpp @@ -0,0 +1,135 @@ +/** + * Copyright (C) 2015 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 . + * + * 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 "mongo/base/status.h" +#include "mongo/db/commands.h" +#include "mongo/s/config.h" +#include "mongo/s/grid.h" +#include "mongo/util/log.h" + +namespace mongo { +namespace { + + class DropDatabaseCmd : public Command { + public: + DropDatabaseCmd() : Command("dropDatabase") { } + + virtual bool slaveOk() const { + return true; + } + + virtual bool adminOnly() const { + return false; + } + + virtual bool isWriteCommandForConfigServer() const { + return false; + } + + virtual void addRequiredPrivileges(const std::string& dbname, + const BSONObj& cmdObj, + std::vector* out) { + + ActionSet actions; + actions.addAction(ActionType::dropDatabase); + out->push_back(Privilege(ResourcePattern::forDatabaseName(dbname), actions)); + } + + virtual bool run(OperationContext* txn, + const std::string& dbname, + BSONObj& cmdObj, + int options, + std::string& errmsg, + BSONObjBuilder& result, + bool fromRepl) { + + // Disallow dropping the config database from mongos + if (dbname == "config") { + return appendCommandStatus(result, Status(ErrorCodes::IllegalOperation, + "Cannot drop the config database")); + } + + BSONElement e = cmdObj.firstElement(); + + if (!e.isNumber() || e.number() != 1) { + errmsg = "invalid params"; + return 0; + } + + DBConfigPtr conf = grid.getDBConfig(dbname, false); + + log() << "DROP DATABASE: " << dbname; + + if (!conf) { + result.append("info", "database didn't exist"); + return true; + } + + // + // Reload the database configuration so that we're sure a database entry exists + // TODO: This won't work with parallel dropping + // + + grid.removeDBIfExists(*conf); + grid.getDBConfig(dbname); + + // TODO: Make dropping logic saner and more tolerant of partial drops. This is + // particularly important since a database drop can be aborted by *any* collection + // with a distributed namespace lock taken (migrates/splits) + + // + // Create a copy of the DB config object to drop, so that no one sees a weird + // intermediate version of the info + // + + DBConfig confCopy(conf->name()); + if (!confCopy.load()) { + errmsg = "could not load database info to drop"; + return false; + } + + // Enable sharding so we can correctly retry failed drops + // This will re-drop old sharded entries if they exist + confCopy.enableSharding(false); + + if (!confCopy.dropDatabase(errmsg)) { + return false; + } + + result.append("dropped", dbname); + return true; + } + + } clusterDropDatabaseCmd; + +} // namespace +} // namespace mongo diff --git a/src/mongo/s/commands_public.cpp b/src/mongo/s/commands_public.cpp index 65e03a3109b..2a2e8aa4295 100644 --- a/src/mongo/s/commands_public.cpp +++ b/src/mongo/s/commands_public.cpp @@ -720,74 +720,6 @@ namespace mongo { } } dropCmd; - class DropDBCmd : public PublicGridCommand { - public: - DropDBCmd() : PublicGridCommand( "dropDatabase" ) {} - virtual void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector* out) { - ActionSet actions; - actions.addAction(ActionType::dropDatabase); - out->push_back(Privilege(ResourcePattern::forDatabaseName(dbname), actions)); - } - bool run(OperationContext* txn, const string& dbName , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { - // disallow dropping the config database from mongos - if( dbName == "config" ) { - errmsg = "Cannot drop 'config' database via mongos"; - return false; - } - - BSONElement e = cmdObj.firstElement(); - - if ( ! e.isNumber() || e.number() != 1 ) { - errmsg = "invalid params"; - return 0; - } - - DBConfigPtr conf = grid.getDBConfig( dbName, false ); - - log() << "DROP DATABASE: " << dbName << endl; - - if ( ! conf ) { - result.append( "info" , "database didn't exist" ); - return true; - } - - // - // Reload the database configuration so that we're sure a database entry exists - // TODO: This won't work with parallel dropping - // - - grid.removeDBIfExists( *conf ); - grid.getDBConfig( dbName ); - - // TODO: Make dropping logic saner and more tolerant of partial drops. This is - // particularly important since a database drop can be aborted by *any* collection - // with a distributed namespace lock taken (migrates/splits) - - // - // Create a copy of the DB config object to drop, so that no one sees a weird - // intermediate version of the info - // - - DBConfig confCopy( conf->name() ); - if( ! confCopy.load() ){ - errmsg = "could not load database info to drop"; - return false; - } - - // Enable sharding so we can correctly retry failed drops - // This will re-drop old sharded entries if they exist - confCopy.enableSharding( false ); - - if ( ! confCopy.dropDatabase( errmsg ) ) - return false; - - result.append( "dropped" , dbName ); - return true; - } - } dropDBCmd; - class RenameCollectionCmd : public PublicGridCommand { public: RenameCollectionCmd() : PublicGridCommand( "renameCollection" ) {}