DCL 3.7.4
Loading...
Searching...
No Matches
PqField Class Reference

#include <PqField.h>

Inheritance diagram for PqField:
SQL::Field Object

Public Member Functions

 PqField ()
virtual ~PqField ()
bool init (SQL::Query *_query, int _index, const PGresult *_res)
virtual const wchar_t * serverDataTypeName () const
virtual bool __getDataSize (size_t *_size, bool _maxsize)
virtual bool __getData (void *_buf, size_t *_size, SQL::DataType _bufType)
Public Member Functions inherited from Object
virtual String toString () const
virtual void destroy ()
String className () const
bool isInstanceOf (const std::type_info &typeinfo) const
virtual const std::type_info & typeInfo () const

Protected Member Functions

PqQueryquery () const
PqConnectionconn () const
bool getInteger (void *_buf, size_t *_size)
bool getUInteger (void *_buf, size_t *_size)
bool getFloat (void *_buf, size_t *_size)
bool getDate (SQL::Date *_buf, size_t *_size)
bool getTime (SQL::Time *_buf, size_t *_size)
bool getTimeStamp (SQL::TimeStamp *_buf, size_t *_size)
bool getInterval (SQL::Interval *_buf, size_t *_size)
bool getNumeric (char *_buf, size_t *_size)
bool getBytes (char *_buf, size_t *_size)
bool writeTo (OutputStream *_output, size_t *_size)
Protected Member Functions inherited from SQL::Field
 Field (Query *_queryHandle)
virtual ~Field ()
Protected Member Functions inherited from Object
virtual ~Object ()
 Object ()

Additional Inherited Members

Protected Attributes inherited from SQL::Field
Query__queryHandle
String __name
DataType __dataType
short __precision
short __scale

Detailed Description

Definition at line 8 of file PqField.h.

Constructor & Destructor Documentation

◆ PqField()

PqField::PqField ( )

◆ ~PqField()

PqField::~PqField ( )
virtual

Definition at line 73 of file PqField.cpp.

74{
75// __DCL_TRACE1("~PqField: %ls", Field::__name.data());
76}

Member Function Documentation

◆ __getData()

bool PqField::__getData ( void * _buf,
size_t * _size,
SQL::DataType _bufType )
virtual

Implements SQL::Field.

Definition at line 253 of file PqField.cpp.

258{
259 switch(_bufType) {
260 case SQL::typeInteger:
261 return getInteger(_buf, _size);
263 return getUInteger(_buf, _size);
264 case SQL::typeFloat:
265 return getFloat(_buf, _size);
266 case SQL::typeDate:
267 return getDate((SQL::Date*)_buf, _size);
268 case SQL::typeTime:
269 return getTime((SQL::Time*)_buf, _size);
271 return getTimeStamp((SQL::TimeStamp*)_buf, _size);
273 return getInterval((SQL::Interval*)_buf, _size);
274 case SQL::typeText:
275 if (Field::__dataType == SQL::typeNumeric) {
276 return getNumeric((char*)_buf, _size);
277 }
278 case SQL::typeBinary:
279 return getBytes((char*)_buf, _size);
281 return writeTo((OutputStream*)_buf, _size);
282 default:
283 __DCL_ASSERT(false); // SQL::Field::getData bug
284 }
285 return true;
286}
#define __DCL_ASSERT(expr)
Definition Object.h:394
bool getTimeStamp(SQL::TimeStamp *_buf, size_t *_size)
Definition PqField.cpp:915
bool writeTo(OutputStream *_output, size_t *_size)
Definition PqField.cpp:1022
bool getNumeric(char *_buf, size_t *_size)
Definition PqField.cpp:968
bool getDate(SQL::Date *_buf, size_t *_size)
Definition PqField.cpp:853
bool getFloat(void *_buf, size_t *_size)
Definition PqField.cpp:698
bool getInteger(void *_buf, size_t *_size)
Definition PqField.cpp:288
bool getBytes(char *_buf, size_t *_size)
Definition PqField.cpp:988
bool getUInteger(void *_buf, size_t *_size)
Definition PqField.cpp:493
bool getInterval(SQL::Interval *_buf, size_t *_size)
Definition PqField.cpp:941
bool getTime(SQL::Time *_buf, size_t *_size)
Definition PqField.cpp:883
@ typeBinary
Definition SQLCore.h:74
@ typeNumeric
Definition SQLCore.h:64
@ typeTime
Definition SQLCore.h:66
@ typeUInteger
Definition SQLCore.h:62
@ typeTimeStamp
Definition SQLCore.h:68
@ typeInterval
Definition SQLCore.h:70
@ typeDate
Definition SQLCore.h:65
@ typeOutputStream
Definition SQLCore.h:82
@ typeText
Definition SQLCore.h:73
@ typeFloat
Definition SQLCore.h:63
@ typeInteger
Definition SQLCore.h:61

◆ __getDataSize()

bool PqField::__getDataSize ( size_t * _size,
bool _maxsize )
virtual

Implements SQL::Field.

Definition at line 234 of file PqField.cpp.

235{
236 if (_maxsize) {
237 *_size = __maxDataSize;
238 return true;
239 }
240
241 const char* value;
242 int length;
243 if (query()->getValue(__index, value, length)) {
244 *_size = length;
245 }
246 else {
247 *_size = (size_t)-1;
248 }
249
250 return true;
251}
PqQuery * query() const
Definition PqField.h:52

◆ conn()

PqConnection * PqField::conn ( ) const
inlineprotected

Definition at line 57 of file PqField.h.

58{
59 return query()->conn();
60}

◆ getBytes()

bool PqField::getBytes ( char * _buf,
size_t * _size )
protected

Definition at line 988 of file PqField.cpp.

989{
990 const char* value;
991 int length;
992 __DCL_VERIFY(query()->getValue(__index, value, length));
993 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
994
995 if (__type == BYTEAOID && __format == __FORMAT_TEXT) {
996 bool __UNUSED__ r = false;
997 const char* srcend = value + length;
998 char* dstend = _buf + *_size;
999 if (__is_hex_escaped(value))
1000 r = __unescape_hex(value, srcend, _buf, dstend);
1001 else
1002 r = __unescape_oct(value, srcend, _buf, dstend);
1003
1004 size_t dstlen = dstend - _buf;
1005 __DCL_TRACE2_N(L"unescaped [%zd][%ls]\n", dstlen, String::valueOf(r).data());
1006
1007 if (dstlen < *_size) {
1008 *(_buf + dstlen) = '\0';
1009 *_size = dstlen;
1010 }
1011 }
1012 else {
1013 if ((size_t) length < *_size) {
1014 *(_buf + length) = '\0';
1015 *_size = length;
1016 }
1017 memcpy(_buf, value, *_size);
1018 }
1019 return true;
1020}
#define __UNUSED__
Definition Config.h:341
#define __DCL_TRACE2_N(fmt, arg1, arg2)
IOException *size_t r
Definition MediaInfo.cpp:82
#define __DCL_VERIFY(expr)
Definition Object.h:396
#define __FORMAT_TEXT
Definition PqQuery.h:6
bool __unescape_hex(const char *_src, const char *&_srcend, char *_dst, char *&_dstend)
Definition PqTypes.cpp:59
bool __unescape_oct(const char *_src, const char *&_srcend, char *_dst, char *&_dstend)
Definition PqTypes.cpp:108
bool __is_hex_escaped(const char *_src)
Definition PqTypes.h:111

◆ getDate()

bool PqField::getDate ( SQL::Date * _buf,
size_t * _size )
protected

Definition at line 853 of file PqField.cpp.

854{
855 if (*_size != sizeof(SQL::Date)) {
857 return false;
858 }
859
860 const char* value;
861 int length;
862 __DCL_VERIFY(query()->getValue(__index, value, length));
863 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
864
865 if (__format == __FORMAT_BINARY) {
866 memset(_buf, 0, sizeof(SQL::Date));
867 }
868 else {
869 SQL::TimeStamp ts;
870 if (!__decode_timestamp_iso(value, NULL, ts)) {
871 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
873 return false;
874 }
875 _buf->year = ts.year;
876 _buf->month = ts.month;
877 _buf->day = ts.day;
878 }
879
880 return true;
881}
#define NULL
Definition Config.h:312
#define __FORMAT_BINARY
Definition PqQuery.h:7
bool __decode_timestamp_iso(const char *_s, const char **_endptr, SQL::TimeStamp &_r)
Definition PqTypes.cpp:176
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:149
@ eInvalidBufferSize
Definition SQLCore.h:50
@ eInvalidData
Definition SQLCore.h:54
int16_t year
Definition SQLCore.h:96
uint8_t month
Definition SQLCore.h:97
uint8_t day
Definition SQLCore.h:98
uint8_t day
Definition SQLCore.h:114
int16_t year
Definition SQLCore.h:112
uint8_t month
Definition SQLCore.h:113

◆ getFloat()

bool PqField::getFloat ( void * _buf,
size_t * _size )
protected

Definition at line 698 of file PqField.cpp.

699{
700 const char* value;
701 int length;
702 double d;
703 __DCL_VERIFY(query()->getValue(__index, value, length));
704 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
705
706 if (__format == __FORMAT_BINARY) {
707 switch (__type) {
708 case BOOLOID: {
709 d = (double)*(int8_t*)value;
710 break;
711 }
712 case INT2OID: {
713 d = (double)(int16_t)__ntohs(*(uint16_t*)value);
714 break;
715 }
716 case INT4OID: {
717 d = (double)(int32_t)__ntohl(*(uint32_t*)value);
718 break;
719 }
720 case INT8OID: {
721 d = (double)(int64_t)__ntohll(*(uint64_t*)value);
722 break;
723 }
724 case FLOAT4OID: {
725 d = (double)__ntohf(*(uint32_t*)value);
726 break;
727 }
728 case FLOAT8OID: {
729 d = (double)__ntohd(*(uint64_t*)value);
730 break;
731 }
732 case MONEYOID:
733 case NUMERICOID: {
734 d = 0;
735 }
736 default: {
738 return false;
739 }
740 }
741 }
742 else { // __FORMAT_TEXT
743 ByteString s; // for MONEYOID
744 switch (__type) {
745 case BOOLOID: {
746 d = strchr("fF0", *value) ? 0 : 1;
747 break;
748 }
749 case INT2OID:
750 case INT4OID:
751 case INT8OID: {
752 errno = 0;
753 char* endptr = NULL;
754 long long n = strtoll(value, &endptr, 10);
755 if (errno == ERANGE) {
757 n == LLONG_MAX || n == LLONG_MIN // overflow
758 );
759 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
761 return false;
762 }
763 #if __UNNEED__
764 else if (errno == EINVAL) {
765 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
767 return false;
768 }
769 #endif
770 d = (double)n;
771 break;
772 }
773 case FLOAT4OID:
774 case FLOAT8OID: {
775 errno = 0;
776 char* endptr = NULL;
777 d = strtod(value, &endptr);
778 if (errno == ERANGE) {
780 +HUGE_VAL == d || -HUGE_VAL == d // overflow
781 || !(DBL_MIN < d) // underflow
782 );
783 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
785 return false;
786 }
787 #if __UNNEED__
788 else if (errno == EINVAL) {
789 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
791 return false;
792 }
793 #endif
794 break;
795 }
796 case MONEYOID: {
797 s.assign(value, length);
798 s = s.replace_r("[^0-9\\.]", "", false);
799 value = s.data();
800 }
801 case NUMERICOID: {
802 errno = 0;
803 char* endptr = NULL;
804 d = strtod(value, &endptr);
805 if (errno == ERANGE) {
807 +HUGE_VAL == d || -HUGE_VAL == d // overflow
808 || !(DBL_MIN < d) // underflow
809 );
810 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
812 return false;
813 }
814 #if __UNNEED__
815 else if (errno == EINVAL) {
816 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
818 return false;
819 }
820 #endif
821 break;
822 }
823 default: {
825 return false;
826 }
827 }
828 }
829
830 switch (*_size) {
831 case sizeof(float) : {
832 if (d < -FLT_MAX || FLT_MAX < d) {
834 return false;
835 }
836 *(float*)_buf = (float)d;
837 break;
838 }
839 case sizeof(double) : {
840 *(double*)_buf = (double)d;
841 break;
842 }
843 default: {
844 *_size = sizeof(double);
846 return false;
847 }
848 }
849
850 return true;
851}
#define __ntohll(_x)
Definition PqTypes.h:47
float __ntohf(uint32_t _x)
Definition PqTypes.h:89
#define __ntohl(_x)
Definition PqTypes.h:46
#define __ntohs(_x)
Definition PqTypes.h:45
double __ntohd(uint64_t _x)
Definition PqTypes.h:100
@ eOutOfRange
Definition SQLCore.h:52
@ eInvalidDataType
Definition SQLCore.h:49

◆ getInteger()

bool PqField::getInteger ( void * _buf,
size_t * _size )
protected

Definition at line 288 of file PqField.cpp.

289{
290 const char* value;
291 int length;
292 long long n;
293 __DCL_VERIFY(query()->getValue(__index, value, length));
294 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
295
296 if (__format == __FORMAT_BINARY) {
297 switch (__type) {
298 case BOOLOID: {
299 n = *(int8_t*)value;
300 break;
301 }
302 case INT2OID: {
303 n = (int16_t)__ntohs(*(uint16_t*)value);
304 break;
305 }
306 case INT4OID: {
307 n = (int32_t)__ntohl(*(uint32_t*)value);
308 break;
309 }
310 case INT8OID: {
311 n = (int64_t)__ntohll(*(uint64_t*)value);
312 break;
313 }
314 case FLOAT4OID: {
315 n = (int64_t)__ntohf(*(uint32_t*)value);
316 break;
317 }
318 case FLOAT8OID: {
319 n = (int64_t)__ntohd(*(uint64_t*)value);
320 break;
321 }
322 case MONEYOID:
323 case NUMERICOID: {
324 n = 0;
325 }
326 default: {
328 return false;
329 }
330 }
331 }
332 else { // __FORMAT_TEXT
333 ByteString s; // for MONEYOID
334 switch (__type) {
335 case BOOLOID: {
336 n = strchr("fF0", *value) ? 0 : 1;
337 break;
338 }
339 case INT2OID:
340 case INT4OID:
341 case INT8OID: {
342 errno = 0;
343 char* endptr = NULL;
344 n = strtoll(value, &endptr, 10);
345 if (errno == ERANGE) {
347 n == LLONG_MAX || n == LLONG_MIN // overflow
348 );
349 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
351 return false;
352 }
353 #define __UNNEED__ 0
354 #if __UNNEED__
355 else if (errno == EINVAL) {
356 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
358 return false;
359 }
360 #endif
361 break;
362 }
363 case FLOAT4OID:
364 case FLOAT8OID: {
365 errno = 0;
366 char* endptr = NULL;
367 double d = strtod(value, &endptr);
368 if (errno == ERANGE) {
370 +HUGE_VAL == d || -HUGE_VAL == d // overflow
371 || !(DBL_MIN < d) // underflow
372 );
373 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
375 return false;
376 }
377 #if __UNNEED__
378 else if (errno == EINVAL) {
379 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
381 return false;
382 }
383 #endif
384 double i;
385 (void)modf(d, &i); // 정수부분만, 반환값(소수)는 버림
386 if (i < (double)LLONG_MIN || (double)LLONG_MAX < i) {
388 return false;
389 }
390 n = (long long)i;
391 break;
392 }
393 case MONEYOID: {
394 s.assign(value, length);
395 s = s.replace_r("[^0-9\\.]", "", false);
396 value = s.data();
397 }
398 case NUMERICOID: {
399 errno = 0;
400 char* endptr = NULL;
401 if ((Field::__precision - Field::__scale) < 20) {
402 n = strtoll(value, &endptr, 10);
403 if (errno == ERANGE) {
405 n == LLONG_MAX || n == LLONG_MIN // overflow
406 );
407 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
409 return false;
410 }
411 #if __UNNEED__
412 else if (errno == EINVAL) {
413 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
415 return false;
416 }
417 #endif
418 }
419 else {
420 double d = strtod(value, &endptr);
421 if (errno == ERANGE) {
423 +HUGE_VAL == d || -HUGE_VAL == d // overflow
424 || !(DBL_MIN < d) // underflow
425 );
426 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
428 return false;
429 }
430 #if __UNNEED__
431 else if (errno == EINVAL) {
432 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
434 return false;
435 }
436 #endif
437 double i;
438 (void)modf(d, &i); // 정수부분만, 반환값(소수)는 버림
439 if (i < (double)LLONG_MIN || (double)LLONG_MAX < i) {
441 return false;
442 }
443 n = (long long)i;
444 }
445 break;
446 }
447 default: {
449 return false;
450 }
451 }
452 }
453
454 switch (*_size) {
455 case sizeof(int8_t) : {
456 if (n < INT8_MIN || INT8_MAX < n) {
458 return false;
459 }
460 *(int8_t*)_buf = (int8_t)n;
461 break;
462 }
463 case sizeof(int16_t) : {
464 if (n < INT16_MIN || INT16_MAX < n) {
466 return false;
467 }
468 *(int16_t*)_buf = (int16_t)n;
469 break;
470 }
471 case sizeof(int32_t) : {
472 if (n < INT32_MIN || INT32_MAX < n) {
474 return false;
475 }
476 *(int32_t*)_buf = (int32_t)n;
477 break;
478 }
479 case sizeof(int64_t) : {
480 *(int64_t*)_buf = (int64_t)n;
481 break;
482 }
483 default: {
484 *_size = sizeof(int64_t);
486 return false;
487 }
488 }
489
490 return true;
491}
#define INT32_MAX
Definition Config.h:290
#define INT32_MIN
Definition Config.h:285
#define INT8_MIN
Definition Config.h:283
#define INT8_MAX
Definition Config.h:288
#define INT16_MAX
Definition Config.h:289
#define INT16_MIN
Definition Config.h:284

◆ getInterval()

bool PqField::getInterval ( SQL::Interval * _buf,
size_t * _size )
protected

Definition at line 941 of file PqField.cpp.

942{
943 if (*_size != sizeof(SQL::Interval)) {
945 return false;
946 }
947
948 const char* value;
949 int length;
950 __DCL_VERIFY(query()->getValue(__index, value, length));
951 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
952
953 if (__format == __FORMAT_BINARY) {
954 memset(_buf, 0, sizeof(SQL::Interval));
955 }
956 else {
957 if (!__decode_interval_iso(value, NULL, *_buf)) {
958 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
960 return false;
961 }
962
963 }
964
965 return true;
966}
bool __decode_interval_iso(const char *_s, const char **_endptr, SQL::Interval &_r)
Definition PqTypes.cpp:308

◆ getNumeric()

bool PqField::getNumeric ( char * _buf,
size_t * _size )
protected

Definition at line 968 of file PqField.cpp.

969{
970 const char* value;
971 int length;
972 __DCL_VERIFY(query()->getValue(__index, value, length));
973 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
974
975 if (__format == __FORMAT_BINARY) {
976 *_size = 0;
977 }
978 else { // __FORMAT_TEXT
979 if ((size_t)length < *_size) {
980 *(_buf + length) = '\0';
981 *_size = length;
982 }
983 memcpy(_buf, value, *_size);
984 }
985
986 return true;
987}

◆ getTime()

bool PqField::getTime ( SQL::Time * _buf,
size_t * _size )
protected

Definition at line 883 of file PqField.cpp.

884{
885 if (*_size != sizeof(SQL::Time)) {
887 return false;
888 }
889
890 const char* value;
891 int length;
892 __DCL_VERIFY(query()->getValue(__index, value, length));
893 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
894
895 if (__format == __FORMAT_BINARY) {
896 memset(_buf, 0, sizeof(SQL::Time));
897 }
898 else {
899 SQL::TimeStamp ts;
900 if (!__decode_timestamp_iso(value, NULL, ts)) {
901 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
903 return false;
904 }
905 _buf->hour = ts.hour;
906 _buf->min = ts.min;
907 _buf->sec = ts.sec;
908 _buf->frac = ts.frac;
909 _buf->tzoff = ts.tzoff;
910 }
911
912 return true;
913}
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

◆ getTimeStamp()

bool PqField::getTimeStamp ( SQL::TimeStamp * _buf,
size_t * _size )
protected

Definition at line 915 of file PqField.cpp.

916{
917 if (*_size != sizeof(SQL::TimeStamp)) {
919 return false;
920 }
921
922 const char* value;
923 int length;
924 __DCL_VERIFY(query()->getValue(__index, value, length));
925 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
926
927 if (__format == __FORMAT_BINARY) {
928 memset(_buf, 0, sizeof(SQL::TimeStamp));
929 }
930 else {
931 if (!__decode_timestamp_iso(value, NULL, *_buf)) {
932 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
934 return false;
935 }
936 }
937
938 return true;
939}

◆ getUInteger()

bool PqField::getUInteger ( void * _buf,
size_t * _size )
protected

Definition at line 493 of file PqField.cpp.

494{
495 const char* value;
496 int length;
497 unsigned long long u;
498 ByteString s;
499 __DCL_VERIFY(query()->getValue(__index, value, length));
500 __DCL_TRACE2_N(L"[%d][%ls]\n", length, String::tryString(value, length).data());
501
502 if (__format == __FORMAT_BINARY) {
503 switch (__type) {
504 case BOOLOID: {
505 u = *(uint8_t*)value;
506 break;
507 }
508 case INT2OID: {
509 u = (uint16_t)__ntohs(*(uint16_t*)value);
510 break;
511 }
512 case INT4OID: {
513 u = (uint32_t)__ntohl(*(uint32_t*)value);
514 break;
515 }
516 case INT8OID: {
517 u = (uint64_t)__ntohll(*(uint64_t*)value);
518 break;
519 }
520 case FLOAT4OID: {
521 u = (uint64_t)__ntohf(*(uint32_t*)value);
522 break;
523 }
524 case FLOAT8OID: {
525 u = (uint64_t)__ntohd(*(uint64_t*)value);
526 break;
527 }
528 case MONEYOID:
529 case NUMERICOID: {
530 u = 0;
531 }
532 default: {
534 return false;
535 }
536 }
537 }
538 else { // __FORMAT_TEXT
539 ByteString s; // for MONEYOID
540 switch (__type) {
541 case BOOLOID: {
542 u = strchr("fF0", *value) ? 0 : 1;
543 break;
544 }
545 case INT2OID:
546 case INT4OID:
547 case INT8OID: {
548 errno = 0;
549 char* endptr = NULL;
550 u = strtoull(value, &endptr, 10);
551 if (errno == ERANGE) {
553 u == ULONG_MAX // overflow
554 );
555 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
557 return false;
558 }
559 #if __UNNEED__
560 else if (errno == EINVAL) {
561 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
563 return false;
564 }
565 #endif
566 break;
567 }
568 case FLOAT4OID:
569 case FLOAT8OID: {
570 errno = 0;
571 char* endptr = NULL;
572 double d = strtod(value, &endptr);
573 if (errno == ERANGE) {
575 +HUGE_VAL == d || -HUGE_VAL == d // overflow
576 || !(DBL_MIN < d) // underflow
577 );
578 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
580 return false;
581 }
582 #if __UNNEED__
583 else if (errno == EINVAL) {
584 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
586 return false;
587 }
588 #endif
589 double i;
590 (void)modf(d, &i); // 정수부분만, 반환값(소수)는 버림
591 if (i < (double)LLONG_MIN || (double)LLONG_MAX < i) {
593 return false;
594 }
595 u = (unsigned long long)i;
596 break;
597 }
598 case MONEYOID: {
599 s.assign(value, length);
600 s = s.replace_r("[^0-9\\.]", "", false);
601 value = s.data();
602 }
603 case NUMERICOID: {
604 errno = 0;
605 char* endptr = NULL;
606 if ((Field::__precision - Field::__scale) <= 20) {
607 u = strtoull(value, &endptr, 10);
608 if (errno == ERANGE) {
610 u == ULONG_MAX // overflow
611 );
612 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
614 return false;
615 }
616 #if __UNNEED__
617 else if (errno == EINVAL) {
618 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
620 return false;
621 }
622 #endif
623 }
624 else {
625 double d = strtod(value, &endptr);
626 if (errno == ERANGE) {
628 +HUGE_VAL == d || -HUGE_VAL == d // overflow
629 || !(DBL_MIN < d) // underflow
630 );
631 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
633 return false;
634 }
635 #if __UNNEED__
636 else if (errno == EINVAL) {
637 // API 버그 또는 서버로부터 수신된 값에 오류가 있다.
639 return false;
640 }
641 #endif
642 double i;
643 (void)modf(d, &i); // 정수부분만, 반환값(소수)는 버림
644 if (i < 0 || (double)ULONG_MAX < i) {
646 return false;
647 }
648 u = (unsigned long long)i;
649 }
650 break;
651 }
652 default: {
654 return false;
655 }
656 }
657 }
658
659 switch (*_size) {
660 case sizeof(uint8_t) : {
661 if (UINT8_MAX < u) {
663 return false;
664 }
665 *(uint8_t*)_buf = (uint8_t)u;
666 break;
667 }
668 case sizeof(uint16_t) : {
669 if (UINT16_MAX < u) {
671 return false;
672 }
673 *(uint16_t*)_buf = (uint16_t)u;
674 break;
675 }
676 case sizeof(uint32_t) : {
677 if (UINT32_MAX < u) {
679 return false;
680 }
681 *(uint32_t*)_buf = (uint32_t)u;
682 break;
683 }
684 case sizeof(uint64_t) : {
685 *(uint64_t*)_buf = (uint64_t)u;
686 break;
687 }
688 default: {
689 *_size = sizeof(uint64_t);
691 return false;
692 }
693 }
694
695 return true;
696}
#define UINT16_MAX
Definition Config.h:294
#define UINT32_MAX
Definition Config.h:295
#define UINT8_MAX
Definition Config.h:293

◆ init()

bool PqField::init ( SQL::Query * _query,
int _index,
const PGresult * _res )

Definition at line 78 of file PqField.cpp.

79{
80 __DCL_ASSERT(Field::__queryHandle == NULL);
81 __DCL_ASSERT(_queryHandle != NULL && _res != NULL);
82
83 Field::__queryHandle = _queryHandle;
84
85 try {
86 Field::__name = UTF8Decoder::decode(PQfname(_res, _index)).toUpperCase();
87 }
88 catch (CharsetConvertException* _e) {
89 __SET_ERROR_MSG(UTF8Encoder::encode(_e->toStringAll()));
90 _e->destroy();
91 return false;
92 }
93
94 __index = _index;
95 __type = PQftype(_res, _index);
96 __size = PQfsize(_res, _index);
97 __format = PQfformat(_res, _index);
98 int mod = PQfmod(_res, _index);
99
100 switch (__type) {
101 case BOOLOID: {
102 Field::__dataType = SQL::typeInteger;
103 Field::__precision = 1;
104 break;
105 }
106 case INT2OID: {
107 Field::__dataType = SQL::typeInteger;
108 Field::__precision = 5;
109 break;
110 }
111 case INT4OID: {
112 Field::__dataType = SQL::typeInteger;
113 Field::__precision = 10;
114 break;
115 }
116 case INT8OID: {
117 Field::__dataType = SQL::typeInteger;
118 Field::__precision = 19;
119 break;
120 }
121 case FLOAT4OID: {
122 Field::__dataType = SQL::typeFloat;
123 break;
124 }
125 case FLOAT8OID: {
126 Field::__dataType = SQL::typeFloat;
127 break;
128 }
129 case MONEYOID: {
130 Field::__dataType = SQL::typeNumeric;
131 Field::__precision = 19;
132 Field::__scale = 2;
133 break;
134 }
135 case NUMERICOID: {
136 Field::__dataType = SQL::typeNumeric;
137 Field::__precision = mod >> 16;
138 Field::__scale = (mod - 4) & 0xffff;
139 break;
140 }
141 case DATEOID: {
142 Field::__dataType = SQL::typeDate;
143 __maxDataSize = sizeof(SQL::Date);
144 break;
145 }
146 case TIMEOID: {
147 Field::__dataType = SQL::typeTime;
148 Field::__scale = 6;
149 __maxDataSize = sizeof(SQL::Time);
150 break;
151 }
152 case TIMETZOID: {
153 Field::__dataType = SQL::typeTimeTz;
154 Field::__scale = 6;
155 __maxDataSize = sizeof(SQL::Time);
156 break;
157 }
158 case TIMESTAMPOID: {
159 Field::__dataType = SQL::typeTimeStamp;
160 Field::__scale = 6;
161 __maxDataSize = sizeof(SQL::TimeStamp);
162 break;
163 }
164 case TIMESTAMPTZOID: {
165 Field::__dataType = SQL::typeTimeStampTz;
166 Field::__scale = 6;
167 __maxDataSize = sizeof(SQL::TimeStamp);
168 break;
169 }
170 case INTERVALOID: {
171 Field::__dataType = SQL::typeInterval;
172 Field::__precision = mod >> 16;
173 Field::__scale = (mod - 4) & 0xffff;
174 __maxDataSize = sizeof(SQL::Interval);
175 break;
176 }
177 case BITOID:
178 case VARBITOID: {
179 Field::__dataType = SQL::typeText;
180 __maxDataSize = mod;
181 break;
182 }
183 case CHAROID:
184 case BPCHAROID:
185 case VARCHAROID: {
186 Field::__dataType = SQL::typeText;
187 if (mod != -1) {
188 __maxDataSize = mod - 4;
189 }
190 break;
191 }
192 case TEXTOID:
193 case JSONOID:
194 case XMLOID:
195
196 case MACADDROID:
197 case INETOID:
198 case CIDROID:
199 case MACADDR8OID:
200
201 case UUIDOID:
202
203 case TSVECTOROID:
204 case TSQUERYOID:
205 case JSONBOID:
206 case JSONPATHOID:
207 default: {
208 Field::__dataType = SQL::typeText;
209 break;
210 }
211
212 case BYTEAOID: {
213 Field::__dataType = SQL::typeBinary;
214 break;
215 }
216 }
217
218 if (__maxDataSize == 0) {
219 __maxDataSize = __size >= 0 ?
220 __size : 10 * 1024 * 1024; // cannot exceed 1 GB;
221 }
222
223 __DCL_TRACE6_N(L"Field [%2d] size [%6d %7d %3d,%3d] [%ls]\n",
224 __index, __size, mod, __precision, __scale, __name.data());
225
226 return true;
227}
#define __SET_ERROR_MSG(_message)
#define __DCL_TRACE6_N(fmt, arg1, arg2, arg3, arg4, arg5, arg6)
Definition ODBCQuery.cpp:45
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
short __precision
Definition SQLCore.h:189
short __scale
Definition SQLCore.h:190
String __name
Definition SQLCore.h:187
@ typeTimeStampTz
Definition SQLCore.h:69
@ typeTimeTz
Definition SQLCore.h:67

◆ query()

PqQuery * PqField::query ( ) const
inlineprotected

Definition at line 52 of file PqField.h.

53{
54 return (PqQuery*)Field::__queryHandle;
55}

◆ serverDataTypeName()

const wchar_t * PqField::serverDataTypeName ( ) const
virtual

Implements SQL::Field.

Definition at line 229 of file PqField.cpp.

230{
231 return __dataTypeName(__type);
232}
const wchar_t * __dataTypeName(const ifx_sqlvar_t *_sqlvar)
Definition IFXField.cpp:304

◆ writeTo()

bool PqField::writeTo ( OutputStream * _output,
size_t * _size )
protected

Definition at line 1022 of file PqField.cpp.

1023{
1024 const char* value;
1025 int length;
1026 __DCL_VERIFY(query()->getValue(__index, value, length));
1027
1028 if (__type == BYTEAOID && __format == __FORMAT_TEXT) {
1029 try {
1030 size_t total = 0;
1031 bool __is_hex = __is_hex_escaped(value);
1032 char buf[4096];
1033 const char* src = value;
1034 const char* srcend = value + length;
1035 while (src < srcend && total < *_size) {
1036 char* dstend = buf + sizeof(buf);
1037 bool __UNUSED__ r = __is_hex ? __unescape_hex(src, srcend, buf, dstend)
1038 : __unescape_oct(src, srcend, buf, dstend);
1039
1040 size_t dstlen = dstend - buf;
1041 __DCL_TRACE2_N(L"unescaped [%zd][%ls]\n", dstlen, String::valueOf(r).data());
1042 if (dstlen) {
1043 _output->write(buf, dstlen);
1044 total += dstlen;
1045 }
1046 // value의 데이터에 오류가 있어서 dstlen이 0인 경우도 있을 수 있다.
1047 // srclen이 0dl 될때까지 반복한다.
1048 src = srcend;
1049 srcend = value + length;
1050 }
1051 }
1052 catch (IOException* e) {
1053 __SET_ERROR_MSG(UTF8Encoder::encode(e->toStringAll()));
1054 e->destroy();
1055 return false;
1056 }
1057 }
1058 else {
1059 if ((size_t)length < *_size) {
1060 *_size = length;
1061 }
1062 try {
1063 _output->write(value, *_size);
1064 }
1065 catch (IOException* e) {
1066 __SET_ERROR_MSG(UTF8Encoder::encode(e->toStringAll()));
1067 e->destroy();
1068 return false;
1069 }
1070 }
1071 return true;
1072}

The documentation for this class was generated from the following files: