00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #ifndef _OCIPL_H
00043
00044
00045 #ifdef UNICODE
00046 #ifndef _UNICODE
00047 #define _UNICODE
00048 #endif
00049 #else
00050 #ifdef _UNICODE
00051 #define UNICODE
00052 #endif
00053 #endif
00054
00055 #ifdef _WIN32
00056 #define WIN32_LEAN_AND_MEAN
00057 #include <windows.h>
00058 #else
00059 #define TCHAR char
00060 #endif
00061
00062 #ifdef _MSC_VER
00063 #pragma warning(disable: 4786)
00064 #else
00065 #define LONGLONG long long
00066 #endif
00067
00068
00069
00070 #ifdef __STDC_WANT_SECURE_LIB__
00071
00072 #ifndef _stprintf_s1
00073 #define _stprintf_s1 sprintf_s
00074 #endif
00075
00076 #else
00077
00078 #ifndef strcpy_s
00079 #define strcpy_s(d, l, s) strcpy(d, s)
00080 #endif
00081
00082 #ifndef _strupr_s
00083 #define _strupr_s(b, s) strupr(b)
00084 #endif
00085
00086 #ifndef _tcscpy_s
00087 #define _tcscpy_s(d, l, s) _tcscpy(d, s)
00088 #endif
00089
00090 #ifndef _tcsupr_s
00091 #define _tcsupr_s(b, s) _tcsupr(b)
00092 #endif
00093
00094 #ifndef _stprintf_s1
00095 #define _stprintf_s1(b, l, f, p1) ((b)+(l),_stprintf(b, f, p1))
00096 #endif
00097
00098 #endif // __STDC_WANT_SECURE_LIB__
00099
00100
00101 #if _MSC_VER>=1400
00102 #ifndef _CRT_SECURE_NO_DEPRECATE
00103 #define __STDC_WANT_SECURE_LIB__ 1
00104 #endif
00105
00106 #ifndef COUNTOF
00107 #define COUNTOF _countof
00108 #endif
00109
00110 #else // _MSC_VER>=1400
00111
00112 #ifndef COUNTOF
00113 #define COUNTOF(b) (sizeof(b)/sizeof(b[0]))
00114 #define _countof COUNTOF
00115 #endif
00116
00117 #endif
00118
00119
00120 #include <map>
00121 #include <set>
00122 #include <string>
00123 #include <vector>
00124 #include <ostream>
00125 #include <sstream>
00126 #include <exception>
00127
00128 #ifndef min
00129 #define min(a,b) ((a)<(b)?(a):(b))
00130 #endif
00131
00132
00133 #undef SQL_SUCCESS
00134 #undef SQL_ERROR
00135
00136 #define iterator __iterator_
00137 #if !__STDC__
00138 #define __STDC__ 1 // for Oracle 8.0 header files
00139 #endif
00140 #include <oci.h>
00141 #undef iterator
00142
00143
00144 #ifndef ORACLE_VERSION
00145 #ifdef OCI_MAJOR_VERSION // OCI_MAJOR_VERSION/OCI_MINOR_VERSION is only available since Oracle 10.
00146 #define ORACLE_VERSION (10*OCI_MAJOR_VERSION+OCI_MINOR_VERSION)
00147 #else
00148 #if OCI_HTYPE_LAST>=29
00149 #define ORACLE_VERSION 102 // Oracle 10g2
00150 #elif OCI_HTYPE_LAST>=27
00151 #define ORACLE_VERSION 92 // Oracle 9i2
00152 #elif OCI_HTYPE_LAST>=18
00153 #define ORACLE_VERSION 82 // Oracle 8.1.6/7
00154 #elif OCI_HTYPE_LAST>=17
00155 #define ORACLE_VERSION 81 // Oracle 8.1.5
00156 #else
00157 #define ORACLE_VERSION 80 // Oracle 8.0.x
00158 #endif
00159 #endif // OCI_MAJOR_VERSION
00160 #endif
00161
00162
00163
00164 #ifdef _WIN32
00165
00166 #include <tchar.h>
00167
00168 #else // _WIN32
00169
00170 #include <wchar.h>
00171 #ifndef UNICODE
00172 #define TEXT(x) x
00173 #endif
00174
00175 #endif // _WIN32
00176
00177 #ifdef UNICODE
00178 typedef utext TOraText;
00179 typedef std::wstring tstring;
00180 typedef std::wstringbuf tstringbuf;
00181 typedef std::wostringstream tostringstream;
00182 typedef std::wistream tistream;
00183 typedef std::wostream tostream;
00184 #else
00185 typedef OraText TOraText;
00186 typedef std::string tstring;
00187 typedef std::stringbuf tstringbuf;
00188 typedef std::ostringstream tostringstream;
00189 typedef std::istream tistream;
00190 typedef std::ostream tostream;
00191 #endif
00192
00193
00194 #ifndef _MSC_VER
00195
00196 #ifndef UNICODE
00197 #define _stprintf sprintf
00198 #define _tcscmp strcmp
00199 #define _tcscpy strcpy
00200 #define _tcsdup _strdup
00201 #define _tcslen strlen
00202 #define _tcsnicmp strncasecmp
00203 #define _tcsupr strupr
00204 #define _tcspbrk strpbrk
00205 #endif
00206
00207 #ifndef _strdup
00208 #define _strdup strdup
00209 #endif
00210
00211 #ifndef _snprintf
00212 #define _snprintf snprintf
00213 #endif
00214
00215 extern char* strupr(char*);
00216
00217 #endif // _MSC_VER
00218
00219
00220 #ifdef _MSC_VER
00221 #include <minmax.h>
00222
00223 #ifndef OCIPL_NO_COMMENT
00224 #pragma comment(lib, "oci")
00225
00226 #if defined(_DEBUG) && defined(_DLL) // DEBUG version only supported with MSVCRTD
00227 #if _MSC_VER==1400
00228 #pragma comment(lib, "ocipl-vc8d.lib")
00229 #else
00230 #pragma comment(lib, "ocipl-vc6d.lib")
00231 #endif
00232 #else
00233 #ifdef _DLL
00234 #if _MSC_VER==1400
00235 #pragma comment(lib, "ocipl-vc8")
00236 #else
00237 #pragma comment(lib, "ocipl-vc6")
00238 #endif
00239 #elif defined(_MT)
00240 #if _MSC_VER==1400
00241 #pragma comment(lib, "ocipl-vc8t")
00242 #else
00243 #pragma comment(lib, "ocipl-vc6t")
00244 #endif
00245 #else
00246
00247 #pragma comment(lib, "ocipl-vc6l")
00248 #endif
00249 #endif
00250
00251 #endif // OCIPL_NO_COMMENT
00252 #endif // _MSC_VER
00253
00254
00255
00256
00257 #if 1 // use stdlib allocation
00258 #define ocipl_alloc malloc
00259 #define ocipl_realloc realloc
00260 #define ocipl_free free
00261 #else
00262 extern void* ocipl_alloc(size_t);
00263 extern void* ocipl_realloc(void* p, size_t l);
00264 extern void ocipl_free(void*);
00265 #endif
00266
00267 extern size_t max_strlen(const char* s, size_t max_len);
00268 extern char* max_strdup(const char* s, size_t max_len);
00269
00270
00271 namespace OCIPL {
00272
00273
00274
00275 extern int g_OCIPL_BULK_ROWS;
00276
00277
00278 #define OCIPL_DEFAULT_STRING_BUFFER 2000
00279
00280
00281 #ifndef istspace
00282 inline int istspace(TCHAR c)
00283 {
00284 #ifdef UNICODE
00285 return _istspace((unsigned short)c);
00286 #else
00287 return isspace((unsigned char)c);
00288 #endif
00289 }
00290 #endif
00291
00292
00293 struct SqlStatement;
00294
00295
00296 struct OciException : public std::exception
00297 {
00298 typedef std::exception super;
00299
00300 OciException(OCIEnv* envh, const char* file, int line);
00301 OciException(OCIError* errh, const char* file, int line);
00302 OciException(const char* msg, const char* file, int line);
00303 OciException(OCIError* errh, SqlStatement& stmt, const char* file, int line);
00304 OciException(const OciException&);
00305
00306 ~OciException() throw();
00307
00308
00309 virtual const char* what() const throw()
00310 {
00311 return _msg;
00312 }
00313
00314 int _sql_error_code;
00315 char* _msg;
00316 const char* _file;
00317 int _line;
00318 tstring _last_sql;
00319 ub2 _parse_offset;
00320 };
00321
00322
00323 #define SQLCODE_DUPLICATE_KEY 1
00324 #define SQLCODE_NO_DATA_FOUND 1403
00325 #define SQLCODE_TOO_MANY_ROWS 1422
00326
00327
00328 enum OCI_STATE {
00329 OS_NONE,
00330 OS_PREPARE,
00331 OS_RELEASE,
00332 OS_EXECUTE,
00333 OS_FETCH,
00334 OS_TRANSACTION
00335 };
00336
00337
00338
00339
00340 struct OciEnv;
00341
00342 extern void throw_oci_exception(OCIError* errh, sword res);
00343 extern void throw_oci_exception(OCIEnv* envh, sword res);
00344
00345 void oci_check_error(OCIError* errh, sword res);
00346 void oci_check_error(OCIEnv* envh, sword res);
00347 void oci_check_error(OciEnv& env, sword res);
00348
00349 #define CODEPOS __FILE__, __LINE__
00350
00351
00352 #ifdef _MSC_VER
00353 __declspec(noreturn)
00354 #endif
00355 void throw_ocipl_exception(OciException e);
00356
00357
00358 #define THROW_OCI_EXCEPTION(par) throw_ocipl_exception(OCIPL::OciException(par, CODEPOS))
00359
00360
00361
00362
00363 template<typename TYPE>
00364 struct OciHandleID
00365 {
00366 static ub4 get_type_id();
00367 static ub4 get_attr_id();
00368 };
00369
00370 inline ub4 OciHandleID<OCIEnv>::get_type_id() {return OCI_HTYPE_ENV;}
00371 inline ub4 OciHandleID<OCIError>::get_type_id() {return OCI_HTYPE_ERROR;}
00372 inline ub4 OciHandleID<OCISvcCtx>::get_type_id() {return OCI_HTYPE_SVCCTX;}
00373 inline ub4 OciHandleID<OCIStmt>::get_type_id() {return OCI_HTYPE_STMT;}
00374 inline ub4 OciHandleID<OCIBind>::get_type_id() {return OCI_HTYPE_BIND;}
00375 inline ub4 OciHandleID<OCIDefine>::get_type_id() {return OCI_HTYPE_DEFINE;}
00376 inline ub4 OciHandleID<OCIDescribe>::get_type_id() {return OCI_HTYPE_DESCRIBE;}
00377 inline ub4 OciHandleID<OCIServer>::get_type_id() {return OCI_HTYPE_SERVER;}
00378 inline ub4 OciHandleID<OCISession>::get_type_id() {return OCI_HTYPE_SESSION;}
00379 inline ub4 OciHandleID<OCITrans>::get_type_id() {return OCI_HTYPE_TRANS;}
00380 inline ub4 OciHandleID<OCIComplexObject>::get_type_id() {return OCI_HTYPE_COMPLEXOBJECT;}
00381 inline ub4 OciHandleID<OCISecurity>::get_type_id() {return OCI_HTYPE_SECURITY;}
00382 #if ORACLE_VERSION>=81
00383 inline ub4 OciHandleID<OCISubscription>::get_type_id() {return OCI_HTYPE_SUBSCRIPTION;}
00384 #endif
00385
00386
00387
00388
00389
00390
00391
00392 inline ub4 OciHandleID<OCIServer>::get_attr_id() {return OCI_ATTR_SERVER;}
00393 inline ub4 OciHandleID<OCISession>::get_attr_id() {return OCI_ATTR_SESSION;}
00394
00395
00396
00397
00398 template<typename TYPE>
00399 struct OciSimpleHandle : public OciHandleID<TYPE>
00400 {
00401 typedef OciHandleID<TYPE> super;
00402 typedef TYPE HandleType;
00403
00404
00405 OciSimpleHandle()
00406 : _handle(0), _envh(0)
00407 {
00408 }
00409
00410
00411 OciSimpleHandle(OCIEnv* envh, HandleType* handle)
00412 : _envh(envh), _handle(handle)
00413 {
00414 }
00415
00416
00417 OciSimpleHandle(OCIEnv* envh)
00418 : _handle(0)
00419 {
00420 alloc(envh);
00421 }
00422
00423
00424 ~OciSimpleHandle()
00425 {
00426 if (_handle)
00427 destroy();
00428 }
00429
00430
00431 operator HandleType*()
00432 {
00433 return _handle;
00434 }
00435
00436
00437 void alloc(OCIEnv* envh)
00438 {
00439
00440 if (_handle)
00441 destroy();
00442
00443 _envh = envh;
00444
00445 sword res = OCIHandleAlloc(envh, (dvoid**)&_handle, super::get_type_id(), 0, 0);
00446 oci_check_error(envh, res);
00447 }
00448
00449
00450 void destroy()
00451 {
00452 sword res = OCIHandleFree(_handle, super::get_type_id());
00453 _handle = 0;
00454
00455 if (_envh) {
00456 oci_check_error(_envh, res);
00457 _envh = 0;
00458 }
00459 }
00460
00461
00462 void get_attribute(dvoid* attributep, ub4* sizep, ub4 attrtype, OCIError* errh)
00463 {
00464 sword res = OCIAttrGet(_handle, super::get_type_id(), attributep, sizep, attrtype, errh);
00465 oci_check_error(_envh, res);
00466 }
00467
00468 protected:
00469 HandleType* _handle;
00470 OCIEnv* _envh;
00471 };
00472
00473
00474
00475
00476 template<typename TYPE>
00477 struct OciHandleWrapper : public OciHandleID<TYPE>
00478 {
00479 typedef TYPE HandleType;
00480
00481
00482 OciHandleWrapper(HandleType* handle)
00483 : _handle(handle)
00484 {
00485 }
00486
00487
00488 operator HandleType*()
00489 {
00490 return _handle;
00491 }
00492
00493 protected:
00494 HandleType* _handle;
00495 };
00496
00497
00498
00499 typedef OciSimpleHandle<OCIError> OciError;
00500
00501
00502
00503 typedef OciSimpleHandle<OCIDescribe> OciDescribe;
00504
00505
00506
00507
00508 struct OciEnv : public OciHandleWrapper<OCIEnv>
00509 {
00510 typedef OciHandleWrapper<OCIEnv> super;
00511
00512 OciEnv(OCIEnv* envh)
00513 : super(envh)
00514 {
00515
00516 _errh.alloc(_handle);
00517 }
00518
00519 OciError _errh;
00520 };
00521
00522
00523
00524
00525 struct OciEnvAlloc : public OciSimpleHandle<OCIEnv>
00526 {
00527 typedef OciSimpleHandle<OCIEnv> super;
00528
00529
00530 OciEnvAlloc(ub4 oci_mode=OCI_OBJECT)
00531 {
00532 #if ORACLE_VERSION>=81
00533 #ifdef UNICODE
00534 sword res = OCIEnvNlsCreate(&_handle, oci_mode, 0, 0, 0, 0, 0, 0, OCI_UTF16ID, OCI_UTF16ID);
00535 #else
00536 sword res = OCIEnvCreate(&_handle, oci_mode, 0, 0, 0, 0, 0, 0);
00537 #endif
00538
00539 #else
00540 sword res = OCIInitialize(oci_mode, 0, 0, 0, 0);
00541
00542
00543 OCIEnvInit(&_handle, OCI_DEFAULT, (size_t)0, (dvoid **) 0);
00544 #endif
00545 }
00546 };
00547
00548
00549
00550
00551 template<typename TYPE>
00552 struct OciHandle : public OciHandleID<TYPE>
00553 {
00554 typedef OciHandleID<TYPE> super;
00555 typedef TYPE HandleType;
00556
00557
00558 OciHandle(OciEnv& env)
00559 : _env(env),
00560 _handle(0)
00561 {
00562 alloc();
00563 }
00564
00565
00566 OciHandle(OciEnv& env, HandleType* handle)
00567 : _env(env),
00568 _handle(handle)
00569 {
00570 }
00571
00572
00573 OciHandle(const OciHandle& other)
00574 : _env(other._env),
00575 _handle(other._handle)
00576 {
00577 other._handle = NULL;
00578 }
00579
00580
00581 ~OciHandle()
00582 {
00583 if (_handle)
00584 destroy();
00585 }
00586
00587
00588 void alloc()
00589 {
00590 if (_handle)
00591 destroy();
00592
00593 sword res = OCIHandleAlloc(_env, (dvoid**)&_handle, super::get_type_id(), 0, 0);
00594 oci_check_error(_env, res);
00595 }
00596
00597
00598 void destroy()
00599 {
00600 sword res = OCIHandleFree(_handle, super::get_type_id());
00601 _handle = 0;
00602
00603 oci_check_error(_env, res);
00604 }
00605
00606
00607 void set_attribute(ub4 attrtype, const tstring& str)
00608 {
00609 sword res = OCIAttrSet(_handle, super::get_type_id(), (TOraText*)str.c_str(), (ub4)str.length()*sizeof(TOraText), attrtype, _env._errh);
00610 oci_check_error(_env, res);
00611 }
00612
00613
00614 void set_attribute(ub4 attrtype, ub4 value)
00615 {
00616 sword res = OCIAttrSet(_handle, super::get_type_id(), (OraText*)&value, (ub4)sizeof(value), attrtype, _env._errh);
00617 oci_check_error(_env, res);
00618 }
00619
00620
00621 void get_attribute(dvoid* attributep, ub4* sizep, ub4 attrtype)
00622 {
00623 sword res = OCIAttrGet(_handle, super::get_type_id(), attributep, sizep, attrtype, _env._errh);
00624 oci_check_error(_env, res);
00625 }
00626
00627
00628 void set_attribute_handle(ub4 attrtype, void* handle)
00629 {
00630 sword res = OCIAttrSet(_handle, super::get_type_id(), handle, 0, attrtype, _env._errh);
00631 oci_check_error(_env, res);
00632 }
00633
00634
00635 template<typename ATTR> void set_attribute(ATTR& attr)
00636 {
00637 sword res = OCIAttrSet(_handle, super::get_type_id(), attr, 0, ATTR::get_attr_id(), _env._errh);
00638 oci_check_error(_env, res);
00639 }
00640
00641
00642 operator HandleType*()
00643 {
00644 return _handle;
00645 }
00646
00647 protected:
00648 HandleType* _handle;
00649
00650 public:
00651 OciEnv& _env;
00652 };
00653
00654
00655
00656
00657 template<typename TYPE>
00658 struct OciDescriptor : public OciHandleID<TYPE>
00659 {
00660 typedef OciHandleID<TYPE> super;
00661 typedef TYPE HandleType;
00662
00663
00664 OciDescriptor(OciEnv& env)
00665 : _env(env)
00666 {
00667 }
00668
00669
00670 OciDescriptor(OciEnv& env, HandleType* handle)
00671 : _env(env), _handle(handle)
00672 {
00673 }
00674
00675
00676 ~OciDescriptor()
00677 {
00678 if (_handle)
00679 destroy();
00680 }
00681
00682
00683 operator HandleType*()
00684 {
00685 return _handle;
00686 }
00687
00688
00689 void destroy()
00690 {
00691 sword res = OCIDescriptorFree(_handle, super::get_type_id());
00692 _handle = 0;
00693
00694 oci_check_error(_env, res);
00695 }
00696
00697
00698 void get_attribute(dvoid* attributep, ub4* sizep, ub4 attrtype)
00699 {
00700 sword res = OCIAttrGet(_handle, super::get_type_id(), attributep, sizep, attrtype, _env._errh);
00701 oci_check_error(_env, res);
00702 }
00703
00704 protected:
00705 HandleType* _handle;
00706 OciEnv& _env;
00707 };
00708
00709
00710 inline ub4 OciHandleID<OCIParam>::get_type_id() {return OCI_DTYPE_PARAM;}
00711
00712 typedef OciDescriptor<OCIParam> OciParam;
00713
00714
00715
00716 inline void oci_check_error(OCIError* errh, sword res)
00717 {
00718 if (res != OCI_SUCCESS)
00719 throw_oci_exception(errh, res);
00720 }
00721
00722
00723 inline void oci_check_error(OCIEnv* envh, sword res)
00724 {
00725 if (res != OCI_SUCCESS)
00726 throw_oci_exception(envh, res);
00727 }
00728
00729
00730 inline void oci_check_error(OciEnv& env, sword res)
00731 {
00732 oci_check_error(env._errh, res);
00733 }
00734
00735
00736 #if ORACLE_VERSION>=81
00737
00738
00739
00740 struct OciMessageFile
00741 {
00742
00743 OciMessageFile(OciEnv& env, const TCHAR* product, const TCHAR* facility)
00744 : _env(env), _msgh(0)
00745 {
00746 open(product, facility);
00747 }
00748
00749
00750 ~OciMessageFile()
00751 {
00752 if (_msgh)
00753 close();
00754 }
00755
00756
00757 operator OCIMsg*()
00758 {
00759 return _msgh;
00760 }
00761
00762
00763 void open(const TCHAR* product, const TCHAR* facility, OCIDuration dur=OCI_DURATION_PROCESS)
00764 {
00765 sword res = OCIMessageOpen(_env, _env._errh, &_msgh, (OraText*)(TOraText*)product, (OraText*)(TOraText*)facility, dur);
00766 oci_check_error(_env._errh, res);
00767 }
00768
00769
00770 void OciMessageFile::close()
00771 {
00772 sword res = OCIMessageClose(_env, _env._errh, _msgh);
00773 oci_check_error(_env._errh, res);
00774
00775 _msgh = 0;
00776 }
00777
00778
00779 TOraText* get_msg(ub4 msgno) const
00780 {
00781 return (TOraText*)OCIMessageGet(_msgh, msgno, 0, 0);
00782 }
00783
00784 protected:
00785 OCIMsg* _msgh;
00786 OciEnv& _env;
00787 };
00788
00789 #endif
00790
00791
00792
00793
00794 struct OracleServer : public OciHandle<OCIServer>
00795 {
00796 typedef OciHandle<OCIServer> super;
00797
00798
00799 OracleServer(OciEnv& env)
00800 : super(env)
00801 {
00802 #if ORACLE_VERSION>=82
00803 _version = 0;
00804 #endif
00805 _version_string[0] = '\0';
00806 }
00807
00808
00809 ~OracleServer()
00810 {
00811 if (_handle)
00812 detach();
00813 }
00814
00815
00816 void attach(const tstring& tnsname)
00817 {
00818 sword res = OCIServerAttach(_handle, _env._errh, (OraText*)tnsname.c_str(), (sb4)tnsname.length()*sizeof(TOraText), OCI_DEFAULT);
00819 oci_check_error(_env, res);
00820
00821 #if ORACLE_VERSION>=82
00822 res = OCIServerRelease(_handle, _env._errh, (OraText*)_version_string, sizeof(_version_string), OCI_HTYPE_SERVER, &_version);
00823 #else
00824 res = OCIServerVersion(_handle, _env._errh, (OraText*)_version_string, sizeof(_version_string), OCI_HTYPE_SERVER);
00825 #endif
00826 oci_check_error(_env, res);
00827 }
00828
00829
00830 void detach()
00831 {
00832 sword res = OCIServerDetach(_handle, _env._errh, OCI_DEFAULT);
00833 oci_check_error(_env, res);
00834
00835 #if ORACLE_VERSION>=82
00836 _version = 0;
00837 #endif
00838 _version_string[0] = '\0';
00839 }
00840
00841 #if ORACLE_VERSION>=82
00842 ub4 _version;
00843 #endif
00844 TCHAR _version_string[2000];
00845 };
00846
00847
00848
00849
00850 struct LoginPara
00851 {
00852 tstring _tnsname;
00853 tstring _username;
00854 tstring _password;
00855 ub4 _mode;
00856
00857
00858 LoginPara()
00859 : _mode(OCI_DEFAULT)
00860 {
00861 }
00862
00863
00864 LoginPara(const TCHAR* username, const TCHAR* password, const TCHAR* tnsname)
00865 : _username(username),
00866 _password(password),
00867 _tnsname(tnsname),
00868 _mode(OCI_DEFAULT)
00869 {
00870 }
00871
00872
00873 void parse(const TCHAR* conn_str);
00874 };
00875
00876
00877 struct OciContext : OciHandleWrapper<OCISvcCtx>
00878 {
00879 typedef OciHandleWrapper<OCISvcCtx> super;
00880
00881 OciContext(OciEnv& env, OCISvcCtx* ctx)
00882 : super(ctx),
00883 _state(OS_NONE),
00884 _stmt_type(0),
00885 _trans_cnt(0),
00886 _env(env)
00887 {
00888 }
00889
00890
00891 void commit(ub4 flags=OCI_DEFAULT);
00892
00893
00894 void rollback(ub4 flags=OCI_DEFAULT);
00895
00896 void set_state(OCI_STATE state)
00897 {
00898
00899 _state = state;
00900 }
00901
00902 void set_state(OCI_STATE state, int stmt_type)
00903 {
00904
00905 _state = state;
00906 _stmt_type = stmt_type;
00907
00908 if (state == OS_EXECUTE)
00909 if ((stmt_type>=OCI_STMT_UPDATE && stmt_type<=OCI_STMT_INSERT) ||
00910 stmt_type==OCI_STMT_BEGIN || stmt_type==OCI_STMT_DECLARE)
00911 ++_trans_cnt;
00912 }
00913
00914 void reset_state()
00915 {
00916 _state = OS_NONE;
00917 _stmt_type = 0;
00918 }
00919
00920 bool maybe_active_transaction() const
00921 {
00922 return _trans_cnt > 0;
00923 }
00924
00925 OCI_STATE _state;
00926 int _stmt_type;
00927 int _trans_cnt;
00928
00929 private:
00930 OciEnv& _env;
00931 };
00932
00933
00934
00935
00936 struct OciLogin : public OciHandle<OCISvcCtx>
00937 {
00938 typedef OciHandle<OCISvcCtx> super;
00939
00940
00941 OciLogin(OciEnv& env)
00942 : super(env),
00943 _server(env),
00944 _ctx(env, _handle),
00945 _session(env),
00946 _connected(false)
00947 {
00948 }
00949
00950
00951 OciLogin(OciEnv& env, const LoginPara& login_para)
00952 : super(env),
00953 _server(env),
00954 _ctx(env, _handle),
00955 _session(env),
00956 _connected(false)
00957 {
00958 connect(login_para);
00959 }
00960
00961
00962 OciLogin(OciEnv& env, const tstring& username, const tstring& password, const tstring& tnsname, ub4 mode=OCI_DEFAULT)
00963 : super(env),
00964 _server(env),
00965 _ctx(env, _handle),
00966 _session(env),
00967 _connected(false)
00968 {
00969 connect(username, password, tnsname, mode);
00970 }
00971
00972
00973 void connect(const LoginPara& login_para)
00974 {
00975 connect(login_para._username, login_para._password, login_para._tnsname, login_para._mode);
00976 }
00977
00978
00979 void connect(const tstring& username, const tstring& password, const tstring& tnsname, ub4 mode=OCI_DEFAULT)
00980 {
00981
00982 _server.attach(tnsname);
00983 _tnsname = tnsname;
00984
00985
00986 _session.set_attribute(OCI_ATTR_USERNAME, username);
00987 _session.set_attribute(OCI_ATTR_PASSWORD, password);
00988
00989
00990 set_attribute(_server);
00991
00992 sword res = OCISessionBegin(_handle, _env._errh, _session, OCI_CRED_RDBMS, mode);
00993
00994 if (res!=OCI_SUCCESS && res!=OCI_SUCCESS_WITH_INFO) {
00995 _server.detach();
00996 oci_check_error(_env, res);
00997 }
00998
00999
01000 if (res == OCI_SUCCESS_WITH_INFO) {
01001 TOraText buffer[1024];
01002
01003 sb4 errorcode;
01004 sword res = OCIErrorGet(_env._errh, 1, NULL, &errorcode, (OraText*)buffer, sizeof(buffer), OCI_HTYPE_ERROR);
01005
01006 if (res == OCI_SUCCESS)
01007 _warnings = (const TCHAR*)buffer;
01008 }
01009
01010 _connected = true;
01011
01012 set_attribute(_session);
01013
01014
01015
01016
01017
01018
01019
01020
01021 }
01022
01023
01024 ~OciLogin()
01025 {
01026 disconnect();
01027 }
01028
01029
01030 void disconnect()
01031 {
01032 if (_connected) {
01033
01034
01035
01036
01037 sword res = OCISessionEnd(_handle, _env._errh, _session, OCI_DEFAULT);
01038 oci_check_error(_env, res);
01039
01040 _server.detach();
01041
01042 _connected = false;
01043 }
01044 }
01045
01046
01047 bool connected() const
01048 {
01049 return _connected;
01050 }
01051
01052
01053 void commit(ub4 flags=OCI_DEFAULT)
01054 {
01055 _ctx.commit(flags);
01056 }
01057
01058
01059 void rollback(ub4 flags=OCI_DEFAULT)
01060 {
01061 _ctx.rollback(flags);
01062 }
01063
01064 OracleServer _server;
01065 tstring _warnings;
01066 tstring _tnsname;
01067
01068 protected:
01069 OciContext _ctx;
01070 OciHandle<OCISession> _session;
01071
01072 bool _connected;
01073 };
01074
01075
01076 #if ORACLE_VERSION>=90
01077
01078
01079 struct StatementCache : public std::map<tstring, tstring>
01080 {
01081 };
01082
01083 #endif
01084
01085
01086
01087
01088 struct OciConnection
01089 {
01090 OciConnection(OCIEnv* envh, OCISvcCtx* ctx)
01091 : _env(envh),
01092 _ctx(_env, ctx)
01093 {
01094 }
01095
01096 static OciConnection* CreateFromESqlContext(void* context);
01097
01098
01099 void commit(ub4 flags=OCI_DEFAULT)
01100 {
01101 _ctx.commit(flags);
01102 }
01103
01104
01105 void rollback(ub4 flags=OCI_DEFAULT)
01106 {
01107 _ctx.rollback(flags);
01108 }
01109
01110
01111 void cancel();
01112
01113 #if ORACLE_VERSION>=81
01114
01115 void reset();
01116 #endif
01117
01118 OciEnv _env;
01119 OciContext _ctx;
01120
01121 #if ORACLE_VERSION>=90
01122 StatementCache _stmt_cache;
01123 #endif
01124
01125
01126 operator OCIError*()
01127 {
01128 return _env._errh;
01129 }
01130
01131 private:
01132 OciConnection(const OciConnection&);
01133 };
01134
01135
01136
01137
01138 struct ColumnTypeInfo
01139 {
01140 ub2 _data_type;
01141 ub2 _width;
01142 ub1 _char_semantics;
01143 sb1 _scale;
01144 sb2 _precision;
01145 ub1 _nullable;
01146
01147
01148 tstring get_type_str(bool show_null=false) const;
01149 };
01150
01151
01152
01153
01154 struct ColumnType : public ColumnTypeInfo
01155 {
01156 tstring _name;
01157
01158
01159 ColumnType()
01160 {
01161 _data_type = 0;
01162 _width = 0;
01163 _char_semantics = 0;
01164 _precision = 0;
01165 _scale = -127;
01166 _nullable = false;
01167 }
01168
01169
01170 void init(OCIError* errh, dvoid* handle);
01171 };
01172
01173
01174 typedef OciHandle<OCIBind> OciBindHandle;
01175 typedef OciHandle<OCIDefine> OciDefineHandle;
01176
01177
01178
01179
01180 struct SqlInd
01181 {
01182
01183 SqlInd(OCIInd ind=OCI_IND_NULL)
01184 : _ind(ind)
01185 {
01186 }
01187
01188 operator OCIInd() const {return _ind;}
01189 operator OCIInd*() {return &_ind;}
01190 operator const OCIInd*() const {return &_ind;}
01191
01192 bool is_null() const {return _ind==OCI_IND_NULL;}
01193 bool is_not_null() const {return _ind!=OCI_IND_NULL;}
01194
01195 void clear() {_ind = OCI_IND_NULL;}
01196 void set() {_ind = OCI_IND_NOTNULL;}
01197
01198 protected:
01199 OCIInd _ind;
01200 };
01201
01202
01203
01204
01205 struct SqlValue
01206 {
01207 SqlValue() {}
01208 SqlValue(OCIInd ind) : _ind(ind) {}
01209 SqlValue(const SqlValue& other) : _ind(other._ind) {}
01210
01211 bool is_null() const {return _ind.is_null();}
01212 bool is_not_null() const {return _ind.is_not_null();}
01213
01214 const SqlInd& ind() const {return _ind;}
01215 SqlInd& ind() {return _ind;}
01216
01217 protected:
01218 SqlInd _ind;
01219 };
01220
01221
01222 enum {INT_NULL = -1};
01223
01224
01225
01226 struct SqlIndArray
01227 {
01228
01229 SqlIndArray(int size=g_OCIPL_BULK_ROWS)
01230 : _count(size),
01231 _pind(new SqlInd[size])
01232 {
01233 }
01234
01235
01236 SqlIndArray(const SqlIndArray& other)
01237 : _count(other._count),
01238 _pind(new SqlInd[other._count])
01239 {
01240 memcpy(_pind, other._pind, other._count*sizeof(SqlInd));
01241 }
01242
01243
01244 ~SqlIndArray()
01245 {
01246 delete [] _pind;
01247 }
01248
01249 bool is_null(int idx) const {return _pind[idx].is_null();}
01250 bool is_not_null(int idx) const {return _pind[idx].is_not_null();}
01251
01252 const SqlInd& ind(int idx) const {return _pind[idx];}
01253 SqlInd& ind(int idx) {return _pind[idx];}
01254
01255 int get_buffer_count() const {return _count;}
01256
01257 protected:
01258 int _count;
01259 SqlInd* _pind;
01260 };
01261
01262
01263
01264
01265 struct SqlInt : public SqlValue
01266 {
01267
01268 SqlInt()
01269 {
01270 }
01271
01272
01273 SqlInt(int value)
01274 : _value(value)
01275 {
01276 _ind.set();
01277 }
01278
01279
01280 SqlInt(int value, OCIInd ind)
01281 : SqlValue(ind),
01282 _value(value)
01283 {
01284 }
01285
01286
01287 SqlInt(const SqlInt& other)
01288 : SqlValue(other),
01289 _value(other._value)
01290 {
01291 }
01292
01293
01294 operator int() const
01295 {
01296 return _ind.is_not_null()? _value: INT_NULL;
01297 }
01298
01299 int get_int(int null=INT_NULL) const
01300 {
01301 return _ind.is_not_null()? _value: null;
01302 }
01303
01304
01305 int* get_ref()
01306 {
01307 return &_value;
01308 }
01309
01310
01311 const int* get_ptr() const
01312 {
01313 return &_value;
01314 }
01315
01316
01317 tstring str() const
01318 {
01319 TCHAR buffer[16];
01320
01321 if (_ind.is_not_null()) {
01322 _stprintf_s1(buffer, sizeof(buffer)/sizeof(TCHAR), TEXT("%d"), _value);
01323 return buffer;
01324 } else
01325 return tstring();
01326 }
01327
01328 protected:
01329 int _value;
01330 };
01331
01332
01333
01334
01335 struct SqlIntArray : public SqlIndArray
01336 {
01337
01338 SqlIntArray(int size=g_OCIPL_BULK_ROWS)
01339 : SqlIndArray(size),
01340 _pvalues((int*)ocipl_alloc(size*sizeof(int)))
01341 {
01342 }
01343
01344 SqlIntArray(const SqlIntArray& other)
01345 : SqlIndArray(other),
01346 _pvalues((int*)ocipl_alloc(other._count*sizeof(int)))
01347 {
01348 memcpy(_pvalues, other._pvalues, other._count*sizeof(int));
01349 }
01350
01351 ~SqlIntArray()
01352 {
01353 ocipl_free(_pvalues);
01354 }
01355
01356 int get_int(int row, int null=INT_NULL) const {return _pind[row].is_not_null()? _pvalues[row]: null;}
01357
01358 int* get_ref(int row) {return &_pvalues[row];}
01359 const int* get_ptr(int row) const {return &_pvalues[row];}
01360
01361 tstring str(int row) const
01362 {
01363 TCHAR buffer[16];
01364
01365 if (_pind[row].is_not_null()) {
01366 _stprintf_s1(buffer, sizeof(buffer)/sizeof(TCHAR), TEXT("%d"), _pvalues[row]);
01367 return buffer;
01368 } else
01369 return tstring();
01370 }
01371
01372 protected:
01373 int* _pvalues;
01374 };
01375
01376
01377
01378
01379 struct SqlString : public SqlValue
01380 {
01381 SqlString(int blen=OCIPL_DEFAULT_STRING_BUFFER)
01382 : _blen(blen),
01383 _str((TCHAR*)ocipl_alloc((blen+1)*sizeof(TCHAR)))
01384 {
01385 *_str = '\0';
01386 }
01387
01388 SqlString(const TCHAR* s)
01389 : _blen(_tcslen(s)),
01390 _str(_tcsdup(s))
01391 {
01392 if (*s)
01393 _ind.set();
01394 }
01395
01396 SqlString(const TCHAR* s, int blen)
01397 : _blen(blen),
01398 _str((TCHAR*)ocipl_alloc((blen+1)*sizeof(TCHAR)))
01399 {
01400 ocipl_tcscpyn(_str, s, blen+1);
01401
01402 if (*s)
01403 _ind.set();
01404 }
01405
01406 SqlString(const SqlString& other)
01407 : SqlValue(other),
01408 _blen(_tcslen(other._str)),
01409 _str(_tcsdup(other._str))
01410 {
01411 }
01412
01413 ~SqlString()
01414 {
01415 ocipl_free(_str);
01416 }
01417
01418 size_t len() const {return is_null()? 0: _tcslen(_str);}
01419 size_t blen() const {return _blen;}
01420 size_t alen() const {return _blen + 1;}
01421
01422 void resize(size_t l) {_blen = l; _str = (TCHAR*)ocipl_realloc(_str, (l+1)*sizeof(TCHAR)); _str[l] = '\0';}
01423 void clear() {*_str = '\0'; _ind.clear();}
01424
01425 TCHAR* str() {return _str;}
01426 TCHAR* str(int l) {resize(l); return _str;}
01427
01428 const TCHAR* c_str() const {return is_null()? TEXT(""): _str;}
01429 operator const TCHAR*() const {return is_null()? TEXT(""): _str;}
01430
01431 SqlString& operator=(const TCHAR* s);
01432 SqlString& operator=(const tstring& s);
01433
01434 bool operator==(const TCHAR* s) const {return !_tcscmp(c_str(), s);}
01435 bool operator!=(const TCHAR* s) const {return _tcscmp(c_str(), s) != 0;}
01436 bool operator<(const TCHAR* s) const {return _tcscmp(c_str(), s) < 0;}
01437
01438 friend tostream& operator<<(tostream& os, const SqlString& str)
01439 {if (str.is_not_null()) os << str._str; return os;}
01440
01441 static inline TCHAR* ocipl_tcscpyn(TCHAR* dest, const TCHAR* source, size_t count)
01442 {
01443 TCHAR* d = dest;
01444
01445 for(const TCHAR* s=source; count&&(*d++=*s++); )
01446 count--;
01447
01448 return dest;
01449 }
01450
01451 protected:
01452 size_t _blen;
01453 TCHAR* _str;
01454 };
01455
01456
01457
01458
01459 struct SqlStringArray : public SqlIndArray
01460 {
01461
01462 SqlStringArray(int size=g_OCIPL_BULK_ROWS, int blen=OCIPL_DEFAULT_STRING_BUFFER)
01463 : SqlIndArray(size),
01464 _blen(blen),
01465 _buffer((TCHAR*)ocipl_alloc(size*(blen+1)*sizeof(TCHAR)))
01466 {
01467 memset(_buffer, 0, size*(blen+1)*sizeof(TCHAR));
01468 }
01469
01470 SqlStringArray(const SqlStringArray& other)
01471 : SqlIndArray(other),
01472 _blen(other._blen),
01473 _buffer((TCHAR*)ocipl_alloc(other._count*(other._blen+1)*sizeof(TCHAR)))
01474 {
01475 memcpy(_buffer, 0, other._count*(other._blen+1)*sizeof(TCHAR));
01476 }
01477
01478 ~SqlStringArray()
01479 {
01480 ocipl_free(_buffer);
01481 }
01482
01483 size_t len(int row) const {return is_not_null(row)? _tcslen(_buffer): 0;}
01484 size_t blen() const {return _blen;}
01485 size_t alen() const {return _blen+1;}
01486
01487 void clear(int row) {*_buffer = '\0'; _pind[row].clear();}
01488
01489 void assign(int row, const TCHAR* s) {strcpy_s(_buffer, _blen, s);}
01490
01491 TCHAR* str(int row) {return _buffer + row*(_blen+1);}
01492 const TCHAR* c_str(int row) const {return is_not_null(row)? _buffer + row*(_blen+1): TEXT("");}
01493
01494 protected:
01495 size_t _blen;
01496 TCHAR* _buffer;
01497 };
01498
01499
01500 extern tstring ocidate_to_string(const OCIDate& date);
01501 extern tstring ocidate_to_short_string(const OCIDate& date);
01502 extern struct tm* ocidate_to_gmt(const OCIDate& date);
01503 extern struct tm* ocidate_to_lctime(const OCIDate& date);
01504 extern time_t ocidate_to_time_t(const OCIDate& date);
01505
01506 #ifdef _WIN32
01507 extern bool ocidate_to_systemtime(const OCIDate& date, SYSTEMTIME* pSysTime);
01508 #endif
01509
01510
01511
01512
01513 struct OciDate : public OCIDate, public SqlValue
01514 {
01515 OciDate() {}
01516 OciDate(const OCIDate& date, OCIInd ind=OCI_IND_NOTNULL);
01517 OciDate(OCIError* errh, const TCHAR* str, const TCHAR* fmt=TEXT("dd.mm.yyyy"));
01518 OciDate(struct tm* t);
01519
01520 tstring str() const
01521 {
01522 if (_ind.is_not_null())
01523 return ocidate_to_string(*this);
01524 else
01525 return tstring();
01526 }
01527
01528 tstring short_str() const
01529 {
01530 if (_ind.is_not_null())
01531 return ocidate_to_short_string(*this);
01532 else
01533 return tstring();
01534 }
01535
01536 int get_int_date() const
01537 {
01538 if (_ind.is_not_null())
01539 return ((OCIDateYYYY*100) + OCIDateMM)*100 + OCIDateDD;
01540 else
01541 return 0;
01542 }
01543
01544 struct tm* get_gmt() const
01545 {
01546 if (_ind.is_not_null())
01547 return ocidate_to_gmt(*this);
01548 else
01549 return 0;
01550 }
01551
01552 struct tm* get_lctime() const
01553 {
01554 if (_ind.is_not_null())
01555 return ocidate_to_lctime(*this);
01556 else
01557 return 0;
01558 }
01559
01560 time_t get_time_t() const
01561 {
01562 if (_ind.is_not_null())
01563 return ocidate_to_time_t(*this);
01564 else
01565 return 0;
01566 }
01567
01568 #ifdef _WIN32
01569 bool get_systemtime(SYSTEMTIME* pSysTime) const
01570 {
01571 if (_ind.is_not_null())
01572 return ocidate_to_systemtime(*this, pSysTime);
01573 else
01574 return false;
01575 }
01576 #endif
01577
01578 int compare(const OciDate& other) const;
01579 };
01580
01581
01582
01583
01584 struct OciDateArray : public SqlIndArray
01585 {
01586
01587 OciDateArray(int size=g_OCIPL_BULK_ROWS)
01588 : SqlIndArray(size),
01589 _buffers((OCIDate*)ocipl_alloc(size*sizeof(OCIDate)))
01590 {
01591 }
01592
01593 ~OciDateArray()
01594 {
01595 ocipl_free(_buffers);
01596 }
01597
01598 const OCIDate& get_date(int row) const {return _buffers[row];}
01599 OciDate get_oci_date(int row) const {return OciDate(_buffers[row], _pind[row]);}
01600
01601 OCIDate* get_ref(int row) {return &_buffers[row];}
01602 const OCIDate* get_ref(int row) const {return &_buffers[row];}
01603
01604 tstring str(int row) const
01605 {
01606 if (_pind[row].is_not_null())
01607 return ocidate_to_string(_buffers[row]);
01608 else
01609 return tstring();
01610 }
01611
01612 tstring short_str(int row) const
01613 {
01614 if (_pind[row].is_not_null())
01615 return ocidate_to_short_string(_buffers[row]);
01616 else
01617 return tstring();
01618 }
01619
01620 int get_int_date(int row) const
01621 {
01622 if (_pind[row].is_not_null()) {
01623 const OCIDate& date = _buffers[row];
01624 return ((date.OCIDateYYYY*100) + date.OCIDateMM)*100 + date.OCIDateDD;
01625 } else
01626 return 0;
01627 }
01628
01629 struct tm* get_gmt(int row) const
01630 {
01631 if (_pind[row].is_not_null())
01632 return ocidate_to_gmt(_buffers[row]);
01633 else
01634 return 0;
01635 }
01636
01637 struct tm* get_lctime(int row) const
01638 {
01639 if (_pind[row].is_not_null())
01640 return ocidate_to_lctime(_buffers[row]);
01641 else
01642 return 0;
01643 }
01644
01645 time_t get_time_t(int row) const
01646 {
01647 if (_pind[row].is_not_null())
01648 return ocidate_to_time_t(_buffers[row]);
01649 else
01650 return 0;
01651 }
01652
01653 void set_date(int row, const OciDate& date) {_buffers[row] = date; _pind[row] = date.ind();}
01654
01655 protected:
01656 OCIDate* _buffers;
01657 };
01658
01659
01660
01661 struct ocidatetime {
01662 ub1 century;
01663 ub1 year;
01664 ub1 month;
01665 ub1 day;
01666 ub1 hour;
01667 ub1 minute;
01668 ub1 second;
01669 };
01670
01671 extern tstring ocidatetime_to_string(const ocidatetime& date);
01672
01673
01674
01675
01676 struct SqlDateTime : public SqlValue
01677 {
01678 SqlDateTime() {}
01679
01680 SqlDateTime(const ocidatetime& date, OCIInd ind=OCI_IND_NOTNULL)
01681 : SqlValue(ind),
01682 _date(date)
01683 {
01684 }
01685
01686 ocidatetime* get_ref() {return &_date;}
01687 const ocidatetime* get_ptr() const {return &_date;}
01688
01689 const ocidatetime& get_datetime() const {return _date;}
01690
01691 tstring str() const
01692 {
01693 if (_ind.is_not_null())
01694 return ocidatetime_to_string(_date);
01695 else
01696 return tstring();
01697 }
01698
01699 protected:
01700 ocidatetime _date;
01701 };
01702
01703
01704
01705
01706 struct SqlDateTimeArray : public SqlIndArray
01707 {
01708
01709 SqlDateTimeArray(int size=g_OCIPL_BULK_ROWS)
01710 : SqlIndArray(size),
01711 _buffers((ocidatetime*)ocipl_alloc(size*sizeof(ocidatetime)))
01712 {
01713 }
01714
01715 ~SqlDateTimeArray()
01716 {
01717 ocipl_free(_buffers);
01718 }
01719
01720 const ocidatetime& get_datetime(int row) const {return _buffers[row];}
01721 SqlDateTime get_sql_date(int row) const {return SqlDateTime(_buffers[row], _pind[row]);}
01722
01723 ocidatetime* get_ref(int row) {return &_buffers[row];}
01724 const ocidatetime* get_ptr(int row) const {return &_buffers[row];}
01725
01726 tstring str(int row) const
01727 {
01728 if (_pind[row].is_not_null())
01729 return ocidatetime_to_string(_buffers[row]);
01730 else
01731 return tstring();
01732 }
01733
01734 void set_datetime(int row, const SqlDateTime& datetime) {_buffers[row] = datetime.get_datetime(); _pind[row] = datetime.ind();}
01735
01736 protected:
01737 ocidatetime* _buffers;
01738 };
01739
01740
01741
01742 struct oraclenumber {
01743 ub1 len;
01744 ub1 exp;
01745 ub1 mant[20];
01746 };
01747
01748
01749 extern int number_to_int(const oraclenumber& val, OCIError* errh);
01750 extern double number_to_double(const oraclenumber& val, OCIError* errh);
01751 extern tstring number_to_str(const oraclenumber& val, OCIError* errh, const TCHAR* fmt, const TCHAR* nls_fmt);
01752
01753 #ifdef _MSC_VER
01754 extern LONGLONG number_to_int64(const oraclenumber& val, OCIError* errh, int null=INT_NULL);
01755 #endif
01756
01757
01758
01759
01760 struct SqlNumber : public SqlValue
01761 {
01762 SqlNumber() {}
01763
01764 SqlNumber(const oraclenumber* pnum);
01765
01766 SqlNumber(OCIError* errh, const TCHAR* s,
01767 const TCHAR* fmt=TEXT("99999999999999999999999999999999999999D99999999999999999999"),
01768 const TCHAR* nls_fmt=TEXT("NLS_NUMERIC_CHARACTERS='.,'"));
01769
01770 SqlNumber(OCIError* errh, double d)
01771 {
01772 sword res = OCINumberFromReal(errh, &d, sizeof(d), (OCINumber*)&_val);
01773 oci_check_error(errh, res);
01774 _ind.set();
01775 }
01776
01777
01778 SqlNumber(OCIError* errh, double d, OCIInd ind)
01779 : SqlValue(ind)
01780 {
01781 if (ind != OCI_IND_NULL) {
01782 sword res = OCINumberFromReal(errh, &d, sizeof(d), (OCINumber*)&_val);
01783 oci_check_error(errh, res);
01784 }
01785 }
01786
01787 SqlNumber(OCIError* errh, int i)
01788 {
01789 sword res = OCINumberFromInt(errh, &i, sizeof(i), OCI_NUMBER_SIGNED, (OCINumber*)&_val);
01790 oci_check_error(errh, res);
01791 _ind.set();
01792 }
01793
01794
01795 SqlNumber(OCIError* errh, int i, OCIInd ind)
01796 : SqlValue(ind)
01797 {
01798 if (ind != OCI_IND_NULL) {
01799 sword res = OCINumberFromInt(errh, &i, sizeof(i), OCI_NUMBER_SIGNED, (OCINumber*)&_val);
01800 oci_check_error(errh, res);
01801 }
01802 }
01803
01804 SqlNumber(ub1* num_ptr, ub1 num_len)
01805 {
01806 memcpy(&_val.exp, num_ptr, num_len);
01807 _val.len = num_len;
01808 _ind.set();
01809 }
01810
01811 const oraclenumber& get_number() const {return _val;}
01812
01813 oraclenumber* get_ref() {return &_val;}
01814 const oraclenumber* get_ptr() const {return &_val;}
01815
01816
01817 tstring str(OCIError* errh, const TCHAR* fmt=TEXT("TM9"),
01818 const TCHAR* nls_fmt=TEXT("NLS_NUMERIC_CHARACTERS='.,'")) const
01819 {
01820 if (_ind.is_not_null())
01821 return number_to_str(_val, errh, fmt, nls_fmt);
01822 else
01823 return tstring();
01824 }
01825
01826 operator OCINumber*() {return (OCINumber*)&_val;}
01827 operator const OCINumber*() const {return (OCINumber*)&_val;}
01828
01829 int get_int(OCIError* errh, int null=INT_NULL) const
01830 {
01831 if (is_null())
01832 return null;
01833 else
01834 return number_to_int(_val, errh);
01835 }
01836
01837 #ifdef _MSC_VER
01838 LONGLONG get_int64(OCIError* errh, int null=INT_NULL) const
01839 {
01840 if (is_null())
01841 return null;
01842 else
01843 return number_to_int64(_val, errh, null);
01844 }
01845 #endif
01846
01847 double get_double(OCIError* errh, double null=0.) const
01848 {
01849 if (is_null())
01850 return null;
01851 else
01852 return number_to_double(_val, errh);
01853 }
01854
01855 protected:
01856 oraclenumber _val;
01857 };
01858
01859
01860
01861
01862 struct SqlNumberArray : public SqlIndArray
01863 {
01864
01865 SqlNumberArray(int size=g_OCIPL_BULK_ROWS)
01866 : SqlIndArray(size),
01867 _pvalues((oraclenumber*)ocipl_alloc(size*sizeof(oraclenumber)))
01868 {
01869 }
01870
01871 ~SqlNumberArray()
01872 {
01873 ocipl_free(_pvalues);
01874 }
01875
01876 const oraclenumber& get_number(int row) const {return _pvalues[row];}
01877
01878 oraclenumber* get_ref(int row) {return &_pvalues[row];}
01879 const oraclenumber* get_ptr(int row) const {return &_pvalues[row];}
01880
01881
01882 tstring str(int row, OCIError* errh, const TCHAR* fmt=TEXT("TM9"),
01883 const TCHAR* nls_fmt=TEXT("NLS_NUMERIC_CHARACTERS='.,'")) const
01884 {
01885 if (_pind[row].is_not_null())
01886 return number_to_str(_pvalues[row], errh, fmt, nls_fmt);
01887 else
01888 return tstring();
01889 }
01890
01891 int get_int(int row, OCIError* errh, int null=INT_NULL) const
01892 {
01893 if (is_not_null(row))
01894 return number_to_int(_pvalues[row], errh);
01895 else
01896 return null;
01897 }
01898
01899 #ifdef _MSC_VER
01900 LONGLONG get_int64(int row, OCIError* errh, int null=INT_NULL) const
01901 {
01902 if (is_not_null(row))
01903 return number_to_int64(_pvalues[row], errh, null);
01904 else
01905 return null;
01906 }
01907 #endif
01908
01909 double get_double(int row, OCIError* errh, double null=0.) const
01910 {
01911 if (is_not_null(row))
01912 return number_to_double(_pvalues[row], errh);
01913 else
01914 return null;
01915 }
01916
01917 void set_number(int row, const SqlNumber& num) {_pvalues[row] = num.get_number(); _pind[row] = num.ind();}
01918
01919 protected:
01920 oraclenumber* _pvalues;
01921 };
01922
01923
01924
01925
01926
01927 struct OciLob : public SqlValue
01928 {
01929
01930
01931 OciLob(OciConnection& conn)
01932 : _conn(conn)
01933 {
01934 sword res = OCIDescriptorAlloc(conn._env, (dvoid**)&_loc, OCI_DTYPE_LOB, 0, NULL);
01935 oci_check_error(conn._env, res);
01936 }
01937
01938 OciLob(OciConnection& conn, OCILobLocator* loc)
01939 : _conn(conn),
01940 _loc(loc)
01941 {
01942 }
01943
01944 OciLob(const OciLob& other)
01945 : _conn(other._conn)
01946 {
01947 sword res = OCIDescriptorAlloc(_conn._env, (dvoid**)&_loc, OCI_DTYPE_LOB, 0, NULL);
01948 oci_check_error(_conn._env._errh, res);
01949
01950 #if ORACLE_VERSION>=81
01951 res = OCILobLocatorAssign(_conn._ctx, _conn._env._errh, other._loc, &_loc);
01952 #else
01953 res = OCILobAssign(_conn._env, _conn._env._errh, other._loc, &_loc);
01954 #endif
01955 oci_check_error(_conn._env._errh, res);
01956
01957 clear();
01958 }
01959
01960 ~OciLob()
01961 {
01962 #if ORACLE_VERSION>=81
01963
01964
01965 if (is_temporary()) {
01966 sword res = OCILobFreeTemporary(_conn._ctx, _conn._env._errh, _loc);
01967 oci_check_error(_conn._env._errh, res);
01968 }
01969 #endif
01970
01971 sword res = OCIDescriptorFree(_loc, OCI_DTYPE_LOB);
01972 oci_check_error(_conn._env._errh, res);
01973 }
01974
01975 boolean operator==(const OciLob& other) const
01976 {
01977 boolean is_equal;
01978
01979 sword res = OCILobIsEqual(_conn._env, _loc, other._loc, &is_equal);
01980
01981 oci_check_error(_conn._env._errh, res);
01982
01983 return is_equal;
01984 }
01985
01986 void clear()
01987 {
01988 ub4 lobEmpty = 0;
01989 sword res = OCIAttrSet(_loc, OCI_DTYPE_LOB, &lobEmpty, 0, OCI_ATTR_LOBEMPTY, _conn._env._errh);
01990 oci_check_error(_conn._env._errh, res);
01991 }
01992
01993 void* get_ref() {return &_loc;}
01994 const void* get_ptr() const {return &_loc;}
01995
01996
01997
01998
01999 ub4 get_chunk_size()
02000 {
02001 ub4 len;
02002
02003 sword res = OCILobGetLength(_conn._ctx, _conn._env._errh, _loc, &len);
02004 oci_check_error(_conn._env._errh, res);
02005
02006 return len;
02007 }
02008
02009 #if ORACLE_VERSION>=81
02010 ub4 get_length()
02011 {
02012 ub4 size;
02013
02014 sword res = OCILobGetChunkSize(_conn._ctx, _conn._env._errh, _loc, &size);
02015 oci_check_error(_conn._env._errh, res);
02016
02017 return size;
02018 }
02019
02020 boolean is_open() const
02021 {
02022 boolean flag;
02023
02024 sword res = OCILobIsOpen(_conn._ctx, _conn._env._errh, _loc, &flag);
02025 oci_check_error(_conn._env._errh, res);
02026
02027 return flag;
02028 }
02029
02030 boolean is_temporary() const
02031 {
02032 boolean flag;
02033
02034 sword res = OCILobIsTemporary(_conn._env, _conn._env._errh, _loc, &flag);
02035 oci_check_error(_conn._env._errh, res);
02036
02037 return flag;
02038 }
02039 #endif
02040
02041
02042 void copy(const OciLob& src, ub4 amount, ub4 dst_offset, ub4 src_offset)
02043 {
02044 sword res = OCILobCopy(_conn._ctx, _conn._env._errh, _loc, src._loc, amount, dst_offset, src_offset);
02045 oci_check_error(_conn._env._errh, res);
02046 }
02047
02048 void append(const OciLob& src)
02049 {
02050 sword res = OCILobAppend(_conn._ctx, _conn._env._errh, _loc, src._loc);
02051 oci_check_error(_conn._env._errh, res);
02052 }
02053
02054 void trim(ub4 newlen=0)
02055 {
02056 sword res = OCILobTrim(_conn._ctx, _conn._env._errh, _loc, newlen);
02057 oci_check_error(_conn._env._errh, res);
02058 }
02059
02060 ub4 erase(ub4 offset, ub4 amount)
02061 {
02062 sword res = OCILobErase(_conn._ctx, _conn._env._errh, _loc, &amount, offset);
02063 oci_check_error(_conn._env._errh, res);
02064
02065 return amount;
02066 }
02067
02068
02069 void enable_buffering()
02070 {
02071 sword res = OCILobEnableBuffering(_conn._ctx, _conn._env._errh, _loc);
02072 oci_check_error(_conn._env._errh, res);
02073 }
02074
02075 void disable_buffering()
02076 {
02077 sword res = OCILobDisableBuffering(_conn._ctx, _conn._env._errh, _loc);
02078 oci_check_error(_conn._env._errh, res);
02079 }
02080
02081 void flush(ub4 flag=OCI_LOB_BUFFER_NOFREE)
02082 {
02083 sword res = OCILobFlushBuffer(_conn._ctx, _conn._env._errh, _loc, flag);
02084 oci_check_error(_conn._env._errh, res);
02085 }
02086
02087 protected:
02088 OciConnection& _conn;
02089 OCILobLocator* _loc;
02090
02091 friend struct OciOpenLob;
02092 };
02093
02094
02095 #if ORACLE_VERSION>=81
02096
02097
02098
02099 struct OciOpenLob
02100 {
02101 OciOpenLob(OciLob& lob, ub1 mode=OCI_LOB_READWRITE)
02102 : _lob(lob)
02103 {
02104 sword res = OCILobOpen(lob._conn._ctx, lob._conn._env._errh, lob._loc, mode);
02105 oci_check_error(lob._conn._env._errh, res);
02106 }
02107
02108 ~OciOpenLob()
02109 {
02110 sword res = OCILobClose(_lob._conn._ctx, _lob._conn._env._errh, _lob._loc);
02111 oci_check_error(_lob._conn._env._errh, res);
02112 }
02113
02114 protected:
02115 OciLob& _lob;
02116 };
02117
02118
02119
02120 struct OciBlob : public OciLob
02121 {
02122 OciBlob(OciConnection& conn) : OciLob(conn) {}
02123 OciBlob(const OciLob& other) : OciLob(other) {}
02124
02125 ub4 write(const dvoid* bufp, ub4 buflen, ub4 offset, ub4 amount)
02126 {
02127 sword res = OCILobWrite(_conn._ctx, _conn._env._errh, _loc,
02128 &amount, offset, (dvoid*)bufp, buflen,
02129 OCI_ONE_PIECE, NULL, NULL,
02130 0, 0);
02131
02132 oci_check_error(_conn._env._errh, res);
02133
02134 return amount;
02135 }
02136
02137 ub4 write_append(const dvoid* bufp, ub4 buflen, ub4 amount)
02138 {
02139 sword res = OCILobWriteAppend(_conn._ctx, _conn._env._errh, _loc,
02140 &amount, (dvoid*)bufp, buflen,
02141 OCI_ONE_PIECE, NULL, NULL,
02142 0, 0);
02143
02144 oci_check_error(_conn._env._errh, res);
02145
02146 return amount;
02147 }
02148
02149 ub4 read(dvoid* bufp, ub4 buflen, ub4 offset, ub4 amount)
02150 {
02151 sword res = OCILobRead(_conn._ctx, _conn._env._errh, _loc,
02152 &amount, offset, bufp, buflen,
02153 NULL, NULL,
02154 0, 0);
02155
02156 oci_check_error(_conn._env._errh, res);
02157
02158 return amount;
02159 }
02160 };
02161
02162 struct OciTempBlob : public OciBlob
02163 {
02164 OciTempBlob(OciConnection& conn, OCIDuration dur=OCI_DURATION_SESSION)
02165 : OciBlob(conn)
02166 {
02167 sword res = OCILobCreateTemporary(conn._ctx, conn._env._errh, _loc,
02168 OCI_DEFAULT, SQLCS_IMPLICIT, OCI_TEMP_BLOB, FALSE, dur);
02169
02170 oci_check_error(_conn._env._errh, res);
02171 }
02172
02173 ~OciTempBlob()
02174 {
02175
02176
02177
02178
02179 }
02180 };
02181
02182 #endif
02183
02184
02185
02186
02187 struct OciClob : public OciLob
02188 {
02189 OciClob(OciConnection& conn) : OciLob(conn) {}
02190 OciClob(const OciLob& other) : OciLob(other) {}
02191
02192 ub4 write(const dvoid* bufp, ub4 buflen, ub4 offset, ub4 amount, ub2 csid=0, ub1 csfrm=SQLCS_IMPLICIT)
02193 {
02194 sword res = OCILobWrite(_conn._ctx, _conn._env._errh, _loc,
02195 &amount, offset, (dvoid*)bufp, buflen,
02196 OCI_ONE_PIECE, NULL, NULL,
02197 csid, csfrm);
02198
02199 oci_check_error(_conn._env._errh, res);
02200
02201 return amount;
02202 }
02203
02204 #if ORACLE_VERSION>=81
02205 ub4 write_append(const dvoid* bufp, ub4 buflen, ub4 amount, ub2 csid=0, ub1 csfrm=SQLCS_IMPLICIT)
02206 {
02207 sword res = OCILobWriteAppend(_conn._ctx, _conn._env._errh, _loc,
02208 &amount, (dvoid*)bufp, buflen,
02209 OCI_ONE_PIECE, NULL, NULL,
02210 csid, csfrm);
02211
02212 oci_check_error(_conn._env._errh, res);
02213
02214 return amount;
02215 }
02216 #endif
02217
02218 ub4 read(dvoid* bufp, ub4 buflen, ub4 offset, ub4 amount, ub2 csid=0, ub1 csfrm=SQLCS_IMPLICIT)
02219 {
02220 sword res = OCILobRead(_conn._ctx, _conn._env._errh, _loc,
02221 &amount, offset, bufp, buflen,
02222 NULL, NULL,
02223 csid, csfrm);
02224
02225 oci_check_error(_conn._env._errh, res);
02226
02227 return amount;
02228 }
02229 };
02230
02231 #if ORACLE_VERSION>=81
02232 struct OciTempClob : public OciClob
02233 {
02234 OciTempClob(OciConnection& conn, OCIDuration dur=OCI_DURATION_SESSION)
02235 : OciClob(conn)
02236 {
02237 sword res = OCILobCreateTemporary(conn._ctx, conn._env._errh, _loc,
02238 OCI_DEFAULT, SQLCS_IMPLICIT, OCI_TEMP_CLOB, FALSE, dur);
02239
02240 oci_check_error(_conn._env._errh, res);
02241 }
02242
02243 ~OciTempClob()
02244 {
02245
02246
02247
02248
02249 }
02250 };
02251 #endif
02252
02253
02254
02255
02256
02257
02258
02259
02260
02261
02262
02263
02264
02265
02266
02267
02268
02269
02270
02271
02272
02273
02274
02275
02276
02277
02278
02279
02280
02281
02282
02283
02284
02285
02286
02287
02288
02289
02290
02291
02292
02293
02294
02295
02296 struct BindInput
02297 {
02298 const dvoid* valuep;
02299 sb4 value_sz;
02300 ub2 dty;
02301 const OCIInd* indp;
02302
02303 BindInput(const SqlInt& var)
02304 {
02305 valuep = var.get_ptr();
02306 value_sz= sizeof(int);
02307 dty = SQLT_INT;
02308 indp = var.ind();
02309 }
02310
02311 BindInput(const int& var, OCIInd* ind=NULL)
02312 {
02313 valuep = (void*)&var;
02314 value_sz= sizeof(int);
02315 dty = SQLT_INT;
02316 indp = ind;
02317 }
02318
02319 BindInput(const unsigned int& var, OCIInd* ind=NULL)
02320 {
02321 valuep = (void*)&var;
02322 value_sz= sizeof(unsigned int);
02323 dty = SQLT_UIN;
02324 indp = ind;
02325 }
02326
02327 BindInput(const long& var, OCIInd* ind=NULL)
02328 {
02329 valuep = (void*)&var;
02330 value_sz= sizeof(long);
02331 dty = SQLT_INT;
02332 indp = ind;
02333 }
02334
02335 BindInput(const unsigned long& var, OCIInd* ind=NULL)
02336 {
02337 valuep = (void*)&var;
02338 value_sz= sizeof(unsigned long);
02339 dty = SQLT_UIN;
02340 indp = ind;
02341 }
02342
02343 BindInput(const char& var, OCIInd* ind=NULL)
02344 {
02345 valuep = (void*)&var;
02346 value_sz= sizeof(char);
02347 dty = SQLT_CHR;
02348 indp = ind;
02349 }
02350
02351 BindInput(const float& var, OCIInd* ind=NULL)
02352 {
02353 valuep = (void*)&var;
02354 value_sz= sizeof(float);
02355 dty = SQLT_FLT;
02356 indp = ind;
02357 }
02358
02359 BindInput(const double& var, OCIInd* ind=NULL)
02360 {
02361 valuep = (void*)&var;
02362 value_sz= sizeof(double);
02363 dty = SQLT_FLT;
02364 indp = ind;
02365 }
02366
02367 BindInput(const TCHAR* buffer)
02368 {
02369 valuep = (dvoid*) buffer;
02370 value_sz= buffer? (sb4)(_tcslen(buffer)+1)*sizeof(TCHAR): 0;
02371 dty = SQLT_STR;
02372 indp = NULL;
02373 }
02374
02375 BindInput(const TCHAR* buffer, size_t len, ub2 type=SQLT_AFC, OCIInd* ind=NULL)
02376 {
02377 valuep = (dvoid*) buffer;
02378 value_sz= (sb4)len;
02379 dty = type;
02380 indp = ind;
02381 }
02382
02383 BindInput(const tstring& str)
02384 {
02385 valuep = (dvoid*) str.c_str();
02386 value_sz= (sb4)(str.length()+1)*sizeof(TCHAR);
02387 dty = SQLT_STR;
02388 indp = NULL;
02389 }
02390
02391 BindInput(const SqlString& str)
02392 {
02393 valuep = (dvoid*) str.c_str();
02394 value_sz= (sb4)str.alen()*sizeof(TCHAR);
02395 dty = SQLT_STR;
02396 indp = NULL;
02397 }
02398
02399 #ifdef __ISSD_H
02400 BindInput(const String& str)
02401 {
02402 valuep = (dvoid*) str.c_str();
02403 value_sz= (sb4)(str.length()+1)*sizeof(TCHAR);
02404 dty = SQLT_STR;
02405 indp = NULL;
02406 }
02407 #endif
02408
02409
02410
02411
02412
02413
02414
02415
02416
02417
02418 BindInput(const OciDate& date)
02419 {
02420 valuep = &date;
02421 value_sz= sizeof(OCIDate);
02422 dty = SQLT_ODT;
02423 indp = date.ind();
02424 }
02425
02426 BindInput(const OCIDate& date, OCIInd* ind)
02427 {
02428 valuep = &date;
02429 value_sz= sizeof(OCIDate);
02430 dty = SQLT_ODT;
02431 indp = ind;
02432 }
02433
02434 BindInput(const SqlDateTime& date)
02435 {
02436 valuep = date.get_ptr();
02437 value_sz= sizeof(ocidatetime);
02438 dty = SQLT_DAT;
02439 indp = date.ind();
02440 }
02441
02442 BindInput(const ocidatetime& date, OCIInd* ind)
02443 {
02444 valuep = &date;
02445 value_sz= sizeof(ocidatetime);
02446 dty = SQLT_DAT;
02447 indp = ind;
02448 }
02449
02450 BindInput(const SqlNumber& num)
02451 {
02452 valuep = num.get_ptr();
02453 value_sz= sizeof(oraclenumber);
02454 dty = SQLT_VNU;
02455 indp = num.ind();
02456 }
02457
02458 BindInput(const oraclenumber& num, OCIInd* ind)
02459 {
02460 valuep = #
02461 value_sz= sizeof(oraclenumber);
02462 dty = SQLT_VNU;
02463 indp = ind;
02464 }
02465
02466 #if ORACLE_VERSION>=81
02467 BindInput(const OciBlob& blob)
02468 {
02469 valuep = blob.get_ptr();
02470 value_sz= sizeof(OCILobLocator*);
02471 dty = SQLT_BLOB;
02472 indp = blob.ind();
02473 }
02474
02475 BindInput(const OciClob& clob)
02476 {
02477 valuep = clob.get_ptr();
02478 value_sz= sizeof(OCIClobLocator*);
02479 dty = SQLT_CLOB;
02480 indp = clob.ind();
02481 }
02482 #endif
02483
02484 protected:
02485 BindInput()
02486 {
02487 }
02488 };
02489
02490
02491
02492
02493 struct BindOutput
02494 {
02495 dvoid* valuep;
02496 sb4 value_sz;
02497 ub2 dty;
02498 OCIInd* indp;
02499
02500 BindOutput(SqlInt& var)
02501 {
02502 valuep = var.get_ref();
02503 value_sz= sizeof(int);
02504 dty = SQLT_INT;
02505 indp = var.ind();
02506 }
02507
02508 BindOutput(int& var, OCIInd* ind=NULL)
02509 {
02510 valuep = (void*)&var;
02511 value_sz= sizeof(int);
02512 dty = SQLT_INT;
02513 indp = ind;
02514 }
02515
02516 BindOutput(unsigned int& var, OCIInd* ind=NULL)
02517 {
02518 valuep = (void*)&var;
02519 value_sz= sizeof(unsigned int);
02520 dty = SQLT_UIN;
02521 indp = ind;
02522 }
02523
02524 BindOutput(long& var, OCIInd* ind=NULL)
02525 {
02526 valuep = (void*)&var;
02527 value_sz= sizeof(long);
02528 dty = SQLT_INT;
02529 indp = ind;
02530 }
02531
02532 BindOutput(unsigned long& var, OCIInd* ind=NULL)
02533 {
02534 valuep = (void*)&var;
02535 value_sz= sizeof(unsigned long);
02536 dty = SQLT_UIN;
02537 indp = ind;
02538 }
02539
02540 BindOutput(char& var, OCIInd* ind=NULL)
02541 {
02542 valuep = (void*)&var;
02543 value_sz= sizeof(char);
02544 dty = SQLT_CHR;
02545 indp = ind;
02546 }
02547
02548 BindOutput(float& var, OCIInd* ind=NULL)
02549 {
02550 valuep = (void*)&var;
02551 value_sz= sizeof(float);
02552 dty = SQLT_FLT;
02553 indp = ind;
02554 }
02555
02556 BindOutput(double& var, OCIInd* ind=NULL)
02557 {
02558 valuep = (void*)&var;
02559 value_sz= sizeof(double);
02560 dty = SQLT_FLT;
02561 indp = ind;
02562 }
02563
02564 BindOutput(TCHAR* buffer)
02565 {
02566 valuep = (dvoid*) buffer;
02567 value_sz= buffer? (sb4)(_tcslen(buffer)+1)*sizeof(TCHAR): 0;
02568 dty = SQLT_STR;
02569 indp = NULL;
02570 }
02571
02572 BindOutput(TCHAR* buffer, size_t len, ub2 type=SQLT_AFC, OCIInd* ind=NULL)
02573 {
02574 valuep = (dvoid*) buffer;
02575 value_sz= (sb4)len;
02576 dty = type;
02577 indp = ind;
02578 }
02579
02580 BindOutput(tstring& str)
02581 {
02582 valuep = (dvoid*) str.c_str();
02583 value_sz= (sb4)(str.length()+1)*sizeof(TCHAR);
02584 dty = SQLT_STR;
02585 indp = NULL;
02586 }
02587
02588 BindOutput(SqlString& str)
02589 {
02590 valuep = (dvoid*) str.str();
02591 value_sz= (sb4)str.alen()*sizeof(TCHAR);
02592 dty = SQLT_STR;
02593 indp = str.ind();
02594 }
02595
02596
02597
02598
02599
02600
02601
02602
02603
02604
02605 BindOutput(OciDate& date)
02606 {
02607 valuep = &date;
02608 value_sz= sizeof(OCIDate);
02609 dty = SQLT_ODT;
02610 indp = date.ind();
02611 }
02612
02613 BindOutput(SqlDateTime& date)
02614 {
02615 valuep = date.get_ref();
02616 value_sz= sizeof(ocidatetime);
02617 dty = SQLT_DAT;
02618 indp = date.ind();
02619 }
02620
02621 BindOutput(SqlNumber& num)
02622 {
02623 valuep = num.get_ref();
02624 value_sz= sizeof(oraclenumber);
02625 dty = SQLT_VNU;
02626 indp = num.ind();
02627 }
02628
02629 #if ORACLE_VERSION>=81
02630 BindOutput(OciBlob& blob)
02631 {
02632 valuep = blob.get_ref();
02633 value_sz= sizeof(OCILobLocator*);
02634 dty = SQLT_BLOB;
02635 indp = blob.ind();
02636 }
02637
02638 BindOutput(OciClob& clob)
02639 {
02640 valuep = clob.get_ref();
02641 value_sz= sizeof(OCIClobLocator*);
02642 dty = SQLT_CLOB;
02643 indp = clob.ind();
02644 }
02645 #endif
02646
02647 protected:
02648 BindOutput()
02649 {
02650 }
02651 };
02652
02653
02654
02655
02656 struct TrimBindPar : BindInput
02657 {
02658 TrimBindPar(const TCHAR* buffer, size_t max_len)
02659 {
02660 size_t len = _tcslen(buffer);
02661
02662 valuep = (dvoid*) buffer;
02663 value_sz= (sb4)min(len, max_len)*sizeof(TCHAR);
02664 dty = SQLT_AFC;
02665 indp = NULL;
02666 }
02667
02668 TrimBindPar(const tstring& str, size_t max_len)
02669 {
02670 size_t len = str.length();
02671
02672 valuep = (dvoid*) str.c_str();
02673 value_sz= (sb4)min(len, max_len)*sizeof(TCHAR);
02674 dty = SQLT_AFC;
02675 indp = NULL;
02676 }
02677
02678 TrimBindPar(const SqlString& str, size_t max_len)
02679 {
02680 size_t len = str.len();
02681
02682 valuep = (dvoid*) str.c_str();
02683 value_sz= (sb4)min(len, max_len)*sizeof(TCHAR);
02684 dty = SQLT_AFC;
02685 indp = NULL;
02686 }
02687 };
02688
02689
02690
02691
02692 struct DefinePar
02693 {
02694 dvoid* valuep;
02695 sb4 value_sz;
02696 ub2 dty;
02697 OCIInd* indp;
02698 int buffers;
02699
02700 DefinePar(SqlInt& var)
02701 {
02702 valuep = var.get_ref();
02703 value_sz= sizeof(int);
02704 dty = SQLT_INT;
02705 indp = var.ind();
02706 buffers = 1;
02707 }
02708 DefinePar(SqlIntArray& arr)
02709 {
02710 valuep = arr.get_ref(0);
02711 value_sz= sizeof(int);
02712 dty = SQLT_INT;
02713 indp = arr.ind(0);
02714 buffers = arr.get_buffer_count();
02715 }
02716
02717 DefinePar(int& var, OCIInd* ind=NULL)
02718 {
02719 valuep = &var;
02720 value_sz= sizeof(int);
02721 dty = SQLT_INT;
02722 indp = ind;
02723 buffers = 1;
02724 }
02725 DefinePar(int* arr, int count, OCIInd* ind=NULL)
02726 {
02727 valuep = arr;
02728 value_sz= sizeof(int);
02729 dty = SQLT_INT;
02730 indp = ind;
02731 buffers = count;
02732 }
02733
02734 DefinePar(unsigned int& var, OCIInd* ind=NULL)
02735 {
02736 valuep = &var;
02737 value_sz= sizeof(unsigned int);
02738 dty = SQLT_UIN;
02739 indp = ind;
02740 buffers = 1;
02741 }
02742 DefinePar(unsigned int* arr, int count, OCIInd* ind=NULL)
02743 {
02744 valuep = arr;
02745 value_sz= sizeof(unsigned int);
02746 dty = SQLT_UIN;
02747 indp = ind;
02748 buffers = count;
02749 }
02750
02751 DefinePar(LONGLONG& var, OCIInd* ind=NULL)
02752 {
02753 valuep = &var;
02754 value_sz= sizeof(LONGLONG);
02755 dty = SQLT_INT;
02756 indp = ind;
02757 buffers = 1;
02758 }
02759 DefinePar(LONGLONG* arr, int count, OCIInd* ind=NULL)
02760 {
02761 valuep = arr;
02762 value_sz= sizeof(LONGLONG);
02763 dty = SQLT_INT;
02764 indp = ind;
02765 buffers = count;
02766 }
02767
02768 DefinePar(long& var, OCIInd* ind=NULL)
02769 {
02770 valuep = &var;
02771 value_sz= sizeof(long);
02772 dty = SQLT_INT;
02773 indp = ind;
02774 buffers = 1;
02775 }
02776 DefinePar(long* arr, int count, OCIInd* ind=NULL)
02777 {
02778 valuep = arr;
02779 value_sz= sizeof(long);
02780 dty = SQLT_INT;
02781 indp = ind;
02782 buffers = count;
02783 }
02784
02785 DefinePar(unsigned long& var, OCIInd* ind=NULL)
02786 {
02787 valuep = &var;
02788 value_sz= sizeof(unsigned long);
02789 dty = SQLT_UIN;
02790 indp = ind;
02791 buffers = 1;
02792 }
02793 DefinePar(unsigned long* arr, int count, OCIInd* ind=NULL)
02794 {
02795 valuep = arr;
02796 value_sz= sizeof(unsigned long);
02797 dty = SQLT_UIN;
02798 indp = ind;
02799 buffers = count;
02800 }
02801
02802 DefinePar(double& var, OCIInd* ind=NULL)
02803 {
02804 valuep = &var;
02805 value_sz= sizeof(double);
02806 dty = SQLT_FLT;
02807 indp = ind;
02808 buffers = 1;
02809 }
02810 DefinePar(double* arr, int count, OCIInd* ind=NULL)
02811 {
02812 valuep = arr;
02813 value_sz= sizeof(double);
02814 dty = SQLT_FLT;
02815 indp = ind;
02816 buffers = count;
02817 }
02818
02819 #ifdef SQLT_BFLOAT
02820 DefinePar(float& var, OCIInd* ind=NULL)
02821 {
02822 valuep = &var;
02823 value_sz= sizeof(float);
02824 dty = SQLT_FLT;
02825 indp = ind;
02826 buffers = 1;
02827 }
02828 DefinePar(float* arr, int count, OCIInd* ind=NULL)
02829 {
02830 valuep = arr;
02831 value_sz= sizeof(float);
02832 dty = SQLT_FLT;
02833 indp = ind;
02834 buffers = count;
02835 }
02836 #endif
02837
02838 DefinePar(char& var, OCIInd* ind=NULL)
02839 {
02840 valuep = (void*)&var;
02841 value_sz= sizeof(char);
02842 dty = SQLT_CHR;
02843 indp = ind;
02844 buffers = 1;
02845 }
02846
02847 DefinePar(const TCHAR* buffer, size_t len, ub2 type=SQLT_STR, OCIInd* ind=NULL)
02848 {
02849 valuep = (dvoid*) buffer;
02850 value_sz= (sb4)len*sizeof(TCHAR);
02851 dty = type;
02852 indp = ind;
02853 buffers = 1;
02854 }
02855
02856 DefinePar(SqlString& str)
02857 {
02858 valuep = str.str();
02859 value_sz= (sb4)str.alen()*sizeof(TCHAR);
02860 dty = SQLT_STR;
02861 indp = str.ind();
02862 buffers = 1;
02863 }
02864 DefinePar(SqlStringArray& arr)
02865 {
02866 valuep = arr.str(0);
02867 value_sz= (sb4)arr.alen()*sizeof(TCHAR);
02868 dty = SQLT_STR;
02869 indp = arr.ind(0);
02870 buffers = arr.get_buffer_count();
02871 }
02872
02873
02874
02875
02876
02877
02878
02879
02880
02881
02882
02883
02884 DefinePar(OciDate& date)
02885 {
02886 valuep = &date;
02887 value_sz= sizeof(OCIDate);
02888 dty = SQLT_ODT;
02889 indp = date.ind();
02890 buffers = 1;
02891 }
02892 DefinePar(OciDateArray& arr)
02893 {
02894 valuep = arr.get_ref(0);
02895 value_sz= sizeof(OCIDate);
02896 dty = SQLT_ODT;
02897 indp = arr.ind(0);
02898 buffers = arr.get_buffer_count();
02899 }
02900
02901 DefinePar(SqlDateTime& date)
02902 {
02903 valuep = date.get_ref();
02904 value_sz= sizeof(ocidatetime);
02905 dty = SQLT_DAT;
02906 indp = date.ind();
02907 buffers = 1;
02908 }
02909 DefinePar(SqlDateTimeArray& arr)
02910 {
02911 valuep = arr.get_ref(0);
02912 value_sz= sizeof(ocidatetime);
02913 dty = SQLT_DAT;
02914 indp = arr.ind(0);
02915 buffers = arr.get_buffer_count();
02916 }
02917
02918 DefinePar(SqlNumber& num)
02919 {
02920 valuep = num.get_ref();
02921 value_sz= sizeof(oraclenumber);
02922 dty = SQLT_VNU;
02923 indp = num.ind();
02924 buffers = 1;
02925 }
02926 DefinePar(SqlNumberArray& arr)
02927 {
02928 valuep = arr.get_ref(0);
02929 value_sz= sizeof(oraclenumber);
02930 dty = SQLT_VNU;
02931 indp = arr.ind(0);
02932 buffers = arr.get_buffer_count();
02933 }
02934
02935 #if ORACLE_VERSION>=81
02936 DefinePar(OciBlob& blob)
02937 {
02938 valuep = blob.get_ref();
02939 value_sz= sizeof(OCILobLocator*);
02940 dty = SQLT_BLOB;
02941 indp = blob.ind();
02942 buffers = 1;
02943 }
02944
02945 DefinePar(OciClob& clob)
02946 {
02947 valuep = clob.get_ref();
02948 value_sz= sizeof(OCIClobLocator*);
02949 dty = SQLT_CLOB;
02950 indp = clob.ind();
02951 buffers = 1;
02952 }
02953 #endif
02954 };
02955
02956
02957 struct LocalOciState
02958 {
02959 LocalOciState(OciContext& ctx, OCI_STATE state)
02960 : _ctx(ctx)
02961 {
02962 _ctx.set_state(state);
02963 }
02964
02965 LocalOciState(OciContext& ctx, OCI_STATE state, int stmt_type)
02966 : _ctx(ctx)
02967 {
02968 _ctx.set_state(state, stmt_type);
02969 }
02970
02971 ~LocalOciState()
02972 {
02973 _ctx.reset_state();
02974 }
02975
02976 private:
02977 OciContext& _ctx;
02978 };
02979
02980
02981
02982
02983 struct SqlStatement : public OciHandle<OCIStmt>
02984 {
02985 typedef OciHandle<OCIStmt> super;
02986
02987 SqlStatement(OciConnection& conn, int bulk_rows=g_OCIPL_BULK_ROWS)
02988 : super(conn._env),
02989 _ctx(conn._ctx),
02990 _state(UNINITIALIZED),
02991 _last_file(NULL),
02992 _last_line(-1),
02993 _res(NULL),
02994 _stmt_type(-1),
02995 _bulk_rows(bulk_rows),
02996 _result_buffers(0),
02997 _last_row((ub4)-1),
02998 _last_fetched_row((ub4)-1)
02999 {
03000 }
03001
03002 #ifndef FORCE_CODEPOS
03003 SqlStatement(OciConnection& conn, const tstring& sql, ub4 lang=OCI_NTV_SYNTAX, int bulk_rows=g_OCIPL_BULK_ROWS)
03004 : super(conn._env),
03005 _ctx(conn._ctx),
03006 _state(UNINITIALIZED),
03007 _last_file(NULL),
03008 _last_line(-1),
03009 _res(NULL),
03010 _stmt_type(-1),
03011 _bulk_rows(bulk_rows),
03012 _result_buffers(0),
03013 _last_row((ub4)-1),
03014 _last_fetched_row((ub4)-1)
03015 {
03016 prepare(sql, lang);
03017 }
03018 #endif
03019
03020 SqlStatement(OciConnection& conn, const tstring& sql, const char* file, int line, ub4 lang=OCI_NTV_SYNTAX, int bulk_rows=g_OCIPL_BULK_ROWS)
03021 : super(conn._env),
03022 _ctx(conn._ctx),
03023 _state(UNINITIALIZED),
03024 _last_file(NULL),
03025 _last_line(-1),
03026 _res(NULL),
03027 _stmt_type(-1),
03028 _bulk_rows(bulk_rows),
03029 _result_buffers(0),
03030 _last_row((ub4)-1),
03031 _last_fetched_row((ub4)-1)
03032 {
03033 prepare(sql, file, line, lang);
03034 }
03035
03036 virtual ~SqlStatement();
03037
03038
03039 protected:
03040
03041 enum _NO_ALLOC_ {NO_HANDLE_ALLOC};
03042
03043 SqlStatement(OciConnection& conn, int bulk_rows, _NO_ALLOC_)
03044 : super(conn._env, NULL),
03045 _ctx(conn._ctx),
03046 _state(UNINITIALIZED),
03047 _last_file(NULL),
03048 _last_line(-1),
03049 _res(NULL),
03050 _stmt_type(-1),
03051 _bulk_rows(bulk_rows),
03052 _result_buffers(0),
03053 _last_row((ub4)-1),
03054 _last_fetched_row((ub4)-1)
03055 {
03056 }
03057
03058 OciContext& _ctx;
03059
03060 enum STATE {
03061 UNINITIALIZED=0,
03062 PREPARED=1, DEFINED=2, EXECUTED=4, FETCHED=8,
03063 EOF_DATA=16, STMT_ERROR=32
03064 };
03065 int _state;
03066
03067 tstring _last_sql;
03068 const char* _last_file;
03069 int _last_line;
03070
03071 struct SqlResult* _res;
03072
03073 mutable int _stmt_type;
03074
03075 int _bulk_rows;
03076 int _result_buffers;
03077
03078
03079 public:
03080
03081 bool eof() const {return _state >= EOF_DATA;}
03082
03083
03084
03085
03086 #ifndef FORCE_CODEPOS
03087 void prepare(const tstring& sql, ub4 lang=OCI_NTV_SYNTAX);
03088 #endif
03089
03090 virtual void prepare(const tstring& sql, const char* file, int line, ub4 lang=OCI_NTV_SYNTAX);
03091
03092
03093
03094
03095 int get_stmt_type() const;
03096
03097
03098 const tstring& get_last_sql() const
03099 {
03100 return _last_sql;
03101 }
03102
03103 const char* get_last_file() const
03104 {
03105 return _last_file;
03106 }
03107
03108 int get_last_line() const
03109 {
03110 return _last_line;
03111 }
03112
03113
03114
03115
03116 ub4 fetched_rows() const;
03117
03118
03119
03120
03121 ub4 row_count() const;
03122
03123
03124
03125
03126 int result_buffers() const
03127 {
03128 return _result_buffers;
03129 }
03130
03131
03132
03133
03134 OCIBind* bind_input(int idx, BindInput par, OCIBind* bindp=NULL)
03135 {
03136 sword res = OCIBindByPos(_handle, &bindp, _env._errh, idx+1,
03137 const_cast<void*>(par.valuep), par.value_sz, par.dty,
03138 const_cast<OCIInd*>(par.indp), 0, 0,
03139 0, 0, OCI_DEFAULT);
03140 oci_check_error(_env, res);
03141
03142 return bindp;
03143 }
03144
03145 OCIBind* bind_input(const tstring& name, BindInput par, OCIBind* bindp=NULL)
03146 {
03147 sword res = OCIBindByName(_handle, &bindp, _env._errh, (OraText*)name.c_str(), (sb4)name.length()*sizeof(TOraText),
03148 const_cast<void*>(par.valuep), par.value_sz, par.dty,
03149 const_cast<OCIInd*>(par.indp), 0, 0,
03150 0, 0, OCI_DEFAULT);
03151 oci_check_error(_env, res);
03152
03153 return bindp;
03154 }
03155
03156
03157
03158
03159 OCIBind* bind_output(int idx, BindOutput par, OCIBind* bindp=NULL)
03160 {
03161 sword res = OCIBindByPos(_handle, &bindp, _env._errh, idx+1,
03162 par.valuep, par.value_sz, par.dty,
03163 par.indp, 0, 0,
03164 0, 0, OCI_DEFAULT);
03165 oci_check_error(_env, res);
03166
03167 return bindp;
03168 }
03169
03170 OCIBind* bind_output(const tstring& name, BindOutput par, OCIBind* bindp=NULL)
03171 {
03172 sword res = OCIBindByName(_handle, &bindp, _env._errh, (OraText*)name.c_str(), (sb4)name.length()*sizeof(TOraText),
03173 par.valuep, par.value_sz, par.dty,
03174 par.indp, 0, 0,
03175 0, 0, OCI_DEFAULT);
03176 oci_check_error(_env, res);
03177
03178 return bindp;
03179 }
03180
03181 OCIBind* bind_inout(int idx, BindOutput par, OCIBind* bindp=NULL)
03182 {
03183 return bind_output(idx, par, bindp);
03184 }
03185
03186 OCIBind* bind_inout(const tstring& name, BindOutput par, OCIBind* bindp=NULL)
03187 {
03188 return bind_output(name, par, bindp);
03189 }
03190
03191
03192
03193
03194 OCIDefine* bind_result(int idx, DefinePar par, OCIDefine* defnp=NULL);
03195
03196
03197
03198
03199 void bind_result(struct SqlRecord& rec);
03200
03201
03202
03203
03204 void execute()
03205 {
03206 int rows = get_stmt_type()==OCI_STMT_SELECT? 0: 1;
03207
03208 execute(rows);
03209 }
03210
03211 void execute(ub4 rows, ub4 mode=OCI_DEFAULT);
03212
03213 #ifndef FORCE_CODEPOS
03214 void execute(const tstring& sql)
03215 {
03216 prepare(sql);
03217
03218 int rows = get_stmt_type()==OCI_STMT_SELECT? 0: 1;
03219
03220 execute(rows);
03221 }
03222 #endif
03223
03224 void execute(const tstring& sql, const char* file, int line)
03225 {
03226 prepare(sql, file, line);
03227
03228 int rows = get_stmt_type()==OCI_STMT_SELECT? 0: 1;
03229
03230 execute(rows);
03231 }
03232
03233 #ifndef FORCE_CODEPOS
03234 void execute(const tstring& sql, ub4 rows)
03235 {
03236 prepare(sql);
03237
03238 execute(rows);
03239 }
03240 #endif
03241
03242 void execute(const tstring& sql, const char* file, int line, ub4 rows)
03243 {
03244 prepare(sql, file, line);
03245
03246 execute(rows);
03247 }
03248
03249 void ensure_execute()
03250 {
03251 if (!(_state & EXECUTED))
03252 execute();
03253 }
03254
03255
03256
03257
03258 void execute_fetch(ub4 mode=OCI_DEFAULT);
03259
03260 #ifndef FORCE_CODEPOS
03261 void execute_fetch(const tstring& sql, ub4 lang=OCI_NTV_SYNTAX, ub4 mode=OCI_DEFAULT)
03262 {
03263 prepare(sql, lang);
03264
03265 execute_fetch(mode);
03266 }
03267 #endif
03268
03269 void execute_fetch(const tstring& sql, const char* file, int line, ub4 lang=OCI_NTV_SYNTAX, ub4 mode=OCI_DEFAULT)
03270 {
03271 prepare(sql, file, line, lang);
03272
03273 execute_fetch(mode);
03274 }
03275
03276
03277
03278 void fetch(ub4 rows=(ub4)-1);
03279
03280
03281
03282
03283 bool next()
03284 {
03285 if (!eof()) {
03286 fetch(1);
03287
03288 return fetched_rows() > 0;
03289 } else
03290 return false;
03291 }
03292
03293
03294
03295
03296 int first_bulk()
03297 {
03298 execute_fetch();
03299
03300 return fetched_rows();
03301 }
03302
03303 int next_bulk()
03304 {
03305 if (!eof()) {
03306 fetch();
03307
03308 return fetched_rows();
03309 } else
03310 return 0;
03311 }
03312
03313
03314 ub4 get_column_count() const
03315 {
03316 ub4 count;
03317 ub4 size = sizeof(count);
03318
03319 sword res = OCIAttrGet(_handle, super::get_type_id(), &count, &size, OCI_ATTR_PARAM_COUNT, _env._errh);
03320 oci_check_error(_env, res);
03321
03322 return count;
03323 }
03324
03325 void get_column_type(int idx, ColumnType& info) const;
03326
03327
03328 void print_results(tostream& out, bool header=true);
03329
03330 void print_results(const tstring& sql, tostream& out, bool header=true)
03331 {
03332 execute(sql, CODEPOS);
03333
03334 if (!eof())
03335 print_results(out, header);
03336 }
03337
03338
03339 const SqlResult& get_result()
03340 {
03341 if (!(_state & EXECUTED))
03342 execute();
03343
03344 return *_res;
03345 }
03346
03347
03348 #ifdef _XMLSTORAGE_H
03349 void dump_results(XMLStorage::XMLPos& pos, const XMLStorage::XS_String& element_name);
03350 void dump_results(XMLStorage::XMLWriter& writer, const XMLStorage::XS_String& element_name);
03351
03352 void dump_results(const tstring& sql, XMLStorage::XMLPos& pos, const XMLStorage::XS_String& element_name)
03353 {
03354 execute(sql, CODEPOS);
03355
03356 if (!eof())
03357 dump_results(pos, element_name);
03358 }
03359
03360 void dump_results(const tstring& sql, XMLStorage::XMLWriter& writer, const XMLStorage::XS_String& element_name)
03361 {
03362 execute(sql, CODEPOS);
03363
03364 if (!eof())
03365 dump_results(writer, element_name);
03366 }
03367 #endif
03368
03369
03370 SqlResult* operator->()
03371 {
03372 if (!_res)
03373 fetch();
03374
03375 return _res;
03376 }
03377
03378 protected:
03379 void execute_internal(ub4 rows, ub4 mode);
03380
03381 ub4 _last_row;
03382 ub4 _last_fetched_row;
03383 };
03384
03385
03386 #if ORACLE_VERSION>=90
03387
03388 struct SqlCacheStmt : public SqlStatement
03389 {
03390 typedef SqlStatement super;
03391
03392 SqlCacheStmt(OciConnection& conn, int bulk_rows=g_OCIPL_BULK_ROWS)
03393 : super(conn, bulk_rows, NO_HANDLE_ALLOC),
03394 _stmt_cache(conn._stmt_cache)
03395 {
03396 }
03397
03398 #ifndef FORCE_CODEPOS
03399 SqlCacheStmt(OciConnection& conn, const tstring& sql, ub4 lang=OCI_NTV_SYNTAX, int bulk_rows=g_OCIPL_BULK_ROWS)
03400 : super(conn, bulk_rows, NO_HANDLE_ALLOC),
03401 _stmt_cache(conn._stmt_cache)
03402 {
03403 prepare(sql, NULL, -1, lang);
03404 }
03405 #endif
03406
03407 SqlCacheStmt(OciConnection& conn, const tstring& sql, const char* file, int line, ub4 lang=OCI_NTV_SYNTAX, int bulk_rows=g_OCIPL_BULK_ROWS)
03408 : super(conn, bulk_rows, NO_HANDLE_ALLOC),
03409 _stmt_cache(conn._stmt_cache)
03410 {
03411 prepare(sql, file, line, lang);
03412 }
03413
03414 virtual ~SqlCacheStmt();
03415
03416 void prepare(const tstring& sql, ub4 lang=OCI_NTV_SYNTAX);
03417
03418 virtual void prepare(const tstring& sql, const char* file, int line, ub4 lang=OCI_NTV_SYNTAX);
03419
03420 void release();
03421
03422 protected:
03423 StatementCache& _stmt_cache;
03424 tstring _tag;
03425 };
03426
03427 #endif
03428
03429
03430
03431
03432 struct SqlVariantArray
03433 {
03434 SqlVariantArray()
03435 : _data_type(0)
03436 {
03437 _punion_ptr = NULL;
03438 }
03439
03440 SqlVariantArray(const ColumnTypeInfo& type, int size);
03441 SqlVariantArray(const SqlVariantArray& other);
03442 ~SqlVariantArray() {clear();}
03443
03444 void clear();
03445 void assign(const SqlVariantArray& other);
03446
03447 ub2 get_data_type() const
03448 {return _data_type;}
03449
03450 SqlVariantArray& operator=(const SqlVariantArray& other) {assign(other); return *this;}
03451
03452 tstring str(int row, OCIError* errh) const;
03453 SqlNumber number(int row, OCIError* errh) const;
03454 OciDate oci_date(int row, OCIError* errh) const;
03455 SqlDateTime sql_date(int row, OCIError* errh) const;
03456
03457 bool is_null(int row) const {return !is_not_null(row);}
03458 bool is_not_null(int row) const;
03459
03460 void bind_result(SqlStatement& stmt, int idx);
03461
03462 void set_string(int row, const TCHAR* str);
03463 void set_number(int row, const SqlNumber& num);
03464 void set_date(int row, const OciDate& date);
03465 void set_datetime(int row, const SqlDateTime& datetime);
03466 #ifdef SQLT_BFLOAT
03467 void set_float(int row, float f);
03468 void set_double(int row, double d);
03469 #endif
03470
03471 void bind_input(SqlStatement& stmt, int idx, int row);
03472
03473 protected:
03474 union {
03475 SqlStringArray* _pstring;
03476 SqlNumberArray* _pnumber;
03477 OciDateArray* _poci_date;
03478 SqlDateTimeArray*_psql_date;
03479
03480
03481 void* _punion_ptr;
03482 #ifdef SQLT_BFLOAT
03483 float* _pfloat;
03484 double* _pdouble;
03485 #endif
03486 };
03487
03488 int _size;
03489 ub2 _data_type;
03490 };
03491
03492
03493
03494
03495 struct SqlRecord
03496 {
03497 SqlRecord(SqlStatement& stmt, int rows);
03498 SqlRecord(OciEnv& env, size_t column_cnt) : _env(_env) {_values.resize(column_cnt);}
03499
03500 ~SqlRecord();
03501
03502 size_t get_column_count() const
03503 {return _values.size();}
03504
03505 SqlVariantArray& get_column(int idx)
03506 {return *_values[idx]._pvar;}
03507 ColumnType& get_column_type(int idx)
03508 {return _values[idx]._type;}
03509
03510 const SqlVariantArray& get_column(int idx) const
03511 {return *_values[idx]._pvar;}
03512 const ColumnType& get_column_type(int idx) const
03513 {return _values[idx]._type;}
03514
03515 const ColumnType& get_column_type(const tstring& col_name) const;
03516 const SqlVariantArray& get_column(const tstring& col_name) const;
03517
03518 void bind_result(SqlStatement& stmt);
03519
03520 void alloc_column(size_t col_idx, const ColumnTypeInfo& type, int rows);
03521
03522 void print_columns(tostream& out);
03523 void print_values(tostream& out, int row);
03524
03525 #ifdef _XMLSTORAGE_H
03526 void dump_values(XMLStorage::XMLPos& out, int row);
03527 void dump_values(XMLStorage::XMLWriter& writer, int row);
03528 #endif
03529
03530 protected:
03531
03532 struct Data {
03533 Data() : _pvar(NULL) {}
03534
03535 SqlVariantArray* _pvar;
03536 ColumnType _type;
03537 #ifdef _DEBUG
03538 tstring _col_name;
03539 #endif
03540 };
03541 typedef std::vector<Data> ColumnVector;
03542
03543 ColumnVector _values;
03544
03545 typedef std::map<tstring, int> NameMap;
03546 mutable NameMap _name_map;
03547
03548 NameMap::const_iterator find_column(const tstring& col_name) const;
03549
03550 public:
03551 OciEnv& _env;
03552 };
03553
03554
03555
03556
03557 struct SqlResult : public SqlRecord
03558 {
03559 SqlResult(SqlStatement& stmt, int rows=1)
03560 : SqlRecord(stmt, rows),
03561 _env(stmt._env)
03562 {
03563 bind_result(stmt);
03564 }
03565
03566 bool is_null(int idx, int row) const
03567 {
03568 return get_column(idx).is_null(row);
03569 }
03570 int is_null(const tstring& col_name, int row) const
03571 {
03572 return get_column(col_name).is_null(row);
03573 }
03574
03575 bool is_not_null(int idx, int row) const
03576 {
03577 return get_column(idx).is_not_null(row);
03578 }
03579 int is_not_null(const tstring& col_name, int row) const
03580 {
03581 return get_column(col_name).is_not_null(row);
03582 }
03583
03584 int get_int(int idx, int row) const
03585 {
03586 return get_column(idx).number(row, _env._errh).get_int(_env._errh);
03587 }
03588 int get_int(const tstring& col_name, int row) const
03589 {
03590 return get_column(col_name).number(row, _env._errh).get_int(_env._errh);
03591 }
03592
03593 #ifdef _MSC_VER
03594 LONGLONG get_int64(int idx, int row) const
03595 {
03596 return get_column(idx).number(row, _env._errh).get_int64(_env._errh);
03597 }
03598 LONGLONG get_int64(const tstring& col_name, int row) const
03599 {
03600 return get_column(col_name).number(row, _env._errh).get_int64(_env._errh);
03601 }
03602 #endif
03603
03604 double get_double(int idx, int row) const
03605 {
03606 return get_column(idx).number(row, _env._errh).get_double(_env._errh);
03607 }
03608 double get_double(const tstring& col_name, int row) const
03609 {
03610 return get_column(col_name).number(row, _env._errh).get_double(_env._errh);
03611 }
03612
03613 SqlNumber get_number(int idx, int row) const
03614 {
03615 return get_column(idx).number(row, _env._errh);
03616 }
03617 SqlNumber get_number(const tstring& col_name, int row) const
03618 {
03619 return get_column(col_name).number(row, _env._errh);
03620 }
03621
03622 tstring get_string(int idx, int row) const
03623 {
03624 return get_column(idx).str(row, _env._errh);
03625 }
03626 tstring get_string(const tstring& col_name, int row) const
03627 {
03628 return get_column(col_name).str(row, _env._errh);
03629 }
03630
03631 OciDate get_oci_date(int idx, int row) const
03632 {
03633 return get_column(idx).oci_date(row, _env._errh);
03634 }
03635 OciDate get_oci_date(const tstring& col_name, int row) const
03636 {
03637 return get_column(col_name).oci_date(row, _env._errh);
03638 }
03639
03640 SqlDateTime get_sql_date(int idx, int row) const
03641 {
03642 return get_column(idx).sql_date(row, _env._errh);
03643 }
03644 SqlDateTime get_sql_date(const tstring& col_name, int row) const
03645 {
03646 return get_column(col_name).sql_date(row, _env._errh);
03647 }
03648
03649 OciEnv& _env;
03650 };
03651
03652
03653
03654
03655 struct ResultIterator
03656 {
03657 typedef ResultIterator myType;
03658
03659 ResultIterator(SqlStatement& stmt)
03660 : _stmt(stmt),
03661 _row_idx(0),
03662 _row_nr(1)
03663 {
03664 _fetched = stmt.first_bulk();
03665 }
03666
03667 int get_row_idx() const
03668 {
03669 return _row_idx;
03670 }
03671
03672 operator int() const
03673 {
03674 return _row_idx;
03675 }
03676
03677 int get_row_nr() const
03678 {
03679 return _row_nr;
03680 }
03681
03682 bool has_next()
03683 {
03684 return _row_idx < _fetched;
03685 }
03686
03687 myType& operator++()
03688 {
03689 if (++_row_idx >= _fetched) {
03690 _fetched = _stmt.next_bulk();
03691
03692 if (_fetched) {
03693 _row_idx = 0;
03694 ++_row_nr;
03695 }
03696 } else
03697 ++_row_nr;
03698
03699 return *this;
03700 }
03701
03702 bool is_null(int idx) const
03703 {
03704 return _stmt->is_null(idx, _row_idx);
03705 }
03706 int is_null(const tstring& col_name) const
03707 {
03708 return _stmt->is_null(col_name, _row_idx);
03709 }
03710
03711 bool is_not_null(int idx) const
03712 {
03713 return _stmt->is_not_null(idx, _row_idx);
03714 }
03715 int is_not_null(const tstring& col_name) const
03716 {
03717 return _stmt->is_not_null(col_name, _row_idx);
03718 }
03719
03720 int get_int(int idx) const
03721 {
03722 return _stmt->get_int(idx, _row_idx);
03723 }
03724 int get_int(const tstring& col_name) const
03725 {
03726 return _stmt->get_int(col_name, _row_idx);
03727 }
03728
03729 #ifdef _MSC_VER
03730 LONGLONG get_int64(int idx) const
03731 {
03732 return _stmt->get_int64(idx, _row_idx);
03733 }
03734 LONGLONG get_int64(const tstring& col_name) const
03735 {
03736 return _stmt->get_int64(col_name, _row_idx);
03737 }
03738 #endif
03739
03740 double get_double(int idx) const
03741 {
03742 return _stmt->get_double(idx, _row_idx);
03743 }
03744 double get_double(const tstring& col_name) const
03745 {
03746 return _stmt->get_double(col_name, _row_idx);
03747 }
03748
03749 SqlNumber get_number(int idx) const
03750 {
03751 return _stmt->get_number(idx, _row_idx);
03752 }
03753 SqlNumber get_number(const tstring& col_name) const
03754 {
03755 return _stmt->get_number(col_name, _row_idx);
03756 }
03757
03758 tstring get_string(int idx) const
03759 {
03760 return _stmt->get_string(idx, _row_idx);
03761 }
03762 tstring get_string(const tstring& col_name) const
03763 {
03764 return _stmt->get_string(col_name, _row_idx);
03765 }
03766
03767 OciDate get_oci_date(int idx) const
03768 {
03769 return _stmt->get_oci_date(idx, _row_idx);
03770 }
03771 OciDate get_oci_date(const tstring& col_name) const
03772 {
03773 return _stmt->get_oci_date(col_name, _row_idx);
03774 }
03775
03776 SqlDateTime get_sql_date(int idx) const
03777 {
03778 return _stmt->get_sql_date(idx, _row_idx);
03779 }
03780 SqlDateTime get_sql_date(const tstring& col_name) const
03781 {
03782 return _stmt->get_sql_date(col_name, _row_idx);
03783 }
03784
03785 protected:
03786 SqlStatement& _stmt;
03787
03788 int _fetched;
03789 int _row_idx;
03790 int _row_nr;
03791 };
03792
03793
03794 inline void SqlStatement::bind_result(SqlRecord& rec)
03795 {rec.bind_result(*this);}
03796
03797
03798 #if ORACLE_VERSION>=81
03799
03800 struct BlobWriterBuffer : public tstringbuf
03801 {
03802 typedef tstringbuf super;
03803 typedef OciBlob LOB;
03804
03805 BlobWriterBuffer(LOB& lob)
03806 : _lob(lob)
03807 {
03808 _offset = 1;
03809 }
03810
03811 virtual ~BlobWriterBuffer()
03812 {
03813 sync();
03814 }
03815
03816 virtual int sync()
03817 {
03818 const tstring& s = str();
03819 size_t l = s.length();
03820
03821 if (l > 0) {
03822 #if ORACLE_VERSION>=90
03823 _lob.write_append((const void*)s.c_str(), (sb4)l*sizeof(TOraText), (sb4)l);
03824 #else
03825 _lob.write((const void*)s.c_str(), (ub4)l, (ub4)_offset, (ub4)l);
03826 #endif
03827
03828 _offset += l;
03829 }
03830
03831 str(tstring());
03832
03833 return 0;
03834 }
03835
03836 protected:
03837 LOB& _lob;
03838 size_t _offset;
03839 };
03840
03841 struct ClobWriterBuffer : public tstringbuf
03842 {
03843 typedef tstringbuf super;
03844 typedef OciClob LOB;
03845
03846 ClobWriterBuffer(LOB& lob, ub2 csid=0, ub1 csfrm=SQLCS_IMPLICIT)
03847 : _lob(lob),
03848 _csid(csid),
03849 _csfrm(csfrm)
03850 {
03851 }
03852
03853 virtual ~ClobWriterBuffer()
03854 {
03855 sync();
03856 }
03857
03858 virtual int sync()
03859 {
03860 const tstring& s = str();
03861 size_t l = s.length();
03862
03863 if (l > 0)
03864 _lob.write_append((const void*)s.c_str(), (ub4)l*sizeof(TOraText), (ub4)l, _csid, _csfrm);
03865
03866 str(tstring());
03867
03868 return 0;
03869 }
03870
03871 protected:
03872 LOB& _lob;
03873 ub2 _csid;
03874 ub1 _csfrm;
03875 };
03876
03877 template<typename BUFFER>
03878 struct LobWriter : public tostream
03879 {
03880 typedef tostream super;
03881
03882 LobWriter(typename BUFFER::LOB& lob)
03883 : super(&_buffer),
03884 _buffer(lob)
03885 {
03886 }
03887
03888 LobWriter(typename BUFFER::LOB& lob, ub2 csid, ub1 csfrm=SQLCS_IMPLICIT)
03889 : super(&_buffer),
03890 _buffer(lob, csid, csfrm)
03891 {
03892 }
03893
03894 void sync()
03895 {
03896 _buffer.sync();
03897 }
03898
03899 protected:
03900 BUFFER _buffer;
03901 };
03902
03903 typedef LobWriter<BlobWriterBuffer> BlobWriter;
03904 typedef LobWriter<ClobWriterBuffer> ClobWriter;
03905
03906
03907 struct BlobReaderBuffer : public tstringbuf
03908 {
03909 typedef tstringbuf super;
03910 typedef OciBlob LOB;
03911
03912 BlobReaderBuffer(LOB& lob, ub4 offset=1)
03913 : _lob(lob),
03914 _offset(offset)
03915 {
03916 _bsize = lob.get_chunk_size();
03917 _buffer = (TCHAR*) ocipl_alloc(_bsize*sizeof(TCHAR));
03918 }
03919
03920 ~BlobReaderBuffer()
03921 {
03922 ocipl_free(_buffer);
03923 }
03924
03925 virtual int_type underflow()
03926 {
03927 ub4 amount = _lob.read(_buffer, _bsize, _offset, _bsize);
03928 if (amount <= 0)
03929 return -1;
03930
03931 setg(_buffer, _buffer, _buffer+amount);
03932 _offset += amount;
03933
03934 return *_buffer;
03935 }
03936
03937 protected:
03938 LOB& _lob;
03939 ub4 _offset;
03940 TCHAR* _buffer;
03941 int _bsize;
03942 };
03943
03944 struct ClobReaderBuffer : public tstringbuf
03945 {
03946 typedef tstringbuf super;
03947 typedef OciClob LOB;
03948
03949 ClobReaderBuffer(LOB& lob, ub4 offset=1, ub2 csid=0, ub1 csfrm=SQLCS_IMPLICIT)
03950 : _lob(lob),
03951 _offset(offset),
03952 _csid(csid),
03953 _csfrm(csfrm)
03954 {
03955 _bsize = lob.get_chunk_size();
03956 _buffer = (TCHAR*) ocipl_alloc(_bsize*sizeof(TCHAR));
03957 }
03958
03959 ~ClobReaderBuffer()
03960 {
03961 ocipl_free(_buffer);
03962 }
03963
03964 virtual int_type underflow()
03965 {
03966 ub4 amount = _lob.read(_buffer, _bsize, _offset, _bsize, _csid, _csfrm);
03967 if (amount <= 0)
03968 return -1;
03969
03970 setg(_buffer, _buffer, _buffer+amount);
03971 _offset += amount;
03972
03973 return *_buffer;
03974 }
03975
03976 protected:
03977 LOB& _lob;
03978 ub4 _offset;
03979 TCHAR* _buffer;
03980 int _bsize;
03981 ub2 _csid;
03982 ub1 _csfrm;
03983 };
03984
03985 template<typename BUFFER>
03986 struct LobReader : public tistream
03987 {
03988 typedef tistream super;
03989
03990 LobReader(typename BUFFER::LOB& lob)
03991 : super(&_buffer),
03992 _buffer(lob)
03993 {
03994 }
03995
03996 LobReader(typename BUFFER::LOB& lob, ub2 csid, ub1 csfrm=SQLCS_IMPLICIT)
03997 : super(&_buffer),
03998 _buffer(lob, csid, csfrm)
03999 {
04000 }
04001
04002 protected:
04003 BUFFER _buffer;
04004 };
04005
04006 typedef LobReader<BlobReaderBuffer> BlobReader;
04007 typedef LobReader<ClobReaderBuffer> ClobReader;
04008
04009 #endif
04010
04011
04012
04013 extern const TCHAR* get_oci_ptype_str(ub1 type);
04014
04015 }
04016
04017 #define _OCIPL_H
04018 #endif // _OCIPL_H