From 1f66d719f2cbbcb144b5080c89dd73fcae261798 Mon Sep 17 00:00:00 2001 From: StormBytePP Date: Sat, 15 Aug 2015 02:19:10 +0200 Subject: Core/BuildSystem: Merge collision, debugging, threading, utilities and configuration into "common" which does not depend on shared anymore and moved database out of shared library These changes enables to build tools only without even having MySQL installed --- src/server/database/Database/QueryHolder.cpp | 189 +++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100644 src/server/database/Database/QueryHolder.cpp (limited to 'src/server/database/Database/QueryHolder.cpp') diff --git a/src/server/database/Database/QueryHolder.cpp b/src/server/database/Database/QueryHolder.cpp new file mode 100644 index 00000000000..2fdb3825526 --- /dev/null +++ b/src/server/database/Database/QueryHolder.cpp @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2008-2015 TrinityCore + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "MySQLConnection.h" +#include "QueryHolder.h" +#include "PreparedStatement.h" +#include "Log.h" + +bool SQLQueryHolder::SetQuery(size_t index, const char *sql) +{ + if (m_queries.size() <= index) + { + TC_LOG_ERROR("sql.sql", "Query index (%u) out of range (size: %u) for query: %s", uint32(index), (uint32)m_queries.size(), sql); + return false; + } + + /// not executed yet, just stored (it's not called a holder for nothing) + SQLElementData element; + element.type = SQL_ELEMENT_RAW; + element.element.query = strdup(sql); + + SQLResultSetUnion result; + result.qresult = NULL; + + m_queries[index] = SQLResultPair(element, result); + return true; +} + +bool SQLQueryHolder::SetPreparedQuery(size_t index, PreparedStatement* stmt) +{ + if (m_queries.size() <= index) + { + TC_LOG_ERROR("sql.sql", "Query index (%u) out of range (size: %u) for prepared statement", uint32(index), (uint32)m_queries.size()); + return false; + } + + /// not executed yet, just stored (it's not called a holder for nothing) + SQLElementData element; + element.type = SQL_ELEMENT_PREPARED; + element.element.stmt = stmt; + + SQLResultSetUnion result; + result.presult = NULL; + + m_queries[index] = SQLResultPair(element, result); + return true; +} + +QueryResult SQLQueryHolder::GetResult(size_t index) +{ + // Don't call to this function if the index is of an ad-hoc statement + if (index < m_queries.size()) + { + ResultSet* result = m_queries[index].second.qresult; + if (!result || !result->GetRowCount() || !result->NextRow()) + return QueryResult(NULL); + + return QueryResult(result); + } + else + return QueryResult(NULL); +} + +PreparedQueryResult SQLQueryHolder::GetPreparedResult(size_t index) +{ + // Don't call to this function if the index is of a prepared statement + if (index < m_queries.size()) + { + PreparedResultSet* result = m_queries[index].second.presult; + if (!result || !result->GetRowCount()) + return PreparedQueryResult(NULL); + + return PreparedQueryResult(result); + } + else + return PreparedQueryResult(NULL); +} + +void SQLQueryHolder::SetResult(size_t index, ResultSet* result) +{ + if (result && !result->GetRowCount()) + { + delete result; + result = NULL; + } + + /// store the result in the holder + if (index < m_queries.size()) + m_queries[index].second.qresult = result; +} + +void SQLQueryHolder::SetPreparedResult(size_t index, PreparedResultSet* result) +{ + if (result && !result->GetRowCount()) + { + delete result; + result = NULL; + } + + /// store the result in the holder + if (index < m_queries.size()) + m_queries[index].second.presult = result; +} + +SQLQueryHolder::~SQLQueryHolder() +{ + for (size_t i = 0; i < m_queries.size(); i++) + { + /// if the result was never used, free the resources + /// results used already (getresult called) are expected to be deleted + if (SQLElementData* data = &m_queries[i].first) + { + switch (data->type) + { + case SQL_ELEMENT_RAW: + free((void*)(const_cast(data->element.query))); + break; + case SQL_ELEMENT_PREPARED: + delete data->element.stmt; + break; + } + } + } +} + +void SQLQueryHolder::SetSize(size_t size) +{ + /// to optimize push_back, reserve the number of queries about to be executed + m_queries.resize(size); +} + +SQLQueryHolderTask::~SQLQueryHolderTask() +{ + if (!m_executed) + delete m_holder; +} + +bool SQLQueryHolderTask::Execute() +{ + m_executed = true; + + if (!m_holder) + return false; + + /// we can do this, we are friends + std::vector &queries = m_holder->m_queries; + + for (size_t i = 0; i < queries.size(); i++) + { + /// execute all queries in the holder and pass the results + if (SQLElementData* data = &queries[i].first) + { + switch (data->type) + { + case SQL_ELEMENT_RAW: + { + char const* sql = data->element.query; + if (sql) + m_holder->SetResult(i, m_conn->Query(sql)); + break; + } + case SQL_ELEMENT_PREPARED: + { + PreparedStatement* stmt = data->element.stmt; + if (stmt) + m_holder->SetPreparedResult(i, m_conn->Query(stmt)); + break; + } + } + } + } + + m_result.set_value(m_holder); + return true; +} -- cgit v1.2.3