DCL 3.7.4
Loading...
Searching...
No Matches
SqParam.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <sqlite3.h>
4
5#include <dcl/Object.h>
6#if __DCL_HAVE_ALLOC_DEBUG
7#undef __DCL_ALLOC_LEVEL
8#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
9#endif
10
11#include <dcl/DateTime.h>
12#include <dcl/InputStream.h>
13#include <dcl/Files.h>
14#include <dcl/SQLCore.h>
15
16#include "SqConnection.h"
17#include "SqQuery.h"
18#include "SqParam.h"
19#include "SqTypes.h"
20
21#define __TRACE_THIS 0
22#if __TRACE_THIS
23#define __DCL_TRACE0_N __DCL_TRACE0
24#define __DCL_TRACE1_N __DCL_TRACE1
25#define __DCL_TRACE2_N __DCL_TRACE2
26#define __DCL_TRACE3_N __DCL_TRACE3
27#define __DCL_TRACE4_N __DCL_TRACE4
28#else
29#define __DCL_TRACE0_N(fmt)
30#define __DCL_TRACE1_N(fmt, arg)
31#define __DCL_TRACE2_N(fmt, arg1, arg2)
32#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
33#define __DCL_TRACE4_N(fmt, arg1, arg2, arg3, arg4)
34#endif
35
36#undef __THIS_FILE__
37static const char_t __THIS_FILE__[] = __T("dcl/sql/SqParam.cpp");
38
39__DCL_BEGIN_NAMESPACE
40
41#define __SET_ERROR(_error) \
42 connection()->setErrorStatus(_error, __THIS_FILE__, __LINE__)
43#define __SET_ERROR_MSG(_message) \
44 conn()->setErrorMessage(_message, __THIS_FILE__, __LINE__)
45
47
48SqParam::SqParam() : Param(NULL)
49{
50 __number = -1;
51 __type = SQLITE_NULL;
52}
53
57
58bool SqParam::init(SQL::Query* _queryHandle, int _number, const char* _name)
59{
60 __DCL_ASSERT(Param::__queryHandle == NULL);
61 __DCL_ASSERT(_queryHandle != NULL);
62
63 Param::__queryHandle = _queryHandle;
64
65 __number = _number;
66 __name.assign(_name);
67
68 return true;
69}
70
72{
73 int rc = SQLITE_OK;
74 switch (__type) {
75 case SQLITE_INTEGER: {
76 rc = sqlite3_bind_int64(query()->stmt(), __number, __data.n);
77 break;
78 }
79 case SQLITE_FLOAT: {
80 rc = sqlite3_bind_double(query()->stmt(), __number, __data.d);
81 break;
82 }
83 case SQLITE_TEXT: {
84 rc = sqlite3_bind_text64(query()->stmt(), __number, (const char*)__data.p,
85 __size, NULL, SQLITE_UTF8);
86 break;
87 }
88 case SQLITE_BLOB: {
89 rc = sqlite3_bind_blob(query()->stmt(), __number, __data.p, (int)__size, NULL);
90 break;
91 }
92 case SQLITE_NULL:
93 default: {
94 rc = sqlite3_bind_null(query()->stmt(), __number);
95 }
96 }
97
98 if (rc != SQLITE_OK) {
99 ByteStringBuilder sb = sqlite3_errmsg(conn()->connHandle());
100 sb.append(' ').append(__name);
101 __SET_ERROR_MSG(sb.toByteString());
102 return false;
103 }
104
105 return true;
106}
108{
109 setNull();
110 return true;
111}
112
113const wchar_t* SqParam::serverDataTypeName() const
114{
115 return __dataTypeName(__type);
116}
117
119{
120 Param::__dataType = SQL::typeUnknown;
121 __type = SQLITE_NULL;
122
123}
124
125static inline int __ABS(int _n)
126{
127 return _n < 0 ? -_n : _n;
128}
129
131 _CONST void* _val,
132 size_t _size,
133 SQL::DataType _valType,
134 SQL::DataType _sqlType
135)
136{
137 bool r = false;
138 switch(_valType) {
139 case SQL::typeInteger:
140 r = setInteger(_val, _size);
141 break;
143 r = setUInteger(_val, _size);
144 break;
145 case SQL::typeFloat:
146 r = setFloat(_val, _size);
147 break;
148 case SQL::typeDate:
149 r = setDate((const SQL::Date*)_val, _size);
150 break;
151 case SQL::typeTime:
152 r = setTime((const SQL::Time*)_val, _size);
153 break;
155 r = setTimeStamp((const SQL::TimeStamp*)_val, _size);
156 break;
158 r = setInterval((const SQL::Interval*)_val, _size);
159 break;
160 case SQL::typeText:
161 case SQL::typeBinary:
163 r = setBytes(_val, _size, _valType, _sqlType);
164 break;
165 default: {
167 return false;
168 }
169 }
170
171 if (r) {
172 Param::__dataType = _sqlType;
173 }
174 return r;
175}
176
177bool SqParam::setInteger(const void* _val, size_t _size)
178{
179 switch (_size) {
180 case sizeof(int8_t) : {
181 __data.n = *(int8_t*)_val;
182 break;
183 }
184 case sizeof(int16_t) : {
185 __data.n = *(int16_t*)_val;
186 break;
187 }
188 case sizeof(int32_t) : {
189 __data.n = *(int32_t*)_val;
190 break;
191 }
192 case sizeof(int64_t) : {
193 __data.n = *(int64_t*)_val;
194 break;
195 }
196 default: {
198 return false;
199 }
200 }
201
202 __type = SQLITE_INTEGER;
203 return true;
204}
205
206bool SqParam::setUInteger(const void* _val, size_t _size)
207{
208 switch (_size) {
209 case sizeof(uint8_t) : {
210 __data.n = *(uint8_t*)_val;
211 break;
212 }
213 case sizeof(uint16_t) : {
214 __data.n = *(uint16_t*)_val;
215 break;
216 }
217 case sizeof(uint32_t) : {
218 __data.n = *(uint32_t*)_val;
219 break;
220 }
221 case sizeof(uint64_t) : {
222 __data.n = *(uint64_t*)_val;
223 break;
224 }
225 default: {
227 return false;
228 }
229 }
230
231 __type = SQLITE_INTEGER;
232 return true;
233}
234
235bool SqParam::setFloat(const void* _val, size_t _size)
236{
237 switch (_size) {
238 case sizeof(float) : {
239 __data.d = *(float*)_val;
240 break;
241 }
242 case sizeof(double) : {
243 __data.d = *(double*)_val;
244 break;
245 }
246 default: {
248 return false;
249 }
250 }
251
252 __type = SQLITE_FLOAT;
253 return true;
254}
255
256bool SqParam::setDate(const SQL::Date* _val, size_t _size)
257{
258 if (_size != sizeof(SQL::Date)) {
260 return false;
261 }
262
263 const SQL::Date* val = (const SQL::Date*)_val;
264 ByteStringBuilder sb;
265 sb.format(
266 "%04d-%02d-%02d",
267 __ABS(val->year),
268 val->month,
269 val->day
270 );
271 if (val->year < 0) {
272 sb += " BC";
273 }
274 __bytes = sb.toByteString();
275
276 __data.p = (void*) __bytes.data();
277 __size = __bytes.length();
278
279 __type = SQLITE_TEXT;
280 return true;
281}
282
283bool SqParam::setTime(const SQL::Time* _val, size_t _size)
284{
285 if (_size != sizeof(SQL::Time)) {
287 return false;
288 }
289
290 const SQL::Time* val = (const SQL::Time*)_val;
291 if (val->tzoff == INT16_MIN) {
292 __bytes = ByteString::format(
293 "%02d:%02d:%02d.%06d",
294 val->hour,
295 val->min,
296 val->sec,
297 val->frac / 1000
298 );
299 }
300 else {
301 __bytes = ByteString::format(
302 "%02d:%02d:%02d.%06d %+03d:%02d",
303 val->hour,
304 val->min,
305 val->sec,
306 val->frac / 1000,
307 val->tzoff / 60,
308 __ABS(val->tzoff % 60)
309 );
310 }
311
312 __data.p = (void*)__bytes.data();
313 __size = __bytes.length();
314
315 __type = SQLITE_TEXT;
316 return true;
317}
318
319bool SqParam::setTimeStamp(const SQL::TimeStamp* _val, size_t _size)
320{
321 if (_size != sizeof(SQL::TimeStamp)) {
323 return false;
324 }
325
326 const SQL::TimeStamp* val = (const SQL::TimeStamp*)_val;
327 ByteStringBuilder sb;
328 if (val->tzoff == INT16_MIN) {
329 sb.format(
330 "%04d-%02d-%02d %02d:%02d:%02d.%06d",
331 __ABS(val->year),
332 val->month,
333 val->day,
334 val->hour,
335 val->min,
336 val->sec,
337 val->frac / 1000
338 );
339 }
340 else {
341 sb.format(
342 "%04d-%02d-%02d %02d:%02d:%02d.%06d %+03d:%02d",
343 __ABS(val->year),
344 val->month,
345 val->day,
346 val->hour,
347 val->min,
348 val->sec,
349 val->frac / 1000,
350 val->tzoff / 60,
351 __ABS(val->tzoff % 60)
352 );
353 }
354 if (val->year < 0) {
355 sb += " BC";
356 }
357 __bytes = sb.toByteString();
358
359 __data.p = (void*)__bytes.data();
360 __size = __bytes.length();
361
362 __type = SQLITE_TEXT;
363 return true;
364}
365
366bool SqParam::setInterval(const SQL::Interval* _val, size_t _size)
367{
368 if (_size != sizeof(SQL::Interval)) {
370 return false;
371 }
372
373 const SQL::Interval* val = (const SQL::Interval*)_val;
374 if (val->secs || val->fracs >= 0) {
375 __bytes = ByteString::format(
376 "P%dY%dM%dDT%dH%dM%d.%dS",
377 val->years,
378 val->months,
379 val->days,
380 val->hours,
381 val->mins,
382 val->secs,
383 __ABS(val->fracs)
384 );
385 }
386 else {
387 __bytes = ByteString::format(
388 "P%dY%dM%dDT%dH%dM%-0.%dS",
389 val->years,
390 val->months,
391 val->days,
392 val->hours,
393 val->mins,
394 __ABS(val->fracs)
395 );
396 }
397
398 __data.p = (void*)__bytes.data();
399 __size = __bytes.length();
400
401 __type = SQLITE_TEXT;
402 return true;
403}
404
406 _CONST void* _val,
407 size_t _size,
408 SQL::DataType _valType,
409 SQL::DataType _sqlType
410)
411{
412 const char* val = (const char*)_val;
413 size_t size = _size;
414 SQL::DataType valType = _valType;
415 if (_valType == SQL::typeInputStream) {
416 try {
417 __bytes = Files::readBytes(*(InputStream*)_val, _size);
418 val = __bytes;
419 size = __bytes.length();
420 }
421 catch (IOException* _e) {
422 __SET_ERROR_MSG(UTF8Encoder::encode(_e->toStringAll()));
423 _e->destroy();
424 return false;
425 }
426 if (_sqlType == SQL::typeText
427 || _sqlType == SQL::typeLongText
428 || _sqlType == SQL::typeClob) {
429 valType = SQL::typeText;
430 }
431 else {
432 valType = SQL::typeBinary;
433 }
434 }
435
436 __data.p = (const void*)val;
437 __size = size;
438
439 __type = valType == SQL::typeText ? SQLITE_TEXT : SQLITE_BLOB;
440 return true;
441}
442
443__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 _CONST
Definition Config.h:325
#define INT16_MIN
Definition Config.h:284
#define __SET_ERROR_MSG(_message)
const wchar_t * __dataTypeName(const ifx_sqlvar_t *_sqlvar)
Definition IFXField.cpp:304
IOException *size_t r
Definition MediaInfo.cpp:82
#define __ABS(n)
Definition MyParam.cpp:145
#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
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
static ByteString readBytes(InputStream &_input, size_t _n=(size_t) -1) __DCL_THROWS1(IOException *)
Definition Files.cpp:397
DataType
Definition SQLCore.h:59
@ typeBinary
Definition SQLCore.h:74
@ typeClob
Definition SQLCore.h:77
@ typeTime
Definition SQLCore.h:66
@ typeUInteger
Definition SQLCore.h:62
@ typeUnknown
Definition SQLCore.h:60
@ typeTimeStamp
Definition SQLCore.h:68
@ typeInputStream
Definition SQLCore.h:81
@ typeInterval
Definition SQLCore.h:70
@ typeDate
Definition SQLCore.h:65
@ typeText
Definition SQLCore.h:73
@ typeFloat
Definition SQLCore.h:63
@ typeInteger
Definition SQLCore.h:61
@ typeLongText
Definition SQLCore.h:75
@ eNotSupportDataType
Definition SQLCore.h:48
@ eInvalidDataSize
Definition SQLCore.h:55
bool onBeforeExecute()
Definition SqParam.cpp:71
bool setUInteger(const void *_val, size_t _size)
Definition SqParam.cpp:206
bool setDate(const SQL::Date *_val, size_t _size)
Definition SqParam.cpp:256
bool init(SQL::Query *_query, int _number, const char *_name)
Definition SqParam.cpp:58
bool setFloat(const void *_val, size_t _size)
Definition SqParam.cpp:235
bool setTime(const SQL::Time *_val, size_t _size)
Definition SqParam.cpp:283
bool onAfterExecute()
Definition SqParam.cpp:107
virtual void setNull()
Definition SqParam.cpp:118
virtual ~SqParam()
Definition SqParam.cpp:54
virtual bool __setData(_CONST void *_val, size_t _size, SQL::DataType _valType, SQL::DataType _sqlType)
Definition SqParam.cpp:130
bool setBytes(_CONST void *_val, size_t _size, SQL::DataType _valType, SQL::DataType _sqlType)
Definition SqParam.cpp:405
SqConnection * conn() const
Definition SqParam.h:67
virtual const wchar_t * serverDataTypeName() const
Definition SqParam.cpp:113
bool setInteger(const void *_val, size_t _size)
Definition SqParam.cpp:177
bool setTimeStamp(const SQL::TimeStamp *_val, size_t _size)
Definition SqParam.cpp:319
SqQuery * query() const
Definition SqParam.h:62
bool setInterval(const SQL::Interval *_val, size_t _size)
Definition SqParam.cpp:366
int16_t year
Definition SQLCore.h:96
uint8_t month
Definition SQLCore.h:97
uint8_t day
Definition SQLCore.h:98
int32_t years
Definition SQLCore.h:126
int32_t days
Definition SQLCore.h:128
int8_t hours
Definition SQLCore.h:129
int8_t mins
Definition SQLCore.h:130
int32_t fracs
Definition SQLCore.h:132
int8_t months
Definition SQLCore.h:127
int8_t secs
Definition SQLCore.h:131
uint8_t hour
Definition SQLCore.h:103
uint8_t sec
Definition SQLCore.h:105
uint32_t frac
Definition SQLCore.h:106
uint8_t min
Definition SQLCore.h:104
int16_t tzoff
Definition SQLCore.h:107
uint32_t frac
Definition SQLCore.h:118
int16_t tzoff
Definition SQLCore.h:119
uint8_t min
Definition SQLCore.h:116
uint8_t sec
Definition SQLCore.h:117
uint8_t hour
Definition SQLCore.h:115
uint8_t day
Definition SQLCore.h:114
int16_t year
Definition SQLCore.h:112
uint8_t month
Definition SQLCore.h:113