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