Planeshift
dal.h
Go to the documentation of this file.
1 /*
2  * dal.h by Stefano Angeleri
3  * Database Abstraction Layer (sqlite3)
4  *
5  * Copyright (C) 2010 Atomic Blue (info@planeshift.it, http://www.atomicblue.org)
6  *
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation (version 2 of the License)
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19 
20 #ifndef __DAL_H__
21 #define __DAL_H__
22 
23 #include <idal.h>
24 
25 #include <csutil/scf.h>
26 #include <csutil/scf_implementation.h>
27 #include <csutil/threading/thread.h>
28 
29 #include "iutil/comp.h"
30 
31 #include "net/netbase.h" // Make sure that winsock is included.
32 
33 #include <sqlite3.h>
34 
35 #include <csutil/csstring.h>
36 #include "util/stringarray.h"
37 #include "util/dbprofile.h"
38 
39 using namespace CS::Threading;
40 
41 struct iObjectRegistry;
42 
44 {
45  #ifdef USE_DELAY_QUERY
46  #define THREADED_BUFFER_SIZE 300
47  class DelayedQueryManager : public CS::Threading::Runnable
48  {
49  public:
50  DelayedQueryManager(const char *host, unsigned int port, const char *database,
51  const char *user, const char *pwd);
52 
53  virtual void Run ();
54  void Push(csString query);
55  void Stop();
56  private:
57  sqlite3* m_conn;
58  csString arr[THREADED_BUFFER_SIZE];
59  size_t start, end;
60  CS::Threading::Mutex mutex;
61  CS::Threading::RecursiveMutex mutexArray;
62  CS::Threading::Condition datacondition;
63  bool m_Close;
64  psDBProfiles profs;
65  csString m_host;
66  unsigned int m_port;
67  csString m_db;
68  csString m_user;
69  csString m_pwd;
70  };
71  #endif
72 
73  class psMysqlConnection : public scfImplementation2<psMysqlConnection, iComponent, iDataConnection>
74  {
75  protected:
76  sqlite3 *conn; //Points to mydb after a successfull connection to the db
77  csString lastquery;
78  iObjectRegistry *objectReg;
79  psDBProfiles profs;
80  csString profileDump;
81  LogCSV* logcsv;
82 
83  public:
84  psMysqlConnection(iBase *iParent);
85  virtual ~psMysqlConnection();
86 
87  bool Initialize (iObjectRegistry *objectreg);
88  bool Initialize(const char *host, unsigned int port, const char *database,
89  const char *user, const char *pwd, LogCSV* logcsv);
90  virtual bool Close();
91 
92  int IsValid(void);
93 
98  void Escape(csString& to, const char *from);
99 
100  iResultSet *Select(const char *sql,...);
101  int SelectSingleNumber(const char *sql, ...);
102  unsigned long Command(const char *sql,...);
103  unsigned long CommandPump(const char *sql,...);
104 
105  uint64 GenericInsertWithID(const char *table,const char **fieldnames,psStringArray& fieldvalues);
106  bool GenericUpdateWithID(const char *table,const char *idfield,const char *id,const char **fieldnames,psStringArray& fieldvalues);
107  bool GenericUpdateWithID(const char *table,const char *idfield,const char *id,psStringArray& fields);
108 
109  const char *GetLastError(void);
110  const char *GetLastQuery(void)
111  {
112  return lastquery;
113  };
114  uint64 GetLastInsertID();
115 
116  const char *uint64tostring(uint64 value,csString& recv);
117 
118  virtual const char* DumpProfile();
119  virtual void ResetProfile();
120 
121  iRecord* NewUpdatePreparedStatement(const char* table, const char* idfield, unsigned int count, const char* file, unsigned int line);
122  iRecord* NewInsertPreparedStatement(const char* table, unsigned int count, const char* file, unsigned int line);
123 
124  #ifdef USE_DELAY_QUERY
125  csRef<DelayedQueryManager> dqm;
126  csRef<Thread> dqmThread;
127  #endif
128  };
129 
130 
131  class psResultRow : public iResultRow
132  {
133  protected:
134  int rowNum;
135  char **rs;
136  int max;
137 
138  public:
139  psResultRow()
140  {
141  rowNum = 0;
142  rs = NULL;
143  };
144 
145  void SetMaxFields(int fields) { max = fields; };
146  void SetResultSet(void* resultsettoken);
147 
148  int Fetch(int row);
149 
150  const char *operator[](int whichfield);
151  const char *operator[](const char *fieldname);
152 
153  const char* GetString(int whichfield);
154  const char* GetString(const char *fieldname);
155 
156  int GetInt(int whichfield);
157  int GetInt(const char *fieldname);
158 
159  unsigned long GetUInt32(int whichfield);
160  unsigned long GetUInt32(const char *fieldname);
161 
162  float GetFloat(int whichfield);
163  float GetFloat(const char *fieldname);
164 
165  uint64 GetUInt64(int whichfield);
166  uint64 GetUInt64(const char *fieldname);
167 
168  uint64 stringtouint64(const char *stringbuf);
169  const char *uint64tostring(uint64 value,char *stringbuf,int buflen);
170  };
171 
172  class psResultSet : public iResultSet
173  {
174  protected:
175  char **rs;
176  unsigned long rows, fields, current;
177  psResultRow row;
178 
179  public:
180  psResultSet(char **result, int rows, int columns);
181  virtual ~psResultSet();
182 
183  void Release(void) { delete this; };
184 
185  iResultRow& operator[](unsigned long whichrow);
186 
187  unsigned long Count(void) { return rows; };
188  };
189 
190  class dbRecord : public iRecord
191  {
192  protected:
193  enum FIELDTYPE { SQL_TYPE_FLOAT, SQL_TYPE_INT, SQL_TYPE_STRING, SQL_TYPE_NULL };
194 
195  typedef struct
196  {
197  float fValue;
198  int iValue;
199  csString sValue;
200  FIELDTYPE type;
201  } StatField;
202  const char* table;
203  const char* idfield;
204 
205  sqlite3* conn;
206 
207  psStringArray command;
208  bool prepared;
209 
210  sqlite3_stmt* stmt;
211 
212  unsigned int index;
213  unsigned int count;
214 
215  // Useful for debugging
216  LogCSV* logcsv;
217  const char* file;
218  unsigned int line;
219 
220  StatField* temp;
221 
222  virtual void AddToStatement(const char* fname) = 0;
223 
224  virtual void SetID(uint32 uid) = 0;
225 
226  public:
227  dbRecord(sqlite3* db, const char* Table, const char* Idfield, unsigned int count, LogCSV* logcsv, const char* file, unsigned int line)
228  {
229  conn = db;
230  table = Table;
231  idfield = Idfield;
232  temp = new StatField[count];
233  index = 0;
234  this->count = count;
235  this->logcsv = logcsv;
236  this->file = file;
237  this->line = line;
238 
239  stmt = NULL;
240  prepared = false;
241  }
242 
243  virtual ~dbRecord()
244  {
245  sqlite3_finalize(stmt);
246  delete[] temp;
247  }
248 
249  void Reset()
250  {
251  index = 0;
252  command.Empty(); //clears the command array to avoid restarting from a wrong position.
253  if(stmt)
254  sqlite3_reset(stmt);
255  }
256 
257 
258  void AddField(const char* fname, float fValue);
259 
260  void AddField(const char* fname, int iValue);
261 
262  void AddField(const char* fname, unsigned int uiValue);
263 
264  void AddField(const char* fname, unsigned short usValue);
265 
266  void AddField(const char* fname, const char* sValue);
267 
268  void AddFieldNull(const char* fname);
269 
270  virtual bool Prepare() = 0;
271 
272  virtual bool Execute(uint32 uid);
273  };
274 
275  class dbInsert : public dbRecord
276  {
277  virtual void AddToStatement(const char* fname)
278  {
279  if(!prepared)
280  command.Push(fname);
281  }
282 
283  virtual void SetID(uint32 /*uid*/) { };
284 
285  public:
286  dbInsert(sqlite3* db, const char* Table, unsigned int count, LogCSV* logcsv, const char* file, unsigned int line)
287  : dbRecord(db, Table, "", count, logcsv, file, line) { }
288 
289  virtual bool Prepare();
290  };
291 
292  class dbUpdate : public dbRecord
293  {
294  virtual void AddToStatement(const char* fname)
295  {
296  if(!prepared)
297  command.FormatPush("%s = ?", fname);
298  }
299 
300  virtual void SetID(uint32 uid)
301  {
302  temp[index].iValue = uid;
303  temp[index].type = SQL_TYPE_INT;
304  index++;
305  }
306  public:
307  dbUpdate(sqlite3* db, const char* Table, const char* Idfield, unsigned int count, LogCSV* logcsv, const char* file, unsigned int line)
308  : dbRecord(db, Table, Idfield, count, logcsv, file, line) { }
309  virtual bool Prepare();
310 
311  };
312 } CS_PLUGIN_NAMESPACE_END(dbsqlite3)
313 #endif
314 
Definition: log.h:306
iDataConnection * db
Global connection to the Database. Set from the psDatabase class.
CS_PLUGIN_NAMESPACE_BEGIN(dbmysql)
Definition: dal.h:30
Statistics of time consumed by SQL statements.
Definition: dbprofile.h:33
void void Initialize(iObjectRegistry *object_reg)
#define max(x, y)
Definition: xdelta3.h:314
A slightly improved version of csStringArray, sporting the handy FormatPush method.
Definition: stringarray.h:33