mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-18 00:18:43 +01:00
Core/DBLayer:
- Allow transactions to contain both raw ad-hoc queries and prepared statement elements * When coding on high level code, just make sure you use the right argument type for Transaction::Append and the proper execution will be done automagically --HG-- branch : trunk
This commit is contained in:
@@ -19,9 +19,13 @@
|
||||
#include "DatabaseEnv.h"
|
||||
#include "Transaction.h"
|
||||
|
||||
//- Append a raw ad-hoc query to the transaction
|
||||
void Transaction::Append(const char* sql)
|
||||
{
|
||||
m_queries.push(strdup(sql));
|
||||
TransactionElementData data;
|
||||
data.type = TRANSACTION_ELEMENT_RAW;
|
||||
data.element.query = strdup(sql);
|
||||
m_queries.push(data);
|
||||
}
|
||||
|
||||
void Transaction::PAppend(const char* sql, ...)
|
||||
@@ -35,41 +39,74 @@ void Transaction::PAppend(const char* sql, ...)
|
||||
Append(szQuery);
|
||||
}
|
||||
|
||||
//- Append a prepared statement to the transaction
|
||||
void Transaction::Append(PreparedStatement* stmt)
|
||||
{
|
||||
TransactionElementData data;
|
||||
data.type = TRANSACTION_ELEMENT_PREPARED;
|
||||
data.element.stmt = stmt;
|
||||
m_queries.push(data);
|
||||
}
|
||||
|
||||
void Transaction::Cleanup()
|
||||
{
|
||||
while (!m_queries.empty())
|
||||
{
|
||||
free((void*)const_cast<char*>(m_queries.front()));
|
||||
TransactionElementData data = m_queries.front();
|
||||
switch (data.type)
|
||||
{
|
||||
case TRANSACTION_ELEMENT_PREPARED:
|
||||
delete data.element.stmt;
|
||||
break;
|
||||
case TRANSACTION_ELEMENT_RAW:
|
||||
free((void*)(data.element.query));
|
||||
break;
|
||||
}
|
||||
m_queries.pop();
|
||||
}
|
||||
}
|
||||
|
||||
bool TransactionTask::Execute()
|
||||
{
|
||||
std::queue<char*>& queries = m_trans->m_queries;
|
||||
std::queue<TransactionElementData> &queries = m_trans->m_queries;
|
||||
if (queries.empty())
|
||||
return false;
|
||||
|
||||
const char* sql;
|
||||
|
||||
m_conn->BeginTransaction();
|
||||
while (!queries.empty())
|
||||
{
|
||||
sql = queries.front();
|
||||
ASSERT(sql);
|
||||
if (!m_conn->Execute(sql))
|
||||
TransactionElementData data = queries.front();
|
||||
switch (data.type)
|
||||
{
|
||||
sLog.outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
||||
free((void*)const_cast<char*>(sql));
|
||||
queries.pop();
|
||||
m_conn->RollbackTransaction();
|
||||
return false;
|
||||
case TRANSACTION_ELEMENT_PREPARED:
|
||||
{
|
||||
PreparedStatement* stmt = data.element.stmt;
|
||||
ASSERT(stmt);
|
||||
if (!m_conn->Execute(stmt))
|
||||
{
|
||||
sLog.outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
||||
m_conn->RollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
delete data.element.stmt;
|
||||
}
|
||||
break;
|
||||
case TRANSACTION_ELEMENT_RAW:
|
||||
{
|
||||
const char* sql = data.element.query;
|
||||
ASSERT(sql)
|
||||
if (!m_conn->Execute(sql))
|
||||
{
|
||||
sLog.outSQLDriver("[Warning] Transaction aborted. %u queries not executed.", (uint32)queries.size());
|
||||
m_conn->RollbackTransaction();
|
||||
return false;
|
||||
}
|
||||
free((void*)const_cast<char*>(sql));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
free((void*)const_cast<char*>(sql));
|
||||
queries.pop();
|
||||
}
|
||||
|
||||
m_conn->CommitTransaction();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -21,6 +21,30 @@
|
||||
|
||||
#include "SQLOperation.h"
|
||||
|
||||
//- Forward declare (don't include header to prevent circular includes)
|
||||
class PreparedStatement;
|
||||
|
||||
//- Union that holds element data
|
||||
union TransactionElementUnion
|
||||
{
|
||||
PreparedStatement* stmt;
|
||||
const char* query;
|
||||
};
|
||||
|
||||
//- Type specifier of our element data
|
||||
enum TransactionElementDataType
|
||||
{
|
||||
TRANSACTION_ELEMENT_RAW,
|
||||
TRANSACTION_ELEMENT_PREPARED,
|
||||
};
|
||||
|
||||
//- The transaction element
|
||||
struct TransactionElementData
|
||||
{
|
||||
TransactionElementUnion element;
|
||||
TransactionElementDataType type;
|
||||
};
|
||||
|
||||
/*! Transactions, high level class. */
|
||||
class Transaction
|
||||
{
|
||||
@@ -28,6 +52,7 @@ class Transaction
|
||||
public:
|
||||
~Transaction() { Cleanup(); }
|
||||
|
||||
void Append(PreparedStatement* statement);
|
||||
void Append(const char* sql);
|
||||
void PAppend(const char* sql, ...);
|
||||
|
||||
@@ -35,7 +60,7 @@ class Transaction
|
||||
|
||||
protected:
|
||||
void Cleanup();
|
||||
std::queue<char*> m_queries;
|
||||
std::queue<TransactionElementData> m_queries;
|
||||
|
||||
private:
|
||||
bool m_actioned;
|
||||
|
||||
Reference in New Issue
Block a user