# HG changeset patch # User Sebastien Jodogne # Date 1531312799 -7200 # Node ID 1e9bad4934758253fa5bf5b122f980c0b70216ec # Parent 2e5d2c69d4f95e7dfd46cab533992999be09d241 prevent running unit tests on a non-existing db diff -r 2e5d2c69d4f9 -r 1e9bad493475 Framework/MySQL/MySQLDatabase.cpp --- a/Framework/MySQL/MySQLDatabase.cpp Tue Jul 10 14:33:05 2018 +0200 +++ b/Framework/MySQL/MySQLDatabase.cpp Wed Jul 11 14:39:59 2018 +0200 @@ -264,6 +264,18 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); } } + + + static void CheckAlphanumericString(const std::string& name) + { + for (size_t i = 0; i < name.length(); i++) + { + if (!isalnum(name[i])) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); + } + } + } bool MySQLDatabase::DoesTableExist(MySQLTransaction& transaction, @@ -274,14 +286,8 @@ throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } - for (size_t i = 0; i < name.length(); i++) - { - if (!isalnum(name[i])) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange); - } - } - + CheckAlphanumericString(name); + Query query("SELECT COUNT(*) FROM information_schema.TABLES WHERE " "(TABLE_SCHEMA = ${database}) AND (TABLE_NAME = ${table})", true); query.SetType("database", ValueType_Utf8String); @@ -301,6 +307,33 @@ } + bool MySQLDatabase::DoesDatabaseExist(MySQLTransaction& transaction, + const std::string& name) + { + if (mysql_ == NULL) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); + } + + CheckAlphanumericString(name); + + Query query("SELECT COUNT(*) FROM information_schema.SCHEMATA " + "WHERE SCHEMA_NAME = ${database}", true); + query.SetType("database", ValueType_Utf8String); + + MySQLStatement statement(*this, query); + + Dictionary args; + args.SetUtf8Value("database", name); + + std::auto_ptr result(statement.Execute(transaction, args)); + return (!result->IsDone() && + result->GetFieldsCount() == 1 && + result->GetField(0).GetType() == ValueType_Integer64 && + dynamic_cast(result->GetField(0)).GetValue() == 1); + } + + void MySQLDatabase::Execute(const std::string& sql, bool arobaseSeparator) { diff -r 2e5d2c69d4f9 -r 1e9bad493475 Framework/MySQL/MySQLDatabase.h --- a/Framework/MySQL/MySQLDatabase.h Tue Jul 10 14:33:05 2018 +0200 +++ b/Framework/MySQL/MySQLDatabase.h Wed Jul 11 14:39:59 2018 +0200 @@ -72,6 +72,9 @@ bool DoesTableExist(MySQLTransaction& transaction, const std::string& name); + bool DoesDatabaseExist(MySQLTransaction& transaction, + const std::string& name); + virtual Dialect GetDialect() const { return Dialect_MySQL; diff -r 2e5d2c69d4f9 -r 1e9bad493475 Framework/MySQL/MySQLParameters.cpp --- a/Framework/MySQL/MySQLParameters.cpp Tue Jul 10 14:33:05 2018 +0200 +++ b/Framework/MySQL/MySQLParameters.cpp Wed Jul 11 14:39:59 2018 +0200 @@ -125,4 +125,17 @@ { unixSocket_ = socket; } + + + void MySQLParameters::Format(Json::Value& target) const + { + target = Json::objectValue; + target["Host"] = host_; + target["Username"] = username_; + target["Password"] = password_; + target["Database"] = database_; + target["Port"] = port_; + target["UnixSocket"] = unixSocket_; + target["Lock"] = lock_; + } } diff -r 2e5d2c69d4f9 -r 1e9bad493475 Framework/MySQL/MySQLParameters.h --- a/Framework/MySQL/MySQLParameters.h Tue Jul 10 14:33:05 2018 +0200 +++ b/Framework/MySQL/MySQLParameters.h Wed Jul 11 14:39:59 2018 +0200 @@ -98,5 +98,7 @@ { return lock_; } + + void Format(Json::Value& target) const; }; } diff -r 2e5d2c69d4f9 -r 1e9bad493475 MySQL/Plugins/MySQLIndex.cpp --- a/MySQL/Plugins/MySQLIndex.cpp Tue Jul 10 14:33:05 2018 +0200 +++ b/MySQL/Plugins/MySQLIndex.cpp Wed Jul 11 14:39:59 2018 +0200 @@ -82,7 +82,14 @@ db.Open(); MySQLTransaction t(db); - db.Execute("DROP DATABASE IF EXISTS " + database, false); + + if (!db.DoesDatabaseExist(t, database)) + { + LOG(ERROR) << "Inexistent database, please create it first: " << database; + throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource); + } + + db.Execute("DROP DATABASE " + database, false); db.Execute("CREATE DATABASE " + database, false); t.Commit(); } diff -r 2e5d2c69d4f9 -r 1e9bad493475 MySQL/UnitTests/UnitTestsMain.cpp --- a/MySQL/UnitTests/UnitTestsMain.cpp Tue Jul 10 14:33:05 2018 +0200 +++ b/MySQL/UnitTests/UnitTestsMain.cpp Wed Jul 11 14:39:59 2018 +0200 @@ -145,28 +145,50 @@ return -1; } - if (argc == 5) + std::vector args; + for (int i = 1; i < argc; i++) { - // UNIX - globalParameters_.SetUnixSocket(argv[1]); - globalParameters_.SetUsername(argv[2]); - globalParameters_.SetPassword(argv[3]); - globalParameters_.SetDatabase(argv[4]); + // Ignore arguments beginning with "-" to allow passing arguments + // to Google Test such as "--gtest_filter=" + if (argv[i] != NULL && + argv[i][0] != '-') + { + args.push_back(std::string(argv[i])); + } } - else - { - // Windows - globalParameters_.SetHost(argv[1]); - globalParameters_.SetPort(boost::lexical_cast(argv[2])); - globalParameters_.SetUsername(argv[3]); - globalParameters_.SetPassword(argv[4]); - globalParameters_.SetDatabase(argv[5]); - } - + ::testing::InitGoogleTest(&argc, argv); Orthanc::Logging::Initialize(); Orthanc::Logging::EnableInfoLevel(true); Orthanc::Logging::EnableTraceLevel(true); + + if (args.size() == 4) + { + // UNIX flavor + globalParameters_.SetUnixSocket(args[0]); + globalParameters_.SetUsername(args[1]); + globalParameters_.SetPassword(args[2]); + globalParameters_.SetDatabase(args[3]); + } + else if (args.size() == 5) + { + // Windows flavor + globalParameters_.SetHost(args[0]); + globalParameters_.SetPort(boost::lexical_cast(args[1])); + globalParameters_.SetUsername(args[2]); + globalParameters_.SetPassword(args[3]); + globalParameters_.SetDatabase(args[4]); + } + else + { + LOG(ERROR) << "Bad number of arguments"; + return -1; + } + + Json::Value config; + globalParameters_.Format(config); + std::cout << "Parameters of the MySQL connection: " << std::endl + << config.toStyledString() << std::endl; int result = RUN_ALL_TESTS();