DCL 4.0
Loading...
Searching...
No Matches
OciField.cpp
Go to the documentation of this file.
1#include <dcl/Config.h>
2
3#include <oci.h>
4
5#include <stdlib.h> // malloc, free
6
7#include <dcl/Object.h>
8#if __DCL_HAVE_ALLOC_DEBUG
9#undef __DCL_ALLOC_LEVEL
10#define __DCL_ALLOC_LEVEL __DCL_ALLOC_INTERNAL
11#endif
12
13#include <dcl/OutputStream.h>
15#include <dcl/Charset.h>
16#include <dcl/SQLCore.h>
17
18#include "OciConnection.h"
19#include "OciQuery.h"
20#include "OciField.h"
21
22#define __TRACE_THIS 0
23#if __TRACE_THIS
24#define __DCL_TRACE0_N __DCL_TRACE0
25#define __DCL_TRACE1_N __DCL_TRACE1
26#define __DCL_TRACE2_N __DCL_TRACE2
27#define __DCL_TRACE3_N __DCL_TRACE3
28#define __DCL_TRACE4_N __DCL_TRACE4
29#else
30#define __DCL_TRACE0_N(fmt)
31#define __DCL_TRACE1_N(fmt, arg)
32#define __DCL_TRACE2_N(fmt, arg1, arg2)
33#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
34#define __DCL_TRACE4_N(fmt, arg1, arg2, arg3, arg4)
35#endif
36
37#undef __THIS_FILE__
38static const wchar_t __THIS_FILE__[] = __T("dcl/sql/OciField.cpp");
39
40__DCL_BEGIN_NAMESPACE
41
42#undef __SET_ERROR
43#define __SET_ERROR(_error, status, pError) \
44 conn()->setErrorStatus(_error, status, pError, \
45 true, __THIS_FILE__, __LINE__)
46
48
50 : Field(NULL)
51{
52 __define = NULL;
53 __dataType = 0;
54
55 __bufferSize = 0;
56}
57
59{
62 conn()->OCIDescriptorFree(
63 *(void**)OciData::__value,
65 ) == OCI_SUCCESS);
66 }
67
68 if (OciData::__value) {
69 free(OciData::__value);
70// OciData::__value = NULL;
71 }
72}
73
74bool OciField::init(SQL::Query* _queryHandle, size_t _position)
75{
76 __DCL_ASSERT(_queryHandle != NULL);
77
78 Field::__queryHandle = _queryHandle;
79 OciData::__queryHandle = (OciQuery*)_queryHandle;
80 OciData::__position = _position; // 1, 2, 3, ...
81
82 OciConnection* pConnection = conn();
83 OCIError* pError = pConnection->errorHandle();
84 OCIStmt* pStmt = query()->stmtHandle();
85 sword status = OCI_SUCCESS;
86
87 OCIParam* _param = NULL;
88 status = ::OCIParamGet(
89 pStmt,
90 OCI_HTYPE_STMT,
91 pError,
92 (dvoid**)&_param,
94 if (status != OCI_SUCCESS) {
95 __SET_ERROR(SQL::eServerError, status, pError);
96 return false;
97 }
98
99 text* name = NULL;
100 ub4 size = 0;
101 status = ::OCIAttrGet(_param, OCI_DTYPE_PARAM,
102 &name,
103 &size,
104 OCI_ATTR_NAME,
105 pError);
106 if (status != OCI_SUCCESS) {
107 __SET_ERROR(SQL::eServerError, status, pError);
108 return false;
109 }
110
111 try {
112 Field::__name = UTF8Decoder::decode((const char*)name, size);
113 }
114 catch (CharsetConvertException* _e) {
115 __SET_ERROR(SQL::eServerError, status, pError);
116 conn()->setErrorEx(UTF8Encoder::encode(_e->toStringAll()));
117 _e->destroy();
118 return false;
119 }
120
121 status = ::OCIAttrGet(_param, OCI_DTYPE_PARAM,
122 &__dataType,
123 NULL,
124 OCI_ATTR_DATA_TYPE,
125 pError);
126 if (status != OCI_SUCCESS) {
127 __SET_ERROR(SQL::eServerError, status, pError);
128 return false;
129 }
130
131 ub2 dataSize = 0;
132 status = ::OCIAttrGet(_param, OCI_DTYPE_PARAM,
133 &dataSize,
134 NULL,
135 OCI_ATTR_DATA_SIZE,
136 pError);
137 if (status != OCI_SUCCESS) {
138 __SET_ERROR(SQL::eServerError, status, pError);
139 return false;
140 }
141
142 sb2 precision;
143 sb1 scale;
144 status = ::OCIAttrGet(_param, OCI_DTYPE_PARAM,
145 &precision,
146 NULL,
147 OCI_ATTR_PRECISION,
148 pError);
149 if (status != OCI_SUCCESS) {
150 __SET_ERROR(SQL::eServerError, status, pError);
151 return false;
152 }
153 status = ::OCIAttrGet(_param, OCI_DTYPE_PARAM,
154 &scale,
155 NULL,
156 OCI_ATTR_SCALE,
157 pError);
158 if (status != OCI_SUCCESS) {
159 __SET_ERROR(SQL::eServerError, status, pError);
160 return false;
161 }
162 Field::__precision = precision;
163 Field::__scale = scale;
164 __DCL_TRACE3_N(L"[%ls] precision[%d] scale[%d]\n", __name.data(), precision, scale);
165
167 __bufferSize = 0;
169 OciData::__dynamicMode = OCI_DEFAULT;
170 switch(__dataType) {
171 case SQLT_NUM: {
172 __bufferSize = OciData::__valueSize = sizeof(OCINumber);
173 OciData::__dataType = SQLT_VNU;
174 Field::__dataType = SQL::typeNumeric;
175 OciData::__maxDataSize = 132; // between 1.0 x 10^-130
176 // and 9.9...9 x 10^125
177 // (38 nines followed by 88 zeroes)
178 break;
179 }
180 case SQLT_DAT: {
181 __bufferSize = OciData::__valueSize = sizeof(OCIDate);
182 OciData::__dataType = SQLT_ODT;
183 Field::__dataType = SQL::typeTimeStamp;
185 break;
186 }
187 case SQLT_TIMESTAMP: {
188 __bufferSize = OciData::__valueSize = sizeof(OCIDateTime*);
189 OciData::__descType = OCI_DTYPE_TIMESTAMP;
190 OciData::__dataType = __dataType;
191 Field::__dataType = SQL::typeTimeStamp;
193 break;
194 }
195 case SQLT_TIMESTAMP_TZ: {
196 __bufferSize = OciData::__valueSize = sizeof(OCIDateTime*);
197 OciData::__descType = OCI_DTYPE_TIMESTAMP_TZ;
198 OciData::__dataType = __dataType;
199 Field::__dataType = SQL::typeTimeStampTz;
201 break;
202 }
203 case SQLT_TIMESTAMP_LTZ: {
204 __bufferSize = OciData::__valueSize = sizeof(OCIDateTime*);
205 OciData::__descType = OCI_DTYPE_TIMESTAMP_LTZ;
206 OciData::__dataType = __dataType;
207 Field::__dataType = SQL::typeTimeStampTz;
209 break;
210 }
211 case SQLT_INTERVAL_YM: {
212 __bufferSize = OciData::__valueSize = sizeof(OCIInterval*);
213 OciData::__descType = OCI_DTYPE_INTERVAL_YM;
214 OciData::__dataType = __dataType;
215 Field::__dataType = SQL::typeIntervalYm;
217 break;
218 }
219 case SQLT_INTERVAL_DS: {
220 __bufferSize = OciData::__valueSize = sizeof(OCIInterval*);
221 OciData::__descType = OCI_DTYPE_INTERVAL_DS;
222 OciData::__dataType = __dataType;
223 Field::__dataType = SQL::typeIntervalDs;
225 break;
226 }
227 case SQLT_CHR: { // VARCHAR2, NVARCHAR2
228 __bufferSize = OciData::__valueSize = dataSize;
229 OciData::__dataType = __dataType;
230 Field::__dataType = SQL::typeText;
231 // OciData::__maxDataSize = 4000;
232 OciData::__maxDataSize = dataSize;
233 break;
234 }
235 case SQLT_AFC: { // CHAR, NCHAR, ANSI Fixed Char
236 __bufferSize = OciData::__valueSize = dataSize;
237 OciData::__dataType = __dataType;
238 Field::__dataType = SQL::typeText;
239 // OciData::__maxDataSize = 2000;
240 OciData::__maxDataSize = dataSize;
241 break;
242 }
243 case SQLT_BIN: {
244 // OciData::__dynamicMode = OCI_DYNAMIC_FETCH;
245 __bufferSize = OciData::__valueSize = dataSize;
246 OciData::__dataType = __dataType;
247 Field::__dataType = SQL::typeBinary;
248 // OciData::__maxDataSize = 2000;
249 OciData::__maxDataSize = dataSize;
250 break;
251 }
252 case SQLT_RDD: {
253 OciData::__dynamicMode = OCI_DYNAMIC_FETCH;
254 // oci.h
255 //#define OCI_ROWID_LEN 23
256 // ROWID를 CHR로 받으면 base64로 인코딩되어 리턴한다.
257 // 초기 버퍼를 3의 배수로 정한다.
258 __bufferSize = 24;
260 OciData::__dataType = SQLT_CHR;
261 Field::__dataType = SQL::typeText;
263 break;
264 }
265 case SQLT_LNG: {
266 OciData::__dynamicMode = OCI_DYNAMIC_FETCH;
267 __bufferSize = DYNAMIC_BUFFER_SIZE;
269 OciData::__dataType = __dataType;
270 Field::__dataType = SQL::typeLongText;
271 OciData::__maxDataSize = INT32_MAX; // 2^31 - 1
272 break;
273 }
274 case SQLT_LBI: {
275 OciData::__dynamicMode = OCI_DYNAMIC_FETCH;
276 __bufferSize = DYNAMIC_BUFFER_SIZE;
278 OciData::__dataType = __dataType;
279 Field::__dataType = SQL::typeLongBinary;
280 OciData::__maxDataSize = INT32_MAX; // 2^31 - 1
281 break;
282 }
283 case SQLT_CLOB :
284 case SQLT_CFILE: {
285 __bufferSize = OciData::__valueSize = sizeof(OCILobLocator*);
286 if (__dataType == SQLT_CFILE)
287 OciData::__descType = OCI_DTYPE_FILE;
288 else
289 OciData::__descType = OCI_DTYPE_LOB;
290 OciData::__dataType = __dataType;
291 Field::__dataType = SQL::typeClob;
293 break;
294 }
295 case SQLT_BLOB :
296 case SQLT_BFILE: {
297 __bufferSize = OciData::__valueSize = sizeof(OCILobLocator*);
298 if (__dataType == SQLT_BFILE)
299 OciData::__descType = OCI_DTYPE_FILE;
300 else
301 OciData::__descType = OCI_DTYPE_LOB;
302 OciData::__dataType = __dataType;
303 Field::__dataType = SQL::typeBlob;
305 break;
306 }
307 default: {
308#ifdef __DCL_DEBUG
309 __DCL_ASSERT(false);
310#else
312 return false;
313#endif
314 }
315 }
316
317 OciData::__actualLength = __bufferSize;
318 OciData::__value = malloc(__bufferSize);
319 if (!OciData::__value) {
321 return false;
322 }
323
325 status = pConnection->OCIDescriptorAlloc(
326 (dvoid**)OciData::__value,
328 );
329 if (status != OCI_SUCCESS) {
331 return false;
332 }
333 }
334
335 if (OciData::__dynamicMode == OCI_DYNAMIC_FETCH) {
336 status = ::OCIDefineByPos(
337 pStmt, // OCIStmt *stmtp,
338 &__define, // OCIDefine **defnpp,
339 pError, // OCIError *errhp,
340 OciData::__position, // ub4 position,
341 NULL, // dvoid *valuep,
342 OciData::__valueSize, // sb4 value_sz,
343 OciData::__dataType, // ub2 dty,
344 NULL, // dvoid *indp,
345 NULL, // ub2 *rlenp,
346 NULL, // ub2 *rcodep,
347 OCI_DYNAMIC_FETCH // ub4 mode
348 );
349 if (status == OCI_SUCCESS)
350 status = OCIDefineDynamic(
351 __define, // OCIDefine *defnp,
352 pError, // OCIError *errhp,
353 this, // dvoid *octxp,
355 );
356 }
357 else {
358 status = ::OCIDefineByPos(
359 pStmt,
360 &__define,
361 pError,
369 OCI_DEFAULT
370 );
371 }
372
373 if (status != OCI_SUCCESS) {
374 __SET_ERROR(SQL::eServerError, status, pError);
375 return false;
376 }
377
378 return true;
379}
380
382{
383 return OciData::__indicator == -1;
384}
385
386const wchar_t* OciField::serverDataTypeName() const
387{
388 return OciData::dataTypeName(__dataType);
389}
390
391bool OciField::__getDataSize(size_t* _size, bool _maxSize)
392{
393 return OciData::getDataSize(_size, _maxSize);
394}
395
397 void* _pv,
398 size_t* _size,
399 SQL::DataType _dataType
400 )
401{
402 return OciData::getData(_pv, _size, _dataType);
403}
404
406 dvoid *octxp,
407 OCIDefine *defnp,
408 ub4 iter,
409 dvoid **bufpp,
410 ub4 **alenpp,
411 ub1 *piecep,
412 dvoid **indpp,
413 ub2 **rcodep
414 )
415{
416 return ((OciField*)octxp)->onCallbackDefine(
417 defnp,
418 iter,
419 bufpp,
420 alenpp,
421 piecep,
422 indpp,
423 rcodep
424 );
425}
426
428 OCIDefine *pDefine,
429 ub4 nIterator,
430 dvoid **ppvBuffer,
431 ub4 **ppnActualLength,
432 ub1 *pnPiece,
433 dvoid **ppvIndicator,
434 ub2 **ppnReturnCode
435 )
436{
437 __DCL_ASSERT(OciData::__dynamicMode == OCI_DYNAMIC_FETCH);
438/*
439#ifdef __DCL_DEBUG
440 switch(*pnPiece)
441 {
442 case OCI_ONE_PIECE :
443 __DCL_TRACE0_N("OCI_ONE_PIECE\n");
444 break;
445 case OCI_FIRST_PIECE :
446 __DCL_TRACE0_N("OCI_FIRST_PIECE\n");
447 break;
448 case OCI_NEXT_PIECE :
449 __DCL_TRACE0_N("OCI_NEXT_PIECE\n");
450 break;
451 case OCI_LAST_PIECE :
452 __DCL_TRACE0_N("OCI_LAST_PIECE\n");
453 }
454#endif
455*/
456 if (*pnPiece == OCI_ONE_PIECE)
457 *pnPiece = OCI_FIRST_PIECE;
458
459 if (*pnPiece == OCI_FIRST_PIECE) {
461 OciData::__bytesOutput->reset();
462 }
463 else {
468 return OCI_ERROR;
469 }
470
471 }
472
474 try {
476 }
477 catch(IOException* e) {
478 conn()->setErrorEx(
479 UTF8Encoder::encode(e->toStringAll())
480 );
481 e->destroy();
482 return OCI_ERROR;
483 }
484 }
485
486 OciData::__callbackActualLength = __bufferSize;
487 *ppvBuffer = OciData::__value;
488 *ppnActualLength = &(OciData::__callbackActualLength);
489 *ppvIndicator = &(OciData::__indicator);
490 *ppnReturnCode = &(OciData::__returnCode);
491
492 return OCI_CONTINUE;
493}
494
495__DCL_END_NAMESPACE
#define __THIS_FILE__
Definition _trace.h:14
#define NULL
Definition Config.h:340
#define INT32_MAX
Definition Config.h:318
#define UINT32_MAX
Definition Config.h:323
#define __DCL_TRACE3_N(fmt, arg1, arg2, arg3)
#define __DCL_VERIFY(expr)
Definition Object.h:373
#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
#define DYNAMIC_BUFFER_SIZE
Definition OciData.h:11
#define __SET_ERROR(_errorCode)
Definition SQLCore.cpp:150
virtual void destroy()
Definition Exception.cpp:74
String toStringAll() const
Definition Exception.cpp:45
sword OCIDescriptorAlloc(void **ppDescriptorHandle, ub4 nDescriptorType, size_t xtramem_sz=0, void **ppvUserMem=NULL)
OCIError * errorHandle() const
void setErrorEx(const ByteString &_message)
sb2 __indicator
Definition OciData.h:24
bool getData(void *_pv, size_t *_size, SQL::DataType _dataType)
Definition OciData.cpp:202
ub2 __dataType
Definition OciData.h:21
sb4 __valueSize
Definition OciData.h:23
ub2 __actualLength
Definition OciData.h:25
OciQuery * __queryHandle
Definition OciData.h:16
ub4 __dynamicMode
Definition OciData.h:19
static const wchar_t * dataTypeName(ub2 _dataType)
Definition OciData.cpp:844
bool getDataSize(size_t *_size, bool _maxSize)
Definition OciData.cpp:172
ub4 __position
Definition OciData.h:17
ub2 __returnCode
Definition OciData.h:27
ub4 __callbackActualLength
Definition OciData.h:26
size_t __maxDataSize
Definition OciData.h:31
OciConnection * conn() const
Definition OciData.h:62
ub4 __descType
Definition OciData.h:18
void * __value
Definition OciData.h:22
BytesOutputStream * __bytesOutput
Definition OciData.h:29
virtual bool __getDataSize(size_t *_size, bool _maxSize)
Definition OciField.cpp:391
static sb4 CallbackDefine(dvoid *octxp, OCIDefine *defnp, ub4 iter, dvoid **bufpp, ub4 **alenpp, ub1 *piecep, dvoid **indpp, ub2 **rcodep)
Definition OciField.cpp:405
virtual ~OciField()
Definition OciField.cpp:58
bool init(SQL::Query *_query, size_t _position)
Definition OciField.cpp:74
virtual bool __getData(void *_pv, size_t *_size, SQL::DataType _dataType)
Definition OciField.cpp:396
virtual bool isNull() const
Definition OciField.cpp:381
virtual const wchar_t * serverDataTypeName() const
Definition OciField.cpp:386
sb4 onCallbackDefine(OCIDefine *pDefine, ub4 nIterator, dvoid **ppvBuffer, ub4 **ppnActualLength, ub1 *pnPiece, dvoid **ppvIndicator, ub2 **ppnReturnCode)
Definition OciField.cpp:427
String __name
Definition SQLCore.h:183
DataType
Definition SQLCore.h:62
@ typeBinary
Definition SQLCore.h:76
@ typeClob
Definition SQLCore.h:79
@ typeNumeric
Definition SQLCore.h:67
@ typeLongBinary
Definition SQLCore.h:78
@ typeTimeStamp
Definition SQLCore.h:70
@ typeBlob
Definition SQLCore.h:80
@ typeTimeStampTz
Definition SQLCore.h:71
@ typeIntervalDs
Definition SQLCore.h:74
@ typeText
Definition SQLCore.h:75
@ typeIntervalYm
Definition SQLCore.h:73
@ typeLongText
Definition SQLCore.h:77
@ eOutOfMemory
Definition SQLCore.h:24
@ eNotSupportDataType
Definition SQLCore.h:48
@ eServerError
Definition SQLCore.h:21