version 0.3.0
[fms.git] / src / db / sqlite3statement.cpp
1 #include "../../include/db/sqlite3db/sqlite3statement.h"\r
2 \r
3 #ifdef XMEM\r
4         #include <xmem.h>\r
5 #endif\r
6 \r
7 namespace SQLite3DB\r
8 {\r
9 \r
10 std::map<sqlite3_stmt *, long> Statement::m_statementcount;\r
11 \r
12 Statement::Statement()\r
13 {\r
14         m_statement=NULL;\r
15         m_parametercount=0;\r
16         m_resultcolumncount=0;\r
17         m_rowreturned=false;\r
18         m_lastinsertrowid=-1;\r
19 }\r
20 \r
21 Statement::Statement(sqlite3_stmt *statement)\r
22 {\r
23         m_statement=statement;\r
24         m_parametercount=sqlite3_bind_parameter_count(m_statement);\r
25         m_resultcolumncount=sqlite3_column_count(m_statement);\r
26         m_rowreturned=false;\r
27         m_lastinsertrowid=-1;\r
28         \r
29         if(m_statement)\r
30         {\r
31                 m_statementcount[m_statement]++;\r
32         }\r
33 }\r
34 \r
35 Statement::Statement(const Statement &rhs)\r
36 {\r
37         m_statement=NULL;\r
38         m_parametercount=0;\r
39         m_resultcolumncount=0;\r
40         m_rowreturned=false;\r
41         m_lastinsertrowid=-1;\r
42         *this=rhs;\r
43 }\r
44 \r
45 Statement::~Statement()\r
46 {\r
47         \r
48         Finalize();\r
49         \r
50         /*\r
51         std::vector<char *>::iterator i;\r
52         for(i=textptrs.begin(); i!=textptrs.end(); i++)\r
53         {\r
54                 if((*i))\r
55                 {\r
56                         delete [] (*i);\r
57                 }\r
58         }\r
59         */\r
60 \r
61 }\r
62 \r
63 const bool Statement::Bind(const int column)\r
64 {\r
65         if(Valid() && column>=0 && column<m_parametercount)\r
66         {\r
67                 //ZThread::Guard<ZThread::Mutex> g(DB::instance()->m_mutex);\r
68                 //PThread::Guard g(DB::Instance()->m_mutex);\r
69                 if(sqlite3_bind_null(m_statement,column+1)==SQLITE_OK)\r
70                 {\r
71                         return true;\r
72                 }\r
73                 else\r
74                 {\r
75                         return false;\r
76                 }\r
77         }\r
78         else\r
79         {\r
80                 return false;\r
81         }\r
82 }\r
83 \r
84 const bool Statement::Bind(const int column, const int value)\r
85 {\r
86         if(Valid() && column>=0 && column<m_parametercount)\r
87         {\r
88                 //ZThread::Guard<ZThread::Mutex> g(DB::instance()->m_mutex);\r
89                 //PThread::Guard g(DB::Instance()->m_mutex);\r
90                 if(sqlite3_bind_int(m_statement,column+1,value)==SQLITE_OK)\r
91                 {\r
92                         return true;\r
93                 }\r
94                 else\r
95                 {\r
96                         return false;\r
97                 }\r
98         }\r
99         else\r
100         {\r
101                 return false;\r
102         }\r
103 }\r
104 \r
105 const bool Statement::Bind(const int column, const double value)\r
106 {\r
107         if(Valid() && column>=0 && column<m_parametercount)\r
108         {\r
109                 //ZThread::Guard<ZThread::Mutex> g(DB::instance()->m_mutex);\r
110                 //PThread::Guard g(DB::Instance()->m_mutex);\r
111                 if(sqlite3_bind_double(m_statement,column+1,value)==SQLITE_OK)\r
112                 {\r
113                         return true;\r
114                 }\r
115                 else\r
116                 {\r
117                         return false;\r
118                 }\r
119         }\r
120         else\r
121         {\r
122                 return false;\r
123         }       \r
124 }\r
125 \r
126 const bool Statement::Bind(const int column, const std::string &value)\r
127 {\r
128         if(Valid() && column>=0 && column<m_parametercount)\r
129         {\r
130                 //ZThread::Guard<ZThread::Mutex> g(DB::instance()->m_mutex);\r
131                 //PThread::Guard g(DB::Instance()->m_mutex);\r
132                 if(sqlite3_bind_text(m_statement,column+1,value.c_str(),value.size(),SQLITE_TRANSIENT)==SQLITE_OK)\r
133                 {\r
134                         return true;\r
135                 }\r
136                 else\r
137                 {\r
138                         return false;\r
139                 }\r
140         }\r
141         else\r
142         {\r
143                 return false;\r
144         }       \r
145 }\r
146 \r
147 const bool Statement::Bind(const int column, const void *data, const int length)\r
148 {\r
149         if(Valid() && column>=0 && column<m_parametercount)\r
150         {\r
151                 //ZThread::Guard<ZThread::Mutex> g(DB::instance()->m_mutex);\r
152                 //PThread::Guard g(DB::Instance()->m_mutex);\r
153                 if(sqlite3_bind_blob(m_statement,column+1,data,length,SQLITE_TRANSIENT)==SQLITE_OK)\r
154                 {\r
155                         return true;\r
156                 }\r
157                 else\r
158                 {\r
159                         return false;\r
160                 }\r
161         }\r
162         else\r
163         {\r
164                 return false;\r
165         }\r
166 }\r
167 \r
168 void Statement::Finalize()\r
169 {\r
170         if(m_statement)\r
171         {\r
172                 Poco::ScopedLock<Poco::FastMutex> g(DB::Instance()->m_mutex);\r
173                 m_statementcount[m_statement]--;\r
174                 if(m_statementcount[m_statement]<=0)\r
175                 {\r
176                         m_statementcount.erase(m_statement);\r
177                         sqlite3_finalize(m_statement);\r
178                 }\r
179                 m_statement=NULL;\r
180         }\r
181 }\r
182 \r
183 Statement &Statement::operator=(const Statement &rhs)\r
184 {\r
185         if(&rhs!=this)\r
186         {\r
187                 Finalize();\r
188 \r
189                 m_statement=rhs.m_statement;\r
190                 m_parametercount=rhs.m_parametercount;\r
191                 m_resultcolumncount=rhs.m_resultcolumncount;\r
192                 m_rowreturned=rhs.m_rowreturned;\r
193 \r
194                 if(m_statement)\r
195                 {\r
196                         Poco::ScopedLock<Poco::FastMutex> g(DB::Instance()->m_mutex);\r
197                         m_statementcount[m_statement]++;\r
198                 }\r
199         }\r
200         return *this;\r
201 }\r
202 \r
203 const bool Statement::Reset()\r
204 {\r
205         if(Valid())\r
206         {\r
207                 Poco::ScopedLock<Poco::FastMutex> g(DB::Instance()->m_mutex);\r
208                 if(sqlite3_reset(m_statement)==SQLITE_OK)\r
209                 {\r
210                         return true;\r
211                 }\r
212                 else\r
213                 {\r
214                         return false;\r
215                 }\r
216         }\r
217         else\r
218         {\r
219                 return false;\r
220         }\r
221 }\r
222 \r
223 const bool Statement::ResultBlob(const int column, void *data, int &length)\r
224 {\r
225         if(Valid() && column>=0 && column<m_resultcolumncount)\r
226         {\r
227                 int bloblength=sqlite3_column_bytes(m_statement,column);\r
228                 if(bloblength>length)\r
229                 {\r
230                         bloblength=length;\r
231                 }\r
232                 if(bloblength<length)\r
233                 {\r
234                         length=bloblength;\r
235                 }\r
236                 const void *blobptr=sqlite3_column_blob(m_statement,column);\r
237                 if(blobptr)\r
238                 {\r
239                         std::copy((unsigned char *)blobptr,(unsigned char *)blobptr+bloblength,(unsigned char *)data);\r
240                 }\r
241                 else\r
242                 {\r
243                         length=0;\r
244                 }\r
245                 return true;\r
246         }\r
247         else\r
248         {\r
249                 return false;\r
250         }\r
251 }\r
252 \r
253 const bool Statement::ResultDouble(const int column, double &result)\r
254 {\r
255         if(Valid() && column>=0 && column<m_resultcolumncount)\r
256         {\r
257                 result=sqlite3_column_double(m_statement,column);\r
258                 return true;\r
259         }\r
260         else\r
261         {\r
262                 return false;\r
263         }\r
264 }\r
265 \r
266 const bool Statement::ResultInt(const int column, int &result)\r
267 {\r
268         if(Valid() && column>=0 && column<m_resultcolumncount)\r
269         {\r
270                 result=sqlite3_column_int(m_statement,column);\r
271                 return true;\r
272         }\r
273         else\r
274         {\r
275                 return false;\r
276         }\r
277 }\r
278 \r
279 const bool Statement::ResultNull(const int column)\r
280 {\r
281         if(Valid() && column>=0 && column<m_resultcolumncount)\r
282         {\r
283                 if(sqlite3_column_type(m_statement,column)==SQLITE_NULL)\r
284                 {\r
285                         return true;\r
286                 }\r
287                 else\r
288                 {\r
289                         return false;\r
290                 }\r
291         }\r
292         else\r
293         {\r
294                 return false;\r
295         }\r
296 }\r
297 \r
298 const bool Statement::ResultText(const int column, std::string &result)\r
299 {\r
300         if(Valid() && column>=0 && column<m_resultcolumncount)\r
301         {\r
302                 const unsigned char *cresult=sqlite3_column_text(m_statement,column);\r
303                 if(cresult)\r
304                 {\r
305                         result=(char *)cresult;\r
306                 }\r
307                 else\r
308                 {\r
309                         result="";\r
310                 }\r
311                 return true;\r
312         }\r
313         else\r
314         {\r
315                 return false;\r
316         }\r
317 }\r
318 \r
319 const bool Statement::Step(const bool saveinsertrowid)\r
320 {\r
321         m_rowreturned=false;\r
322         if(Valid())\r
323         {\r
324                 Poco::ScopedLock<Poco::FastMutex> g(DB::Instance()->m_mutex);\r
325                 int result=sqlite3_step(m_statement);\r
326                 if(result==SQLITE_OK || result==SQLITE_ROW || result==SQLITE_DONE)\r
327                 {\r
328                         if(result==SQLITE_ROW)\r
329                         {\r
330                                 m_rowreturned=true;\r
331                         }\r
332                         if(saveinsertrowid)\r
333                         {\r
334                                 m_lastinsertrowid=sqlite3_last_insert_rowid(DB::Instance()->GetDB());\r
335                         }\r
336                         return true;\r
337                 }\r
338                 else\r
339                 {\r
340                         return false;\r
341                 }\r
342         }\r
343         else\r
344         {\r
345                 return false;\r
346         }\r
347 }\r
348 \r
349 const bool Statement::Valid()\r
350 {\r
351         Poco::ScopedLock<Poco::FastMutex> g(DB::Instance()->m_mutex);\r
352         return m_statement ? true : false ;\r
353 }\r
354 \r
355 }       // namespace\r