aboutsummaryrefslogtreecommitdiff
path: root/src/server/database/Database
diff options
context:
space:
mode:
authorShauren <shauren.trinity@gmail.com>2019-07-27 10:52:33 +0200
committerGiacomo Pozzoni <giacomopoz@gmail.com>2020-03-31 13:42:01 +0000
commit635b8d52d58f7d502fc249c11c1044923e80935f (patch)
tree3305f07a454da2d7385e1cd60fd20a3dde5e2cec /src/server/database/Database
parentfe1003bdbd88e2bccf2ac91ffd18804a6d9b6fb3 (diff)
Core/DBLayer: Prevent committing transactions started on a different database
(cherry picked from commit f6e2b8cdc1c8a3dd291947f67566b41dac116622) # Conflicts: # src/server/bnetserver/REST/LoginRESTService.cpp # src/server/database/Database/DatabaseWorkerPool.cpp # src/server/database/Database/DatabaseWorkerPool.h # src/server/database/Database/Implementation/HotfixDatabase.h # src/server/database/Database/MySQLConnection.h # src/server/database/Database/Transaction.cpp # src/server/database/Database/Transaction.h # src/server/game/Achievements/AchievementMgr.cpp # src/server/game/Achievements/AchievementMgr.h # src/server/game/AuctionHouse/AuctionHouseMgr.cpp # src/server/game/AuctionHouse/AuctionHouseMgr.h # src/server/game/BattlePets/BattlePetMgr.cpp # src/server/game/BattlePets/BattlePetMgr.h # src/server/game/BlackMarket/BlackMarketMgr.cpp # src/server/game/BlackMarket/BlackMarketMgr.h # src/server/game/Entities/Creature/Creature.cpp # src/server/game/Entities/Item/Item.cpp # src/server/game/Entities/Item/Item.h # src/server/game/Entities/Player/CollectionMgr.cpp # src/server/game/Entities/Player/CollectionMgr.h # src/server/game/Entities/Player/Player.cpp # src/server/game/Entities/Player/Player.h # src/server/game/Garrison/Garrison.cpp # src/server/game/Garrison/Garrison.h # src/server/game/Groups/Group.cpp # src/server/game/Guilds/Guild.cpp # src/server/game/Guilds/Guild.h # src/server/game/Guilds/GuildFinderMgr.cpp # src/server/game/Handlers/BlackMarketHandler.cpp # src/server/game/Handlers/CalendarHandler.cpp # src/server/game/Handlers/CharacterHandler.cpp # src/server/game/Handlers/MailHandler.cpp # src/server/game/Handlers/PetHandler.cpp # src/server/game/Handlers/PetitionsHandler.cpp # src/server/game/Mails/Mail.cpp # src/server/game/Pools/PoolMgr.cpp # src/server/game/Quests/QuestObjectiveCriteriaMgr.cpp # src/server/game/Quests/QuestObjectiveCriteriaMgr.h # src/server/game/Scenarios/InstanceScenario.cpp # src/server/game/Server/WorldSession.cpp # src/server/game/Server/WorldSession.h # src/server/game/Spells/SpellHistory.cpp # src/server/game/Support/SupportMgr.cpp # src/server/game/Tools/PlayerDump.cpp # src/server/scripts/Commands/cs_misc.cpp
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/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
10 files changed, 53 insertions, 29 deletions
diff --git a/src/server/database/Database/DatabaseEnvFwd.h b/src/server/database/Database/DatabaseEnvFwd.h
index 1fe95c54a5c..f6f7653c3f9 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 da30c84a753..ac1cc3c71dc 100644
--- a/src/server/database/Database/DatabaseWorkerPool.cpp
+++ b/src/server/database/Database/DatabaseWorkerPool.cpp
@@ -232,13 +232,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.
@@ -261,7 +261,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);
@@ -447,7 +447,7 @@ void DatabaseWorkerPool<T>::DirectExecute(PreparedStatement<T>* stmt)
}
template <class T>
-void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& trans, char const* sql)
+void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction<T>& trans, char const* sql)
{
if (!trans)
Execute(sql);
@@ -456,7 +456,7 @@ void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& trans, char const* 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 635670dce08..25cd87bf6cd 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, char const* sql);
+ void ExecuteOrAppend(SQLTransaction<T>& trans, char const* 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 bb78cdbc542..1367971d697 100644
--- a/src/server/database/Database/Implementation/CharacterDatabase.h
+++ b/src/server/database/Database/Implementation/CharacterDatabase.h
@@ -540,6 +540,4 @@ public:
void DoPrepareStatements() override;
};
-using CharacterDatabasePreparedStatement = PreparedStatement<CharacterDatabaseConnection>;
-
#endif
diff --git a/src/server/database/Database/Implementation/LoginDatabase.h b/src/server/database/Database/Implementation/LoginDatabase.h
index ea9b0d4a30f..f9a18960728 100644
--- a/src/server/database/Database/Implementation/LoginDatabase.h
+++ b/src/server/database/Database/Implementation/LoginDatabase.h
@@ -137,6 +137,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 d767908244a..7b009320716 100644
--- a/src/server/database/Database/Implementation/WorldDatabase.h
+++ b/src/server/database/Database/Implementation/WorldDatabase.h
@@ -118,6 +118,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 06e7f703437..8205b70f38d 100644
--- a/src/server/database/Database/MySQLConnection.cpp
+++ b/src/server/database/Database/MySQLConnection.cpp
@@ -366,7 +366,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 411f570ba32..e4368db44ba 100644
--- a/src/server/database/Database/MySQLConnection.h
+++ b/src/server/database/Database/MySQLConnection.h
@@ -76,7 +76,7 @@ class TC_DATABASE_API MySQLConnection
void BeginTransaction();
void RollbackTransaction();
void CommitTransaction();
- int ExecuteTransaction(SQLTransaction& transaction);
+ int ExecuteTransaction(std::shared_ptr<TransactionBase> transaction);
size_t EscapeString(char* to, const char* from, size_t length);
void Ping();
diff --git a/src/server/database/Database/Transaction.cpp b/src/server/database/Database/Transaction.cpp
index 867dcf1f1f0..be5c28bceb3 100644
--- a/src/server/database/Database/Transaction.cpp
+++ b/src/server/database/Database/Transaction.cpp
@@ -29,7 +29,7 @@ std::mutex TransactionTask::_deadlockLock;
#define DEADLOCK_MAX_RETRY_TIME_MS 60000
//- Append a raw ad-hoc query to the transaction
-void Transaction::Append(char const* sql)
+void TransactionBase::Append(char const* sql)
{
SQLElementData data;
data.type = SQL_ELEMENT_RAW;
@@ -38,7 +38,7 @@ void Transaction::Append(char const* 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;
@@ -46,7 +46,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 0a926f1e55d..b11f94ce14e 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(char const* 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;
};