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

#include <OciField.h>

Inheritance diagram for OciField:
SQL::Field OciData Object

Public Member Functions

bool init (SQL::Query *_query, ub4 _position, ub2 _type, void *_buf, ub2 _buflen)
 OciField ()
virtual ~OciField ()
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
Public Member Functions inherited from OciData
bool onAfterFetch ()

Protected Member Functions

sb4 defineCallback (OCIDefine *_defnp, ub4 _iter, dvoid **_bufpp, ub4 **_alenpp, ub1 *_piecep, dvoid **_indpp, ub2 **_rcodep)
Protected Member Functions inherited from SQL::Field
 Field (Query *_queryHandle)
virtual ~Field ()
Protected Member Functions inherited from Object
virtual ~Object ()
 Object ()
Protected Member Functions inherited from OciData
OciConnectionconn () const
 OciData ()
 ~OciData ()
const wchar_t * serverDataTypeName () const
bool getDataSize (size_t *_size, bool _maxsize)
bool getData (void *_buf, size_t *_size, SQL::DataType _bufType)
bool getInteger (void *_buf, size_t *_size, SQL::DataType _bufType)
bool getFloat (void *_buf, size_t *_size)
bool getNumericText (char *_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)
bool getInterval (SQL::Interval *_buf)
bool getBytes (byte_t *_buf, size_t *_size)
bool writeTo (OutputStream *_buf, size_t *_size)
bool getBytesFromLob (byte_t *_buf, size_t *_size)
bool writeToFromLob (OutputStream *_output, size_t *_size)

Static Protected Member Functions

static sb4 defineCallback (dvoid *_octxp, OCIDefine *_defnp, ub4 _iter, dvoid **_bufpp, ub4 **_alenpp, ub1 *_piecep, dvoid **_indpp, ub2 **_rcodepp)

Additional Inherited Members

Static Public Member Functions inherited from OciData
static const wchar_t * __TYPE_NAME (ub2 _sqlt)
static ub4 __TYPE_SIZE (ub2 _sqlt, ub4 _size)
static size_t __TYPE_ALIGN (size_t _offset, ub2 _sqlt)
Protected Attributes inherited from SQL::Field
Query__queryHandle
String __name
DataType __dataType
short __precision
short __scale
Protected Attributes inherited from OciData
ub4 __position
ub4 __dynamicMode
ub4 __descType
void * __valuePtr
sb4 __valueSize
ub2 __valueType
sb2 __indicator
ub2 __actualLength
ub2 __returnCode
ub4 __callbackActualLength
BytesOutputStream__bytesOutput
size_t __dataSize
size_t __maxDataSize

Detailed Description

Definition at line 10 of file OciField.h.

Constructor & Destructor Documentation

◆ OciField()

OciField::OciField ( )

◆ ~OciField()

OciField::~OciField ( )
virtual

Definition at line 56 of file OciField.cpp.

57{
60 conn()->DescriptorFree(
61 *(void**)OciData::__valuePtr,
63 ) == OCI_SUCCESS
64 );
65 }
66}
#define __DCL_VERIFY(expr)
Definition Object.h:396
void * __valuePtr
Definition OciData.h:20
OciConnection * conn() const
Definition OciData.h:67
ub4 __descType
Definition OciData.h:19

Member Function Documentation

◆ __getData()

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

Implements SQL::Field.

Definition at line 393 of file OciField.cpp.

398{
399#if __TRACE_THIS && 0
400 __DCL_TRACE3_N(L"Field::__name[%ls] _bufType[%3d] _size[%zd]\n",
401 Field::__name.data(), _bufType, *_size);
402 bool r = OciData::getData(_buf, _size, _bufType);
403 __DCL_TRACE3_N(L"Field::__name[%ls] _bufType[%3d] _size[%zd]\n",
404 Field::__name.data(), _bufType, *_size);
405 if (_bufType == SQL::typeText) {
406 __DCL_TRACE1_N(L"_buf[%ls]\n",
407 String::tryString((const char*) _buf, *_size).data());
408 }
409 return r;
410#else
411 return OciData::getData(_buf, _size, _bufType);
412#endif
413}
#define __DCL_TRACE1_N(fmt, arg)
#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
IOException *size_t r
Definition MediaInfo.cpp:82
bool getData(void *_buf, size_t *_size, SQL::DataType _bufType)
Definition OciData.cpp:193
@ typeText
Definition SQLCore.h:73

◆ __getDataSize()

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

Implements SQL::Field.

Definition at line 388 of file OciField.cpp.

389{
390 return OciData::getDataSize(_size, _maxsize);
391}
bool getDataSize(size_t *_size, bool _maxsize)
Definition OciData.cpp:169

◆ defineCallback() [1/2]

sb4 OciField::defineCallback ( dvoid * _octxp,
OCIDefine * _defnp,
ub4 _iter,
dvoid ** _bufpp,
ub4 ** _alenpp,
ub1 * _piecep,
dvoid ** _indpp,
ub2 ** _rcodepp )
staticprotected

Definition at line 415 of file OciField.cpp.

425{
426 return ((OciField*)_octxp)->defineCallback(
427 _defnp,
428 _iter,
429 _bufpp,
430 _alenpp,
431 _piecep,
432 _indpp,
433 _rcodepp
434 );
435}

◆ defineCallback() [2/2]

sb4 OciField::defineCallback ( OCIDefine * _defnp,
ub4 _iter,
dvoid ** _bufpp,
ub4 ** _alenpp,
ub1 * _piecep,
dvoid ** _indpp,
ub2 ** _rcodep )
protected

Definition at line 437 of file OciField.cpp.

446{
447 __DCL_ASSERT(OciData::__dynamicMode == OCI_DYNAMIC_FETCH);
448
449#if defined(__DCL_DEBUG) && 0
450 switch(*_piecep) {
451 case OCI_ONE_PIECE:
452 __DCL_TRACE1_N(L"OCI_ONE_PIECE [%d]\n", __position);
453 break;
454 case OCI_FIRST_PIECE:
455 __DCL_TRACE1_N(L"OCI_FIRST_PIECE [%d]\n", __position);
456 break;
457 case OCI_NEXT_PIECE:
458 __DCL_TRACE1_N(L"OCI_NEXT_PIECE [%d]\n", __position);
459 break;
460 case OCI_LAST_PIECE:
461 __DCL_TRACE1_N(L"OCI_LAST_PIECE [%d]\n", __position);
462 }
463#endif
464
465 if (*_piecep == OCI_ONE_PIECE)
466 *_piecep = OCI_FIRST_PIECE;
467
468 if (*_piecep == OCI_FIRST_PIECE) {
470 OciData::__bytesOutput->reset();
471 }
472 else {
474 OciData::__bytesOutput = new BytesOutputStream();
477 return OCI_ERROR;
478 }
479
480 }
482 try {
483 // 이전 PIECE 데이터를 보관한다.
485 }
486 catch(IOException* _cause) {
487 __SET_ERROR_MSG(UTF8Encoder::encode(_cause->toStringAll()));
488 _cause->destroy();
489 return OCI_ERROR;
490 }
491 }
492
493 // OCI_DYNAMIC_FETCH에서 버퍼의 크기는 __actualLength에 보관되어있다.
496 *_bufpp = OciData::__valuePtr;
498 *_indpp = &(OciData::__indicator);
499 *_rcodepp = &(OciData::__returnCode);
500
501 return OCI_CONTINUE;
502}
#define NULL
Definition Config.h:312
#define __SET_ERROR_MSG(_message)
#define __SET_ERROR_HANDLE(_SQLCODE)
#define __DCL_ASSERT(expr)
Definition Object.h:394
#define __DYNAMIC_BUFFER_SIZE
Definition OciData.h:11
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
sb2 __indicator
Definition OciData.h:24
ub2 __actualLength
Definition OciData.h:25
ub4 __dynamicMode
Definition OciData.h:17
ub4 __position
Definition OciData.h:16
ub2 __returnCode
Definition OciData.h:26
ub4 __callbackActualLength
Definition OciData.h:27
BytesOutputStream * __bytesOutput
Definition OciData.h:29
@ eOutOfMemory
Definition SQLCore.h:24

◆ init()

bool OciField::init ( SQL::Query * _query,
ub4 _position,
ub2 _type,
void * _buf,
ub2 _buflen )

Definition at line 73 of file OciField.cpp.

76{
77 __DCL_ASSERT(_queryHandle != NULL);
78 Field::__queryHandle = _queryHandle;
79 OciData::__position = _position; // 1, 2, 3, ...
80 __sqlt = _sqlt;
81
82 OCIParam* param = NULL;
83 sword status = OCIParamGet(
84 query()->stmtHandle(), // const void *hndlp
85 OCI_HTYPE_STMT, // ub4 htype
86 conn()->errorHandle(), // OCIError *errhp
87 (dvoid**)&param, // void **parmdpp
88 _position // ub4 pos
89 );
90 if (status != OCI_SUCCESS) {
91 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
92 return false;
93 }
94
95 text* name = NULL;
96 ub4 size = 0;
97 status = OCIAttrGet(
98 param, // const void *trgthndlp
99 OCI_DTYPE_PARAM, // ub4 trghndltyp
100 &name, // void *attributep
101 &size, // ub4 *sizep
102 OCI_ATTR_NAME, // ub4 attrtype
103 conn()->errorHandle() // OCIError *errhp
104 );
105 if (status != OCI_SUCCESS) {
106 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
107 return false;
108 }
109
110 try {
111 Field::__name = UTF8Decoder::decode((const char*)name, size);
112 }
113 catch (CharsetConvertException* _e) {
114 __SET_ERROR_MSG(UTF8Encoder::encode(_e->toStringAll()));
115 _e->destroy();
116 return false;
117 }
118
119 sb2 precision = 0;
120 size = sizeof(precision);
121 status = OCIAttrGet(
122 param, // const void *trgthndlp
123 OCI_DTYPE_PARAM, // ub4 trghndltyp
124 &precision, // void *attributep
125 &size, // ub4 *sizep
126 OCI_ATTR_PRECISION, // ub4 attrtype
127 conn()->errorHandle() // OCIError *errhp
128 );
129 __DCL_ASSERT(size == sizeof(precision));
130 if (status != OCI_SUCCESS) {
131 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
132 return false;
133 }
134
135 sb1 scale = 0;
136 size = sizeof(scale);
137 status = OCIAttrGet(
138 param, // const void *trgthndlp
139 OCI_DTYPE_PARAM, // ub4 trghndltyp
140 &scale, // void *attributep
141 &size, // ub4 *sizep
142 OCI_ATTR_SCALE, // ub4 attrtype
143 conn()->errorHandle() // OCIError *errhp
144 );
145 __DCL_ASSERT(size == sizeof(scale));
146 if (status != OCI_SUCCESS) {
147 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
148 return false;
149 }
150
151 Field::__precision = precision;
152 Field::__scale = scale;
153
154#ifdef __DCL_DEBUG
155 // ub2 dataSize 이었었는데, Assert failed 되었다.
156 // 반환값의 범위는 0 ~ 4000이다.
157 ub4 dataSize = 0;
158 size = sizeof(dataSize);
159 status = OCIAttrGet(
160 param, // const void *trgthndlp
161 OCI_DTYPE_PARAM, // ub4 trghndltyp
162 &dataSize, // void *attributep
163 &size, // ub4 *sizep
164 OCI_ATTR_DATA_SIZE, // ub4 attrtype
165 conn()->errorHandle() // OCIError *errhp
166 );
167 __DCL_ASSERT(size == sizeof(dataSize));
168 if (status != OCI_SUCCESS) {
169 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
170 return false;
171 }
172 __DCL_TRACE5_N(L"Field [%2d] size [%6d %3d,%3d] [%ls]\n",
173 __position, dataSize, precision, scale, __name.data());
174#endif
175
176 OciData::__dynamicMode = OCI_DEFAULT;
177 OciData::__valueSize = _buflen;
178 OciData::__valueType = _sqlt;
179 switch(_sqlt) {
180 case SQLT_NUM: {
181 OciData::__valueType = SQLT_VNU;
182 // between 1.0 x 10^-130 and 9.9...9 x 10^125
183 // (38 nines followed by 88 zeroes)
185 Field::__dataType = SQL::typeNumeric;
186 break;
187 }
188 case SQLT_IBFLOAT: {
189 OciData::__valueType = SQLT_BFLOAT;
190 OciData::__maxDataSize = sizeof(float);
191 Field::__dataType = SQL::typeFloat;
192 break;
193 }
194 case SQLT_IBDOUBLE: {
195 OciData::__valueType = SQLT_BDOUBLE;
196 OciData::__maxDataSize = sizeof(double);
197 Field::__dataType = SQL::typeFloat;
198 break;
199 }
200 case SQLT_DAT: {
201 OciData::__valueType = SQLT_ODT;
202 OciData::__maxDataSize = sizeof(SQL::TimeStamp);
203 Field::__dataType = SQL::typeTimeStamp;
204 break;
205 }
206 case SQLT_TIMESTAMP: {
207 OciData::__descType = OCI_DTYPE_TIMESTAMP;
208 OciData::__maxDataSize = sizeof(SQL::TimeStamp);
209 Field::__dataType = SQL::typeTimeStamp;
210 break;
211 }
212 case SQLT_TIMESTAMP_TZ: {
213 OciData::__descType = OCI_DTYPE_TIMESTAMP_TZ;
214 OciData::__maxDataSize = sizeof(SQL::TimeStamp);
215 Field::__dataType = SQL::typeTimeStampTz;
216 break;
217 }
218 case SQLT_TIMESTAMP_LTZ: {
219 OciData::__descType = OCI_DTYPE_TIMESTAMP_LTZ;
220 OciData::__maxDataSize = sizeof(SQL::TimeStamp);
221 Field::__dataType = SQL::typeTimeStampTz;
222 break;
223 }
224 case SQLT_INTERVAL_YM: {
225 OciData::__descType = OCI_DTYPE_INTERVAL_YM;
226 OciData::__maxDataSize = sizeof(SQL::Interval);
227 Field::__dataType = SQL::typeIntervalYm;
228 break;
229 }
230 case SQLT_INTERVAL_DS: {
231 OciData::__descType = OCI_DTYPE_INTERVAL_DS;
232 OciData::__maxDataSize = sizeof(SQL::Interval);
233 Field::__dataType = SQL::typeIntervalDs;
234 break;
235 }
236 case SQLT_RDD: {
237 // oci.h
238 // #define OCI_ROWID_LEN 23
239 // ROWID를 CHR로 받으면 base64로 인코딩되어 리턴한다.
240 // 초기 버퍼를 3의 배수로 정한다.
241 OciData::__valueType = SQLT_CHR;
242 OciData::__maxDataSize = _buflen;
243 Field::__dataType = SQL::typeText;
244 break;
245 }
246 case SQLT_CHR: { // VARCHAR2, NVARCHAR2
247 OciData::__maxDataSize = _buflen; // 4000
248 Field::__dataType = SQL::typeText;
249 break;
250 }
251 case SQLT_AFC: { // CHAR, NCHAR, ANSI Fixed Char
252 OciData::__maxDataSize = _buflen; // 2000
253 Field::__dataType = SQL::typeText;
254 break;
255 }
256 case SQLT_BIN: {
257 OciData::__maxDataSize = _buflen; // 2000
258 Field::__dataType = SQL::typeBinary;
259 break;
260 }
261 case SQLT_LNG: {
262 OciData::__dynamicMode = OCI_DYNAMIC_FETCH;
265 Field::__dataType = SQL::typeLongText;
266 break;
267 }
268 case SQLT_LBI: {
269 OciData::__dynamicMode = OCI_DYNAMIC_FETCH;
272 Field::__dataType = SQL::typeLongBinary;
273 break;
274 }
275 case SQLT_CLOB: {
276 OciData::__descType = OCI_DTYPE_LOB;
278 Field::__dataType = SQL::typeClob;
279 break;
280 }
281 case SQLT_BLOB: {
282 OciData::__descType = OCI_DTYPE_LOB;
284 Field::__dataType = SQL::typeBlob;
285 break;
286 }
287 case SQLT_CFILE: {
288 OciData::__descType = OCI_DTYPE_FILE;
290 Field::__dataType = SQL::typeClob;
291 break;
292 }
293 case SQLT_BFILE: {
294 OciData::__descType = OCI_DTYPE_FILE;
296 Field::__dataType = SQL::typeBlob;
297 break;
298 }
299 default: {
300#ifdef __DCL_DEBUG
301 __DCL_ASSERT(false);
302#else
304 return false;
305#endif
306 }
307 }
308
309#if 0
310 // 이 지점에서 반환하면 Segmentation fault
311 // 이유를 모르겠다!
312 // 위 switch 시작에서 반환하면 문제가 없다.
313 // OCIExecute에서 스택에 흔적을 남겼을까?
314 // 2025-12-27
315 if (_position > 2) {
317 return false;
318 }
319#endif
320
321 OciData::__valuePtr = _buf;
322 OciData::__actualLength = _buflen;
323
325 status = conn()->DescriptorAlloc(
326 (dvoid**)OciData::__valuePtr,
328 );
329 if (status != OCI_SUCCESS) {
331 return false;
332 }
333 }
334
335 OCIDefine* defnp = NULL;
336 if (OciData::__dynamicMode == OCI_DEFAULT) {
337 status = OCIDefineByPos(
338 query()->stmtHandle(), // OCIStmt *stmtp,
339 &defnp, // OCIDefine **defnpp,
340 conn()->errorHandle(), // OCIError *errhp,
341 OciData::__position, // ub4 position,
342 OciData::__valuePtr, // dvoid *valuep,
343 OciData::__valueSize, // sb4 value_sz,
344 OciData::__valueType, // ub2 dty,
345 &(OciData::__indicator), // dvoid *indp,
346 &(OciData::__actualLength), // ub2 *rlenp,
347 &(OciData::__returnCode), // ub2 *rcodep,
348 OciData::__dynamicMode // ub4 mode
349 );
350 }
351 else {
352 // OCI_DYNAMIC_FETCH
353 status = OCIDefineByPos(
354 query()->stmtHandle(), // OCIStmt *stmtp,
355 &defnp, // OCIDefine **defnpp,
356 conn()->errorHandle(), // OCIError *errhp,
357 OciData::__position, // ub4 position,
358 NULL, // dvoid *valuep,
359 OciData::__valueSize, // sb4 value_sz,
360 OciData::__valueType, // ub2 dty,
361 NULL, // dvoid *indp,
362 NULL, // ub2 *rlenp,
363 NULL, // ub2 *rcodep,
364 OciData::__dynamicMode // ub4 mode
365 );
366 if (status == OCI_SUCCESS) {
367 status = OCIDefineDynamic(
368 defnp, // OCIDefine *defnp,
369 conn()->errorHandle(), // OCIError *errhp,
370 this, // dvoid *octxp,
371 defineCallback // OCICallbackDefine(ocbfp)
372 );
373 }
374 }
375 if (status != OCI_SUCCESS) {
376 __SET_ERROR_HANDLE(SQL::eServerError, status, conn()->errorHandle());
377 return false;
378 }
379
380 return true;
381}
#define INT32_MAX
Definition Config.h:290
#define UINT32_MAX
Definition Config.h:295
#define __DCL_TRACE5_N(fmt, arg1, arg2, arg3, arg4, arg5)
Definition ODBCQuery.cpp:44
sword DescriptorAlloc(void **_descpp, ub4 _type, size_t _xtramem_sz=0, void **_usrmempp=NULL)
ub2 __valueType
Definition OciData.h:22
sb4 __valueSize
Definition OciData.h:21
virtual OciQuery * query() const =0
size_t __maxDataSize
Definition OciData.h:31
static sb4 defineCallback(dvoid *_octxp, OCIDefine *_defnp, ub4 _iter, dvoid **_bufpp, ub4 **_alenpp, ub1 *_piecep, dvoid **_indpp, ub2 **_rcodepp)
Definition OciField.cpp:415
String __name
Definition SQLCore.h:187
@ typeBinary
Definition SQLCore.h:74
@ typeClob
Definition SQLCore.h:77
@ typeNumeric
Definition SQLCore.h:64
@ typeLongBinary
Definition SQLCore.h:76
@ typeTimeStamp
Definition SQLCore.h:68
@ typeBlob
Definition SQLCore.h:78
@ typeTimeStampTz
Definition SQLCore.h:69
@ typeIntervalDs
Definition SQLCore.h:72
@ typeFloat
Definition SQLCore.h:63
@ typeIntervalYm
Definition SQLCore.h:71
@ typeLongText
Definition SQLCore.h:75
@ eNotSupportDataType
Definition SQLCore.h:48
@ eServerError
Definition SQLCore.h:21

◆ serverDataTypeName()

const wchar_t * OciField::serverDataTypeName ( ) const
virtual

Implements SQL::Field.

Definition at line 383 of file OciField.cpp.

384{
385 return OciData::__TYPE_NAME(__sqlt);
386}
static const wchar_t * __TYPE_NAME(ub2 _sqlt)
Definition OciData.cpp:924

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