aboutsummaryrefslogtreecommitdiff
path: root/src/server/database/Database
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2019-07-27 10:52:33 +0200
committerShauren <shauren.trinity@gmail.com>2019-07-27 10:52:33 +0200
commitf6e2b8cdc1c8a3dd291947f67566b41dac116622 (patch)
tree22a01cb91b2d47827ae73b48fcace3926587a341 /src/server/database/Database
parente8e89f58fb800014f53341f12505f60ee2b5fb6f (diff)
Core/DBLayer: Prevent committing transactions started on a different database
Diffstat (limited to 'src/server/database/Database')
-rw-r--r--src/server/database/Database/DatabaseEnvFwd.h22
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.cpp12
-rw-r--r--src/server/database/Database/DatabaseWorkerPool.h10
-rw-r--r--src/server/database/Database/Implementation/CharacterDatabase.h2
-rw-r--r--src/server/database/Database/Implementation/HotfixDatabase.h2
-rw-r--r--src/server/database/Database/Implementation/LoginDatabase.h2
-rw-r--r--src/server/database/Database/Implementation/WorldDatabase.h2
-rw-r--r--src/server/database/Database/MySQLConnection.cpp2
-rw-r--r--src/server/database/Database/MySQLConnection.h2
-rw-r--r--src/server/database/Database/Transaction.cpp6
-rw-r--r--src/server/database/Database/Transaction.h22
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;
};