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