aboutsummaryrefslogtreecommitdiff
path: root/src/server/shared/Database
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/shared/Database')
-rw-r--r--src/server/shared/Database/AsyncDatabaseImpl.h250
-rw-r--r--src/server/shared/Database/DatabaseEnv.h8
-rw-r--r--src/server/shared/Database/DatabaseImpl.h234
-rw-r--r--src/server/shared/Database/DatabaseWorker.cpp67
-rw-r--r--src/server/shared/Database/DatabaseWorker.h42
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.cpp216
-rw-r--r--src/server/shared/Database/DatabaseWorkerPool.h157
-rw-r--r--src/server/shared/Database/MySQLConnection.cpp244
-rw-r--r--src/server/shared/Database/MySQLConnection.h56
-rw-r--r--src/server/shared/Database/MySQLThreading.h53
-rw-r--r--src/server/shared/Database/PreparedStatements.cpp93
-rw-r--r--src/server/shared/Database/PreparedStatements.h30
-rw-r--r--src/server/shared/Database/SQLOperation.cpp (renamed from src/server/shared/Database/SqlOperations.cpp)149
-rw-r--r--src/server/shared/Database/SQLOperation.h122
-rw-r--r--src/server/shared/Database/SQLStorage.cpp2
-rw-r--r--src/server/shared/Database/SqlOperations.h168
16 files changed, 1290 insertions, 601 deletions
diff --git a/src/server/shared/Database/AsyncDatabaseImpl.h b/src/server/shared/Database/AsyncDatabaseImpl.h
new file mode 100644
index 00000000000..f85540a8016
--- /dev/null
+++ b/src/server/shared/Database/AsyncDatabaseImpl.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
+ *
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+
+#include "Database/DatabaseWorkerPool.h"
+#include "Database/SQLOperation.h"
+
+
+/// Function body definitions for the template function members of the Database class
+
+#define ASYNC_QUERY_BODY(sql, queue_itr) \
+ if (!sql) return false; \
+ \
+ QueryQueues::iterator queue_itr; \
+ \
+ { \
+ ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
+ queue_itr = m_queryQueues.find(queryThread); \
+ if (queue_itr == m_queryQueues.end()) return false; \
+ }
+
+#define ASYNC_PQUERY_BODY(format, szQuery) \
+ if(!format) return false; \
+ \
+ char szQuery [MAX_QUERY_LEN]; \
+ \
+ { \
+ va_list ap; \
+ \
+ va_start(ap, format); \
+ int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); \
+ va_end(ap); \
+ \
+ if(res==-1) \
+ { \
+ sLog.outError("SQL Query truncated (and not execute) for format: %s",format); \
+ return false; \
+ } \
+ }
+
+
+#define ASYNC_DELAYHOLDER_BODY(holder, queue_itr) \
+ if (!holder) return false; \
+ \
+ QueryQueues::iterator queue_itr; \
+ \
+ { \
+ ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
+ queue_itr = m_queryQueues.find(queryThread); \
+ if (queue_itr == m_queryQueues.end()) return false; \
+ }
+
+
+// -- Query / member --
+
+
+template<class Class>
+bool
+DatabaseWorkerPool::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *sql)
+{
+ ASYNC_QUERY_BODY(sql, itr)
+ SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::QueryCallback<Class>(object, method), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+template<class Class, typename ParamType1>
+bool
+DatabaseWorkerPool::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql)
+{
+ ASYNC_QUERY_BODY(sql, itr)
+ SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::QueryCallback<Class, ParamType1>(object, method, (QueryResult_AutoPtr)NULL, param1), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+template<class Class, typename ParamType1, typename ParamType2>
+bool
+DatabaseWorkerPool::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
+{
+ ASYNC_QUERY_BODY(sql, itr)
+ SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult_AutoPtr)NULL, param1, param2), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+DatabaseWorkerPool::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
+{
+ ASYNC_QUERY_BODY(sql, itr)
+ SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult_AutoPtr)NULL, param1, param2, param3), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+// -- Query / static --
+
+
+template<typename ParamType1>
+bool
+DatabaseWorkerPool::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql)
+{
+ ASYNC_QUERY_BODY(sql, itr)
+ SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::SQueryCallback<ParamType1>(method, (QueryResult_AutoPtr)NULL, param1), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+template<typename ParamType1, typename ParamType2>
+bool
+DatabaseWorkerPool::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
+{
+ ASYNC_QUERY_BODY(sql, itr)
+ SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult_AutoPtr)NULL, param1, param2), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+template<typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+DatabaseWorkerPool::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
+{
+ ASYNC_QUERY_BODY(sql, itr)
+ SQLQueryTask* task = new SQLQueryTask(sql, new Trinity::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult_AutoPtr)NULL, param1, param2, param3), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+// -- PQuery / member --
+
+
+template<class Class>
+bool
+DatabaseWorkerPool::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *format,...)
+{
+ ASYNC_PQUERY_BODY(format, szQuery)
+ return AsyncQuery(object, method, szQuery);
+}
+
+
+template<class Class, typename ParamType1>
+bool
+DatabaseWorkerPool::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...)
+{
+ ASYNC_PQUERY_BODY(format, szQuery)
+ return AsyncQuery(object, method, param1, szQuery);
+}
+
+
+template<class Class, typename ParamType1, typename ParamType2>
+bool
+DatabaseWorkerPool::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
+{
+ ASYNC_PQUERY_BODY(format, szQuery)
+ return AsyncQuery(object, method, param1, param2, szQuery);
+}
+
+
+template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+DatabaseWorkerPool::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
+{
+ ASYNC_PQUERY_BODY(format, szQuery)
+ return AsyncQuery(object, method, param1, param2, param3, szQuery);
+}
+
+
+// -- PQuery / static --
+
+
+template<typename ParamType1>
+bool
+DatabaseWorkerPool::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...)
+{
+ ASYNC_PQUERY_BODY(format, szQuery)
+ return AsyncQuery(method, param1, szQuery);
+}
+
+
+template<typename ParamType1, typename ParamType2>
+bool
+DatabaseWorkerPool::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
+{
+ ASYNC_PQUERY_BODY(format, szQuery)
+ return AsyncQuery(method, param1, param2, szQuery);
+}
+
+
+template<typename ParamType1, typename ParamType2, typename ParamType3>
+bool
+DatabaseWorkerPool::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
+{
+ ASYNC_PQUERY_BODY(format, szQuery)
+ return AsyncQuery(method, param1, param2, param3, szQuery);
+}
+
+
+// -- QueryHolder --
+
+
+template<class Class>
+bool
+DatabaseWorkerPool::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SQLQueryHolder*), SQLQueryHolder *holder)
+{
+ ASYNC_DELAYHOLDER_BODY(holder, itr)
+ SQLQueryHolderTask *task = new SQLQueryHolderTask(holder, new Trinity::QueryCallback<Class, SQLQueryHolder*>(object, method, (QueryResult_AutoPtr)NULL, holder), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+template<class Class, typename ParamType1>
+bool
+DatabaseWorkerPool::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SQLQueryHolder*, ParamType1), SQLQueryHolder *holder, ParamType1 param1)
+{
+ ASYNC_DELAYHOLDER_BODY(holder, itr)
+ SQLQueryHolderTask *task = new SQLQueryHolderTask(holder, new Trinity::QueryCallback<Class, SQLQueryHolder*, ParamType1>(object, method, (QueryResult_AutoPtr)NULL, holder, param1), itr->second);
+ Enqueue(task);
+ return true;
+}
+
+
+#undef ASYNC_QUERY_BODY
+#undef ASYNC_PQUERY_BODY
+#undef ASYNC_DELAYHOLDER_BODY
diff --git a/src/server/shared/Database/DatabaseEnv.h b/src/server/shared/Database/DatabaseEnv.h
index 15c1b1c599e..398ae66f235 100644
--- a/src/server/shared/Database/DatabaseEnv.h
+++ b/src/server/shared/Database/DatabaseEnv.h
@@ -28,8 +28,10 @@
#include "Database/Field.h"
#include "Database/QueryResult.h"
-#include "Database/Database.h"
-typedef Database DatabaseType;
+#include "Database/DatabaseWorkerPool.h"
+#include "Database/MySQLThreading.h"
+
+typedef DatabaseWorkerPool DatabaseType;
#define _LIKE_ "LIKE"
#define _TABLE_SIM_ "`"
#define _CONCAT3_(A,B,C) "CONCAT( " A " , " B " , " C " )"
@@ -39,5 +41,7 @@ extern DatabaseType WorldDatabase;
extern DatabaseType CharacterDatabase;
extern DatabaseType LoginDatabase;
+#define MAX_QUERY_LEN 32*1024
+
#endif
diff --git a/src/server/shared/Database/DatabaseImpl.h b/src/server/shared/Database/DatabaseImpl.h
deleted file mode 100644
index f0ba9c84a30..00000000000
--- a/src/server/shared/Database/DatabaseImpl.h
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-
-#include "Database/Database.h"
-#include "Database/SqlOperations.h"
-
-
-/// Function body definitions for the template function members of the Database class
-
-
-#define ASYNC_QUERY_BODY(sql, queue_itr) \
- if (!sql) return false; \
- \
- QueryQueues::iterator queue_itr; \
- \
- { \
- ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
- queue_itr = m_queryQueues.find(queryThread); \
- if (queue_itr == m_queryQueues.end()) return false; \
- }
-
-
-#define ASYNC_PQUERY_BODY(format, szQuery) \
- if(!format) return false; \
- \
- char szQuery [MAX_QUERY_LEN]; \
- \
- { \
- va_list ap; \
- \
- va_start(ap, format); \
- int res = vsnprintf( szQuery, MAX_QUERY_LEN, format, ap ); \
- va_end(ap); \
- \
- if(res==-1) \
- { \
- sLog.outError("SQL Query truncated (and not execute) for format: %s",format); \
- return false; \
- } \
- }
-
-
-#define ASYNC_DELAYHOLDER_BODY(holder, queue_itr) \
- if (!holder) return false; \
- \
- QueryQueues::iterator queue_itr; \
- \
- { \
- ACE_Based::Thread * queryThread = ACE_Based::Thread::current(); \
- queue_itr = m_queryQueues.find(queryThread); \
- if (queue_itr == m_queryQueues.end()) return false; \
- }
-
-
-// -- Query / member --
-
-
-template<class Class>
-bool
-Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class>(object, method), itr->second));
-}
-
-
-template<class Class, typename ParamType1>
-bool
-Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1>(object, method, (QueryResult_AutoPtr)NULL, param1), itr->second));
-}
-
-
-template<class Class, typename ParamType1, typename ParamType2>
-bool
-Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2>(object, method, (QueryResult_AutoPtr)NULL, param1, param2), itr->second));
-}
-
-
-template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
-bool
-Database::AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- return m_threadBody->Delay(new SqlQuery(sql, new Trinity::QueryCallback<Class, ParamType1, ParamType2, ParamType3>(object, method, (QueryResult_AutoPtr)NULL, param1, param2, param3), itr->second));
-}
-
-
-// -- Query / static --
-
-
-template<typename ParamType1>
-bool
-Database::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1>(method, (QueryResult_AutoPtr)NULL, param1), itr->second));
-}
-
-
-template<typename ParamType1, typename ParamType2>
-bool
-Database::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1, ParamType2>(method, (QueryResult_AutoPtr)NULL, param1, param2), itr->second));
-}
-
-
-template<typename ParamType1, typename ParamType2, typename ParamType3>
-bool
-Database::AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql)
-{
- ASYNC_QUERY_BODY(sql, itr)
- return m_threadBody->Delay(new SqlQuery(sql, new Trinity::SQueryCallback<ParamType1, ParamType2, ParamType3>(method, (QueryResult_AutoPtr)NULL, param1, param2, param3), itr->second));
-}
-
-
-// -- PQuery / member --
-
-
-template<class Class>
-bool
-Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(object, method, szQuery);
-}
-
-
-template<class Class, typename ParamType1>
-bool
-Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(object, method, param1, szQuery);
-}
-
-
-template<class Class, typename ParamType1, typename ParamType2>
-bool
-Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(object, method, param1, param2, szQuery);
-}
-
-
-template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
-bool
-Database::AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(object, method, param1, param2, param3, szQuery);
-}
-
-
-// -- PQuery / static --
-
-
-template<typename ParamType1>
-bool
-Database::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(method, param1, szQuery);
-}
-
-
-template<typename ParamType1, typename ParamType2>
-bool
-Database::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(method, param1, param2, szQuery);
-}
-
-
-template<typename ParamType1, typename ParamType2, typename ParamType3>
-bool
-Database::AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...)
-{
- ASYNC_PQUERY_BODY(format, szQuery)
- return AsyncQuery(method, param1, param2, param3, szQuery);
-}
-
-
-// -- QueryHolder --
-
-
-template<class Class>
-bool
-Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SqlQueryHolder*), SqlQueryHolder *holder)
-{
- ASYNC_DELAYHOLDER_BODY(holder, itr)
- return holder->Execute(new Trinity::QueryCallback<Class, SqlQueryHolder*>(object, method, (QueryResult_AutoPtr)NULL, holder), m_threadBody, itr->second);
-}
-
-
-template<class Class, typename ParamType1>
-bool
-Database::DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SqlQueryHolder*, ParamType1), SqlQueryHolder *holder, ParamType1 param1)
-{
- ASYNC_DELAYHOLDER_BODY(holder, itr)
- return holder->Execute(new Trinity::QueryCallback<Class, SqlQueryHolder*, ParamType1>(object, method, (QueryResult_AutoPtr)NULL, holder, param1), m_threadBody, itr->second);
-}
-
-
-#undef ASYNC_QUERY_BODY
-#undef ASYNC_PQUERY_BODY
-#undef ASYNC_DELAYHOLDER_BODY
diff --git a/src/server/shared/Database/DatabaseWorker.cpp b/src/server/shared/Database/DatabaseWorker.cpp
new file mode 100644
index 00000000000..17fc1d75a5d
--- /dev/null
+++ b/src/server/shared/Database/DatabaseWorker.cpp
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "DatabaseEnv.h"
+#include "DatabaseWorker.h"
+#include "SQLOperation.h"
+#include "MySQLConnection.h"
+
+DatabaseWorker::DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con) :
+m_queue(new_queue),
+m_conn(con)
+{
+ /// Assign thread to task
+ activate();
+}
+
+int DatabaseWorker::svc()
+{
+ if (!m_queue)
+ return -1;
+
+ SQLOperation *request = NULL;
+ while (1)
+ {
+ request = (SQLOperation*)(m_queue->dequeue());
+ if (!request)
+ break;
+
+ request->SetConnection(m_conn);
+ request->call();
+ delete request;
+ }
+
+ delete m_conn;
+ delete this;
+ return 0;
+}
+
+int DatabaseWorker::activate()
+{
+ /* THR_DETACHED:
+ Create an asynchronous thread. The exit status of the thread would not be available to any other threads.
+ The thread resources are reclaimed by the operating system whenever the thread is terminated. */
+
+ /* THR_NEW_LWP:
+ Create an explicit kernel-level thread (as opposed to a user-level thread). */
+
+ ACE_Task_Base::activate(THR_NEW_LWP | THR_DETACHED, 1);
+ return 0; //^ - Spawn one thread to handle this task.
+ // However more of these tasks may be activated
+ // See DatabaseWorkerPool ctor.
+} \ No newline at end of file
diff --git a/src/server/shared/Database/DatabaseWorker.h b/src/server/shared/Database/DatabaseWorker.h
new file mode 100644
index 00000000000..ad5102d28ca
--- /dev/null
+++ b/src/server/shared/Database/DatabaseWorker.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _WORKERTHREAD_H
+#define _WORKERTHREAD_H
+
+#include <ace/Task.h>
+#include <ace/Activation_Queue.h>
+
+class MySQLConnection;
+
+class DatabaseWorker : protected ACE_Task_Base
+{
+ public:
+ DatabaseWorker(ACE_Activation_Queue* new_queue, MySQLConnection* con);
+
+ ///- Inherited from ACE_Task_Base
+ int svc();
+ int activate();
+
+ private:
+ DatabaseWorker() : ACE_Task_Base() {}
+ ACE_Activation_Queue* m_queue;
+ MySQLConnection* m_conn;
+};
+
+#endif \ No newline at end of file
diff --git a/src/server/shared/Database/DatabaseWorkerPool.cpp b/src/server/shared/Database/DatabaseWorkerPool.cpp
new file mode 100644
index 00000000000..532d9cad7df
--- /dev/null
+++ b/src/server/shared/Database/DatabaseWorkerPool.cpp
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "DatabaseWorkerPool.h"
+#include "MySQLConnection.h"
+#include "DatabaseEnv.h"
+#include "SQLOperation.h"
+
+DatabaseWorkerPool::DatabaseWorkerPool() :
+m_queue(new ACE_Activation_Queue(new ACE_Message_Queue<ACE_MT_SYNCH>)),
+m_connections(0)
+{
+ m_infoString = "";
+
+ mysql_library_init(-1, NULL, NULL);
+ WPFatal (mysql_thread_safe(), "Used MySQL library isn't thread-safe.");
+}
+
+DatabaseWorkerPool::~DatabaseWorkerPool()
+{
+}
+
+bool DatabaseWorkerPool::Open(const std::string& infoString, uint8 num_threads)
+{
+ sLog.outDebug("Creating bundled/master MySQL connection.");
+ m_bundle_conn = new MySQLConnection();
+ m_bundle_conn->Open(infoString);
+ ++m_connections;
+
+ m_async_connections.resize(num_threads);
+
+ /// Open the Async pool
+ for (uint8 i = 0; i < num_threads; i++)
+ {
+ m_async_connections[i] = new MySQLConnection(m_queue);
+ m_async_connections[i]->Open(infoString);
+ ++m_connections;
+ sLog.outDebug("Async database thread pool opened. Worker thread count: %u", num_threads);
+ }
+
+ m_infoString = infoString;
+ return true;
+}
+
+void DatabaseWorkerPool::Close()
+{
+ /// Shuts down worker threads for this connection pool.
+ for (uint8 i = 0; i < m_async_connections.size(); i++)
+ Enqueue(NULL);
+
+ //- MySQL::Thread_End() should be called manually from the aborting calling threads
+
+ delete m_bundle_conn;
+ m_bundle_conn = NULL;
+}
+
+/*! This function creates a new MySQL connection for every MapUpdate thread
+ and every unbundled task.
+ */
+void DatabaseWorkerPool::Init_MySQL_Connection()
+{
+ MySQLConnection* conn = new MySQLConnection();
+ conn->Open(m_infoString);
+
+ {
+ ACE_Guard<ACE_Thread_Mutex> guard(m_connectionMap_mtx);
+ m_sync_connections[ACE_Based::Thread::current()] = conn;
+ }
+
+ sLog.outDebug("Core thread with ID ["UI64FMTD"] initializing MySQL connection.",
+ (uint64)ACE_Based::Thread::currentId());
+}
+
+void DatabaseWorkerPool::End_MySQL_Connection()
+{
+ MySQLConnection* conn;
+ {
+ ACE_Guard<ACE_Thread_Mutex> guard(m_connectionMap_mtx);
+ conn = m_sync_connections[ACE_Based::Thread::current()];
+ }
+ delete conn;
+ conn = NULL;
+}
+
+void DatabaseWorkerPool::Execute(const char* sql)
+{
+ if (!sql)
+ return;
+
+ BasicStatementTask* task = new BasicStatementTask(sql);
+ Enqueue(task);
+}
+
+void DatabaseWorkerPool::PExecute(const char* sql, ...)
+{
+ if (!sql)
+ return;
+
+ va_list ap;
+ char szQuery[MAX_QUERY_LEN];
+ va_start(ap, sql);
+ int res = vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
+ va_end(ap);
+
+ Execute(szQuery);
+}
+
+void DatabaseWorkerPool::DirectExecute(const char* sql)
+{
+ if (sql)
+ GetConnection()->Execute(sql);
+}
+
+void DatabaseWorkerPool::DirectPExecute(const char* sql, ...)
+{
+ if (!sql)
+ return;
+
+ va_list ap;
+ char szQuery[MAX_QUERY_LEN];
+ va_start(ap, sql);
+ int res = vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
+ va_end(ap);
+
+ return DirectExecute(szQuery);
+}
+
+QueryResult_AutoPtr DatabaseWorkerPool::Query(const char* sql)
+{
+ return GetConnection()->Query(sql);
+}
+
+QueryResult_AutoPtr DatabaseWorkerPool::PQuery(const char* sql, ...)
+{
+ if (!sql)
+ return QueryResult_AutoPtr(NULL);
+
+ va_list ap;
+ char szQuery[MAX_QUERY_LEN];
+ va_start(ap, sql);
+ int res = vsnprintf(szQuery, MAX_QUERY_LEN, sql, ap);
+ va_end(ap);
+
+ return Query(szQuery);
+}
+
+void DatabaseWorkerPool::BeginTransaction()
+{
+ ACE_Guard<ACE_Thread_Mutex> guard(m_transQueues_mtx);
+ ACE_Based::Thread* tranThread = ACE_Based::Thread::current(); // owner of this transaction
+ TransactionQueues::iterator itr = m_tranQueues.find(tranThread);
+ if (itr != m_tranQueues.end() && itr->second != NULL)
+ {
+ itr->second->ForcefulDelete();
+ delete itr->second;
+ }
+ m_tranQueues[tranThread] = new TransactionTask();
+ return;
+}
+
+void DatabaseWorkerPool::RollbackTransaction()
+{
+ ACE_Guard<ACE_Thread_Mutex> guard(m_transQueues_mtx);
+ ACE_Based::Thread* tranThread = ACE_Based::Thread::current(); // owner of this transaction
+ TransactionQueues::iterator itr = m_tranQueues.find(tranThread);
+ if (itr != m_tranQueues.end() && itr->second != NULL)
+ {
+ itr->second->ForcefulDelete();
+ delete itr->second;
+ }
+}
+
+void DatabaseWorkerPool::CommitTransaction()
+{
+ ACE_Guard<ACE_Thread_Mutex> guard(m_transQueues_mtx);
+ ACE_Based::Thread* tranThread = ACE_Based::Thread::current(); // owner of this transaction
+ TransactionQueues::iterator itr = m_tranQueues.find(tranThread);
+ if (itr != m_tranQueues.end() && itr->second != NULL)
+ {
+ Enqueue(itr->second);
+ m_tranQueues.erase(itr);
+ }
+}
+
+
+MySQLConnection* DatabaseWorkerPool::GetConnection()
+{
+ MySQLConnection* conn;
+ ConnectionMap::const_iterator itr;
+ {
+ /*! MapUpdate + unbundled threads */
+ ACE_Guard<ACE_Thread_Mutex> guard(m_connectionMap_mtx);
+ itr = m_sync_connections.find(ACE_Based::Thread::current());
+ if (itr != m_sync_connections.end())
+ conn = itr->second;
+ }
+ /*! Bundled threads */
+ conn = m_bundle_conn;
+ ASSERT (conn);
+ return conn;
+} \ No newline at end of file
diff --git a/src/server/shared/Database/DatabaseWorkerPool.h b/src/server/shared/Database/DatabaseWorkerPool.h
new file mode 100644
index 00000000000..d6275e0307f
--- /dev/null
+++ b/src/server/shared/Database/DatabaseWorkerPool.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _DATABASEWORKERPOOL_H
+#define _DATABASEWORKERPOOL_H
+
+#include "Common.h"
+#include "Logging/Log.h"
+
+#include <ace/Activation_Queue.h>
+#include <ace/Atomic_Op_T.h>
+#include <ace/Thread_Mutex.h>
+
+#include "SQLOperation.h"
+#include "QueryResult.h"
+#include "MySQLConnection.h"
+
+enum MySQLThreadBundle
+{
+ MYSQL_BUNDLE_NONE = 0x00, //- Each task will run their own MySQL connection
+ MYSQL_BUNDLE_CLI = 0x01, //- Commandline interface thread
+ MYSQL_BUNDLE_RA = 0x02, //- Remote admin thread
+ MYSQL_BUNDLE_RAR = 0x04, //- Reactor runnable thread
+ MYSQL_BUNDLE_WORLD = 0x08, //- WorldRunnable
+ MYSQL_BUNDLE_ALL = MYSQL_BUNDLE_CLI | MYSQL_BUNDLE_RA | MYSQL_BUNDLE_RAR | MYSQL_BUNDLE_WORLD,
+};
+
+class DatabaseWorkerPool
+{
+ public:
+ DatabaseWorkerPool();
+ ~DatabaseWorkerPool();
+
+ bool Open(const std::string& infoString, uint8 num_threads);
+ void Close();
+
+ void Init_MySQL_Connection();
+ void End_MySQL_Connection();
+
+ void Execute(const char* sql);
+ void PExecute(const char* sql, ...);
+ void DirectExecute(const char* sql);
+ void DirectPExecute(const char* sql, ...);
+ QueryResult_AutoPtr Query(const char* sql);
+ QueryResult_AutoPtr PQuery(const char* sql, ...);
+
+ /// Async queries and query holders, implemented in DatabaseImpl.h
+
+ // Query / member
+ template<class Class>
+ bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *sql);
+ template<class Class, typename ParamType1>
+ bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql);
+ template<class Class, typename ParamType1, typename ParamType2>
+ bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
+ template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+ bool AsyncQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
+ // Query / static
+ template<typename ParamType1>
+ bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *sql);
+ template<typename ParamType1, typename ParamType2>
+ bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *sql);
+ template<typename ParamType1, typename ParamType2, typename ParamType3>
+ bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *sql);
+ // PQuery / member
+ template<class Class>
+ bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr), const char *format,...) ATTR_PRINTF(4,5);
+ template<class Class, typename ParamType1>
+ bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(5,6);
+ template<class Class, typename ParamType1, typename ParamType2>
+ bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(6,7);
+ template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
+ bool AsyncPQuery(Class *object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(7,8);
+ // PQuery / static
+ template<typename ParamType1>
+ bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char *format,...) ATTR_PRINTF(4,5);
+ template<typename ParamType1, typename ParamType2>
+ bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char *format,...) ATTR_PRINTF(5,6);
+ template<typename ParamType1, typename ParamType2, typename ParamType3>
+ bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char *format,...) ATTR_PRINTF(6,7);
+ template<class Class>
+ // QueryHolder
+ bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SQLQueryHolder*), SQLQueryHolder *holder);
+ template<class Class, typename ParamType1>
+ bool DelayQueryHolder(Class *object, void (Class::*method)(QueryResult_AutoPtr, SQLQueryHolder*, ParamType1), SQLQueryHolder *holder, ParamType1 param1);
+
+ void SetResultQueue(SQLResultQueue * queue)
+ {
+ m_queryQueues[ACE_Based::Thread::current()] = queue;
+ }
+
+ void BeginTransaction();
+ void RollbackTransaction();
+ void CommitTransaction();
+
+ void escape_string(std::string& str)
+ {
+ if (str.empty())
+ return;
+
+ char* buf = new char[str.size()*2+1];
+ escape_string(buf,str.c_str(),str.size());
+ str = buf;
+ delete[] buf;
+ }
+
+ unsigned long escape_string(char *to, const char *from, unsigned long length)
+ {
+ if (!to || !from || !length)
+ return 0;
+ return (mysql_real_escape_string(GetConnection()->GetHandle(), to, from, length));
+ }
+
+ private:
+ void Enqueue(SQLOperation* op)
+ {
+ m_queue->enqueue(op);
+ }
+
+ MySQLConnection* GetConnection();
+
+ private:
+ typedef UNORDERED_MAP<ACE_Based::Thread*, MySQLConnection*> ConnectionMap;
+ typedef UNORDERED_MAP<ACE_Based::Thread*, TransactionTask*> TransactionQueues;
+ typedef UNORDERED_MAP<ACE_Based::Thread*, SQLResultQueue*> QueryQueues;
+ typedef ACE_Atomic_Op<ACE_SYNCH_MUTEX, uint32> AtomicUInt;
+
+ private:
+ ACE_Activation_Queue* m_queue; //! Queue shared by async worker threads.
+ ACE_Thread_Mutex m_queue_mtx; //! For thread safe enqueues of delayed statements.
+ std::vector<MySQLConnection*> m_async_connections;
+ ConnectionMap m_sync_connections; //! Holds a mysql connection+thread per mapUpdate thread and unbundled runnnables.
+ ACE_Thread_Mutex m_connectionMap_mtx; //! For thread safe access to the synchroneous connection map
+ MySQLConnection* m_bundle_conn; //! Bundled connection (see Database.ThreadBundleMask config)
+ AtomicUInt m_connections; //! Counter of MySQL connections;
+ std::string m_infoString; //! Infostring that is passed on to child connections.
+ TransactionQueues m_tranQueues; //! Transaction queues from diff. threads
+ ACE_Thread_Mutex m_transQueues_mtx; //! To guard m_transQueues
+ QueryQueues m_queryQueues; //! Query queues from diff threads
+};
+
+#endif \ No newline at end of file
diff --git a/src/server/shared/Database/MySQLConnection.cpp b/src/server/shared/Database/MySQLConnection.cpp
new file mode 100644
index 00000000000..cd28474c63d
--- /dev/null
+++ b/src/server/shared/Database/MySQLConnection.cpp
@@ -0,0 +1,244 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "MySQLConnection.h"
+#include "DatabaseWorker.h"
+#include "Utilities/Util.h"
+#include "Utilities/Timer.h"
+
+MySQLConnection::MySQLConnection() :
+m_Mysql(NULL)
+{
+}
+
+MySQLConnection::MySQLConnection(ACE_Activation_Queue* queue) :
+m_queue(queue),
+m_Mysql(NULL)
+{
+ m_worker = new DatabaseWorker(m_queue, this);
+}
+
+MySQLConnection::~MySQLConnection()
+{
+ delete m_worker;
+}
+
+bool MySQLConnection::Open(const std::string& infoString)
+{
+ MYSQL *mysqlInit;
+ mysqlInit = mysql_init(NULL);
+ if (!mysqlInit)
+ {
+ sLog.outError("Could not initialize Mysql connection");
+ return false;
+ }
+
+ Tokens tokens = StrSplit(infoString, ";");
+
+ Tokens::iterator iter;
+
+ std::string host, port_or_socket, user, password, database;
+ int port;
+ char const* unix_socket;
+
+ iter = tokens.begin();
+
+ if (iter != tokens.end())
+ host = *iter++;
+ if (iter != tokens.end())
+ port_or_socket = *iter++;
+ if (iter != tokens.end())
+ user = *iter++;
+ if (iter != tokens.end())
+ password = *iter++;
+ if (iter != tokens.end())
+ database = *iter++;
+
+ mysql_options(mysqlInit, MYSQL_SET_CHARSET_NAME, "utf8");
+ #ifdef _WIN32
+ if (host==".") // named pipe use option (Windows)
+ {
+ unsigned int opt = MYSQL_PROTOCOL_PIPE;
+ mysql_options(mysqlInit, MYSQL_OPT_PROTOCOL, (char const*)&opt);
+ port = 0;
+ unix_socket = 0;
+ }
+ else // generic case
+ {
+ port = atoi(port_or_socket.c_str());
+ unix_socket = 0;
+ }
+ #else
+ if (host==".") // socket use option (Unix/Linux)
+ {
+ unsigned int opt = MYSQL_PROTOCOL_SOCKET;
+ mysql_options(mysqlInit, MYSQL_OPT_PROTOCOL, (char const*)&opt);
+ host = "localhost";
+ port = 0;
+ unix_socket = port_or_socket.c_str();
+ }
+ else // generic case
+ {
+ port = atoi(port_or_socket.c_str());
+ unix_socket = 0;
+ }
+ #endif
+
+ m_Mysql = mysql_real_connect(mysqlInit, host.c_str(), user.c_str(),
+ password.c_str(), database.c_str(), port, unix_socket, 0);
+
+ if (m_Mysql)
+ {
+ sLog.outDetail("Connected to MySQL database at %s", host.c_str());
+ sLog.outString("MySQL client library: %s", mysql_get_client_info());
+ sLog.outString("MySQL server ver: %s ", mysql_get_server_info( m_Mysql));
+
+ if (!mysql_autocommit(m_Mysql, 1))
+ sLog.outDetail("AUTOCOMMIT SUCCESSFULLY SET TO 1");
+ else
+ sLog.outDetail("AUTOCOMMIT NOT SET TO 1");
+
+ // set connection properties to UTF8 to properly handle locales for different
+ // server configs - core sends data in UTF8, so MySQL must expect UTF8 too
+ Execute("SET NAMES `utf8`");
+ Execute("SET CHARACTER SET `utf8`");
+
+ #if MYSQL_VERSION_ID >= 50003
+ my_bool my_true = (my_bool)1;
+ if (mysql_options(m_Mysql, MYSQL_OPT_RECONNECT, &my_true))
+ sLog.outDetail("Failed to turn on MYSQL_OPT_RECONNECT.");
+ else
+ sLog.outDetail("Successfully turned on MYSQL_OPT_RECONNECT.");
+ #else
+ #warning "Your mySQL client lib version does not support reconnecting after a timeout.\nIf this causes you any trouble we advice you to upgrade your mySQL client libs to at least mySQL 5.0.13 to resolve this problem."
+ #endif
+ return true;
+ }
+ else
+ {
+ sLog.outError("Could not connect to MySQL database at %s: %s\n", host.c_str(), mysql_error(mysqlInit));
+ mysql_close(mysqlInit);
+ return false;
+ }
+}
+
+bool MySQLConnection::Execute(const char* sql)
+{
+ if (!m_Mysql)
+ return false;
+
+ {
+ // guarded block for thread-safe mySQL request
+ ACE_Guard<ACE_Thread_Mutex> query_connection_guard(m_Mutex);
+
+ #ifdef TRINITY_DEBUG
+ uint32 _s = getMSTime();
+ #endif
+ if (mysql_query(m_Mysql, sql))
+ {
+ sLog.outErrorDb("SQL: %s", sql);
+ sLog.outErrorDb("SQL ERROR: %s", mysql_error(m_Mysql));
+ return false;
+ }
+ else
+ {
+ #ifdef TRINITY_DEBUG
+ sLog.outDebug("[%u ms] SQL: %s", getMSTimeDiff(_s, getMSTime()), sql);
+ #endif
+ }
+ }
+
+ return true;
+}
+
+QueryResult_AutoPtr MySQLConnection::Query(const char* sql)
+{
+ if (!sql)
+ return QueryResult_AutoPtr(NULL);
+
+ MYSQL_RES *result = NULL;
+ MYSQL_FIELD *fields = NULL;
+ uint64 rowCount = 0;
+ uint32 fieldCount = 0;
+
+ if (!_Query(sql, &result, &fields, &rowCount, &fieldCount))
+ return QueryResult_AutoPtr(NULL);
+
+ QueryResult *queryResult = new QueryResult(result, fields, rowCount, fieldCount);
+
+ queryResult->NextRow();
+
+ return QueryResult_AutoPtr(queryResult);
+}
+
+bool MySQLConnection::_Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount)
+{
+ if (!m_Mysql)
+ return false;
+
+ {
+ // guarded block for thread-safe mySQL request
+ ACE_Guard<ACE_Thread_Mutex> query_connection_guard(m_Mutex);
+ #ifdef TRINITY_DEBUG
+ uint32 _s = getMSTime();
+ #endif
+ if (mysql_query(m_Mysql, sql))
+ {
+ sLog.outErrorDb("SQL: %s", sql);
+ sLog.outErrorDb("query ERROR: %s", mysql_error(m_Mysql));
+ return false;
+ }
+ else
+ {
+ #ifdef TRINITY_DEBUG
+ sLog.outDebug("[%u ms] SQL: %s", getMSTimeDiff(_s,getMSTime()), sql);
+ #endif
+ }
+
+ *pResult = mysql_store_result(m_Mysql);
+ *pRowCount = mysql_affected_rows(m_Mysql);
+ *pFieldCount = mysql_field_count(m_Mysql);
+ }
+
+ if (!*pResult )
+ return false;
+
+ if (!*pRowCount)
+ {
+ mysql_free_result(*pResult);
+ return false;
+ }
+
+ *pFields = mysql_fetch_fields(*pResult);
+ return true;
+}
+
+void MySQLConnection::BeginTransaction()
+{
+ Execute("START TRANSACTION");
+}
+
+void MySQLConnection::RollbackTransaction()
+{
+ Execute("ROLLBACK");
+}
+
+void MySQLConnection::CommitTransaction()
+{
+ Execute("COMMIT");
+} \ No newline at end of file
diff --git a/src/server/shared/Database/MySQLConnection.h b/src/server/shared/Database/MySQLConnection.h
new file mode 100644
index 00000000000..08ceaa2860c
--- /dev/null
+++ b/src/server/shared/Database/MySQLConnection.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _MYSQLCONNECTION_H
+#define _MYSQLCONNECTION_H
+
+class DatabaseWorker;
+
+class MySQLConnection
+{
+ friend class DatabaseWorkerPool;
+
+ public:
+ MySQLConnection(); //! Constructor for synchroneous connections.
+ MySQLConnection(ACE_Activation_Queue* queue); //! Constructor for asynchroneous connections.
+ ~MySQLConnection();
+
+ bool Open(const std::string& infoString); //! Connection details.
+
+ public:
+ bool Execute(const char* sql);
+ QueryResult_AutoPtr Query(const char* sql);
+ bool _Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64* pRowCount, uint32* pFieldCount);
+
+ void BeginTransaction();
+ void RollbackTransaction();
+ void CommitTransaction();
+
+ operator bool () const { return m_Mysql != NULL; }
+
+ protected:
+ MYSQL* GetHandle() { return m_Mysql; }
+
+ private:
+ ACE_Activation_Queue* m_queue; //! Queue shared with other asynchroneous connections.
+ DatabaseWorker* m_worker; //! Core worker task.
+ MYSQL * m_Mysql; //! MySQL Handle.
+ ACE_Thread_Mutex m_Mutex;
+};
+
+#endif \ No newline at end of file
diff --git a/src/server/shared/Database/MySQLThreading.h b/src/server/shared/Database/MySQLThreading.h
new file mode 100644
index 00000000000..3c039a4d165
--- /dev/null
+++ b/src/server/shared/Database/MySQLThreading.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _MYSQLTHREADING_H
+#define _MYSQLTHREADING_H
+
+#include "Log.h"
+
+class MySQL
+{
+ public:
+ /*! Create a thread on the MySQL server to mirrior the calling thread,
+ initializes thread-specific variables and allows thread-specific
+ operations without concurrence from other threads.
+ This should only be called if multiple core threads are running
+ on the same MySQL connection. Seperate MySQL connections implicitly
+ create a mirror thread.
+ */
+ static void Thread_Init()
+ {
+ mysql_thread_init();
+ printf("Core thread with ID ["UI64FMTD"] initializing MySQL thread.",
+ (uint64)ACE_Based::Thread::currentId());
+ }
+
+ /*! Shuts down MySQL thread and frees resources, should only be called
+ when we terminate. MySQL threads and connections are not configurable
+ during runtime.
+ */
+ static void Thread_End()
+ {
+ mysql_thread_end();
+ printf("Core thread with ID ["UI64FMTD"] shutting down MySQL thread.",
+ (uint64)ACE_Based::Thread::currentId());
+ }
+};
+
+#endif \ No newline at end of file
diff --git a/src/server/shared/Database/PreparedStatements.cpp b/src/server/shared/Database/PreparedStatements.cpp
deleted file mode 100644
index ec57a0f90e8..00000000000
--- a/src/server/shared/Database/PreparedStatements.cpp
+++ /dev/null
@@ -1,93 +0,0 @@
-#include "PreparedStatements.h"
-
-void PreparedStatementHolder::_prepareStatement(const char* name, const char* sql, Database *db, uint32 &count)
-{
- const char prefix[] = "PREPARE ";
- size_t querySize = 8 + strlen(name) + 6 + strlen(sql) + 2 + 1;
- char* query = new char[querySize];
- strcpy(query, prefix);
- strcat(query, name);
- strcat(query, " FROM ");
- strcat(query, "'");
- strcat(query, sql);
- strcat(query, "'");
-
- DEBUG_LOG("Preparing statement: %s", query);
- db->Execute(query);
-
- delete[] query;
- ++count;
-}
-
-void PreparedStatementHolder::LoadAuthserver(Database *db, uint32 &count)
-{
- _prepareStatement("auth_ping", "SELECT 1 FROM realmlist LIMIT 1", db, count);
-};
-
-void PreparedStatementHolder::Execute(Database *db, const char *name)
-{
- const char prefix[] = "EXECUTE ";
- size_t querySize = 8 + strlen(name) + 1;
- char* query = new char[querySize];
- strcpy(query, prefix);
- strcat(query, name);
-
- DEBUG_LOG("Prepared statement: %s", query);
- db->Execute(query);
- delete[] query;
-}
-
-void PreparedStatementHolder::PExecute(Database *db, const char *name, const char* args)
-{
- // NOTE: if args == NULL, we're crashing here. No need to waste performance on checking;
- // devs must make sure they use PExecute for args and Execute for no args.
-
- const char prefix[] = "EXECUTE ";
- size_t querySize = 8 + strlen(name) + 7 + strlen(args) + 1;
- char* query = new char[querySize];
- strcpy(query, prefix);
- strcat(query, name);
- strcat(query, " USING ");
- strcat(query, args);
-
- DEBUG_LOG("Prepared statement (parsed args): %s", query);
- db->Execute(query);
- delete[] query;
-}
-
-QueryResult_AutoPtr PreparedStatementHolder::Query(Database *db, const char *name)
-{
- QueryResult_AutoPtr _return = QueryResult_AutoPtr(NULL);
-
- const char prefix[] = "EXECUTE ";
- size_t querySize = 8 + strlen(name) + 1;
- char* query = new char[querySize];
- strcpy(query, prefix);
- strcat(query, name);
-
- DEBUG_LOG("Prepared statement with resultset: %s", query);
- _return = db->Query(query);
- delete[] query;
- return _return;
-}
-
-QueryResult_AutoPtr PreparedStatementHolder::PQuery(Database *db, const char *name, const char *args)
-{
- // NOTE: if args == NULL, we're crashing here. No need to waste performance on checking;
- // devs must make sure they use PQuery for args and Query for no args.
-
- QueryResult_AutoPtr _return = QueryResult_AutoPtr(NULL);
-
- const char prefix[] = "EXECUTE ";
- size_t querySize = 8 + strlen(name) + 7 + strlen(args) + 1;
- char* query = new char[querySize];
- strcpy(query, prefix);
- strcat(query, name);
- strcat(query, " USING ");
- strcat(query, args);
-
- DEBUG_LOG("Prepared statement with resultset (parsed args): %s", query);
- _return = db->Query(query);
- delete[] query;
- return _return;
-} \ No newline at end of file
diff --git a/src/server/shared/Database/PreparedStatements.h b/src/server/shared/Database/PreparedStatements.h
deleted file mode 100644
index 277d2b833ec..00000000000
--- a/src/server/shared/Database/PreparedStatements.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef sPreparedStatement
-
-#include "ace/Singleton.h"
-#include "Database/DatabaseEnv.h"
-
-class PreparedStatementHolder
-{
- public:
- ///- Load prepare statements on database $db and increase $count for every statement
- void LoadCharacters(Database *db, uint32 &count);
- void LoadAuthserver(Database *db, uint32 &count);
- void LoadWorldserver(Database *db, uint32 &count);
-
- ///- Executes prepared statement that doesn't require feedback with name $name on database $db
- void Execute(Database *db, const char* name);
- ///- Executes prepared statement that doesn't require feedback with name $name and args $args
- ///- on database $db
- void PExecute(Database *db, const char* name, const char* args);
-
- ///- Executes a prepared statement without args on db $db with name $name and puts the result set in a pointer.
- QueryResult_AutoPtr Query(Database* db, const char* name);
- ///- Executes a prepared statement with args $args on db $db with name $name and put the result set in a pointer.
- QueryResult_AutoPtr PQuery(Database* db, const char* name, const char* args);
-
- private:
- void _prepareStatement(const char* name, const char* sql, Database *db, uint32 &count);
-
-};
-#define sPreparedStatement (*ACE_Singleton<PreparedStatementHolder, ACE_Null_Mutex>::instance())
-#endif \ No newline at end of file
diff --git a/src/server/shared/Database/SqlOperations.cpp b/src/server/shared/Database/SQLOperation.cpp
index 33b96a30533..d3af5949faf 100644
--- a/src/server/shared/Database/SqlOperations.cpp
+++ b/src/server/shared/Database/SQLOperation.cpp
@@ -1,6 +1,4 @@
/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify
@@ -18,71 +16,74 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include "SqlOperations.h"
-#include "SqlDelayThread.h"
-#include "DatabaseEnv.h"
-#include "DatabaseImpl.h"
+#include "SQLOperation.h"
+#include "MySQLConnection.h"
-/// ---- ASYNC STATEMENTS / TRANSACTIONS ----
+/*! Basic, ad-hoc queries. */
+BasicStatementTask::BasicStatementTask(const char* sql)
+{
+ m_sql = strdup(sql);
+}
-void SqlStatement::Execute(Database *db)
+BasicStatementTask::~BasicStatementTask()
{
- /// just do it
- db->DirectExecute(m_sql);
+ free((void*)m_sql);
}
-void SqlTransaction::Execute(Database *db)
+bool BasicStatementTask::Execute()
{
- const char* sql;
+ return m_conn->Execute(m_sql);
+}
+
+/*! Transactions. */
+TransactionTask::TransactionTask()
+{
+}
+
+TransactionTask::~TransactionTask()
+{
+
+}
- m_Mutex.acquire();
- if (m_queue.empty())
+void TransactionTask::ForcefulDelete()
+{
+ while (!m_queries.empty())
{
- m_Mutex.release();
- return;
+ free((void*)const_cast<char*>(m_queries.front()));
+ m_queries.pop();
}
+}
- db->DirectExecute("START TRANSACTION");
- while (!m_queue.empty())
- {
- sql = m_queue.front();
+bool TransactionTask::Execute()
+{
+ if (m_queries.empty())
+ return false;
+
+ const char* sql;
- if (!db->DirectExecute(sql))
+ m_conn->BeginTransaction();
+ while (!m_queries.empty())
+ {
+ sql = m_queries.front();
+ if (!m_conn->Execute(sql))
{
free((void*)const_cast<char*>(sql));
- m_queue.pop();
- db->DirectExecute("ROLLBACK");
- while (!m_queue.empty())
- {
- free((void*)const_cast<char*>(m_queue.front()));
- m_queue.pop();
- }
- m_Mutex.release();
- return;
+ m_queries.pop();
+ m_conn->RollbackTransaction();
+ ForcefulDelete();
+ return false;
}
free((void*)const_cast<char*>(sql));
- m_queue.pop();
+ m_queries.pop();
}
- db->DirectExecute("COMMIT");
- m_Mutex.release();
-}
-
-/// ---- ASYNC QUERIES ----
-
-void SqlQuery::Execute(Database *db)
-{
- if (!m_callback || !m_queue)
- return;
-
- /// execute the query and store the result in the callback
- m_callback->SetResult(db->Query(m_sql));
- /// add the callback to the sql result queue of the thread it originated from
- m_queue->add(m_callback);
+ m_conn->CommitTransaction();
+ return true;
}
-void SqlResultQueue::Update()
+/*! Callback statements/holders */
+void SQLResultQueue::Update()
{
/// execute the callbacks waiting in the synchronization queue
Trinity::IQueryCallback* callback;
@@ -93,39 +94,27 @@ void SqlResultQueue::Update()
}
}
-bool SqlQueryHolder::Execute(Trinity::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue)
-{
- if (!callback || !thread || !queue)
- return false;
-
- /// delay the execution of the queries, sync them with the delay thread
- /// which will in turn resync on execution (via the queue) and call back
- SqlQueryHolderEx *holderEx = new SqlQueryHolderEx(this, callback, queue);
- thread->Delay(holderEx);
- return true;
-}
-
-bool SqlQueryHolder::SetQuery(size_t index, const char *sql)
+bool SQLQueryHolder::SetQuery(size_t index, const char *sql)
{
if (m_queries.size() <= index)
{
- sLog.outError("Query index (%u) out of range (size: %u) for query: %s",index,(uint32)m_queries.size(),sql);
+ sLog.outError("Query index (%u) out of range (size: %u) for query: %s", index, (uint32)m_queries.size(), sql);
return false;
}
if (m_queries[index].first != NULL)
{
sLog.outError("Attempt assign query to holder index (%u) where other query stored (Old: [%s] New: [%s])",
- index,m_queries[index].first,sql);
+ index, m_queries[index].first, sql);
return false;
}
/// not executed yet, just stored (it's not called a holder for nothing)
- m_queries[index] = SqlResultPair(strdup(sql), QueryResult_AutoPtr(NULL));
+ m_queries[index] = SQLResultPair(strdup(sql), QueryResult_AutoPtr(NULL));
return true;
}
-bool SqlQueryHolder::SetPQuery(size_t index, const char *format, ...)
+bool SQLQueryHolder::SetPQuery(size_t index, const char *format, ...)
{
if (!format)
{
@@ -145,10 +134,10 @@ bool SqlQueryHolder::SetPQuery(size_t index, const char *format, ...)
return false;
}
- return SetQuery(index,szQuery);
+ return SetQuery(index, szQuery);
}
-QueryResult_AutoPtr SqlQueryHolder::GetResult(size_t index)
+QueryResult_AutoPtr SQLQueryHolder::GetResult(size_t index)
{
if (index < m_queries.size())
{
@@ -165,14 +154,14 @@ QueryResult_AutoPtr SqlQueryHolder::GetResult(size_t index)
return QueryResult_AutoPtr(NULL);
}
-void SqlQueryHolder::SetResult(size_t index, QueryResult_AutoPtr result)
+void SQLQueryHolder::SetResult(size_t index, QueryResult_AutoPtr result)
{
/// store the result in the holder
if (index < m_queries.size())
m_queries[index].second = result;
}
-SqlQueryHolder::~SqlQueryHolder()
+SQLQueryHolder::~SQLQueryHolder()
{
for (size_t i = 0; i < m_queries.size(); i++)
{
@@ -183,27 +172,41 @@ SqlQueryHolder::~SqlQueryHolder()
}
}
-void SqlQueryHolder::SetSize(size_t size)
+void SQLQueryHolder::SetSize(size_t size)
{
/// to optimize push_back, reserve the number of queries about to be executed
m_queries.resize(size);
}
-void SqlQueryHolderEx::Execute(Database *db)
+bool SQLQueryHolderTask::Execute()
{
if (!m_holder || !m_callback || !m_queue)
- return;
+ return false;
/// we can do this, we are friends
- std::vector<SqlQueryHolder::SqlResultPair> &queries = m_holder->m_queries;
+ std::vector<SQLQueryHolder::SQLResultPair> &queries = m_holder->m_queries;
for (size_t i = 0; i < queries.size(); i++)
{
/// execute all queries in the holder and pass the results
char const *sql = queries[i].first;
- if(sql) m_holder->SetResult(i, db->Query(sql));
+ if (sql)
+ m_holder->SetResult(i, m_conn->Query(sql));
}
/// sync with the caller thread
m_queue->add(m_callback);
+ return true;
}
+
+bool SQLQueryTask::Execute()
+{
+ if (!m_callback || !m_queue)
+ return false;
+
+ /// execute the query and store the result in the callback
+ m_callback->SetResult(m_conn->Query(m_sql));
+ /// add the callback to the sql result queue of the thread it originated from
+ m_queue->add(m_callback);
+ return true;
+} \ No newline at end of file
diff --git a/src/server/shared/Database/SQLOperation.h b/src/server/shared/Database/SQLOperation.h
new file mode 100644
index 00000000000..8f2a59151a3
--- /dev/null
+++ b/src/server/shared/Database/SQLOperation.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _SQLOPERATION_H
+#define _SQLOPERATION_H
+
+#include <ace/Method_Request.h>
+
+#include "Common.h"
+#include "Threading/Callback.h"
+
+class MySQLConnection;
+
+class SQLOperation : public ACE_Method_Request
+{
+ public:
+ SQLOperation(){};
+ int call()
+ {
+ Execute();
+ return 0;
+ }
+ virtual bool Execute() = 0;
+
+ virtual void SetConnection(MySQLConnection* con) { m_conn = con; }
+
+ MySQLConnection* m_conn;
+};
+
+/*! Raw, ad-hoc query. */
+class BasicStatementTask : public SQLOperation
+{
+ public:
+ BasicStatementTask(const char* sql);
+ ~BasicStatementTask();
+
+ bool Execute();
+
+ private:
+ const char* m_sql; //- Raw query to be executed
+};
+
+/*! Transactions */
+class TransactionTask : public SQLOperation
+{
+ public:
+ TransactionTask();
+ ~TransactionTask();
+ void ForcefulDelete();
+
+ bool Execute();
+
+ private:
+ std::queue<char*> m_queries;
+};
+
+/*! ResultQueue */
+class SQLResultQueue : public ACE_Based::LockedQueue<Trinity::IQueryCallback* , ACE_Thread_Mutex>
+{
+ public:
+ SQLResultQueue() {}
+ void Update();
+};
+
+class SQLQueryHolder
+{
+ friend class SQLQueryHolderTask;
+ private:
+ typedef std::pair<const char*, QueryResult_AutoPtr> SQLResultPair;
+ std::vector<SQLResultPair> m_queries;
+ public:
+ SQLQueryHolder() {}
+ ~SQLQueryHolder();
+ bool SetQuery(size_t index, const char *sql);
+ bool SetPQuery(size_t index, const char *format, ...) ATTR_PRINTF(3,4);
+ void SetSize(size_t size);
+ QueryResult_AutoPtr GetResult(size_t index);
+ void SetResult(size_t index, QueryResult_AutoPtr result);
+};
+
+class SQLQueryHolderTask : public SQLOperation
+{
+ private:
+ SQLQueryHolder * m_holder;
+ Trinity::IQueryCallback * m_callback;
+ SQLResultQueue * m_queue;
+ public:
+ SQLQueryHolderTask(SQLQueryHolder *holder, Trinity::IQueryCallback * callback, SQLResultQueue * queue)
+ : m_holder(holder), m_callback(callback), m_queue(queue) {}
+ bool Execute();
+};
+
+class SQLQueryTask : public SQLOperation
+{
+ private:
+ const char *m_sql;
+ Trinity::IQueryCallback * m_callback;
+ SQLResultQueue * m_queue;
+ public:
+ SQLQueryTask(const char *sql, Trinity::IQueryCallback * callback, SQLResultQueue * queue)
+ : m_sql(strdup(sql)), m_callback(callback), m_queue(queue) {}
+ ~SQLQueryTask() { void* tofree = const_cast<char*>(m_sql); free(tofree); }
+ bool Execute();
+};
+
+
+#endif \ No newline at end of file
diff --git a/src/server/shared/Database/SQLStorage.cpp b/src/server/shared/Database/SQLStorage.cpp
index 1a65824a631..26aecb80fa3 100644
--- a/src/server/shared/Database/SQLStorage.cpp
+++ b/src/server/shared/Database/SQLStorage.cpp
@@ -21,7 +21,7 @@
#include "SQLStorage.h"
#include "SQLStorageImpl.h"
-extern Database WorldDatabase;
+extern DatabaseType WorldDatabase;
const char CreatureInfosrcfmt[]="iiiiiiiiiisssiiiiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiisi";
const char CreatureInfodstfmt[]="iiiiiiiiiisssibbiiiifffiffiifiiiiiiiiiiffiiiiiiiiiiiiiiiiiiiiiiiisiifffliiiiiiiliiiii";
diff --git a/src/server/shared/Database/SqlOperations.h b/src/server/shared/Database/SqlOperations.h
deleted file mode 100644
index 337790e4c72..00000000000
--- a/src/server/shared/Database/SqlOperations.h
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- * Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
- *
- * Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
- *
- * 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __SQLOPERATIONS_H
-#define __SQLOPERATIONS_H
-
-#include "Common.h"
-
-#include "ace/Thread_Mutex.h"
-#include "ace/Method_Request.h"
-#include "Threading/LockedQueue.h"
-#include <queue>
-#include "Threading/Callback.h"
-#include "QueryResult.h"
-
-/// ---- BASE ---
-
-class Database;
-class SqlDelayThread;
-
-class SqlOperation
-{
- public:
- virtual void OnRemove() { delete this; }
- virtual void Execute(Database *db) = 0;
- virtual ~SqlOperation() {}
-};
-
-/// ---- ASYNC STATEMENTS / TRANSACTIONS ----
-
-class SqlStatement : public SqlOperation
-{
- private:
- const char *m_sql;
- public:
- SqlStatement(const char *sql) : m_sql(strdup(sql)){}
- ~SqlStatement() { void* tofree = const_cast<char*>(m_sql); free(tofree); }
- void Execute(Database *db);
-};
-
-class SqlTransaction : public SqlOperation
-{
- private:
- std::queue<const char*> m_queue;
- ACE_Thread_Mutex m_Mutex;
- public:
- SqlTransaction() {}
- void DelayExecute(const char *sql)
- {
- m_Mutex.acquire();
- char* _sql = strdup(sql);
- if (_sql)
- m_queue.push(_sql);
- m_Mutex.release();
- }
- void Execute(Database *db);
-};
-
-/// ---- ASYNC QUERIES ----
-
-class SqlQuery; /// contains a single async query
-class QueryResult; /// the result of one
-class SqlResultQueue; /// queue for thread sync
-class SqlQueryHolder; /// groups several async quries
-class SqlQueryHolderEx; /// points to a holder, added to the delay thread
-
-class SqlResultQueue : public ACE_Based::LockedQueue<Trinity::IQueryCallback* , ACE_Thread_Mutex>
-{
- public:
- SqlResultQueue() {}
- void Update();
-};
-
-class SqlQuery : public SqlOperation
-{
- private:
- const char *m_sql;
- Trinity::IQueryCallback * m_callback;
- SqlResultQueue * m_queue;
- public:
- SqlQuery(const char *sql, Trinity::IQueryCallback * callback, SqlResultQueue * queue)
- : m_sql(strdup(sql)), m_callback(callback), m_queue(queue) {}
- ~SqlQuery() { void* tofree = const_cast<char*>(m_sql); free(tofree); }
- void Execute(Database *db);
-};
-
-class SqlQueryHolder
-{
- friend class SqlQueryHolderEx;
- private:
- typedef std::pair<const char*, QueryResult_AutoPtr> SqlResultPair;
- std::vector<SqlResultPair> m_queries;
- public:
- SqlQueryHolder() {}
- ~SqlQueryHolder();
- bool SetQuery(size_t index, const char *sql);
- bool SetPQuery(size_t index, const char *format, ...) ATTR_PRINTF(3,4);
- void SetSize(size_t size);
- QueryResult_AutoPtr GetResult(size_t index);
- void SetResult(size_t index, QueryResult_AutoPtr result);
- bool Execute(Trinity::IQueryCallback * callback, SqlDelayThread *thread, SqlResultQueue *queue);
-};
-
-class SqlQueryHolderEx : public SqlOperation
-{
- private:
- SqlQueryHolder * m_holder;
- Trinity::IQueryCallback * m_callback;
- SqlResultQueue * m_queue;
- public:
- SqlQueryHolderEx(SqlQueryHolder *holder, Trinity::IQueryCallback * callback, SqlResultQueue * queue)
- : m_holder(holder), m_callback(callback), m_queue(queue) {}
- void Execute(Database *db);
-};
-
-class SqlAsyncTask : public ACE_Method_Request
-{
-public:
- SqlAsyncTask(Database * db, SqlOperation * op) : m_db(db), m_op(op){}
- ~SqlAsyncTask()
- {
- if (!m_op)
- return;
-
- delete m_op;
- m_op = NULL;
- }
-
- int call()
- {
- if (m_db == NULL || m_op == NULL)
- return -1;
-
- try
- {
- m_op->Execute(m_db);
- }
- catch(...)
- {
- return -1;
- }
-
- return 0;
- }
-
-private:
- Database * m_db;
- SqlOperation * m_op;
-};
-#endif //__SQLOPERATIONS_H
-