# HG changeset patch # User Sebastien Jodogne # Date 1618308450 -7200 # Node ID a063bbf10a3eb20aa3e9a244cea72f9b9e228044 # Parent c82c2cf84ae8d7a58e0621227c2391fd7ac8f4e8 simplification of class DatabaseManager::Transaction diff -r c82c2cf84ae8 -r a063bbf10a3e Framework/Common/DatabaseManager.cpp --- a/Framework/Common/DatabaseManager.cpp Mon Apr 12 17:07:06 2021 +0200 +++ b/Framework/Common/DatabaseManager.cpp Tue Apr 13 12:07:30 2021 +0200 @@ -241,7 +241,7 @@ TransactionType type) : manager_(manager), database_(manager.GetDatabase()), - committed_(false) + active_(true) { manager_.StartTransaction(type); } @@ -249,7 +249,7 @@ DatabaseManager::Transaction::~Transaction() { - if (!committed_) + if (active_) { try { @@ -266,14 +266,28 @@ void DatabaseManager::Transaction::Commit() { - if (committed_) + if (active_) + { + manager_.CommitTransaction(); + active_ = true; + } + else { throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } + } + + + void DatabaseManager::Transaction::Rollback() + { + if (active_) + { + manager_.RollbackTransaction(); + active_ = true; + } else { - manager_.CommitTransaction(); - committed_ = true; + throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); } } diff -r c82c2cf84ae8 -r a063bbf10a3e Framework/Common/DatabaseManager.h --- a/Framework/Common/DatabaseManager.h Mon Apr 12 17:07:06 2021 +0200 +++ b/Framework/Common/DatabaseManager.h Tue Apr 13 12:07:30 2021 +0200 @@ -88,13 +88,14 @@ void RollbackTransaction(); - // This class is only used in the "StorageBackend" + // This class is only used in the "StorageBackend" and in + // "IDatabaseBackend::ConfigureDatabase()" class Transaction : public boost::noncopyable { private: DatabaseManager& manager_; IDatabase& database_; - bool committed_; + bool active_; public: explicit Transaction(DatabaseManager& manager, @@ -104,29 +105,16 @@ void Commit(); - DatabaseManager& GetManager() - { - return manager_; - } + void Rollback(); - IDatabase& GetDatabase() - { - return database_; - } - - bool DoesTableExist(const std::string& name) + /** + * WARNING: Don't call "GetDatabaseTransaction().Commit()" and + * "GetDatabaseTransaction().Rollback()", but use the "Commit()" + * and "Rollback()" methods above. + **/ + ITransaction& GetDatabaseTransaction() { - return manager_.GetTransaction().DoesTableExist(name); - } - - bool DoesTriggerExist(const std::string& name) - { - return manager_.GetTransaction().DoesTriggerExist(name); - } - - void ExecuteMultiLines(const std::string& sql) - { - manager_.GetTransaction().ExecuteMultiLines(sql); + return manager_.GetTransaction(); } }; diff -r c82c2cf84ae8 -r a063bbf10a3e MySQL/Plugins/MySQLIndex.cpp --- a/MySQL/Plugins/MySQLIndex.cpp Mon Apr 12 17:07:06 2021 +0200 +++ b/MySQL/Plugins/MySQLIndex.cpp Tue Apr 13 12:07:30 2021 +0200 @@ -112,18 +112,18 @@ { DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); - t.ExecuteMultiLines("ALTER DATABASE " + parameters_.GetDatabase() + - " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); + t.GetDatabaseTransaction().ExecuteMultiLines("ALTER DATABASE " + parameters_.GetDatabase() + + " CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); // This is the first table to be created - if (!t.DoesTableExist("GlobalProperties")) + if (!t.GetDatabaseTransaction().DoesTableExist("GlobalProperties")) { std::string query; Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::MYSQL_PREPARE_INDEX); - // Need to escape arobases: Don't use "t.ExecuteMultiLines()" here + // Need to escape arobases: Don't use "t.GetDatabaseTransaction().ExecuteMultiLines()" here db.ExecuteMultiLines(query, true); } @@ -144,14 +144,14 @@ DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); // This is the last table to be created - if (!t.DoesTableExist("PatientRecyclingOrder")) + if (!t.GetDatabaseTransaction().DoesTableExist("PatientRecyclingOrder")) { LOG(ERROR) << "Corrupted MySQL database"; throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); } // This is the last item to be created - if (!t.DoesTriggerExist("PatientAdded")) + if (!t.GetDatabaseTransaction().DoesTriggerExist("PatientAdded")) { ThrowCannotCreateTrigger(); } @@ -194,7 +194,7 @@ // very long values => switch to the LONGTEXT type that can // store up to 4GB: // https://stackoverflow.com/a/13932834/881731 - t.ExecuteMultiLines("ALTER TABLE GlobalProperties MODIFY value LONGTEXT"); + t.GetDatabaseTransaction().ExecuteMultiLines("ALTER TABLE GlobalProperties MODIFY value LONGTEXT"); revision = 2; SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); @@ -212,10 +212,10 @@ Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::MYSQL_GET_LAST_CHANGE_INDEX); - // Need to escape arobases: Don't use "t.ExecuteMultiLines()" here + // Need to escape arobases: Don't use "t.GetDatabaseTransaction().ExecuteMultiLines()" here db.ExecuteMultiLines(query, true); - if (!t.DoesTriggerExist("ChangeAdded")) + if (!t.GetDatabaseTransaction().DoesTriggerExist("ChangeAdded")) { ThrowCannotCreateTrigger(); } @@ -235,7 +235,7 @@ // for applications such as the Osimis Web viewer that stores // large amount of metadata. // http://book.orthanc-server.com/faq/features.html#central-registry-of-metadata-and-attachments - t.ExecuteMultiLines("ALTER TABLE Metadata MODIFY value LONGTEXT"); + t.GetDatabaseTransaction().ExecuteMultiLines("ALTER TABLE Metadata MODIFY value LONGTEXT"); revision = 4; SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, revision); @@ -253,7 +253,7 @@ Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::MYSQL_CREATE_INSTANCE); - // Need to escape arobases: Don't use "t.ExecuteMultiLines()" here + // Need to escape arobases: Don't use "t.GetDatabaseTransaction().ExecuteMultiLines()" here db.ExecuteMultiLines(query, true); revision = 5; @@ -273,10 +273,10 @@ // New in release 4.0 to deal with multiple writers DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); - if (!t.DoesTableExist("ServerProperties")) + if (!t.GetDatabaseTransaction().DoesTableExist("ServerProperties")) { - t.ExecuteMultiLines("CREATE TABLE ServerProperties(server VARCHAR(64) NOT NULL, " - "property INTEGER, value TEXT, PRIMARY KEY(server, property))"); + t.GetDatabaseTransaction().ExecuteMultiLines("CREATE TABLE ServerProperties(server VARCHAR(64) NOT NULL, " + "property INTEGER, value TEXT, PRIMARY KEY(server, property))"); } t.Commit(); diff -r c82c2cf84ae8 -r a063bbf10a3e PostgreSQL/Plugins/PostgreSQLIndex.cpp --- a/PostgreSQL/Plugins/PostgreSQLIndex.cpp Mon Apr 12 17:07:06 2021 +0200 +++ b/PostgreSQL/Plugins/PostgreSQLIndex.cpp Tue Apr 13 12:07:30 2021 +0200 @@ -96,20 +96,20 @@ { DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); - if (!t.DoesTableExist("Resources")) + if (!t.GetDatabaseTransaction().DoesTableExist("Resources")) { std::string query; Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::POSTGRESQL_PREPARE_INDEX); - t.ExecuteMultiLines(query); + t.GetDatabaseTransaction().ExecuteMultiLines(query); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion, expectedVersion); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, 1); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasTrigramIndex, 0); } - if (!t.DoesTableExist("Resources")) + if (!t.GetDatabaseTransaction().DoesTableExist("Resources")) { LOG(ERROR) << "Corrupted PostgreSQL database"; throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); @@ -163,7 +163,7 @@ LOG(WARNING) << "Trying to enable trigram matching on the PostgreSQL database " << "to speed up wildcard searches. This may take several minutes"; - t.ExecuteMultiLines( + t.GetDatabaseTransaction().ExecuteMultiLines( "CREATE EXTENSION IF NOT EXISTS pg_trgm; " "CREATE INDEX DicomIdentifiersIndexValues2 ON DicomIdentifiers USING gin(value gin_trgm_ops);"); @@ -199,14 +199,14 @@ if (property == 1) { // Drop older, experimental versions of this extension - t.ExecuteMultiLines("DROP FUNCTION CreateInstance(" - "IN patient TEXT, IN study TEXT, IN series TEXT, in instance TEXT)"); + t.GetDatabaseTransaction().ExecuteMultiLines("DROP FUNCTION CreateInstance(" + "IN patient TEXT, IN study TEXT, IN series TEXT, in instance TEXT)"); } std::string query; Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::POSTGRESQL_CREATE_INSTANCE); - t.ExecuteMultiLines(query); + t.GetDatabaseTransaction().ExecuteMultiLines(query); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasCreateInstance, 2); } @@ -221,7 +221,7 @@ std::string query; Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::POSTGRESQL_FAST_TOTAL_SIZE); - t.ExecuteMultiLines(query); + t.GetDatabaseTransaction().ExecuteMultiLines(query); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_GetTotalSizeIsFast, 1); } @@ -239,7 +239,7 @@ std::string query; Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::POSTGRESQL_FAST_COUNT_RESOURCES); - t.ExecuteMultiLines(query); + t.GetDatabaseTransaction().ExecuteMultiLines(query); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_HasFastCountResources, 1); } @@ -257,7 +257,7 @@ std::string query; Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::POSTGRESQL_GET_LAST_CHANGE_INDEX); - t.ExecuteMultiLines(query); + t.GetDatabaseTransaction().ExecuteMultiLines(query); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_GetLastChangeIndex, 1); } @@ -270,10 +270,10 @@ // New in release 4.0 to deal with multiple writers DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); - if (!t.DoesTableExist("ServerProperties")) + if (!t.GetDatabaseTransaction().DoesTableExist("ServerProperties")) { - t.ExecuteMultiLines("CREATE TABLE ServerProperties(server VARCHAR(64) NOT NULL, " - "property INTEGER, value TEXT, PRIMARY KEY(server, property))"); + t.GetDatabaseTransaction().ExecuteMultiLines("CREATE TABLE ServerProperties(server VARCHAR(64) NOT NULL, " + "property INTEGER, value TEXT, PRIMARY KEY(server, property))"); } t.Commit(); diff -r c82c2cf84ae8 -r a063bbf10a3e SQLite/Plugins/SQLiteIndex.cpp --- a/SQLite/Plugins/SQLiteIndex.cpp Mon Apr 12 17:07:06 2021 +0200 +++ b/SQLite/Plugins/SQLiteIndex.cpp Tue Apr 13 12:07:30 2021 +0200 @@ -85,14 +85,14 @@ { DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); - if (!t.DoesTableExist("Resources")) + if (!t.GetDatabaseTransaction().DoesTableExist("Resources")) { std::string query; Orthanc::EmbeddedResources::GetFileResource (query, Orthanc::EmbeddedResources::SQLITE_PREPARE_INDEX); - t.ExecuteMultiLines(query); + t.GetDatabaseTransaction().ExecuteMultiLines(query); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabaseSchemaVersion, expectedVersion); SetGlobalIntegerProperty(manager, MISSING_SERVER_IDENTIFIER, Orthanc::GlobalProperty_DatabasePatchLevel, 1); @@ -104,7 +104,7 @@ { DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); - if (!t.DoesTableExist("Resources")) + if (!t.GetDatabaseTransaction().DoesTableExist("Resources")) { LOG(ERROR) << "Corrupted SQLite database"; throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); @@ -137,10 +137,10 @@ { DatabaseManager::Transaction t(manager, TransactionType_ReadWrite); - if (!t.DoesTableExist("ServerProperties")) + if (!t.GetDatabaseTransaction().DoesTableExist("ServerProperties")) { - t.ExecuteMultiLines("CREATE TABLE ServerProperties(server TEXT, " - "property INTEGER, value TEXT, PRIMARY KEY(server, property))"); + t.GetDatabaseTransaction().ExecuteMultiLines("CREATE TABLE ServerProperties(server TEXT, " + "property INTEGER, value TEXT, PRIMARY KEY(server, property))"); } t.Commit();