Mercurial > hg > orthanc-databases
diff Framework/MySQL/MySQLDatabase.cpp @ 137:52b3859ee0b7
MySQL: acquiring named locks instead of numbers
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Thu, 09 May 2019 11:29:17 +0200 |
parents | e26690365c25 |
children | 4cd7e45b671e |
line wrap: on
line diff
--- a/Framework/MySQL/MySQLDatabase.cpp Thu May 09 09:52:11 2019 +0200 +++ b/Framework/MySQL/MySQLDatabase.cpp Thu May 09 11:29:17 2019 +0200 @@ -290,41 +290,65 @@ } - bool MySQLDatabase::RunAdvisoryLockStatement(const std::string& s) + bool MySQLDatabase::RunAdvisoryLockStatement(Query& query, + const std::string& lock) { - Query query(s, false); + const std::string& dbName = parameters_.GetDatabase(); + + // Prepend the name of the lock by the database name. This allows + // to create a namespace for advisory locks: + // https://groups.google.com/d/msg/orthanc-users/yV3LSTh_TjI/MQIcvnMlAQAJ + std::string prefix; + prefix.reserve(dbName.size()); + for (size_t i = 0; i < dbName.size(); i++) + { + if (isalnum(dbName[i]) || + dbName[i] == '$' || + dbName[i] == '_') + { + prefix.push_back(dbName[i]); + } + } + + query.SetType("lock", ValueType_Utf8String); + MySQLStatement statement(*this, query); - MySQLTransaction t(*this); Dictionary args; + args.SetUtf8Value("lock", prefix + "." + lock); - std::auto_ptr<IResult> result(t.Execute(statement, args)); + bool success; - bool success = (!result->IsDone() && - result->GetField(0).GetType() == ValueType_Integer64 && - dynamic_cast<const Integer64Value&>(result->GetField(0)).GetValue() == 1); + { + MySQLTransaction t(*this); + std::auto_ptr<IResult> result(t.Execute(statement, args)); - t.Commit(); + success = (!result->IsDone() && + result->GetField(0).GetType() == ValueType_Integer64 && + dynamic_cast<const Integer64Value&>(result->GetField(0)).GetValue() == 1); + + t.Commit(); + } return success; } - bool MySQLDatabase::AcquireAdvisoryLock(int32_t lock) + bool MySQLDatabase::AcquireAdvisoryLock(const std::string& lock) { - return RunAdvisoryLockStatement("SELECT GET_LOCK('Lock" + - boost::lexical_cast<std::string>(lock) + "', 0);"); + Query query("SELECT GET_LOCK(${lock}, 0)", false); + return RunAdvisoryLockStatement(query, lock); } - bool MySQLDatabase::ReleaseAdvisoryLock(int32_t lock) + bool MySQLDatabase::ReleaseAdvisoryLock(const std::string& lock) { - return RunAdvisoryLockStatement("SELECT RELEASE_LOCK('Lock" + - boost::lexical_cast<std::string>(lock) + "');"); + Query query("SELECT RELEASE_LOCK(${lock})", false); + return RunAdvisoryLockStatement(query, lock); } - void MySQLDatabase::AdvisoryLock(int32_t lock) + void MySQLDatabase::AdvisoryLock(const std::string& lock) { if (!AcquireAdvisoryLock(lock)) { @@ -513,7 +537,7 @@ MySQLDatabase::TransientAdvisoryLock:: TransientAdvisoryLock(MySQLDatabase& database, - int32_t lock) : + const std::string& lock) : database_(database), lock_(lock) {