From 247576e101f02eec4d6194627c71ed37cfdb0ac9 Mon Sep 17 00:00:00 2001 From: David Markowitz <39972741+EmosewaMC@users.noreply.github.com> Date: Tue, 31 Mar 2026 15:35:28 -0700 Subject: [PATCH] fix: use copy ellision (#1963) * use copy ellision tested that the server still starts * Update dDatabase/GameDatabase/MySQL/MySQLDatabase.h Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- dDatabase/GameDatabase/MySQL/MySQLDatabase.h | 24 +++++++------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/dDatabase/GameDatabase/MySQL/MySQLDatabase.h b/dDatabase/GameDatabase/MySQL/MySQLDatabase.h index 5b26a075..b481877c 100644 --- a/dDatabase/GameDatabase/MySQL/MySQLDatabase.h +++ b/dDatabase/GameDatabase/MySQL/MySQLDatabase.h @@ -9,8 +9,8 @@ typedef std::unique_ptr& UniquePreppedStmtRef; typedef std::unique_ptr UniqueResultSet; -// Holds a PreparedStatement and its ResultSet together to ensure the statement -// outlives the result. +// This struct is used to keep the PreparedStatement alive alongside the ResultSet, since the ResultSet will be invalidated if the PreparedStatement is destroyed. +// Declaring the members in reverse order of usage to ensure the PreparedStatement is destroyed after the ResultSet. This is guaranteed by the C++ standard. struct PreparedStmtResultSet { std::unique_ptr m_stmt; std::unique_ptr m_resultSet; @@ -18,14 +18,6 @@ struct PreparedStmtResultSet { PreparedStmtResultSet(sql::PreparedStatement* stmt = nullptr, sql::ResultSet* resultSet = nullptr) : m_stmt(stmt), m_resultSet(resultSet) {} - PreparedStmtResultSet(PreparedStmtResultSet&&) = default; - PreparedStmtResultSet& operator=(PreparedStmtResultSet&&) = default; - - ~PreparedStmtResultSet() { - m_resultSet.reset(); - m_stmt.reset(); - } - sql::ResultSet* operator->() const { return m_resultSet.get(); } @@ -161,12 +153,12 @@ private: // The return type is a PreparedStmtResultSet which keeps the PreparedStatement alive alongside the ResultSet. template inline PreparedStmtResultSet ExecuteSelect(const std::string& query, Args&&... args) { - std::unique_ptr preppedStmt(CreatePreppedStmt(query)); - SetParams(preppedStmt, std::forward(args)...); - std::unique_ptr resultSet; - DLU_SQL_TRY_CATCH_RETHROW(resultSet.reset(preppedStmt->executeQuery())); - // Release ownership of the pointers to the PreparedStatement and ResultSet to the PreparedStmtResultSet struct, which will ensure they are properly cleaned up. - return PreparedStmtResultSet(preppedStmt.release(), resultSet.release()); + PreparedStmtResultSet toReturn; + toReturn.m_stmt.reset(CreatePreppedStmt(query)); + SetParams(toReturn.m_stmt, std::forward(args)...); + DLU_SQL_TRY_CATCH_RETHROW(toReturn.m_resultSet.reset(toReturn.m_stmt->executeQuery())); + // Return the PreparedStmtResultSet, which now owns both the PreparedStatement and ResultSet via unique_ptr and will ensure they are properly cleaned up. + return toReturn; } template