diff options
Diffstat (limited to 'src/server/database/Database')
16 files changed, 78 insertions, 54 deletions
diff --git a/src/server/database/Database/DatabaseEnvFwd.h b/src/server/database/Database/DatabaseEnvFwd.h index c7203a89d5d..c5c8f6dd3c3 100644 --- a/src/server/database/Database/DatabaseEnvFwd.h +++ b/src/server/database/Database/DatabaseEnvFwd.h @@ -28,6 +28,9 @@ typedef std::shared_ptr<ResultSet> QueryResult; typedef std::future<QueryResult> QueryResultFuture; typedef std::promise<QueryResult> QueryResultPromise; +class PreparedStatementBase; + +template<typename T> class PreparedStatement; class PreparedResultSet; diff --git a/src/server/database/Database/DatabaseWorkerPool.cpp b/src/server/database/Database/DatabaseWorkerPool.cpp index f30cd48b459..cda22f6ed93 100644 --- a/src/server/database/Database/DatabaseWorkerPool.cpp +++ b/src/server/database/Database/DatabaseWorkerPool.cpp @@ -162,7 +162,7 @@ QueryResult DatabaseWorkerPool<T>::Query(const char* sql, T* connection /*= null } template <class T> -PreparedQueryResult DatabaseWorkerPool<T>::Query(PreparedStatement* stmt) +PreparedQueryResult DatabaseWorkerPool<T>::Query(PreparedStatement<T>* stmt) { auto connection = GetFreeConnection(); PreparedResultSet* ret = connection->Query(stmt); @@ -191,7 +191,7 @@ QueryCallback DatabaseWorkerPool<T>::AsyncQuery(const char* sql) } template <class T> -QueryCallback DatabaseWorkerPool<T>::AsyncQuery(PreparedStatement* stmt) +QueryCallback DatabaseWorkerPool<T>::AsyncQuery(PreparedStatement<T>* stmt) { PreparedStatementTask* task = new PreparedStatementTask(stmt, true); // Store future result before enqueueing - task might get already processed and deleted before returning from this method @@ -269,9 +269,9 @@ void DatabaseWorkerPool<T>::DirectCommitTransaction(SQLTransaction& transaction) } template <class T> -PreparedStatement* DatabaseWorkerPool<T>::GetPreparedStatement(PreparedStatementIndex index) +PreparedStatement<T>* DatabaseWorkerPool<T>::GetPreparedStatement(PreparedStatementIndex index) { - return new PreparedStatement(index); + return new PreparedStatement<T>(index); } template <class T> @@ -397,7 +397,7 @@ void DatabaseWorkerPool<T>::Execute(const char* sql) } template <class T> -void DatabaseWorkerPool<T>::Execute(PreparedStatement* stmt) +void DatabaseWorkerPool<T>::Execute(PreparedStatement<T>* stmt) { PreparedStatementTask* task = new PreparedStatementTask(stmt); Enqueue(task); @@ -415,7 +415,7 @@ void DatabaseWorkerPool<T>::DirectExecute(const char* sql) } template <class T> -void DatabaseWorkerPool<T>::DirectExecute(PreparedStatement* stmt) +void DatabaseWorkerPool<T>::DirectExecute(PreparedStatement<T>* stmt) { T* connection = GetFreeConnection(); connection->Execute(stmt); @@ -435,7 +435,7 @@ void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& trans, const char* s } template <class T> -void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& trans, PreparedStatement* stmt) +void DatabaseWorkerPool<T>::ExecuteOrAppend(SQLTransaction& 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 ad6dd517e13..c8fe778f1e8 100644 --- a/src/server/database/Database/DatabaseWorkerPool.h +++ b/src/server/database/Database/DatabaseWorkerPool.h @@ -83,7 +83,7 @@ class DatabaseWorkerPool //! Enqueues a one-way SQL operation in prepared statement format that will be executed asynchronously. //! Statement must be prepared with CONNECTION_ASYNC flag. - void Execute(PreparedStatement* stmt); + void Execute(PreparedStatement<T>* stmt); /** Direct synchronous one-way statement methods. @@ -106,7 +106,7 @@ class DatabaseWorkerPool //! Directly executes a one-way SQL operation in prepared statement format, that will block the calling thread until finished. //! Statement must be prepared with the CONNECTION_SYNCH flag. - void DirectExecute(PreparedStatement* stmt); + void DirectExecute(PreparedStatement<T>* stmt); /** Synchronous query (with resultset) methods. @@ -141,7 +141,7 @@ class DatabaseWorkerPool //! Directly executes an SQL query in prepared format that will block the calling thread until finished. //! Returns reference counted auto pointer, no need for manual memory management in upper level code. //! Statement must be prepared with CONNECTION_SYNCH flag. - PreparedQueryResult Query(PreparedStatement* stmt); + PreparedQueryResult Query(PreparedStatement<T>* stmt); /** Asynchronous query (with resultset) methods. @@ -154,7 +154,7 @@ class DatabaseWorkerPool //! Enqueues a query in prepared format that will set the value of the PreparedQueryResultFuture return object as soon as the query is executed. //! The return value is then processed in ProcessQueryCallback methods. //! Statement must be prepared with CONNECTION_ASYNC flag. - QueryCallback AsyncQuery(PreparedStatement* stmt); + QueryCallback AsyncQuery(PreparedStatement<T>* stmt); //! Enqueues a vector of SQL operations (can be both adhoc and prepared) that will set the value of the QueryResultHolderFuture //! return object as soon as the query is executed. @@ -183,7 +183,7 @@ class DatabaseWorkerPool //! 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* stmt); + void ExecuteOrAppend(SQLTransaction& trans, PreparedStatement<T>* stmt); /** Other @@ -194,7 +194,7 @@ class DatabaseWorkerPool //! Automanaged (internally) pointer to a prepared statement object for usage in upper level code. //! Pointer is deleted in this->DirectExecute(PreparedStatement*), this->Query(PreparedStatement*) or PreparedStatementTask::~PreparedStatementTask. //! This object is not tied to the prepared statement on the MySQL context yet until execution. - PreparedStatement* GetPreparedStatement(PreparedStatementIndex index); + PreparedStatement<T>* GetPreparedStatement(PreparedStatementIndex index); //! Apply escape string'ing for current collation. (utf8) void EscapeString(std::string& str); diff --git a/src/server/database/Database/Implementation/CharacterDatabase.h b/src/server/database/Database/Implementation/CharacterDatabase.h index fa2f0071a23..5bb6aec0c74 100644 --- a/src/server/database/Database/Implementation/CharacterDatabase.h +++ b/src/server/database/Database/Implementation/CharacterDatabase.h @@ -647,4 +647,6 @@ 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 e31704bebe7..e42d07011ee 100644 --- a/src/server/database/Database/Implementation/HotfixDatabase.h +++ b/src/server/database/Database/Implementation/HotfixDatabase.h @@ -589,4 +589,6 @@ 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 5fcc11a358a..74f2f47a3a7 100644 --- a/src/server/database/Database/Implementation/LoginDatabase.h +++ b/src/server/database/Database/Implementation/LoginDatabase.h @@ -181,4 +181,6 @@ 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 94dd3519c17..6f6db8b83f2 100644 --- a/src/server/database/Database/Implementation/WorldDatabase.h +++ b/src/server/database/Database/Implementation/WorldDatabase.h @@ -116,4 +116,6 @@ 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 9f586739d4a..1d2286ede44 100644 --- a/src/server/database/Database/MySQLConnection.cpp +++ b/src/server/database/Database/MySQLConnection.cpp @@ -193,7 +193,7 @@ bool MySQLConnection::Execute(const char* sql) return true; } -bool MySQLConnection::Execute(PreparedStatement* stmt) +bool MySQLConnection::Execute(PreparedStatementBase* stmt) { if (!m_Mysql) return false; @@ -243,7 +243,7 @@ bool MySQLConnection::Execute(PreparedStatement* stmt) } } -bool MySQLConnection::_Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount) +bool MySQLConnection::_Query(PreparedStatementBase* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount) { if (!m_Mysql) return false; @@ -387,7 +387,7 @@ int MySQLConnection::ExecuteTransaction(SQLTransaction& transaction) { case SQL_ELEMENT_PREPARED: { - PreparedStatement* stmt = data.element.stmt; + PreparedStatementBase* stmt = data.element.stmt; ASSERT(stmt); if (!Execute(stmt)) { @@ -490,7 +490,7 @@ void MySQLConnection::PrepareStatement(uint32 index, const char* sql, Connection } } -PreparedResultSet* MySQLConnection::Query(PreparedStatement* stmt) +PreparedResultSet* MySQLConnection::Query(PreparedStatementBase* stmt) { MYSQL_RES *result = NULL; uint64 rowCount = 0; diff --git a/src/server/database/Database/MySQLConnection.h b/src/server/database/Database/MySQLConnection.h index 73bab8f7602..dcf7f21567b 100644 --- a/src/server/database/Database/MySQLConnection.h +++ b/src/server/database/Database/MySQLConnection.h @@ -70,11 +70,11 @@ class TC_DATABASE_API MySQLConnection public: bool Execute(const char* sql); - bool Execute(PreparedStatement* stmt); + bool Execute(PreparedStatementBase* stmt); ResultSet* Query(const char* sql); - PreparedResultSet* Query(PreparedStatement* stmt); + PreparedResultSet* Query(PreparedStatementBase* stmt); bool _Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount); - bool _Query(PreparedStatement* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount); + bool _Query(PreparedStatementBase* stmt, MYSQL_RES **pResult, uint64* pRowCount, uint32* pFieldCount); void BeginTransaction(); void RollbackTransaction(); diff --git a/src/server/database/Database/PreparedStatement.cpp b/src/server/database/Database/PreparedStatement.cpp index c9da6452bf8..371543453da 100644 --- a/src/server/database/Database/PreparedStatement.cpp +++ b/src/server/database/Database/PreparedStatement.cpp @@ -26,13 +26,13 @@ #include <mysql.h> #include <sstream> -PreparedStatement::PreparedStatement(uint32 index) : +PreparedStatementBase::PreparedStatementBase(uint32 index) : m_stmt(NULL), m_index(index) { } -PreparedStatement::~PreparedStatement() { } +PreparedStatementBase::~PreparedStatementBase() { } -void PreparedStatement::BindParameters() +void PreparedStatementBase::BindParameters() { ASSERT(m_stmt); @@ -92,7 +92,7 @@ void PreparedStatement::BindParameters() } //- Bind to buffer -void PreparedStatement::setBool(const uint8 index, const bool value) +void PreparedStatementBase::setBool(const uint8 index, const bool value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -101,7 +101,7 @@ void PreparedStatement::setBool(const uint8 index, const bool value) statement_data[index].type = TYPE_BOOL; } -void PreparedStatement::setUInt8(const uint8 index, const uint8 value) +void PreparedStatementBase::setUInt8(const uint8 index, const uint8 value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -110,7 +110,7 @@ void PreparedStatement::setUInt8(const uint8 index, const uint8 value) statement_data[index].type = TYPE_UI8; } -void PreparedStatement::setUInt16(const uint8 index, const uint16 value) +void PreparedStatementBase::setUInt16(const uint8 index, const uint16 value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -119,7 +119,7 @@ void PreparedStatement::setUInt16(const uint8 index, const uint16 value) statement_data[index].type = TYPE_UI16; } -void PreparedStatement::setUInt32(const uint8 index, const uint32 value) +void PreparedStatementBase::setUInt32(const uint8 index, const uint32 value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -128,7 +128,7 @@ void PreparedStatement::setUInt32(const uint8 index, const uint32 value) statement_data[index].type = TYPE_UI32; } -void PreparedStatement::setUInt64(const uint8 index, const uint64 value) +void PreparedStatementBase::setUInt64(const uint8 index, const uint64 value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -137,7 +137,7 @@ void PreparedStatement::setUInt64(const uint8 index, const uint64 value) statement_data[index].type = TYPE_UI64; } -void PreparedStatement::setInt8(const uint8 index, const int8 value) +void PreparedStatementBase::setInt8(const uint8 index, const int8 value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -146,7 +146,7 @@ void PreparedStatement::setInt8(const uint8 index, const int8 value) statement_data[index].type = TYPE_I8; } -void PreparedStatement::setInt16(const uint8 index, const int16 value) +void PreparedStatementBase::setInt16(const uint8 index, const int16 value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -155,7 +155,7 @@ void PreparedStatement::setInt16(const uint8 index, const int16 value) statement_data[index].type = TYPE_I16; } -void PreparedStatement::setInt32(const uint8 index, const int32 value) +void PreparedStatementBase::setInt32(const uint8 index, const int32 value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -164,7 +164,7 @@ void PreparedStatement::setInt32(const uint8 index, const int32 value) statement_data[index].type = TYPE_I32; } -void PreparedStatement::setInt64(const uint8 index, const int64 value) +void PreparedStatementBase::setInt64(const uint8 index, const int64 value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -173,7 +173,7 @@ void PreparedStatement::setInt64(const uint8 index, const int64 value) statement_data[index].type = TYPE_I64; } -void PreparedStatement::setFloat(const uint8 index, const float value) +void PreparedStatementBase::setFloat(const uint8 index, const float value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -182,7 +182,7 @@ void PreparedStatement::setFloat(const uint8 index, const float value) statement_data[index].type = TYPE_FLOAT; } -void PreparedStatement::setDouble(const uint8 index, const double value) +void PreparedStatementBase::setDouble(const uint8 index, const double value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -191,7 +191,7 @@ void PreparedStatement::setDouble(const uint8 index, const double value) statement_data[index].type = TYPE_DOUBLE; } -void PreparedStatement::setString(const uint8 index, const std::string& value) +void PreparedStatementBase::setString(const uint8 index, const std::string& value) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -201,7 +201,7 @@ void PreparedStatement::setString(const uint8 index, const std::string& value) statement_data[index].type = TYPE_STRING; } -void PreparedStatement::setBinary(const uint8 index, const std::vector<uint8>& value) +void PreparedStatementBase::setBinary(const uint8 index, const std::vector<uint8>& value) { if (index >= statement_data.size()) statement_data.resize(index + 1); @@ -210,7 +210,7 @@ void PreparedStatement::setBinary(const uint8 index, const std::vector<uint8>& v statement_data[index].type = TYPE_BINARY; } -void PreparedStatement::setNull(const uint8 index) +void PreparedStatementBase::setNull(const uint8 index) { if (index >= statement_data.size()) statement_data.resize(index+1); @@ -472,7 +472,7 @@ std::string MySQLPreparedStatement::getQueryString(std::string const& sqlPattern } //- Execution -PreparedStatementTask::PreparedStatementTask(PreparedStatement* stmt, bool async) : +PreparedStatementTask::PreparedStatementTask(PreparedStatementBase* stmt, bool async) : m_stmt(stmt), m_result(nullptr) { m_has_result = async; // If it's async, then there's a result diff --git a/src/server/database/Database/PreparedStatement.h b/src/server/database/Database/PreparedStatement.h index 0cc2d9179e7..df56bebca32 100644 --- a/src/server/database/Database/PreparedStatement.h +++ b/src/server/database/Database/PreparedStatement.h @@ -73,15 +73,15 @@ struct PreparedStatementData class MySQLPreparedStatement; //- Upper-level class that is used in code -class TC_DATABASE_API PreparedStatement +class TC_DATABASE_API PreparedStatementBase { friend class PreparedStatementTask; friend class MySQLPreparedStatement; friend class MySQLConnection; public: - explicit PreparedStatement(uint32 index); - ~PreparedStatement(); + explicit PreparedStatementBase(uint32 index); + virtual ~PreparedStatementBase(); void setBool(const uint8 index, const bool value); void setUInt8(const uint8 index, const uint8 value); @@ -106,8 +106,21 @@ class TC_DATABASE_API PreparedStatement uint32 m_index; std::vector<PreparedStatementData> statement_data; //- Buffer of parameters, not tied to MySQL in any way yet - PreparedStatement(PreparedStatement const& right) = delete; - PreparedStatement& operator=(PreparedStatement const& right) = delete; + PreparedStatementBase(PreparedStatementBase const& right) = delete; + PreparedStatementBase& operator=(PreparedStatementBase const& right) = delete; +}; + +template<typename T> +class PreparedStatement : public PreparedStatementBase +{ +public: + explicit PreparedStatement(uint32 index) : PreparedStatementBase(index) + { + } + +private: + PreparedStatement(PreparedStatement const& right) = delete; + PreparedStatement& operator=(PreparedStatement const& right) = delete; }; //- Class of which the instances are unique per MySQLConnection @@ -116,7 +129,7 @@ class TC_DATABASE_API PreparedStatement class TC_DATABASE_API MySQLPreparedStatement { friend class MySQLConnection; - friend class PreparedStatement; + friend class PreparedStatementBase; public: MySQLPreparedStatement(MYSQL_STMT* stmt); @@ -139,7 +152,7 @@ class TC_DATABASE_API MySQLPreparedStatement protected: MYSQL_STMT* GetSTMT() { return m_Mstmt; } MYSQL_BIND* GetBind() { return m_bind; } - PreparedStatement* m_stmt; + PreparedStatementBase* m_stmt; void ClearParameters(); void CheckValidIndex(uint8 index); std::string getQueryString(std::string const& sqlPattern) const; @@ -158,14 +171,14 @@ class TC_DATABASE_API MySQLPreparedStatement class TC_DATABASE_API PreparedStatementTask : public SQLOperation { public: - PreparedStatementTask(PreparedStatement* stmt, bool async = false); + PreparedStatementTask(PreparedStatementBase* stmt, bool async = false); ~PreparedStatementTask(); bool Execute() override; PreparedQueryResultFuture GetFuture() { return m_result->get_future(); } protected: - PreparedStatement* m_stmt; + PreparedStatementBase* m_stmt; bool m_has_result; PreparedQueryResultPromise* m_result; }; diff --git a/src/server/database/Database/QueryHolder.cpp b/src/server/database/Database/QueryHolder.cpp index 9a31c2c8412..ff228e1a7d2 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, PreparedStatement* stmt) +bool SQLQueryHolder::SetPreparedQuery(size_t index, PreparedStatementBase* stmt) { if (m_queries.size() <= index) { @@ -86,7 +86,7 @@ bool SQLQueryHolderTask::Execute() /// execute all queries in the holder and pass the results for (size_t i = 0; i < m_holder->m_queries.size(); i++) - if (PreparedStatement* stmt = m_holder->m_queries[i].first) + if (PreparedStatementBase* stmt = m_holder->m_queries[i].first) m_holder->SetPreparedResult(i, m_conn->Query(stmt)); m_result.set_value(m_holder); diff --git a/src/server/database/Database/QueryHolder.h b/src/server/database/Database/QueryHolder.h index a96e864a79f..2eefc9e2f96 100644 --- a/src/server/database/Database/QueryHolder.h +++ b/src/server/database/Database/QueryHolder.h @@ -24,11 +24,11 @@ class TC_DATABASE_API SQLQueryHolder { friend class SQLQueryHolderTask; private: - std::vector<std::pair<PreparedStatement*, PreparedQueryResult>> m_queries; + std::vector<std::pair<PreparedStatementBase*, PreparedQueryResult>> m_queries; public: SQLQueryHolder() { } virtual ~SQLQueryHolder(); - bool SetPreparedQuery(size_t index, PreparedStatement* stmt); + bool SetPreparedQuery(size_t index, PreparedStatementBase* stmt); void SetSize(size_t size); PreparedQueryResult GetPreparedResult(size_t index); void SetPreparedResult(size_t index, PreparedResultSet* result); diff --git a/src/server/database/Database/SQLOperation.h b/src/server/database/Database/SQLOperation.h index 8b09c321be0..bdcaa094b2b 100644 --- a/src/server/database/Database/SQLOperation.h +++ b/src/server/database/Database/SQLOperation.h @@ -24,7 +24,7 @@ //- Union that holds element data union SQLElementUnion { - PreparedStatement* stmt; + PreparedStatementBase* stmt; const char* query; }; diff --git a/src/server/database/Database/Transaction.cpp b/src/server/database/Database/Transaction.cpp index 60232c2154e..b135d7a44cc 100644 --- a/src/server/database/Database/Transaction.cpp +++ b/src/server/database/Database/Transaction.cpp @@ -32,7 +32,7 @@ void Transaction::Append(const char* sql) } //- Append a prepared statement to the transaction -void Transaction::Append(PreparedStatement* stmt) +void Transaction::Append(PreparedStatementBase* stmt) { SQLElementData data; data.type = SQL_ELEMENT_PREPARED; diff --git a/src/server/database/Database/Transaction.h b/src/server/database/Database/Transaction.h index 4a68e5193ff..164dcb2d82a 100644 --- a/src/server/database/Database/Transaction.h +++ b/src/server/database/Database/Transaction.h @@ -38,7 +38,7 @@ class TC_DATABASE_API Transaction Transaction() : _cleanedUp(false) { } ~Transaction() { Cleanup(); } - void Append(PreparedStatement* statement); + void Append(PreparedStatementBase* statement); void Append(const char* sql); template<typename Format, typename... Args> void PAppend(Format&& sql, Args&&... args) |