Planeshift
dal.h
Go to the documentation of this file.
1 /*
2  * dal.h by Stefano Angeleri
3  * Database Abstraction Layer (postgresql)
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 <libpq-fe.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  csString arr[THREADED_BUFFER_SIZE];
58  size_t start, end;
59  CS::Threading::Mutex mutex;
60  CS::Threading::RecursiveMutex mutexArray;
61  CS::Threading::Condition datacondition;
62  bool m_Close;
63  psDBProfiles profs;
64  csString m_host;
65  unsigned int m_port;
66  csString m_db;
67  csString m_user;
68  csString m_pwd;
69  };
70  #endif
71 
72  class psMysqlConnection : public scfImplementation2<psMysqlConnection, iComponent, iDataConnection>
73  {
74  protected:
75  PGconn* conn; //Points to mydb after a successfull connection to the db
76  uint64 lastRow;
77  csString lastquery;
78  int stmtNum;
79  iObjectRegistry *objectReg;
80  psDBProfiles profs;
81  csString profileDump;
82  LogCSV* logcsv;
83 
84  public:
85  psMysqlConnection(iBase *iParent);
86  virtual ~psMysqlConnection();
87 
88  bool Initialize (iObjectRegistry *objectreg);
89  bool Initialize(const char *host, unsigned int port, const char *database,
90  const char *user, const char *pwd, LogCSV* logcsv);
91  virtual bool Close();
92 
93  int IsValid(void);
94 
99  void Escape(csString& to, const char *from);
100 
101  iResultSet *Select(const char *sql,...);
102  int SelectSingleNumber(const char *sql, ...);
103  unsigned long Command(const char *sql,...);
104  unsigned long CommandPump(const char *sql,...);
105 
106  uint64 GenericInsertWithID(const char *table,const char **fieldnames,psStringArray& fieldvalues);
107  bool GenericUpdateWithID(const char *table,const char *idfield,const char *id,const char **fieldnames,psStringArray& fieldvalues);
108  bool GenericUpdateWithID(const char *table,const char *idfield,const char *id,psStringArray& fields);
109 
110  const char *GetLastError(void);
111  const char *GetLastQuery(void)
112  {
113  return lastquery;
114  };
115  uint64 GetLastInsertID();
116 
117  const char *uint64tostring(uint64 value,csString& recv);
118 
119  virtual const char* DumpProfile();
120  virtual void ResetProfile();
121 
122  iRecord* NewUpdatePreparedStatement(const char* table, const char* idfield, unsigned int count, const char* file, unsigned int line);
123  iRecord* NewInsertPreparedStatement(const char* table, unsigned int count, const char* file, unsigned int line);
124 
125  #ifdef USE_DELAY_QUERY
126  csRef<DelayedQueryManager> dqm;
127  csRef<Thread> dqmThread;
128  #endif
129  };
130 
131 
132  class psResultRow : public iResultRow
133  {
134  protected:
135  int rowNum;
136  PGresult *rs;
137  int max;
138 
139  public:
140  psResultRow()
141  {
142  rowNum = 0;
143  rs = NULL;
144  };
145 
146  void SetMaxFields(int fields) { max = fields; };
147  void SetResultSet(void* resultsettoken);
148 
149  int Fetch(int row);
150 
151  const char *operator[](int whichfield);
152  const char *operator[](const char *fieldname);
153 
154  const char* GetString(int whichfield);
155  const char* GetString(const char *fieldname);
156 
157  int GetInt(int whichfield);
158  int GetInt(const char *fieldname);
159 
160  unsigned long GetUInt32(int whichfield);
161  unsigned long GetUInt32(const char *fieldname);
162 
163  float GetFloat(int whichfield);
164  float GetFloat(const char *fieldname);
165 
166  uint64 GetUInt64(int whichfield);
167  uint64 GetUInt64(const char *fieldname);
168 
169  uint64 stringtouint64(const char *stringbuf);
170  const char *uint64tostring(uint64 value,char *stringbuf,int buflen);
171  };
172 
173  class psResultSet : public iResultSet
174  {
175  protected:
176  PGresult *rs;
177  unsigned long rows, fields, current;
178  psResultRow row;
179 
180  public:
181  psResultSet(PGresult *res);
182  virtual ~psResultSet();
183 
184  void Release(void) { delete this; };
185 
186  iResultRow& operator[](unsigned long whichrow);
187 
188  unsigned long Count(void) { return rows; };
189  };
190 
191  class dbRecord : public iRecord
192  {
193  protected:
194  enum FIELDTYPE { SQL_TYPE_FLOAT, SQL_TYPE_INT, SQL_TYPE_STRING, SQL_TYPE_NULL };
195 
196  typedef struct
197  {
198  float fValue;
199  int iValue;
200  csString sValue;
201  FIELDTYPE type;
202  } StatField;
203  const char* table;
204  const char* idfield;
205 
206  PGconn *conn;
207  int *stmtNum;
208 
209  psStringArray command;
210  bool prepared;
211 
212  csString stmt;
213 
214  unsigned int index;
215  unsigned int count;
216 
217  // Useful for debugging
218  LogCSV* logcsv;
219  const char* file;
220  unsigned int line;
221 
222  StatField* temp;
223 
224  virtual void AddToStatement(const char* fname) = 0;
225 
226  virtual void SetID(uint32 uid) = 0;
227 
228  public:
229  dbRecord(PGconn* db, int *StmtNum, const char* Table, const char* Idfield, unsigned int count, LogCSV* logcsv, const char* file, unsigned int line)
230  {
231  conn = db;
232  table = Table;
233  idfield = Idfield;
234  temp = new StatField[count];
235  index = 0;
236  this->count = count;
237  this->logcsv = logcsv;
238  this->file = file;
239  this->line = line;
240  stmtNum = StmtNum;
241  prepared = false;
242  }
243 
244  virtual ~dbRecord()
245  {
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  }
254 
255  void AddField(const char* fname, float fValue);
256 
257  void AddField(const char* fname, int iValue);
258 
259  void AddField(const char* fname, unsigned int uiValue);
260 
261  void AddField(const char* fname, unsigned short usValue);
262 
263  void AddField(const char* fname, const char* sValue);
264 
265  void AddFieldNull(const char* fname);
266 
267  virtual bool Prepare() = 0;
268 
269  virtual bool Execute(uint32 uid);
270  };
271 
272  class dbInsert : public dbRecord
273  {
274  virtual void AddToStatement(const char* fname)
275  {
276  if(!prepared)
277  command.Push(fname);
278  }
279 
280  virtual void SetID(uint32 /*uid*/) {};
281 
282  public:
283  dbInsert(PGconn* db, int *StmtNum, const char* Table, unsigned int count, LogCSV* logcsv, const char* file, unsigned int line)
284  : dbRecord(db, StmtNum, Table, "", count, logcsv, file, line) { }
285 
286  virtual bool Prepare();
287  };
288 
289  class dbUpdate : public dbRecord
290  {
291  virtual void AddToStatement(const char* fname)
292  {
293  if(!prepared)
294  command.FormatPush("%s = $", fname);
295  }
296 
297  virtual void SetID(uint32 uid)
298  {
299  temp[index].iValue = uid;
300  temp[index].type = SQL_TYPE_INT;
301  index++;
302  }
303  public:
304  dbUpdate(PGconn* db, int *StmtNum, const char* Table, const char* Idfield, unsigned int count, LogCSV* logcsv, const char* file, unsigned int line)
305  : dbRecord(db, StmtNum, Table, Idfield, count, logcsv, file, line) { }
306  virtual bool Prepare();
307 
308  };
309 }
310 CS_PLUGIN_NAMESPACE_END(dbpostgresql)
311 
312 #endif
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