DCL 4.1
Loading...
Searching...
No Matches
IBField.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <stdlib.h> // malloc, free
4#include <string.h> // strncpy
5#include <time.h> // struct tm
6
7#include <ibase.h>
8
9#include <dcl/Object.h>
10#if __DCL_HAVE_ALLOC_DEBUG
11#undef __DCL_ALLOC_LEVEL
12#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
13#endif
14
15#include <dcl/Numeric.h>
17#include <dcl/Charset.h>
18#include <dcl/SQLCore.h>
19
20#include "IBConnection.h"
21#include "IBQuery.h"
22#include "IBField.h"
23
24#undef __THIS_FILE__
25static const wchar_t __THIS_FILE__[] = __T("dcl/sql/IBField.cpp");
26
27__DCL_BEGIN_NAMESPACE
28
30
31#define __SQLTYPE_IS(__sqltype) ((__sqlvar->sqltype & ~1) == __sqltype)
32
34 : Field(NULL)
35{
36 __sqlvar = NULL;
37 __indicator = 0; /* NOT NULL의 경우 체크하지 않는다. 때문에 초기값은
38 NOT NULL (0) 으로 둔다. */
39
40 __maxDataSize = 0;
41 __dataSize = 0;
42}
43
45{
46// cerr << "~IBField:" << name() << endl;
47}
48
49bool IBField::init(SQL::Query* _queryHandle, XSQLVAR* _sqlvar)
50{
51 __DCL_ASSERT((Field::__queryHandle == NULL) && (__sqlvar == NULL));
52 __DCL_ASSERT((_sqlvar != NULL) && (_sqlvar->sqldata != NULL));
53
54 Field::__queryHandle = _queryHandle;
55 __sqlvar = _sqlvar;
56 __sqlvar->sqlind = &__indicator;
57
58 try {
59 Field::__name = UTF8Decoder::decode(__sqlvar->sqlname,
60 __sqlvar->sqlname_length).toUpperCase();
61 }
62 catch (CharsetConvertException* _e) {
63 __SET_ERROR_MSG(UTF8Encoder::encode(_e->toStringAll()));
64 _e->destroy();
65 return false;
66 }
67
68#ifndef FIREBIRD_IBASE_H
69 Field::__precision = __sqlvar->sqlprecision;
70#endif
71 Field::__scale = __sqlvar->sqlscale;
72
73 switch(__sqlvar->sqltype & ~1) {
74 case SQL_SHORT: {
75 if (__sqlvar->sqlscale == 0) {
76 Field::__dataType = SQL::typeInteger;
77 __maxDataSize = sizeof(int16_t);
78 }
79 else {
80 Field::__dataType = SQL::typeNumeric;
81 __maxDataSize = 5 + 2; // "-32768."
82 }
83 break;
84 }
85 case SQL_LONG: {
86 if (__sqlvar->sqlscale == 0) {
87 Field::__dataType = SQL::typeInteger;
88 __maxDataSize = sizeof(int32_t);
89 }
90 else {
91 Field::__dataType = SQL::typeNumeric;
92 __maxDataSize = 10 + 2; // "-2147483648."
93 }
94 break;
95 }
96 case SQL_INT64: {
97 if (__sqlvar->sqlscale == 0) {
98 Field::__dataType = SQL::typeInteger;
99 __maxDataSize = sizeof(int64_t);
100 }
101 else {
102 Field::__dataType = SQL::typeNumeric;
103 __maxDataSize = 19 + 2; // "-9223372036854775807."
104
105 }
106 break;
107 }
108 case SQL_FLOAT: {
109 Field::__dataType = SQL::typeFloat;
110 __maxDataSize = sizeof(float);
111 break;
112 }
113 case SQL_DOUBLE: {
114 Field::__dataType = SQL::typeFloat;
115 __maxDataSize = sizeof(double);
116 break;
117 }
118 case SQL_TYPE_DATE: {
119 Field::__dataType = SQL::typeDate;
120 __maxDataSize = sizeof(SQL::Date);
121 break;
122 }
123 case SQL_TYPE_TIME: {
124 Field::__dataType = SQL::typeTime;
125 __maxDataSize = sizeof(SQL::Time);
126 break;
127 }
128 case SQL_TIMESTAMP: {
129 Field::__dataType = SQL::typeTimeStamp;
130 __maxDataSize = sizeof(SQL::TimeStamp);
131 break;
132 }
133#if defined(FIREBIRD_IBASE_H) && FB_API_VER >= 40
134 case SQL_TIME_TZ_EX: {
135 Field::__dataType = SQL::typeTimeTz;
136 __maxDataSize = sizeof(SQL::Time);
137 break;
138 }
139 case SQL_TIMESTAMP_TZ_EX: {
140 Field::__dataType = SQL::typeTimeStampTz;
141 __maxDataSize = sizeof(SQL::TimeStamp);
142 break;
143 }
144#endif
145 case SQL_TEXT: {
146 Field::__dataType = SQL::typeText;
147 __maxDataSize = __sqlvar->sqllen; // 32767;
148 break;
149 }
150 case SQL_VARYING: {
151 Field::__dataType = SQL::typeText;
152 __maxDataSize = __sqlvar->sqllen; // 32765;
153 break;
154 }
155 case SQL_BLOB: {
156 if (__sqlvar->sqlsubtype == isc_blob_text)
157 Field::__dataType = SQL::typeLongText;
158 else
159 Field::__dataType = SQL::typeLongBinary;
160 __maxDataSize = 64 * 1024; // 64KB
161 break;
162 }
163 default: {
164 __DCL_ASSERT(false);
165 }
166 }
167 return true;
168}
169
171{
172 if (__indicator == -1)
173 return true;
174
175 // not null
176 if (Field::__dataType == SQL::typeLongText
177 || Field::__dataType == SQL::typeLongBinary) {
178 __DCL_ASSERT(__SQLTYPE_IS(SQL_BLOB));
179
180 IBConnection* connHandle = (IBConnection*)Field::connection();
181 ISC_STATUS* statusVector = connHandle->statusVector();
182 isc_blob_handle hBlob = NULL;
183 ISC_QUAD* pBlobID = (ISC_QUAD*)(__sqlvar->sqldata);
184
185 if(isc_open_blob2(
186 statusVector,
187 connHandle->dbHandlePtr(),
188 connHandle->trHandlePtr(),
189 &hBlob,
190 pBlobID,
191 0,
192 NULL)) {
194 return false;
195 }
196
197 bool b = getBlobInfo(&hBlob, isc_info_blob_total_length, &__dataSize);
198 ISC_STATUS status2[ISC_STATUS_VECTOR_LENGTH];
199 isc_close_blob(status2, &hBlob);
200
201 if (!b) {
203 return false;
204 }
205 }
206 return true;
207}
208
209#define SQLTYPE_NAME(_dataType, name) case _dataType : return L ## name
210
211const wchar_t* __dataTypeName(const XSQLVAR* _sqlvar)
212{
213 switch(_sqlvar->sqltype & ~1) {
214 case SQL_SHORT:
215 case SQL_LONG:
216 case SQL_INT64: {
217 if (_sqlvar->sqlscale) {
218 switch (_sqlvar->sqltype & ~1) {
219 SQLTYPE_NAME(SQL_SHORT, "DECIMAL16");
220 SQLTYPE_NAME(SQL_LONG, "DECIMAL32");
221 SQLTYPE_NAME(SQL_INT64, "DECIMAL64");
222 }
223 }
224 else {
225 switch (_sqlvar->sqltype & ~1) {
226 SQLTYPE_NAME(SQL_SHORT, "SMALLINT");
227 SQLTYPE_NAME(SQL_LONG, "INTEGER");
228 SQLTYPE_NAME(SQL_INT64, "INT64");
229 }
230 }
231 }
232 SQLTYPE_NAME(SQL_FLOAT, "FLOAT");
233 SQLTYPE_NAME(SQL_DOUBLE, "DOUBLE");
234 SQLTYPE_NAME(SQL_TYPE_DATE, "DATE");
235 SQLTYPE_NAME(SQL_TYPE_TIME, "TIME");
236 SQLTYPE_NAME(SQL_TIMESTAMP, "TIMESTAMP");
237#if defined(FIREBIRD_IBASE_H) && FB_API_VER >= 40
238 SQLTYPE_NAME(SQL_TIME_TZ_EX, "TIME WITH TIMEZONE");
239 SQLTYPE_NAME(SQL_TIMESTAMP_TZ_EX, "TIMESTAMP WITH TIMEZONE");
240#endif
241 SQLTYPE_NAME(SQL_TEXT, "CHAR");
242 SQLTYPE_NAME(SQL_VARYING, "VARCHAR");
243 case SQL_BLOB: {
244 if (_sqlvar->sqlsubtype == 1)
245 return L"BLOB(TEXT)";
246 else
247 return L"BLOB";
248 }
249 }
250 return L"Unknown Type: Driver is not Support";
251}
252
253const wchar_t* IBField::serverDataTypeName() const
254{
255 return __dataTypeName(__sqlvar);
256}
257
258bool IBField::isNull() const
259{
260 // SELECT 이면 fetch 이후
261 // EXECUTE PROCEDURE 이면 즉시
262// return __indicator == -1;
263 if (query()->stmtType() == isc_info_sql_stmt_select) {
264 if (!query()->inState(SQL::Query::stFetched)) {
265 return true;
266 }
267 }
268 return __indicator == -1;
269}
270
271bool IBField::__getDataSize(size_t* _size, bool _maxSize)
272{
273 if (_maxSize) {
274 *_size = __maxDataSize;
275 return true;
276 }
277
278 if (query()->stmtType() == isc_info_sql_stmt_select) {
279 if (!query()->inState(SQL::Query::stFetched)) {
281 return false;
282 }
283 }
284// else
285// isc_info_sql_stmt_exec_procedure
286
287 switch(Field::__dataType) {
288 case SQL::typeText: {
289 if (__SQLTYPE_IS(SQL_TEXT))
290 *_size = __sqlvar->sqllen;
291 else
292 {
293 __DCL_ASSERT(__SQLTYPE_IS(SQL_VARYING));
294 *_size = *(short*)(__sqlvar->sqldata);
295 }
296 break;
297 }
299 case SQL::typeLongBinary: {
300 *_size = __dataSize;
301 break;
302 }
303 default: {
304 // typeInteger, typeUInteger, typeFloat, typeNumeric
305 // typeDate, typeTime, typeTimeStamp
306 *_size = __maxDataSize;
307 }
308 }
309
310 return true;
311}
312
314 void* _buf,
315 size_t* _size,
316 SQL::DataType _dataType
317 )
318{
319 if (query()->stmtType() == isc_info_sql_stmt_select) {
320 if (!query()->inState(SQL::Query::stFetched)) {
322 return false;
323 }
324 }
325 else {
326 // isc_info_sql_stmt_exec_procedure
327 if (!__queryHandle->inState(SQL::Query::stExecuted)) {
329 return false;
330 }
331 }
332
333 switch(_dataType) {
334 case SQL::typeInteger:
335 return getInteger(_buf, _size);
337 return getUInteger(_buf, _size);
338 case SQL::typeFloat:
339 return getFloat(_buf, _size);
340 case SQL::typeDate:
341 return getDate((SQL::Date*)_buf, _size);
342 case SQL::typeTime:
343 return getTime((SQL::Time*)_buf, _size);
345 return getTimeStamp((SQL::TimeStamp*)_buf, _size);
348 return false;
349 case SQL::typeText:
350 if (Field::__dataType == SQL::typeNumeric)
351 return getDecimal((char*)_buf, _size);
352 case SQL::typeBinary:
353 return getBytes((byte_t*)_buf, _size);
355 return writeTo((OutputStream*)_buf, _size);
356 default :
357 __DCL_ASSERT(false); // SQL::Field::getData bug
358 }
359
360 return true;
361}
362
363static int32_t __divider32 [] =
364{
365 1, // 0
366 10, // -1
367 100, // -2
368 1000, // -3
369 10000, // -4
370 100000, // -5
371 1000000, // -6
372 10000000, // -7
373 100000000, // -8
374 1000000000 // -9
375};
376
377static int64_t __divider64 [] =
378{
379#ifdef _MSC_VER
380 1I64, // 0
381 10I64, // -1
382 100I64, // -2
383 1000I64, // -3
384 10000I64, // -4
385 100000I64, // -5
386 1000000I64, // -6
387 10000000I64, // -7
388 100000000I64, // -8
389 1000000000I64, // -9
390 10000000000I64, // -10
391 100000000000I64, // -11
392 1000000000000I64, // -12
393 10000000000000I64, // -13
394 100000000000000I64, // -14
395 1000000000000000I64, // -15
396 10000000000000000I64, // -16
397 100000000000000000I64, // -17
398 1000000000000000000I64 // -18
399#else // __GNUC__
400 1LL, // 0
401 10LL, // -1
402 100LL, // -2
403 1000LL, // -3
404 10000LL, // -4
405 100000LL, // -5
406 1000000LL, // -6
407 10000000LL, // -7
408 100000000LL, // -8
409 1000000000LL, // -9
410 10000000000LL, // -10
411 100000000000LL, // -11
412 1000000000000LL, // -12
413 10000000000000LL, // -13
414 100000000000000LL, // -14
415 1000000000000000LL, // -15
416 10000000000000000LL, // -16
417 100000000000000000LL, // -17
418 1000000000000000000LL // -18
419#endif
420};
421
423{
424 int16_t i16;
425 int32_t i32;
426 int64_t i64;
427};
428
429bool IBField::getInteger(void* _buf, size_t* _size)
430{
431 if (__sqlvar->sqlscale == 0) {
432 // integer
433 switch(__sqlvar->sqltype & ~1) {
434 case SQL_SHORT: {
435 switch (*_size) {
436 case sizeof(int16_t) : {
437 *(int16_t*)_buf =
438 *(int16_t*)(__sqlvar->sqldata);
439 break;
440 }
441 case sizeof(int32_t) : {
442 *(int32_t*)_buf =
443 (int32_t)(
444 *(int16_t*)(__sqlvar->sqldata)
445 );
446 break;
447 }
448 case sizeof(int64_t) : {
449 *(int64_t*)_buf =
450 (int64_t)(
451 *(int16_t*)(__sqlvar->sqldata)
452 );
453 break;
454 }
455 default: {
456 *_size = sizeof(int16_t);
458 return false;
459 }
460 }
461 break;
462 }
463 case SQL_LONG: {
464 switch (*_size) {
465 case sizeof(int32_t) : {
466 *(int32_t*)_buf =
467 *(int32_t*)(__sqlvar->sqldata);
468 break;
469 }
470 case sizeof(int64_t) : {
471 *(int64_t*)_buf =
472 (int64_t)(
473 *(int32_t*)(__sqlvar->sqldata)
474 );
475 break;
476 }
477 default: {
478 *_size = sizeof(int32_t);
480 return false;
481 }
482 }
483 break;
484 }
485 case SQL_INT64: {
486 switch (*_size) {
487 case sizeof(int64_t) : {
488 *(int64_t*)_buf =
489 *(int64_t*)(__sqlvar->sqldata);
490 break;
491 }
492 default: {
493 *_size = sizeof(int64_t);
495 return false;
496 }
497 }
498 break;
499 }
500 default: {
501 __DCL_ASSERT(false); // IBField::init bug
502 }
503 }
504 }
505 else {
506 // decimal
508 switch(__sqlvar->sqltype & ~1) {
509 case SQL_SHORT: {
510 n.i16 = (int16_t)(
511 (*(int16_t*)(__sqlvar->sqldata))
512 / __divider32[-(__sqlvar->sqlscale)]
513 );
514 switch (*_size) {
515 case sizeof(int8_t) : {
516 if (n.i16 < INT8_MIN || INT8_MAX < n.i16) {
518 return false;
519 }
520 *(int8_t*)_buf = (int8_t)n.i16;
521 break;
522 }
523 case sizeof(int16_t) : {
524 *(int16_t*)_buf = n.i16;
525 break;
526 }
527 case sizeof(int32_t) : {
528 *(int32_t*)_buf = (int32_t)n.i16;
529 break;
530 }
531 case sizeof(int64_t) : {
532 *(int64_t*)_buf = (int64_t)n.i16;
533 break;
534 }
535 default: {
536 *_size = sizeof(int16_t);
538 return false;
539 }
540 }
541 break;
542 }
543 case SQL_LONG: {
544 n.i32 = (int32_t)(
545 (*(int32_t*)(__sqlvar->sqldata))
546 / __divider32[-(__sqlvar->sqlscale)]
547 );
548 switch (*_size) {
549 case sizeof(int8_t) : {
550 if (n.i32 < INT8_MIN || INT8_MAX < n.i32) {
552 return false;
553 }
554 *(int8_t*)_buf = (int8_t)n.i32;
555 break;
556 }
557 case sizeof(int16_t) : {
558 if (n.i32 < INT16_MIN || INT16_MAX < n.i32) {
560 return false;
561 }
562 *(int16_t*)_buf = (int16_t)n.i32;
563 break;
564 }
565 case sizeof(int32_t) : {
566 *(int32_t*)_buf = n.i32;
567 break;
568 }
569 case sizeof(int64_t) : {
570 *(int64_t*)_buf = (int64_t)n.i32;
571 break;
572 }
573 default: {
574 *_size = sizeof(int32_t);
576 return false;
577 }
578 }
579 break;
580 }
581 case SQL_INT64: {
582 n.i64 = *(int64_t*)(__sqlvar->sqldata)
583 / __divider64[-(__sqlvar->sqlscale)];
584 switch (*_size) {
585 case sizeof(int8_t) : {
586 if (n.i64 < INT8_MIN || INT8_MAX < n.i64) {
588 return false;
589 }
590 *(int8_t*)_buf = (int8_t)n.i64;
591 break;
592 }
593 case sizeof(int16_t) : {
594 if (n.i64 < INT16_MIN || INT16_MAX < n.i64) {
596 return false;
597 }
598 *(int16_t*)_buf = (int16_t)n.i64;
599 break;
600 }
601 case sizeof(int32_t) : {
602 if (n.i64 < INT32_MIN || INT32_MAX < n.i64) {
604 return false;
605 }
606 *(int32_t*)_buf = (int32_t)n.i64;
607 break;
608 }
609 case sizeof(int64_t) : {
610 *(int64_t*)_buf = n.i64;
611 break;
612 }
613 default: {
614 *_size = sizeof(int64_t);
616 return false;
617 }
618 }
619 break;
620 }
621 default: {
622 __DCL_ASSERT(false); // IBField::init bug
623 }
624 }
625 }
626 return true;
627}
628
629bool IBField::getUInteger(void* _buf, size_t* _size)
630{
631 if (__sqlvar->sqlscale == 0) {
632 // integer
633 switch(__sqlvar->sqltype & ~1) {
634 case SQL_SHORT: {
635 switch (*_size) {
636 case sizeof(uint16_t) : {
637 *(uint16_t*)_buf =
638 (uint16_t)(
639 *(int16_t*)(__sqlvar->sqldata)
640 );
641 break;
642 }
643 case sizeof(uint32_t) : {
644 *(uint32_t*)_buf =
645 (uint32_t)(
646 *(int16_t*)(__sqlvar->sqldata)
647 );
648 break;
649 }
650 case sizeof(uint64_t) : {
651 *(uint64_t*)_buf =
652 (uint64_t)(
653 *(int16_t*)(__sqlvar->sqldata)
654 );
655 break;
656 }
657 default: {
658 *_size = sizeof(uint16_t);
660 return false;
661 }
662 }
663 break;
664 }
665 case SQL_LONG: {
666 switch (*_size) {
667 case sizeof(uint32_t) : {
668 *(uint32_t*)_buf =
669 (uint32_t)(
670 *(int32_t*)(__sqlvar->sqldata)
671 );
672 break;
673 }
674 case sizeof(int64_t) : {
675 *(uint64_t*)_buf =
676 (uint64_t)(
677 *(int32_t*)(__sqlvar->sqldata)
678 );
679 break;
680 }
681 default: {
682 *_size = sizeof(uint32_t);
684 return false;
685 }
686 }
687 break;
688 }
689 case SQL_INT64: {
690 switch (*_size) {
691 case sizeof(uint64_t) : {
692 *(uint64_t*)_buf =
693 (uint64_t)(
694 *(int64_t*)(__sqlvar->sqldata)
695 );
696 break;
697 }
698 default: {
699 *_size = sizeof(uint64_t);
701 return false;
702 }
703 }
704 break;
705 }
706 default: {
707 __DCL_ASSERT(false); // IBField::init bug
708 }
709 }
710 }
711 else {
712 // decimal
714 switch(__sqlvar->sqltype & ~1) {
715 case SQL_SHORT: {
716 n.i16 = (int16_t)(
717 (*(int16_t*)(__sqlvar->sqldata))
718 / __divider32[-(__sqlvar->sqlscale)]
719 );
720 switch (*_size) {
721 case sizeof(int8_t) : {
722 if (n.i16 < INT8_MIN || INT8_MAX < n.i16) {
724 return false;
725 }
726 *(uint8_t*)_buf = (uint8_t)n.i16;
727 break;
728 }
729 case sizeof(int16_t) : {
730 *(uint16_t*)_buf = (uint16_t)n.i16;
731 break;
732 }
733 case sizeof(int32_t) : {
734 *(uint32_t*)_buf = (uint32_t)n.i16;
735 break;
736 }
737 case sizeof(int64_t) : {
738 *(uint64_t*)_buf = (uint64_t)n.i16;
739 break;
740 }
741 default: {
742 *_size = sizeof(uint16_t);
744 return false;
745 }
746 }
747 break;
748 }
749 case SQL_LONG: {
750 n.i32 = (int32_t)(
751 (*(int32_t*)(__sqlvar->sqldata))
752 / __divider32[-(__sqlvar->sqlscale)]
753 );
754 switch (*_size) {
755 case sizeof(int8_t) : {
756 if (n.i32 < INT8_MIN || INT8_MAX < n.i32) {
758 return false;
759 }
760 *(uint8_t*)_buf = (uint8_t)n.i32;
761 break;
762 }
763 case sizeof(int16_t) : {
764 if (n.i32 < INT16_MIN || INT16_MAX < n.i32) {
766 return false;
767 }
768 *(uint16_t*)_buf = (uint16_t)n.i32;
769 break;
770 }
771 case sizeof(int32_t) : {
772 *(uint32_t*)_buf = (uint32_t)n.i32;
773 break;
774 }
775 case sizeof(int64_t) : {
776 *(uint64_t*)_buf = (uint64_t)n.i32;
777 break;
778 }
779 default: {
780 *_size = sizeof(uint32_t);
782 return false;
783 }
784 }
785 break;
786 }
787 case SQL_INT64: {
788 n.i64 = *(int64_t*)(__sqlvar->sqldata)
789 / __divider64[-(__sqlvar->sqlscale)];
790 switch (*_size) {
791 case sizeof(int8_t) : {
792 if (n.i64 < INT8_MIN || INT8_MAX < n.i64) {
794 return false;
795 }
796 *(uint8_t*)_buf = (uint8_t)n.i64;
797 break;
798 }
799 case sizeof(int16_t) : {
800 if (n.i64 < INT16_MIN || INT16_MAX < n.i64) {
802 return false;
803 }
804 *(uint16_t*)_buf = (uint16_t)n.i64;
805 break;
806 }
807 case sizeof(int32_t) : {
808 if (n.i64 < INT32_MIN || INT32_MAX < n.i64) {
810 return false;
811 }
812 *(uint32_t*)_buf = (uint32_t)n.i64;
813 break;
814 }
815 case sizeof(int64_t) : {
816 *(uint64_t*)_buf = (uint64_t)n.i64;
817 break;
818 }
819 default: {
820 *_size = sizeof(int64_t);
822 return false;
823 }
824 }
825 break;
826 }
827 default: {
828 __DCL_ASSERT(false); // IBField::init bug
829 }
830 }
831 }
832 return true;
833}
834
835bool IBField::getFloat(void* _buf, size_t* _size)
836{
837 switch(__sqlvar->sqltype & ~1) {
838 case SQL_FLOAT: {
839 switch (*_size) {
840 case sizeof(float) : {
841 *(float*)_buf =
842 *(float*)(__sqlvar->sqldata);
843 break;
844 }
845 case sizeof(double) : {
846 *(double*)_buf =
847 (double)(
848 *(float*)(__sqlvar->sqldata)
849 );
850 break;
851 }
852 default: {
853 *_size = sizeof(float);
855 return false;
856 }
857 }
858 break;
859 }
860 case SQL_DOUBLE: {
861 switch (*_size) {
862 case sizeof(double) : {
863 *(double*)_buf =
864 *(double*)(__sqlvar->sqldata);
865 break;
866 }
867 default: {
868 *_size = sizeof(double);
870 return false;
871 }
872 }
873 break;
874 }
875 case SQL_SHORT: {
876 __DCL_ASSERT(Field::__dataType == SQL::typeNumeric);
877 __DCL_ASSERT(__sqlvar->sqlscale < 0);
878 switch (*_size) {
879 case sizeof(float) : {
880 *(float*)_buf =
881 (float)(*(int16_t*)(__sqlvar->sqldata))
882 / (float)__divider32[-(__sqlvar->sqlscale)];
883 break;
884 }
885 case sizeof(double) : {
886 *(double*)_buf =
887 (double)(*(int16_t*)(__sqlvar->sqldata))
888 / (double)__divider32[-(__sqlvar->sqlscale)];
889 break;
890 }
891 default: {
892 *_size = sizeof(float);
894 return false;
895 }
896 }
897 break;
898 }
899 case SQL_LONG: {
900 __DCL_ASSERT(Field::__dataType == SQL::typeNumeric);
901 __DCL_ASSERT(__sqlvar->sqlscale < 0);
902 switch (*_size) {
903 case sizeof(float) : {
904 *(float*)_buf =
905 (float)(*(int32_t*)(__sqlvar->sqldata))
906 / (float)__divider32[-(__sqlvar->sqlscale)];
907 break;
908 }
909 case sizeof(double) : {
910 *(double*)_buf =
911 (double)(*(int32_t*)(__sqlvar->sqldata))
912 / (double)__divider32[-(__sqlvar->sqlscale)];
913 break;
914 }
915 default: {
916 *_size = sizeof(double);
918 return false;
919 }
920 }
921 break;
922 }
923 case SQL_INT64: {
924 __DCL_ASSERT(Field::__dataType == SQL::typeNumeric);
925 __DCL_ASSERT(__sqlvar->sqlscale < 0);
926 switch (*_size) {
927 case sizeof(float) : {
928 *(float*)_buf =
929 (float)(*(int64_t*)(__sqlvar->sqldata))
930 / (float)__divider32[-(__sqlvar->sqlscale)];
931 break;
932 }
933 case sizeof(double) : {
934 *(double*)_buf =
935 (double)(*(int64_t*)(__sqlvar->sqldata))
936 / (double)__divider64[-(__sqlvar->sqlscale)];
937 break;
938 }
939 default: {
940 *_size = sizeof(double);
942 return false;
943 }
944 }
945 break;
946 }
947 default: {
948 __DCL_ASSERT(false); // IBField::init bug
949 }
950 }
951 return true;
952}
953
954bool IBField::getDate(SQL::Date* _buf, size_t* _size)
955{
956 if (*_size != sizeof(SQL::Date)) {
958 return false;
959 }
960
961 struct tm tm;
962
963 switch(__sqlvar->sqltype & ~1) {
964#if defined(FIREBIRD_IBASE_H) && FB_API_VER >= 40
965 case SQL_TIMESTAMP_TZ_EX:
966#endif
967 case SQL_TIMESTAMP:
968 case SQL_TYPE_DATE: {
969 isc_decode_sql_date((ISC_DATE*)(__sqlvar->sqldata), &tm);
970 break;
971 }
972#if 0
973 case SQL_TIMESTAMP: {
974 isc_decode_timestamp((ISC_TIMESTAMP*)(__sqlvar->sqldata), &tm);
975 break;
976 }
977#endif
978 default: {
979 __DCL_ASSERT(false); // IBField::init bug
980 }
981 }
982
983 _buf->year = tm.tm_year + 1900;
984 _buf->month = tm.tm_mon + 1;
985 _buf->day = tm.tm_mday;
986 return true;
987}
988
989bool IBField::getTime(SQL::Time* _buf, size_t* _size)
990{
991 if (*_size != sizeof(SQL::Time)) {
993 return false;
994 }
995
996 struct tm tm;
997 ISC_TIME t = 0;
998
999 _buf->tzoff = INT16_MIN;
1000
1001 switch(__sqlvar->sqltype & ~1) {
1002#if defined(FIREBIRD_IBASE_H) && FB_API_VER >= 40
1003 case SQL_TIME_TZ_EX: {
1004 _buf->tzoff = ((ISC_TIME_TZ_EX*)(__sqlvar->sqldata))->ext_offset;
1005 }
1006#endif
1007 case SQL_TYPE_TIME: {
1008 isc_decode_sql_time((ISC_TIME*)(__sqlvar->sqldata), &tm);
1009 t = *(ISC_TIME*)(__sqlvar->sqldata);
1010 break;
1011 }
1012#if defined(FIREBIRD_IBASE_H) && FB_API_VER >= 40
1013 case SQL_TIMESTAMP_TZ_EX: {
1014 _buf->tzoff = ((ISC_TIMESTAMP_TZ_EX*)(__sqlvar->sqldata))->ext_offset;
1015 }
1016#endif
1017 case SQL_TIMESTAMP: {
1018 isc_decode_timestamp((ISC_TIMESTAMP*)(__sqlvar->sqldata), &tm);
1019 t = ((ISC_TIMESTAMP*)(__sqlvar->sqldata))->timestamp_time;
1020 break;
1021 }
1022 default: {
1023 __DCL_ASSERT(false); // IBField::init bug
1024 }
1025 }
1026
1027 _buf->hour = tm.tm_hour;
1028 _buf->min = tm.tm_min;
1029 _buf->sec = tm.tm_sec;
1030// #define ISC_TIME_SECONDS_PRECISION 10000
1031// #define ISC_TIME_SECONDS_PRECISION_SCALE (-4)
1032 _buf->frac = (t % ISC_TIME_SECONDS_PRECISION) * 100000;
1033
1034 return true;
1035}
1036
1037bool IBField::getTimeStamp(SQL::TimeStamp* _buf, size_t* _size)
1038{
1039 if (*_size != sizeof(SQL::TimeStamp)) {
1041 return false;
1042 }
1043
1044 struct tm tm;
1045 ISC_TIME t = 0;
1046
1047 _buf->tzoff = INT16_MIN;
1048
1049 switch(__sqlvar->sqltype & ~1) {
1050 case SQL_TYPE_DATE : {
1051 isc_decode_sql_date((ISC_DATE*)(__sqlvar->sqldata), &tm);
1052 break;
1053 }
1054#if defined(FIREBIRD_IBASE_H) && FB_API_VER >= 40
1055 case SQL_TIME_TZ_EX: {
1056 _buf->tzoff = ((ISC_TIME_TZ_EX*)(__sqlvar->sqldata))->ext_offset;
1057 }
1058#endif
1059 case SQL_TYPE_TIME: {
1060 isc_decode_sql_time((ISC_TIME*)(__sqlvar->sqldata), &tm);
1061 t = *(ISC_TIME*)(__sqlvar->sqldata);
1062 break;
1063 }
1064#if defined(FIREBIRD_IBASE_H) && FB_API_VER >= 40
1065 case SQL_TIMESTAMP_TZ_EX: {
1066 _buf->tzoff = ((ISC_TIMESTAMP_TZ_EX*)(__sqlvar->sqldata))->ext_offset;
1067 }
1068#endif
1069 case SQL_TIMESTAMP: {
1070 isc_decode_timestamp((ISC_TIMESTAMP*)(__sqlvar->sqldata), &tm);
1071 t = ((ISC_TIMESTAMP*)(__sqlvar->sqldata))->timestamp_time;
1072 break;
1073 }
1074 default: {
1075 __DCL_ASSERT(false); // IBField::init bug
1076 }
1077 }
1078
1079 _buf->year = tm.tm_year + 1900;
1080 _buf->month = tm.tm_mon + 1;
1081 _buf->day = tm.tm_mday;
1082 _buf->hour = tm.tm_hour;
1083 _buf->min = tm.tm_min;
1084 _buf->sec = tm.tm_sec;
1085// #define ISC_TIME_SECONDS_PRECISION 10000
1086// #define ISC_TIME_SECONDS_PRECISION_SCALE (-4)
1087 _buf->frac = (t % ISC_TIME_SECONDS_PRECISION) * 100000;
1088
1089 return true;
1090}
1091
1092inline int __ABS(int n) {
1093 return n < 0 ? -n : n;
1094}
1095
1096static ByteString __GetDecimalString(void* _buf, short _sqltype, short _sqlscale)
1097{
1098 ByteString str;
1099 switch(_sqltype & ~1) {
1100 case SQL_SHORT: {
1101 str = Int32::toByteString((int32_t) * (short*)_buf);
1102 break;
1103 }
1104 case SQL_LONG: {
1105 str = Int32::toByteString(*(int32_t*)_buf);
1106 break;
1107 }
1108 case SQL_INT64: {
1109 str = Int64::toByteString(*(int64_t*)_buf);
1110 break;
1111 }
1112 default: {
1113 __DCL_ASSERT(false);
1114 }
1115 }
1116
1117 ByteStringBuilder strNumber;
1118 if (str.length() > 0) {
1119 if (str[(size_t)0] == '-') {
1120 strNumber = '-';
1121 str = str.mid(1);
1122 }
1123
1124 __DCL_ASSERT(_sqlscale < 0);
1125 int padLen = str.length() + _sqlscale - 1;
1126 if (padLen < 0) {
1127 ByteString pad('0', __ABS(padLen));
1128 if (padLen < 0) {
1129 str = pad + str;
1130 }
1131 else {
1132 str = str + pad;
1133 }
1134 }
1135
1136 strNumber += str;
1137 strNumber.insert(strNumber.length() + _sqlscale, '.');
1138
1139 size_t len = strNumber.length();
1140 for(; len > 1 && strNumber[len - 1] == '0'; len--) {
1141 if (strNumber[len - 2] == '.')
1142 break;
1143 }
1144
1145 if (len < strNumber.length()) {
1146 strNumber = strNumber.toByteString().left(len);
1147 }
1148 }
1149 else {
1150 __DCL_ASSERT(false);
1151 strNumber = "0.0";
1152 }
1153
1154 return strNumber;
1155}
1156
1157bool IBField::getDecimal(char* _buf, size_t* _size)
1158{
1159 __DCL_ASSERT(__sqlvar->sqlscale != 0);
1160 ByteString r = __GetDecimalString(
1161 __sqlvar->sqldata,
1162 __sqlvar->sqltype,
1163 __sqlvar->sqlscale
1164 );
1165 if (*_size < (size_t)r.length()) {
1166 // fprintf(stderr, "%s:%d [%zd], s[%s]\n",
1167 // __FILE__, __LINE__,
1168 // *_size, r.data());
1170 return false;
1171 }
1172 strncpy(_buf, r.data(), r.length());
1173 if (*_size > (size_t)r.length()) {
1174 *_size = (size_t)r.length();
1175 _buf[*_size] = '\0';
1176 }
1177
1178 return true;
1179}
1180
1181bool IBField::getBytes(byte_t* _buf, size_t* _size)
1182{
1183 if (__SQLTYPE_IS(SQL_TEXT) || __SQLTYPE_IS(SQL_VARYING)) {
1184 char* pSrc = (char*)(__sqlvar->sqldata);
1185 size_t nCopy = (size_t)(__sqlvar->sqllen);
1186 if (__SQLTYPE_IS(SQL_VARYING)) {
1187 pSrc += sizeof(short);
1188 nCopy = (size_t)(*(short*)pSrc);
1189 }
1190
1191 if (nCopy > *_size)
1192 nCopy = *_size;
1193
1194 if (nCopy) {
1195 memcpy(_buf, pSrc, nCopy);
1196 if (nCopy < *_size)
1197 *(_buf + nCopy) = '\0';
1198 }
1199 *_size = nCopy;
1200 }
1201 else if (__SQLTYPE_IS(SQL_BLOB)) {
1202 if (*_size)
1203 return getBytesFromBlob(_buf, _size);
1204 }
1205 else {
1206 __DCL_ASSERT(false); // IBField::init bug
1207 }
1208
1209 return true;
1210}
1211
1212bool IBField::writeTo(OutputStream* _buf, size_t* _size)
1213{
1214 if (__SQLTYPE_IS(SQL_TEXT) || __SQLTYPE_IS(SQL_VARYING)) {
1215 char* pSrc = (char*)(__sqlvar->sqldata);
1216 size_t nCopy = (size_t)(__sqlvar->sqllen);
1217 if (__SQLTYPE_IS(SQL_VARYING)) {
1218 pSrc += sizeof(short);
1219 nCopy = (size_t)(*(short*)pSrc);
1220 }
1221
1222 if (nCopy > *_size)
1223 nCopy = *_size;
1224
1225 if (nCopy) {
1226 try {
1227 _buf->write(pSrc, nCopy);
1228 }
1229 catch(IOException* e) {
1230 __SET_ERROR_MSG(UTF8Encoder::encode(e->toStringAll()));
1231 e->destroy();
1232 return false;
1233 }
1234 }
1235 *_size = nCopy;
1236 }
1237 else if (__SQLTYPE_IS(SQL_BLOB)) {
1238 if (*_size)
1239 return writeToFromBlob(_buf, _size);
1240 }
1241 else {
1242 __DCL_ASSERT(false); // IBField::init bug
1243 }
1244
1245 return true;
1246}
1247
1248/*
1249static char blob_info_items[] = {
1250 isc_info_blob_num_segments,
1251 isc_info_blob_max_segment,
1252 isc_info_blob_total_length,
1253 isc_info_end
1254};
1255*/
1256
1258 isc_blob_handle* _blobHandle,
1259 char _blob_info_item, size_t* _buf
1260 )
1261{
1262 char res_buffer[10]; // 1 + 2 + 4 == 7
1263 if (isc_blob_info(
1264 ((IBConnection*)Field::connection())->statusVector(),
1265 _blobHandle,
1266 sizeof(_blob_info_item),
1267 &_blob_info_item,
1268 sizeof(res_buffer),
1269 res_buffer)
1270 ) {
1271// __DCL_ASSERT(STATUS_FAILED(statusVector));
1272
1273// __SET_ERROR(eServerError);
1274 return false;
1275 }
1276
1277 char* p = res_buffer;
1278 __DCL_ASSERT(*p == _blob_info_item);
1279 p++;
1280 unsigned short length = (unsigned short)isc_vax_integer(p, 2);
1281 p += 2;
1282 *_buf = isc_vax_integer(p, length);
1283
1284 return true;
1285}
1286
1287inline size_t __MIN(size_t x, size_t y)
1288{
1289 return x < y ? x : y;
1290}
1291
1292bool IBField::getBytesFromBlob(byte_t* _buf, size_t* _size)
1293{
1294 IBConnection* connHandle = (IBConnection*)Field::connection();
1295 ISC_STATUS* statusVector = connHandle->statusVector();
1296 isc_blob_handle hBlob = NULL;
1297 ISC_QUAD* pBlobID = (ISC_QUAD*)(__sqlvar->sqldata);
1298
1299 if(isc_open_blob2(
1300 statusVector,
1301 connHandle->dbHandlePtr(),
1302 connHandle->trHandlePtr(),
1303 &hBlob,
1304 pBlobID,
1305 0,
1306 NULL)) {
1308 return false;
1309 }
1310
1311 size_t nMaxSegment = 0;
1312 if(!getBlobInfo(&hBlob, isc_info_blob_max_segment, &nMaxSegment)) {
1313 ISC_STATUS statusVector[ISC_STATUS_VECTOR_LENGTH];
1314 isc_close_blob(statusVector, &hBlob);
1315
1317 return false;
1318 }
1319
1320 size_t nRemain = *_size;
1321 unsigned short nRead = 0;
1322 unsigned short nActualRead = 0;
1323 char* pch = (char*)_buf;
1324 ISC_STATUS rs = 0;
1325 while(nRemain) {
1326 nRead = __MIN(nRemain, nMaxSegment);
1327 rs = isc_get_segment(
1328 statusVector,
1329 &hBlob,
1330 &nActualRead,
1331 nRead,
1332 pch);
1333
1334// if (nActualRead == 0) // 혹여나...
1335// break;
1336
1337 if (rs)
1338 break;
1339/*
1340 if ((rs != 0) && (statusVector[1] != isc_segment))
1341 break;
1342*/
1343 nRemain -= nActualRead;
1344 pch += nActualRead;
1345 }
1346
1347 if (statusVector[0] && statusVector[1] && (statusVector[1] != isc_segstr_eof)) {
1348 ISC_STATUS statusVector[ISC_STATUS_VECTOR_LENGTH];
1349 isc_close_blob(statusVector, &hBlob);
1350
1351 // 심각한 오류 !
1353 return false;
1354 }
1355
1356 if (isc_close_blob(statusVector, &hBlob)) {
1358 return false;
1359 }
1360
1361 *_size -= nRemain;
1362
1363 return true;
1364}
1365
1366
1367bool IBField::writeToFromBlob(OutputStream* _output, size_t* _size)
1368{
1369 IBConnection* connHandle = (IBConnection*)Field::connection();
1370 ISC_STATUS* statusVector = connHandle->statusVector();
1371 isc_blob_handle hBlob = NULL;
1372 ISC_QUAD* pBlobID = (ISC_QUAD*)(__sqlvar->sqldata);
1373
1374 if(isc_open_blob2(
1375 statusVector,
1376 connHandle->dbHandlePtr(),
1377 connHandle->trHandlePtr(),
1378 &hBlob,
1379 pBlobID,
1380 0,
1381 NULL)) {
1383 return false;
1384 }
1385
1386 size_t nMaxSegment = 0;
1387 if(!getBlobInfo(&hBlob, isc_info_blob_max_segment, &nMaxSegment)) {
1388 ISC_STATUS statusVector[ISC_STATUS_VECTOR_LENGTH];
1389 isc_close_blob(statusVector, &hBlob);
1390
1392 return false;
1393 }
1394
1395 char* _buf = (char*)malloc(nMaxSegment);
1396 if (!_buf) {
1398 ISC_STATUS statusVector[ISC_STATUS_VECTOR_LENGTH];
1399 isc_close_blob(statusVector, &hBlob);
1400 return false;
1401 }
1402
1403 ISC_STATUS rs = 0;
1404 size_t nRemain = *_size;
1405 unsigned short nActualRead = 0;
1406 unsigned short nRead = 0;
1407
1408 while(nRemain) {
1409 nRead = __MIN(nRemain, nMaxSegment);
1410
1411 rs = isc_get_segment(
1412 statusVector,
1413 &hBlob,
1414 &nActualRead,
1415 nRead,
1416 _buf);
1417
1418 if (nActualRead) {
1419 try {
1420 _output->write(_buf, nActualRead);
1421 }
1422 catch(IOException* e) {
1423 __SET_ERROR_MSG(UTF8Encoder::encode(e->toStringAll()));
1424 e->destroy();
1425 free(_buf);
1426 ISC_STATUS statusVector[ISC_STATUS_VECTOR_LENGTH];
1427 isc_close_blob(statusVector, &hBlob);
1428 return false;
1429 }
1430 nRemain -= nActualRead;
1431 }
1432
1433 if (rs)
1434 break;
1435 }
1436 *_size -= nRemain;
1437
1438 free(_buf);
1439
1440 if (statusVector[0] && statusVector[1] && (statusVector[1] != isc_segstr_eof)) {
1441 ISC_STATUS statusVector[ISC_STATUS_VECTOR_LENGTH];
1442 isc_close_blob(statusVector, &hBlob);
1443
1444 // 심각한 오류 !
1446 return false;
1447 }
1448
1449 if (isc_close_blob(statusVector, &hBlob)) {
1451 return false;
1452 }
1453
1454 return true;
1455}
1456
1457__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
#define INT32_MAX
Definition Config.h:318
#define INT32_MIN
Definition Config.h:313
unsigned char byte_t
Definition Config.h:274
#define INT8_MIN
Definition Config.h:311
#define INT8_MAX
Definition Config.h:316
#define INT16_MAX
Definition Config.h:317
#define INT16_MIN
Definition Config.h:312
#define ISC_STATUS_VECTOR_LENGTH
Definition IBConnection.h:6
const wchar_t * __dataTypeName(const XSQLVAR *_sqlvar)
Definition IBField.cpp:211
size_t __MIN(size_t x, size_t y)
Definition IBField.cpp:1287
#define SQLTYPE_NAME(_dataType, name)
Definition IBField.cpp:209
#define __SET_ERROR_MSG(_message)
const wchar_t * __dataTypeName(const ifx_sqlvar_t *_sqlvar)
Definition IFXField.cpp:290
#define __SQLTYPE_IS(_sqltype)
Definition IFXField.cpp:61
#define __ABS(n)
Definition MyParam.cpp:143
#define __DCL_ASSERT(expr)
Definition Object.h:371
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
Definition Object.h:228
#define __T(str)
Definition Object.h:44
ByteString r
size_t len
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:153
void CharsetConvertException *size_t n
Definition SQLField.cpp:254
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
isc_tr_handle * trHandlePtr()
ISC_STATUS * statusVector()
isc_db_handle * dbHandlePtr()
virtual bool __getDataSize(size_t *_size, bool _maxSize)
Definition IBField.cpp:271
bool getBlobInfo(isc_blob_handle *_blobHandle, char _blob_info_item, size_t *_buf)
Definition IBField.cpp:1257
bool getInteger(void *_buf, size_t *_size)
Definition IBField.cpp:429
virtual bool __getData(void *_buf, size_t *_size, SQL::DataType _dataType)
Definition IBField.cpp:313
bool onAfterFetch()
Definition IBField.cpp:170
bool getDecimal(char *_buf, size_t *_size)
Definition IBField.cpp:1157
bool writeToFromBlob(OutputStream *_output, size_t *_size)
Definition IBField.cpp:1367
bool getUInteger(void *_buf, size_t *_size)
Definition IBField.cpp:629
bool writeTo(OutputStream *_output, size_t *_size)
Definition IBField.cpp:1212
virtual bool isNull() const
Definition IBField.cpp:258
bool getBytesFromBlob(byte_t *_buf, size_t *_size)
Definition IBField.cpp:1292
bool getBytes(byte_t *_buf, size_t *_size)
Definition IBField.cpp:1181
bool init(SQL::Query *_query, XSQLVAR *_sqlvar)
Definition IBField.cpp:49
virtual ~IBField()
Definition IBField.cpp:44
bool getTimeStamp(SQL::TimeStamp *_buf, size_t *_size)
Definition IBField.cpp:1037
bool getTime(SQL::Time *_buf, size_t *_size)
Definition IBField.cpp:989
IBQuery * query() const
Definition IBField.h:71
bool getFloat(void *_buf, size_t *_size)
Definition IBField.cpp:835
virtual const wchar_t * serverDataTypeName() const
Definition IBField.cpp:253
bool getDate(SQL::Date *_buf, size_t *_size)
Definition IBField.cpp:954
static ByteString toByteString(int32_t _n, unsigned _base=10)
Definition Numeric.cpp:365
static ByteString toByteString(int64_t _n, unsigned _base=10)
Definition Numeric.cpp:581
Query * __queryHandle
Definition SQLCore.h:184
DataType
Definition SQLCore.h:62
@ typeBinary
Definition SQLCore.h:77
@ typeNumeric
Definition SQLCore.h:67
@ typeTime
Definition SQLCore.h:69
@ typeLongBinary
Definition SQLCore.h:79
@ typeUInteger
Definition SQLCore.h:65
@ typeTimeStamp
Definition SQLCore.h:71
@ typeTimeStampTz
Definition SQLCore.h:72
@ typeInterval
Definition SQLCore.h:73
@ typeDate
Definition SQLCore.h:68
@ typeOutputStream
Definition SQLCore.h:85
@ typeText
Definition SQLCore.h:76
@ typeTimeTz
Definition SQLCore.h:70
@ typeFloat
Definition SQLCore.h:66
@ typeInteger
Definition SQLCore.h:64
@ typeLongText
Definition SQLCore.h:78
@ eOutOfRange
Definition SQLCore.h:52
@ eOutOfMemory
Definition SQLCore.h:24
@ eNotExecuted
Definition SQLCore.h:42
@ eInvalidBufferSize
Definition SQLCore.h:50
@ eNotSupportDataType
Definition SQLCore.h:48
@ eServerError
Definition SQLCore.h:21
@ eNotFetched
Definition SQLCore.h:43
size_t __MIN(size_t x, size_t y)
Definition size_t.h:27
int16_t year
Definition SQLCore.h:97
uint8_t month
Definition SQLCore.h:98
uint8_t day
Definition SQLCore.h:99
uint8_t hour
Definition SQLCore.h:104
uint8_t sec
Definition SQLCore.h:106
uint32_t frac
Definition SQLCore.h:107
uint8_t min
Definition SQLCore.h:105
int16_t tzoff
Definition SQLCore.h:108
uint32_t frac
Definition SQLCore.h:119
int16_t tzoff
Definition SQLCore.h:120
uint8_t min
Definition SQLCore.h:117
uint8_t sec
Definition SQLCore.h:118
uint8_t hour
Definition SQLCore.h:116
uint8_t day
Definition SQLCore.h:115
int16_t year
Definition SQLCore.h:113
uint8_t month
Definition SQLCore.h:114
int32_t i32
Definition IBField.cpp:425
int16_t i16
Definition IBField.cpp:424
int64_t i64
Definition IBField.cpp:426