OregonCore  revision 3611e8a-git
Your Favourite TBC server
Database.h
Go to the documentation of this file.
1 /*
2  * This file is part of the OregonCore Project. See AUTHORS file for Copyright information
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the
6  * Free Software Foundation; either version 2 of the License, or (at your
7  * option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #ifndef DATABASE_H
19 #define DATABASE_H
20 
21 #include "Threading.h"
22 #include "Utilities/UnorderedMap.h"
24 #include "Policies/Singleton.h"
25 #include "ace/Thread_Mutex.h"
26 #include "ace/Guard_T.h"
27 #include "ace/Atomic_Op.h"
28 #include "PreparedStatement.h"
29 #include "QueryResult.h"
30 
31 #ifdef WIN32
32 #define FD_SETSIZE 1024
33 #include <winsock2.h>
34 #endif
35 #include <mysql.h>
36 
37 class SqlTransaction;
38 class SqlResultQueue;
40 
41 typedef UNORDERED_MAP<ACE_Based::Thread*, SqlTransaction*> TransactionQueues;
42 typedef UNORDERED_MAP<ACE_Based::Thread*, SqlResultQueue*> QueryQueues;
43 
44 #define MAX_QUERY_LEN 1024
45 
46 class Database
47 {
48  protected:
49  TransactionQueues m_tranQueues; // Transaction queues from diff. threads
50  QueryQueues m_queryQueues; // Query queues from diff threads
51  SqlDelayThread* m_threadBody; // Pointer to delay sql executer (owned by m_delayThread)
52  ACE_Based::Thread* m_delayThread; // Pointer to executer thread
53 
54  public:
55 
56  Database();
57  ~Database();
58 
60  bool Initialize(const char* infoString);
61 
62  bool IsConnected() const { return m_connected; }
63 
64  void InitDelayThread();
65  void HaltDelayThread();
66 
67  QueryResult_AutoPtr Query(const char* sql);
68  QueryResult_AutoPtr PQuery(const char* format, ...) ATTR_PRINTF(2, 3);
69 
70  bool ExecuteFile(const char* file);
71 
72  // Async queries and query holders, implemented in DatabaseImpl.h
73 
74  // Query / member
75  template<class Class>
76  bool AsyncQuery(Class* object, void (Class::*method)(QueryResult_AutoPtr), const char* sql);
77  template<class Class, typename ParamType1>
78  bool AsyncQuery(Class* object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char* sql);
79  template<class Class, typename ParamType1, typename ParamType2>
80  bool AsyncQuery(Class* object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char* sql);
81  template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
82  bool AsyncQuery(Class* object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char* sql);
83  // Query / static
84  template<typename ParamType1>
85  bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char* sql);
86  template<typename ParamType1, typename ParamType2>
87  bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char* sql);
88  template<typename ParamType1, typename ParamType2, typename ParamType3>
89  bool AsyncQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char* sql);
90  // PQuery / member
91  template<class Class>
92  bool AsyncPQuery(Class* object, void (Class::*method)(QueryResult_AutoPtr), const char* format, ...) ATTR_PRINTF(4, 5);
93  template<class Class, typename ParamType1>
94  bool AsyncPQuery(Class* object, void (Class::*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char* format, ...) ATTR_PRINTF(5, 6);
95  template<class Class, typename ParamType1, typename ParamType2>
96  bool AsyncPQuery(Class* object, void (Class::*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char* format, ...) ATTR_PRINTF(6, 7);
97  template<class Class, typename ParamType1, typename ParamType2, typename ParamType3>
98  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);
99  // PQuery / static
100  template<typename ParamType1>
101  bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1), ParamType1 param1, const char* format, ...) ATTR_PRINTF(4, 5);
102  template<typename ParamType1, typename ParamType2>
103  bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2), ParamType1 param1, ParamType2 param2, const char* format, ...) ATTR_PRINTF(5, 6);
104  template<typename ParamType1, typename ParamType2, typename ParamType3>
105  bool AsyncPQuery(void (*method)(QueryResult_AutoPtr, ParamType1, ParamType2, ParamType3), ParamType1 param1, ParamType2 param2, ParamType3 param3, const char* format, ...) ATTR_PRINTF(6, 7);
106  template<class Class>
107  // QueryHolder
108  bool DelayQueryHolder(Class* object, void (Class::*method)(QueryResult_AutoPtr, SqlQueryHolder*), SqlQueryHolder* holder);
109  template<class Class, typename ParamType1>
110  bool DelayQueryHolder(Class* object, void (Class::*method)(QueryResult_AutoPtr, SqlQueryHolder*, ParamType1), SqlQueryHolder* holder, ParamType1 param1);
111 
112  bool Execute(const char* sql);
113  bool PExecute(const char* format, ...) ATTR_PRINTF(2, 3);
114 
115  bool DirectExecute(const char* sql)
116  {
117  return DirectExecute(true, sql);
118  }
119  bool DirectPExecute(const char* format, ...) ATTR_PRINTF(2, 3);
120  bool DirectExecute(PreparedStatement* stmt, PreparedValues& values, va_list* args);
121 
122  // Writes SQL commands to a LOG file (see Oregond.conf "LogSQL")
123  bool PExecuteLog(const char* format, ...) ATTR_PRINTF(2, 3);
124 
125  // Writes SQL commands to a LOG file (see Oregond.conf "LogSQL")
126  // but runs via PreparedStatements
127  bool PreparedExecuteLog(const char* sql, const char* format = NULL, ...);
128  bool PreparedExecuteLog(const char* sql, PreparedValues& values);
129 
130  bool BeginTransaction();
131  bool CommitTransaction();
132  bool RollbackTransaction();
133 
134  bool ExecuteTransaction(SqlTransaction* transaction);
135 
136  PreparedQueryResult_AutoPtr PreparedQuery(const char* sql, const char* format = NULL, ...);
137  PreparedQueryResult_AutoPtr PreparedQuery(const char* sql, PreparedValues& values);
138  bool PreparedExecute(const char* sql, const char* format = NULL, ...);
139  bool PreparedExecute(const char* sql, PreparedValues& values);
140 
141  operator bool () const
142  {
143  return mMysql != NULL;
144  }
145  unsigned long escape_string(char* to, const char* from, unsigned long length);
146  void escape_string(std::string& str);
147 
148  void ThreadStart();
149  void ThreadEnd();
150 
151  // sets the result queue of the current thread, be careful what thread you call this from
152  void SetResultQueue(SqlResultQueue* queue);
153 
154  protected:
155  bool DirectExecute(bool lock, const char* sql);
156  private:
157  bool m_logSQL;
158  std::string m_logsDir;
159  ACE_Thread_Mutex mMutex; // For thread safe operations between core and mySQL server
160  ACE_Thread_Mutex nMutex; // For thread safe operations on m_transQueues
161  ACE_Thread_Mutex pMutex; // For thread safe operations on m_preparedStatements
162 
164 
165  MYSQL* mMysql;
167 
168  static size_t db_count;
169 
170  bool _TransactionCmd(const char* sql);
171  bool _Query(const char* sql, MYSQL_RES** pResult, MYSQL_FIELD** pFields, uint64* pRowCount, uint32* pFieldCount);
172 
173  PreparedStatement* _GetOrMakePreparedStatement(const char* query, const char* format, PreparedValues* values);
174  bool _ExecutePreparedStatement(PreparedStatement* ps, PreparedValues* values, va_list* args, bool resultset);
175  void _ConvertValistToPreparedValues(va_list ap, PreparedValues& values, const char* fmt);
176 
177  typedef UNORDERED_MAP<std::string, PreparedStatement*> PreparedStatementsMap;
178  PreparedStatementsMap m_preparedStatements;
179 };
180 #endif
181 
bool AsyncQuery(Class *object, void(Class::*method)(QueryResult_AutoPtr), const char *sql)
Definition: DatabaseImpl.h:68
void SetResultQueue(SqlResultQueue *queue)
Definition: Database.cpp:332
SqlDelayThread * m_threadBody
Definition: Database.h:51
std::string m_logsDir
Definition: Database.h:158
ACE_Refcounted_Auto_Ptr< PreparedQueryResult, ACE_Null_Mutex > PreparedQueryResult_AutoPtr
Definition: QueryResult.h:114
bool bool DirectExecute(const char *sql)
Definition: Database.h:115
bool m_connected
Definition: Database.h:166
void _ConvertValistToPreparedValues(va_list ap, PreparedValues &values, const char *fmt)
Definition: Database.cpp:964
bool BeginTransaction()
Definition: Database.cpp:533
MYSQL * mMysql
Definition: Database.h:165
void ThreadEnd()
Definition: Database.cpp:196
QueryResult_AutoPtr PQuery(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:400
QueryResult_AutoPtr bool ExecuteFile(const char *file)
Definition: Database.cpp:657
bool _Query(const char *sql, MYSQL_RES **pResult, MYSQL_FIELD **pFields, uint64 *pRowCount, uint32 *pFieldCount)
Definition: Database.cpp:337
bool Execute(const char *sql)
Definition: Database.cpp:420
bool ExecuteTransaction(SqlTransaction *transaction)
Atomically executed SqlTransaction. Don&#39;t call this directly, use BeginTransaction and CommitTransact...
Definition: Database.cpp:593
bool IsConnected() const
Definition: Database.h:62
unsigned long escape_string(char *to, const char *from, unsigned long length)
Definition: Database.cpp:212
QueryResult_AutoPtr Query(const char *sql)
Definition: Database.cpp:383
bool RollbackTransaction()
Definition: Database.cpp:571
ACE_Based::Thread * tranThread
Definition: Database.h:163
bool CommitTransaction()
Definition: Database.cpp:551
bool PExecuteLog(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:221
bool bool PreparedExecuteLog(const char *sql, const char *format=NULL,...)
Definition: Database.cpp:242
bool PreparedExecute(const char *sql, const char *format=NULL,...)
Executes Query via Prepared Statements.
Definition: Database.cpp:1071
Database()
Definition: Database.cpp:43
UNORDERED_MAP< ACE_Based::Thread *, SqlTransaction * > TransactionQueues
Definition: Database.h:39
#define ATTR_PRINTF(F, V)
Definition: Define.h:60
~Database()
Definition: Database.cpp:56
static size_t db_count
Definition: Database.h:168
UNORDERED_MAP< std::string, PreparedStatement * > PreparedStatementsMap
Definition: Database.h:177
bool Initialize(const char *infoString)
Definition: Database.cpp:75
TransactionQueues m_tranQueues
Definition: Database.h:49
bool AsyncPQuery(Class *object, void(Class::*method)(QueryResult_AutoPtr), const char *format,...) ATTR_PRINTF(4
Definition: DatabaseImpl.h:128
void ThreadStart()
Definition: Database.cpp:191
PreparedQueryResult_AutoPtr PreparedQuery(const char *sql, const char *format=NULL,...)
Runs Query via Prepared Statements. If statement doesn&#39;t exist, it shall be created. This function blocks calling thread until query is done, if your query is result-less use PreparedExecute instead.
Definition: Database.cpp:1024
bool PExecute(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:441
bool m_logSQL
Definition: Database.h:157
void HaltDelayThread()
Definition: Database.cpp:645
ACE_Thread_Mutex mMutex
Definition: Database.h:159
ACE_UINT64 uint64
Definition: Define.h:70
void InitDelayThread()
Definition: Database.cpp:636
ACE_Thread_Mutex pMutex
Definition: Database.h:161
ACE_Refcounted_Auto_Ptr< QueryResult, ACE_Null_Mutex > QueryResult_AutoPtr
Definition: QueryResult.h:113
PreparedStatementsMap m_preparedStatements
Definition: Database.h:178
UNORDERED_MAP< ACE_Based::Thread *, SqlResultQueue * > QueryQueues
Definition: Database.h:42
bool bool bool bool bool bool bool bool DelayQueryHolder(Class *object, void(Class::*method)(QueryResult_AutoPtr, SqlQueryHolder *), SqlQueryHolder *holder)
bool DirectPExecute(const char *format,...) ATTR_PRINTF(2
Definition: Database.cpp:497
bool _ExecutePreparedStatement(PreparedStatement *ps, PreparedValues *values, va_list *args, bool resultset)
Definition: Database.cpp:826
ACE_UINT32 uint32
Definition: Define.h:71
ACE_Thread_Mutex nMutex
Definition: Database.h:160
bool _TransactionCmd(const char *sql)
Definition: Database.cpp:517
QueryQueues m_queryQueues
Definition: Database.h:50
ACE_Based::Thread * m_delayThread
Definition: Database.h:52
PreparedStatement * _GetOrMakePreparedStatement(const char *query, const char *format, PreparedValues *values)
Definition: Database.cpp:751