aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared/Database
diff options
context:
space:
mode:
authorMachiavelli <none@none>2010-09-04 16:49:23 +0200
committerMachiavelli <none@none>2010-09-04 16:49:23 +0200
commit27c00a8cbbfb684630a8977ccd1b007d9e69d441 (patch)
tree9aa9200a0f8acce9707d9b3dfdfc011aefa5d3bc /src/server/shared/Database
parentfd1c6c54400bbfd117e689d5f9b6b0775b1a4272 (diff)
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
Diffstat (limited to 'src/server/shared/Database')
-rw-r--r--src/server/shared/Database/Transaction.cpp69
-rw-r--r--src/server/shared/Database/Transaction.h27
2 files changed, 79 insertions, 17 deletions
diff --git a/src/server/shared/Database/Transaction.cpp b/src/server/shared/Database/Transaction.cpp
index 93dc8fdc195..e45717864cf 100644
--- a/src/server/shared/Database/Transaction.cpp
+++ b/src/server/shared/Database/Transaction.cpp
@@ -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;
}
diff --git a/src/server/shared/Database/Transaction.h b/src/server/shared/Database/Transaction.h
index 58c87b61270..cd749b0c2d7 100644
--- a/src/server/shared/Database/Transaction.h
+++ b/src/server/shared/Database/Transaction.h
@@ -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;