Commit cc1c750c authored by Steven Murray's avatar Steven Murray
Browse files

Catalogue command-line tools now use getopt

parent 7b5977f9
......@@ -44,6 +44,15 @@ public:
*/
virtual ~CmdLineTool() noexcept = 0;
/**
* 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.
*/
virtual int exceptionThrowingMain(const int argc, char *const *const argv) = 0;
protected:
/**
......
......@@ -46,6 +46,12 @@ CreateSchemaCmd::~CreateSchemaCmd() noexcept {
//------------------------------------------------------------------------------
int CreateSchemaCmd::exceptionThrowingMain(const int argc, char *const *const argv) {
const CreateSchemaCmdLineArgs cmdLineArgs(argc, argv);
if(cmdLineArgs.help) {
cmdLineArgs.printUsage(m_out);
return 0;
}
const auto login = rdbms::Login::parseFile(cmdLineArgs.dbConfigPath);
auto factory = rdbms::ConnFactoryFactory::create(login);
auto conn = factory->create();
......
......@@ -51,7 +51,7 @@ public:
* @param argv The command-line arguments.
* @return The exit value of the program.
*/
int exceptionThrowingMain(const int argc, char *const *const argv);
int exceptionThrowingMain(const int argc, char *const *const argv) override;
private:
......
......@@ -17,8 +17,9 @@
*/
#include "catalogue/CreateSchemaCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
#include "common/exception/UserError.hpp"
#include <getopt.h>
#include <ostream>
namespace cta {
......@@ -27,15 +28,67 @@ namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
CreateSchemaCmdLineArgs::CreateSchemaCmdLineArgs(const int argc, const char *const *const argv) {
if(argc != 2) {
exception::Exception ex;
ex.getMessage() << "Wrong number of command-line arguments: excepted=1 actual=" << (argc - 1) << std::endl <<
std::endl;
printUsage(ex.getMessage());
CreateSchemaCmdLineArgs::CreateSchemaCmdLineArgs(const int argc, char *const *const argv):
help(false) {
static struct option longopts[] = {
{"help", 0, 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::UserError ex;
ex.getMessage() << "The -" << (char)opt << " option requires a parameter";
throw ex;
}
case '?': // Unknown option
{
exception::UserError ex;
if(0 == optopt) {
ex.getMessage() << "Unknown command-line option";
} else {
ex.getMessage() << "Unknown command-line option: -" << (char)optopt;
}
throw ex;
}
default:
{
exception::UserError 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::UserError ex;
ex.getMessage() << "Wrong number of command-line arguments: excepted=1 actual=" << (argc - 1);
throw ex;
}
dbConfigPath = argv[1];
dbConfigPath = argv[optind];
}
//------------------------------------------------------------------------------
......@@ -44,11 +97,14 @@ CreateSchemaCmdLineArgs::CreateSchemaCmdLineArgs(const int argc, const char *con
void CreateSchemaCmdLineArgs::printUsage(std::ostream &os) {
os <<
"Usage:" << std::endl <<
" cta-catalogue-schema-create databaseConnectionFile" << std::endl <<
" cta-catalogue-schema-create databaseConnectionFile [options]" << 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;
" catalogue database" << std::endl <<
"Options:" << std::endl <<
" -h,--help" << std::endl <<
" Prints this usage message" << std::endl;
}
} // namespace catalogue
......
......@@ -26,6 +26,11 @@ namespace catalogue {
* named cta-catalogue-schema-create.
*/
struct CreateSchemaCmdLineArgs {
/**
* True if the usage message should be printed.
*/
bool help;
/**
* Path to the file containing the connection details of the catalogue
* database.
......@@ -39,7 +44,7 @@ struct CreateSchemaCmdLineArgs {
* executable.
* @param argv The vector of command-line arguments.
*/
CreateSchemaCmdLineArgs(const int argc, const char *const *const argv);
CreateSchemaCmdLineArgs(const int argc, char *const *const argv);
/**
* Prints the usage message of the command-line tool.
......
......@@ -17,7 +17,9 @@
*/
#include "catalogue/CreateSchemaCmd.hpp"
#include "catalogue/CreateSchemaCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
#include "common/exception/UserError.hpp"
#include <iostream>
......@@ -36,10 +38,14 @@ static int exceptionThrowingMain(const int argc, char *const *const argv);
int main(const int argc, char *const *const argv) {
using namespace cta;
bool userError = false;
std::string errorMessage;
try {
return exceptionThrowingMain(argc, argv);
} catch(exception::UserError &ue) {
errorMessage = ue.getMessage().str();
userError = true;
} catch(exception::Exception &ex) {
errorMessage = ex.getMessage().str();
} catch(std::exception &se) {
......@@ -52,6 +58,10 @@ int main(const int argc, char *const *const argv) {
// and errorMessage has been set accordingly
std::cerr << "Aborting: " << errorMessage << std::endl;
if(userError) {
std::cerr << std::endl;
catalogue::CreateSchemaCmdLineArgs::printUsage(std::cerr);
}
return 1;
}
......
......@@ -45,6 +45,12 @@ DeleteAllCatalogueDataCmd::~DeleteAllCatalogueDataCmd() noexcept {
//------------------------------------------------------------------------------
int DeleteAllCatalogueDataCmd::exceptionThrowingMain(const int argc, char *const *const argv) {
const DeleteAllCatalogueDataCmdLineArgs cmdLineArgs(argc, argv);
if(cmdLineArgs.help) {
DeleteAllCatalogueDataCmdLineArgs::printUsage(m_out);
return 0;
}
const auto dbLogin = rdbms::Login::parseFile(cmdLineArgs.dbConfigPath);
const uint64_t nbDbConns = 1;
auto catalogue = CatalogueFactory::create(dbLogin, nbDbConns);
......
......@@ -52,7 +52,7 @@ public:
* @param argv The command-line arguments.
* @return The exit value of the program.
*/
int exceptionThrowingMain(const int argc, char *const *const argv);
int exceptionThrowingMain(const int argc, char *const *const argv) override;
private:
......
......@@ -17,8 +17,9 @@
*/
#include "catalogue/DeleteAllCatalogueDataCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
#include "common/exception/UserError.hpp"
#include <getopt.h>
#include <ostream>
namespace cta {
......@@ -27,15 +28,67 @@ namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
DeleteAllCatalogueDataCmdLineArgs::DeleteAllCatalogueDataCmdLineArgs(const int argc, const char *const *const argv) {
if(argc != 2) {
exception::Exception ex;
ex.getMessage() << "Wrong number of command-line arguments: excepted=1 actual=" << (argc - 1) << std::endl <<
std::endl;
printUsage(ex.getMessage());
DeleteAllCatalogueDataCmdLineArgs::DeleteAllCatalogueDataCmdLineArgs(const int argc, char *const *const argv):
help(false) {
static struct option longopts[] = {
{"help", 0, 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::UserError ex;
ex.getMessage() << "The -" << (char)opt << " option requires a parameter";
throw ex;
}
case '?': // Unknown option
{
exception::UserError ex;
if(0 == optopt) {
ex.getMessage() << "Unknown command-line option";
} else {
ex.getMessage() << "Unknown command-line option: -" << (char)optopt;
}
throw ex;
}
default:
{
exception::UserError 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::UserError ex;
ex.getMessage() << "Wrong number of command-line arguments: excepted=1 actual=" << (argc - 1);
throw ex;
}
dbConfigPath = argv[1];
dbConfigPath = argv[optind];
}
//------------------------------------------------------------------------------
......@@ -44,11 +97,14 @@ DeleteAllCatalogueDataCmdLineArgs::DeleteAllCatalogueDataCmdLineArgs(const int a
void DeleteAllCatalogueDataCmdLineArgs::printUsage(std::ostream &os) {
os <<
"Usage:" << std::endl <<
" cta-catalogue-delete-all-data databaseConnectionFile" << std::endl <<
" cta-catalogue-delete-all-data databaseConnectionFile [options]" << 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;
" catalogue database" << std::endl <<
"Options:" << std::endl <<
" -h,--help" << std::endl <<
" Prints this usage message" << std::endl;
}
} // namespace catalogue
......
......@@ -26,6 +26,11 @@ namespace catalogue {
* named cta-catalogue-delete-all-data.
*/
struct DeleteAllCatalogueDataCmdLineArgs {
/**
* True if the usage message should be printed.
*/
bool help;
/**
* Path to the file containing the connection details of the catalogue
* database.
......@@ -39,7 +44,7 @@ struct DeleteAllCatalogueDataCmdLineArgs {
* executable.
* @param argv The vector of command-line arguments.
*/
DeleteAllCatalogueDataCmdLineArgs(const int argc, const char *const *const argv);
DeleteAllCatalogueDataCmdLineArgs(const int argc, char *const *const argv);
/**
* Prints the usage message of the command-line tool.
......
......@@ -17,7 +17,9 @@
*/
#include "catalogue/DeleteAllCatalogueDataCmd.hpp"
#include "catalogue/DeleteAllCatalogueDataCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
#include "common/exception/UserError.hpp"
#include <iostream>
......@@ -36,10 +38,14 @@ static int exceptionThrowingMain(const int argc, char *const *const argv);
int main(const int argc, char *const *const argv) {
using namespace cta;
bool userError = false;
std::string errorMessage;
try {
return exceptionThrowingMain(argc, argv);
} catch(exception::UserError &ue) {
errorMessage = ue.getMessage().str();
userError = true;
} catch(exception::Exception &ex) {
errorMessage = ex.getMessage().str();
} catch(std::exception &se) {
......@@ -52,6 +58,10 @@ int main(const int argc, char *const *const argv) {
// and errorMessage has been set accordingly
std::cerr << "Aborting: " << errorMessage << std::endl;
if(userError) {
std::cerr << std::endl;
catalogue::DeleteAllCatalogueDataCmdLineArgs::printUsage(std::cerr);
}
return 1;
}
......
......@@ -48,6 +48,12 @@ DropSchemaCmd::~DropSchemaCmd() noexcept {
//------------------------------------------------------------------------------
int DropSchemaCmd::exceptionThrowingMain(const int argc, char *const *const argv) {
const DropSchemaCmdLineArgs cmdLineArgs(argc, argv);
if(cmdLineArgs.help) {
DropSchemaCmdLineArgs::printUsage(m_out);
return 0;
}
const rdbms::Login dbLogin = rdbms::Login::parseFile(cmdLineArgs.dbConfigPath);
// Abort if the schema is already dropped
......
......@@ -53,7 +53,7 @@ public:
* @param argv The command-line arguments.
* @return The exit value of the program.
*/
int exceptionThrowingMain(const int argc, char *const *const argv);
int exceptionThrowingMain(const int argc, char *const *const argv) override;
private:
......
......@@ -17,8 +17,9 @@
*/
#include "catalogue/DropSchemaCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
#include "common/exception/UserError.hpp"
#include <getopt.h>
#include <ostream>
namespace cta {
......@@ -27,15 +28,67 @@ namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
DropSchemaCmdLineArgs::DropSchemaCmdLineArgs(const int argc, const char *const *const argv) {
if(argc != 2) {
exception::Exception ex;
ex.getMessage() << "Wrong number of command-line arguments: excepted=1 actual=" << (argc - 1) << std::endl <<
std::endl;
printUsage(ex.getMessage());
DropSchemaCmdLineArgs::DropSchemaCmdLineArgs(const int argc, char *const *const argv):
help(false) {
static struct option longopts[] = {
{"help", 0, 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::UserError ex;
ex.getMessage() << "The -" << (char)opt << " option requires a parameter";
throw ex;
}
case '?': // Unknown option
{
exception::UserError ex;
if(0 == optopt) {
ex.getMessage() << "Unknown command-line option";
} else {
ex.getMessage() << "Unknown command-line option: -" << (char)optopt;
}
throw ex;
}
default:
{
exception::UserError 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::UserError ex;
ex.getMessage() << "Wrong number of command-line arguments: excepted=1 actual=" << (argc - 1);
throw ex;
}
dbConfigPath = argv[1];
dbConfigPath = argv[optind];
}
//------------------------------------------------------------------------------
......@@ -44,11 +97,14 @@ DropSchemaCmdLineArgs::DropSchemaCmdLineArgs(const int argc, const char *const *
void DropSchemaCmdLineArgs::printUsage(std::ostream &os) {
os <<
"Usage:" << std::endl <<
" cta-catalogue-schema-drop databaseConnectionFile" << std::endl <<
" cta-catalogue-schema-drop databaseConnectionFile [options]" << 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;
" catalogue database" << std::endl <<
"Options:" << std::endl <<
" -h,--help" << std::endl <<
" Prints this usage message" << std::endl;
}
} // namespace catalogue
......
......@@ -26,6 +26,11 @@ namespace catalogue {
* named cta-catalogue-schema-drop
*/
struct DropSchemaCmdLineArgs {
/**
* True if the usage message should be printed.
*/
bool help;
/**
* Path to the file containing the connection details of the catalogue
* database.
......@@ -39,7 +44,7 @@ struct DropSchemaCmdLineArgs {
* executable.
* @param argv The vector of command-line arguments.
*/
DropSchemaCmdLineArgs(const int argc, const char *const *const argv);
DropSchemaCmdLineArgs(const int argc, char *const *const argv);
/**
* Prints the usage message of the command-line tool.
......
......@@ -17,7 +17,9 @@
*/
#include "catalogue/DropSchemaCmd.hpp"
#include "catalogue/DropSchemaCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
#include "common/exception/UserError.hpp"
#include <iostream>
......@@ -36,10 +38,14 @@ static int exceptionThrowingMain(const int argc, char *const *const argv);
int main(const int argc, char *const *const argv) {
using namespace cta;
bool userError = false;
std::string errorMessage;
try {
return exceptionThrowingMain(argc, argv);
} catch(exception::UserError &ue) {
errorMessage = ue.getMessage().str();
userError = true;
} catch(exception::Exception &ex) {
errorMessage = ex.getMessage().str();
} catch(std::exception &se) {
......@@ -52,6 +58,10 @@ int main(const int argc, char *const *const argv) {
// and errorMessage has been set accordingly
std::cerr << "Aborting: " << errorMessage << std::endl;
if(userError) {
std::cerr << std::endl;
catalogue::DropSchemaCmdLineArgs::printUsage(std::cerr);
}
return 1;
}
......
......@@ -41,6 +41,12 @@ LockSchemaCmd::~LockSchemaCmd() noexcept {
//------------------------------------------------------------------------------
int LockSchemaCmd::exceptionThrowingMain(const int argc, char *const *const argv) {
const LockSchemaCmdLineArgs cmdLineArgs(argc, argv);
if(cmdLineArgs.help) {
LockSchemaCmdLineArgs::printUsage(m_out);
return 0;
}
const auto dbLogin = rdbms::Login::parseFile(cmdLineArgs.dbConfigPath);
const uint64_t nbDbConns = 1;
auto catalogue = CatalogueFactory::create(dbLogin, nbDbConns);
......
......@@ -17,8 +17,9 @@
*/
#include "catalogue/LockSchemaCmdLineArgs.hpp"
#include "common/exception/Exception.hpp"
#include "common/exception/UserError.hpp"
#include <getopt.h>
#include <ostream>
namespace cta {
......@@ -27,15 +28,67 @@ namespace catalogue {
//------------------------------------------------------------------------------
// constructor
//------------------------------------------------------------------------------
LockSchemaCmdLineArgs::LockSchemaCmdLineArgs(const int argc, const char *const *const argv) {
if(argc != 2) {
exception::Exception ex;
ex.getMessage() << "Wrong number of command-line arguments: excepted=1 actual=" << (argc - 1) << std::endl <<
std::endl;
printUsage(ex.getMessage());
LockSchemaCmdLineArgs::LockSchemaCmdLineArgs(const int argc, char *const *const argv):
help(false) {
static struct option longopts[] = {
{"help", 0, NULL, 'h'},
{NULL , 0, NULL, 0}
};