DCL 3.7.4
Loading...
Searching...
No Matches
MyParam.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <string.h> // memset
4
5#include <mysql.h>
6
7#include <dcl/Object.h>
8#if __DCL_HAVE_ALLOC_DEBUG
9#undef __DCL_ALLOC_LEVEL
10#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
11#endif
12
13#include <dcl/size_t.h>
14#include <dcl/SQLCore.h>
15#include <dcl/Numeric.h>
16#include <dcl/InputStream.h>
17#include <dcl/Charset.h>
18
19#include "MyConnection.h"
20#include "MyQuery.h"
21#include "MyParam.h"
22
23#define __TRACE_THIS 0
24#if __TRACE_THIS
25#define __DCL_TRACE0_N __DCL_TRACE0
26#define __DCL_TRACE1_N __DCL_TRACE1
27#define __DCL_TRACE2_N __DCL_TRACE2
28#define __DCL_TRACE3_N __DCL_TRACE3
29#define __DCL_TRACE4_N __DCL_TRACE4
30#else
31#define __DCL_TRACE0_N(fmt)
32#define __DCL_TRACE1_N(fmt, arg)
33#define __DCL_TRACE2_N(fmt, arg1, arg2)
34#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
35#define __DCL_TRACE4_N(fmt, arg1, arg2, arg3, arg4)
36#endif
37
38#undef __THIS_FILE__
39static const char_t __THIS_FILE__[] = __T("dcl/sql/MyParam.cpp");
40
41__DCL_BEGIN_NAMESPACE
42
43#define __SET_ERROR(_error) \
44 connection()->setErrorStatus(_error, __THIS_FILE__, __LINE__)
45#define __SET_ERROR_HANDLE(_error) \
46 conn()->setErrorHandle(_error, __THIS_FILE__, __LINE__)
47#define __SET_ERROR_MSG(_msg) \
48 conn()->setErrorMessage(_msg, __THIS_FILE__, __LINE__)
49
51
52MyParam::MyParam() : Param(NULL)
53{
54 __index = 0;
55 __bind = NULL;
56 __input = NULL;
57}
58
60{
61
62}
63
64bool MyParam::init(SQL::Query* _query, unsigned int _index, MYSQL_BIND* _bind)
65{
66 __DCL_ASSERT(Param::__queryHandle == NULL);
67 Param::__queryHandle = _query;
68 __index = _index;
69 __bind = _bind;
70
71 return true;
72}
73
75{
76 if (__input) {
77 try {
78 char buf[4096];
79 size_t total = 0;
80 for (; ; ) {
81 size_t n = __MIN(__size - total, sizeof(buf));
82 if (n && (n = __input->read(buf, n))) {
83 __DCL_TRACE1_N(L"mysql_stmt_send_long_data [%u]\n", n);
84 if (mysql_stmt_send_long_data(query()->stmtHandle(),
85 __index, buf, (unsigned int) n)) {
86 __SET_ERROR_MSG(ByteString::format("(%u) %hs",
87 mysql_stmt_errno(query()->stmtHandle()),
88 mysql_stmt_error(query()->stmtHandle()))
89 );
90 return false;
91 }
92 }
93 else {
94 break;
95 }
96 }
97 }
98 catch (IOException* e) {
99 __SET_ERROR_MSG(UTF8Encoder::encode(e->toStringAll()));
100 e->destroy();
101 return false;
102 }
103 }
104 return true;
105}
106
108{
109 setNull();
110}
111
112// in MyField.cpp
113const wchar_t* __dataTypeName(enum_field_types _type, unsigned int _flags);
114
115const wchar_t* MyParam::serverDataTypeName() const
116{
117 unsigned int flags = 0;
118 switch (SQL::Param::__dataType) {
119 case SQL::typeUInteger :
120 flags = UNSIGNED_FLAG;
121 break;
122 case SQL::typeBinary :
124 case SQL::typeBlob :
125 flags = BINARY_FLAG;
126 break;
127 default:
128 ;
129 }
130
131 return __dataTypeName(__bind->buffer_type, flags);
132}
133
135{
136 Param::__dataType = SQL::typeUnknown;
137 __bind->buffer_length = 0;
138 __bind->buffer = NULL;
139 __bind->length_value = 0;
140 __bind->is_null_value = 1;
141 __input = NULL;
142 __size = 0;
143}
144
145#define __ABS(n) (n < 0) ? -n : n
146
148 _CONST void* _val,
149 size_t _size,
150 SQL::DataType _valType,
151 SQL::DataType _sqlType
152)
153{
154 switch(_valType) {
155 case SQL::typeInteger: {
156 switch (_size) {
157 case sizeof(int8_t) : {
158 __data.i32 = (int32_t) * (int8_t*)_val;
159 __bind->buffer_type = MYSQL_TYPE_LONG;
160 __bind->buffer_length = sizeof(int32_t);
161 __bind->buffer = &__data;
162 break;
163 }
164 case sizeof(int16_t) : {
165 __data.i32 = (int32_t) * (int16_t*)_val;
166 __bind->buffer_type = MYSQL_TYPE_LONG;
167 __bind->buffer_length = sizeof(int32_t);
168 __bind->buffer = &__data;
169 break;
170 }
171 case sizeof(int32_t) : {
172 __data.i32 = (int32_t) * (int32_t*)_val;
173 __bind->buffer_type = MYSQL_TYPE_LONG;
174 __bind->buffer_length = sizeof(int32_t);
175 __bind->buffer = &__data;
176 break;
177 }
178 case sizeof(int64_t) : {
179 __data.i64 = (int64_t) * (int64_t*)_val;
180 __bind->buffer_type = MYSQL_TYPE_LONGLONG;
181 __bind->buffer_length = sizeof(int64_t);
182 __bind->buffer = &__data;
183 break;
184 }
185 default: {
187 return false;
188 }
189 }
190 __bind->is_unsigned = 0;
191 break;
192 }
193 case SQL::typeUInteger : {
194 switch (_size) {
195 case sizeof(uint8_t) : {
196 __data.u32 = (uint32_t) * (uint8_t*)_val;
197 __bind->buffer_type = MYSQL_TYPE_LONG;
198 __bind->buffer_length = sizeof(uint32_t);
199 __bind->buffer = &__data;
200 break;
201 }
202 case sizeof(uint16_t) : {
203 __data.u32 = (uint32_t) * (uint16_t*)_val;
204 __bind->buffer_type = MYSQL_TYPE_LONG;
205 __bind->buffer_length = sizeof(uint32_t);
206 __bind->buffer = &__data;
207 break;
208 }
209 case sizeof(uint32_t) : {
210 __data.u32 = (uint32_t) * (uint32_t*)_val;
211 __bind->buffer_type = MYSQL_TYPE_LONG;
212 __bind->buffer_length = sizeof(uint32_t);
213 __bind->buffer = &__data;
214 break;
215 }
216 case sizeof(uint64_t) : {
217 __data.u64 = (uint64_t) * (uint64_t*)_val;
218 __bind->buffer_type = MYSQL_TYPE_LONGLONG;
219 __bind->buffer_length = sizeof(uint64_t);
220 __bind->buffer = &__data;
221 break;
222 }
223 default: {
225 return false;
226 }
227 }
228 __bind->is_unsigned = 1;
229 break;
230 }
231 case SQL::typeFloat: {
232 switch (_size) {
233 case sizeof(float) : {
234 __data.f32 = *(float*)_val;
235 __bind->buffer_type = MYSQL_TYPE_FLOAT;
236 __bind->buffer_length = sizeof(float);
237 __bind->buffer = &__data;
238 break;
239 }
240 case sizeof(double) : {
241 __data.f64 = *(double*)_val;
242 __bind->buffer_type = MYSQL_TYPE_DOUBLE;
243 __bind->buffer_length = sizeof(double);
244 __bind->buffer = &__data;
245 break;
246 }
247 default: {
249 return false;
250 }
251 }
252 break;
253 }
254 case SQL::typeDate: {
255 if (_size == sizeof(SQL::Date)) {
256 const SQL::Date* p = (const SQL::Date*)_val;
257 __data.time.year = __ABS(p->year);
258 __data.time.month = p->month;
259 __data.time.day = p->day;
260 __data.time.hour = 0;
261 __data.time.minute = 0;
262 __data.time.second = 0;
263 __data.time.second_part = 0;
264 __data.time.neg = p->year < 0 ? 1 : 0;
265 __data.time.time_type = MYSQL_TIMESTAMP_DATE;
266 __bind->buffer_type = MYSQL_TYPE_DATE;
267 __bind->buffer_length = sizeof(MYSQL_TIME);
268 __bind->buffer = &__data;
269 }
270 else {
272 return false;
273 }
274 break;
275 }
276 case SQL::typeTime: {
277 if (_size == sizeof(SQL::Time)) {
278 const SQL::Time* p = (const SQL::Time*)_val;
279 __data.time.year = 0;
280 __data.time.month = 0;
281 __data.time.day = 0;
282 __data.time.hour = p->hour;
283 __data.time.minute = p->min;
284 __data.time.second = p->sec;
285 __data.time.second_part = p->frac / 1000;
286 __data.time.neg = 0;
287 __data.time.time_type = MYSQL_TIMESTAMP_TIME;
288 __bind->buffer_type = MYSQL_TYPE_TIME;
289 __bind->buffer_length = sizeof(MYSQL_TIME);
290 __bind->buffer = &__data;
291 }
292 else {
294 return false;
295 }
296 break;
297 }
298 case SQL::typeTimeStamp: {
299 if (_size == sizeof(SQL::TimeStamp)) {
300 const SQL::TimeStamp* p = (const SQL::TimeStamp*)_val;
301#if 0
302 if (p->tzoff != INT16_MIN) {
304 return false;
305 }
306#endif
307 __data.time.year = __ABS(p->year);
308 __data.time.month = p->month;
309 __data.time.day = p->day;
310 __data.time.hour = p->hour;
311 __data.time.minute = p->min;
312 __data.time.second = p->sec;
313 __data.time.second_part = p->frac / 1000;
314 __data.time.neg = p->year < 0 ? 1 : 0;
315 __data.time.time_type = MYSQL_TIMESTAMP_DATETIME;
316 __bind->buffer_type = MYSQL_TYPE_DATETIME;
317 __bind->buffer_length = sizeof(MYSQL_TIME);
318 __bind->buffer = &__data;
319 }
320 else {
322 return false;
323 }
324 break;
325 }
326 case SQL::typeInterval: {
327 if (_size == sizeof(SQL::Interval)) {
328 const SQL::Interval* p = (const SQL::Interval*)_val;
329 __data.time.year = 0;
330 __data.time.month = 0;
331 __data.time.day = __ABS(p->years * 365 + p->months * 30 + p->days);
332 __data.time.hour = __ABS(p->hours);
333 __data.time.minute = __ABS(p->mins);
334 __data.time.second = __ABS(p->secs);
335 __data.time.second_part = __ABS(p->fracs) / 1000;
336 __data.time.neg = p->years < 0 || p->months < 0 || p->days
337 || p->hours < 0 || p->mins || p->secs || p->fracs < 0 ? 1 : 0;
338 __data.time.time_type = MYSQL_TIMESTAMP_TIME;
339 __bind->buffer_type = MYSQL_TYPE_TIME;
340 __bind->buffer_length = sizeof(MYSQL_TIME);
341 __bind->buffer = &__data;
342 }
343 else {
345 return false;
346 }
347 break;
348 }
349 case SQL::typeText :
350 case SQL::typeBinary: {
351 if (_size > UINT32_MAX) {
353 return false;
354 }
355 __bind->buffer_type = MYSQL_TYPE_STRING;
356 __bind->buffer_length = (unsigned int) _size;
357 __bind->buffer = _val;
358 break;
359 }
360 case SQL::typeInputStream : {
361 if (_size != (size_t)-1 && _size > UINT32_MAX) {
363 return false;
364 }
365 __bind->buffer_type = MYSQL_TYPE_STRING;
366 __bind->buffer_length = 0;
367 __bind->buffer = NULL;
368 __input = (InputStream*)_val;
369 __size = _size;
370 break;
371 }
372 default: {
374 return false;
375 }
376 }
377
378 __bind->is_null_value = 0;
379 Param::__dataType = _sqlType;
380 return true;
381}
382
383__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 UINT32_MAX
Definition Config.h:295
#define INT16_MIN
Definition Config.h:284
#define __DCL_TRACE1_N(fmt, arg)
#define __SET_ERROR_MSG(_message)
const wchar_t * __dataTypeName(const ifx_sqlvar_t *_sqlvar)
Definition IFXField.cpp:304
#define __ABS(n)
Definition MyParam.cpp:145
const wchar_t * __dataTypeName(enum_field_types _type, unsigned int _flags)
Definition MyField.cpp:233
#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
virtual void setNull()
Definition MyParam.cpp:134
bool init(SQL::Query *_query, unsigned int _index, MYSQL_BIND *_bind)
Definition MyParam.cpp:64
virtual const wchar_t * serverDataTypeName() const
Definition MyParam.cpp:115
virtual ~MyParam()
Definition MyParam.cpp:59
MyQuery * query() const
Definition MyParam.h:50
void onAfterExecute()
Definition MyParam.cpp:107
bool onBeforeExecute()
Definition MyParam.cpp:74
virtual bool __setData(_CONST void *_val, size_t _size, SQL::DataType _valType, SQL::DataType _sqlType)
Definition MyParam.cpp:147
DataType __dataType
Definition SQLCore.h:188
DataType
Definition SQLCore.h:59
@ typeBinary
Definition SQLCore.h:74
@ typeTime
Definition SQLCore.h:66
@ typeLongBinary
Definition SQLCore.h:76
@ typeUInteger
Definition SQLCore.h:62
@ typeUnknown
Definition SQLCore.h:60
@ typeTimeStamp
Definition SQLCore.h:68
@ typeBlob
Definition SQLCore.h:78
@ 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
@ eInvalidData
Definition SQLCore.h:54
@ eNotSupportDataType
Definition SQLCore.h:48
@ eInvalidDataSize
Definition SQLCore.h:55
size_t __MIN(size_t x, size_t y)
Definition size_t.h:27
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
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