Commit 6882daef authored by Steven Murray's avatar Steven Murray
Browse files

cta/CTA#87 cta-catalogue-delete-all-data and cta-catalogue-schema-drop should...

cta/CTA#87 cta-catalogue-delete-all-data and cta-catalogue-schema-drop should require interactive confirmation

Removed the now redundant locking commands for the catalogue schema.
These commands were made redundant when the cta-catalogue-schema-drop
command was made interactive.
parent ac442cf8
......@@ -113,39 +113,6 @@ install (FILES cta_catalogue_db.conf.example
DESTINATION ${CMAKE_INSTALL_SYSCONFDIR}/cta
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
add_executable(cta-catalogue-schema-lock
LockSchemaCmd.cpp
LockSchemaCmdLineArgs.cpp
LockSchemaCmdMain.cpp)
target_link_libraries (cta-catalogue-schema-lock
ctacatalogue)
install (TARGETS cta-catalogue-schema-lock DESTINATION /usr/bin)
install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-catalogue-schema-lock.1cta DESTINATION /usr/share/man/man1)
add_executable(cta-catalogue-schema-unlock
UnlockSchemaCmd.cpp
UnlockSchemaCmdLineArgs.cpp
UnlockSchemaCmdMain.cpp)
target_link_libraries (cta-catalogue-schema-unlock
ctacatalogue)
install (TARGETS cta-catalogue-schema-unlock DESTINATION /usr/bin)
install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-catalogue-schema-unlock.1cta DESTINATION /usr/share/man/man1)
add_executable(cta-catalogue-schema-status
SchemaStatusCmd.cpp
SchemaStatusCmdLineArgs.cpp
SchemaStatusCmdMain.cpp)
target_link_libraries (cta-catalogue-schema-status
ctacatalogue)
install (TARGETS cta-catalogue-schema-status DESTINATION /usr/bin)
install (FILES ${CMAKE_CURRENT_SOURCE_DIR}/cta-catalogue-schema-status.1cta DESTINATION /usr/share/man/man1)
add_custom_command(OUTPUT oracle_catalogue_schema.cpp
COMMAND sed 's/^/\ \ \"/' oracle_catalogue_schema.sql | sed 's/$$/\"/' > oracle_catalogue_schema.cpp
DEPENDS oracle_catalogue_schema.sql)
......@@ -238,14 +205,8 @@ set (CATALOGUE_CMD_LINE_UNIT_TESTS_LIB_SRC_FILES
CreateSchemaCmdLineArgsTest.cpp
DropSchemaCmdLineArgs.cpp
DropSchemaCmdLineArgsTest.cpp
LockSchemaCmdLineArgs.cpp
LockSchemaCmdLineArgsTest.cpp
PollDatabaseCmdLineArgs.cpp
PollDatabaseCmdLineArgsTest.cpp
SchemaStatusCmdLineArgs.cpp
SchemaStatusCmdLineArgsTest.cpp
UnlockSchemaCmdLineArgs.cpp
UnlockSchemaCmdLineArgsTest.cpp)
PollDatabaseCmdLineArgsTest.cpp)
add_library (ctacataloguecmdlineunittests SHARED
${CATALOGUE_CMD_LINE_UNIT_TESTS_LIB_SRC_FILES})
......
......@@ -518,29 +518,6 @@ public:
*/
virtual bool isAdmin(const common::dataStructures::SecurityIdentity &admin) const = 0;
/**
* Returns true if SCHEMA_STATUS column of the CTA_TABLE contains the value
* LOCKED.
*
* @return True if SCHEMA_STATUS column of the CTA_TABLE contains the value
* LOCKED.
*/
virtual bool schemaIsLocked() const = 0;
/**
* Sets the value of the SCHEMA_STATUS column of the CTA_TABLE to LOCKED.
*
* Please note that this method is idempotent.
*/
virtual void lockSchema() = 0;
/**
* Sets the value of the SCHEMA_STATUS column of the CTA_TABLE to UNLOCKED.
*
* Please note that this method is idempotent.
*/
virtual void unlockSchema() = 0;
/**
* Checks that the most trivial query goes through. Throws an exception if not.
*/
......
......@@ -7316,17 +7316,6 @@ TEST_P(cta_catalogue_CatalogueTest, reclaimTape_full_lastFSeq_1_one_tape_file) {
ASSERT_THROW(m_catalogue->reclaimTape(m_admin, vid1), exception::UserError);
}
TEST_P(cta_catalogue_CatalogueTest, lockSchema_unlockSchema_lockSchema) {
using namespace cta;
m_catalogue->lockSchema();
ASSERT_TRUE(m_catalogue->schemaIsLocked());
m_catalogue->unlockSchema();
ASSERT_FALSE(m_catalogue->schemaIsLocked());
m_catalogue->lockSchema();
ASSERT_TRUE(m_catalogue->schemaIsLocked());
}
TEST_P(cta_catalogue_CatalogueTest, ping) {
using namespace cta;
......
......@@ -16,6 +16,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <rdbms/OcciConn.hpp>
#include "catalogue/CatalogueFactory.hpp"
#include "catalogue/DropOracleCatalogueSchema.hpp"
#include "catalogue/DropSchemaCmd.hpp"
......@@ -23,6 +24,7 @@
#include "catalogue/DropSqliteCatalogueSchema.hpp"
#include "common/exception/Exception.hpp"
#include "rdbms/ConnFactoryFactory.hpp"
#include "rdbms/OcciConn.hpp"
namespace cta {
namespace catalogue {
......@@ -55,37 +57,45 @@ int DropSchemaCmd::exceptionThrowingMain(const int argc, char *const *const argv
}
const rdbms::Login dbLogin = rdbms::Login::parseFile(cmdLineArgs.dbConfigPath);
auto factory = rdbms::ConnFactoryFactory::create(dbLogin);
auto conn = factory->create();
// Abort if the schema is already dropped
{
auto factory = rdbms::ConnFactoryFactory::create(dbLogin);
auto conn = factory->create();
if(conn->getTableNames().empty()) {
m_out << "Database contains no tables. Assuming the schema has already been dropped." << std::endl;
switch(dbLogin.dbType) {
case rdbms::Login::DBTYPE_IN_MEMORY:
case rdbms::Login::DBTYPE_SQLITE:
if (conn->getTableNames().empty()) {
m_out << "Database contains no tables." << std::endl <<
"Assuming the schema has already been dropped." << std::endl;
return 0;
}
}
// Abort if the schema is not locked
{
const uint64_t nbDbConns = 1;
auto catalogue = CatalogueFactory::create(dbLogin, nbDbConns);
if(catalogue->schemaIsLocked()) {
m_err <<
"Cannot drop the schema of the catalogue database because the schema is locked.\n"
"\n"
"Please see the following command-line tools:\n"
" cta-catalogue-schema-lock\n"
" cta-catalogue-schema-status\n"
" cta-catalogue-schema-unlock" << std::endl;
return 1;
break;
case rdbms::Login::DBTYPE_ORACLE:
{
rdbms::OcciConn *const occiConn = dynamic_cast<rdbms::OcciConn *>(conn.get());
if(nullptr == occiConn) {
throw exception::Exception("Failed to down cast rdbms::conn to rdbms::OcciConn");
}
if(occiConn->getTableNames().empty() && occiConn->getSequenceNames().empty()) {
m_out << "Database contains no tables and no sequences." << std::endl <<
"Assuming the schema has already been dropped." << std::endl;
return 0;
}
}
break;
case rdbms::Login::DBTYPE_NONE:
throw exception::Exception("Cannot delete the schema of catalogue database without a database type");
default:
{
exception::Exception ex;
ex.getMessage() << "Unknown database type: value=" << dbLogin.dbType;
throw ex;
}
}
if(userConfirmsDropOfSchema(dbLogin)) {
m_out << "DROPPING the schema of the CTA calalogue database" << std::endl;
dropCatalogueSchema(dbLogin);
dropCatalogueSchema(dbLogin.dbType, *conn);
} else {
m_out << "Aborting" << std::endl;
}
......@@ -114,30 +124,22 @@ bool DropSchemaCmd::userConfirmsDropOfSchema(const rdbms::Login &dbLogin) {
//------------------------------------------------------------------------------
// dropCatalogueSchema
//------------------------------------------------------------------------------
void DropSchemaCmd::dropCatalogueSchema(const rdbms::Login &dbLogin) {
auto factory = rdbms::ConnFactoryFactory::create(dbLogin);
auto conn = factory->create();
void DropSchemaCmd::dropCatalogueSchema(const rdbms::Login::DbType &dbType, rdbms::Conn &conn) {
try {
switch(dbLogin.dbType) {
switch(dbType) {
case rdbms::Login::DBTYPE_IN_MEMORY:
case rdbms::Login::DBTYPE_SQLITE:
{
DropSqliteCatalogueSchema dropSchema;
conn->executeNonQueries(dropSchema.sql);
}
dropSqliteCatalogueSchema(conn);
break;
case rdbms::Login::DBTYPE_ORACLE:
{
DropOracleCatalogueSchema dropSchema;
conn->executeNonQueries(dropSchema.sql);
}
dropOracleCatalogueSchema(conn);
break;
case rdbms::Login::DBTYPE_NONE:
throw exception::Exception("Cannot delete the schema of catalogue database without a database type");
default:
{
exception::Exception ex;
ex.getMessage() << "Unknown database type: value=" << dbLogin.dbType;
ex.getMessage() << "Unknown database type: value=" << dbType;
throw ex;
}
}
......@@ -146,6 +148,30 @@ void DropSchemaCmd::dropCatalogueSchema(const rdbms::Login &dbLogin) {
}
}
//------------------------------------------------------------------------------
// dropSqliteCatalogueSchema
//------------------------------------------------------------------------------
void DropSchemaCmd::dropSqliteCatalogueSchema(rdbms::Conn &conn) {
try {
DropSqliteCatalogueSchema dropSchema;
conn.executeNonQueries(dropSchema.sql);
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
//------------------------------------------------------------------------------
// dropOracleCatalogueSchema
//------------------------------------------------------------------------------
void DropSchemaCmd::dropOracleCatalogueSchema(rdbms::Conn &conn) {
try {
DropOracleCatalogueSchema dropSchema;
conn.executeNonQueries(dropSchema.sql);
} catch(exception::Exception &ex) {
throw exception::Exception(std::string(__FUNCTION__) + " failed: " + ex.getMessage().str());
}
}
//------------------------------------------------------------------------------
// printUsage
//------------------------------------------------------------------------------
......
......@@ -75,11 +75,28 @@ private:
/**
* Unconditionally drops the schema of the catalogue database associated with
* the specified database login.
* the specified database connection.
*
* @param dbLogin The database login.
* @param dbType The database type.
* @param conn The database connection.
*/
void dropCatalogueSchema(const rdbms::Login::DbType &dbType, rdbms::Conn &conn);
/**
* Unconditionally drops the schema of the catalogue database associated with
* the specified database connection.
*
* @param conn The database connection.
*/
void dropSqliteCatalogueSchema(rdbms::Conn &conn);
/**
* Unconditionally drops the schema of the catalogue database associated with
* the specified database connection.
*
* @param conn The database connection.
*/
void dropCatalogueSchema(const rdbms::Login &dbLogin);
void dropOracleCatalogueSchema(rdbms::Conn &conn);
}; // class DropSchemaCmd
......
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catalogue/CatalogueFactory.hpp"
#include "catalogue/LockSchemaCmd.hpp"
#include "catalogue/LockSchemaCmdLineArgs.hpp"
namespace cta {
namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
LockSchemaCmd::LockSchemaCmd(std::istream &inStream, std::ostream &outStream, std::ostream &errStream):
CmdLineTool(inStream, outStream, errStream) {
}
//------------------------------------------------------------------------------
// destructor
//------------------------------------------------------------------------------
LockSchemaCmd::~LockSchemaCmd() noexcept {
}
//------------------------------------------------------------------------------
// exceptionThrowingMain
//------------------------------------------------------------------------------
int LockSchemaCmd::exceptionThrowingMain(const int argc, char *const *const argv) {
const LockSchemaCmdLineArgs cmdLineArgs(argc, argv);
if(cmdLineArgs.help) {
printUsage(m_out);
return 0;
}
const auto dbLogin = rdbms::Login::parseFile(cmdLineArgs.dbConfigPath);
const uint64_t nbDbConns = 1;
auto catalogue = CatalogueFactory::create(dbLogin, nbDbConns);
catalogue->lockSchema();
return 0;
}
//------------------------------------------------------------------------------
// printUsage
//------------------------------------------------------------------------------
void LockSchemaCmd::printUsage(std::ostream &os) {
LockSchemaCmdLineArgs::printUsage(os);
}
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "catalogue/CmdLineTool.hpp"
namespace cta {
namespace catalogue {
/**
* Command-line tool for locking the catalogue schema in order to help
* protect it from accidental deletion.
*/
class LockSchemaCmd: public CmdLineTool {
public:
/**
* Constructor.
*
* @param inStream Standard input stream.
* @param outStream Standard output stream.
* @param errStream Standard error stream.
*/
LockSchemaCmd(std::istream &inStream, std::ostream &outStream, std::ostream &errStream);
/**
* Destructor.
*/
~LockSchemaCmd() noexcept;
private:
/**
* An exception throwing version of main().
*
* @param argc The number of command-line arguments including the program name.
* @param argv The command-line arguments.
* @return The exit value of the program.
*/
int exceptionThrowingMain(const int argc, char *const *const argv) override;
/**
* Prints the usage message of the command-line tool.
*
* @param os The output stream to which the usage message is to be printed.
*/
void printUsage(std::ostream &os) override;
}; // class LockSchemaCmd
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "catalogue/LockSchemaCmdLineArgs.hpp"
#include "common/exception/CommandLineNotParsed.hpp"
#include <getopt.h>
#include <ostream>
namespace cta {
namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
LockSchemaCmdLineArgs::LockSchemaCmdLineArgs(const int argc, char *const *const argv):
help(false) {
static struct option longopts[] = {
{"help", no_argument, NULL, 'h'},
{NULL , 0, NULL, 0}
};
// Prevent getopt() from printing an error message if it does not recognize
// an option character
opterr = 0;
int opt = 0;
while((opt = getopt_long(argc, argv, ":h", longopts, NULL)) != -1) {
switch(opt) {
case 'h':
help = true;
break;
case ':': // Missing parameter
{
exception::CommandLineNotParsed ex;
ex.getMessage() << "The -" << (char)opt << " option requires a parameter";
throw ex;
}
case '?': // Unknown option
{
exception::CommandLineNotParsed ex;
if(0 == optopt) {
ex.getMessage() << "Unknown command-line option";
} else {
ex.getMessage() << "Unknown command-line option: -" << (char)optopt;
}
throw ex;
}
default:
{
exception::CommandLineNotParsed ex;
ex.getMessage() <<
"getopt_long returned the following unknown value: 0x" <<
std::hex << (int)opt;
throw ex;
}
} // switch(opt)
} // while getopt_long()
// There is no need to continue parsing when the help option is set
if(help) {
return;
}
// Calculate the number of non-option ARGV-elements
const int nbArgs = argc - optind;
// Check the number of arguments
if(nbArgs != 1) {
exception::CommandLineNotParsed ex;
ex.getMessage() << "Wrong number of command-line arguments: excepted=1 actual=" << nbArgs;
throw ex;
}
dbConfigPath = argv[optind];
}
//------------------------------------------------------------------------------
// printUsage
//------------------------------------------------------------------------------
void LockSchemaCmdLineArgs::printUsage(std::ostream &os) {
os <<
"Usage:" << std::endl <<
" cta-catalogue-schema-lock databaseConnectionFile" << std::endl <<
"Where:" << std::endl <<
" databaseConnectionFile" << std::endl <<
" The path to the file containing the connection details of the CTA" << std::endl <<
" catalogue database" << std::endl <<
"Options:" << std::endl <<
" -h,--help" << std::endl <<
" Prints this usage message" << std::endl;
}
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive (CTA) project
* Copyright (C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
namespace cta {
namespace catalogue {
/**
* Structure to store the command-line arguments of the command-line tool
* named cta-catalogue-schema-lock.
*/
struct LockSchemaCmdLineArgs {
/**
* True if the usage message should be printed.
*/
bool help;
/**
* Path to the file containing the connection details of the catalogue
* database.
*/
std::string dbConfigPath;
/**
* Constructor that parses the specified command-line arguments.
*
* @param argc The number of command-line arguments including the name of the
* executable.
* @param argv The vector of command-line arguments.
*/
LockSchemaCmdLineArgs(const int argc, char *const *const argv);
/**
* Prints the usage message of the command-line tool.
*
* @param os The output stream to which the usage message is to be printed.
*/
static void printUsage(std::ostream &os);
};
} // namespace catalogue
} // namespace cta
/*
* The CERN Tape Archive(CTA) project
* Copyright(C) 2015 CERN
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
*(at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common/exception/Exception.hpp"