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