diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-03-02 19:40:59 +0100 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2021-12-22 20:59:50 +0100 |
commit | ce9c7b477c8dbe8a1ef79bbb6e2a9f2214de44e0 (patch) | |
tree | a8eb285710d95b9727e1712436acc8c2a80d598f /src/server/database/Database | |
parent | 31efaaac4036903783ae9fa285f661a3f3d29012 (diff) |
Core/DBLayer: Refactor PreparedStatement class to not depend on MySQLPreparedStatement
(cherry picked from commit 5b0a32d164ba91207360d8b8a266b69dd0db9869)
Diffstat (limited to 'src/server/database/Database')
-rw-r--r-- | src/server/database/Database/MySQLConnection.cpp | 22 | ||||
-rw-r--r-- | src/server/database/Database/MySQLConnection.h | 2 | ||||
-rw-r--r-- | src/server/database/Database/MySQLPreparedStatement.cpp | 66 | ||||
-rw-r--r-- | src/server/database/Database/MySQLPreparedStatement.h | 2 | ||||
-rw-r--r-- | src/server/database/Database/PreparedStatement.cpp | 64 | ||||
-rw-r--r-- | src/server/database/Database/PreparedStatement.h | 10 |
6 files changed, 79 insertions, 87 deletions
diff --git a/src/server/database/Database/MySQLConnection.cpp b/src/server/database/Database/MySQLConnection.cpp index b72b4a15453..6e42fe3a76c 100644 --- a/src/server/database/Database/MySQLConnection.cpp +++ b/src/server/database/Database/MySQLConnection.cpp @@ -198,13 +198,12 @@ bool MySQLConnection::Execute(PreparedStatementBase* stmt) if (!m_Mysql) return false; - uint32 index = stmt->m_index; + uint32 index = stmt->GetIndex(); MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index); ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query - m_mStmt->m_stmt = stmt; // Cross reference them for debug output - stmt->BindParameters(m_mStmt); + m_mStmt->BindParameters(stmt); MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT(); MYSQL_BIND* msql_BIND = m_mStmt->GetBind(); @@ -241,18 +240,18 @@ bool MySQLConnection::Execute(PreparedStatementBase* stmt) return true; } -bool MySQLConnection::_Query(PreparedStatementBase* stmt, MySQLResult** pResult, uint64* pRowCount, uint32* pFieldCount) +bool MySQLConnection::_Query(PreparedStatementBase* stmt, MySQLPreparedStatement** mysqlStmt, MySQLResult** pResult, uint64* pRowCount, uint32* pFieldCount) { if (!m_Mysql) return false; - uint32 index = stmt->m_index; + uint32 index = stmt->GetIndex(); MySQLPreparedStatement* m_mStmt = GetPreparedStatement(index); ASSERT(m_mStmt); // Can only be null if preparation failed, server side error or bad query - m_mStmt->m_stmt = stmt; // Cross reference them for debug output - stmt->BindParameters(m_mStmt); + m_mStmt->BindParameters(stmt); + *mysqlStmt = m_mStmt; MYSQL_STMT* msql_STMT = m_mStmt->GetSTMT(); MYSQL_BIND* msql_BIND = m_mStmt->GetBind(); @@ -265,7 +264,7 @@ bool MySQLConnection::_Query(PreparedStatementBase* stmt, MySQLResult** pResult, TC_LOG_ERROR("sql.sql", "SQL(p): %s\n [ERROR]: [%u] %s", m_mStmt->getQueryString().c_str(), lErrno, mysql_stmt_error(msql_STMT)); if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return _Query(stmt, pResult, pRowCount, pFieldCount); // Try again + return _Query(stmt, mysqlStmt, pResult, pRowCount, pFieldCount); // Try again m_mStmt->ClearParameters(); return false; @@ -278,7 +277,7 @@ bool MySQLConnection::_Query(PreparedStatementBase* stmt, MySQLResult** pResult, m_mStmt->getQueryString().c_str(), lErrno, mysql_stmt_error(msql_STMT)); if (_HandleMySQLErrno(lErrno)) // If it returns true, an error was handled successfully (i.e. reconnection) - return _Query(stmt, pResult, pRowCount, pFieldCount); // Try again + return _Query(stmt, mysqlStmt, pResult, pRowCount, pFieldCount); // Try again m_mStmt->ClearParameters(); return false; @@ -494,18 +493,19 @@ void MySQLConnection::PrepareStatement(uint32 index, std::string const& sql, Con PreparedResultSet* MySQLConnection::Query(PreparedStatementBase* stmt) { + MySQLPreparedStatement* mysqlStmt = nullptr; MySQLResult* result = nullptr; uint64 rowCount = 0; uint32 fieldCount = 0; - if (!_Query(stmt, &result, &rowCount, &fieldCount)) + if (!_Query(stmt, &mysqlStmt, &result, &rowCount, &fieldCount)) return nullptr; if (mysql_more_results(m_Mysql)) { mysql_next_result(m_Mysql); } - return new PreparedResultSet(stmt->m_stmt->GetSTMT(), result, rowCount, fieldCount); + return new PreparedResultSet(mysqlStmt->GetSTMT(), result, rowCount, fieldCount); } bool MySQLConnection::_HandleMySQLErrno(uint32 errNo, uint8 attempts /*= 5*/) diff --git a/src/server/database/Database/MySQLConnection.h b/src/server/database/Database/MySQLConnection.h index f1ae98279cd..e4368db44ba 100644 --- a/src/server/database/Database/MySQLConnection.h +++ b/src/server/database/Database/MySQLConnection.h @@ -71,7 +71,7 @@ class TC_DATABASE_API MySQLConnection ResultSet* Query(char const* sql); PreparedResultSet* Query(PreparedStatementBase* stmt); bool _Query(char const* sql, MySQLResult** pResult, MySQLField** pFields, uint64* pRowCount, uint32* pFieldCount); - bool _Query(PreparedStatementBase* stmt, MySQLResult** pResult, uint64* pRowCount, uint32* pFieldCount); + bool _Query(PreparedStatementBase* stmt, MySQLPreparedStatement** mysqlStmt, MySQLResult** pResult, uint64* pRowCount, uint32* pFieldCount); void BeginTransaction(); void RollbackTransaction(); diff --git a/src/server/database/Database/MySQLPreparedStatement.cpp b/src/server/database/Database/MySQLPreparedStatement.cpp index 5fe2ab25658..f7d72dfad98 100644 --- a/src/server/database/Database/MySQLPreparedStatement.cpp +++ b/src/server/database/Database/MySQLPreparedStatement.cpp @@ -48,6 +48,66 @@ MySQLPreparedStatement::~MySQLPreparedStatement() delete[] m_bind; } +void MySQLPreparedStatement::BindParameters(PreparedStatementBase* stmt) +{ + m_stmt = stmt; // Cross reference them for debug output + + uint8 pos = 0; + for (PreparedStatementData const& data : stmt->GetParameters()) + { + switch (data.type) + { + case TYPE_BOOL: + setBool(pos, std::get<bool>(data.data)); + break; + case TYPE_UI8: + setUInt8(pos, std::get<uint8>(data.data)); + break; + case TYPE_UI16: + setUInt16(pos, std::get<uint16>(data.data)); + break; + case TYPE_UI32: + setUInt32(pos, std::get<uint32>(data.data)); + break; + case TYPE_I8: + setInt8(pos, std::get<int8>(data.data)); + break; + case TYPE_I16: + setInt16(pos, std::get<int16>(data.data)); + break; + case TYPE_I32: + setInt32(pos, std::get<int32>(data.data)); + break; + case TYPE_UI64: + setUInt64(pos, std::get<uint64>(data.data)); + break; + case TYPE_I64: + setInt64(pos, std::get<int64>(data.data)); + break; + case TYPE_FLOAT: + setFloat(pos, std::get<float>(data.data)); + break; + case TYPE_DOUBLE: + setDouble(pos, std::get<double>(data.data)); + break; + case TYPE_STRING: + setString(pos, std::get<std::string>(data.data)); + break; + case TYPE_BINARY: + setBinary(pos, std::get<std::vector<uint8>>(data.data)); + break; + case TYPE_NULL: + setNull(pos); + break; + } + ++pos; + } +#ifdef _DEBUG + if (pos < m_paramCount) + TC_LOG_WARN("sql.sql", "[WARNING]: BindParameters() for statement %u did not bind all allocated parameters", stmt->GetIndex()); +#endif +} + void MySQLPreparedStatement::ClearParameters() { for (uint32 i=0; i < m_paramCount; ++i) @@ -82,10 +142,10 @@ static void SetParameterValue(MYSQL_BIND* param, enum_field_types type, const vo //- Bind on mysql level void MySQLPreparedStatement::AssertValidIndex(uint8 index) { - ASSERT(index < m_paramCount || ParamenterIndexAssertFail(m_stmt->m_index, index, m_paramCount)); + ASSERT(index < m_paramCount || ParamenterIndexAssertFail(m_stmt->GetIndex(), index, m_paramCount)); if (m_paramsSet[index]) - TC_LOG_ERROR("sql.sql", "[ERROR] Prepared Statement (id: %u) trying to bind value on already bound index (%u).", m_stmt->m_index, index); + TC_LOG_ERROR("sql.sql", "[ERROR] Prepared Statement (id: %u) trying to bind value on already bound index (%u).", m_stmt->GetIndex(), index); } void MySQLPreparedStatement::setNull(const uint8 index) @@ -226,7 +286,7 @@ std::string MySQLPreparedStatement::getQueryString() const std::string queryString(m_queryString); size_t pos = 0; - for (PreparedStatementData& data : m_stmt->statement_data) + for (PreparedStatementData const& data : m_stmt->GetParameters()) { pos = queryString.find('?', pos); std::stringstream ss; diff --git a/src/server/database/Database/MySQLPreparedStatement.h b/src/server/database/Database/MySQLPreparedStatement.h index 65ecbdcd5df..9a06e7ef92e 100644 --- a/src/server/database/Database/MySQLPreparedStatement.h +++ b/src/server/database/Database/MySQLPreparedStatement.h @@ -39,6 +39,8 @@ class TC_DATABASE_API MySQLPreparedStatement MySQLPreparedStatement(MySQLStmt* stmt, std::string queryString); ~MySQLPreparedStatement(); + void BindParameters(PreparedStatementBase* stmt); + void setNull(const uint8 index); void setBool(const uint8 index, const bool value); void setUInt8(const uint8 index, const uint8 value); diff --git a/src/server/database/Database/PreparedStatement.cpp b/src/server/database/Database/PreparedStatement.cpp index 4b536307973..6cefaf14119 100644 --- a/src/server/database/Database/PreparedStatement.cpp +++ b/src/server/database/Database/PreparedStatement.cpp @@ -24,71 +24,10 @@ #include "MySQLWorkaround.h" PreparedStatementBase::PreparedStatementBase(uint32 index, uint8 capacity) : - m_stmt(nullptr), m_index(index), statement_data(capacity) { } + m_index(index), statement_data(capacity) { } PreparedStatementBase::~PreparedStatementBase() { } -void PreparedStatementBase::BindParameters(MySQLPreparedStatement* stmt) -{ - ASSERT(stmt); - m_stmt = stmt; - - uint8 pos = 0; - for (PreparedStatementData const& data : statement_data) - { - switch (data.type) - { - case TYPE_BOOL: - stmt->setBool(pos, std::get<bool>(data.data)); - break; - case TYPE_UI8: - stmt->setUInt8(pos, std::get<uint8>(data.data)); - break; - case TYPE_UI16: - stmt->setUInt16(pos, std::get<uint16>(data.data)); - break; - case TYPE_UI32: - stmt->setUInt32(pos, std::get<uint32>(data.data)); - break; - case TYPE_I8: - stmt->setInt8(pos, std::get<int8>(data.data)); - break; - case TYPE_I16: - stmt->setInt16(pos, std::get<int16>(data.data)); - break; - case TYPE_I32: - stmt->setInt32(pos, std::get<int32>(data.data)); - break; - case TYPE_UI64: - stmt->setUInt64(pos, std::get<uint64>(data.data)); - break; - case TYPE_I64: - stmt->setInt64(pos, std::get<int64>(data.data)); - break; - case TYPE_FLOAT: - stmt->setFloat(pos, std::get<float>(data.data)); - break; - case TYPE_DOUBLE: - stmt->setDouble(pos, std::get<double>(data.data)); - break; - case TYPE_STRING: - stmt->setString(pos, std::get<std::string>(data.data)); - break; - case TYPE_BINARY: - stmt->setBinary(pos, std::get<std::vector<uint8>>(data.data)); - break; - case TYPE_NULL: - stmt->setNull(pos); - break; - } - ++pos; - } - #ifdef _DEBUG - if (pos < stmt->m_paramCount) - TC_LOG_WARN("sql.sql", "[WARNING]: BindParameters() for statement %u did not bind all allocated parameters", m_index); - #endif -} - //- Bind to buffer void PreparedStatementBase::setBool(const uint8 index, const bool value) { @@ -184,7 +123,6 @@ void PreparedStatementBase::setBinary(const uint8 index, const std::vector<uint8 void PreparedStatementBase::setNull(const uint8 index) { ASSERT(index < statement_data.size()); - statement_data[index].type = TYPE_NULL; } diff --git a/src/server/database/Database/PreparedStatement.h b/src/server/database/Database/PreparedStatement.h index e11fcee5f85..e4bd08753f5 100644 --- a/src/server/database/Database/PreparedStatement.h +++ b/src/server/database/Database/PreparedStatement.h @@ -67,15 +67,10 @@ struct PreparedStatementData PreparedStatementValueType type; }; -//- Forward declare -class MySQLPreparedStatement; - //- Upper-level class that is used in code class TC_DATABASE_API PreparedStatementBase { friend class PreparedStatementTask; - friend class MySQLPreparedStatement; - friend class MySQLConnection; public: explicit PreparedStatementBase(uint32 index, uint8 capacity); @@ -103,12 +98,9 @@ class TC_DATABASE_API PreparedStatementBase } uint32 GetIndex() const { return m_index; } + std::vector<PreparedStatementData> const& GetParameters() const { return statement_data; } protected: - void BindParameters(MySQLPreparedStatement* stmt); - - protected: - MySQLPreparedStatement* m_stmt; uint32 m_index; //- Buffer of parameters, not tied to MySQL in any way yet |