# HG changeset patch # User Sebastien Jodogne # Date 1531211582 -7200 # Node ID 54ea251aed7053b5abcf0dc0e53d3f4e6bd8e3bb # Parent 9e419261f1c95b2cb114a9311c01034cd1a98d7f unit test diff -r 9e419261f1c9 -r 54ea251aed70 MySQL/CMakeLists.txt --- a/MySQL/CMakeLists.txt Tue Jul 10 10:10:35 2018 +0200 +++ b/MySQL/CMakeLists.txt Tue Jul 10 10:33:02 2018 +0200 @@ -30,6 +30,7 @@ ) add_library(OrthancMySQLStorage SHARED + Plugins/MySQLStorageArea.cpp Plugins/StoragePlugin.cpp ${DATABASES_SOURCES} ${AUTOGENERATED_SOURCES} @@ -63,7 +64,9 @@ add_executable(UnitTests Plugins/MySQLIndex.cpp + Plugins/MySQLStorageArea.cpp UnitTests/UnitTestsMain.cpp + ${DATABASES_SOURCES} ${GOOGLE_TEST_SOURCES} ${AUTOGENERATED_SOURCES} diff -r 9e419261f1c9 -r 54ea251aed70 MySQL/Plugins/MySQLStorageArea.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MySQL/Plugins/MySQLStorageArea.cpp Tue Jul 10 10:33:02 2018 +0200 @@ -0,0 +1,87 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * 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 . + **/ + + +#include "MySQLStorageArea.h" + +#include "../../Framework/MySQL/MySQLDatabase.h" +#include "../../Framework/MySQL/MySQLTransaction.h" + +#include + +#include + + +namespace OrthancDatabases +{ + IDatabase* MySQLStorageArea::OpenInternal() + { + std::auto_ptr db(new MySQLDatabase(parameters_)); + + db->Open(); + + if (parameters_.HasLock()) + { + db->AdvisoryLock(43 /* some arbitrary constant */); + } + + { + MySQLTransaction t(*db); + + int64_t size; + if (db->LookupGlobalIntegerVariable(size, "max_allowed_packet")) + { + int mb = boost::math::iround(static_cast(size) / + static_cast(1024 * 1024)); + LOG(WARNING) << "Your MySQL server cannot " + << "store DICOM files larger than " << mb << "MB"; + LOG(WARNING) << " => Consider increasing \"max_allowed_packet\" " + << "in \"my.cnf\" if this limit is insufficient for your use"; + } + else + { + LOG(WARNING) << "Unable to auto-detect the maximum size of DICOM " + << "files that can be stored in this MySQL server"; + } + + if (clearAll_) + { + db->Execute("DROP TABLE IF EXISTS StorageArea", false); + } + + db->Execute("CREATE TABLE IF NOT EXISTS StorageArea(" + "uuid VARCHAR(64) NOT NULL PRIMARY KEY," + "content LONGBLOB NOT NULL," + "type INTEGER NOT NULL)", false); + + t.Commit(); + } + + return db.release(); + } + + + MySQLStorageArea::MySQLStorageArea(const MySQLParameters& parameters) : + StorageBackend(new Factory(*this)), + parameters_(parameters), + clearAll_(false) + { + } +} diff -r 9e419261f1c9 -r 54ea251aed70 MySQL/Plugins/MySQLStorageArea.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/MySQL/Plugins/MySQLStorageArea.h Tue Jul 10 10:33:02 2018 +0200 @@ -0,0 +1,69 @@ +/** + * Orthanc - A Lightweight, RESTful DICOM Store + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2018 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero 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 + * 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 . + **/ + + +#pragma once + +#include "../../Framework/Plugins/StorageBackend.h" +#include "../../Framework/MySQL/MySQLParameters.h" + + +namespace OrthancDatabases +{ + class MySQLStorageArea : public StorageBackend + { + private: + class Factory : public IDatabaseFactory + { + private: + MySQLStorageArea& that_; + + public: + Factory(MySQLStorageArea& that) : + that_(that) + { + } + + virtual Dialect GetDialect() const + { + return Dialect_MySQL; + } + + virtual IDatabase* Open() + { + return that_.OpenInternal(); + } + }; + + OrthancPluginContext* context_; + MySQLParameters parameters_; + bool clearAll_; + + IDatabase* OpenInternal(); + + public: + MySQLStorageArea(const MySQLParameters& parameters); + + void SetClearAll(bool clear) + { + clearAll_ = clear; + } + }; +} diff -r 9e419261f1c9 -r 54ea251aed70 MySQL/Plugins/StoragePlugin.cpp --- a/MySQL/Plugins/StoragePlugin.cpp Tue Jul 10 10:10:35 2018 +0200 +++ b/MySQL/Plugins/StoragePlugin.cpp Tue Jul 10 10:33:02 2018 +0200 @@ -19,114 +19,12 @@ **/ -#include "../../Framework/Plugins/StorageBackend.h" +#include "MySQLStorageArea.h" +#include "../../Framework/MySQL/MySQLDatabase.h" #include -#include "../../Framework/Common/Integer64Value.h" -#include "../../Framework/MySQL/MySQLDatabase.h" -#include "../../Framework/MySQL/MySQLResult.h" -#include "../../Framework/MySQL/MySQLStatement.h" -#include "../../Framework/MySQL/MySQLTransaction.h" - -#include - -namespace OrthancDatabases -{ - class MySQLStorageArea : public StorageBackend - { - private: - class Factory : public IDatabaseFactory - { - private: - MySQLStorageArea& that_; - - public: - Factory(MySQLStorageArea& that) : - that_(that) - { - } - - virtual Dialect GetDialect() const - { - return Dialect_MySQL; - } - - virtual IDatabase* Open() - { - return that_.OpenInternal(); - } - }; - - OrthancPluginContext* context_; - MySQLParameters parameters_; - bool clearAll_; - - IDatabase* OpenInternal() - { - std::auto_ptr db(new MySQLDatabase(parameters_)); - - db->Open(); - - if (parameters_.HasLock()) - { - db->AdvisoryLock(43 /* some arbitrary constant */); - } - - { - MySQLTransaction t(*db); - - int64_t size; - if (db->LookupGlobalIntegerVariable(size, "max_allowed_packet")) - { - int mb = boost::math::iround(static_cast(size) / - static_cast(1024 * 1024)); - LOG(WARNING) << "Your MySQL server cannot " - << "store DICOM files larger than " << mb << "MB"; - LOG(WARNING) << " => Consider increasing \"max_allowed_packet\" " - << "in \"my.cnf\" if this limit is insufficient for your use"; - } - else - { - LOG(WARNING) << "Unable to auto-detect the maximum size of DICOM " - << "files that can be stored in this MySQL server"; - } - - if (clearAll_) - { - db->Execute("DROP TABLE IF EXISTS StorageArea", false); - } - - db->Execute("CREATE TABLE IF NOT EXISTS StorageArea(" - "uuid VARCHAR(64) NOT NULL PRIMARY KEY," - "content LONGBLOB NOT NULL," - "type INTEGER NOT NULL)", false); - - t.Commit(); - } - - return db.release(); - } - - public: - MySQLStorageArea(const MySQLParameters& parameters) : - StorageBackend(new Factory(*this)), - parameters_(parameters), - clearAll_(false) - { - } - - void SetClearAll(bool clear) - { - clearAll_ = clear; - } - }; -} - - - - static bool DisplayPerformanceWarning() { (void) DisplayPerformanceWarning; // Disable warning about unused function diff -r 9e419261f1c9 -r 54ea251aed70 MySQL/UnitTests/UnitTestsMain.cpp --- a/MySQL/UnitTests/UnitTestsMain.cpp Tue Jul 10 10:10:35 2018 +0200 +++ b/MySQL/UnitTests/UnitTestsMain.cpp Tue Jul 10 10:33:02 2018 +0200 @@ -20,11 +20,15 @@ #include "../Plugins/MySQLIndex.h" +#include "../Plugins/MySQLStorageArea.h" OrthancDatabases::MySQLParameters globalParameters_; +#include "../../Framework/Common/Integer64Value.h" +#include "../../Framework/MySQL/MySQLDatabase.h" +#include "../../Framework/MySQL/MySQLResult.h" +#include "../../Framework/MySQL/MySQLStatement.h" #include "../../Framework/Plugins/IndexUnitTests.h" -#include "../../Framework/MySQL/MySQLDatabase.h" #include @@ -56,6 +60,76 @@ } +static int64_t CountFiles(OrthancDatabases::MySQLDatabase& db) +{ + OrthancDatabases::Query query("SELECT COUNT(*) FROM StorageArea", true); + OrthancDatabases::MySQLStatement s(db, query); + OrthancDatabases::MySQLTransaction t(db); + OrthancDatabases::Dictionary d; + std::auto_ptr result(s.Execute(t, d)); + return dynamic_cast(result->GetField(0)).GetValue(); +} + + +TEST(MySQL, StorageArea) +{ + OrthancDatabases::MySQLStorageArea storageArea(globalParameters_); + storageArea.SetClearAll(true); + + { + OrthancDatabases::DatabaseManager::Transaction transaction(storageArea.GetManager()); + OrthancDatabases::MySQLDatabase& db = + dynamic_cast(transaction.GetDatabase()); + + ASSERT_EQ(0, CountFiles(db)); + + for (int i = 0; i < 10; i++) + { + std::string uuid = boost::lexical_cast(i); + std::string value = "Value " + boost::lexical_cast(i * 2); + storageArea.Create(transaction, uuid, value.c_str(), value.size(), OrthancPluginContentType_Unknown); + } + + std::string tmp; + ASSERT_THROW(storageArea.ReadToString(tmp, transaction, "nope", OrthancPluginContentType_Unknown), + Orthanc::OrthancException); + + ASSERT_EQ(10, CountFiles(db)); + storageArea.Remove(transaction, "5", OrthancPluginContentType_Unknown); + + ASSERT_EQ(9, CountFiles(db)); + + for (int i = 0; i < 10; i++) + { + std::string uuid = boost::lexical_cast(i); + std::string expected = "Value " + boost::lexical_cast(i * 2); + std::string content; + + if (i == 5) + { + ASSERT_THROW(storageArea.ReadToString(content, transaction, uuid, OrthancPluginContentType_Unknown), + Orthanc::OrthancException); + } + else + { + storageArea.ReadToString(content, transaction, uuid, OrthancPluginContentType_Unknown); + ASSERT_EQ(expected, content); + } + } + + for (int i = 0; i < 10; i++) + { + storageArea.Remove(transaction, boost::lexical_cast(i), + OrthancPluginContentType_Unknown); + } + + ASSERT_EQ(0, CountFiles(db)); + + transaction.Commit(); + } +} + + int main(int argc, char **argv) { if (argc < 5)