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