DCL 3.7.4
Loading...
Searching...
No Matches
SqQuery.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <stdlib.h> // malloc
4#include <string.h> // memset
5
6#include <sqlite3.h>
7
8#include <dcl/Object.h>
9#if __DCL_HAVE_ALLOC_DEBUG
10#undef __DCL_ALLOC_LEVEL
11#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
12#endif
13
14#include <dcl/SQLCore.h>
15
16#include "SqConnection.h"
17#include "SqQuery.h"
18#include "SqField.h"
19#include "SqParam.h"
20#include "SqTypes.h"
21
22#define __TRACE_THIS 0
23#if __TRACE_THIS
24#define __DCL_TRACE0_N __DCL_TRACE0
25#define __DCL_TRACE1_N __DCL_TRACE1
26#define __DCL_TRACE2_N __DCL_TRACE2
27#define __DCL_TRACE3_N __DCL_TRACE3
28#define __DCL_TRACE4_N __DCL_TRACE4
29#define __DCL_TRACE5_N __DCL_TRACE5
30#define __DCL_TRACE6_N __DCL_TRACE6
31#else
32#define __DCL_TRACE0_N(fmt)
33#define __DCL_TRACE1_N(fmt, arg)
34#define __DCL_TRACE2_N(fmt, arg1, arg2)
35#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
36#define __DCL_TRACE4_N(fmt, arg1, arg2, arg3, arg4)
37#define __DCL_TRACE5_N(fmt, arg1, arg2, arg3, arg4, arg5)
38#define __DCL_TRACE6_N(fmt, arg1, arg2, arg3, arg4, arg5, arg6)
39#endif
40
41#undef __THIS_FILE__
42static const char_t __THIS_FILE__[] = __T("dcl/sql/SqQuery.cpp");
43
44__DCL_BEGIN_NAMESPACE
45
46#define __SET_ERROR(_error) \
47 connection()->setErrorStatus(_error, __THIS_FILE__, __LINE__)
48#define __SET_ERROR_MSG(_message) \
49 conn()->setErrorMessage(_message, __THIS_FILE__, __LINE__)
50
52
54 : Query(pConnection)
55{
56 Query::__placeholder = L'$';
57 __stmt = NULL;
58 __first = true;
59
60 __fields = NULL;
61 __params = NULL;
62}
63
65{
66#ifdef __DCL_DEBUG
67 if (!reset()) {
68 char buf[256];
69 size_t buflen = sizeof(buf) - 1;
70 bool b = conn()->__getErrorMessage(buf, &buflen);
71 buf[b ? buflen : 0] = '\0';
72 __DCL_TRACE1(L"Warning! Query reset error! %hs\n", buf);
73 }
74#else
75 (void)reset();
76#endif
77}
78
80{
81 delete this;
82}
83
85{
86 Query::__eof = true;
87 Query::__affectedRows = -1;
88
89 // clear fields
90 if (__fields) {
91 __DCL_ASSERT(Query::__fieldCount > 0);
92 delete[] __fields;
93 __fields = NULL;
94 Query::__fieldCount = 0;
95 }
96
97 // clear binds
98 if (__params) {
99 __DCL_ASSERT(Query::__paramCount > 0);
100 delete[] __params;
101 __params = NULL;
102 Query::__paramCount = 0;
103 }
104
105 bool r = true;
106 if (__stmt) {
107 int rc = sqlite3_finalize(__stmt);
108 if (rc != SQLITE_OK) {
109 __SET_ERROR_MSG(sqlite3_errmsg(conn()->connHandle()));
110 r = false;
111 }
112 }
113
114 return r;
115}
116
118 const char* _sql, size_t _sqllen, size_t _paramCount
119)
120{
121 if(!reset())
122 return false;
123
124 sqlite3_stmt* stmt = NULL;
125 const char* pzTail = NULL;
126 int rc = sqlite3_prepare_v2(conn()->connHandle(),
127 _sql, (int)_sqllen, &stmt, &pzTail);
128 if (rc != SQLITE_OK) {
129 __SET_ERROR_MSG(sqlite3_errmsg(conn()->connHandle()));
130 return false;
131 }
132
133#if defined(__DCL_DEBUG) && __TRACE_THIS
134 __DCL_TRACE1_N(L"bind_parameter_count [%d]\n",
135 sqlite3_bind_parameter_count(stmt)
136 );
137 __DCL_TRACE1_N(L"column_count [%d]\n",
138 sqlite3_column_count(stmt)
139 );
140#endif
141
143 && (Query::__paramCount == 0)
144 );
145
146 Query::__paramCount = sqlite3_bind_parameter_count(stmt);
147 if (Query::__paramCount) {
148 __params = new SqParam[Query::__paramCount];
149 if (__params == NULL) {
151 return false;
152 }
153
154 for (size_t i = 0; i < Query::__paramCount; i++) {
155 int number = (int) i + 1;
156 const char* name = sqlite3_bind_parameter_name(stmt, number);
157 if (!__params[i].init(this, number, name)) {
158 return false;
159 }
160 }
161 }
162
163 __stmt = stmt;
164 return true;
165}
166
168{
170
171 for (size_t i = 0; i < Query::__paramCount; i++) {
172 if (!(__params[i].onBeforeExecute()))
173 return false;
174 }
175
176 int rc = sqlite3_step(__stmt);
177 switch (rc) {
178 case SQLITE_ROW: {
180 (__fields == NULL)
181 && (Query::__fieldCount == 0)
182 );
183 Query::__fieldCount = sqlite3_column_count(__stmt);
184 __fields = new SqField[Query::__fieldCount];
185 if (__fields == NULL) {
187 return false;
188 }
189
190 for (size_t i = 0; i < Query::__fieldCount; i++) {
191 if (!__fields[i].init(this, (int) i))
192 return false;
193 }
194 Query::__eof = false;
195 __first = true;
196 break;
197 }
198 case SQLITE_OK:
199 case SQLITE_DONE: {
200#if SQLITE_VERSION_NUMBER >= 3037000
201 Query::__affectedRows = sqlite3_changes64(conn()->connHandle());
202#else
203 Query::__affectedRows = sqlite3_changes(conn()->connHandle());
204#endif
205 __DCL_TRACE2_N(L"__execute sqlite3_step[%d][%lld]\n",
206 rc, Query::__affectedRows
207 );
208 break;
209 }
210 default: {
211 __SET_ERROR_MSG(sqlite3_errmsg(conn()->connHandle()));
212 return false;
213 }
214 }
215
216 if (Query::__paramCount) {
217 for (size_t i = 0; i < Query::__paramCount; i++) {
218 if (!(__params[i].onAfterExecute()))
219 return false;
220 }
221 rc = sqlite3_reset(__stmt);
222 if (rc != SQLITE_OK) {
223 __SET_ERROR_MSG(sqlite3_errmsg(conn()->connHandle()));
224 return false;
225 }
226 }
227
228 return true;
229}
230
232{
233 if (__first) {
234 __first = false;
235 }
236 else {
237 int rc = sqlite3_step(__stmt);
238 __DCL_TRACE1_N(L"sqlite3_step [%d]\n", rc);
239 switch (rc) {
240 case SQLITE_ROW:
241 break;
242 case SQLITE_DONE:
243 Query::__eof = true;
244 break;
245 default: {
246 __SET_ERROR_MSG(sqlite3_errmsg(conn()->connHandle()));
247 return false;
248 }
249 }
250 }
251 return true;
252}
253
254bool SqQuery::__getField(size_t _index, SQL::Field** _fieldHandleOut)
255{
256 __DCL_ASSERT(Query::__fieldCount > 0);
257 __DCL_ASSERT((0 <= _index) && (_index < Query::__fieldCount));
258 *_fieldHandleOut = &__fields[_index];
259 return true;
260}
261
262bool SqQuery::__getParam(size_t _index, SQL::Param** _paramHandleOut)
263{
264 __DCL_ASSERT(Query::__paramCount > 0);
265 __DCL_ASSERT((0 <= _index) && (_index < Query::__paramCount));
266 *_paramHandleOut = &__params[_index];
267 return true;
268}
269
270__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:312
wchar_t char_t
Definition Config.h:247
#define __DCL_TRACE1_N(fmt, arg)
#define __DCL_TRACE2_N(fmt, arg1, arg2)
#define __SET_ERROR_MSG(_message)
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_TRACE1(fmt, arg1)
Definition Object.h:399
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:245
#define __T(str)
Definition Object.h:60
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:149
@ eOutOfMemory
Definition SQLCore.h:24
sqlite3_stmt * __stmt
Definition SqQuery.h:17
virtual bool __execute()
Definition SqQuery.cpp:167
virtual bool __getField(size_t _index, SQL::Field **_fieldHandleOut)
Definition SqQuery.cpp:254
virtual bool __fetch()
Definition SqQuery.cpp:231
virtual bool __getParam(size_t _index, SQL::Param **_paramHandleOut)
Definition SqQuery.cpp:262
bool reset()
Definition SqQuery.cpp:84
SqQuery(SqConnection *pConnection)
virtual ~SqQuery()
Definition SqQuery.cpp:64
SqField * __fields
Definition SqQuery.h:20
bool __first
Definition SqQuery.h:18
virtual void __destroy()
Definition SqQuery.cpp:79
virtual bool __prepare(const char *_sql, size_t _sqllen, size_t _paramCount)
Definition SqQuery.cpp:117
SqParam * __params
Definition SqQuery.h:21