comparison Framework/MySQL/MySQLDatabase.cpp @ 23:b2ff1cd2907a

handling of implicit transactions in DatabaseManager
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 12 Jul 2018 10:44:17 +0200
parents 1e9bad493475
children 17f849b2af34
comparison
equal deleted inserted replaced
22:1e9bad493475 23:b2ff1cd2907a
22 #include "MySQLDatabase.h" 22 #include "MySQLDatabase.h"
23 23
24 #include "MySQLResult.h" 24 #include "MySQLResult.h"
25 #include "MySQLStatement.h" 25 #include "MySQLStatement.h"
26 #include "MySQLTransaction.h" 26 #include "MySQLTransaction.h"
27 #include "../Common/ImplicitTransaction.h"
27 #include "../Common/Integer64Value.h" 28 #include "../Common/Integer64Value.h"
28 29
29 #include <Core/Logging.h> 30 #include <Core/Logging.h>
30 #include <Core/OrthancException.h> 31 #include <Core/OrthancException.h>
31 #include <Core/Toolbox.h> 32 #include <Core/Toolbox.h>
102 return mysql_; 103 return mysql_;
103 } 104 }
104 } 105 }
105 106
106 107
107 void MySQLDatabase::Open() 108 void MySQLDatabase::OpenInternal(const char* db)
108 { 109 {
109 if (mysql_ != NULL) 110 if (mysql_ != NULL)
110 { 111 {
111 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); 112 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
112 } 113 }
116 { 117 {
117 LOG(ERROR) << "Cannot initialize the MySQL connector"; 118 LOG(ERROR) << "Cannot initialize the MySQL connector";
118 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 119 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
119 } 120 }
120 121
121 const char* db = (parameters_.GetDatabase().empty() ? NULL :
122 parameters_.GetDatabase().c_str());
123
124 const char* socket = (parameters_.GetUnixSocket().empty() ? NULL : 122 const char* socket = (parameters_.GetUnixSocket().empty() ? NULL :
125 parameters_.GetUnixSocket().c_str()); 123 parameters_.GetUnixSocket().c_str());
126 124
127 if (mysql_real_connect(mysql_, 125 if (mysql_real_connect(mysql_,
128 parameters_.GetHost().c_str(), 126 parameters_.GetHost().c_str(),
142 if (mysql_set_character_set(mysql_, "utf8mb4") != 0) 140 if (mysql_set_character_set(mysql_, "utf8mb4") != 0)
143 { 141 {
144 LOG(ERROR) << "Cannot set the character set to UTF8"; 142 LOG(ERROR) << "Cannot set the character set to UTF8";
145 Close(); 143 Close();
146 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database); 144 throw Orthanc::OrthancException(Orthanc::ErrorCode_Database);
145 }
146 }
147
148
149 void MySQLDatabase::Open()
150 {
151 if (parameters_.GetDatabase().empty())
152 {
153 throw Orthanc::OrthancException(Orthanc::ErrorCode_ParameterOutOfRange);
154 }
155 else
156 {
157 OpenInternal(parameters_.GetDatabase().c_str());
158 }
159 }
160
161
162 void MySQLDatabase::ClearDatabase(const MySQLParameters& parameters)
163 {
164 MySQLDatabase db(parameters);
165 db.OpenRoot();
166
167 const std::string& database = parameters.GetDatabase();
168
169 {
170 MySQLTransaction t(db);
171
172 if (!db.DoesDatabaseExist(t, database))
173 {
174 LOG(ERROR) << "Inexistent database, please create it first: " << database;
175 throw Orthanc::OrthancException(Orthanc::ErrorCode_UnknownResource);
176 }
177
178 db.Execute("DROP DATABASE " + database, false);
179 db.Execute("CREATE DATABASE " + database, false);
180 t.Commit();
147 } 181 }
148 } 182 }
149 183
150 184
151 namespace 185 namespace
376 410
377 return new MySQLStatement(*this, query); 411 return new MySQLStatement(*this, query);
378 } 412 }
379 413
380 414
381 ITransaction* MySQLDatabase::CreateTransaction() 415
382 { 416 namespace
383 if (mysql_ == NULL) 417 {
384 { 418 class MySQLImplicitTransaction : public ImplicitTransaction
385 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); 419 {
386 } 420 private:
387 421 MySQLDatabase& db_;
388 return new MySQLTransaction(*this); 422
423 protected:
424 virtual IResult* ExecuteInternal(IPrecompiledStatement& statement,
425 const Dictionary& parameters)
426 {
427 return dynamic_cast<MySQLStatement&>(statement).Execute(*this, parameters);
428 }
429
430 virtual void ExecuteWithoutResultInternal(IPrecompiledStatement& statement,
431 const Dictionary& parameters)
432 {
433 dynamic_cast<MySQLStatement&>(statement).ExecuteWithoutResult(*this, parameters);
434 }
435
436 public:
437 MySQLImplicitTransaction(MySQLDatabase& db) :
438 db_(db)
439 {
440 }
441 };
442 }
443
444
445 ITransaction* MySQLDatabase::CreateTransaction(bool isImplicit)
446 {
447 if (mysql_ == NULL)
448 {
449 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls);
450 }
451
452 if (isImplicit)
453 {
454 return new MySQLImplicitTransaction(*this);
455 }
456 else
457 {
458 return new MySQLTransaction(*this);
459 }
389 } 460 }
390 461
391 462
392 void MySQLDatabase::GlobalFinalization() 463 void MySQLDatabase::GlobalFinalization()
393 { 464 {