diff options
| author | Shauren <shauren.trinity@gmail.com> | 2019-07-27 10:52:33 +0200 |
|---|---|---|
| committer | Shauren <shauren.trinity@gmail.com> | 2019-07-27 10:52:33 +0200 |
| commit | f6e2b8cdc1c8a3dd291947f67566b41dac116622 (patch) | |
| tree | 22a01cb91b2d47827ae73b48fcace3926587a341 /src/server/database/Database | |
| parent | e8e89f58fb800014f53341f12505f60ee2b5fb6f (diff) | |
Core/DBLayer: Prevent committing transactions started on a different database
Diffstat (limited to 'src/server/database/Database')
11 files changed, 53 insertions, 31 deletions
diff --git a/src/server/database/Database/DatabaseEnvFwd.h b/src/server/database/Database/DatabaseEnvFwd.h index c5c8f6dd3c3..61dad270e99 100644 --- a/src/server/database/Database/DatabaseEnvFwd.h +++ b/src/server/database/Database/DatabaseEnvFwd.h @@ -28,11 +28,21 @@ typedef std::shared_ptr<ResultSet> QueryResult; typedef std::future<QueryResult> QueryResultFuture; typedef std::promise<QueryResult> QueryResultPromise; +class CharacterDatabaseConnection; +class HotfixDatabaseConnection; +class LoginDatabaseConnection; +class WorldDatabaseConnection; + class PreparedStatementBase; template<typename T> class PreparedStatement; +using CharacterDatabasePreparedStatement = PreparedStatement<CharacterDatabaseConnection>; +using HotfixDatabasePreparedStatement = PreparedStatement<HotfixDatabaseConnection>; +using LoginDatabasePreparedStatement = PreparedStatement<LoginDatabaseConnection>; +using WorldDatabasePreparedStatement = PreparedStatement<WorldDatabaseConnection>; + class PreparedResultSet; typedef std::shared_ptr<PreparedResultSet> PreparedQueryResult; typedef std::future<PreparedQueryResult> PreparedQueryResultFuture; @@ -40,8 +50,18 @@ typedef std::promise<PreparedQueryResult> PreparedQueryResultPromise; class QueryCallback; +class TransactionBase; + +template<typename T> class Transaction; -typedef std::shared_ptr<Transaction> SQLTransaction; + +template<typename T> +using SQLTransaction = std::shared_ptr<Transaction<T>>; + +using CharacterDatabaseTransaction = SQLTransaction<CharacterDatabaseConnection>; +using HotfixDatabaseTransaction = SQLTransaction<HotfixDatabaseConnection>; +using LoginDatabaseTransaction = SQLTransaction<LoginDatabaseConnection>; +using WorldDatabaseTransaction = SQLTransaction<WorldDatabaseConnection>; class SQLQueryHolder; typedef std::future<SQLQueryHolder*> QueryResultHolderFuture; diff --git a/src/server/database/Database/DatabaseWorkerPool.cpp b/src/server/database/Database/DatabaseWorkerPool.cpp index cda22f6ed93..d6ce7dd2e33 100644 --- a/src/server/database/Database/DatabaseWorkerPool.cpp +++ b/src/server/database/Database/DatabaseWorkerPool.cpp @@ -211,13 +211,13 @@ QueryResultHolderFuture DatabaseWorkerPool<T>::DelayQueryHolder(SQLQueryHolder* } template <class T> -SQLTransaction DatabaseWorkerPool<T>::BeginTransaction() +SQLTransaction<T> DatabaseWorkerPool<T>::BeginTransaction() { - return std::make_shared<Transaction>(); + return std::make_shared<Transaction<T>>(); } template <class T> -void DatabaseWorkerPool<T>::CommitTransaction(SQLTransaction transaction) +void DatabaseWorkerPool<T>::CommitTransaction(SQLTransaction<T> transaction) { #ifdef TRINITY_DEBUG //! Only analyze transaction weaknesses in Debug mode. @@ -240,7 +240,7 @@ void DatabaseWorkerPool<T>::CommitTransaction(SQLTransaction transaction) } template <class T> -void DatabaseWorkerPool<T>::DirectCommitTransaction(SQLTransaction& transaction) +void DatabaseWorkerPool<T>::DirectCommitTransaction(SQLTransaction<T>& transaction) { T* connection = GetFreeConnection(); int errorCode = connection->ExecuteTransaction(transaction); @@ -426,7 +426,7 @@ void DatabaseWorkerPool<T>::DirectExecute(PreparedStatement<T>* stmt) } template <class T> -void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& trans, const char* sql) +void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction<T>& trans, const char* sql) { if (!trans) Execute(sql); @@ -435,7 +435,7 @@ void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& trans, const char* s } template <class T> -void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& trans, PreparedStatement<T>* stmt) +void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction<T>& trans, PreparedStatement<T>* stmt) { if (!trans) Execute(stmt); diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h index c8fe778f1e8..548315e9f26 100644 --- a/src/server/database/Database/DatabaseWorkerPool.h +++ b/src/server/database/Database/DatabaseWorkerPool.h @@ -167,23 +167,23 @@ class DatabaseWorkerPool */ //! Begins an automanaged transaction pointer that will automatically rollback if not commited. (Autocommit=0) - SQLTransaction BeginTransaction(); + SQLTransaction<T> BeginTransaction(); //! Enqueues a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations //! were appended to the transaction will be respected during execution. - void CommitTransaction(SQLTransaction transaction); + void CommitTransaction(SQLTransaction<T> transaction); //! Directly executes a collection of one-way SQL operations (can be both adhoc and prepared). The order in which these operations //! were appended to the transaction will be respected during execution. - void DirectCommitTransaction(SQLTransaction& transaction); + void DirectCommitTransaction(SQLTransaction<T>& transaction); //! Method used to execute ad-hoc statements in a diverse context. //! Will be wrapped in a transaction if valid object is present, otherwise executed standalone. - void ExecuteOrAppend(SQLTransaction& trans, const char* sql); + void ExecuteOrAppend(SQLTransaction<T>& trans, const char* sql); //! Method used to execute prepared statements in a diverse context. //! Will be wrapped in a transaction if valid object is present, otherwise executed standalone. - void ExecuteOrAppend(SQLTransaction& trans, PreparedStatement<T>* stmt); + void ExecuteOrAppend(SQLTransaction<T>& trans, PreparedStatement<T>* stmt); /** Other diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index 5bb6aec0c74..fa2f0071a23 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -647,6 +647,4 @@ public: void DoPrepareStatements() override; }; -using CharacterDatabasePreparedStatement = PreparedStatement<CharacterDatabaseConnection>; - #endif diff --git a/src/server/database/Database/Implementation/HotfixDatabase.h b/src/server/database/Database/Implementation/HotfixDatabase.h index e42d07011ee..e31704bebe7 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -589,6 +589,4 @@ public: void DoPrepareStatements() override; }; -using HotfixDatabasePreparedStatement = PreparedStatement<HotfixDatabaseConnection>; - #endif diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h index 74f2f47a3a7..5fcc11a358a 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -181,6 +181,4 @@ public: void DoPrepareStatements() override; }; -using LoginDatabasePreparedStatement = PreparedStatement<LoginDatabaseConnection>; - #endif diff --git a/src/server/database/Database/Implementation/WorldDatabase.h b/src/server/database/Database/Implementation/WorldDatabase.h index 6f6db8b83f2..94dd3519c17 100644 --- a/src/server/database/Database/Implementation/WorldDatabase.h +++ b/src/server/database/Database/Implementation/WorldDatabase.h @@ -116,6 +116,4 @@ public: void DoPrepareStatements() override; }; -using WorldDatabasePreparedStatement = PreparedStatement<WorldDatabaseConnection>; - #endif diff --git a/src/server/database/Database/MySQLConnection.cpp b/src/server/database/Database/MySQLConnection.cpp index 1d2286ede44..229081a3ce0 100644 --- a/src/server/database/Database/MySQLConnection.cpp +++ b/src/server/database/Database/MySQLConnection.cpp @@ -372,7 +372,7 @@ void MySQLConnection::CommitTransaction() Execute("COMMIT"); } -int MySQLConnection::ExecuteTransaction(SQLTransaction& transaction) +int MySQLConnection::ExecuteTransaction(std::shared_ptr<TransactionBase> transaction) { std::vector<SQLElementData> const& queries = transaction->m_queries; if (queries.empty()) diff --git a/src/server/database/Database/MySQLConnection.h b/src/server/database/Database/MySQLConnection.h index dcf7f21567b..1e0c65cb27c 100644 --- a/src/server/database/Database/MySQLConnection.h +++ b/src/server/database/Database/MySQLConnection.h @@ -79,7 +79,7 @@ class TC_DATABASE_API MySQLConnection void BeginTransaction(); void RollbackTransaction(); void CommitTransaction(); - int ExecuteTransaction(SQLTransaction& transaction); + int ExecuteTransaction(std::shared_ptr<TransactionBase> transaction); void Ping(); diff --git a/src/server/database/Database/Transaction.cpp b/src/server/database/Database/Transaction.cpp index b135d7a44cc..a522f1a5f46 100644 --- a/src/server/database/Database/Transaction.cpp +++ b/src/server/database/Database/Transaction.cpp @@ -23,7 +23,7 @@ std::mutex TransactionTask::_deadlockLock; //- Append a raw ad-hoc query to the transaction -void Transaction::Append(const char* sql) +void TransactionBase::Append(const char* sql) { SQLElementData data; data.type = SQL_ELEMENT_RAW; @@ -32,7 +32,7 @@ void Transaction::Append(const char* sql) } //- Append a prepared statement to the transaction -void Transaction::Append(PreparedStatementBase* stmt) +void TransactionBase::AppendPreparedStatement(PreparedStatementBase* stmt) { SQLElementData data; data.type = SQL_ELEMENT_PREPARED; @@ -40,7 +40,7 @@ void Transaction::Append(PreparedStatementBase* stmt) m_queries.push_back(data); } -void Transaction::Cleanup() +void TransactionBase::Cleanup() { // This might be called by explicit calls to Cleanup or by the auto-destructor if (_cleanedUp) diff --git a/src/server/database/Database/Transaction.h b/src/server/database/Database/Transaction.h index 164dcb2d82a..26d1fa5910d 100644 --- a/src/server/database/Database/Transaction.h +++ b/src/server/database/Database/Transaction.h @@ -26,7 +26,7 @@ #include <vector> /*! Transactions, high level class. */ -class TC_DATABASE_API Transaction +class TC_DATABASE_API TransactionBase { friend class TransactionTask; friend class MySQLConnection; @@ -35,10 +35,9 @@ class TC_DATABASE_API Transaction friend class DatabaseWorkerPool; public: - Transaction() : _cleanedUp(false) { } - ~Transaction() { Cleanup(); } + TransactionBase() : _cleanedUp(false) { } + virtual ~TransactionBase() { Cleanup(); } - void Append(PreparedStatementBase* statement); void Append(const char* sql); template<typename Format, typename... Args> void PAppend(Format&& sql, Args&&... args) @@ -49,12 +48,23 @@ class TC_DATABASE_API Transaction std::size_t GetSize() const { return m_queries.size(); } protected: + void AppendPreparedStatement(PreparedStatementBase* statement); void Cleanup(); std::vector<SQLElementData> m_queries; private: bool _cleanedUp; +}; +template<typename T> +class Transaction : public TransactionBase +{ +public: + using TransactionBase::Append; + void Append(PreparedStatement<T>* statement) + { + AppendPreparedStatement(statement); + } }; /*! Low level class*/ @@ -64,13 +74,13 @@ class TC_DATABASE_API TransactionTask : public SQLOperation friend class DatabaseWorker; public: - TransactionTask(SQLTransaction trans) : m_trans(trans) { } + TransactionTask(std::shared_ptr<TransactionBase> trans) : m_trans(trans) { } ~TransactionTask() { } protected: bool Execute() override; - SQLTransaction m_trans; + std::shared_ptr<TransactionBase> m_trans; static std::mutex _deadlockLock; }; |
