From f7a67099d45cae68964975ac7b60892fdc468d39 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sat, 27 Jul 2019 11:45:56 +0200 Subject: Core/DBLayer: Prevent mixing databases with query holders (cherry picked from commit 13440434c34da28a5106af8419aabc8e5783faf0) # Conflicts: # src/server/game/Server/WorldSession.cpp # src/server/game/Server/WorldSession.h --- src/server/database/Database/DatabaseEnvFwd.h | 12 +++++++++-- .../database/Database/DatabaseWorkerPool.cpp | 2 +- src/server/database/Database/DatabaseWorkerPool.h | 2 +- src/server/database/Database/QueryHolder.cpp | 10 ++++----- src/server/database/Database/QueryHolder.h | 24 ++++++++++++++++------ 5 files changed, 35 insertions(+), 15 deletions(-) (limited to 'src/server/database') diff --git a/src/server/database/Database/DatabaseEnvFwd.h b/src/server/database/Database/DatabaseEnvFwd.h index f6f7653c3f9..b743c88506d 100644 --- a/src/server/database/Database/DatabaseEnvFwd.h +++ b/src/server/database/Database/DatabaseEnvFwd.h @@ -63,9 +63,17 @@ using HotfixDatabaseTransaction = SQLTransaction; using LoginDatabaseTransaction = SQLTransaction; using WorldDatabaseTransaction = SQLTransaction; +class SQLQueryHolderBase; +typedef std::future QueryResultHolderFuture; +typedef std::promise QueryResultHolderPromise; + +template class SQLQueryHolder; -typedef std::future QueryResultHolderFuture; -typedef std::promise QueryResultHolderPromise; + +using CharacterDatabaseQueryHolder = SQLQueryHolder; +using HotfixDatabaseQueryHolder = SQLQueryHolder; +using LoginDatabaseQueryHolder = SQLQueryHolder; +using WorldDatabaseQueryHolder = SQLQueryHolder; // mysql struct MySQLHandle; diff --git a/src/server/database/Database/DatabaseWorkerPool.cpp b/src/server/database/Database/DatabaseWorkerPool.cpp index ac1cc3c71dc..75bda12ffbf 100644 --- a/src/server/database/Database/DatabaseWorkerPool.cpp +++ b/src/server/database/Database/DatabaseWorkerPool.cpp @@ -222,7 +222,7 @@ QueryCallback DatabaseWorkerPool::AsyncQuery(PreparedStatement* stmt) } template -QueryResultHolderFuture DatabaseWorkerPool::DelayQueryHolder(SQLQueryHolder* holder) +QueryResultHolderFuture DatabaseWorkerPool::DelayQueryHolder(SQLQueryHolder* holder) { SQLQueryHolderTask* task = new SQLQueryHolderTask(holder); // Store future result before enqueueing - task might get already processed and deleted before returning from this method diff --git a/src/server/database/Database/DatabaseWorkerPool.h b/src/server/database/Database/DatabaseWorkerPool.h index 25cd87bf6cd..8824dc38d85 100644 --- a/src/server/database/Database/DatabaseWorkerPool.h +++ b/src/server/database/Database/DatabaseWorkerPool.h @@ -160,7 +160,7 @@ class DatabaseWorkerPool //! return object as soon as the query is executed. //! The return value is then processed in ProcessQueryCallback methods. //! Any prepared statements added to this holder need to be prepared with the CONNECTION_ASYNC flag. - QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder); + QueryResultHolderFuture DelayQueryHolder(SQLQueryHolder* holder); /** Transaction context methods. diff --git a/src/server/database/Database/QueryHolder.cpp b/src/server/database/Database/QueryHolder.cpp index e9012cc9a90..dacd12913da 100644 --- a/src/server/database/Database/QueryHolder.cpp +++ b/src/server/database/Database/QueryHolder.cpp @@ -21,7 +21,7 @@ #include "Log.h" #include "QueryResult.h" -bool SQLQueryHolder::SetPreparedQuery(size_t index, PreparedStatementBase* stmt) +bool SQLQueryHolderBase::SetPreparedQueryImpl(size_t index, PreparedStatementBase* stmt) { if (m_queries.size() <= index) { @@ -33,7 +33,7 @@ bool SQLQueryHolder::SetPreparedQuery(size_t index, PreparedStatementBase* stmt) return true; } -PreparedQueryResult SQLQueryHolder::GetPreparedResult(size_t index) +PreparedQueryResult SQLQueryHolderBase::GetPreparedResult(size_t index) { // Don't call to this function if the index is of a prepared statement if (index < m_queries.size()) @@ -42,7 +42,7 @@ PreparedQueryResult SQLQueryHolder::GetPreparedResult(size_t index) return PreparedQueryResult(nullptr); } -void SQLQueryHolder::SetPreparedResult(size_t index, PreparedResultSet* result) +void SQLQueryHolderBase::SetPreparedResult(size_t index, PreparedResultSet* result) { if (result && !result->GetRowCount()) { @@ -55,7 +55,7 @@ void SQLQueryHolder::SetPreparedResult(size_t index, PreparedResultSet* result) m_queries[index].second = PreparedQueryResult(result); } -SQLQueryHolder::~SQLQueryHolder() +SQLQueryHolderBase::~SQLQueryHolderBase() { for (std::pair& query : m_queries) { @@ -65,7 +65,7 @@ SQLQueryHolder::~SQLQueryHolder() } } -void SQLQueryHolder::SetSize(size_t size) +void SQLQueryHolderBase::SetSize(size_t size) { /// to optimize push_back, reserve the number of queries about to be executed m_queries.resize(size); diff --git a/src/server/database/Database/QueryHolder.h b/src/server/database/Database/QueryHolder.h index f7a21a97e70..fe4a0e78331 100644 --- a/src/server/database/Database/QueryHolder.h +++ b/src/server/database/Database/QueryHolder.h @@ -20,29 +20,41 @@ #include "SQLOperation.h" -class TC_DATABASE_API SQLQueryHolder +class TC_DATABASE_API SQLQueryHolderBase { friend class SQLQueryHolderTask; private: std::vector> m_queries; public: - SQLQueryHolder() { } - virtual ~SQLQueryHolder(); - bool SetPreparedQuery(size_t index, PreparedStatementBase* stmt); + SQLQueryHolderBase() { } + virtual ~SQLQueryHolderBase(); void SetSize(size_t size); PreparedQueryResult GetPreparedResult(size_t index); void SetPreparedResult(size_t index, PreparedResultSet* result); + + protected: + bool SetPreparedQueryImpl(size_t index, PreparedStatementBase* stmt); +}; + +template +class SQLQueryHolder : public SQLQueryHolderBase +{ +public: + bool SetPreparedQuery(size_t index, PreparedStatement* stmt) + { + return SetPreparedQueryImpl(index, stmt); + } }; class TC_DATABASE_API SQLQueryHolderTask : public SQLOperation { private: - SQLQueryHolder* m_holder; + SQLQueryHolderBase* m_holder; QueryResultHolderPromise m_result; bool m_executed; public: - SQLQueryHolderTask(SQLQueryHolder* holder) + SQLQueryHolderTask(SQLQueryHolderBase* holder) : m_holder(holder), m_executed(false) { } ~SQLQueryHolderTask(); -- cgit v1.2.3