// ================================================================================= // ORACLE, ODBC and DB2/CLI Template Library, Version 4.0.476, // Copyright (C) 1996-2023, Sergei Kuchin (skuchin@gmail.com) // // This library is free software. Permission to use, copy, modify, // and/or distribute this software for any purpose with or without fee // is hereby granted, provided that the above copyright notice and // this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // // a.k.a. as Open BSD license // (http://www.openbsd.org/cgi-bin/cvsweb/~checkout~/src/share/misc/license.template // ================================================================================= #ifndef OTL_H #define OTL_H #if defined(OTL_INCLUDE_0) #include "otl_include_0.h" #endif #define OTL_VERSION_NUMBER (0x0401DCL) #if defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS) #define OTL_STD_STRING_VIEW_CLASS OTL_THIRD_PARTY_STRING_VIEW_CLASS #endif #if defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS) #define OTL_STD_UNICODE_STRING_VIEW_CLASS OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS #endif #if defined(OTL_CPP_14_ON) #define OTL_CPP_11_ON #endif #if defined(OTL_CPP_17_ON) #define OTL_CPP_11_ON #define OTL_CPP_14_ON #endif #if defined(OTL_CPP_20_ON) #define OTL_CPP_11_ON #define OTL_CPP_14_ON #define OTL_CPP_17_ON #endif #if defined(_MSC_VER) && (_MSC_VER==1700) #define OTL_CPP_11_ON #endif #if defined(_MSC_VER) && (_MSC_VER==1800) #define OTL_CPP_11_ON #endif #if defined(_MSC_VER) && (_MSC_VER==1900) && !defined(_MSVC_LANG) // VC++ 2015 before update 3 #if !defined(OTL_CPP_11_ON) #define OTL_CPP_11_ON #endif #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__<=407) && (__GNUC__*100+__GNUC_MINOR__>=404) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=701) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wimplicit-fallthrough" #endif #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wimplicit-fallthrough" #endif #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 800) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wextra-semi-stmt" #endif // auto-detection of "std" compiler switches #if defined(_MSC_VER) // >= VC++ 2015 Update 3, and /std:c++14 #if defined(_MSVC_LANG) && (_MSVC_LANG==201402L) #if !defined(OTL_CPP_11_ON) #define OTL_CPP_11_ON #endif #if !defined(OTL_CPP_14_ON) #define OTL_CPP_14_ON #endif #endif // >= VC++ 2015 Update 3, and /std:c++latest #if defined(_MSVC_LANG) && (_MSVC_LANG>201402L) #if !defined(OTL_CPP_11_ON) #define OTL_CPP_11_ON #endif #if !defined(OTL_CPP_14_ON) #define OTL_CPP_14_ON #endif #if !defined(OTL_CPP_17_ON) && defined(_MSC_VER) && (_MSC_VER>=1910) #define OTL_CPP_17_ON #endif #if defined(_MSC_VER) && (_MSC_VER>=1910) #define OTL_COMPILER_HAS_STD_OPTIONAL #endif #endif #endif #if defined(__clang__) || defined(__GNUC__) // clang or g++ #if defined(__cplusplus) && (__cplusplus==201103L) // std=c++11 is used #if !defined(OTL_CPP_11_ON) #define OTL_CPP_11_ON #endif #elif defined(__cplusplus) && (__cplusplus==201402L) // std=c++14 is used #if !defined(OTL_CPP_11_ON) #define OTL_CPP_11_ON #endif #if !defined(OTL_CPP_14_ON) #define OTL_CPP_14_ON #endif #elif defined(__cplusplus) && (__cplusplus>201402L) // std=c++17 / std=c++1z is used #if !defined(OTL_CPP_11_ON) #define OTL_CPP_11_ON #endif #if !defined(OTL_CPP_14_ON) #define OTL_CPP_14_ON #endif #if !defined(OTL_CPP_17_ON) #define OTL_CPP_17_ON #endif #endif #endif #if defined(OTL_CPP_11_ON) && defined(OTL_FUNC_THROW_SPEC_ON) #error OTL_CPP_11_ON and OTL_FUNC_THROW_SPEC_ON cannot be used together #endif #if defined(_MSC_VER) && (_MSC_VER >= 1600) #pragma warning(disable : 28251) #endif #if defined(_MSC_VER) && (_MSC_VER >= 1900) #pragma warning(disable : 6385) #pragma warning(disable : 6386) #endif // enable C++ standard features #if defined(OTL_CPP_11_ON) #if !defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) #define OTL_ANSI_CPP_11_RVAL_REF_SUPPORT #endif #if !defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) #define OTL_ANSI_CPP_11_NULLPTR_SUPPORT #endif #if !(defined(_MSC_VER) && (_MSC_VER<1800)) #if !defined(OTL_ANSI_CPP_11_VARIADIC_TEMPLATES) #define OTL_ANSI_CPP_11_VARIADIC_TEMPLATES #endif #if !defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED) #define OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED #endif #if !defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) #define OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT #endif #endif #if !defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) #define OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT #endif #endif #if defined(OTL_CPP_14_ON) #if !defined(OTL_MAKE_UNIQUE_IS_SUPPORTED) #define OTL_MAKE_UNIQUE_IS_SUPPORTED #endif #endif #define OTL_ANSI_CPP_11_NOEXCEPT #if !defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) && !defined(__cplusplus_cli) // define nullptr as 0 only if C++/CLI is not used #define nullptr 0 #endif #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) #if defined(_MSC_VER) && (_MSC_VER>=1700) && (_MSC_VER<=1800) #undef OTL_ANSI_CPP_11_NOEXCEPT #define OTL_ANSI_CPP_11_NOEXCEPT _NOEXCEPT #elif defined(_MSC_VER) && (_MSC_VER==1600) #undef OTL_ANSI_CPP_11_NOEXCEPT #define OTL_ANSI_CPP_11_NOEXCEPT #else #undef OTL_ANSI_CPP_11_NOEXCEPT #define OTL_ANSI_CPP_11_NOEXCEPT noexcept(true) #define OTL_ANSI_CPP_11_NOEXCEPT_FALSE noexcept(false) #endif #endif #if defined(OTL_CPP_17_ON) && \ (defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=700) || \ defined(_MSVC_LANG) && (_MSVC_LANG>=201703L) && defined(_MSC_VER) && (_MSC_VER>=1913) || \ defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 600)) // using c++17 binary left fold expressions: g++ 7.0 or higher, // VC++2017 update 6 or higher, clang++ 6.0 or higher #define OTL_ANSI_CPP_17_FOLD_EXPRESSIONS #define OTL_ANSI_CPP_17_CONSTEXPR_IF #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__==404) && \ defined(__GXX_EXPERIMENTAL_CXX0X__) // automatically enable some C++0X features for GNU C++ 4.4 when it's // used with -std=c++0x #if !defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) #define OTL_ANSI_CPP_11_RVAL_REF_SUPPORT #endif #if !defined(OTL_ANSI_CPP_11_VARIADIC_TEMPLATES) #define OTL_ANSI_CPP_11_VARIADIC_TEMPLATES #endif #if !defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED) #define OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED #endif #if !defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED) #define OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED #endif #if !defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) #define OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED #endif #endif #if defined(OTL_CPP_14_ON) // atomically enable support for std::tuples and std::arrays under // OTL_CPP_14_ON #if !defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED) #define OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED #endif #if !defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) #define OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED #endif #endif #if defined(OTL_STREAM_WITH_STD_TUPLE_ON) && defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED) #include #include template struct otl_tuple_helper{ static void write(streamType& s, const Tuple& t){ otl_tuple_helper::write(s,t); s<(t); } static void read(streamType& s, Tuple& t){ otl_tuple_helper::read(s,t); s>>std::get(t); } }; template struct otl_tuple_helper{ static void write(streamType& s, const Tuple& t) { s<(t); } static void read(streamType& s, Tuple& t) { s>>std::get<0>(t); } }; #endif // C++11/14/17 attributes #if defined(OTL_CPP_11_ON) #if defined(_MSC_VER) && (_MSC_VER>=1900) #define OTL_NORETURN [[noreturn]] #elif defined(_MSC_VER) && (_MSC_VER<1900) #define OTL_NORETURN #else #define OTL_NORETURN [[noreturn]] #endif #else #define OTL_NORETURN #endif #if defined(OTL_CPP_14_ON) #define OTL_DEPRECATED [[deprecated]] #define OTL_DEPRECATED_WITH_ARG(x) [[deprecated(x)]] #else #define OTL_DEPRECATED #define OTL_DEPRECATED_WITH_ARG(x) #endif #if defined(OTL_CPP_17_ON) #define OTL_NODISCARD [[nodiscard]] #define OTL_FALLTHROUGH [[fallthrough]]; #define OTL_MAYBE_UNUSED [[maybe_unused]] #else #define OTL_NODISCARD #define OTL_FALLTHROUGH #define OTL_MAYBE_UNUSED #endif #if defined(_MSC_VER) && (_MSC_VER >= 1400) #pragma warning(disable : 4351) #pragma warning(disable : 4290) #define OTL_STRCAT_S(dest, dest_sz, src) strcat_s(dest, dest_sz, src) #define OTL_STRCPY_S(dest, dest_sz, src) strcpy_s(dest, dest_sz, src) #define OTL_STRNCPY_S(dest, dest_sz, src, count) strncpy_s(dest, dest_sz, src, count) #define OTL_SPRINTF_S sprintf_s #else #ifndef OTL_STRCAT_S #define OTL_STRCAT_S(dest, dest_sz, src) (strncat(dest, src, static_cast(dest_sz-1))) #endif // OTL_STRCAT_S #ifndef OTL_STRCPY_S #define OTL_STRCPY_S(dest, dest_sz, src) (strncpy(dest, src, static_cast(dest_sz-1)),dest[static_cast(dest_sz-1)]=0) #endif // OTL_STRCPY_S #ifndef OTL_STRNCPY_S #define OTL_STRNCPY_S(dest, dest_sz, src, count) \ ((void)(dest_sz),strncpy(dest, src, count),dest[static_cast(count)]=0) #endif // OTL_STRNCPY_S #ifndef OTL_SPRINTF_S #include #include #if defined(__GNUC__) #define OTL_SPRINTF_S_ATTRIBUTE __attribute__ ((format (printf, 3, 4))) #elif defined(__clang__) #define OTL_SPRINTF_S_ATTRIBUTE __attribute__ ((__format__ (__printf__, 3, 4))) #else #define OTL_SPRINTF_S_ATTRIBUTE #endif int otl_sprintf_s(char* dest, size_t dest_sz, const char* fmt, ...) OTL_SPRINTF_S_ATTRIBUTE; inline int otl_sprintf_s(char* dest, size_t dest_sz, const char* fmt, ...){ va_list vl; va_start(vl, fmt); int res = vsnprintf(dest, dest_sz, fmt, vl); va_end(vl); return res; } #define OTL_SPRINTF_S otl_sprintf_s #endif // OTL_SPRINTF_S #endif #include #include #include #include //======================= CONFIGURATION #DEFINEs =========================== // Uncomment the following line in order to include the OTL for ODBC: //#define OTL_ODBC // Uncomment the following line in order to include the OTL for // MySQL/MyODBC for MyODBC 2.5 (pretty old). Otherwise, use OTL_ODBC //#define OTL_ODBC_MYSQL // Uncomment the following line in order to include the OTL for DB2 CLI: //#define OTL_DB2_CLI // Uncomment the following line in order to include the OTL for // Oracle 8: //#define OTL_ORA8 // Uncomment the following line in order to include the OTL for // Oracle 8i: //#define OTL_ORA8I // Uncomment the following line in order to include the OTL for // Oracle 9i: //#define OTL_ORA9I // Uncomment the following line in order to include the OTL for // Oracle 10g Release 1: //#define OTL_ORA10G // Uncomment the following line in order to include the OTL for // Oracle 10g Release 2: //#define OTL_ORA10G_R2 // Uncomment the following line in order to include the OTL for // Oracle 11g Release 1 //#define OTL_ORA11G // The macro definitions may be also turned on via C++ compiler command line // option, e.g.: -DOTL_ODBC, DOTL_ORA8, -DOTL_ORA8I, // -DOTL_ODBC_UNIX // -DOTL_ODBC_MYSQL, -DOTL_DB2_CLI // this #define is always defined #if !defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) #define OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON #endif #if !defined(OTL_STLPORT) #include #include #define OTL_SETFILL std::setfill('0') #define OTL_SETW(s) std::setw(s.frac_precision) #else #endif #if !defined(OTL_TRACE_LEVEL) #define OTL_TRACE_FORMAT_TZ_DATETIME(s) #define OTL_TRACE_FORMAT_DATETIME(s) #else #if !defined(OTL_TRACE_FORMAT_DATETIME) #if !defined(OTL_LEGACY_TRACE_DATETIME_FORMAT_ON) #define OTL_TRACE_FORMAT_TZ_DATETIME(s) \ s.month << "/" << s.day << "/" << s.year << " " << s.hour << ":" << s.minute \ << ":" << s.second << "." \ << OTL_SETFILL \ << OTL_SETW(s) \ << s.fraction << " " << s.tz_hour << ":" \ << s.tz_minute #define OTL_TRACE_FORMAT_DATETIME(s) \ s.month << "/" << s.day << "/" << s.year << " " << s.hour << ":" << s.minute \ << ":" << s.second << "." \ << OTL_SETFILL \ << OTL_SETW(s) \ << s.fraction #else #define OTL_TRACE_FORMAT_TZ_DATETIME(s) \ s.month << "/" << s.day << "/" << s.year << " " << s.hour << ":" << s.minute \ << ":" << s.second << "." \ << s.fraction << " " << s.tz_hour << ":" \ << s.tz_minute #define OTL_TRACE_FORMAT_DATETIME(s) \ s.month << "/" << s.day << "/" << s.year << " " << s.hour << ":" << s.minute \ << ":" << s.second << "." \ << s.fraction #endif #endif #endif #if !defined(OTL_THROW) #define OTL_THROW(x) throw x #endif #if defined(_MSC_VER) && (_MSC_VER >= 1900) && defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) // vc++ 14 or higher #define OTL_THROWS_OTL_EXCEPTION noexcept(false) #define OTL_THROWS_OTL_EXCEPTION2 noexcept(false) #define OTL_THROWS_OTL_EXCEPTION3 noexcept(false) #define OTL_THROWS_OTL_EXCEPTION4 noexcept(false) #define OTL_NO_THROW noexcept(true) #endif #if defined(OTL_ORA11G) #if !defined(OTL_ORA10G_R2) #define OTL_ORA10G_R2 #endif #if defined(OTL_UNICODE) #define OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES #endif #endif #if defined(OTL_ORA19C) #if !defined(OTL_ORA18C) #define OTL_ORA18C #endif #endif #if defined(OTL_ORA18C) #if !defined(OTL_ORA12C_R2) #define OTL_ORA12C_R2 #endif #endif #if defined(OTL_ORA12C_R2) #if !defined(OTL_ORA12C) #define OTL_ORA12C #endif #endif #if defined(OTL_ORA12C) #if !defined(OTL_ORA11G_R2) #define OTL_ORA11G_R2 #endif #if defined(OTL_UNICODE) #if !defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES) #define OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES #endif #endif #endif #if defined(OTL_ORA11G_R2) #if !defined(OTL_ORA10G_R2) #define OTL_ORA10G_R2 #endif #if defined(OTL_UNICODE) && !defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES) #define OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES #endif #endif #if defined(OTL_STREAM_LEGACY_BUFFER_SIZE_TYPE) typedef short int otl_stream_buffer_size_type; #else typedef int otl_stream_buffer_size_type; #endif #if defined(OTL_ODBC_MULTI_MODE) #define OTL_ODBC #define OTL_ODBC_SQL_EXTENDED_FETCH_ON #endif #if defined(OTL_ODBC_MSSQL_2005) #define OTL_ODBC #endif #if defined(OTL_ODBC_MSSQL_2008) #define OTL_ODBC #define OTL_ODBC_MSSQL_2005 #endif #if defined(OTL_IODBC_BSD) #define OTL_ODBC #define OTL_ODBC_UNIX #endif #if defined(OTL_ODBC_TIMESTEN_WIN) #define OTL_ODBC_TIMESTEN #define OTL_ODBC #define OTL_ODBC_SQL_EXTENDED_FETCH_ON #define ODBCVER 0x0250 #include #endif #if defined(OTL_ODBC_TIMESTEN_UNIX) #define OTL_ODBC_TIMESTEN #define OTL_ODBC #define OTL_ODBC_UNIX #define OTL_ODBC_SQL_EXTENDED_FETCH_ON #include #endif #if defined(OTL_ODBC_ENTERPRISEDB) #define OTL_ODBC_POSTGRESQL #endif #if defined(OTL_ODBC_POSTGRESQL) #define OTL_ODBC #endif // Comment out this #define when using pre-ANSI C++ compiler #if !defined(OTL_ODBC_zOS) && !defined(OTL_ANSI_CPP) #define OTL_ANSI_CPP #endif #if defined(OTL_ODBC_zOS) #define OTL_ODBC_UNIX #define OTL_ODBC_SQL_EXTENDED_FETCH_ON #endif #if defined(OTL_ORA8I) #define OTL_ORA8 #define OTL_ORA8_8I_REFCUR #define OTL_ORA8_8I_DESC_COLUMN_SCALE #endif #if defined(OTL_ORA10G) || defined(OTL_ORA10G_R2) #define OTL_ORA9I #define OTL_ORA_NATIVE_TYPES #if defined(OTL_UNICODE) #define OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES #endif #endif #if defined(OTL_ORA9I) #define OTL_ORA8 #define OTL_ORA8_8I_REFCUR #define OTL_ORA8_8I_DESC_COLUMN_SCALE #endif #if defined(OTL_ODBC_MYSQL) #define OTL_ODBC #endif #if defined(OTL_ODBC_XTG_IBASE6) #define OTL_ODBC #endif #define OTL_VALUE_TEMPLATE //#define OTL_ODBC_SQL_EXTENDED_FETCH_ON #if defined(OTL_ODBC_UNIX) && !defined(OTL_ODBC) #define OTL_ODBC #endif #if !defined(OTL_ORA11G_R2) && defined(OTL_ORA8) && defined(OTL_UBIGINT) #error OTL_UBIGINT is only supported for OTL_ORA11G_R2 or higher #endif #if defined(OTL_UBIGINT) && defined(OTL_BIGINT_TO_STR) && \ defined(OTL_STR_TO_BIGINT) #error OTL_UBIGINT is not supported when OTL_BIGINT_TO_STR / \ OTL_STR_TO_BIGINT are defined #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \ !defined(OTL_NUMERIC_TYPE_1) && !defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ !defined(OTL_NUMERIC_TYPE_1_TO_STR) && !defined(OTL_NUMERIC_TYPE_1_ID) #error OTL_NUMERIC_TYPE_2 macros should be used after OTL_NUMERIC_TYPE_1 macros \ are already defined #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \ ((!defined(OTL_NUMERIC_TYPE_1) && !defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ !defined(OTL_NUMERIC_TYPE_1_TO_STR) && \ !defined(OTL_NUMERIC_TYPE_1_ID)) || \ (!defined(OTL_NUMERIC_TYPE_2) && !defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ !defined(OTL_NUMERIC_TYPE_2_TO_STR) && !defined(OTL_NUMERIC_TYPE_2_ID))) #error OTL_NUMERIC_TYPE_3 macros should be used after OTL_NUMERIC_TYPE_1 and \ OTL_NUMERIC_TYPE_2 macros are already defined #endif #if defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON) #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) #define OTL_CHECK_BIND_VARS \ if (strcmp(type_arr, "INT") == 0 || strcmp(type_arr, "UNSIGNED") == 0 || \ strcmp(type_arr, "SHORT") == 0 || strcmp(type_arr, "LONG") == 0 || \ strcmp(type_arr, "FLOAT") == 0 || strcmp(type_arr, "DOUBLE") == 0 || \ strcmp(type_arr, "BFLOAT") == 0 || strcmp(type_arr, "BDOUBLE") == 0 || \ strcmp(type_arr, "TIMESTAMP") == 0 || \ strcmp(type_arr, "TZ_TIMESTAMP") == 0 || \ strcmp(type_arr, "LTZ_TIMESTAMP") == 0 || \ strcmp(type_arr, "BIGINT") == 0 || strcmp(type_arr, "UBIGINT") == 0 || \ strcmp(type_arr, "CHAR") == 0 || strcmp(type_arr, "CHARZ") == 0 || \ strcmp(type_arr, "DB2DATE") == 0 || strcmp(type_arr, "DB2TIME") == 0 || \ strcmp(type_arr, "VARCHAR_LONG") == 0 || \ strcmp(type_arr, "RAW_LONG") == 0 || strcmp(type_arr, "RAW") == 0 || \ strcmp(type_arr, "CLOB") == 0 || strcmp(type_arr, "BLOB") == 0 || \ strcmp(type_arr, "NCHAR") == 0 || strcmp(type_arr, "NCLOB") == 0 || \ strcmp(type_arr, "REFCUR") == 0 || \ strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0 || \ strcmp(type_arr, OTL_NUMERIC_TYPE_2_ID) == 0 || \ strcmp(type_arr, OTL_NUMERIC_TYPE_3_ID) == 0) \ ; \ else \ return 0; #else #define OTL_CHECK_BIND_VARS \ if (strcmp(type_arr, "INT") == 0 || strcmp(type_arr, "UNSIGNED") == 0 || \ strcmp(type_arr, "SHORT") == 0 || strcmp(type_arr, "LONG") == 0 || \ strcmp(type_arr, "FLOAT") == 0 || strcmp(type_arr, "DOUBLE") == 0 || \ strcmp(type_arr, "BFLOAT") == 0 || strcmp(type_arr, "BDOUBLE") == 0 || \ strcmp(type_arr, "TIMESTAMP") == 0 || \ strcmp(type_arr, "TZ_TIMESTAMP") == 0 || \ strcmp(type_arr, "LTZ_TIMESTAMP") == 0 || \ strcmp(type_arr, "BIGINT") == 0 || strcmp(type_arr, "UBIGINT") == 0 || \ strcmp(type_arr, "CHAR") == 0 || strcmp(type_arr, "CHARZ") == 0 || \ strcmp(type_arr, "DB2DATE") == 0 || strcmp(type_arr, "DB2TIME") == 0 || \ strcmp(type_arr, "VARCHAR_LONG") == 0 || \ strcmp(type_arr, "RAW_LONG") == 0 || strcmp(type_arr, "RAW") == 0 || \ strcmp(type_arr, "CLOB") == 0 || strcmp(type_arr, "BLOB") == 0 || \ strcmp(type_arr, "NCHAR") == 0 || strcmp(type_arr, "NCLOB") == 0 || \ strcmp(type_arr, "REFCUR") == 0 || \ strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0 || \ strcmp(type_arr, OTL_NUMERIC_TYPE_2_ID) == 0) \ ; \ else \ return 0; #endif #else #define OTL_CHECK_BIND_VARS \ if (strcmp(type_arr, "INT") == 0 || strcmp(type_arr, "UNSIGNED") == 0 || \ strcmp(type_arr, "SHORT") == 0 || strcmp(type_arr, "LONG") == 0 || \ strcmp(type_arr, "FLOAT") == 0 || strcmp(type_arr, "DOUBLE") == 0 || \ strcmp(type_arr, "BFLOAT") == 0 || strcmp(type_arr, "BDOUBLE") == 0 || \ strcmp(type_arr, "TIMESTAMP") == 0 || \ strcmp(type_arr, "TZ_TIMESTAMP") == 0 || \ strcmp(type_arr, "LTZ_TIMESTAMP") == 0 || \ strcmp(type_arr, "BIGINT") == 0 || strcmp(type_arr, "UBIGINT") == 0 || \ strcmp(type_arr, "CHAR") == 0 || strcmp(type_arr, "CHARZ") == 0 || \ strcmp(type_arr, "DB2DATE") == 0 || strcmp(type_arr, "DB2TIME") == 0 || \ strcmp(type_arr, "VARCHAR_LONG") == 0 || \ strcmp(type_arr, "RAW_LONG") == 0 || strcmp(type_arr, "RAW") == 0 || \ strcmp(type_arr, "CLOB") == 0 || strcmp(type_arr, "BLOB") == 0 || \ strcmp(type_arr, "NCHAR") == 0 || strcmp(type_arr, "NCLOB") == 0 || \ strcmp(type_arr, "REFCUR") == 0 || \ strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0) \ ; \ else \ return 0; #endif #else #define OTL_CHECK_BIND_VARS \ if (strcmp(type_arr, "INT") == 0 || strcmp(type_arr, "UNSIGNED") == 0 || \ strcmp(type_arr, "SHORT") == 0 || strcmp(type_arr, "LONG") == 0 || \ strcmp(type_arr, "FLOAT") == 0 || strcmp(type_arr, "DOUBLE") == 0 || \ strcmp(type_arr, "BFLOAT") == 0 || strcmp(type_arr, "BDOUBLE") == 0 || \ strcmp(type_arr, "TIMESTAMP") == 0 || \ strcmp(type_arr, "TZ_TIMESTAMP") == 0 || \ strcmp(type_arr, "LTZ_TIMESTAMP") == 0 || \ strcmp(type_arr, "BIGINT") == 0 || strcmp(type_arr, "UBIGINT") == 0 || \ strcmp(type_arr, "CHAR") == 0 || strcmp(type_arr, "CHARZ") == 0 || \ strcmp(type_arr, "DB2DATE") == 0 || strcmp(type_arr, "DB2TIME") == 0 || \ strcmp(type_arr, "VARCHAR_LONG") == 0 || \ strcmp(type_arr, "RAW_LONG") == 0 || strcmp(type_arr, "RAW") == 0 || \ strcmp(type_arr, "CLOB") == 0 || strcmp(type_arr, "BLOB") == 0 || \ strcmp(type_arr, "NCHAR") == 0 || strcmp(type_arr, "NCLOB") == 0 || \ strcmp(type_arr, "REFCUR") == 0) \ ; \ else \ return 0; #endif #else #define OTL_CHECK_BIND_VARS #endif // ------------------- Namespace generation ------------------------ #if defined(OTL_EXPLICIT_NAMESPACES) #if defined(OTL_DB2_CLI) #define OTL_ODBC_NAMESPACE_BEGIN namespace db2 { #define OTL_ODBC_NAMESPACE_PREFIX db2:: #define OTL_ODBC_NAMESPACE_END } #else #define OTL_ODBC_NAMESPACE_BEGIN namespace odbc { #define OTL_ODBC_NAMESPACE_PREFIX odbc:: #define OTL_ODBC_NAMESPACE_END } #endif #define OTL_ORA8_NAMESPACE_BEGIN namespace oracle { #define OTL_ORA8_NAMESPACE_PREFIX oracle:: #define OTL_ORA8_NAMESPACE_END } #else // Only one OTL is being intantiated #if defined(OTL_ODBC) && !defined(OTL_ORA8) && !defined(OTL_DB2_CLI) || \ !defined(OTL_ODBC) && defined(OTL_ORA8) && !defined(OTL_DB2_CLI) || \ !defined(OTL_ODBC) && !defined(OTL_ORA8) && !defined(OTL_DB2_CLI) || \ !defined(OTL_ODBC) && !defined(OTL_ORA8) && defined(OTL_DB2_CLI) #define OTL_ODBC_NAMESPACE_BEGIN #define OTL_ODBC_NAMESPACE_PREFIX #define OTL_ODBC_NAMESPACE_END #define OTL_ORA8_NAMESPACE_BEGIN #define OTL_ORA8_NAMESPACE_PREFIX #define OTL_ORA8_NAMESPACE_END #endif // ================ Combinations of two OTLs ========================= #if defined(OTL_ODBC) && defined(OTL_ORA8) && !defined(OTL_DB2_CLI) #define OTL_ODBC_NAMESPACE_BEGIN namespace odbc { #define OTL_ODBC_NAMESPACE_PREFIX odbc:: #define OTL_ODBC_NAMESPACE_END } #define OTL_ORA8_NAMESPACE_BEGIN namespace oracle { #define OTL_ORA8_NAMESPACE_PREFIX oracle:: #define OTL_ORA8_NAMESPACE_END } #endif #if !defined(OTL_ODBC) && defined(OTL_ORA8) && defined(OTL_DB2_CLI) #define OTL_ORA8_NAMESPACE_BEGIN namespace oracle { #define OTL_ORA8_NAMESPACE_PREFIX oracle:: #define OTL_ORA8_NAMESPACE_END } #define OTL_ODBC_NAMESPACE_BEGIN namespace db2 { #define OTL_ODBC_NAMESPACE_PREFIX db2:: #define OTL_ODBC_NAMESPACE_END } #endif #endif // -------------------- End of namespace generation ------------------- // --------------------- Invalid combinations -------------------------- #if defined(OTL_ORA_MAP_BIGINT_TO_LONG) && defined(OTL_BIGINT_TO_STR) && \ defined(OTL_STR_TO_BIGINT) #error OTL_ORA_MAP_BIGINT_TO_LONG cannot be used when \ OTL_BIGINT_TO_STR and OTL_STR_TO_BIGINT are defined #endif #if defined(OTL_STL) && defined(OTL_UNICODE_STRING_TYPE) #error Invalid combination: OTL_STL and OTL_UNICODE_STRING_TYPE #endif #if defined(OTL_ORA_UTF8) && !defined(OTL_ORA10G) && \ !defined(OTL_ORA_10G_R2) && !defined(OTL_ORA9I) #error Invalid combination: OTL_ORA_UTF8 can only be used with OTL_ORA9I or higher #endif #if defined(OTL_ORA_UTF8) && defined(OTL_UNICODE) #error Invalid combination: OTL_ORA_UTF8 and OTL_UNICODE are mutually exclusive #endif #if defined(OTL_ODBC) && defined(OTL_DB2_CLI) #error Invalid combination: OTL_ODBC && OTL_DB2_CLI together #endif #if defined(OTL_ORA_OCI_ENV_CREATE) && \ (!defined(OTL_ORA8I) && !defined(OTL_ORA9I) && !defined(OTL_ORA10G) && \ !defined(OTL_ORA10G_R2)) #error OTL_ORA_OCI_ENV_CREATE can be only defined when OTL_ORA8I, OTL_ORA9I, OTL_ORA10G, OTL_ORA10G_R2, or OTL_ORA11G, or OTL_ORA11G_R2, or OTL_ORA12C is defined #endif // -------------------------------------------------------------------- #if defined(OTL_TRACE_LEVEL) #if !defined(OTL_TRACE_LINE_PREFIX) #define OTL_TRACE_LINE_PREFIX "OTL TRACE ==> " #endif #if defined(OTL_UNICODE_CHAR_TYPE) && !defined(OTL_UNICODE) #error OTL_UNICODE needs to be defined if OTL_UNICODE_CHAR_TYPE is defined #endif #if defined(OTL_UNICODE_STRING_TYPE) && !defined(OTL_UNICODE_CHAR_TYPE) #error OTL_UNICODE_CHAR_TYPE needs to be defined if OTL_UNICODE_STRING_TYPE is defined #endif #if defined(OTL_UNICODE_STRING_TYPE) && !defined(OTL_UNICODE_CHAR_TYPE) #error OTL_UNICODE_CHAR_TYPE needs to be defined if OTL_UNICODE_STRING_TYPE is defined #endif #if defined(OTL_UNICODE_STRING_TYPE) && !defined(OTL_UNICODE) #error OTL_UNICODE needs to be defined if OTL_UNICODE_STRING_TYPE is defined #endif #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) && !defined(OTL_UNICODE_CHAR_TYPE) #error OTL_UNICODE_CHAR_TYPE needs to be defined if OTL_UNICODE_EXCEPTION_AND_RLOGON is defined #endif #if !defined(OTL_TRACE_LINE_SUFFIX) #if defined(OTL_UNICODE) #define OTL_TRACE_LINE_SUFFIX L"\n" #else #define OTL_TRACE_LINE_SUFFIX "\n" #endif #endif #if !defined(OTL_TRACE_STREAM_OPEN) #define OTL_TRACE_STREAM_OPEN \ if (OTL_TRACE_LEVEL & 0x4) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::open(buffer_size="; \ OTL_TRACE_STREAM << arr_size; \ OTL_TRACE_STREAM << ", sqlstm="; \ OTL_TRACE_STREAM << sqlstm; \ OTL_TRACE_STREAM << ", connect="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, &db); \ OTL_TRACE_STREAM << ", implicit_select="; \ OTL_TRACE_STREAM << implicit_select; \ if (sqlstm_label) { \ OTL_TRACE_STREAM << ", label="; \ OTL_TRACE_STREAM << sqlstm_label; \ } \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_STREAM_OPEN2) #define OTL_TRACE_STREAM_OPEN2 \ if (OTL_TRACE_LEVEL & 0x4) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::open(buffer_size="; \ OTL_TRACE_STREAM << arr_size; \ OTL_TRACE_STREAM << ", sqlstm="; \ OTL_TRACE_STREAM << sqlstm; \ OTL_TRACE_STREAM << ", connect="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, &db); \ if (ref_cur_placeholder) { \ OTL_TRACE_STREAM << ", ref_cur_placeholder="; \ OTL_TRACE_STREAM << ref_cur_placeholder; \ } \ if (sqlstm_label) { \ OTL_TRACE_STREAM << ", label="; \ OTL_TRACE_STREAM << sqlstm_label; \ } \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_DIRECT_EXEC) #define OTL_TRACE_DIRECT_EXEC \ if (OTL_TRACE_LEVEL & 0x2) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_cursor::direct_exec(connect="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, &connect); \ OTL_TRACE_STREAM << ",sqlstm=\""; \ OTL_TRACE_STREAM << sqlstm; \ OTL_TRACE_STREAM << "\",exception_enabled="; \ OTL_TRACE_STREAM << exception_enabled; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_SYNTAX_CHECK) #define OTL_TRACE_SYNTAX_CHECK \ if (OTL_TRACE_LEVEL & 0x2) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_cursor::syntax_check(connect="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, &connect); \ OTL_TRACE_STREAM << ",sqlstm=\""; \ OTL_TRACE_STREAM << sqlstm; \ OTL_TRACE_STREAM << "\""; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_FUNC) #define OTL_TRACE_FUNC(level, class_name, func_name, args) \ if (OTL_TRACE_LEVEL & level) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << class_name; \ OTL_TRACE_STREAM << "(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::" func_name "("; \ OTL_TRACE_STREAM << args; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_EXCEPTION) #define OTL_TRACE_EXCEPTION(code, msg, stm_text, var_info) \ if (OTL_TRACE_LEVEL & 0x20) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_exception, code="; \ OTL_TRACE_STREAM << code; \ OTL_TRACE_STREAM << ", msg="; \ char *c = OTL_RCAST(char *, msg); \ while (*c && *c != '\n') { \ OTL_TRACE_STREAM << *c; \ ++c; \ } \ OTL_TRACE_STREAM << ", stm_text="; \ OTL_TRACE_STREAM << stm_text; \ OTL_TRACE_STREAM << ", var_info="; \ OTL_TRACE_STREAM << var_info; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_EXCEPTION2) #define OTL_TRACE_EXCEPTION2(code, msg, stm_text, var_info, input_str, \ input_str_size) \ if (OTL_TRACE_LEVEL & 0x20) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_exception, code="; \ OTL_TRACE_STREAM << code; \ OTL_TRACE_STREAM << ", msg="; \ char *c = OTL_RCAST(char *, msg); \ while (*c && *c != '\n') { \ OTL_TRACE_STREAM << *c; \ ++c; \ } \ OTL_TRACE_STREAM << ", stm_text="; \ OTL_TRACE_STREAM << stm_text; \ OTL_TRACE_STREAM << ", var_info="; \ OTL_TRACE_STREAM << var_info; \ OTL_TRACE_STREAM << ", input string=\""; \ const char *str = OTL_RCAST(const char *, input_str); \ int i = 0; \ while (i < input_str_size) \ OTL_TRACE_STREAM << str[i++]; \ OTL_TRACE_STREAM << "\"" << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_LEVEL_NOCHECK_ON_LOGON) && !defined(OTL_TRACE_RLOGON_ORA8) && defined(OTL_ORA8) #define OTL_TRACE_RLOGON_ORA8(level, class_name, func_name, tnsname, userid, \ passwd, auto_commit) \ if (OTL_TRACE_LEVEL & level) { \ char temp_connect_str[2048]; \ OTL_STRCPY_S(temp_connect_str, sizeof(temp_connect_str), userid); \ OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str) - strlen(temp_connect_str) - 1, "/"); \ size_t sz = strlen(passwd); \ for (size_t i = 0; i < sz; ++i) \ OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str) - strlen(temp_connect_str) - 1, "*"); \ size_t tns_sz = strlen(tnsname); \ if (tns_sz > 0) { \ OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str) - strlen(temp_connect_str) - 1, "@"); \ OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str) - strlen(temp_connect_str) - 1, tnsname); \ } \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << class_name << "(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::" func_name "("; \ OTL_TRACE_STREAM << "connect_str=\""; \ OTL_TRACE_STREAM << temp_connect_str; \ OTL_TRACE_STREAM << "\", auto_commit="; \ OTL_TRACE_STREAM << auto_commit << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #elif defined(OTL_TRACE_LEVEL_NOCHECK_ON_LOGON) && !defined(OTL_TRACE_RLOGON_ORA8) && defined(OTL_ORA8) #define OTL_TRACE_RLOGON_ORA8(level, class_name, func_name, tnsname, userid, \ passwd, auto_commit) \ { \ char temp_connect_str[2048]; \ OTL_STRCPY_S(temp_connect_str, sizeof(temp_connect_str), userid); \ OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str) - strlen(temp_connect_str) - 1, "/"); \ size_t sz = strlen(passwd); \ for (size_t i = 0; i < sz; ++i) \ OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str) - strlen(temp_connect_str) - 1, "*"); \ size_t tns_sz = strlen(tnsname); \ if (tns_sz > 0) { \ OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str) - strlen(temp_connect_str) - 1, "@"); \ OTL_STRCAT_S(temp_connect_str, sizeof(temp_connect_str) - strlen(temp_connect_str) - 1, tnsname); \ } \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << class_name << "(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::" func_name "("; \ OTL_TRACE_STREAM << "connect_str=\""; \ OTL_TRACE_STREAM << temp_connect_str; \ OTL_TRACE_STREAM << "\", auto_commit="; \ OTL_TRACE_STREAM << auto_commit << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_LEVEL_NOCHECK_ON_LOGON) && !defined(OTL_TRACE_RLOGON_ODBC) \ && (defined(OTL_ODBC) || defined(OTL_DB2_CLI)) #define OTL_TRACE_RLOGON_ODBC(level, class_name, func_name, tnsname, userid, \ passwd, auto_commit) \ if (OTL_TRACE_LEVEL & level) { \ char temp_connect_str2[2048]; \ OTL_STRCPY_S(temp_connect_str2, sizeof(temp_connect_str2), userid); \ OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2) - strlen(temp_connect_str2) - 1, "/"); \ size_t sz = strlen(passwd); \ for (size_t i = 0; i < sz; ++i) \ OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2) - strlen(temp_connect_str2) - 1, "*"); \ size_t tns_sz = strlen(tnsname); \ if (tns_sz > 0) { \ OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2) - strlen(temp_connect_str2) - 1, "@"); \ OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2) - strlen(temp_connect_str2) - 1, tnsname); \ } \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << class_name; \ OTL_TRACE_STREAM << "(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::" func_name "("; \ OTL_TRACE_STREAM << "connect_str=\""; \ OTL_TRACE_STREAM << temp_connect_str2; \ OTL_TRACE_STREAM << "\", auto_commit="; \ OTL_TRACE_STREAM << auto_commit; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #elif defined(OTL_TRACE_LEVEL_NOCHECK_ON_LOGON) && !defined(OTL_TRACE_RLOGON_ODBC) \ && (defined(OTL_ODBC) || defined(OTL_DB2_CLI)) #define OTL_TRACE_RLOGON_ODBC(level, class_name, func_name, tnsname, userid, \ passwd, auto_commit) \ { \ char temp_connect_str2[2048]; \ OTL_STRCPY_S(temp_connect_str2, sizeof(temp_connect_str2), userid); \ OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2) - strlen(temp_connect_str2) - 1, "/"); \ size_t sz = strlen(passwd); \ for (size_t i = 0; i < sz; ++i) \ OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2) - strlen(temp_connect_str2) - 1, "*"); \ size_t tns_sz = strlen(tnsname); \ if (tns_sz > 0) { \ OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2) - strlen(temp_connect_str2) - 1, "@"); \ OTL_STRCAT_S(temp_connect_str2, sizeof(temp_connect_str2) - strlen(temp_connect_str2) - 1, tnsname); \ } \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << class_name; \ OTL_TRACE_STREAM << "(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::" func_name "("; \ OTL_TRACE_STREAM << "connect_str=\""; \ OTL_TRACE_STREAM << temp_connect_str2; \ OTL_TRACE_STREAM << "\", auto_commit="; \ OTL_TRACE_STREAM << auto_commit; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_RLOGON_ODBC_W) && \ (defined(OTL_ODBC) || defined(OTL_DB2_CLI)) #define OTL_TRACE_RLOGON_ODBC_W(level, class_name, func_name, tnsname, userid, \ passwd, auto_commit) \ if (OTL_TRACE_LEVEL & level) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << class_name; \ OTL_TRACE_STREAM << L"(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << L")::" func_name L"("; \ OTL_TRACE_STREAM << L"connect_str=\""; \ OTL_TRACE_STREAM << userid << L"/***@" << tnsname; \ OTL_TRACE_STREAM << L"\", auto_commit="; \ OTL_TRACE_STREAM << auto_commit; \ OTL_TRACE_STREAM << L");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #if !defined(OTL_TRACE_FIRST_FETCH) #if defined(OTL_TRACE_ENABLE_STREAM_LABELS) #define OTL_TRACE_FIRST_FETCH \ if (OTL_TRACE_LEVEL & 0x8) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << this->master_stream_ptr_; \ OTL_TRACE_STREAM << "), "; \ OTL_TRACE_STREAM << "fetched the first batch of rows, SQL Stm="; \ if (this->stm_label) \ OTL_TRACE_STREAM << this->stm_label; \ else \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", RPC="; \ OTL_TRACE_STREAM << row_count; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #else #define OTL_TRACE_FIRST_FETCH \ if (OTL_TRACE_LEVEL & 0x8) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << this->master_stream_ptr_; \ OTL_TRACE_STREAM << "), "; \ OTL_TRACE_STREAM << "fetched the first batch of rows, SQL Stm="; \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", RPC="; \ OTL_TRACE_STREAM << row_count; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #endif #if !defined(OTL_TRACE_NEXT_FETCH) #if defined(OTL_TRACE_ENABLE_STREAM_LABELS) #define OTL_TRACE_NEXT_FETCH \ if (OTL_TRACE_LEVEL & 0x8 && cur_row == 0) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << this->master_stream_ptr_; \ OTL_TRACE_STREAM << "), "; \ OTL_TRACE_STREAM << "fetched the next batch of rows, SQL Stm="; \ if (this->stm_label) \ OTL_TRACE_STREAM << this->stm_label; \ else \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", RPC="; \ OTL_TRACE_STREAM << row_count; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #define OTL_TRACE_NEXT_FETCH2 \ if (OTL_TRACE_LEVEL & 0x8 && cur_row == 1) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << this->master_stream_ptr_; \ OTL_TRACE_STREAM << "), "; \ OTL_TRACE_STREAM << "fetched the next batch of rows, SQL Stm="; \ if (this->stm_label) \ OTL_TRACE_STREAM << this->stm_label; \ else \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", RPC="; \ OTL_TRACE_STREAM << row_count; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #else #define OTL_TRACE_NEXT_FETCH \ if (OTL_TRACE_LEVEL & 0x8 && cur_row == 0) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << this->master_stream_ptr_; \ OTL_TRACE_STREAM << "), "; \ OTL_TRACE_STREAM << "fetched the next batch of rows, SQL Stm="; \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", RPC="; \ OTL_TRACE_STREAM << row_count; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #define OTL_TRACE_NEXT_FETCH2 \ if (OTL_TRACE_LEVEL & 0x8 && cur_row == 1) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << this->master_stream_ptr_; \ OTL_TRACE_STREAM << "), "; \ OTL_TRACE_STREAM << "fetched the next batch of rows, SQL Stm="; \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", RPC="; \ OTL_TRACE_STREAM << row_count; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #endif #if !defined(OTL_TRACE_STREAM_EXECUTION) #if defined(OTL_TRACE_ENABLE_STREAM_LABELS) #define OTL_TRACE_STREAM_EXECUTION \ if (OTL_TRACE_LEVEL & 0x8) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << override_->get_master_stream_ptr(); \ OTL_TRACE_STREAM << "), executing SQL Stm="; \ if (this->stm_label) \ OTL_TRACE_STREAM << this->stm_label; \ else \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", buffer size="; \ OTL_TRACE_STREAM << this->array_size; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #else #define OTL_TRACE_STREAM_EXECUTION \ if (OTL_TRACE_LEVEL & 0x8) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << override_->get_master_stream_ptr(); \ OTL_TRACE_STREAM << "), executing SQL Stm="; \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", buffer size="; \ OTL_TRACE_STREAM << this->array_size; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #endif #if !defined(OTL_TRACE_STREAM_EXECUTION2) #if defined(OTL_TRACE_ENABLE_STREAM_LABELS) #define OTL_TRACE_STREAM_EXECUTION2 \ if (OTL_TRACE_LEVEL & 0x8) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << this->master_stream_ptr_; \ OTL_TRACE_STREAM << "), executing SQL Stm="; \ if (this->stm_label) \ OTL_TRACE_STREAM << this->stm_label; \ else \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", current batch size="; \ OTL_TRACE_STREAM << (cur_y + 1); \ OTL_TRACE_STREAM << ", row offset="; \ OTL_TRACE_STREAM << rowoff; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #else #define OTL_TRACE_STREAM_EXECUTION2 \ if (OTL_TRACE_LEVEL & 0x8) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << this->master_stream_ptr_; \ OTL_TRACE_STREAM << "), executing SQL Stm="; \ OTL_TRACE_STREAM << this->stm_text; \ OTL_TRACE_STREAM << ", current batch size="; \ OTL_TRACE_STREAM << (cur_y + 1); \ OTL_TRACE_STREAM << ", row offset="; \ OTL_TRACE_STREAM << rowoff; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } #endif #endif #if !defined(OTL_TRACE_READ) #define OTL_TRACE_READ(val, function, type) \ if (OTL_TRACE_LEVEL & 0x10) { \ otl_var_desc *temp_vdesc = describe_next_in_var(); \ if (temp_vdesc) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::" function "(" type ": "; \ OTL_TRACE_STREAM << "ftype="; \ OTL_TRACE_STREAM << temp_vdesc->ftype; \ OTL_TRACE_STREAM << ", placeholder="; \ OTL_TRACE_STREAM << temp_vdesc->name; \ OTL_TRACE_STREAM << ", value="; \ OTL_TRACE_STREAM << val; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } else { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "loading superfluous input variable"; \ OTL_TRACE_STREAM << "::" function "(" type ": "; \ OTL_TRACE_STREAM << ", value="; \ OTL_TRACE_STREAM << val; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } \ } #endif #if !defined(OTL_TRACE_WRITE) #define OTL_TRACE_WRITE(val, function, type) \ if (OTL_TRACE_LEVEL & 0x10) { \ otl_var_desc *temp_vdesc = describe_next_out_var(); \ if (temp_vdesc) { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "otl_stream(this="; \ OTL_TRACE_STREAM << OTL_RCAST(void *, this); \ OTL_TRACE_STREAM << ")::" function "(" type " : "; \ OTL_TRACE_STREAM << "ftype="; \ OTL_TRACE_STREAM << temp_vdesc->ftype; \ OTL_TRACE_STREAM << ", placeholder="; \ OTL_TRACE_STREAM << temp_vdesc->name; \ OTL_TRACE_STREAM << ", value="; \ if (this->is_null()) \ OTL_TRACE_STREAM << "NULL"; \ else \ OTL_TRACE_STREAM << val; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } else { \ OTL_TRACE_STREAM << OTL_TRACE_LINE_PREFIX; \ OTL_TRACE_STREAM << "writing superfluous output variable"; \ OTL_TRACE_STREAM << "::" function "(" type " : "; \ OTL_TRACE_STREAM << ", value="; \ if (this->is_null()) \ OTL_TRACE_STREAM << "NULL"; \ else \ OTL_TRACE_STREAM << val; \ OTL_TRACE_STREAM << ");"; \ OTL_TRACE_STREAM << OTL_TRACE_LINE_SUFFIX; \ } \ } #endif #else #define OTL_TRACE_LINE_PREFIX #define OTL_TRACE_LINE_SUFFIX #define OTL_TRACE_DIRECT_EXEC #define OTL_TRACE_SYNTAX_CHECK #define OTL_TRACE_FUNC(level, class_name, func_name, args) #define OTL_TRACE_EXCEPTION(code, msg, stm_text, var_info) #define OTL_TRACE_EXCEPTION2(code, msg, stm_text, var_info, input_str, \ inputs_str_size) #define OTL_TRACE_RLOGON_ORA8(level, class_name, func_name, tnsname, userid, \ passwd, auto_commit) #define OTL_TRACE_RLOGON_ODBC(level, class_name, func_name, tnsname, userid, \ passwd, auto_commit) #define OTL_TRACE_STREAM_OPEN #define OTL_TRACE_STREAM_OPEN2 #define OTL_TRACE_FIRST_FETCH #define OTL_TRACE_NEXT_FETCH #define OTL_TRACE_NEXT_FETCH2 #define OTL_TRACE_STREAM_EXECUTION #define OTL_TRACE_STREAM_EXECUTION2 #define OTL_TRACE_WRITE(val, function, type) #define OTL_TRACE_READ(val, function, type) #define OTL_TRACE_RLOGON_ODBC_W(level, class_name, func_name, tnsname, userid, \ passwd, auto_commit) #endif #if defined(OTL_DB2_CLI) #define OTL_ODBC #endif #if defined(OTL_UNICODE) #if !defined(OTL_UNICODE_CHAR_TYPE) #define OTL_UNICODE_CHAR_TYPE wchar_t #endif #if !defined(OTL_UNICODE_CHAR_TYPE_TRACE_NAME) #define OTL_UNICODE_CHAR_TYPE_TRACE_NAME "wchar_t" #endif #endif #if defined(OTL_UNICODE) && (defined(OTL_ORA8I) || defined(OTL_ORA9I) || \ defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) #define OTL_ORA_UNICODE #endif #if defined(OTL_UNICODE) #if (defined(OTL_ORA8I) || defined(OTL_ORA9I) || defined(OTL_ORA10G) || \ defined(OTL_ORA10G_R2)) && \ defined(OTL_ODBC) #error OTL_UNICODE is not supported when both OTL_ORAxx and OTL_ODBC/OTL_DB2_CLI are defined #endif #if defined(OTL_ORA8I) || defined(OTL_ORA9I) || defined(OTL_ORA10G) || \ defined(OTL_ORA10G_R2) #define OTL_CHAR unsigned short #define OTL_UNICODE_CHAR OTL_CHAR #define OTL_WCHAR unsigned long #if defined(OTL_ORA8I) && !defined(OTL_ORA9I) && !defined(OTL_ORA10G) && \ !defined(OTL_ORA10G_R2) && !defined(OTL_ORA11G) && \ !defined(OTL_ORA11G_R2) && !defined(OTL_ORA12C) #define OTL_UNICODE_ID OCI_UCS2ID #endif #if defined(OTL_ORA9I) #define OTL_UNICODE_ID OCI_UTF16ID #endif #elif defined(OTL_ODBC) #define OTL_CHAR unsigned short #define OTL_UNICODE_CHAR OTL_CHAR #define OTL_WCHAR OTL_CHAR #endif #else #define OTL_CHAR unsigned char #endif #if defined(OTL_ORA8) #define OTL_PL_TAB #endif const int otl_short_int_max = 32760; #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED) #define OTL_ADAPTER_ENUM otl_adapter_enum:: enum class otl_adapter_enum : unsigned char { otl_odbc_adapter = 1, otl_ora8_adapter = 2 }; #else #define OTL_ADAPTER_ENUM typedef unsigned char otl_adapter_enum; const otl_adapter_enum otl_odbc_adapter = 1; const otl_adapter_enum otl_ora8_adapter = 2; #endif #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED) #define OTL_BINDING_ENUM otl_binding_enum:: enum class otl_binding_enum : unsigned char { otl_inout_binding = 1, otl_select_binding = 2 }; #else #define OTL_BINDING_ENUM typedef unsigned char otl_binding_enum; const otl_binding_enum otl_inout_binding = 1; const otl_binding_enum otl_select_binding = 2; #endif const int otl_unsupported_type = -10000; #if defined(OTL_ANSI_CPP) #define OTL_SCAST(_t, _e) static_cast<_t>(_e) #define OTL_RCAST(_t, _e) reinterpret_cast<_t>(_e) #define OTL_DCAST(_t, _e) dynamic_cast<_t>(_e) #define OTL_CCAST(_t, _e) const_cast<_t>(_e) #define OTL_CONST_EXCEPTION const #if defined(OTL_FUNC_THROW_SPEC_ON) #define OTL_THROWS_OTL_EXCEPTION throw(otl_exception) #define OTL_THROWS_OTL_EXCEPTION2 #define OTL_THROWS_OTL_EXCEPTION3 throw(OTL_TMPL_EXCEPTION) #define OTL_THROWS_OTL_EXCEPTION4 #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) #define OTL_NO_THROW OTL_ANSI_CPP_11_NOEXCEPT #else #define OTL_NO_THROW throw() #endif #else #if defined(OTL_ANSI_CPP_11_NOEXCEPT_FALSE) && !defined(OTL_THROWS_OTL_EXCEPTION) #define OTL_THROWS_OTL_EXCEPTION OTL_ANSI_CPP_11_NOEXCEPT_FALSE #define OTL_THROWS_OTL_EXCEPTION2 OTL_ANSI_CPP_11_NOEXCEPT_FALSE #define OTL_THROWS_OTL_EXCEPTION3 OTL_ANSI_CPP_11_NOEXCEPT_FALSE #define OTL_THROWS_OTL_EXCEPTION4 OTL_ANSI_CPP_11_NOEXCEPT_FALSE #else #if !defined(OTL_THROWS_OTL_EXCEPTION) #define OTL_THROWS_OTL_EXCEPTION #define OTL_THROWS_OTL_EXCEPTION2 #define OTL_THROWS_OTL_EXCEPTION3 #define OTL_THROWS_OTL_EXCEPTION4 #endif #endif #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) && !defined(OTL_NO_THROW) #define OTL_NO_THROW OTL_ANSI_CPP_11_NOEXCEPT #else #if defined(OTL_NO_THROW_IS_EMPTY_THROW) #define OTL_NO_THROW throw() #else #if !defined(OTL_NO_THROW) #define OTL_NO_THROW #endif #endif #endif #endif #define OTL_TYPE_NAME typename #include #else #define OTL_SCAST(_t, _e) ((_t)(_e)) #define OTL_RCAST(_t, _e) ((_t)(_e)) #define OTL_DCAST(_t, _e) ((_t)(_e)) #define OTL_CCAST(_t, _e) ((_t)(_e)) #define OTL_CONST_EXCEPTION #define OTL_THROWS_OTL_EXCEPTION #define OTL_THROWS_OTL_EXCEPTION2 #define OTL_THROWS_OTL_EXCEPTION3 #if defined(OTL_NO_THROW_IS_EMPTY_THROW) #define OTL_NO_THROW throw() #else #define OTL_NO_THROW #endif #define OTL_TYPE_NAME class #endif #define OTL_PCONV(_to, _from, _val) \ OTL_SCAST(_to, *OTL_RCAST(_from *, OTL_CCAST(void *, _val))) #if defined(OTL_ACE) #include #include #include #include #include #define OTL_USER_DEFINED_STRING_CLASS_ON #define USER_DEFINED_STRING_CLASS ACE_TString #define OTL_VALUE_TEMPLATE_ON const int otl_tmpl_vector_default_size = 16; template class otl_tmpl_vector : public ACE_Array { public: otl_tmpl_vector(const int init_size = otl_tmpl_vector_default_size) : ACE_Array(init_size == 0 ? otl_tmpl_vector_default_size : init_size) { length_ = 0; } ~otl_tmpl_vector() {} OTL_NODISCARD int capacity(void) const { return this->max_size(); } OTL_NODISCARD int size(void) const { return length_; } void clear(void) { length_ = 0; } void resize(const int new_size, const T &t = T()) { ACE_Array::size(new_size); if (new_size > length_) { for (int i = length_; i < new_size; ++i) (*this)[i] = t; } length_ = new_size; } void push_back(const T &elem) { int curr_max_size = OTL_SCAST(int, this->max_size()); if (length_ == curr_max_size) ACE_Array::size(curr_max_size * 2); ++length_; (*this)[length_ - 1] = elem; } void pop_back(void) { if (length_ > 0) --length_; } private: int length_; }; #endif #if defined(OTL_STLPORT) #if defined(__STLPORT_STD) #define OTL_STLPORT_NAMESPACE __STLPORT_STD #else #if defined(_STLP_USE_OWN_NAMESPACE) #define OTL_STLPORT_NAMESPACE _STL #else #define OTL_STLPORT_NAMESPACE std #endif #endif #define OTL_STL #endif #if defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) #include #if !defined(OTL_STLPORT) #if defined(OTL_CPP_17_ON) // C++17 and higher deprecated bool std::uncaught_exception() OTL_NODISCARD inline bool otl_uncaught_exception() { return std::uncaught_exceptions() > 0; } #else OTL_NODISCARD inline bool otl_uncaught_exception() { return std::uncaught_exception(); } #endif #else OTL_NODISCARD inline bool otl_uncaught_exception() { #if defined(OTL_STLPORT_USES_STD_ALIAS_NAMESPACE) return __std_alias::uncaught_exception(); #else return OTL_STLPORT_NAMESPACE::uncaught_exception(); #endif } #endif #else OTL_NODISCARD inline bool otl_uncaught_exception() { return std::uncaught_exception(); } #endif #define OTL_UNCAUGHT_EXCEPTION_NORETURN if(otl_uncaught_exception()) return; #define OTL_UNCAUGHT_EXCEPTION_RETURN(x) if(otl_uncaught_exception()) return x; #if defined(OTL_VALUE_TEMPLATE_ON) && !defined(OTL_STL) && !defined(OTL_ACE) #define STD_NAMESPACE_PREFIX #if (defined(_MSC_VER) && (_MSC_VER >= 1300)) || defined(OTL_ANSI_CPP) #include #include #else #include #include #endif #endif #if defined(OTL_USER_DEFINED_STRING_CLASS_ON) #if defined(OTL_STL) #error OTL_STL cannot be used in combination with OTL_USER_DEFINED_STRING_CLASS_ON #endif #if defined(USER_DEFINED_STRING_CLASS) #define OTL_STRING_CONTAINER USER_DEFINED_STRING_CLASS #define STD_NAMESPACE_PREFIX #else #error USER_DEFINED_STRING_CLASS macro needs to be defined before including otlv4.h #endif #endif #if defined(OTL_STL) #if defined(_MSC_VER) #if (_MSC_VER >= 1200) #pragma warning(disable : 4786) #pragma warning(disable : 4290) #pragma warning(disable : 4996) #endif #endif #if defined(OTL_STL_NOSTD_NAMESPACE) #ifndef OTL_STRING_CONTAINER #define OTL_STRING_CONTAINER string #endif #define STD_NAMESPACE_PREFIX #else #ifndef OTL_STRING_CONTAINER #if defined(OTL_STLPORT) #define OTL_STRING_CONTAINER OTL_STLPORT_NAMESPACE::string #else #define OTL_STRING_CONTAINER std::string #endif #endif #if defined(OTL_STLPORT) #define STD_NAMESPACE_PREFIX OTL_STLPORT_NAMESPACE:: #else #define STD_NAMESPACE_PREFIX std:: #endif #endif #include #include #include #ifndef OTL_STL_NOSTD_NAMESPACE #include #include #else #if defined(_MSC_VER) && (_MSC_VER >= 1300) #include #include #else #include #include #endif #endif #endif //======================= END OF CONFIGURATION ============================== // ====== COMMON NON-TEMPLATE OBJECTS: CONSTANTS, CLASSES, ETC. =========== #if defined(OTL_INITIAL_VAR_LIST_SIZE) const int otl_var_list_size = OTL_INITIAL_VAR_LIST_SIZE; #else #if defined(OTL_ORA8) const int otl_var_list_size = 1024; #else const int otl_var_list_size = 512; #endif #endif const int otl_error_code_0 = 32000; #define otl_error_msg_0 "Incompatible data types in stream operation" const int otl_error_code_1 = 32004; #define otl_error_msg_1 "No input variables have been defined in SQL statement" const int otl_error_code_2 = 32003; #define otl_error_msg_2 "Not all input variables have been initialized" const int otl_error_code_3 = 32001; #define otl_error_msg_3 "Row must be full for flushing output stream" const int otl_error_code_4 = 32005; #define otl_error_msg_4 "Input string value is too large to fit into the buffer" const int otl_error_code_5 = 32006; #define otl_error_msg_5 \ "Input otl_long_string is too large to fit into the buffer" const int otl_error_code_6 = 32007; #define otl_error_msg_6 "PL/SQL table size is too large (>32767)" const int otl_error_code_7 = 32008; #define otl_error_msg_7 \ "Writing CLOB/BLOB in stream mode: actual size is greater than specified" const int otl_error_code_8 = 32009; #define otl_error_msg_8 \ "Closing CLOB/BLOB in stream mode: actual size is not equal to specified " \ "size" const int otl_error_code_9 = 32010; #define otl_error_msg_9 "CLOB/BLOB stream is not open for writing" const int otl_error_code_10 = 32011; #define otl_error_msg_10 "CLOB/BLOB stream is not open for reading" const int otl_error_code_11 = 32012; #define otl_error_msg_11 "First session must be started with session_begin()" const int otl_error_code_12 = 32013; #define otl_error_msg_12 "Invalid bind variable declaration" const int otl_error_code_13 = 32014; #define otl_error_msg_13 "No stored procedure was found" const int otl_error_code_14 = 32015; #define otl_error_msg_14 "Unsupported data type: " const int otl_error_code_15 = 32016; #define otl_error_msg_15 "Unsupported procedure type" const int otl_error_code_16 = 32017; #define otl_error_msg_16 "Stream buffer size can't be > 1 in this case" const int otl_error_code_17 = 32018; #define otl_error_msg_17 \ "ODBC / DB2 CLI function name is not recognized. " \ "It should be one of the following: SQLTables, SQLColumns, " \ "SQLProcedures, SQLColumnPrivileges, SQLTablePrivileges, " \ "SQLPrimaryKeys, SQLProcedureColumns, SQLForeignKeys, SQLStatistics" const int otl_error_code_18 = 32019; #define otl_error_msg_18 \ "otl_stream::operator>>() should have been called " \ "before otl_stream::operator int()" const int otl_error_code_19 = 32020; #define otl_error_msg_19 "otl_stream_read_iterator: otl_stream is not open" const int otl_error_code_20 = 32021; #define otl_error_msg_20 \ "otl_stream_read_iterator: PL/SQL table and 'refcur' " \ "parameters are not supported" const int otl_error_code_21 = 32022; #define otl_error_msg_21 \ "otl_stream_read_iterator: otl_stream cannot be described" const int otl_error_code_22 = 32023; #define otl_error_msg_22 "otl_stream_read_iterator: position is out of range" const int otl_error_code_23 = 32024; #define otl_error_msg_23 "otl_stream_read_iterator: incompatible types in get()" const int otl_error_code_24 = 32025; #define otl_error_msg_24 \ "otl_stream::operator int() is not supported in the LOB stream mode" const int otl_error_code_25 = 32026; #define otl_error_msg_25 \ "otl_stream_read_iterator: get(otl_lob_stream*&) function " \ "can only be used if otl_stream::set_lob_stream_mode(true) had been called " \ "before the iterator was attached to the stream" const int otl_error_code_26 = 32027; #define otl_error_msg_26 \ "otl_stream_read_iterator: variable name is not recognized " const int otl_error_code_27 = 32028; #define otl_error_msg_27 "Unsupported column data type" const int otl_error_code_28 = 32029; #define otl_error_msg_28 \ "RAW value cannot be read with otl_lob_stream, use otl_long_string instead" const int otl_error_code_29 = 32030; #define otl_error_msg_29 "otl_stream is already open" const int otl_error_code_30 = 32031; #define otl_error_msg_30 "otl_connect is already connected" const int otl_error_code_31 = 32032; #define otl_error_msg_31 \ "SELECT otl_stream buffer size for TimesTen should be in [0..128] range" const int otl_error_code_32 = 32033; #define otl_error_msg_32 \ "otl_connect object needs to be connected to DB before using otl_subscriber" const int otl_error_code_33 = 32034; #define otl_error_msg_33 \ "otl_stream buffer size should be 1 when refcur or plsql table is used" const int otl_error_code_34 = 32035; #define otl_error_msg_34 "END-OF-ROW check failed" const int otl_error_code_35 = 32036; #define otl_error_msg_35 "otl_connect is not connected to the database" const int otl_error_code_36 = 32037; #define otl_error_msg_36 \ "SQL Statement has a white space in bind variable declaration" const int otl_error_code_37 = 32038; #define otl_error_msg_37 \ "otl_long_unicode_string should be used with strings when OTL_UNICODE is " \ "enabled, " \ " and otl_long_string should be use with strings when OTL_UNICODE is not " \ "enabled" const int otl_error_code_38 = 32039; #define otl_error_msg_38 \ "otl_long_string should be used with nonstrings when OTL_UNICODE is enabled" const int otl_error_code_39 = 32040; #define otl_error_msg_39 "This type of otl_stream can only have input variables" const int otl_error_code_40 = 32041; #define otl_error_msg_40 "Invalid stream buffer size (<=0)" const int otl_error_code_41 = 32042; #define otl_error_msg_41 \ "otl_lob_stream can't be used as an input parameter " \ "with a SELECT statement or a stored procedure that returns an implicit " \ "result set" const int otl_error_code_42 = 32043; #define otl_error_msg_42 \ "otl_stream::operator>>(%s) has been called when EOF was already reached" const int otl_error_code_43 = 32044; #define otl_error_msg_43 \ "Bind variable declaration is missing a terminator: > or */" const int otl_error_code_44 = 32045; #define otl_error_msg_44 "Empty TNS name in connect string" const int otl_error_code_45 = 32046; #define otl_error_msg_45 "target std::array container is too small" const int otl_error_code_46 = 32047; #define otl_error_msg_46 "target std::array container is too small" const int otl_error_code_47 = 32048; #define otl_error_msg_47 "rewind() cannot be called when implicit_select == otl_direct_exec_select" const int otl_oracle_date_size = 7; const int otl_explicit_select = 0; const int otl_implicit_select = 1; const int otl_direct_exec_select = 2; const int otl_input_param = 0; const int otl_output_param = 1; const int otl_inout_param = 2; const unsigned int otl_all_num2str = 1; const unsigned int otl_all_date2str = 2; const int otl_num_str_size = 60; const int otl_date_str_size = 60; template class otl_auto_array_ptr { public: otl_auto_array_ptr() : ptr(0), arr_size_(0) {} otl_auto_array_ptr(const int arr_size) : ptr(new T[OTL_SCAST(size_t,arr_size)]), arr_size_(arr_size) {} void double_size(void) { int old_arr_size = arr_size_; arr_size_ *= 2; T *temp_ptr = new T[OTL_SCAST(size_t,arr_size_)]; for (int i = 0; i < old_arr_size; ++i) temp_ptr[i] = ptr[i]; delete[] ptr; ptr = temp_ptr; } virtual ~otl_auto_array_ptr() { delete[] ptr; } OTL_NODISCARD T *get_ptr() { return ptr; } OTL_NODISCARD int get_arr_size() const { return arr_size_; } private: T *ptr; int arr_size_; otl_auto_array_ptr(const otl_auto_array_ptr &) : ptr(nullptr), arr_size_(0) {} otl_auto_array_ptr &operator=(const otl_auto_array_ptr &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_auto_array_ptr(otl_auto_array_ptr &&) : ptr(nullptr), arr_size_(0) {} otl_auto_array_ptr &operator=(otl_auto_array_ptr &&) { return *this; } #endif }; template class otl_ptr { public: otl_ptr() : ptr(nullptr), arr_flag(0) {} void assign(T **var) { ptr = var; arr_flag = 0; } void assign_array(T **var) { ptr = var; arr_flag = 1; } void disconnect(void) { if (ptr != nullptr) *ptr = nullptr; ptr = nullptr; } void destroy(void) { if (ptr == nullptr) return; if (*ptr != nullptr) { if (arr_flag) delete[] * ptr; else delete *ptr; *ptr = nullptr; } } ~otl_ptr() { destroy(); } protected: T **ptr; int arr_flag; private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_ptr(const otl_ptr &) = delete; otl_ptr &operator=(const otl_ptr &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_ptr(otl_ptr &&) = delete; otl_ptr &operator=(otl_ptr &&) = delete; #endif private: #else otl_ptr(const otl_ptr &) : ptr(nullptr), arr_flag(0) {} otl_ptr &operator=(const otl_ptr &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_ptr(otl_ptr &&) : ptr(nullptr), arr_flag(0) {} otl_ptr &operator=(otl_ptr &&) { return *this; } #endif #endif }; template class otl_Tptr { public: otl_Tptr() : ptr(nullptr), do_not_destroy(false) {} void assign(T *var) { ptr = var; } void disconnect(void) { ptr = nullptr; } void destroy(void) { if (do_not_destroy) return; delete ptr; ptr = nullptr; } ~otl_Tptr() { destroy(); } otl_Tptr &operator=(const otl_Tptr &src) { ptr = src.ptr; do_not_destroy = src.do_not_destroy; return *this; } void set_do_not_destroy(const bool ado_not_destroy) { do_not_destroy = ado_not_destroy; } T *get_ptr() { return ptr; } protected: T *ptr; bool do_not_destroy; private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_Tptr(const otl_Tptr &) = delete; otl_Tptr(otl_Tptr &&) = delete; private: #else otl_Tptr(const otl_Tptr &) : ptr(nullptr), do_not_destroy(false) {} #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) otl_Tptr(otl_Tptr &&) : ptr(nullptr), do_not_destroy(false) {} #endif #endif }; class otl_select_struct_override { public: otl_select_struct_override() : col_ndx(new short int[otl_var_list_size]), col_type(new short int[otl_var_list_size]), col_size(new int[otl_var_list_size]), len(0), all_mask(0), lob_stream_mode(false), container_size_(otl_var_list_size), master_stream_ptr_(nullptr) {} ~otl_select_struct_override() { delete[] col_ndx; delete[] col_type; delete[] col_size; } void set_master_stream_ptr(void *stream_ptr) { master_stream_ptr_ = stream_ptr; } OTL_NODISCARD void *get_master_stream_ptr() { return master_stream_ptr_; } void reset(void) { len = 0; all_mask = 0; lob_stream_mode = false; } void add_override(const int andx, const int atype, const int asize = 0) { if (len == container_size_) { unsigned int temp_container_size = OTL_SCAST(unsigned int, container_size_); container_size_ *= 2; short int *temp_col_ndx = nullptr; short int *temp_col_type = nullptr; int *temp_col_size = nullptr; try { temp_col_ndx = new short int[OTL_SCAST(size_t,container_size_)]; temp_col_type = new short int[OTL_SCAST(size_t,container_size_)]; temp_col_size = new int[OTL_SCAST(size_t,container_size_)]; } catch (const std::bad_alloc &) { delete[] temp_col_ndx; delete[] temp_col_type; delete[] temp_col_size; throw; } memcpy(temp_col_ndx, col_ndx, sizeof(short int) * temp_container_size); memcpy(temp_col_type, col_type, sizeof(short int) * temp_container_size); memcpy(temp_col_size, col_size, sizeof(int) * temp_container_size); delete[] col_ndx; delete[] col_type; delete[] col_size; col_ndx = temp_col_ndx; col_type = temp_col_type; col_size = temp_col_size; } ++len; col_ndx[len - 1] = OTL_SCAST(short, andx); col_type[len - 1] = OTL_SCAST(short, atype); col_size[len - 1] = asize; } OTL_NODISCARD int find(const int ndx) const { int i; for (i = 0; i < len; ++i) if (ndx == col_ndx[i]) return i; return -1; } void set_all_column_types(const unsigned int amask = 0) { all_mask = amask; } OTL_NODISCARD int getLen(void) const { return len; } OTL_NODISCARD unsigned int get_all_mask() const { return all_mask; } OTL_NODISCARD short int get_col_type(int ndx) const { return col_type[ndx]; } OTL_NODISCARD int get_col_size(int ndx) const { return col_size[ndx]; } void setLen(const int alen) { len = alen; } OTL_NODISCARD bool get_lob_stream_mode() const { return lob_stream_mode; } void set_lob_stream_mode(const bool alobs_tream_mode) { lob_stream_mode = alobs_tream_mode; } private: short int *col_ndx; short int *col_type; int *col_size; int len; unsigned int all_mask; bool lob_stream_mode; int container_size_; void *master_stream_ptr_; #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_select_struct_override(const otl_select_struct_override &) = delete; otl_select_struct_override &operator=(const otl_select_struct_override &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_select_struct_override(otl_select_struct_override &&) = delete; otl_select_struct_override &operator=(otl_select_struct_override &&) = delete; #endif private: #else otl_select_struct_override(const otl_select_struct_override &) : col_ndx(nullptr), col_type(nullptr), col_size(nullptr), len(0), all_mask(0), lob_stream_mode(false), container_size_(0), master_stream_ptr_(nullptr) {} otl_select_struct_override &operator=(const otl_select_struct_override &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_select_struct_override(otl_select_struct_override &&) : col_ndx(nullptr), col_type(nullptr), col_size(nullptr), len(0), all_mask(0), lob_stream_mode(false), container_size_(0), master_stream_ptr_(nullptr) {} otl_select_struct_override &operator=(otl_select_struct_override &&) { return *this; } #endif #endif }; OTL_NODISCARD inline int otl_decimal_degree(unsigned int num) { int n = 0; while (num != 0) { ++n; num /= 10; } return n; } OTL_NODISCARD inline bool otl_isspace(char c) { return c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '\f' || c == '\v'; } OTL_NODISCARD inline char otl_to_upper(char c) { return OTL_SCAST(char, toupper(c)); } OTL_NODISCARD inline bool otl_str_case_insensitive_equal(const char *s1, const char *s2) { while (*s1 && *s2) { if (otl_to_upper(*s1) != otl_to_upper(*s2)) return false; ++s1; ++s2; } if (*s1 == 0 && *s2 == 0) return true; else return false; } OTL_NODISCARD inline unsigned int otl_to_fraction(unsigned int fraction, int frac_prec) { if (fraction == 0 || frac_prec == 0) return fraction; int fraction_degree = otl_decimal_degree(fraction); if (fraction_degree > frac_prec) { // in case if the actual fraction value is beyond the "fraction // precision" range, truncate the value int excess_decimal_digits = fraction_degree - frac_prec; for (int iter = 1; iter <= excess_decimal_digits; ++iter) fraction /= 10; } int degree_diff = 9 - frac_prec; for (int i = 0; i < degree_diff; ++i) fraction *= 10; return fraction; } OTL_NODISCARD inline unsigned int otl_from_fraction(unsigned int fraction, int frac_prec) { if (fraction == 0 || frac_prec == 0) return fraction; int degree_diff = 9 - frac_prec; for (int i = 0; i < degree_diff; ++i) fraction /= 10; return fraction; } #define OTL_NO_STM_TEXT "#No Stm Text available#" #if (defined(OTL_ODBC) || defined(OTL_DB2_CLI)) && defined(OTL_ORA_UTF8) #if !defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) #define OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS #endif #endif class otl_datetime { public: int year; int month; int day; int hour; int minute; int second; unsigned long fraction; int frac_precision; #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) short int tz_hour; short int tz_minute; #endif otl_datetime() : year(1900), month(1), day(1), hour(0), minute(0), second(0), fraction(0), frac_precision(0) #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) , tz_hour(0), tz_minute(0) #endif { } otl_datetime(const int ayear, const int amonth, const int aday, const int ahour, const int aminute, const int asecond, const unsigned long afraction = 0, const int afrac_precision = 0 #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) , const short int atz_hour = 0, const short int atz_minute = 0 #endif ) : year(ayear), month(amonth), day(aday), hour(ahour), minute(aminute), second(asecond), fraction(afraction), frac_precision(afrac_precision) #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) , tz_hour(atz_hour), tz_minute(atz_minute) #endif { } otl_datetime(const otl_datetime &dt) : year(dt.year), month(dt.month), day(dt.day), hour(dt.hour), minute(dt.minute), second(dt.second), fraction(dt.fraction), frac_precision(dt.frac_precision) #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) , tz_hour(dt.tz_hour), tz_minute(dt.tz_minute) #endif { } ~otl_datetime() {} otl_datetime &operator=(const otl_datetime &dt) { copy(dt); return *this; } private: void copy(const otl_datetime &dt) { year = dt.year; month = dt.month; day = dt.day; hour = dt.hour; minute = dt.minute; second = dt.second; fraction = dt.fraction; frac_precision = dt.frac_precision; #if defined(OTL_ORA_TIMESTAMP) || defined(OTL_ODBC_TIME_ZONE) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) tz_hour = dt.tz_hour; tz_minute = dt.tz_minute; #endif } }; struct otl_oracle_date { unsigned char century; unsigned char year; unsigned char month; unsigned char day; unsigned char hour; unsigned char minute; unsigned char second; otl_oracle_date() : century(0), year(0), month(0), day(0), hour(0), minute(0), second(0) {} otl_oracle_date& operator=(const otl_oracle_date& that){ century=that.century; year=that.year; month=that.month; day=that.day; hour=that.hour; minute=that.minute; second=that.second; return *this; } ~otl_oracle_date() {} }; inline void convert_date(otl_datetime &t, const otl_oracle_date &s) { t.year = (OTL_SCAST(int, s.century - 100) * 100 + (OTL_SCAST(int, s.year - 100))); t.month = s.month; t.day = s.day; t.hour = s.hour - 1; t.minute = s.minute - 1; t.second = s.second - 1; } inline void convert_date(otl_oracle_date &t, const otl_datetime &s) { t.year = OTL_SCAST(unsigned char, ((s.year % 100) + 100)); t.century = OTL_SCAST(unsigned char, ((s.year / 100) + 100)); t.month = OTL_SCAST(unsigned char, s.month); t.day = OTL_SCAST(unsigned char, s.day); t.hour = OTL_SCAST(unsigned char, (s.hour + 1)); t.minute = OTL_SCAST(unsigned char, (s.minute + 1)); t.second = OTL_SCAST(unsigned char, (s.second + 1)); } class otl_null { public: #if defined(OTL_CPP_11_ON) otl_null() = default; ~otl_null() = default; otl_null(const otl_null&) = default; otl_null(otl_null&&) = default; otl_null& operator=(const otl_null&) = default; otl_null& operator=(otl_null&&) = default; #else otl_null() {} ~otl_null() {} otl_null(const otl_null&){} #endif }; #if defined(OTL_CPP_11_ON) #define OTL_NULL_PARM otl_null #else #define OTL_NULL_PARM const otl_null & #endif #if defined(OTL_ORA_SDO_GEOMETRY) struct OCIType; #endif class otl_column_desc { public: char *name; int dbtype; int otl_var_dbtype; #if defined(_WIN64) __int64 dbsize; #else int dbsize; #endif int scale; #if defined(_WIN64) __int64 prec; #else int prec; #endif int nullok; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) int charset_form; int char_size; #endif #if defined(OTL_ORA_SDO_GEOMETRY) char *name_type; OCIType *colOCIType; #endif private: #if defined(OTL_ORA_SDO_GEOMETRY) int name_type_len_; #endif int name_len_; public: otl_column_desc() : name(nullptr), dbtype(0), otl_var_dbtype(0), dbsize(0), scale(0), prec(0), nullok(0), #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) charset_form(0), char_size(0), #endif #if defined(OTL_ORA_SDO_GEOMETRY) name_type(nullptr), colOCIType(nullptr), name_type_len_(0), #endif name_len_(0) { } ~otl_column_desc() { if(name)delete[] name; #if defined(OTL_ORA_SDO_GEOMETRY) if(name_type)delete[] name_type; #endif } #if defined(_MSC_VER) && (_MSC_VER>=1900) #pragma warning(push) #pragma warning(disable : 6387) #endif otl_column_desc &operator=(const otl_column_desc &desc) { if (name_len_ >= desc.name_len_) OTL_STRCPY_S(name, name_len_, desc.name); else if (name == nullptr && desc.name != nullptr) { name = new char[OTL_SCAST(size_t,desc.name_len_)]; name_len_ = desc.name_len_; OTL_STRCPY_S(name, name_len_, desc.name); } else if (name_len_ < desc.name_len_ && desc.name != nullptr) { delete[] name; name = new char[OTL_SCAST(size_t,desc.name_len_)]; name_len_ = desc.name_len_; OTL_STRCPY_S(name, name_len_, desc.name); } dbtype = desc.dbtype; otl_var_dbtype = desc.otl_var_dbtype; dbsize = desc.dbsize; scale = desc.scale; prec = desc.prec; nullok = desc.nullok; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) charset_form = desc.charset_form; char_size = desc.char_size; #endif #if defined(OTL_ORA_SDO_GEOMETRY) if(name_type_len_ >= desc.name_type_len_ && name_type) OTL_STRCPY_S(name_type, name_type_len_, desc.name); else if(name_type == nullptr && desc.name_type != nullptr){ name_type = new char[OTL_SCAST(size_t, desc.name_type_len_)]; name_type_len_ = desc.name_type_len_; OTL_STRCPY_S(name_type, name_type_len_, desc.name_type); }else if(name_type_len_ < desc.name_type_len_ && desc.name_type != nullptr){ delete[] name_type; name_type = new char[OTL_SCAST(size_t, desc.name_type_len_)]; name_type_len_ = desc.name_type_len_; OTL_STRCPY_S(name_type, name_type_len_, desc.name_type); } colOCIType = desc.colOCIType; #endif return *this; } #if defined(_MSC_VER) && (_MSC_VER>=1900) #pragma warning(pop) #endif otl_column_desc(const otl_column_desc &desc) : name(nullptr), dbtype(desc.dbtype), otl_var_dbtype(0), dbsize(desc.dbsize), scale(desc.scale), prec(desc.prec), nullok(desc.nullok), #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) charset_form(desc.charset_form), char_size(desc.char_size), #endif #if defined(OTL_ORA_SDO_GEOMETRY) colOCIType(desc.colOCIType), name_type_len_(desc.name_type_len_), #endif name_len_(desc.name_len_) { if (desc.name != nullptr) { name = new char[OTL_SCAST(size_t,desc.name_len_)]; OTL_STRCPY_S(name, name_len_, desc.name); } #if defined(OTL_ORA_SDO_GEOMETRY) if(desc.name_type != nullptr){ name_type = new char[OTL_SCAST(size_t, desc.name_type_len_)]; OTL_STRCPY_S(name_type, name_type_len_, desc.name_type); } #endif } #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) otl_column_desc &operator=(otl_column_desc &&desc) OTL_ANSI_CPP_11_NOEXCEPT { if (name != nullptr) delete[] name; name = desc.name; name_len_ = desc.name_len_; desc.name = nullptr; desc.name_len_ = 0; dbtype = desc.dbtype; otl_var_dbtype = desc.otl_var_dbtype; dbsize = desc.dbsize; scale = desc.scale; prec = desc.prec; nullok = desc.nullok; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) charset_form = desc.charset_form; char_size = desc.char_size; #endif #if defined(OTL_ORA_SDO_GEOMETRY) name_type = desc.name_type; name_type_len_ = desc.name_type_len_; desc.name_type = nullptr; desc.name_type_len_ = 0; colOCIType = desc.colOCIType; #endif return *this; } otl_column_desc(otl_column_desc &&desc) OTL_ANSI_CPP_11_NOEXCEPT : name(desc.name), dbtype(desc.dbtype), otl_var_dbtype(0), dbsize(desc.dbsize), scale(desc.scale), prec(desc.prec), nullok(desc.nullok), #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) || \ defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) charset_form(desc.charset_form), char_size(desc.char_size), #endif #if defined(OTL_ORA_SDO_GEOMETRY) name_type(desc.name_type), colOCIType(desc.colOCIType), name_type_len_(desc.name_type_len_), #endif name_len_(desc.name_len_) { desc.name = nullptr; desc.name_len_ = 0; #if defined(OTL_ORA_SDO_GEOMETRY) desc.name_type = nullptr; desc.name_type_len_ = 0; #endif } #endif void set_name(const char *aname, const int aname_len = 0) { int len; if (aname_len == 0) len = OTL_SCAST(int, strlen(aname)) + 1; else len = aname_len + 1; if (name_len_ < len) { if (name) delete[] name; name = new char[OTL_SCAST(size_t,len)]; name_len_ = len; for (int i = 0; i < len - 1; ++i) name[i] = aname[i]; name[len - 1] = 0; } } #if defined(OTL_ORA_SDO_GEOMETRY) void set_name_type(const char *aname, const int aname_len = 0){ int len; if(aname_len == 0) len = OTL_SCAST(int, strlen(aname)) + 1; else len = aname_len + 1; if(name_type_len_ < len){ if(name_type)delete[] name_type; name_type = new char[OTL_SCAST(size_t, len)]; name_type_len_ = len; for(int i = 0; i < len - 1; ++i) name_type[i] = aname[i]; name_type[len - 1] = 0; } } #endif }; class otl_var_desc { public: int param_type; int ftype; int elem_size; int array_size; int pos; int name_pos; char name[128]; int pl_tab_flag; otl_var_desc() : param_type(0), ftype(0), elem_size(0), array_size(0), pos(0), name_pos(0), name(), pl_tab_flag(0) { name[0] = 0; } ~otl_var_desc() {} void copy_name(const char *nm) { if (!nm) name[0] = 0; else { #if defined(_MSC_VER) #if (_MSC_VER >= 1400) OTL_STRNCPY_S(name, sizeof(name), nm, sizeof(name) - 1); name[sizeof(name) - 1] = 0; #else strncpy(name, nm, sizeof(name)); name[sizeof(name) - 1] = 0; #endif #else strncpy(name, nm, sizeof(name)); name[sizeof(name) - 1] = 0; #endif } } void set_param_type(const int aparam_type){ this->param_type=aparam_type; } }; #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED) enum otl_var_enum : unsigned char { otl_var_none = 0, otl_var_char = 1, otl_var_double = 2, otl_var_float = 3, otl_var_int = 4, otl_var_unsigned_int = 5, otl_var_short = 6, otl_var_long_int = 7, otl_var_timestamp = 8, otl_var_varchar_long = 9, otl_var_raw_long = 10, otl_var_clob = 11, otl_var_blob = 12, otl_var_refcur = 13, otl_var_long_string = 15, otl_var_db2time = 16, otl_var_db2date = 17, otl_var_tz_timestamp = 18, otl_var_ltz_timestamp = 19, otl_var_bigint = 20, #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) otl_var_nchar = 21, otl_var_nclob = 22, #else #endif otl_var_raw = 23, #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) otl_var_numeric_type_1 = 24, #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) otl_var_numeric_type_2 = 25, #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) otl_var_numeric_type_3 = 26, #endif otl_var_ubigint = 27, otl_var_bfloat = 28, otl_var_bdouble = 29, otl_var_lob_stream = 100 #if defined(OTL_ORA_SDO_GEOMETRY) ,otl_var_sdo_geometry = 101 #endif }; #else typedef unsigned char otl_var_enum; const otl_var_enum otl_var_none = 0; const otl_var_enum otl_var_char = 1; const otl_var_enum otl_var_double = 2; const otl_var_enum otl_var_float = 3; const otl_var_enum otl_var_int = 4; const otl_var_enum otl_var_unsigned_int = 5; const otl_var_enum otl_var_short = 6; const otl_var_enum otl_var_long_int = 7; const otl_var_enum otl_var_timestamp = 8; const otl_var_enum otl_var_varchar_long = 9; const otl_var_enum otl_var_raw_long = 10; const otl_var_enum otl_var_clob = 11; const otl_var_enum otl_var_blob = 12; const otl_var_enum otl_var_refcur = 13; const otl_var_enum otl_var_long_string = 15; const otl_var_enum otl_var_db2time = 16; const otl_var_enum otl_var_db2date = 17; const otl_var_enum otl_var_tz_timestamp = 18; const otl_var_enum otl_var_ltz_timestamp = 19; const otl_var_enum otl_var_bigint = 20; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) const otl_var_enum otl_var_nchar = 21; const otl_var_enum otl_var_nclob = 22; #else #endif const otl_var_enum otl_var_raw = 23; #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) const otl_var_enum otl_var_numeric_type_1 = 24; #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) const otl_var_enum otl_var_numeric_type_2 = 25; #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) const otl_var_enum otl_var_numeric_type_3 = 26; #endif const otl_var_enum otl_var_ubigint = 27; const otl_var_enum otl_var_bfloat = 28; const otl_var_enum otl_var_bdouble = 29; const otl_var_enum otl_var_lob_stream = 100; #if defined(OTL_ORA_SDO_GEOMETRY) const otl_var_enum otl_var_sdo_geometry = 101; #endif #endif const int otl_bigint_str_size = 40; const int otl_ubigint_str_size = 40; #if defined(OTL_NUMERIC_TYPE_1_STR_SIZE) const int otl_numeric_type_1_str_size = OTL_NUMERIC_TYPE_1_STR_SIZE; #else const int otl_numeric_type_1_str_size = 60; #endif #if defined(OTL_NUMERIC_TYPE_2_STR_SIZE) const int otl_numeric_type_2_str_size = OTL_NUMERIC_TYPE_2_STR_SIZE; #else const int otl_numeric_type_2_str_size = 60; #endif #if defined(OTL_NUMERIC_TYPE_3_STR_SIZE) const int otl_numeric_type_3_str_size = OTL_NUMERIC_TYPE_3_STR_SIZE; #else const int otl_numeric_type_3_str_size = 60; #endif typedef unsigned char otl_sql_exec_from_enum; const otl_sql_exec_from_enum otl_sql_exec_from_cursor_class = 0; const otl_sql_exec_from_enum otl_sql_exec_from_select_cursor_class = 1; #if defined(OTL_STREAM_WITH_STD_VARIANT_ON) && defined(OTL_CPP_17_ON) #include #include template struct otl_convert_type_to_code_helper{ static int convert(){ using currType=typename std::variant_alternative::type; if constexpr(std::is_same_v) return otl_var_int; if constexpr(std::is_same_v) return otl_var_double; if constexpr(std::is_same_v) return otl_var_float; if constexpr(std::is_same_v) return otl_var_unsigned_int; if constexpr(std::is_same_v) return otl_var_short; if constexpr(std::is_same_v) return otl_var_long_int; if constexpr(std::is_same_v) return otl_var_timestamp; #if defined(OTL_BIGINT) if constexpr(std::is_same_v) return otl_var_bigint; #endif #if defined(OTL_UBIGINT) if constexpr(std::is_same_v) return otl_var_ubigint; #endif } }; template struct otl_variant_helper{ static void write(streamType& s, const Variant& v, bool& value_written){ otl_variant_helper::write(s,v,value_written); if(value_written)return; otl_var_desc* vd=s.describe_next_in_var(); if(vd && vd->ftype==otl_convert_type_to_code_helper::convert() && v.index()==N-1){ // write the value only when the bind variable is of the same // type and when the variant's currently held alternative's index // is N-1 s<(v); value_written=true; } } static void read(streamType& s, Variant& v, bool& value_read){ otl_variant_helper::read(s,v,value_read); if(value_read)return; otl_var_desc* vd=s.describe_next_out_var(); if(vd && vd->ftype==otl_convert_type_to_code_helper::convert()){ using currType=typename std::variant_alternative::type; currType val; s>>val; v=val; value_read=true; } } }; template struct otl_variant_helper{ static void write(streamType& s, const Variant& v, bool& value_written) { value_written=false; otl_var_desc* vd=s.describe_next_in_var(); if(vd && vd->ftype==otl_convert_type_to_code_helper<0,Variant>::convert() && v.index()==0){ // write the value only when the bind variable is of the same // type and when the variant's currently held alternative's // index is 0 s<(v); value_written=true; } } static void read(streamType& s, Variant& v, bool& value_read) { value_read=false; otl_var_desc* vd=s.describe_next_out_var(); if(vd && vd->ftype==otl_convert_type_to_code_helper<0,Variant>::convert()){ using currType=typename std::variant_alternative<0,Variant>::type; currType val; s>>val; v=val; value_read=true; } } }; #endif class otl_long_string { public: unsigned char *v; otl_long_string(const int buffer_size = otl_short_int_max, const int input_length = 0) : v(nullptr), length(0), extern_buffer_flag(0), buf_size(0), this_is_last_piece_(false), unicode_flag_(false) { this_is_last_piece_ = false; if (buffer_size == 0) { v = nullptr; length = 0; extern_buffer_flag = 0; } else { extern_buffer_flag = 0; length = input_length; buf_size = buffer_size; v = new unsigned char[OTL_SCAST(size_t,buffer_size + 1)]; memset(v, 0, OTL_SCAST(unsigned int, buffer_size+1)); } } otl_long_string(const void *external_buffer, const int buffer_size, const int input_length = 0) : v(OTL_RCAST(unsigned char *, OTL_CCAST(void *, external_buffer))), length(input_length), extern_buffer_flag(1), buf_size(buffer_size), this_is_last_piece_(false), unicode_flag_(false) {} otl_long_string &operator=(const otl_long_string &s) { this_is_last_piece_ = s.this_is_last_piece_; if (s.extern_buffer_flag) { if (!extern_buffer_flag) delete[] v; v = s.v; length = s.length; extern_buffer_flag = s.extern_buffer_flag; buf_size = s.buf_size; } else { if (extern_buffer_flag) { v = new unsigned char[OTL_SCAST(size_t,s.buf_size + 1)]; buf_size = s.buf_size; } else if (buf_size < s.buf_size) { delete[] v; v = new unsigned char[OTL_SCAST(size_t,s.buf_size + 1)]; buf_size = s.buf_size; } length = s.length; extern_buffer_flag = s.extern_buffer_flag; memcpy(v, s.v, OTL_SCAST(unsigned int, length)); if (length < buf_size && s.v[length] == 0) v[length] = 0; } return *this; } otl_long_string(const otl_long_string &s) : v(nullptr), length(s.length), extern_buffer_flag(s.extern_buffer_flag), buf_size(s.buf_size), this_is_last_piece_(s.this_is_last_piece_), unicode_flag_(false) { if (s.extern_buffer_flag) v = s.v; else { v = new unsigned char[OTL_SCAST(size_t,buf_size + 1)]; memcpy(v, s.v, OTL_SCAST(unsigned int, length)); if (length < buf_size && s.v[length] == 0) v[length] = 0; } } #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) otl_long_string &operator=(otl_long_string &&s) OTL_ANSI_CPP_11_NOEXCEPT { if (!extern_buffer_flag) delete[] v; this_is_last_piece_ = s.this_is_last_piece_; length = s.length; extern_buffer_flag = s.extern_buffer_flag; buf_size=s.buf_size; v = s.v; s.v = nullptr; s.length = 0; s.buf_size = 0; return *this; } otl_long_string(otl_long_string &&s) OTL_ANSI_CPP_11_NOEXCEPT : v(s.v), length(s.length), extern_buffer_flag(s.extern_buffer_flag), buf_size(s.buf_size), this_is_last_piece_(s.this_is_last_piece_), unicode_flag_(false) { s.v = nullptr; s.length = 0; s.buf_size = 0; } #endif virtual ~otl_long_string() { if (!extern_buffer_flag) delete[] v; } void set_len(const int alen = 0) { length = alen; } int len(void) const { return length; } void set_last_piece(const bool this_is_last_piece = false) { this_is_last_piece_ = this_is_last_piece; } bool is_last_piece() const { return this_is_last_piece_; } unsigned char &operator[](int ndx) { return v[ndx]; } const unsigned char &operator[](int ndx) const { return v[ndx]; } virtual void null_terminate_string(const int alen) { (*this)[alen] = 0; } int get_buf_size() const { return buf_size; } int get_extern_buffer_flag() const { return extern_buffer_flag; } bool get_unicode_flag() const { return unicode_flag_; } protected: int length; int extern_buffer_flag; int buf_size; bool this_is_last_piece_; bool unicode_flag_; }; #if defined(OTL_UNICODE) class otl_long_unicode_string : public otl_long_string { public: otl_long_unicode_string(const int buffer_size = otl_short_int_max, const int input_length = 0) : otl_long_string(0, 0) { unicode_flag_ = true; extern_buffer_flag = 0; length = input_length; buf_size = buffer_size; v = new unsigned char [OTL_SCAST(size_t, buffer_size + 1) * sizeof(OTL_WCHAR)]; memset(v, 0, OTL_SCAST(size_t, buffer_size) * sizeof(OTL_WCHAR)); } otl_long_unicode_string(const void *external_buffer, const int buffer_size, const int input_length = 0) : otl_long_string(external_buffer, buffer_size, input_length) { unicode_flag_ = true; extern_buffer_flag = 1; length = input_length; buf_size = buffer_size; v = OTL_RCAST(unsigned char *, OTL_CCAST(void *, external_buffer)); } otl_long_unicode_string(const otl_long_unicode_string &s) : otl_long_string(0, 0) { this->unicode_flag_ = true; this->buf_size = s.buf_size; this->this_is_last_piece_ = s.this_is_last_piece_; this->extern_buffer_flag = s.extern_buffer_flag; this->v = nullptr; this->length = s.length; if (s.extern_buffer_flag) v = s.v; else { v = new unsigned char [OTL_SCAST(size_t, buf_size + 1) * sizeof(OTL_WCHAR)]; memcpy(v, s.v, OTL_SCAST(size_t, length) * sizeof(OTL_WCHAR)); if (length < buf_size && s.v[length] == 0) (*this)[length] = 0; } } otl_long_unicode_string &operator=(const otl_long_unicode_string &s) { this_is_last_piece_ = s.this_is_last_piece_; if (s.extern_buffer_flag) { if (!extern_buffer_flag) delete[] v; v = s.v; length = s.length; extern_buffer_flag = s.extern_buffer_flag; buf_size = s.buf_size; } else { if (extern_buffer_flag) { v = new unsigned char [OTL_SCAST(size_t, s.buf_size + 1) * sizeof(OTL_WCHAR)]; buf_size = s.buf_size; } else if (buf_size < s.buf_size) { delete[] v; v = new unsigned char [OTL_SCAST(size_t, s.buf_size + 1) * sizeof(OTL_WCHAR)]; buf_size = s.buf_size; } length = s.length; extern_buffer_flag = s.extern_buffer_flag; memcpy(v, s.v, OTL_SCAST(size_t, length) * sizeof(OTL_WCHAR)); if (length < buf_size && s.v[length] == 0) (*this)[length] = 0; } return *this; } #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) otl_long_unicode_string(otl_long_unicode_string &&s) OTL_ANSI_CPP_11_NOEXCEPT : otl_long_string(0, 0) { unicode_flag_ = true; buf_size = s.buf_size; this_is_last_piece_ = s.this_is_last_piece_; extern_buffer_flag = s.extern_buffer_flag; length = s.length; v = s.v; s.v = nullptr; s.buf_size = 0; s.length = 0; } otl_long_unicode_string & operator=(otl_long_unicode_string &&s) OTL_ANSI_CPP_11_NOEXCEPT { this_is_last_piece_ = s.this_is_last_piece_; if (!extern_buffer_flag) delete[] v; v = s.v; length = s.length; extern_buffer_flag = s.extern_buffer_flag; buf_size = s.buf_size; s.v = nullptr; s.buf_size = 0; s.length = 0; return *this; } #endif virtual ~otl_long_unicode_string() {} OTL_CHAR &operator[](int ndx) { return OTL_RCAST(OTL_CHAR *, v)[ndx]; } const OTL_CHAR &operator[](int ndx) const { return OTL_RCAST(OTL_CHAR *, v)[ndx]; } virtual void null_terminate_string(const int alen) { (*this)[alen] = 0; } }; #endif const int const_STD_CHAR_ARRAY_code=200; const int const_STD_UNICODE_CHAR_ARRAY_code=201; inline const char *otl_var_type_name(const int ftype) { const char *const_STD_CHAR_ARRAY = "std::array"; const char *const_STD_UNICODE_CHAR_ARRAY = "std::array"; const char *const_CHAR = "CHAR"; const char *const_DOUBLE = "DOUBLE"; const char *const_FLOAT = "FLOAT"; const char *const_BDOUBLE = "BINARY_DOUBLE"; const char *const_BFLOAT = "BINARY_FLOAT"; const char *const_INT = "INT"; const char *const_UNSIGNED_INT = "UNSIGNED INT"; const char *const_SHORT_INT = "SHORT INT"; const char *const_LONG_INT = "LONG INT"; const char *const_TIMESTAMP = "TIMESTAMP"; const char *const_DB2DATE = "DB2DATE"; const char *const_DB2TIME = "DB2TIME"; const char *const_TZ_TIMESTAMP = "TIMESTAMP WITH TIME ZONE"; const char *const_LTZ_TIMESTAMP = "TIMESTAMP WITH LOCAL TIME ZONE"; const char *const_BIGINT = "BIGINT"; const char *const_UBIGINT = "UBIGINT"; const char *const_VARCHAR_LONG = "VARCHAR LONG"; const char *const_RAW_LONG = "RAW LONG"; const char *const_CLOB = "CLOB"; const char *const_BLOB = "BLOB"; const char *const_RAW = "RAW"; const char *const_UNKNOWN = "UNKNOWN"; const char *const_LONG_STRING = "otl_long_string()"; const char *const_LOB_STREAM = "otl_lob_stream*&"; const char *const_USER_DEFINED = "User-defined type (object type, VARRAY, Nested Table)"; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) const char *const_NCHAR = "NCHAR"; const char *const_NCLOB = "NCLOB"; #endif switch (ftype) { #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) case otl_var_nchar: return const_NCHAR; case otl_var_nclob: return const_NCLOB; #endif case otl_var_char: return const_CHAR; case otl_var_double: return const_DOUBLE; case otl_var_float: return const_FLOAT; case otl_var_bfloat: return const_BFLOAT; case otl_var_bdouble: return const_BDOUBLE; case otl_var_int: return const_INT; case otl_var_unsigned_int: return const_UNSIGNED_INT; case otl_var_short: return const_SHORT_INT; case otl_var_long_int: return const_LONG_INT; case otl_var_timestamp: return const_TIMESTAMP; case otl_var_db2date: return const_DB2DATE; case otl_var_db2time: return const_DB2TIME; case otl_var_tz_timestamp: return const_TZ_TIMESTAMP; case otl_var_ltz_timestamp: return const_LTZ_TIMESTAMP; case otl_var_bigint: return const_BIGINT; case otl_var_ubigint: return const_UBIGINT; case otl_var_varchar_long: return const_VARCHAR_LONG; case otl_var_raw_long: return const_RAW_LONG; case otl_var_clob: return const_CLOB; case otl_var_blob: return const_BLOB; case otl_var_raw: return const_RAW; case otl_var_long_string: return const_LONG_STRING; case otl_var_lob_stream: return const_LOB_STREAM; case 108: return const_USER_DEFINED; case const_STD_CHAR_ARRAY_code: return const_STD_CHAR_ARRAY; case const_STD_UNICODE_CHAR_ARRAY_code: return const_STD_UNICODE_CHAR_ARRAY; default: return const_UNKNOWN; } } inline void otl_var_info_var(const char *name, const int ftype, const int type_code, char *var_info, const size_t var_info_sz) { char buf1[128]; char buf2[128]; OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype)); OTL_STRCPY_S(buf2, sizeof(buf2), otl_var_type_name(type_code)); OTL_STRCPY_S(var_info, var_info_sz, "Variable: "); OTL_STRCAT_S(var_info, var_info_sz, name); OTL_STRCAT_S(var_info, var_info_sz, "<"); OTL_STRCAT_S(var_info, var_info_sz, buf1); OTL_STRCAT_S(var_info, var_info_sz, ">, datatype in operator <>: "); OTL_STRCAT_S(var_info, var_info_sz, buf2); } inline void otl_var_info_var2(const char *name, const int ftype, char *var_info, const size_t var_info_sz) { char buf1[128]; OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype)); OTL_STRCPY_S(var_info, var_info_sz, "Variable: "); OTL_STRCPY_S(var_info, var_info_sz, name); OTL_STRCAT_S(var_info, var_info_sz, "<"); OTL_STRCAT_S(var_info, var_info_sz, buf1); OTL_STRCAT_S(var_info, var_info_sz, ">"); } inline void otl_var_info_var3(const char *name, const int ftype, const int type_code, char *var_info, const size_t var_info_sz) { char buf1[128]; char buf2[128]; OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype)); OTL_STRCPY_S(buf2, sizeof(buf2), otl_var_type_name(type_code)); OTL_STRCPY_S(var_info, var_info_sz, "Variable: "); OTL_STRCAT_S(var_info, var_info_sz, name); OTL_STRCAT_S(var_info, var_info_sz, "<"); OTL_STRCAT_S(var_info, var_info_sz, buf1); OTL_STRCAT_S(var_info, var_info_sz, ">, datatype in otl_stream_read_iterator::get(): "); OTL_STRCAT_S(var_info, var_info_sz, buf2); } inline void otl_var_info_var4(const char *name, const int ftype, const int type_code, char *var_info, const size_t var_info_sz) { char buf1[128]; char buf2[128]; OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype)); OTL_STRCPY_S(buf2, sizeof(buf2), otl_var_type_name(type_code)); OTL_STRCPY_S(var_info, var_info_sz, "Variable: "); OTL_STRCAT_S(var_info, var_info_sz, name); OTL_STRCAT_S(var_info, var_info_sz, "<"); OTL_STRCAT_S(var_info, var_info_sz, buf1); OTL_STRCAT_S(var_info, var_info_sz, ">, datatype in otl_stream_read_iterator::get(): "); OTL_STRCAT_S(var_info, var_info_sz, buf2); } inline void otl_strcpy(unsigned char *trg, unsigned char *src, int &overflow, const int inp_size = 0, const int actual_inp_size = -1) { OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg); const OTL_CHAR *c2 = OTL_RCAST(const OTL_CHAR *, src); int out_size = 0; overflow = 0; if (actual_inp_size != -1) { while (out_size < inp_size - 1 && out_size < actual_inp_size) { *c1++ = *c2++; ++out_size; } *c1 = 0; if (out_size == inp_size - 1 && out_size < actual_inp_size) overflow = 1; } else { while (*c2 && out_size < inp_size - 1) { *c1++ = *c2++; ++out_size; } *c1 = 0; if (*c2 && out_size == inp_size - 1) overflow = 1; } } inline void otl_strcpy(unsigned char *trg, const unsigned char *src) { OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg); const OTL_CHAR *c2 = OTL_RCAST(const OTL_CHAR *, src); while (*c2) { *c1++ = *c2++; } *c1 = 0; } inline void otl_strcat(char *trg, const char *src) { while (*trg) ++trg; while (*src) { *trg = *src; ++trg; ++src; } *trg = 0; } #if defined(OTL_UNICODE) && !defined(OTL_ODBC) inline void otl_strcpy2(unsigned char *trg, const unsigned char *src, const int max_src_len) { OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg); const OTL_CHAR *c2 = OTL_RCAST(const OTL_CHAR *, src); int src_len = OTL_SCAST(int, *OTL_SCAST(const unsigned short *, c2)); int len = 0; ++c2; while (*c2 && len < max_src_len && len < src_len) { *c1++ = *c2++; ++len; } *c1 = 0; #else inline void otl_strcpy2(unsigned char *trg, const unsigned char *src, const int /* max_src_len */ ) { otl_strcpy(trg, src); #endif } #if defined(OTL_UNICODE) inline void otl_memcpy(unsigned char *trg, unsigned char *src, const int src_len, const int ftype) { if (ftype == otl_var_raw_long || ftype == otl_var_raw) { memcpy(trg, src, OTL_SCAST(size_t, src_len)); return; } OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg); OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src); int len = 0; while (len < src_len) { *c1++ = *c2++; ++len; } #else inline void otl_memcpy(unsigned char *trg, unsigned char *src, const int src_len, const int /* ftype */ ) { memcpy(trg, src, OTL_SCAST(unsigned int, src_len)); #endif } #if defined(OTL_UNICODE) && !defined(OTL_ODBC) inline void otl_strcpy3(unsigned char *trg, unsigned char *src, const int max_src_len, int &overflow, const int inp_size = 0) { OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg); OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src); int len = 0; int src_len = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c2)); ++c2; int out_size = 0; overflow = 0; while (len < src_len && len < max_src_len && out_size < inp_size - 1) { *c1++ = *c2++; ++out_size; ++len; } *c1 = 0; if (len < src_len && out_size == inp_size - 1) overflow = 1; #else inline void otl_strcpy3(unsigned char *trg, unsigned char *src, const int /* max_src_len */, int &overflow, const int inp_size = 0) { OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg); OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src); int out_size = 0; overflow = 0; while (*c2 && out_size < inp_size - 1) { *c1++ = *c2++; ++out_size; } *c1 = 0; if (*c2 && out_size == inp_size - 1) overflow = 1; #endif } inline void otl_strcpy4(unsigned char *trg, unsigned char *src, int &overflow, const int inp_size = 0, const int actual_inp_size = -1) { #if defined(OTL_UNICODE) && !defined(OTL_ODBC) OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg); OTL_CHAR *bc1 = c1; ++c1; OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src); int out_size = 0; overflow = 0; if (actual_inp_size != -1) { while (out_size < inp_size - 1 && out_size < actual_inp_size) { *c1++ = *c2++; ++out_size; } *OTL_RCAST(unsigned short *, bc1) = OTL_SCAST(unsigned short, out_size); if (out_size == inp_size - 1 && out_size < actual_inp_size) overflow = 1; } else { while (*c2 && out_size < inp_size - 1) { *c1++ = *c2++; ++out_size; } *OTL_RCAST(unsigned short *, bc1) = OTL_SCAST(unsigned short, out_size); if (*c2 && out_size == inp_size - 1) overflow = 1; } #else OTL_CHAR *c1 = OTL_RCAST(OTL_CHAR *, trg); OTL_CHAR *c2 = OTL_RCAST(OTL_CHAR *, src); int out_size = 0; overflow = 0; if (actual_inp_size != -1) { while (out_size < inp_size - 1 && out_size < actual_inp_size) { *c1++ = *c2++; ++out_size; } *c1 = 0; if (out_size == inp_size - 1 && out_size < actual_inp_size) overflow = 1; } else { while (*c2 && out_size < inp_size - 1) { *c1++ = *c2++; ++out_size; } *c1 = 0; if (*c2 && out_size == inp_size - 1) overflow = 1; } #endif } inline char *otl_itoa(int i, char *a) { const char *digits = "0123456789"; int n = i; int k; char buf[64]; char *c = buf; char *c1 = a; int klen = 0; char digit = ' '; bool negative = false; if (n < 0) { n = -n; negative = true; } do { if (n >= 10) k = n % 10; else k = n; digit = digits[k]; *c = digit; ++c; ++klen; n = n / 10; } while (n != 0); *c = 0; if (negative) { *c1 = '-'; ++c1; } for (int j = klen - 1; j >= 0; --j) { *c1 = buf[j]; ++c1; } *c1 = 0; return c1; } inline void otl_var_info_col(const int pos, const int ftype, const int type_code, char *var_info, const size_t var_info_sz) { char buf1[128]; char buf2[128]; char name[128]; otl_itoa(pos, name); OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype)); OTL_STRCPY_S(buf2, sizeof(buf2), otl_var_type_name(type_code)); OTL_STRCPY_S(var_info, var_info_sz, "Column: "); OTL_STRCAT_S(var_info, var_info_sz, name); OTL_STRCAT_S(var_info, var_info_sz, "<"); OTL_STRCAT_S(var_info, var_info_sz, buf1); OTL_STRCAT_S(var_info, var_info_sz, ">, datatype in operator <>: "); OTL_STRCAT_S(var_info, var_info_sz, buf2); } inline void otl_var_info_col2(const int pos, const int ftype, char *var_info, const size_t var_info_sz) { char buf1[128]; char name[128]; otl_itoa(pos, name); OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype)); OTL_STRCPY_S(var_info, var_info_sz, "Column: "); OTL_STRCAT_S(var_info, var_info_sz, name); OTL_STRCAT_S(var_info, var_info_sz, "<"); OTL_STRCAT_S(var_info, var_info_sz, buf1); OTL_STRCAT_S(var_info, var_info_sz, ">"); } inline void otl_var_info_col3(const int pos, const int ftype, const char *col_name, char *var_info, const size_t var_info_sz) { char buf1[128]; char name[128]; otl_itoa(pos, name); OTL_STRCPY_S(buf1, sizeof(buf1), otl_var_type_name(ftype)); OTL_STRCPY_S(var_info, var_info_sz, "Column: "); OTL_STRCAT_S(var_info, var_info_sz, name); OTL_STRCAT_S(var_info, var_info_sz, " / "); OTL_STRCAT_S(var_info, var_info_sz, col_name); OTL_STRCAT_S(var_info, var_info_sz, " <"); OTL_STRCAT_S(var_info, var_info_sz, buf1); OTL_STRCAT_S(var_info, var_info_sz, ">"); } class otl_pl_tab_generic { public: otl_pl_tab_generic() : p_v(nullptr), p_null(nullptr), elem_size(0), tab_size(0), tab_len(0), vtype(0) {} virtual ~otl_pl_tab_generic() {} unsigned char *val(int ndx = 0) { return p_v + (ndx * elem_size); } int is_null(int ndx = 0) { return p_null[ndx] != 0; } void set_null(int ndx = 0) { p_null[ndx] = 1; } void set_non_null(int ndx = 0) { p_null[ndx] = 0; } void init_generic(void) { int i; memset(p_v, 0, OTL_SCAST(size_t, elem_size * tab_len)); for (i = 0; i < tab_len; ++i) p_null[i] = 0; } int len() { return tab_len; } void set_len(int new_len = 0) { tab_len = new_len; } int get_vtype() const { return vtype; } int get_elem_size() const { return elem_size; } int get_tab_size() const { return tab_size; } unsigned char *get_p_v() { return p_v; } protected: unsigned char *p_v; short *p_null; int elem_size; int tab_size; int tab_len; int vtype; private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_pl_tab_generic(const otl_pl_tab_generic &) = delete; otl_pl_tab_generic &operator=(const otl_pl_tab_generic &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_pl_tab_generic(otl_pl_tab_generic &&) = delete; otl_pl_tab_generic &operator=(otl_pl_tab_generic &&) = delete; #endif private: #else otl_pl_tab_generic(const otl_pl_tab_generic &) : p_v(nullptr), p_null(nullptr), elem_size(0), tab_size(0), tab_len(0), vtype(0) {} otl_pl_tab_generic &operator=(const otl_pl_tab_generic &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_pl_tab_generic(otl_pl_tab_generic &&) : p_v(nullptr), p_null(nullptr), elem_size(0), tab_size(0), tab_len(0), vtype(0) {} otl_pl_tab_generic &operator=(otl_pl_tab_generic &&) { return *this; } #endif #endif }; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) template inline int otl_numeric_convert_T(const int ftype, const void *val, T &n) { if (ftype == T_type) { n = *OTL_RCAST(T *, OTL_CCAST(void *, val)); return 1; } else return 0; } template inline int otl_numeric_convert_T2(const int ftype, const void *val, T &n) { int rc = 1; switch (ftype) { case otl_var_double: n = OTL_PCONV(T, double, val); break; case otl_var_short: n = OTL_PCONV(T, short, val); break; case otl_var_int: n = OTL_PCONV(T, int, val); break; case otl_var_unsigned_int: n = OTL_PCONV(T, unsigned int, val); break; case otl_var_long_int: n = OTL_PCONV(T, long int, val); break; case otl_var_float: n = OTL_PCONV(T, float, val); break; case otl_var_bfloat: n = OTL_PCONV(T, float, val); break; case otl_var_bdouble: n = OTL_PCONV(T, double, val); break; #if defined(OTL_BIGINT) case otl_var_bigint: n = OTL_PCONV(T, OTL_BIGINT, val); break; #endif #if defined(OTL_UBIGINT) case otl_var_ubigint: n = OTL_PCONV(T, OTL_UBIGINT, val); break; #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) && \ !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS) case otl_var_numeric_type_1: n = OTL_PCONV(T, OTL_NUMERIC_TYPE_1, val); break; #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \ !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS) case otl_var_numeric_type_2: n = OTL_PCONV(T, OTL_NUMERIC_TYPE_2, val); break; #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \ !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS) case otl_var_numeric_type_3: n = OTL_PCONV(T, OTL_NUMERIC_TYPE_3, val); break; #endif default: rc = 0; break; } return rc; } #else template inline int otl_numeric_convert_T(const int ftype, const void *val, T &n) { int rc = 1; switch (ftype) { case otl_var_double: n = OTL_PCONV(T, double, val); break; case otl_var_short: n = OTL_PCONV(T, short, val); break; case otl_var_int: n = OTL_PCONV(T, int, val); break; case otl_var_unsigned_int: n = OTL_PCONV(T, unsigned int, val); break; case otl_var_long_int: n = OTL_PCONV(T, long int, val); break; case otl_var_float: n = OTL_PCONV(T, float, val); break; case otl_var_bfloat: n = OTL_PCONV(T, float, val); break; case otl_var_bdouble: n = OTL_PCONV(T, double, val); break; #if defined(OTL_BIGINT) case otl_var_bigint: n = OTL_PCONV(T, OTL_BIGINT, val); break; #endif #if defined(OTL_UBIGINT) case otl_var_ubigint: n = OTL_PCONV(T, OTL_UBIGINT, val); break; #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) && \ !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS) case otl_var_numeric_type_1: n = OTL_PCONV(T, OTL_NUMERIC_TYPE_1, val); break; #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \ !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS) case otl_var_numeric_type_2: n = OTL_PCONV(T, OTL_NUMERIC_TYPE_2, val); break; #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \ !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS) case otl_var_numeric_type_3: n = OTL_PCONV(T, OTL_NUMERIC_TYPE_3, val); break; #endif default: rc = 0; break; } return rc; } #endif #if defined(OTL_STL) && defined(OTL_STREAM_POOLING_ON) class otl_ltstr { public: bool operator()(const OTL_STRING_CONTAINER &s1, const OTL_STRING_CONTAINER &s2) const { return strcmp(s1.c_str(), s2.c_str()) < 0; } }; const int otl_max_default_pool_size = 32; #endif #if defined(OTL_UNICODE_STRING_TYPE) && defined(OTL_STREAM_POOLING_ON) #include class otl_ltstr { public: bool operator()(const std::string &s1, const std::string &s2) const { return strcmp(s1.c_str(), s2.c_str()) < 0; } }; const int otl_max_default_pool_size = 32; #endif #if defined(OTL_ACE) const int otl_max_default_pool_size = 32; #endif class otl_stream_shell_generic { public: otl_stream_shell_generic() : should_delete(0) {} virtual ~otl_stream_shell_generic() OTL_THROWS_OTL_EXCEPTION2 {} int get_should_delete() const { return should_delete; } void set_should_delete(const int ashould_delete) { should_delete = ashould_delete; } protected: int should_delete; }; #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) #if defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE) #include #include #endif class otl_stream_pool; class otl_stream_pool_entry { public: friend class otl_stream_pool; #if defined(OTL_ACE) otl_tmpl_vector s; #elif defined(OTL_UNICODE_STRING_TYPE) std::vector s; #else STD_NAMESPACE_PREFIX vector s; #endif otl_stream_pool_entry() : s(), cnt(0) {} otl_stream_pool_entry(const otl_stream_pool_entry &sc) : s(), cnt(0) { copy(sc); } otl_stream_pool_entry &operator=(const otl_stream_pool_entry &sc) { copy(sc); return *this; } virtual ~otl_stream_pool_entry() {} int get_cnt() const { return cnt; } void set_cnt(const int acnt) { cnt = acnt; } private: int cnt; void copy(const otl_stream_pool_entry &sc) { s.clear(); #if defined(OTL_ACE) for (int i = 0; i < sc.s.size(); ++i) #else for (size_t i = 0; i < sc.s.size(); ++i) #endif s.push_back(sc.s[i]); cnt = sc.cnt; } }; class otl_stream_pool { public: typedef otl_stream_pool_entry cache_entry_type; #if defined(OTL_ACE) typedef ACE_RB_Tree, ACE_Null_Mutex> sc_type; typedef otl_tmpl_vector vec_type; typedef ACE_RB_Tree_Node ace_map_entry; #elif defined(OTL_UNICODE_STRING_TYPE) typedef std::map sc_type; typedef std::vector vec_type; #else typedef STD_NAMESPACE_PREFIX map sc_type; typedef STD_NAMESPACE_PREFIX vector vec_type; #endif protected: sc_type sc; bool pool_enabled_; int max_size; int size; public: otl_stream_pool() : sc(), pool_enabled_(true), max_size(otl_max_default_pool_size), size(0) {} void init(int amax_size = otl_max_default_pool_size) { if (size == 0 && max_size == 0) return; if (amax_size < 2) amax_size = 2; #if defined(OTL_ACE) sc_type::iterator elem0 = sc.begin(); sc_type::iterator elemN = sc.end(); for (sc_type::iterator i = elem0; i != elemN; ++i) { cache_entry_type &ce = (*i).item(); int sz = ce.s.size(); for (int j = 0; j < sz; ++j) { ce.s[j]->set_should_delete(1); delete ce.s[j]; ce.s[j] = nullptr; } ce.s.clear(); ce.cnt = 0; } sc.clear(); #else sc_type::iterator elem0 = sc.begin(); sc_type::iterator elemN = sc.end(); for (sc_type::iterator i = elem0; i != elemN; ++i) { cache_entry_type &ce = (*i).second; size_t sz = ce.s.size(); for (size_t j = 0; j < sz; ++j) { ce.s[j]->set_should_delete(1); delete ce.s[j]; ce.s[j] = nullptr; } ce.s.clear(); ce.set_cnt(0); } sc.clear(); #endif size = 0; max_size = amax_size; } #if defined(OTL_UNICODE_STRING_TYPE) otl_stream_shell_generic *find(const std::string &stmtxt) #else otl_stream_shell_generic *find(const OTL_STRING_CONTAINER &stmtxt) #endif { otl_stream_shell_generic *s; #if defined(OTL_ACE) ace_map_entry *ce = 0; int found = sc.find(stmtxt, ce); if (found == -1) return 0; // entry not found s = ce->item().s[ce->item().s.size() - 1]; ce->item().s.pop_back(); if (ce->item().s.size() == 0) { sc.unbind(ce); --size; } #else sc_type::iterator cur = sc.find(stmtxt); if (cur == sc.end()) return nullptr; // entry not found cache_entry_type &ce = (*cur).second; s = ce.s[ce.s.size() - 1]; ce.s.pop_back(); if (ce.s.size() == 0) { sc.erase(cur); --size; } #endif return s; } #if defined(OTL_UNICODE_STRING_TYPE) void remove(const otl_stream_shell_generic *s, const std::string &stmtxt) #else void remove(const otl_stream_shell_generic *s, const OTL_STRING_CONTAINER &stmtxt) #endif { #if defined(OTL_ACE) ace_map_entry *cur = 0; int found = sc.find(stmtxt, cur); if (found == -1) return; cache_entry_type &ce = (*cur).item(); for (int i = 0; i < ce.s.size(); ++i) if (ce.s[i] == s) { if (ce.s.size() > 1 && i != ce.s.size() - 1) { otl_stream_shell_generic *temp_s = ce.s[i]; ce.s[i] = ce.s[ce.s.size() - 1]; ce.s[ce.s.size() - 1] = temp_s; } ce.s.pop_back(); --size; return; } #else sc_type::iterator cur = sc.find(stmtxt); if (cur == sc.end()) return; cache_entry_type &ce = (*cur).second; vec_type::iterator bgn = ce.s.begin(); vec_type::iterator end = ce.s.end(); for (vec_type::iterator i = bgn; i != end; ++i) if ((*i) == s) { ce.s.erase(i); --size; return; } #endif } int get_max_size() const { return max_size; } void add(otl_stream_shell_generic *s, const char *stm_text) { #if defined(OTL_UNICODE_STRING_TYPE) std::string stmtxt(stm_text); #else OTL_STRING_CONTAINER stmtxt(stm_text); #endif #if defined(OTL_ACE) ace_map_entry *cur = 0; int found_in_map = sc.find(stmtxt, cur); if (found_in_map == 0) { // entry found bool found = false; cache_entry_type &ce = (*cur).item(); int sz = ce.s.size(); for (int i = 0; i < sz; ++i) { if (s == ce.s[i]) { found = true; break; } } if (!found) ce.s.push_back(s); ++ce.cnt; } else { // entry not found if (size < max_size - 1) { // add new entry cache_entry_type ce; ce.s.push_back(s); ce.cnt = 1; sc.bind(stmtxt, ce); ++size; } else { // erase the least used entry and add new one sc_type::iterator elem0 = sc.begin(); sc_type::iterator elemN = sc.end(); int min_cnt = 0; ace_map_entry *min_entry = 0; for (sc_type::iterator i = elem0; i != elemN; ++i) { if (i == elem0) { // first element min_entry = &(*i); min_cnt = (*i).item().cnt; } if (min_cnt > (*i).item().cnt) { // found less used entry min_entry = &(*i); min_cnt = (*i).item().cnt; } } cache_entry_type &me = (*min_entry).item(); int sz = me.s.size(); for (int n = 0; n < sz; ++n) { me.s[n]->set_should_delete(1); otl_stream_shell_generic *tmp = me.s[n]; delete tmp; } me.s.clear(); sc.unbind(min_entry); cache_entry_type ce; ce.cnt = 1; ce.s.push_back(s); sc.bind(stmtxt, ce); } } #else sc_type::iterator cur = sc.find(stmtxt); if (cur != sc.end()) { // entry found bool found = false; cache_entry_type &ce = (*cur).second; size_t sz = ce.s.size(); for (size_t i = 0; i < sz; ++i) { if (s == ce.s[i]) { found = true; break; } } if (!found) ce.s.push_back(s); ce.set_cnt(ce.get_cnt() + 1); } else { // entry not found if (size < max_size - 1) { // add new entry cache_entry_type ce; ce.s.push_back(s); ce.set_cnt(1); sc[stmtxt] = ce; ++size; } else { // erase the least used entry and add new one sc_type::iterator elem0 = sc.begin(); sc_type::iterator elemN = sc.end(); int min_cnt = 0; sc_type::iterator min_entry; for (sc_type::iterator i = elem0; i != elemN; ++i) { if (i == elem0) { // first element min_entry = i; min_cnt = (*i).second.get_cnt(); } if (min_cnt > (*i).second.get_cnt()) { // found less used entry min_entry = i; min_cnt = (*i).second.get_cnt(); } } cache_entry_type &me = (*min_entry).second; size_t sz = me.s.size(); for (size_t n = 0; n < sz; ++n) { me.s[n]->set_should_delete(1); otl_stream_shell_generic *tmp = me.s[n]; delete tmp; } me.s.clear(); sc.erase(min_entry); cache_entry_type ce; ce.set_cnt(1); ce.s.push_back(s); sc[stmtxt] = ce; } } #endif } virtual ~otl_stream_pool() OTL_THROWS_OTL_EXCEPTION4 { init(); } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_stream_pool(const otl_stream_pool &) = delete; otl_stream_pool &operator=(const otl_stream_pool &) = delete; #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) otl_stream_pool(otl_stream_pool &&) = delete; otl_stream_pool &operator=(otl_stream_pool &&) = delete; #endif private: #else otl_stream_pool(const otl_stream_pool &) : sc(), pool_enabled_(true), max_size(0), size(0) {} otl_stream_pool &operator=(const otl_stream_pool &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_stream_pool(otl_stream_pool &&) : sc(), pool_enabled_(true), max_size(0), size(0) {} otl_stream_pool &operator=(otl_stream_pool &&) { return *this; } #endif #endif }; #endif // =========================== COMMON TEMPLATES ============================ #if (defined(OTL_STL) || defined(OTL_VALUE_TEMPLATE_ON)) && \ defined(OTL_VALUE_TEMPLATE) template class otl_value { public: TData v; bool ind; otl_value() : v(), ind(true) {} ~otl_value() {} otl_value(const otl_value &var) : v(var.v), ind(var.ind) {} otl_value(const TData &var) : v(var), ind(false) {} otl_value(OTL_NULL_PARM ) : v(), ind(true) {} otl_value &operator=(const otl_value &var) { v = var.v; ind = var.ind; return *this; } otl_value &operator=(const TData &var) { v = var; ind = false; return *this; } otl_value &operator=(OTL_NULL_PARM ) { ind = true; return *this; } bool is_null(void) const { return ind; } void set_null(void) { ind = true; } void set_non_null(void) { ind = false; } void set_null(const bool null){ind=null;} }; template class otl_compact_value { public: TData v; otl_compact_value() : v(null_value) {} ~otl_compact_value(){} otl_compact_value(const otl_compact_value &var) : v(var.v) {} otl_compact_value(const TData &var) : v(var) {} otl_compact_value(OTL_NULL_PARM ) : v(null_value) {} otl_compact_value &operator=(const otl_compact_value &var) { v = var.v; return *this; } otl_compact_value &operator=(const TData &var) { v = var; return *this; } otl_compact_value &operator=(OTL_NULL_PARM ) { v=null_value; return *this; } bool is_null(void) const { return v==null_value; } void set_null(const bool null){if(null)v=null_value;} }; template inline STD_NAMESPACE_PREFIX ostream &operator<<(STD_NAMESPACE_PREFIX ostream &s, const otl_value &var) { if(var.is_null()) s<<"NULL"; else s< inline STD_NAMESPACE_PREFIX ostream &operator<< (STD_NAMESPACE_PREFIX ostream &s, const otl_compact_value &var) { if(var.is_null()) s<<"NULL"; else s< &var) { if(var.is_null()) s<<"NULL"; else{ #if !defined(OTL_TRACE_LEVEL) #if !defined(OTL_LEGACY_TRACE_DATETIME_FORMAT_ON) s << var.v.month << "/" << var.v.day << "/" << var.v.year << " " << var.v.hour << ":" << var.v.minute << ":" << var.v.second << "." << OTL_SETFILL << OTL_SETW(var.v) << var.v.fraction; #else s << var.v.month << "/" << var.v.day << "/" << var.v.year << " " << var.v.hour << ":" << var.v.minute << ":" << var.v.second << "." << var.v.fraction; #endif #else s << OTL_TRACE_FORMAT_DATETIME(var.v); #endif } return s; } #endif #endif template class otl_tmpl_nocommit_stream : public OTLStream { public: otl_tmpl_nocommit_stream() OTL_NO_THROW : OTLStream() { OTLStream::set_commit(0); } otl_tmpl_nocommit_stream(const otl_stream_buffer_size_type arr_size, const char *sqlstm, OTLConnect &pdb, const char *ref_cur_placeholder = nullptr) OTL_THROWS_OTL_EXCEPTION: OTLStream(arr_size, sqlstm, pdb, ref_cur_placeholder) { OTLStream::set_commit(0); } void open(otl_stream_buffer_size_type arr_size, const char *sqlstm, OTLConnect &db, const char *ref_cur_placeholder = nullptr) OTL_THROWS_OTL_EXCEPTION { OTLStream::open(arr_size, sqlstm, db, ref_cur_placeholder); OTLStream::set_commit(0); } }; #if defined(OTL_STL) class otl_pl_vec_generic { public: typedef STD_NAMESPACE_PREFIX vector null_flag_type; otl_pl_vec_generic() : p_v(nullptr), null_flag(), vtype(0), elem_size(0) {} virtual int len(void) const { return 0; } virtual void set_len(const int /*new_len*/ = 0, const bool /*set_all_to_null*/ = true) {} bool is_null(const int ndx = 0) const { return null_flag[OTL_SCAST(unsigned int, ndx)]; } void set_null(const int ndx = 0) { null_flag[OTL_SCAST(unsigned int, ndx)] = true; } void set_non_null(const int ndx = 0) { null_flag[OTL_SCAST(unsigned int, ndx)] = false; } virtual ~otl_pl_vec_generic() {} int get_vtype() const { return vtype; } int get_elem_size() const { return elem_size; } void *get_p_v() { return p_v; } protected: void *p_v; null_flag_type null_flag; int vtype; int elem_size; private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_pl_vec_generic(const otl_pl_vec_generic &) = delete; otl_pl_vec_generic &operator=(const otl_pl_vec_generic &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_pl_vec_generic(otl_pl_vec_generic &&) = delete; otl_pl_vec_generic &operator=(otl_pl_vec_generic &&) = delete; #endif private: #else otl_pl_vec_generic(const otl_pl_vec_generic &) : p_v(nullptr), null_flag(), vtype(0), elem_size(0) {} otl_pl_vec_generic &operator=(const otl_pl_vec_generic &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_pl_vec_generic(otl_pl_vec_generic &&) : p_v(nullptr), null_flag(), vtype(0), elem_size(0) {} otl_pl_vec_generic &operator=(otl_pl_vec_generic &&) { return *this; } #endif #endif }; template class otl_T_vec : public otl_pl_vec_generic { public: STD_NAMESPACE_PREFIX vector v; typedef T value_type; otl_T_vec() : v() { this->p_v = OTL_RCAST(void *, &v); this->vtype = type_code; this->elem_size = T_sz; } virtual ~otl_T_vec() {} virtual void set_len(const int new_len = 0, const bool set_all_to_null = true) { int i, vsize; v.resize(OTL_SCAST(size_t, new_len)); this->null_flag.resize(OTL_SCAST(size_t, new_len)); vsize = OTL_SCAST(int, v.size()); if (set_all_to_null) for (i = 0; i < vsize; ++i) this->null_flag[OTL_SCAST(size_t, i)] = true; } virtual int len(void) const { return OTL_SCAST(int, v.size()); } T &operator[](int ndx) { return v[ndx]; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_T_vec(const otl_T_vec &) = delete; otl_T_vec &operator=(const otl_T_vec &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_T_vec(otl_T_vec &&) = delete; otl_T_vec &operator=(otl_T_vec &&) = delete; #endif private: #else otl_T_vec(const otl_T_vec &) : v() {} otl_T_vec &operator=(const otl_T_vec &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_T_vec(otl_T_vec &&) : v() {} otl_T_vec &operator=(otl_T_vec &&) { return *this; } #endif #endif }; typedef otl_T_vec otl_double_vec; typedef otl_T_vec otl_float_vec; typedef otl_T_vec otl_int_vec; typedef otl_T_vec otl_short_vec; typedef otl_T_vec otl_long_int_vec; typedef otl_T_vec otl_datetime_vec; typedef otl_T_vec otl_string_vec; #endif template class otl_tmpl_pl_tab : public otl_pl_tab_generic { public: T v[atab_size]; void init(void) { int i; tab_len = 0; vtype = avtype; tab_size = atab_size; p_null = null_flag; p_v = OTL_RCAST(unsigned char *, v); elem_size = sizeof(T); for (i = 0; i < atab_size; ++i) null_flag[i] = 0; memset(v, 0, sizeof(v)); } otl_tmpl_pl_tab() : v(), null_flag() { init(); } virtual ~otl_tmpl_pl_tab() {} private: short null_flag[atab_size]; #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_pl_tab &operator=(const otl_tmpl_pl_tab &) = delete; otl_tmpl_pl_tab(const otl_tmpl_pl_tab &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_pl_tab &operator=(otl_tmpl_pl_tab &&) = delete; otl_tmpl_pl_tab(otl_tmpl_pl_tab &&) = delete; #endif private: #else otl_tmpl_pl_tab &operator=(const otl_tmpl_pl_tab &) { return *this; } otl_tmpl_pl_tab(const otl_tmpl_pl_tab &) : v(), null_flag() {} #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_pl_tab &operator=(otl_tmpl_pl_tab &&) { return *this; } otl_tmpl_pl_tab(otl_tmpl_pl_tab &&) : v(), null_flag() {} #endif #endif }; template class otl_int_tab : public otl_tmpl_pl_tab { public: otl_int_tab() : otl_tmpl_pl_tab() {} }; template class otl_double_tab : public otl_tmpl_pl_tab { public: otl_double_tab() : otl_tmpl_pl_tab() {} }; template class otl_float_tab : public otl_tmpl_pl_tab { public: otl_float_tab() : otl_tmpl_pl_tab() {} }; template class otl_unsigned_tab : public otl_tmpl_pl_tab { public: otl_unsigned_tab() : otl_tmpl_pl_tab() {} }; template class otl_short_tab : public otl_tmpl_pl_tab { public: otl_short_tab() : otl_tmpl_pl_tab() {} }; template class otl_long_int_tab : public otl_tmpl_pl_tab { public: otl_long_int_tab() : otl_tmpl_pl_tab() {} }; template class otl_cstr_tab : public otl_pl_tab_generic { public: typedef unsigned char T[str_size]; T v[atab_size]; void init(void) { int i; tab_len = 0; vtype = otl_var_char; tab_size = atab_size; p_null = null_flag; p_v = OTL_RCAST(unsigned char *, v); elem_size = sizeof(T); for (i = 0; i < atab_size; ++i) null_flag[i] = 0; memset(v, 0, sizeof(v)); } otl_cstr_tab() : v(), null_flag() { init(); } virtual ~otl_cstr_tab() {} private: short null_flag[atab_size]; #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_cstr_tab(const otl_cstr_tab &) = delete; otl_cstr_tab &operator=(const otl_cstr_tab &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_cstr_tab(otl_cstr_tab &&) = delete; otl_cstr_tab &operator=(otl_cstr_tab &&) = delete; #endif private: #else otl_cstr_tab(const otl_cstr_tab &) : v(), null_flag() {} otl_cstr_tab &operator=(const otl_cstr_tab &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_cstr_tab(otl_cstr_tab &&) : v(), null_flag() {} otl_cstr_tab &operator=(otl_cstr_tab &&) { return *this; } #endif #endif }; template class otl_datetime_tab : public otl_pl_tab_generic { public: typedef otl_datetime T; T v[atab_size]; void init(void) { int i; tab_len = 0; vtype = otl_var_timestamp; tab_size = atab_size; p_null = null_flag; p_v = OTL_RCAST(unsigned char *, v); elem_size = sizeof(otl_oracle_date); for (i = 0; i < atab_size; ++i) null_flag[i] = 0; } otl_datetime_tab() : v(), null_flag() { init(); } virtual ~otl_datetime_tab() {} private: short null_flag[atab_size]; }; template class otl_tmpl_dyn_pl_tab : public otl_pl_tab_generic { public: T *v; void init(const int atab_size = 1) { int i; tab_len = 0; vtype = avtype; tab_size = atab_size; v = new T[OTL_SCAST(size_t,tab_size)]; null_flag = new short[OTL_SCAST(size_t,tab_size)]; p_null = null_flag; p_v = OTL_RCAST(unsigned char *, v); elem_size = sizeof(T); for (i = 0; i < atab_size; ++i) null_flag[i] = 0; memset(v, 0, OTL_SCAST(size_t, elem_size * tab_size)); } otl_tmpl_dyn_pl_tab(const int atab_size = 1) : v(nullptr), null_flag(nullptr) { init(atab_size); } virtual ~otl_tmpl_dyn_pl_tab() { delete[] v; delete[] null_flag; } private: short *null_flag; #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_dyn_pl_tab(const otl_tmpl_dyn_pl_tab &) = delete; otl_tmpl_dyn_pl_tab & operator=(const otl_tmpl_dyn_pl_tab &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_dyn_pl_tab(otl_tmpl_dyn_pl_tab &&) = delete; otl_tmpl_dyn_pl_tab &operator=(otl_tmpl_dyn_pl_tab &&) = delete; #endif private: #else otl_tmpl_dyn_pl_tab(const otl_tmpl_dyn_pl_tab &) : v(nullptr), null_flag(nullptr) {} otl_tmpl_dyn_pl_tab & operator=(const otl_tmpl_dyn_pl_tab &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_dyn_pl_tab(otl_tmpl_dyn_pl_tab &&) : v(nullptr), null_flag(nullptr) {} otl_tmpl_dyn_pl_tab &operator=(otl_tmpl_dyn_pl_tab &&) { return *this; } #endif #endif }; class otl_dynamic_int_tab : public otl_tmpl_dyn_pl_tab { public: otl_dynamic_int_tab(const int atab_size = 1) : otl_tmpl_dyn_pl_tab(atab_size) {} }; class otl_dynamic_double_tab : public otl_tmpl_dyn_pl_tab { public: otl_dynamic_double_tab(const int atab_size = 1) : otl_tmpl_dyn_pl_tab(atab_size) {} }; class otl_dynamic_float_tab : public otl_tmpl_dyn_pl_tab { public: otl_dynamic_float_tab(const int atab_size = 1) : otl_tmpl_dyn_pl_tab(atab_size) {} }; class otl_dynamic_unsigned_tab : public otl_tmpl_dyn_pl_tab { public: otl_dynamic_unsigned_tab(const int atab_size = 1) : otl_tmpl_dyn_pl_tab(atab_size) {} }; class otl_dynamic_short_tab : public otl_tmpl_dyn_pl_tab { public: otl_dynamic_short_tab(const int atab_size = 1) : otl_tmpl_dyn_pl_tab(atab_size) {} }; class otl_dynamic_long_int_tab : public otl_tmpl_dyn_pl_tab { public: otl_dynamic_long_int_tab(const int atab_size = 1) : otl_tmpl_dyn_pl_tab(atab_size) {} }; template class otl_dynamic_cstr_tab : public otl_pl_tab_generic { public: typedef unsigned char T[str_size]; T *v; void init(const int atab_size = 1) { int i; tab_len = 0; vtype = otl_var_char; tab_size = atab_size; v = new T[OTL_SCAST(size_t,tab_size)]; null_flag = new short[OTL_SCAST(size_t,tab_size)]; p_null = null_flag; p_v = OTL_RCAST(unsigned char *, v); elem_size = sizeof(T); for (i = 0; i < atab_size; ++i) null_flag[i] = 0; memset(v, 0, OTL_SCAST(size_t, elem_size) * OTL_SCAST(size_t, tab_size)); } otl_dynamic_cstr_tab(const int atab_size = 1) : v(nullptr), null_flag(nullptr) { init(atab_size); } virtual ~otl_dynamic_cstr_tab() { delete[] v; delete[] null_flag; } private: short *null_flag; #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_dynamic_cstr_tab(const otl_dynamic_cstr_tab &) = delete; otl_dynamic_cstr_tab &operator=(const otl_dynamic_cstr_tab &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_dynamic_cstr_tab(otl_dynamic_cstr_tab &&) = delete; otl_dynamic_cstr_tab &operator=(otl_dynamic_cstr_tab &&) = delete; #endif private: #else otl_dynamic_cstr_tab(const otl_dynamic_cstr_tab &) : v(nullptr), null_flag(nullptr) {} otl_dynamic_cstr_tab &operator=(const otl_dynamic_cstr_tab &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_dynamic_cstr_tab(otl_dynamic_cstr_tab &&) : v(nullptr), null_flag(nullptr) {} otl_dynamic_cstr_tab &operator=(otl_dynamic_cstr_tab &&) { return *this; } #endif #endif }; class otl_dynamic_datetime_tab : public otl_pl_tab_generic { public: typedef otl_datetime T; T *v; void init(const int atab_size = 1) { int i; tab_len = 0; vtype = otl_var_timestamp; tab_size = atab_size; v = new T[OTL_SCAST(size_t,tab_size)]; null_flag = new short[OTL_SCAST(size_t,tab_size)]; p_null = null_flag; p_v = OTL_RCAST(unsigned char *, v); elem_size = sizeof(otl_oracle_date); for (i = 0; i < atab_size; ++i) null_flag[i] = 0; } otl_dynamic_datetime_tab(const int atab_size = 1) : otl_pl_tab_generic(), v(nullptr), null_flag(nullptr) { init(atab_size); } virtual ~otl_dynamic_datetime_tab() { delete[] v; delete[] null_flag; } private: short *null_flag; #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_dynamic_datetime_tab(const otl_dynamic_datetime_tab &) = delete; otl_dynamic_datetime_tab &operator=(const otl_dynamic_datetime_tab &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_dynamic_datetime_tab(otl_dynamic_datetime_tab &&) = delete; otl_dynamic_datetime_tab &operator=(otl_dynamic_datetime_tab &&) = delete; #endif private: #else otl_dynamic_datetime_tab(const otl_dynamic_datetime_tab &) : otl_pl_tab_generic(), v(nullptr), null_flag(nullptr) {} otl_dynamic_datetime_tab &operator=(const otl_dynamic_datetime_tab &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_dynamic_datetime_tab(otl_dynamic_datetime_tab &&) : otl_pl_tab_generic(), v(nullptr), null_flag(nullptr) {} otl_dynamic_datetime_tab &operator=(otl_dynamic_datetime_tab &&) { return *this; } #endif #endif }; #define OTL_TMPL_EXCEPTION \ otl_tmpl_exception #define OTL_TMPL_CONNECT \ otl_tmpl_connect #define OTL_TMPL_CURSOR \ otl_tmpl_cursor #define OTL_TMPL_OUT_STREAM \ otl_tmpl_out_stream #define OTL_TMPL_SELECT_CURSOR \ otl_tmpl_select_cursor #define OTL_TMPL_INOUT_STREAM \ otl_tmpl_inout_stream #define OTL_TMPL_SELECT_STREAM \ otl_tmpl_select_stream #if defined(OTL_EXCEPTION_IS_DERIVED_FROM_STD_EXCEPTION) #if defined(OTL_EXCEPTION_DERIVED_FROM) #error OTL_EXCEPTION_DERIVED_FROM is already defined. \ OTL_EXCEPTION_IS_DERIVED_FROM_STD_EXCEPTION cannot be used #endif #define OTL_EXCEPTION_DERIVED_FROM std::exception #if defined(UNICODE) || defined(_UNICODE) #if !defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) #error OTL_UNICODE_EXCEPTION_AND_RLOGON needs to be defined when \ OTL_EXCEPTION_IS_DERIVED_FROM_STD_EXCEPTION is used with Unicode #endif #if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) #define OTL_EXCEPTION_HAS_MEMBERS \ virtual const char *what() const noexcept { \ otl_convert_SQLWCHAR_to_char_2(this->char_msg, this->msg); \ return reinterpret_cast(this->char_msg); \ } #else #define OTL_EXCEPTION_HAS_MEMBERS \ virtual const char *what() const throw() { \ otl_convert_SQLWCHAR_to_char_2(this->char_msg, this->msg); \ return reinterpret_cast(this->char_msg); \ } #endif #else #define OTL_EXCEPTION_HAS_MEMBERS \ virtual const char *what() const throw() { \ otl_convert_SQLWCHAR_to_char_2(this->char_msg, this->msg); \ return reinterpret_cast(this->char_msg); \ } #endif #else #if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) #define OTL_EXCEPTION_HAS_MEMBERS \ virtual const char *what() const noexcept { \ return reinterpret_cast(this->msg); \ } #else #define OTL_EXCEPTION_HAS_MEMBERS \ virtual const char *what() const throw() { \ return reinterpret_cast(this->msg); \ } #endif #else #define OTL_EXCEPTION_HAS_MEMBERS \ virtual const char *what() const throw() { \ return reinterpret_cast(this->msg); \ } #endif #endif #endif template #if defined(OTL_EXCEPTION_DERIVED_FROM) class otl_tmpl_exception : public OTL_EXCEPTION_DERIVED_FROM, public TExceptionStruct { #else class otl_tmpl_exception : public TExceptionStruct { #endif public: #if defined(OTL_EXCEPTION_HAS_MEMBERS) OTL_EXCEPTION_HAS_MEMBERS #endif #if defined(OTL_EXCEPTION_STM_TEXT_SIZE) char stm_text[OTL_EXCEPTION_STM_TEXT_SIZE]; #else char stm_text[2048]; #endif char var_info[256]; otl_tmpl_exception() #if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) OTL_ANSI_CPP_11_NOEXCEPT #else throw() #endif #else OTL_NO_THROW #endif { stm_text[0] = 0; var_info[0] = 0; } otl_tmpl_exception(TConnectStruct &conn_struct, const char *sqlstm = nullptr) #if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) OTL_ANSI_CPP_11_NOEXCEPT #else throw() #endif #else OTL_NO_THROW #endif { stm_text[0] = 0; var_info[0] = 0; if (sqlstm) { OTL_STRNCPY_S(OTL_RCAST(char *, stm_text), sizeof(stm_text), sqlstm, sizeof(stm_text) - 1); stm_text[sizeof(stm_text) - 1] = 0; } conn_struct.error(OTL_SCAST(TExceptionStruct &, *this)); OTL_TRACE_EXCEPTION(this->code, this->msg, this->stm_text, this->var_info) } otl_tmpl_exception(TCursorStruct &cursor_struct, const char *sqlstm = nullptr) #if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) OTL_ANSI_CPP_11_NOEXCEPT #else throw() #endif #else OTL_NO_THROW #endif { stm_text[0] = 0; var_info[0] = 0; if (sqlstm) { OTL_STRNCPY_S(OTL_RCAST(char *, stm_text), sizeof(stm_text), sqlstm, sizeof(stm_text) - 1); stm_text[sizeof(stm_text) - 1] = 0; } cursor_struct.error(OTL_SCAST(TExceptionStruct &, *this)); OTL_TRACE_EXCEPTION(this->code, this->msg, this->stm_text, this->var_info) } otl_tmpl_exception(const char *amsg, const int acode, const char *sqlstm = nullptr, const char *varinfo = nullptr) #if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) OTL_ANSI_CPP_11_NOEXCEPT #else throw() #endif #else OTL_NO_THROW #endif #if defined(OTL_EXCEPTION_DERIVED_FROM) && \ defined(OTL_EXCEPTION_INITIALIZED_WITH_BASE_CLASS_CONSTRUCTOR_CALL) : OTL_EXCEPTION_INITIALIZED_WITH_BASE_CLASS_CONSTRUCTOR_CALL #endif { stm_text[0] = 0; var_info[0] = 0; if (sqlstm) { #if defined(_MSC_VER) #if (_MSC_VER >= 1400) OTL_STRNCPY_S(OTL_RCAST(char *, stm_text), sizeof(stm_text), sqlstm, sizeof(stm_text) - 1); #else #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>800) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-truncation" #endif strncpy(OTL_RCAST(char *, stm_text), sqlstm, sizeof(stm_text)); #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>800) #pragma GCC diagnostic pop #endif stm_text[sizeof(stm_text) - 1] = 0; #endif #else #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>800) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wstringop-truncation" #endif strncpy(OTL_RCAST(char *, stm_text), sqlstm, sizeof(stm_text)); #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>800) #pragma GCC diagnostic pop #endif stm_text[sizeof(stm_text) - 1] = 0; #endif } if (varinfo) OTL_STRCPY_S(OTL_RCAST(char *, var_info), sizeof(var_info), varinfo); TExceptionStruct::init(amsg, acode); OTL_TRACE_EXCEPTION(this->code, this->msg, this->stm_text, this->var_info) } #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) && \ !defined(OTL_EXCEPTION_DERIVED_FROM) #error OTL_EXCEPTION_DERIVED_FROM needs to be defined when \ OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW is defined #endif #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) otl_tmpl_exception(const char *amsg, const int acode, const char *sqlstm, const char *varinfo, const void *input_string, int input_string_size) #if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) OTL_ANSI_CPP_11_NOEXCEPT #else throw() #endif #else OTL_NO_THROW #endif #if defined(OTL_EXCEPTION_DERIVED_FROM) && \ defined(OTL_EXCEPTION_INITIALIZED_WITH_BASE_CLASS_CONSTRUCTOR_CALL) : OTL_EXCEPTION_INITIALIZED_WITH_BASE_CLASS_CONSTRUCTOR_CALL #endif { stm_text[0] = 0; var_info[0] = 0; if (sqlstm) { #if defined(_MSC_VER) #if (_MSC_VER >= 1400) OTL_STRNCPY_S(OTL_RCAST(char *, stm_text), sizeof(stm_text), sqlstm, sizeof(stm_text) - 1); #else strncpy(OTL_RCAST(char *, stm_text), sqlstm, sizeof(stm_text)); stm_text[sizeof(stm_text) - 1] = 0; #endif #else strncpy(OTL_RCAST(char *, stm_text), sqlstm, sizeof(stm_text)); stm_text[sizeof(stm_text) - 1] = 0; #endif } if (varinfo) OTL_STRCPY_S(OTL_RCAST(char *, var_info), sizeof(var_info), varinfo); TExceptionStruct::init(amsg, acode); OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW(input_string, input_string_size) #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_TRACE_EXCEPTION2(this->code, this->msg, this->stm_text, this->var_info, input_string, input_string_size) #else OTL_TRACE_EXCEPTION(this->code, this->msg, this->stm_text, this->var_info) #endif } #endif #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) otl_tmpl_exception(const otl_tmpl_exception &) = default; #endif virtual ~otl_tmpl_exception() #if defined(__GNUC__) && (__GNUC__ >= 3) #if defined(OTL_ANSI_CPP_11_NOEXCEPT_SUPPORT) OTL_ANSI_CPP_11_NOEXCEPT #else throw() #endif #else OTL_NO_THROW #endif { } }; template class otl_tmpl_connect { protected: #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) bool use_fetch_scroll_; #endif TConnectStruct connect_struct; int long_max_size; int retcode; public: #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) void set_fetch_scroll_mode(const bool use_fetch_scroll_mode = true) { use_fetch_scroll_ = use_fetch_scroll_mode; } bool get_fetch_scroll_mode() const { return use_fetch_scroll_; } #endif void set_retcode(const int aretcode) { retcode = aretcode; } int get_retcode() const { return retcode; } TConnectStruct &get_connect_struct() { return connect_struct; } int connected; void set_max_long_size(const int amax_size) { #if defined(OTL_UNICODE) #if defined(OTL_ORA8I) || defined(OTL_ORA9I) || defined(OTL_ORA10G) || \ defined(OTL_ORA10G_R2) long_max_size = amax_size * OTL_SCAST(int, sizeof(OTL_WCHAR)); #else long_max_size = amax_size; #endif #else long_max_size = amax_size; #endif } int get_max_long_size(void) { return long_max_size; } void set_timeout(const int atimeout = 0) { connect_struct.set_timeout(atimeout); } void set_cursor_type(const int acursor_type = 0) { connect_struct.set_cursor_type(acursor_type); } otl_tmpl_connect() : #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) use_fetch_scroll_(false), #endif connect_struct(), long_max_size(otl_short_int_max), retcode(1), connected(0) { } otl_tmpl_connect(const char *connect_str, const int auto_commit = 0) : #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) use_fetch_scroll_(false), #endif connect_struct(), long_max_size(otl_short_int_max), retcode(1), connected(0) { rlogon(connect_str, auto_commit); } virtual ~otl_tmpl_connect() OTL_THROWS_OTL_EXCEPTION3 { logoff(); } static int otl_initialize(const int threaded_mode = 0) { return TConnectStruct::initialize(threaded_mode); } void rlogon(const char *connect_str, const int auto_commit = 0) { retcode = connect_struct.rlogon(connect_str, auto_commit); if (retcode) connected = 1; else { connected = 0; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_TMPL_EXCEPTION ex(connect_struct); connect_struct.cleanup(); OTL_THROW(ex); } } void logoff(void) { if (!connected) return; OTL_TRACE_FUNC(0x1, "otl_connect", "logoff", "") retcode = connect_struct.logoff(); connected = 0; if (retcode) return; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct))); } void commit(void) { if (!connected) return; OTL_TRACE_FUNC(0x1, "otl_connect", "commit", "") retcode = connect_struct.commit(); if (retcode) return; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct))); } void auto_commit_on(void) { if (!connected) return; OTL_TRACE_FUNC(0x1, "otl_connect", "auto_commit_on", "") retcode = connect_struct.auto_commit_on(); if (retcode) return; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct))); } void auto_commit_off(void) { if (!connected) return; OTL_TRACE_FUNC(0x1, "otl_connect", "auto_commit_off", "") retcode = connect_struct.auto_commit_off(); if (retcode) return; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct))); } void rollback(void) { if (!connected) return; OTL_TRACE_FUNC(0x1, "otl_connect", "rollback", "") retcode = connect_struct.rollback(); if (retcode) return; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(connect_struct))); } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_connect(const otl_tmpl_connect &) = delete; otl_tmpl_connect &operator=(const otl_tmpl_connect &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_connect(otl_tmpl_connect &&) = delete; otl_tmpl_connect &operator=(otl_tmpl_connect &&) = delete; #endif private: #else otl_tmpl_connect(const otl_tmpl_connect &) : connected(0), #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) use_fetch_scroll_(false), #endif connect_struct(), long_max_size(otl_short_int_max), retcode(1) {} otl_tmpl_connect &operator=(const otl_tmpl_connect &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_connect(otl_tmpl_connect &&) : connected(0), connect_struct(), long_max_size(otl_short_int_max), retcode(1){} otl_tmpl_connect &operator=(otl_tmpl_connect &&) { return *this; } #endif #endif }; template class otl_tmpl_variable { protected: int param_type; int ftype; int elem_size; int array_size; char *name; int pos; int name_pos; int bound; int pl_tab_flag; TVariableStruct var_struct; public: TVariableStruct &get_var_struct() { return var_struct; } const TVariableStruct &get_const_var_struct() const { return var_struct; } int get_bound() const { return bound; } int get_param_type() const { return param_type; } int get_ftype() const { return ftype; } int get_name_pos() const { return name_pos; } int get_elem_size() const { return elem_size; } int get_pl_tab_flag() const { return pl_tab_flag; } int get_pos() const { return pos; } int get_array_size() const { return array_size; } const char *get_name() const { return name; } void set_param_type(const int aparam_type){ this->param_type=aparam_type; } void set_pos(const int apos) { this->pos = apos; } void set_bound(const int abound) { this->bound = abound; } void set_name_pos(const int aname_pos) { this->name_pos = aname_pos; } void set_ftype(const int aftype) { this->ftype = aftype; } int actual_elem_size(void) { return var_struct.actual_elem_size(); } void copy_var_desc(otl_var_desc &v) { v.param_type = param_type; v.ftype = ftype; v.elem_size = elem_size; v.array_size = array_size; v.pos = pos; v.name_pos = name_pos; if (name) { OTL_STRNCPY_S(v.name, sizeof(v.name), name, sizeof(v.name) - 1); v.name[sizeof(v.name) - 1] = 0; } else v.name[0] = 0; v.pl_tab_flag = pl_tab_flag; } otl_tmpl_variable() : param_type(0), ftype(0), elem_size(0), array_size(0), name(nullptr), pos(0), name_pos(0), bound(0), pl_tab_flag(0), var_struct() {} virtual ~otl_tmpl_variable() { delete[] name; } void init(const bool select_stm_flag, const int aftype, const int aelem_size, const otl_stream_buffer_size_type aarray_size, const void *connect_struct = nullptr, const int apl_tab_flag = 0 #if defined(OTL_ORA_SDO_GEOMETRY) ,OCIType* colOCIType = nullptr #endif ){ ftype = aftype; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) if (ftype == otl_var_nchar) ftype = otl_var_char; else if (ftype == otl_var_nclob) ftype = otl_var_clob; #endif elem_size = aelem_size; array_size = aarray_size; pl_tab_flag = apl_tab_flag; bound = 0; var_struct.init(select_stm_flag, aftype, elem_size, aarray_size, connect_struct, pl_tab_flag #if defined(OTL_ORA_SDO_GEOMETRY) ,colOCIType #endif ); } int get_param_type(void) { return param_type; } void copy_name(const char *aname) { pos = 0; if (name == aname) return; if (name) delete[] name; size_t len = strlen(aname) + 1; name = new char[len]; OTL_STRCPY_S(name, len, aname); } void copy_pos(const int apos) { if (name) { delete[] name; name = nullptr; name_pos = 0; } pos = apos; } void set_null(int ndx) { var_struct.set_null(ndx); } void set_not_null(int ndx) { var_struct.set_not_null(ndx, elem_size); } void set_len(int len, int ndx = 0) { var_struct.set_len(len, ndx); } int get_len(int ndx = 0) { return var_struct.get_len(ndx); } int get_pl_tab_len(void) { return this->var_struct.get_pl_tab_len(); } int get_max_pl_tab_len(void) { return this->var_struct.get_max_pl_tab_len(); } void set_pl_tab_len(const int pl_tab_len) { this->var_struct.set_pl_tab_len(pl_tab_len); } int is_null(int ndx) { return var_struct.is_null(ndx); } void *val(int ndx = 0) { return var_struct.val(ndx, elem_size); } static void map_ftype(otl_column_desc &desc, const int max_long_size, int &aftype, int &aelem_size, otl_select_struct_override &a_override, const int column_ndx, const int connection_type) { TVariableStruct::map_ftype(desc, max_long_size, aftype, aelem_size, a_override, column_ndx, connection_type); } static int int2ext(int int_type) { return TVariableStruct::int2ext(int_type); } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_variable(const otl_tmpl_variable &) = delete; otl_tmpl_variable &operator=(const otl_tmpl_variable &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_variable(otl_tmpl_variable &&) = delete; otl_tmpl_variable &operator=(otl_tmpl_variable &&) = delete; #endif private: #else otl_tmpl_variable(const otl_tmpl_variable &) : param_type(0), ftype(0), elem_size(0), array_size(0), name(nullptr), pos(0), name_pos(0), bound(0), pl_tab_flag(0), var_struct() {} otl_tmpl_variable &operator=(const otl_tmpl_variable &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_variable(otl_tmpl_variable &&) : param_type(0), ftype(0), elem_size(0), array_size(0), name(nullptr), pos(0), name_pos(0), bound(0), pl_tab_flag(0), var_struct() {} otl_tmpl_variable &operator=(otl_tmpl_variable &&) { return *this; } #endif #endif }; template class otl_tmpl_cursor { protected: int connected; char *stm_text; char *stm_label; TCursorStruct cursor_struct; int vl_len; otl_tmpl_variable **vl; OTL_TMPL_CONNECT *adb; int eof_data; int eof_desc; int retcode; long _rpc; int in_destructor; public: void set_batch_error_mode(const bool batch_error_mode) { cursor_struct.set_batch_error_mode(batch_error_mode); } int get_number_of_errors_in_batch() { int rv = cursor_struct.get_number_of_errors_in_batch(retcode); if (retcode) return rv; OTL_UNCAUGHT_EXCEPTION_RETURN(rv); OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text))); } void get_error(const int error_ndx, int &dml_row_offset, TExceptionStruct &exception_struct) { retcode = cursor_struct.get_error(error_ndx, dml_row_offset, exception_struct); if (retcode) return; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text))); } OTL_TMPL_CONNECT *get_adb() { return adb; } void set_adb(OTL_TMPL_CONNECT *aadb) { adb = aadb; } TCursorStruct &get_cursor_struct_ref() { return cursor_struct; } otl_tmpl_variable **get_vl() { return vl; } int get_vl_len() const { return vl_len; } const char *get_stm_label() const { return stm_label; } const char *get_stm_text() const { return stm_text; } void set_connected(const int aconnected) { connected = aconnected; } int &get_eof_data_ref() { return eof_data; } TCursorStruct &get_cursor_struct() { return cursor_struct; } int get_connected() const { return connected; } otl_tmpl_cursor() : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(), vl_len(0), vl(nullptr), adb(nullptr), eof_data(), eof_desc(), retcode(1), _rpc(0), in_destructor(0) {} otl_tmpl_cursor(OTL_TMPL_CONNECT &connect) : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(), vl_len(0), vl(nullptr), adb(&connect), eof_data(), eof_desc(), retcode(1), _rpc(0), in_destructor(0) { open(connect); } otl_tmpl_cursor(OTL_TMPL_CONNECT &connect, TVariableStruct *var) : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(), vl_len(0), vl(nullptr), adb(&connect), eof_data(), eof_desc(), retcode(1), _rpc(0), in_destructor(0) { open(connect, var); } virtual ~otl_tmpl_cursor() OTL_THROWS_OTL_EXCEPTION2 { in_destructor = 1; otl_tmpl_cursor::close(); delete[] stm_label; stm_label = nullptr; delete[] stm_text; stm_text = nullptr; } void open(OTL_TMPL_CONNECT &connect, TVariableStruct *var = nullptr) { in_destructor = 0; eof_data = 0; eof_desc = 0; retcode = 1; adb = &connect; _rpc = 0; if (var == nullptr) retcode = cursor_struct.open(connect.get_connect_struct()); else retcode = cursor_struct.open(connect.get_connect_struct(), var); if (retcode) { connected = 1; return; } OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct))); } virtual void close(const char force_handle_free = 'N') { _rpc = 0; if (!connected) return; if (!this->adb) return; if (!adb->connected) { connected = 0; adb = nullptr; retcode = 1; return; } connected = 0; retcode = cursor_struct.close(force_handle_free); if (retcode) { adb = nullptr; return; } adb = nullptr; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct))); } void parse(const int direct_exec_flag=0) { _rpc = 0; if (!connected) return; retcode = cursor_struct.parse(stm_text,direct_exec_flag); switch (retcode) { case 0: OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text))); case 2: OTL_UNCAUGHT_EXCEPTION_NORETURN; char var_info[1]; var_info[0] = 0; OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_17, otl_error_code_17, this->stm_label ? this->stm_label : this->stm_text, var_info))); } } void parse(const char *sqlstm) { if (!connected) return; if (stm_text) { delete[] stm_text; stm_text = nullptr; } size_t len = strlen(sqlstm) + 1; stm_text = new char[len]; OTL_STRCPY_S(stm_text, len, sqlstm); parse(); } long get_rpc() OTL_NO_THROW { return _rpc; } void exec(const int iters /*=1*/, const int rowoff /*=0*/, const otl_sql_exec_from_enum otl_sql_exec_from_class /*=otl_sql_exec_from_cursor_class*/) { if (!connected) return; retcode = cursor_struct.exec(iters, rowoff, otl_sql_exec_from_class); _rpc = cursor_struct.get_rpc(); if (retcode) return; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text))); } virtual bool valid_binding(const otl_tmpl_variable &v, const otl_binding_enum binding_type) { bool rc = true; if (((v.get_ftype() == otl_var_varchar_long || v.get_ftype() == otl_var_raw_long) && (v.get_const_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter) && v.get_array_size() > 1) || ((v.get_ftype() == otl_var_blob || v.get_ftype() == otl_var_clob) && v.get_const_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter && v.get_array_size() > 1 && binding_type == OTL_BINDING_ENUM otl_inout_binding)) rc = false; return rc; } virtual void bind(const char *name, otl_tmpl_variable &v) { if (!connected) return; if (v.get_bound()) return; v.copy_name(name); if (!valid_binding(v, OTL_BINDING_ENUM otl_inout_binding)) { char var_info[256]; otl_var_info_var2(v.get_name(), v.get_ftype(), var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_16, otl_error_code_16, stm_label ? stm_label : stm_text, var_info))); } retcode = cursor_struct.bind( name, v.get_var_struct(), v.get_elem_size(), v.get_ftype(), v.get_param_type(), v.get_name_pos(), this->adb->get_connect_struct().get_connection_type(), v.get_pl_tab_flag()); if (retcode) { v.set_bound(1); return; } OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text))); } virtual void bind(const int column_num, otl_tmpl_variable &v) { if (!connected) return; v.copy_pos(column_num); if (!valid_binding(v, OTL_BINDING_ENUM otl_select_binding)) { char var_info[256]; otl_var_info_col2(v.get_pos(), v.get_ftype(), var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_16, otl_error_code_16, stm_label ? stm_label : stm_text, var_info))); } retcode = cursor_struct.bind(column_num, v.get_var_struct(), v.get_elem_size(), v.get_ftype(), v.get_param_type()); if (retcode) return; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text))); } virtual void bind(otl_tmpl_variable &v) { if (!connected) return; if (v.get_name()) bind(v.get_name(), v); if (v.get_pos()) bind(v.get_pos(), v); } static long direct_exec(OTL_TMPL_CONNECT &connect, const char *sqlstm, const int exception_enabled = 1) #if defined(OTL_ANSI_CPP) && defined(OTL_FUNC_THROW_SPEC_ON) throw(OTL_TMPL_EXCEPTION) #endif { OTL_TRACE_DIRECT_EXEC try { OTL_TMPL_CURSOR cur(connect); cur.cursor_struct.set_direct_exec(1); cur.parse(sqlstm); cur.exec(1, 0, otl_sql_exec_from_cursor_class); return cur.cursor_struct.get_rpc(); } catch (OTL_CONST_EXCEPTION OTL_TMPL_EXCEPTION &) { if (exception_enabled) { throw; } } return -1; } static void syntax_check(OTL_TMPL_CONNECT &connect, const char *sqlstm) #if defined(OTL_ANSI_CPP) && defined(OTL_FUNC_THROW_SPEC_ON) throw(OTL_TMPL_EXCEPTION) #endif { OTL_TRACE_SYNTAX_CHECK OTL_TMPL_CURSOR cur(connect); cur.cursor_struct.set_direct_exec(1); cur.cursor_struct.set_parse_only(1); cur.parse(sqlstm); } int eof(void) { return eof_data; } int describe_column(otl_column_desc &col, const int column_num) { if (!connected) return 0; retcode = cursor_struct.describe_column(col, column_num, eof_desc); if (eof_desc) return 0; if (retcode) return 1; OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((OTL_TMPL_EXCEPTION(cursor_struct, stm_label ? stm_label : stm_text))); } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_cursor(const otl_tmpl_cursor &) = delete; otl_tmpl_cursor &operator=(const otl_tmpl_cursor &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_cursor(otl_tmpl_cursor &&) = delete; otl_tmpl_cursor &operator=(otl_tmpl_cursor &&) = delete; #endif private: #else otl_tmpl_cursor(const otl_tmpl_cursor &) : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(), vl_len(0), vl(nullptr), adb(nullptr), eof_data(), eof_desc(), retcode(1), _rpc(0), in_destructor(0) {} otl_tmpl_cursor &operator=(const otl_tmpl_cursor &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_cursor(otl_tmpl_cursor &&) : connected(0), stm_text(nullptr), stm_label(nullptr), cursor_struct(), vl_len(0), vl(nullptr), adb(nullptr), eof_data(), eof_desc(), retcode(1), _rpc(0), in_destructor(0) {} otl_tmpl_cursor &operator=(otl_tmpl_cursor &&) { return *this; } #endif #endif }; inline int is_num(char c) { return c >= '0' && c <= '9'; } template class otl_tmpl_ext_hv_decl { private: char **hv; short int *inout; int *pl_tab_size; int array_size; int prev_array_size; short int vst[4]; int len; char *stm_text_; char *stm_label_; int container_size_; bool has_plsql_tabs_or_refcur_; bool has_space_in_bind_variable_; bool bind_var_terminator_is_missing_; public: bool has_plsql_tabs_or_refcur() const { return has_plsql_tabs_or_refcur_; } bool has_space_in_bind_variable() const { return has_space_in_bind_variable_; } bool bind_var_terminator_is_missing() const { return bind_var_terminator_is_missing_; } short int get_vst(const int ndx) const { return vst[ndx]; } int get_len() const { return len; } short int get_inout(const int ndx) const { return inout[ndx]; } int get_pl_tab_size(const int ndx) const { return pl_tab_size[ndx]; } const char *stm_label() const { return stm_label_; } const char *stm_text() const { return stm_text_; } enum var_status { in = 0, out = 1, io = 2, def = 3 }; otl_tmpl_ext_hv_decl(char *stm, int arr_size = 1, char *label = nullptr, otl_select_struct_override **select_override = nullptr, OTL_TMPL_CONNECT *adb = nullptr) : hv(nullptr), inout(nullptr), pl_tab_size(nullptr), array_size(0), prev_array_size(0), vst(), len(0), stm_text_(nullptr), stm_label_(nullptr), container_size_(0), has_plsql_tabs_or_refcur_(false), has_space_in_bind_variable_(false), bind_var_terminator_is_missing_(false) { container_size_ = otl_var_list_size; hv = new char *[OTL_SCAST(size_t,container_size_)]; inout = new short[OTL_SCAST(size_t,container_size_)]; pl_tab_size = new int[OTL_SCAST(size_t,container_size_)]; int j; array_size = arr_size; prev_array_size = arr_size; stm_text_ = stm; stm_label_ = label; int i = 0; short in_str = 0; bool in_comment = false; bool in_one_line_comment = false; char *c = stm; bool in_comment_column_override = false; hv[i] = nullptr; while (*c) { switch (*c) { case '\'': if (!in_comment && !in_one_line_comment) { if (!in_str) in_str = 1; else { if (c[1] == '\'') ++c; else in_str = 0; } } break; case '/': if (c[1] == '*' && !in_str && c[2] == ':' && c[3] == '#') { in_comment_column_override = true; *c = ' '; ++c; *c = ' '; ++c; } else if (c[1] == '*' && !in_str) { in_comment = true; ++c; } break; case '-': if (c[1] == '-' && !in_str) { in_one_line_comment = true; ++c; } break; case '*': if (c[1] == '/' && in_comment) { in_comment = false; ++c; } else if (c[1] == '/' && in_comment_column_override) { *c = ' '; ++c; *c = ' '; } break; case '\n': if (in_one_line_comment) in_one_line_comment = false; break; } if (*c == ':' && !in_str && !in_comment && !in_one_line_comment && ((c > stm && *(c - 1) != '\\') || c == stm)) { char *bind_var_ptr = c; short in_out = def; int apl_tab_size = 0; char var[64]; char *v = var; *v++ = *c++; while (is_id(*c)) *v++ = *c++; while (otl_isspace(*c) && *c) ++c; if (*c == '<' || (*c == '/' && c[1] == '*')) { if (*c == '<') *c = ' '; else if (*c == '/' && c[1] == '*') { *c = ' '; ++c; *c = ' '; } while (*c != '>' && *c != ',' && *c != '*' && *c != '<' && *c != ':' && *c != '/' && *c) { *v++ = *c; *c++ = ' '; } if (*c == 0 || *c == ':' || *c == '<' || *c == '/') bind_var_terminator_is_missing_ = true; if (*c == ',' && otl_isspace(c[1])) has_space_in_bind_variable_ = true; if (*c == ',') { *c++ = ' '; if (otl_to_upper(*c) == 'I') { if (otl_to_upper(c[2]) == 'O') in_out = io; else in_out = in; } else if (otl_to_upper(*c) == 'O') in_out = out; while (*c != '>' && *c && *c != '*' && (*c != '[' && *c != '(')) *c++ = ' '; if (*c == '*') { *c = ' '; ++c; *c = ' '; } if (*c == '[' || *c == '(') { char tmp[32]; char *t = tmp; *c++ = ' '; while ((*c != ']' && *c != ')') && *c != '>' && *c != '*' && *c) { *t++ = *c; *c++ = ' '; } if (*c == '*') { *c = ' '; ++c; *c = ' '; } *t = 0; apl_tab_size = atoi(tmp); while (*c != '>' && *c != '*' && *c) *c++ = ' '; if (*c == '*') { *c = ' '; ++c; *c = ' '; } } } else if (*c == '*' && c[1] == '/') { *c = ' '; ++c; *c = ' '; } if (*c) *c = ' '; *v = 0; if (select_override != nullptr && bind_var_ptr[1] == '#') { char *c4 = bind_var_ptr + 2; char col_num[64]; char *col_num_ptr = col_num; while (is_num(*c4) && *c4) { *col_num_ptr = *c4; ++col_num_ptr; ++c4; } *col_num_ptr = 0; int col_ndx = atoi(col_num); if (col_ndx > 0) { if (*select_override == nullptr) { *select_override = new otl_select_struct_override(); } int data_type = otl_var_none; int data_len = 0; char name[128]; parse_var(adb, var, data_type, data_len, name); (*select_override)->add_override(col_ndx, data_type, data_len); } c4 = bind_var_ptr; while (*c4 && *c4 != ' ') { *c4 = ' '; ++c4; } } else add_var(i, var, in_out, apl_tab_size); } } if (*c) ++c; } for (j = 0; j < 4; ++j) vst[j] = 0; i = 0; while (hv[i]) { switch (inout[i]) { case in: ++vst[0]; break; case out: ++vst[1]; break; case io: ++vst[2]; break; case def: ++vst[3]; break; } ++i; } len = i; } virtual ~otl_tmpl_ext_hv_decl() { int i; for (i = 0; hv[i] != nullptr; ++i) delete[] hv[i]; delete[] hv; delete[] inout; delete[] pl_tab_size; } char *operator[](int ndx) { return hv[ndx]; } short v_status(int ndx) { return inout[ndx]; } int is_id(char c) { return isalnum(OTL_SCAST(unsigned char, c)) || c == '_' || c == '#'; } int name_comp(char *n1, char *n2) { while (*n1 != ' ' && *n1 != 0 && *n2 != ' ' && *n2 != 0) { if (otl_to_upper(*n1) != otl_to_upper(*n2)) return 0; ++n1; ++n2; } if ((*n1 == ' ' && *n2 != ' ') || (*n2 == ' ' && *n1 != ' ')) return 0; return 1; } void add_var(int &n, char *v, short in_out, int apl_tab_size = 0) { int i; for (i = 0; i < n; ++i) if (name_comp(hv[i], v)) return; char *c = v; bool is_space = false; while (*c) { is_space = otl_isspace(*c); if (is_space) break; ++c; } if (is_space && otl_str_case_insensitive_equal((c + 1), "REFCUR")) { has_plsql_tabs_or_refcur_ = true; if (apl_tab_size == 0) apl_tab_size = 1; } if (apl_tab_size > 0) has_plsql_tabs_or_refcur_ = true; size_t v_len = strlen(v) + 1; hv[n] = new char[v_len]; OTL_STRCPY_S(hv[n], v_len, v); inout[n] = in_out; pl_tab_size[n] = apl_tab_size; if (n == container_size_ - 1) { int temp_container_size = container_size_; container_size_ *= 2; char **temp_hv = nullptr; short *temp_inout = nullptr; int *temp_pl_tab_size = nullptr; try { temp_hv = new char *[OTL_SCAST(size_t,container_size_)]; temp_inout = new short[OTL_SCAST(size_t,container_size_)]; temp_pl_tab_size = new int[OTL_SCAST(size_t,container_size_)]; } catch (const std::bad_alloc &) { delete[] temp_hv; delete[] temp_inout; delete[] temp_pl_tab_size; throw; } size_t temp_container_size_2 = OTL_SCAST(size_t, temp_container_size); memcpy(temp_hv, hv, sizeof(char *) * temp_container_size_2); memcpy(temp_inout, inout, sizeof(short) * temp_container_size_2); memcpy(temp_pl_tab_size, pl_tab_size, sizeof(int) * temp_container_size_2); delete[] hv; delete[] inout; delete[] pl_tab_size; hv = temp_hv; inout = temp_inout; pl_tab_size = temp_pl_tab_size; } hv[++n] = nullptr; inout[n] = def; pl_tab_size[n] = 0; } int parse_var(OTL_TMPL_CONNECT *pdb, char *s, int &data_type, int &data_len, char *name) { data_type = otl_var_none; data_len = 0; #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && \ defined(OTL_NUMERIC_TYPE_1_ID) || \ defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON) char type_arr[256]; #endif char type = ' '; char t2 = ' '; char t3 = ' '; char t4 = ' '; int size = 0; char *c = name, *c1 = s; while (*c1 != ' ' && *c1) *c++ = *c1++; *c = 0; while (*c1 == ' ' && *c1) ++c1; #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && \ defined(OTL_NUMERIC_TYPE_1_ID) || \ defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON) char *ct = c1; char *tac = type_arr; size_t ta_len = 0; while (*ct && (*ct != '[' && *ct != '(') && ta_len < sizeof(type_arr)) { *tac = otl_to_upper(*ct); ++ct; ++tac; ++ta_len; } *tac = 0; #endif size_t clen = strlen(c1); if (clen >= 3) { type = otl_to_upper(c1[0]); t2 = otl_to_upper(c1[1]); t3 = otl_to_upper(c1[2]); t4 = otl_to_upper(c1[3]); } if ((type == 'C' && t2 == 'H') || (type == 'R' && t2 == 'A' && t3 == 'W' && (t4 == '[' || t4 == '('))) { char tmp[32]; char *t = tmp; while ((*c1 != '[' && *c1 != '(') && *c1) ++c1; ++c1; while ((*c1 != ']' && *c1 != ')') && *c1) *t++ = *c1++; *t = 0; size = atoi(tmp); #if defined(OTL_ADD_NULL_TERMINATOR_TO_STRING_SIZE) size += 1; #endif } #if defined(OTL_ORA_UNICODE) if (type == 'N' && t2 == 'C' && t3 == 'H') { char tmp[32]; char *t = tmp; while ((*c1 != '[' && *c1 != '(') && *c1) ++c1; ++c1; while ((*c1 != ']' && *c1 != ')') && *c1) *t++ = *c1++; *t = 0; size = atoi(tmp); #if defined(OTL_ADD_NULL_TERMINATOR_TO_STRING_SIZE) size += 1; #endif } #endif OTL_CHECK_BIND_VARS int rc = 1; #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) if (strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0) { data_type = otl_var_char; data_len = otl_numeric_type_1_str_size; rc = 0; return rc; } #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) if (strcmp(type_arr, OTL_NUMERIC_TYPE_2_ID) == 0) { data_type = otl_var_char; data_len = otl_numeric_type_2_str_size; rc = 0; return rc; } #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) if (strcmp(type_arr, OTL_NUMERIC_TYPE_3_ID) == 0) { data_type = otl_var_char; data_len = otl_numeric_type_3_str_size; rc = 0; return rc; } #endif switch (type) { case 'B': if (t2 == 'L') { data_type = otl_var_blob; if (pdb) data_len = pdb->get_max_long_size(); else data_len = 0; } else if (t2 == 'F') { data_type = otl_var_bfloat; data_len = sizeof(float); } else if (t2 == 'D') { data_type = otl_var_bdouble; data_len = sizeof(double); } #if defined(OTL_BIGINT) else if (t2 == 'I') { data_type = TConnectStruct::var_bigint; data_len = TConnectStruct::bigint_size; } #endif break; case 'C': if (t2 == 'H') { data_type = otl_var_char; data_len = size; } else if (t2 == 'L') { data_type = otl_var_clob; if (pdb) data_len = pdb->get_max_long_size(); else data_len = 0; } else rc = 0; break; case 'D': if (t2 == 'O') { data_type = otl_var_double; data_len = sizeof(double); } else if (t2 == 'B' && t3 == '2') { if (t4 == 'T') { data_type = otl_var_db2time; data_len = sizeof(TTimestampStruct); } else if (t4 == 'D') { data_type = otl_var_db2date; data_len = sizeof(TTimestampStruct); } else rc = 0; } else rc = 0; break; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) case 'N': if (t2 == 'C') { if (t3 == 'L') { data_type = otl_var_nclob; if (pdb) data_len = pdb->get_max_long_size(); else data_len = 0; } else if (t3 == 'H') { data_type = otl_var_nchar; data_len = size; } } break; #endif case 'F': data_type = otl_var_float; data_len = sizeof(float); break; case 'I': data_type = otl_var_int; data_len = sizeof(int); break; case 'U': if (t2 == 'N') { data_type = otl_var_unsigned_int; data_len = sizeof(unsigned); } #if defined(OTL_UBIGINT) else if (t2 == 'B') { data_type = TConnectStruct::var_ubigint; data_len = TConnectStruct::ubigint_size; } #endif break; case 'R': if (t2 == 'E' && t3 == 'F') { data_type = otl_var_refcur; data_len = 1; } else if (t2 == 'A' && t3 == 'W' && t4 != '_') { data_type = otl_var_raw; data_len = size; } else if (t2 == 'A' && t3 == 'W' && t4 == '_') { data_type = otl_var_raw_long; if (pdb) data_len = pdb->get_max_long_size(); else data_len = 0; } break; case 'S': data_type = otl_var_short; data_len = sizeof(short); break; case 'L': if (t2 == 'O' && t3 == 'N') { data_type = otl_var_long_int; data_len = sizeof(long); } else if (t2 == 'T' && t3 == 'Z') { data_type = otl_var_ltz_timestamp; data_len = sizeof(TTimestampStruct); } else rc = 0; break; case 'T': if (t2 == 'Z') { data_type = otl_var_tz_timestamp; data_len = sizeof(TTimestampStruct); } else if (t2 == 'I' && t3 == 'M') { data_type = otl_var_timestamp; data_len = sizeof(TTimestampStruct); } else rc = 0; break; case 'V': data_type = otl_var_varchar_long; if (pdb) data_len = pdb->get_max_long_size(); else data_len = 0; break; default: return 0; } return rc; } otl_tmpl_variable *alloc_var(char *s, const int vstat, const int status, OTL_TMPL_CONNECT &adb, const int apl_tab_size = 0) { char name[128]; #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && \ defined(OTL_NUMERIC_TYPE_1_ID) || \ defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON) char type_arr[256]; #endif char type = ' '; char t2 = ' '; char t3 = ' '; char t4 = ' '; char t5 = ' '; int size = 0; char *c = name, *c1 = s; while (*c1 != ' ' && *c1) *c++ = *c1++; *c = 0; while (*c1 == ' ' && *c1) ++c1; #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && \ defined(OTL_NUMERIC_TYPE_1_ID) || \ defined(OTL_BIND_VAR_STRICT_TYPE_CHECKING_ON) char *ct = c1; char *tac = type_arr; size_t ta_len = 0; while (*ct && (*ct != '[' && *ct != '(') && ta_len < sizeof(type_arr)) { *tac = otl_to_upper(*ct); ++ct; ++tac; ++ta_len; } *tac = 0; #endif size_t clen = strlen(c1); if (clen >= 3) { type = otl_to_upper(c1[0]); t2 = otl_to_upper(c1[1]); t3 = otl_to_upper(c1[2]); t4 = otl_to_upper(c1[3]); } if (clen > 4) t5 = otl_to_upper(c1[4]); if ((type == 'C' && t2 == 'H') || (type == 'R' && t2 == 'A' && t3 == 'W' && (t4 == '[' || t4 == '('))) { char tmp[32]; char *t = tmp; while ((*c1 != '[' && *c1 != '(') && *c1) ++c1; if (*c1) ++c1; while ((*c1 != ']' && *c1 != ')') && *c1) *t++ = *c1++; *t = 0; if (*tmp == 0) // declaration is invalid return nullptr; if (*c1 == 0) // missing ] or ) return nullptr; size = atoi(tmp); #if defined(OTL_ADD_NULL_TERMINATOR_TO_STRING_SIZE) if (type == 'C') size += 1; #endif if (size < 2) // minimum size of should be at 2 return nullptr; } #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) if (type == 'N' && t2 == 'C' && t3 == 'H') { char tmp[32]; char *t = tmp; while ((*c1 != '[' && *c1 != '(') && *c1) ++c1; if (*c1) ++c1; while ((*c1 != ']' && *c1 != ')') && *c1) *t++ = *c1++; *t = 0; if (*tmp == 0) return nullptr; size = atoi(tmp); #if defined(OTL_ADD_NULL_TERMINATOR_TO_STRING_SIZE) size += 1; #endif } #endif if (status == in && (vstat == in || vstat == io)) ; else if (status == out && (vstat == out || vstat == io || vstat == def)) ; else if (status == def) ; else return nullptr; OTL_CHECK_BIND_VARS int pl_tab_flag = 0; if (apl_tab_size) { array_size = apl_tab_size; pl_tab_flag = 1; } else array_size = prev_array_size; otl_tmpl_variable *v = new otl_tmpl_variable; v->copy_name(name); #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) if (strcmp(type_arr, OTL_NUMERIC_TYPE_1_ID) == 0) { v->init(false, otl_var_char, otl_numeric_type_1_str_size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); } else #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) if (strcmp(type_arr, OTL_NUMERIC_TYPE_2_ID) == 0) { v->init(false, otl_var_char, otl_numeric_type_2_str_size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); } else #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) if (strcmp(type_arr, OTL_NUMERIC_TYPE_3_ID) == 0) { v->init(false, otl_var_char, otl_numeric_type_3_str_size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); } else #endif { switch (type) { case 'B': if (t2 == 'L') v->init(false, otl_var_blob, adb.get_max_long_size(), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct()); #if defined(OTL_BIGINT) else if (t2 == 'I') v->init(false, TConnectStruct::var_bigint, TConnectStruct::bigint_size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); #endif else if (t2 == 'F') v->init(false, otl_var_bfloat, sizeof(float), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else if (t2 == 'D') v->init(false, otl_var_bdouble, sizeof(double), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); break; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) case 'N': if (t2 == 'C' && (t3 == 'L' || t3 == 'H')) { if (t3 == 'L') { v->init(false, otl_var_nclob, adb.get_max_long_size(), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct()); v->set_ftype(otl_var_clob); } else if (t3 == 'H') { v->init(false, otl_var_nchar, size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); v->set_ftype(otl_var_char); } } else { delete v; v = nullptr; } break; #endif case 'C': if (t2 == 'H') { v->init(false, otl_var_char, size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); if (t5 == 'Z') v->get_var_struct().set_charz_flag(true); } else if (t2 == 'L') v->init(false, otl_var_clob, adb.get_max_long_size(), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct()); else { delete v; v = nullptr; } break; case 'D': if (t2 == 'O') v->init(false, otl_var_double, sizeof(double), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else if (t2 == 'B' && t3 == '2') { if (t4 == 'T') v->init(false, otl_var_db2time, sizeof(TTimestampStruct), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else if (t4 == 'D') v->init(false, otl_var_db2date, sizeof(TTimestampStruct), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else { delete v; v = nullptr; } } else { delete v; v = nullptr; } break; case 'F': v->init(false, otl_var_float, sizeof(float), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); break; case 'I': v->init(false, otl_var_int, sizeof(int), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); break; case 'U': if (t2 == 'N') v->init(false, otl_var_unsigned_int, sizeof(unsigned), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); #if defined(OTL_UBIGINT) else if (t2 == 'B') v->init(false, TConnectStruct::var_ubigint, TConnectStruct::ubigint_size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); #endif break; case 'R': if (t2 == 'E' && t3 == 'F') v->init(false, otl_var_refcur, 1, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), 0); else if (t2 == 'A' && t3 == 'W' && (t4 == '[' || t4 == '(')) v->init(false, otl_var_raw, size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else if (t2 == 'A' && t3 == 'W') v->init(false, otl_var_raw_long, adb.get_max_long_size(), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct()); break; case 'S': #if defined(OTL_ORA_SDO_GEOMETRY) if(t2 == 'D') v->init(false, otl_var_sdo_geometry, adb.get_max_long_size(), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(),0,adb.get_connect_struct().getGeometryTDO()); else #endif v->init(false, otl_var_short, sizeof(short), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); break; case 'L': if (t2 == 'O' && t3 == 'N') v->init(false, otl_var_long_int, sizeof(long), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else if (t2 == 'T' && t3 == 'Z') v->init(false, otl_var_ltz_timestamp, sizeof(TTimestampStruct), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else { delete v; v = nullptr; } break; case 'T': if (t2 == 'Z') v->init(false, otl_var_tz_timestamp, sizeof(TTimestampStruct), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else if (t2 == 'I' && t3 == 'M') v->init(false, otl_var_timestamp, sizeof(TTimestampStruct), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct(), pl_tab_flag); else { delete v; v = nullptr; } break; case 'V': v->init(false, otl_var_varchar_long, adb.get_max_long_size(), OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb.get_connect_struct()); break; default: delete v; v = nullptr; break; } } return v; } void alloc_host_var_list(otl_tmpl_variable **&vl, int &vl_len, OTL_TMPL_CONNECT &adb, const int status = def) { int j; vl_len = 0; if (!hv[0]) { vl = nullptr; return; } otl_auto_array_ptr *> loc_ptr( container_size_); otl_tmpl_variable **tmp_vl = loc_ptr.get_ptr(); int i = 0; while (hv[i]) { otl_tmpl_variable *vp = alloc_var(hv[i], inout[i], status, adb, pl_tab_size[i]); if (vp == nullptr) { int j2; for (j2 = 0; j2 < vl_len; ++j2) delete tmp_vl[j2]; vl_len = 0; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_12, otl_error_code_12, stm_label_ ? stm_label_ : stm_text_, hv[i]))); } vp->set_name_pos(i + 1); if (vp) { ++vl_len; tmp_vl[vl_len - 1] = vp; } ++i; } if (vl_len > 0) { vl = new otl_tmpl_variable *[OTL_SCAST(size_t,vl_len)]; for (j = 0; j < vl_len; ++j) vl[j] = tmp_vl[j]; } } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_ext_hv_decl(const otl_tmpl_ext_hv_decl< TVariableStruct, TTimestampStruct, TExceptionStruct, TConnectStruct, TCursorStruct> &) = delete; otl_tmpl_ext_hv_decl & operator=(const otl_tmpl_ext_hv_decl &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_ext_hv_decl( otl_tmpl_ext_hv_decl &&) = delete; otl_tmpl_ext_hv_decl & operator=( otl_tmpl_ext_hv_decl &&) = delete; #endif private: #else otl_tmpl_ext_hv_decl(const otl_tmpl_ext_hv_decl< TVariableStruct, TTimestampStruct, TExceptionStruct, TConnectStruct, TCursorStruct> &) : hv(nullptr), inout(nullptr), pl_tab_size(0), array_size(0), prev_array_size(0), vst(), len(0), stm_text_(nullptr), stm_label_(nullptr), container_size_(0), has_plsql_tabs_or_refcur_(0) {} otl_tmpl_ext_hv_decl & operator=(const otl_tmpl_ext_hv_decl &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_ext_hv_decl( otl_tmpl_ext_hv_decl &&) : hv(nullptr), inout(nullptr), pl_tab_size(0), array_size(0), prev_array_size(0), vst(), len(0), stm_text_(nullptr), stm_label_(nullptr), container_size_(0), has_plsql_tabs_or_refcur_(0) {} otl_tmpl_ext_hv_decl & operator=( otl_tmpl_ext_hv_decl &&) { return *this; } #endif #endif }; template class otl_tmpl_select_cursor : public OTL_TMPL_CURSOR { protected: int cur_row; int cur_size; int row_count; int array_size; int prefetch_array_size; TSelectCursorStruct select_cursor_struct; otl_select_struct_override local_override; void *master_stream_ptr_; public: TSelectCursorStruct &get_select_cursor_struct() { return select_cursor_struct; } otl_tmpl_select_cursor(OTL_TMPL_CONNECT &pdb, void *master_stream_ptr, const otl_stream_buffer_size_type arr_size = 1, const char *sqlstm_label = nullptr) : OTL_TMPL_CURSOR(pdb), cur_row(-1), cur_size(0), row_count(0), array_size(0), prefetch_array_size(0), select_cursor_struct(), local_override(), master_stream_ptr_(master_stream_ptr) { local_override.reset(); if (sqlstm_label != nullptr) { if (this->stm_label != nullptr) { delete[] this->stm_label; this->stm_label = nullptr; } size_t len = strlen(sqlstm_label) + 1; this->stm_label = new char[len]; OTL_STRCPY_S(this->stm_label, len, sqlstm_label); } select_cursor_struct.set_arr_size(arr_size, array_size, prefetch_array_size); select_cursor_struct.init(array_size); } otl_tmpl_select_cursor() : OTL_TMPL_CURSOR(), master_stream_ptr_(nullptr) {} void open(OTL_TMPL_CONNECT &db, otl_stream_buffer_size_type arr_size = 1) { local_override.reset(); cur_row = -1; row_count = 0; cur_size = 0; array_size = arr_size; OTL_TMPL_CURSOR::open(db); } void close(const char = 'N') { local_override.reset(); OTL_TMPL_CURSOR::close(); } OTL_NODISCARD int first(void) { if (!OTL_TMPL_CURSOR::connected) return 0; select_cursor_struct.set_prefetch_size(prefetch_array_size); int rc = select_cursor_struct.first(this->cursor_struct, cur_row, cur_size, row_count, this->eof_data, array_size); OTL_TRACE_FIRST_FETCH if (!rc) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label ? this->stm_label : this->stm_text))); } return cur_size != 0; } OTL_NODISCARD int next_throw(void) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label ? this->stm_label : this->stm_text))); } OTL_NODISCARD int next(void) { if (!this->connected) return 0; if (cur_row == -1) return first(); int rc = select_cursor_struct.next(this->cursor_struct, cur_row, cur_size, row_count, this->eof_data, array_size); if (!rc) { return next_throw(); } OTL_TRACE_NEXT_FETCH return cur_size != 0; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_select_cursor(const otl_tmpl_select_cursor &) = delete; otl_tmpl_select_cursor &operator=(const otl_tmpl_select_cursor &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_select_cursor(otl_tmpl_select_cursor &&) = delete; otl_tmpl_select_cursor &operator=(otl_tmpl_select_cursor &&) = delete; #endif private: #else otl_tmpl_select_cursor(const otl_tmpl_select_cursor &) : OTL_TMPL_CURSOR(), cur_row(-1), cur_size(0), row_count(0), array_size(0), prefetch_array_size(0), select_cursor_struct(), local_override() {} otl_tmpl_select_cursor &operator=(const otl_tmpl_select_cursor &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_select_cursor(otl_tmpl_select_cursor &&) : OTL_TMPL_CURSOR(), cur_row(-1), cur_size(0), row_count(0), array_size(0), prefetch_array_size(0), select_cursor_struct(), local_override() {} otl_tmpl_select_cursor &operator=(otl_tmpl_select_cursor &&) { return *this; } #endif #endif }; #if defined(OTL_ORA8) || defined(OTL_ODBC) #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED) #define OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_mode_enum:: enum class otl_lob_stream_mode_enum : unsigned char { otl_lob_stream_read_mode = 1, otl_lob_stream_write_mode = 2, otl_lob_stream_zero_mode = 3 }; #else #define OTL_LOB_STREAM_MODE_ENUM typedef unsigned char otl_lob_stream_mode_enum; const otl_lob_stream_mode_enum otl_lob_stream_read_mode = 1; const otl_lob_stream_mode_enum otl_lob_stream_write_mode = 2; const otl_lob_stream_mode_enum otl_lob_stream_zero_mode = 3; #endif #if defined(OTL_ANSI_CPP_11_ENUM_IS_SUPPORTED) #define OTL_LOB_STREAM_PIECE_ENUM otl_lob_stream_piece_enum:: enum class otl_lob_stream_piece_enum : unsigned char { otl_lob_stream_first_piece = 1, otl_lob_stream_next_piece = 2, otl_lob_stream_las_piece = 3 }; #else #define OTL_LOB_STREAM_MODE_ENUM typedef unsigned char otl_lob_stream_piece_enum; const otl_lob_stream_piece_enum otl_lob_stream_first_piece = 1; const otl_lob_stream_piece_enum otl_lob_stream_next_piece = 2; const otl_lob_stream_piece_enum otl_lob_stream_last_piece = 3; #endif class otl_lob_stream_generic { protected: int mode; int retcode; int ndx; int offset; int lob_len; int in_destructor; int eof_flag; int lob_is_null; bool ora_lob; public: OTL_NODISCARD int get_ora_lob() const { return ora_lob; } otl_lob_stream_generic(const bool aora_lob = true) : mode(0), retcode(0), ndx(0), offset(0), lob_len(0), in_destructor(0), eof_flag(0), lob_is_null(0), ora_lob(aora_lob) {} virtual ~otl_lob_stream_generic() OTL_THROWS_OTL_EXCEPTION2 {} virtual void init(void *avar, void *aconnect, void *acursor, int andx, int amode, const int alob_is_null = 0) = 0; virtual void set_len(const int new_len = 0) = 0; virtual otl_lob_stream_generic &operator<<(const otl_long_string &s) = 0; virtual otl_lob_stream_generic &operator>>(otl_long_string &s) = 0; #if (defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS)) && \ !defined(OTL_UNICODE) virtual otl_lob_stream_generic &operator<<(const OTL_STRING_CONTAINER &s) = 0; virtual otl_lob_stream_generic &operator>>(OTL_STRING_CONTAINER &s) = 0; virtual void setStringBuffer(const int chunk_size) = 0; #endif #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) virtual otl_lob_stream_generic &operator<<(OTL_STD_STRING_VIEW_CLASS s) = 0; #endif OTL_NODISCARD virtual int eof(void) = 0; OTL_NODISCARD virtual int len(void) = 0; OTL_NODISCARD virtual bool is_initialized(void) = 0; virtual void close(bool dont_throw_size_doesnt_match_exception = false) = 0; private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_lob_stream_generic(const otl_lob_stream_generic &) = delete; otl_lob_stream_generic &operator=(const otl_lob_stream_generic &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_lob_stream_generic(otl_lob_stream_generic &&) = delete; otl_lob_stream_generic &operator=(otl_lob_stream_generic &&) = delete; #endif private: #else otl_lob_stream_generic(const otl_lob_stream_generic &) : mode(0), retcode(0), ndx(0), offset(0), lob_len(0), in_destructor(0), eof_flag(0), lob_is_null(0), ora_lob(false) {} otl_lob_stream_generic &operator=(const otl_lob_stream_generic &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_lob_stream_generic(otl_lob_stream_generic &&) : mode(0), retcode(0), ndx(0), offset(0), lob_len(0), in_destructor(0), eof_flag(0), lob_is_null(0), ora_lob(false) {} otl_lob_stream_generic &operator=(otl_lob_stream_generic &&) { return *this; } #endif #endif }; #endif #if defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS) || \ defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS) || \ defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS) #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT #endif #else #if defined(_MSC_VER) && (_MSC_VER <= 1300) #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT #endif #endif #if defined(__SUNPRO_CC) || defined(__HP_aCC) || defined(__BORLANDC__) #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT #endif #endif #if defined(__IBMC__) || defined(__IBMCPP__) || defined(__xlC__) #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT #endif #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ (__GNUC__ * 100 + __GNUC_MINOR__ == 400) #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT #endif #endif #if defined(__GNUC__) && (__GNUC__ <= 3) #if !defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) #define OTL_NO_TMPL_MEMBER_FUNC_SUPPORT #endif #endif #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) #define OTL_OPERATOR_1(strp,var,T,T_type,oper) (*strp)->operator oper(var); #else #define OTL_OPERATOR_1(strp,var,T,T_type,oper) (*strp)->operator oper(var); #endif #if defined(OTL_PARANOID_EOF) #define OTL_PARANOID_EOF_THROW(T) throw_if_eof_was_already_reached(last_eof_rc, T); #else #define OTL_PARANOID_EOF_THROW(T) #endif #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) #define OTL_DEFAULT_NULL_ASSIGN(T,v) \ if ((*this).is_null()) \ v = OTL_SCAST(T, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #else #define OTL_DEFAULT_NULL_ASSIGN(T,v) #endif #if defined(OTL_ORA_SDO_GEOMETRY) struct oci_spatial_geometry; #endif #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) || \ defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) #include #endif template class otl_tmpl_select_stream : public OTL_TMPL_SELECT_CURSOR { protected: otl_column_desc *sl_desc; otl_tmpl_variable *sl; int sl_len; int null_fetched; int cur_col; int cur_in; int executed; int eof_status; char var_info[256]; otl_select_struct_override *override_; int delay_next; bool lob_stream_mode; long _rfc; long rewind_calls; public: OTL_NODISCARD int get_select_row_count() const { return this->cur_row == -1 ? 0 : this->cur_size - this->cur_row; } OTL_NODISCARD int get_prefetched_row_count() const { return this->row_count; } OTL_NODISCARD int get_row_count() const { return this->row_count; } OTL_NODISCARD int get_sl_len() const { return sl_len; } OTL_NODISCARD otl_tmpl_variable *get_sl() { return sl; } OTL_NODISCARD otl_column_desc *get_sl_desc() { return sl_desc; } OTL_NODISCARD long get_rfc() const { return _rfc; } void cleanup(void) { int i; delete[] sl; for (i = 0; i < this->vl_len; ++i) delete this->vl[i]; delete[] this->vl; delete[] sl_desc; } virtual ~otl_tmpl_select_stream() OTL_THROWS_OTL_EXCEPTION3 { cleanup(); } otl_tmpl_select_stream(otl_select_struct_override *aoverride, const otl_stream_buffer_size_type arr_size, const char *sqlstm, OTL_TMPL_CONNECT &pdb, const int implicit_select = otl_explicit_select, const char *sqlstm_label = nullptr) : OTL_TMPL_SELECT_CURSOR(pdb, aoverride->get_master_stream_ptr(), arr_size, sqlstm_label), sl_desc(nullptr), sl(nullptr), sl_len(0), null_fetched(0), cur_col(0), cur_in(0), executed(0), eof_status(0), var_info(), override_(nullptr), delay_next(0), lob_stream_mode(false), _rfc(0), rewind_calls(0) { int i; #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) if (pdb.get_fetch_scroll_mode()) this->select_cursor_struct.set_fetch_scroll_flag(); // set fetch scroll flag as soon as possible #endif this->select_cursor_struct.set_select_type(implicit_select); sl = nullptr; sl_len = 0; _rfc = 0; null_fetched = 0; lob_stream_mode = aoverride->get_lob_stream_mode(); this->retcode = 0; sl_desc = nullptr; executed = 0; cur_in = 0; this->stm_text = nullptr; eof_status = 1; override_ = aoverride; bool out_or_inout_variable_flag = false; bool bind_var_terminator_is_missing = false; { size_t len = strlen(sqlstm) + 1; this->stm_text = new char[len]; OTL_STRCPY_S(this->stm_text, len, sqlstm); otl_select_struct_override *temp_local_override = &this->local_override; otl_tmpl_ext_hv_decl hvd(this->stm_text, 1, this->stm_label, &temp_local_override, &pdb); if (hvd.get_vst(1) > 0 || hvd.get_vst(2) > 0) out_or_inout_variable_flag = true; hvd.alloc_host_var_list(this->vl, this->vl_len, pdb); if (temp_local_override != &this->local_override) delete temp_local_override; bind_var_terminator_is_missing = hvd.bind_var_terminator_is_missing(); } if (out_or_inout_variable_flag) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_39, otl_error_code_39, this->stm_label ? this->stm_label : this->stm_text))); } if (bind_var_terminator_is_missing) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_43, otl_error_code_43, this->stm_label ? this->stm_label : this->stm_text))); } try { if(implicit_select == otl_direct_exec_select) this->parse(1); else this->parse(); if (this->select_cursor_struct.get_implicit_cursor()!=otl_implicit_select) { get_select_list(); bind_all(); } else { for (i = 0; i < this->vl_len; ++i) this->bind(*this->vl[i]); } if (this->vl_len == 0) { rewind(); null_fetched = 0; } } catch (OTL_CONST_EXCEPTION OTL_TMPL_EXCEPTION &) { cleanup(); throw; } if (bind_var_terminator_is_missing) { } // this is to fix a compiler warning } void rewind(void) { OTL_TRACE_STREAM_EXECUTION int i; _rfc = 0; ++rewind_calls; if (!this->select_cursor_struct.close_select(this->cursor_struct)) { OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label ? this->stm_label : this->stm_text))); } if(this->select_cursor_struct.get_implicit_cursor()==otl_direct_exec_select && rewind_calls>1){ OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_47, otl_error_code_47, this->stm_label ? this->stm_label : this->stm_text))); } if (this->select_cursor_struct.get_implicit_cursor()==otl_implicit_select) { this->exec(1, 0, otl_sql_exec_from_select_cursor_class); if (sl) { delete[] sl; sl = nullptr; } get_select_list(); for (i = 0; i < sl_len; ++i) this->bind(sl[i]); } eof_status = this->first(); null_fetched = 0; cur_col = -1; cur_in = 0; executed = 1; delay_next = 0; } void clean(void) { _rfc = 0; this->cursor_struct.set_canceled(false); null_fetched = 0; cur_col = -1; cur_in = 0; executed = 0; eof_status = 0; delay_next = 0; this->cur_row = -1; this->row_count = 0; this->cur_size = 0; if (!this->select_cursor_struct.close_select(this->cursor_struct)) { OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label ? this->stm_label : this->stm_text))); } } OTL_NODISCARD int is_null(void) { return null_fetched; } OTL_NODISCARD int eof(void) { #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH) if (cur_col == sl_len - 1) { get_next(); cur_col = -1; } else { if (delay_next) { look_ahead(); delay_next = 0; } } return !eof_status; #else if (delay_next) { look_ahead(); delay_next = 0; } return !eof_status; #endif } OTL_NODISCARD int eof_intern(void) { return !eof_status; } void skip_to_end_of_row() { check_if_executed(); if (eof_intern()) return; while (cur_col < sl_len - 1) { ++cur_col; null_fetched = sl[cur_col].is_null(this->cur_row); } eof_status = this->next(); cur_col = 0; if (!eof_intern()) cur_col = -1; ++_rfc; } void skip_to_next_var() { check_if_executed(); if (eof_intern()) return; get_next(); look_ahead(); } void bind_all(void) { int i; for (i = 0; i < this->vl_len; ++i) this->bind(*this->vl[i]); for (i = 0; i < sl_len; ++i) this->bind(sl[i]); } void get_select_list(void) { int j; otl_auto_array_ptr loc_ptr(otl_var_list_size); otl_column_desc *sl_desc_tmp = loc_ptr.get_ptr(); int sld_tmp_len = 0; int ftype, elem_size, i; for (i = 1; this->describe_column(sl_desc_tmp[i - 1], i); ++i) { int temp_code_type = otl_tmpl_variable::int2ext( sl_desc_tmp[i - 1].dbtype); if (temp_code_type == otl_unsupported_type) { #ifdef OTL_ORA_SDO_GEOMETRY if(sl_desc_tmp[i - 1].name_type && strcmp(sl_desc_tmp[i - 1].name_type, "SDO_GEOMETRY") != 0){ otl_var_info_col3(i - 1, sl_desc_tmp[i - 1].dbtype, sl_desc_tmp[i - 1].name, this->var_info, sizeof(this->var_info)); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_27, otl_error_code_27, this->stm_label ? this->stm_label : this->stm_text, this->var_info))); } #else otl_var_info_col3(i - 1, sl_desc_tmp[i - 1].dbtype, sl_desc_tmp[i - 1].name, this->var_info, sizeof(this->var_info)); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_27, otl_error_code_27, this->stm_label ? this->stm_label : this->stm_text, this->var_info))); #endif // OTL_ORA_SDO_GEOMETRY } ++sld_tmp_len; if (sld_tmp_len == loc_ptr.get_arr_size()) { loc_ptr.double_size(); sl_desc_tmp = loc_ptr.get_ptr(); } } sl_len = sld_tmp_len; if (sl) { delete[] sl; sl = nullptr; } sl = new otl_tmpl_variable[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)]; int max_long_size = this->adb->get_max_long_size(); for (j = 0; j < sl_len; ++j) { otl_tmpl_variable::map_ftype( sl_desc_tmp[j], max_long_size, ftype, elem_size, this->local_override.getLen() > 0 ? this->local_override : *override_, j + 1, this->adb->get_connect_struct().get_connection_type()); sl[j].copy_pos(j + 1); #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) if (sl_desc_tmp[j].charset_form == 2) sl[j].get_var_struct().set_nls_flag(true); #endif sl[j].init(true, ftype, elem_size, OTL_SCAST(otl_stream_buffer_size_type, (this->array_size)), &this->adb->get_connect_struct() #if defined(OTL_ORA_SDO_GEOMETRY) ,0, sl_desc_tmp[j].colOCIType #endif ); sl[j].get_var_struct().set_lob_stream_mode(this->lob_stream_mode); } if (sl_desc) { delete[] sl_desc; sl_desc = nullptr; } sl_desc = new otl_column_desc[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)]; for (j = 0; j < sl_len; ++j) sl_desc[j] = sl_desc_tmp[j]; } void check_if_executed_throw(void) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_2, otl_error_code_2, this->stm_label ? this->stm_label : this->stm_text, nullptr))); } void check_if_executed(void) { if (!executed) { check_if_executed_throw(); } } OTL_NODISCARD int check_type_throw(int type_code, int actual_data_type) { int out_type_code; if (actual_data_type != 0) out_type_code = actual_data_type; else out_type_code = type_code; otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), out_type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, var_info))); } #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) void strict_check_throw(int type_code) { otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, var_info))); } #endif OTL_NODISCARD int check_type(int type_code, int actual_data_type = 0) { switch (sl[cur_col].get_ftype()) { case otl_var_timestamp: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: if (type_code == otl_var_timestamp) return 1; break; default: #if defined(OTL_CHECK_OUT_TYPE_FUNC) if ((sl[cur_col].get_ftype() == type_code) || OTL_CHECK_OUT_TYPE_FUNC(sl[cur_col].get_ftype(),type_code)) return 1; break; #else if (sl[cur_col].get_ftype() == type_code) return 1; break; #endif } return check_type_throw(type_code, actual_data_type); } void get_next(void) { if (cur_col < sl_len - 1) { ++cur_col; null_fetched = sl[cur_col].is_null(this->cur_row); } else { eof_status = this->next(); cur_col = 0; } } void look_ahead(void) { if (cur_col == sl_len - 1) { #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH) #else eof_status = this->next(); cur_col = -1; #endif ++_rfc; } } OTL_TMPL_SELECT_STREAM &operator>>(char &c) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { c = *OTL_RCAST(char *, sl[cur_col].val(this->cur_row)); look_ahead(); } return *this; } OTL_TMPL_SELECT_STREAM &operator>>(unsigned char &c) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { c = *OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)); look_ahead(); } return *this; } #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) OTL_TMPL_SELECT_STREAM &operator>>(OTL_STRING_CONTAINER &s) { check_if_executed(); if (eof_intern()) return *this; get_next(); switch (sl[cur_col].get_ftype()) { case otl_var_raw: { int len2; if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)); if (sl[cur_col].get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter) { len2 = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c)); c += sizeof(short int); } else len2 = sl[cur_col].get_len(this->cur_row); #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(OTL_USER_DEFINED_STRING_CLASS_ON)) s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len2)); #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, c), len2); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, c), len2, 1); #endif look_ahead(); } } break; case otl_var_char: if (!eof_intern()) { #if defined(OTL_ACE) s.set(OTL_RCAST(char *, sl[cur_col].val(this->cur_row)), 1); #else s = OTL_RCAST(char *, sl[cur_col].val(this->cur_row)); #endif look_ahead(); } break; #if defined(OTL_USER_DEFINED_STRING_CLASS_ON) || defined(OTL_STL) || \ defined(OTL_ACE) case otl_var_varchar_long: case otl_var_raw_long: if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)); int len = sl[cur_col].get_len(this->cur_row); int buf_sz = sl[cur_col].get_elem_size(); if (len > buf_sz || len<0) len = buf_sz; #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(OTL_USER_DEFINED_STRING_CLASS_ON)) s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len)); #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, c), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, c), len, 1); #endif look_ahead(); } break; case otl_var_blob: case otl_var_clob: if (!eof_intern()) { int len = 0; int max_long_sz = this->adb->get_max_long_size(); otl_auto_array_ptr loc_ptr(max_long_sz); unsigned char *temp_buf = loc_ptr.get_ptr(); int rc = sl[cur_col].get_var_struct().get_blob(this->cur_row, temp_buf, max_long_sz, len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(OTL_USER_DEFINED_STRING_CLASS_ON)) s.assign(OTL_RCAST(char *, temp_buf), OTL_SCAST(size_t, len)); #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, temp_buf), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, temp_buf), len, 1); #endif look_ahead(); } break; #endif default: (void)check_type(otl_var_char); } // switch return *this; } #endif OTL_TMPL_SELECT_STREAM &operator>>(char *s) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, sl[cur_col].val(this->cur_row))); look_ahead(); } return *this; } void getString(char *s, int max_size) { check_if_executed(); if (eof_intern()) return; get_next(); if (check_type(otl_var_char) && !eof_intern()) { if(max_sizecur_row)){ otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), const_STD_CHAR_ARRAY_code, var_info, sizeof(var_info)); OTL_THROW((otl_tmpl_exception(otl_error_msg_45, otl_error_code_45, this->stm_label ? this->stm_label : this->stm_text, this->var_info))); } otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, sl[cur_col].val(this->cur_row))); look_ahead(); } } #if defined(OTL_UNICODE_STRING_TYPE) OTL_TMPL_SELECT_STREAM &operator<<(const OTL_UNICODE_STRING_TYPE &s) { check_in_var(); if (check_in_type(otl_var_char, 1)) { int overflow; #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE) otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.OTL_C_STR_FOR_UNICODE_STRING_TYPE())), #else otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.c_str())), #endif overflow, this->vl[cur_in]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info, OTL_RCAST(const void *, s.c_str()), OTL_SCAST(int, this->vl[cur_in]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info))); #endif } this->vl[cur_in]->set_not_null(0); } get_in_next(); return *this; } #endif #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)) OTL_TMPL_SELECT_STREAM &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) { check_in_var(); if (check_in_type(otl_var_char, 1)) { int overflow; otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.data())), overflow, this->vl[cur_in]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info, OTL_RCAST(const void *, s.data()), OTL_SCAST(int, this->vl[cur_in]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info))); #endif } this->vl[cur_in]->set_not_null(0); } get_in_next(); return *this; } #endif #if defined(OTL_UNICODE_STRING_TYPE) OTL_TMPL_SELECT_STREAM &operator>>(OTL_UNICODE_STRING_TYPE &s) { check_if_executed(); if (eof_intern()) return *this; get_next(); switch (sl[cur_col].get_ftype()) { case otl_var_char: if (!eof_intern()) { #if defined(OTL_ODBC) || defined(DB2_CLI) s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row)); #else #if defined(OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR) OTL_UNICODE_CHAR_TYPE *temp_s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row)); OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR(s, temp_s + 1, *temp_s); #else OTL_UNICODE_CHAR_TYPE *temp_s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row)); s.assign(temp_s + 1, *temp_s); #endif #endif look_ahead(); } break; case otl_var_varchar_long: if (!eof_intern()) { #if defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES) int source_len = sl[cur_col].get_var_struct().get_len(this->cur_row); OTL_CHAR *source = OTL_RCAST(OTL_CHAR *, sl[cur_col].val(this->cur_row)); s.assign(OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, source), OTL_SCAST(size_t, source_len)); #else s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row)); #endif look_ahead(); } break; case otl_var_clob: if (!eof_intern()) { int len = 0; int max_long_sz = this->adb->get_max_long_size(); otl_auto_array_ptr loc_ptr(max_long_sz); unsigned char *temp_buf = OTL_RCAST(unsigned char *, loc_ptr.get_ptr()); int rc = sl[cur_col].get_var_struct().get_blob(this->cur_row, temp_buf, max_long_sz, len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, temp_buf); look_ahead(); } break; default: (void)check_type(otl_var_char); } return *this; } #endif OTL_TMPL_SELECT_STREAM &operator>>(unsigned char *s) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { otl_strcpy2(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)), sl[cur_col].get_len(this->cur_row)); look_ahead(); } return *this; } #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE) void getString(char16_t *s, int max_size) { check_if_executed(); if (eof_intern()) return; get_next(); if (check_type(otl_var_char) && !eof_intern()) { if(max_sizecur_row)){ otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), const_STD_UNICODE_CHAR_ARRAY_code, var_info, sizeof(var_info)); OTL_THROW((otl_tmpl_exception(otl_error_msg_46, otl_error_code_46, this->stm_label ? this->stm_label : this->stm_text, this->var_info))); } otl_strcpy2(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)), sl[cur_col].get_len(this->cur_row)); look_ahead(); } } #endif #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) #if !defined(OTL_D1) #define OTL_D1(T, T_type) \ OTL_TMPL_SELECT_STREAM &operator>>(T &n) { \ check_if_executed(); \ if (eof_intern()) \ return *this; \ get_next(); \ if (!eof_intern()) { \ int match_found = otl_numeric_convert_T( \ sl[cur_col].get_ftype(), sl[cur_col].val(this->cur_row), n); \ if (!match_found) \ strict_check_throw(T_type); \ look_ahead(); \ } \ return *this; \ } #endif #else #if defined(OTL_ORA_SDO_GEOMETRY) OTL_TMPL_SELECT_STREAM &operator >> (oci_spatial_geometry &s) { check_if_executed(); if(eof_intern()) return *this; get_next(); if(check_type(otl_var_sdo_geometry) && !eof_intern()){ (void)sl[cur_col].get_var_struct().read_geometry(s, this->cur_row); look_ahead(); } return *this; } #endif #if !defined(OTL_D1) #define OTL_D1(T, T_type) \ OTL_TMPL_SELECT_STREAM &operator>>(T &n) { \ check_if_executed(); \ if (eof_intern()) \ return *this; \ get_next(); \ if (!eof_intern()) { \ int match_found = otl_numeric_convert_T( \ sl[cur_col].get_ftype(), sl[cur_col].val(this->cur_row), n); \ if (!match_found) { \ if (check_type(otl_var_double, T_type)) \ n = OTL_PCONV(T, double, sl[cur_col].val(this->cur_row)); \ } \ look_ahead(); \ } \ return *this; \ } #endif #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) OTL_D1(int, otl_var_int) #if defined(OTL_BIGINT) OTL_D1(OTL_BIGINT, otl_var_bigint) #endif #if defined(OTL_UBIGINT) OTL_D1(OTL_UBIGINT, otl_var_ubigint) #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) && \ !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS) OTL_D1(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1) #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \ !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS) OTL_D1(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2) #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \ !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS) OTL_D1(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3) #endif OTL_D1(unsigned, otl_var_unsigned_int) OTL_D1(long, otl_var_long_int) OTL_D1(short, otl_var_short) OTL_D1(float, otl_var_float) OTL_D1(double, otl_var_double) #else template OTL_D1(T,T_type) #endif OTL_TMPL_SELECT_STREAM &operator>>(TTimestampStruct &t) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_timestamp) && !eof_intern()) { TTimestampStruct *tm = OTL_RCAST(TTimestampStruct *, sl[cur_col].val(this->cur_row)); int rc = sl[cur_col].get_var_struct().read_dt(&t, tm, sizeof(TTimestampStruct)); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } look_ahead(); } return *this; } OTL_TMPL_SELECT_STREAM &operator>>(otl_long_string &s) { check_if_executed(); if (eof_intern()) return *this; get_next(); switch (sl[cur_col].get_ftype()) { case otl_var_raw_long: { if (s.get_unicode_flag()) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)); int len2 = sl[cur_col].get_len(this->cur_row); if (len2 > s.get_buf_size()) len2 = s.get_buf_size(); otl_memcpy(s.v, c, len2, sl[cur_col].get_ftype()); s.set_len(len2); look_ahead(); } } break; case otl_var_varchar_long: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (s.get_unicode_flag() != in_unicode_mode) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } if (!eof_intern()) { if (sl[cur_col].get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter) { #if defined(OTL_UNICODE) int len2 = 0; OTL_CHAR *source = OTL_RCAST(OTL_CHAR *, sl[cur_col].val(this->cur_row)); OTL_CHAR *target = OTL_RCAST(OTL_CHAR *, s.v); #if defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES) int source_len = sl[cur_col].get_var_struct().get_len(this->cur_row); while (*source && len2 < s.get_buf_size() && len2 < source_len) { *target++ = *source++; ++len2; } #else while (*source && len2 < s.get_buf_size()) { *target++ = *source++; ++len2; } #endif s.null_terminate_string(len2); s.set_len(len2); look_ahead(); #else unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)); int len2 = sl[cur_col].get_len(this->cur_row); if (len2 > s.get_buf_size()) len2 = s.get_buf_size(); otl_memcpy(s.v, c, len2, sl[cur_col].get_ftype()); s.null_terminate_string(len2); s.set_len(len2); look_ahead(); #endif } else { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)); int len2 = sl[cur_col].get_len(this->cur_row); if (len2 > s.get_buf_size()) len2 = s.get_buf_size(); otl_memcpy(s.v, c, len2, sl[cur_col].get_ftype()); s.null_terminate_string(len2); s.set_len(len2); look_ahead(); } } } break; case otl_var_raw: { if (s.get_unicode_flag()) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)); if (sl[cur_col].get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter) { int len2 = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c)); otl_memcpy(s.v, c + sizeof(short int), len2, sl[cur_col].get_ftype()); s.set_len(len2); } else { int len2 = sl[cur_col].get_len(this->cur_row); if (len2 > s.get_buf_size()) len2 = s.get_buf_size(); otl_memcpy(s.v, c, len2, sl[cur_col].get_ftype()); s.set_len(len2); } look_ahead(); } } break; case otl_var_blob: case otl_var_clob: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && sl[cur_col].get_ftype() == otl_var_clob) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && sl[cur_col].get_ftype() == otl_var_blob) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } if (!eof_intern()) { int len = 0; int rc = sl[cur_col].get_var_struct().get_blob(this->cur_row, s.v, s.get_buf_size(), len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } if (len > s.get_buf_size()) len = s.get_buf_size(); s.set_len(len); if (sl[cur_col].get_ftype() == otl_var_clob) s.null_terminate_string(len); look_ahead(); } } break; default: { char tmp_var_info[256]; otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), otl_var_long_string, tmp_var_info, sizeof(tmp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, tmp_var_info))); } } return *this; } #if defined(OTL_ORA8) || defined(OTL_ODBC) OTL_TMPL_SELECT_STREAM &operator>>(otl_lob_stream_generic &s) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (s.get_ora_lob() && (sl[cur_col].get_ftype() == otl_var_blob || sl[cur_col].get_ftype() == otl_var_clob) && !eof_intern()) { s.init(OTL_RCAST(void *, &sl[cur_col]), OTL_RCAST(void *, this->adb), OTL_RCAST(void *, this), this->cur_row, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode), this->is_null()); delay_next = 1; } else if ((sl[cur_col].get_ftype() == otl_var_varchar_long || sl[cur_col].get_ftype() == otl_var_raw_long) && !eof_intern()) { s.init(OTL_RCAST(void *, &sl[cur_col]), OTL_RCAST(void *, this->adb), OTL_RCAST(void *, this), this->cur_row, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)); delay_next = 1; } else { char tmp_var_info[256]; otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), otl_var_long_string, tmp_var_info, sizeof(tmp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, tmp_var_info))); } return *this; } #endif int check_in_type_throw(int type_code) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, var_info))); } OTL_NODISCARD int check_in_type(int type_code, int tsize) { switch (this->vl[cur_in]->get_ftype()) { case otl_var_char: if (type_code == otl_var_char) return 1; break; case otl_var_raw: if (type_code == otl_var_raw) return 1; break; case otl_var_db2date: case otl_var_db2time: case otl_var_timestamp: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: if (type_code == otl_var_timestamp) return 1; break; default: #if defined(OTL_CHECK_IN_TYPE_FUNC) if ((this->vl[cur_in]->get_ftype() == type_code && this->vl[cur_in]->get_elem_size() == tsize) || OTL_CHECK_IN_TYPE_FUNC(this->vl[cur_in]->get_ftype(),type_code)) return 1; break; #else if (this->vl[cur_in]->get_ftype() == type_code && this->vl[cur_in]->get_elem_size() == tsize) return 1; break; #endif } return check_in_type_throw(type_code); } void check_in_var_throw(void) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_1, otl_error_code_1, this->stm_label ? this->stm_label : this->stm_text, nullptr))); } void check_in_var(void) { if (this->vl_len == 0) check_in_var_throw(); } void get_in_next(void) { if (cur_in == this->vl_len - 1) rewind(); else { ++cur_in; executed = 0; } } OTL_TMPL_SELECT_STREAM &operator<<(OTL_NULL_PARM /* n */) { check_in_var(); this->vl[cur_in]->set_null(0); get_in_next(); return *this; } OTL_TMPL_SELECT_STREAM &operator<<(const char c) { check_in_var(); if (check_in_type(otl_var_char, 1)) { char *tmp = OTL_RCAST(char *, this->vl[cur_in]->val()); tmp[0] = c; tmp[1] = 0; this->vl[cur_in]->set_not_null(0); } get_in_next(); return *this; } OTL_TMPL_SELECT_STREAM &operator<<(const unsigned char c) { check_in_var(); if (check_in_type(otl_var_char, 1)) { unsigned char *tmp = OTL_RCAST(unsigned char *, this->vl[cur_in]->val()); tmp[0] = c; tmp[1] = 0; this->vl[cur_in]->set_not_null(0); } get_in_next(); return *this; } OTL_TMPL_SELECT_STREAM &operator<<(const char *s) { check_in_var(); if (check_in_type(otl_var_char, 1)) { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s)), overflow, this->vl[cur_in]->get_elem_size()); if (overflow) { char tmp_var_info[256]; otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_char, tmp_var_info, sizeof(tmp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, tmp_var_info, OTL_RCAST(const void *, s), OTL_SCAST(int, this->vl[cur_in]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, tmp_var_info))); #endif } this->vl[cur_in]->set_not_null(0); } get_in_next(); return *this; } #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template OTL_TMPL_SELECT_STREAM &operator<<(const std::array& s){ (*this)< OTL_TMPL_SELECT_STREAM &operator<<(const std::array& s){ (*this)<vl[cur_in]->get_ftype()) { case otl_var_varchar_long: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0)); int len = OTL_CCAST(otl_long_string *, &s)->len(); this->vl[cur_in]->set_not_null(0); if (len > this->vl[cur_in]->actual_elem_size()) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } otl_memcpy(c, s.v, len, this->vl[cur_in]->get_ftype()); this->vl[cur_in]->set_len(len, 0); } break; case otl_var_raw_long: { if (s.get_unicode_flag()) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0)); int len = OTL_CCAST(otl_long_string *, &s)->len(); if (len > this->vl[cur_in]->actual_elem_size()) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_in]->set_not_null(0); otl_memcpy(c, s.v, len, this->vl[cur_in]->get_ftype()); this->vl[cur_in]->set_len(len, 0); } break; case otl_var_raw: { if (s.get_unicode_flag()) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0)); int len = OTL_CCAST(otl_long_string *, &s)->len(); if (len > this->vl[cur_in]->actual_elem_size()) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_raw, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_in]->set_not_null(0); if ((this->vl[cur_in]->get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter) && this->vl[cur_in]->get_ftype() == otl_var_raw) { otl_memcpy(c + sizeof(unsigned short), s.v, len, this->vl[cur_in]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) = OTL_SCAST(unsigned short, len); this->vl[cur_in]->set_len(len, 0); } else { otl_memcpy(c, s.v, len, this->vl[cur_in]->get_ftype()); this->vl[cur_in]->set_len(len, 0); } } break; } get_in_next(); return *this; } #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) OTL_TMPL_SELECT_STREAM &operator<<(const OTL_STRING_CONTAINER &s) { check_in_var(); if (this->vl[cur_in]->get_ftype() == otl_var_raw) { unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0)); int len = OTL_SCAST(int, s.length()); if (len > this->vl[cur_in]->actual_elem_size()) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_raw, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_in]->set_not_null(0); if ((this->vl[cur_in]->get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter)) { otl_memcpy(c + sizeof(unsigned short), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len, this->vl[cur_in]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) = OTL_SCAST(unsigned short, len); this->vl[cur_in]->set_len(len, 0); } else { otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len, this->vl[cur_in]->get_ftype()); this->vl[cur_in]->set_len(len, 0); } } else if (this->vl[cur_in]->get_ftype() == otl_var_char) { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), overflow, this->vl[cur_in]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info, OTL_RCAST(const void *, s.c_str()), OTL_SCAST(int, this->vl[cur_in]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info))); #endif } this->vl[cur_in]->set_not_null(0); } else check_in_type_throw(otl_var_char); get_in_next(); return *this; } #endif #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) OTL_TMPL_SELECT_STREAM &operator<<(OTL_STD_STRING_VIEW_CLASS s) { check_in_var(); if (this->vl[cur_in]->get_ftype() == otl_var_raw) { unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_in]->val(0)); int len = OTL_SCAST(int, s.length()); if (len > this->vl[cur_in]->actual_elem_size()) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_raw, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_in]->set_not_null(0); if ((this->vl[cur_in]->get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter)) { otl_memcpy(c + sizeof(unsigned short), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len, this->vl[cur_in]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) = OTL_SCAST(unsigned short, len); this->vl[cur_in]->set_len(len, 0); } else { otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len, this->vl[cur_in]->get_ftype()); this->vl[cur_in]->set_len(len, 0); } } else if (this->vl[cur_in]->get_ftype() == otl_var_char) { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), overflow, this->vl[cur_in]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info, OTL_RCAST(const void *, s.data()), OTL_SCAST(int, this->vl[cur_in]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info))); #endif } this->vl[cur_in]->set_not_null(0); } else check_in_type_throw(otl_var_char); get_in_next(); return *this; } #endif OTL_TMPL_SELECT_STREAM &operator<<(const unsigned char *s) { check_in_var(); if (check_in_type(otl_var_char, 1)) { int overflow; otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_in]->val()), OTL_CCAST(unsigned char *, s), overflow, this->vl[cur_in]->get_elem_size()); if (overflow) { char temp_var_info[256]; otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info, OTL_RCAST(const void *, s), OTL_SCAST(int, this->vl[cur_in]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info))); #endif } this->vl[cur_in]->set_not_null(0); } get_in_next(); return *this; } #if !defined(OTL_D2) #define OTL_D2(T, T_type) \ OTL_TMPL_SELECT_STREAM &operator<<(const T n) { \ check_in_var(); \ if (check_in_type(T_type, sizeof(T))) { \ *OTL_RCAST(T *, this->vl[cur_in]->val()) = n; \ } \ this->vl[cur_in]->set_not_null(0); \ get_in_next(); \ return *this; \ } #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) OTL_D2(int, otl_var_int) OTL_D2(unsigned, otl_var_unsigned_int) #if defined(OTL_BIGINT) OTL_D2(OTL_BIGINT, otl_var_bigint) #endif #if defined(OTL_UBIGINT) OTL_D2(OTL_UBIGINT, otl_var_ubigint) #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) OTL_D2(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1) #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) OTL_D2(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2) #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) OTL_D2(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3) #endif OTL_D2(long, otl_var_long_int) OTL_D2(short, otl_var_short) OTL_D2(float, otl_var_float) OTL_D2(double, otl_var_double) #else template OTL_D2(T,T_type) #endif OTL_TMPL_SELECT_STREAM &operator<<(const TTimestampStruct &t) { check_in_var(); if (check_in_type(otl_var_timestamp, sizeof(TTimestampStruct))) { TTimestampStruct *tm = OTL_RCAST(TTimestampStruct *, this->vl[cur_in]->val()); int rc = this->vl[cur_in]->get_var_struct().write_dt( tm, &t, sizeof(TTimestampStruct)); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } } this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } #if defined(OTL_ORA_SDO_GEOMETRY) OTL_TMPL_SELECT_STREAM &operator << (const oci_spatial_geometry &s){ check_in_var(); if(check_in_type(otl_var_sdo_geometry, this->adb->get_max_long_size())){ int rc = this->vl[cur_in]->get_var_struct().write_geometry(s, cur_in); if(rc == 0){ OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } } get_in_next(); return *this; } #endif private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_select_stream(const otl_tmpl_select_stream &) = delete; otl_tmpl_select_stream &operator=(const otl_tmpl_select_stream &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_select_stream(otl_tmpl_select_stream &&) = delete; otl_tmpl_select_stream &operator=(otl_tmpl_select_stream &&) = delete; #endif private: #else otl_tmpl_select_stream(const otl_tmpl_select_stream &) : OTL_TMPL_SELECT_CURSOR(), sl_desc(nullptr), sl(nullptr), sl_len(0), null_fetched(0), cur_col(0), cur_in(0), executed(0), eof_status(0), var_info(), override_(nullptr), delay_next(0), lob_stream_mode(false), _rfc(0) {} otl_tmpl_select_stream &operator=(const otl_tmpl_select_stream &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_select_stream(otl_tmpl_select_stream &&) : OTL_TMPL_SELECT_CURSOR(), sl_desc(nullptr), sl(nullptr), sl_len(0), null_fetched(0), cur_col(0), cur_in(0), executed(0), eof_status(0), var_info(), override_(nullptr), delay_next(0), lob_stream_mode(false), _rfc(0) {} otl_tmpl_select_stream &operator=(otl_tmpl_select_stream &&) { return *this; } #endif #endif }; template class otl_tmpl_out_stream : public OTL_TMPL_CURSOR { protected: int auto_commit_flag; int dirty; int cur_x; int cur_y; otl_stream_buffer_size_type array_size; int in_exception_flag; int in_destruct_flag; int should_delete_flag; char var_info[256]; bool flush_flag; bool flush_flag2; bool lob_stream_mode; void *master_stream_ptr_; public: OTL_NODISCARD int get_dirty_buf_len() const { if (dirty) return cur_y + 1; else return 0; } void set_flush_flag(const bool aflush_flag) { flush_flag = aflush_flag; } void set_flush_flag2(const bool aflush_flag2) { flush_flag2 = aflush_flag2; } void cleanup(void) { int i; if (should_delete_flag) { for (i = 0; i < this->vl_len; ++i) delete this->vl[i]; } delete[] this->vl; } otl_tmpl_out_stream(OTL_TMPL_CONNECT &pdb, void *master_stream_ptr, const bool alob_stream_mode = false, const char *sqlstm_label = nullptr) : OTL_TMPL_CURSOR(pdb), auto_commit_flag(0), dirty(0), cur_x(0), cur_y(0), array_size(0), in_exception_flag(0), in_destruct_flag(0), should_delete_flag(0), var_info(), flush_flag(0), flush_flag2(0), lob_stream_mode(0), master_stream_ptr_(master_stream_ptr) { if (sqlstm_label != nullptr) { if (this->stm_label != nullptr) { delete[] this->stm_label; this->stm_label = nullptr; } size_t len = strlen(sqlstm_label) + 1; this->stm_label = new char[len]; OTL_STRCPY_S(this->stm_label, len, sqlstm_label); } should_delete_flag = 1; in_exception_flag = 0; in_destruct_flag = 0; dirty = 0; auto_commit_flag = 1; flush_flag = true; flush_flag2 = true; lob_stream_mode = alob_stream_mode; this->cursor_struct.reset_last_param_data_token(); this->cursor_struct.reset_last_sql_param_data_status(); this->cursor_struct.reset_sql_param_data_count(); cur_x = -1; cur_y = 0; this->stm_text = nullptr; } virtual ~otl_tmpl_out_stream() OTL_THROWS_OTL_EXCEPTION3 { in_destruct_flag = 1; this->in_destructor = 1; if (dirty && !in_exception_flag && flush_flag && flush_flag2) flush(); cleanup(); in_destruct_flag = 0; } void reset_to_last_valid_row() { if (cur_y > 0) { --cur_y; this->in_exception_flag = 0; cur_x = this->vl_len - 1; } } virtual void flush(const int rowoff = 0, const bool force_flush = false) { int i, rc; this->_rpc = 0; if (!dirty) return; if (!flush_flag2) return; if (force_flush) { if (rowoff > cur_y) { clean(); return; } int temp_rc; OTL_TRACE_STREAM_EXECUTION2 this->exec(OTL_SCAST(otl_stream_buffer_size_type, (cur_y + 1)), rowoff, otl_sql_exec_from_cursor_class); for (i = 0; i < this->vl_len; ++i) { temp_rc = this->vl[i]->get_var_struct().put_blob(); if (temp_rc == 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } } if (auto_commit_flag) this->adb->commit(); clean(); return; } #if defined(OTL_STL) && defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) && !defined(OTL_DESTRUCTORS_DO_NOT_THROW) if (otl_uncaught_exception()) { clean(); return; } #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) && !defined(OTL_DESTRUCTORS_DO_NOT_THROW) if (otl_uncaught_exception()) { clean(); return; } #endif if (this->retcode == 0 || this->adb->get_retcode() == 0) { clean(); return; } if (cur_x != this->vl_len - 1) { in_exception_flag = 1; #if defined(OTL_STL) && defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) if (otl_uncaught_exception()) { clean(); return; } #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) if (otl_uncaught_exception()) { clean(); return; } #endif OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_3, otl_error_code_3, this->stm_label ? this->stm_label : this->stm_text, nullptr))); } if (in_destruct_flag) { OTL_TRACE_STREAM_EXECUTION2 this->retcode = this->cursor_struct.exec(cur_y + 1, rowoff, otl_sql_exec_from_cursor_class); for (i = 0; i < this->vl_len; ++i) { rc = this->vl[i]->get_var_struct().put_blob(); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } } if (!this->retcode) { clean(); in_exception_flag = 1; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(this->cursor_struct, this->stm_label ? this->stm_label : this->stm_text))); } if (auto_commit_flag) { this->adb->set_retcode(this->adb->get_connect_struct().commit()); if (!this->adb->get_retcode()) { clean(); OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } } } else { int temp_rc; OTL_TRACE_STREAM_EXECUTION2 this->exec(OTL_SCAST(otl_stream_buffer_size_type, (cur_y + 1)), rowoff, otl_sql_exec_from_cursor_class); long curr_rpc = this->get_rpc(); for (i = 0; i < this->vl_len; ++i) { otl_adapter_enum otl_adapter_type = this->vl[i]->get_const_var_struct().get_otl_adapter(); if (!(otl_adapter_type == OTL_ADAPTER_ENUM otl_ora8_adapter && curr_rpc == 0)) { temp_rc = this->vl[i]->get_var_struct().put_blob(); if (temp_rc == 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } } } if (auto_commit_flag) this->adb->commit(); if (rowoff > 0) clean(); else clean(0); } } virtual void clean(const int clean_up_error_flag = 0) { if (clean_up_error_flag) { this->retcode = 1; this->in_exception_flag = 0; } if (!dirty) return; cur_x = -1; cur_y = 0; dirty = 0; } bool get_error_state(void) const { if (this->retcode == 0 || this->in_exception_flag == 1) return true; else return false; } void set_commit(int auto_commit = 0) { auto_commit_flag = auto_commit; } void get_next(void) { if (cur_x < this->vl_len - 1) ++cur_x; else { if (cur_y < array_size - 1) { ++cur_y; cur_x = 0; } else { flush(); cur_x = 0; } } dirty = 1; } OTL_NODISCARD int check_type_throw(int type_code) { in_exception_flag = 1; otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, var_info))); } OTL_NODISCARD int check_type(int type_code, int tsize) { switch (this->vl[cur_x]->get_ftype()) { case otl_var_char: if (type_code == otl_var_char) return 1; break; case otl_var_bfloat: if (type_code == otl_var_float) return 1; break; case otl_var_bdouble: if (type_code == otl_var_double) return 1; break; case otl_var_db2time: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: case otl_var_db2date: if (type_code == otl_var_timestamp) return 1; break; case otl_var_refcur: if (type_code == otl_var_refcur) return 1; break; default: #if defined(OTL_CHECK_IN_TYPE_FUNC) if ((this->vl[cur_x]->get_ftype() == type_code && this->vl[cur_x]->get_elem_size() == tsize) || OTL_CHECK_IN_TYPE_FUNC(this->vl[cur_x]->get_ftype(),type_code)) return 1; break; #else if (this->vl[cur_x]->get_ftype() == type_code && this->vl[cur_x]->get_elem_size() == tsize) return 1; break; #endif } return check_type_throw(type_code); } void check_buf(void) { if (cur_x == this->vl_len - 1 && cur_y == array_size - 1) flush(); } OTL_TMPL_OUT_STREAM &operator<<(const char c) { if (this->vl_len > 0) { get_next(); if (check_type(otl_var_char, 1)) { char *tmp = OTL_RCAST(char *, this->vl[cur_x]->val(cur_y)); tmp[0] = c; tmp[1] = 0; this->vl[cur_x]->set_not_null(cur_y); } check_buf(); } return *this; } OTL_TMPL_OUT_STREAM &operator<<(const unsigned char c) { if (this->vl_len > 0) { get_next(); if (check_type(otl_var_char, 1)) { unsigned char *tmp = OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)); tmp[0] = c; tmp[1] = 0; this->vl[cur_x]->set_not_null(cur_y); } check_buf(); } return *this; } #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) OTL_TMPL_OUT_STREAM &operator<<(const OTL_STRING_CONTAINER &s) { if (this->vl_len > 0) { get_next(); switch (this->vl[cur_x]->get_ftype()) { #if defined(OTL_USER_DEFINED_STRING_CLASS_ON) || defined(OTL_STL) || \ defined(OTL_ACE) case otl_var_raw: { unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)); int len = OTL_SCAST(int, s.length()); this->vl[cur_x]->set_not_null(cur_y); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } if ((this->vl[cur_x]->get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter)) { otl_memcpy(c + sizeof(unsigned short), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len, this->vl[cur_x]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_x]->val(cur_y)) = OTL_SCAST(unsigned short, len); this->vl[cur_x]->set_len(len, cur_y); } else { otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len, this->vl[cur_x]->get_ftype()); this->vl[cur_x]->set_len(len, cur_y); } } break; #endif case otl_var_char: { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), overflow, this->vl[cur_x]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); in_exception_flag = 1; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info, OTL_RCAST(const void *, s.c_str()), OTL_SCAST(int, this->vl[cur_x]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info))); #endif } this->vl[cur_x]->set_not_null(cur_y); } break; #if defined(OTL_USER_DEFINED_STRING_CLASS_ON) || defined(OTL_STL) || \ defined(OTL_ACE) case otl_var_varchar_long: case otl_var_raw_long: { unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)); int len = OTL_SCAST(int, s.length()); this->vl[cur_x]->set_not_null(cur_y); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len, this->vl[cur_x]->get_ftype()); this->vl[cur_x]->set_len(len, cur_y); } break; case otl_var_blob: case otl_var_clob: { int len = OTL_SCAST(int, s.length()); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_x]->set_not_null(cur_y); (void)this->vl[cur_x]->get_var_struct().save_blob (OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len, 0); } break; #endif default: (void)check_type(otl_var_char, 1); } // switch check_buf(); } return *this; } #endif #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) OTL_TMPL_OUT_STREAM &operator<<(OTL_STD_STRING_VIEW_CLASS s) { if (this->vl_len > 0) { get_next(); switch (this->vl[cur_x]->get_ftype()) { case otl_var_raw: { unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)); int len = OTL_SCAST(int, s.length()); this->vl[cur_x]->set_not_null(cur_y); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } if ((this->vl[cur_x]->get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter)) { otl_memcpy(c + sizeof(unsigned short), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len, this->vl[cur_x]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_x]->val(cur_y)) = OTL_SCAST(unsigned short, len); this->vl[cur_x]->set_len(len, cur_y); } else { otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len, this->vl[cur_x]->get_ftype()); this->vl[cur_x]->set_len(len, cur_y); } } break; case otl_var_char: { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), overflow, this->vl[cur_x]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); in_exception_flag = 1; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info, OTL_RCAST(const void *, s.data()), OTL_SCAST(int, this->vl[cur_x]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info))); #endif } this->vl[cur_x]->set_not_null(cur_y); } break; case otl_var_varchar_long: case otl_var_raw_long: { unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)); int len = OTL_SCAST(int, s.length()); this->vl[cur_x]->set_not_null(cur_y); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len, this->vl[cur_x]->get_ftype()); this->vl[cur_x]->set_len(len, cur_y); } break; case otl_var_blob: case otl_var_clob: { int len = OTL_SCAST(int, s.length()); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_x]->set_not_null(cur_y); (void)this->vl[cur_x]->get_var_struct().save_blob (OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len, 0); } break; default: (void)check_type(otl_var_char, 1); } // switch check_buf(); } return *this; } #endif #if defined(OTL_UNICODE_STRING_TYPE) OTL_TMPL_OUT_STREAM &operator<<(const OTL_UNICODE_STRING_TYPE &s) { if (this->vl_len > 0) { get_next(); switch (this->vl[cur_x]->get_ftype()) { case otl_var_char: { int overflow; #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE) otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.OTL_C_STR_FOR_UNICODE_STRING_TYPE())), #else otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.c_str())), #endif overflow, this->vl[cur_x]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); in_exception_flag = 1; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info, OTL_RCAST(const void *, s.c_str()), OTL_SCAST(int, this->vl[cur_x]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info))); #endif } this->vl[cur_x]->set_not_null(cur_y); break; } case otl_var_varchar_long: { unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)); int len = OTL_SCAST(int, s.length()); this->vl[cur_x]->set_not_null(cur_y); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE) otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.OTL_C_STR_FOR_UNICODE_STRING_TYPE())), #else otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.c_str())), #endif len, this->vl[cur_x]->get_ftype()); this->vl[cur_x]->set_len(len, cur_y); break; } case otl_var_clob: { int len = OTL_SCAST(int, s.length()); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_x]->set_not_null(cur_y); (void)this->vl[cur_x]->get_var_struct().save_blob #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE) (OTL_RCAST(const unsigned char *, s.OTL_C_STR_FOR_UNICODE_STRING_TYPE()), #else (OTL_RCAST(const unsigned char *, s.c_str()), #endif len, 0); } break; default: (void)check_type(otl_var_char, 1); } check_buf(); } return *this; } #endif #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)) OTL_TMPL_OUT_STREAM &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) { if (this->vl_len > 0) { get_next(); switch (this->vl[cur_x]->get_ftype()) { case otl_var_char: { int overflow; otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE*, s.data())), overflow, this->vl[cur_x]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); in_exception_flag = 1; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info, OTL_RCAST(const void *, s.data()), OTL_SCAST(int, this->vl[cur_x]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info))); #endif } this->vl[cur_x]->set_not_null(cur_y); break; } case otl_var_varchar_long: { unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)); int len = OTL_SCAST(int, s.length()); this->vl[cur_x]->set_not_null(cur_y); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } otl_memcpy(c, OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.data())), len, this->vl[cur_x]->get_ftype()); this->vl[cur_x]->set_len(len, cur_y); break; } case otl_var_clob: { int len = OTL_SCAST(int, s.length()); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_x]->set_not_null(cur_y); (void)this->vl[cur_x]->get_var_struct().save_blob (OTL_RCAST(const unsigned char *, s.data()), len, 0); } break; default: (void)check_type(otl_var_char, 1); } check_buf(); } return *this; } #endif OTL_TMPL_OUT_STREAM &operator<<(const char *s) { if (this->vl_len > 0) { get_next(); if (check_type(otl_var_char, 1)) { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s)), overflow, this->vl[cur_x]->get_elem_size()); if (overflow) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); in_exception_flag = 1; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info, OTL_RCAST(const void *, s), OTL_SCAST(int, this->vl[cur_x]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info))); #endif } this->vl[cur_x]->set_not_null(cur_y); } check_buf(); } return *this; } #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE) template OTL_TMPL_OUT_STREAM &operator<<(const std::array& s){ (*this)< OTL_TMPL_OUT_STREAM &operator<<(const std::array& s){ (*this)<vl_len > 0) { get_next(); if (check_type(otl_var_char, 1)) { int overflow; otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)), OTL_CCAST(unsigned char *, s), overflow, this->vl[cur_x]->get_elem_size()); if (overflow) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, var_info, sizeof(var_info)); in_exception_flag = 1; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info, OTL_RCAST(const void *, s), OTL_SCAST(int, this->vl[cur_x]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, var_info))); #endif } this->vl[cur_x]->set_not_null(cur_y); } check_buf(); } return *this; } #if !defined(OTL_D3) #define OTL_D3(T, T_type) \ OTL_TMPL_OUT_STREAM &operator<<(const T n) { \ if (this->vl_len > 0) { \ get_next(); \ if (check_type(T_type, sizeof(T))) { \ *OTL_RCAST(T *, this->vl[cur_x]->val(cur_y)) = n; \ this->vl[cur_x]->set_not_null(cur_y); \ } \ check_buf(); \ } \ return *this; \ } #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) OTL_D3(int, otl_var_int) #if defined(OTL_BIGINT) OTL_D3(OTL_BIGINT, otl_var_bigint) #endif #if defined(OTL_UBIGINT) OTL_D3(OTL_UBIGINT, otl_var_ubigint) #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) OTL_D3(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1) #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) OTL_D3(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2) #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) OTL_D3(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3) #endif OTL_D3(unsigned, otl_var_unsigned_int) OTL_D3(long, otl_var_long_int) OTL_D3(short, otl_var_short) OTL_D3(float, otl_var_float) OTL_D3(double, otl_var_double) #else template OTL_D3(T,T_type) #endif #if defined(OTL_PL_TAB) OTL_TMPL_OUT_STREAM &operator<<(otl_pl_tab_generic &tab) { if (this->vl_len > 0) { get_next(); if (check_type(tab.get_vtype(), tab.get_elem_size())) { int i, tmp_len; if (tab.len() <= this->vl[cur_x]->get_array_size()) tmp_len = tab.len(); else tmp_len = this->vl[cur_x]->get_array_size(); this->vl[cur_x]->set_pl_tab_len(tmp_len); if (tab.get_vtype() == otl_var_char) { int i2; for (i2 = 0; i2 < tmp_len; ++i2) { int overflow; otl_strcpy4(OTL_RCAST(unsigned char *, this->vl[cur_x]->val(i2)), OTL_RCAST(unsigned char *, tab.val(i2)), overflow, this->vl[cur_x]->get_elem_size()); if (overflow) { char tmp_var_info[256]; otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, tmp_var_info, sizeof(tmp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, tmp_var_info, OTL_RCAST(const void *, tab.val(i2)), OTL_SCAST(int, this->vl[cur_x]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, tmp_var_info))); #endif } } } else if (tab.get_vtype() == otl_var_timestamp) { otl_datetime *ext_dt = OTL_RCAST(otl_datetime *, tab.get_p_v()); otl_oracle_date *int_dt = OTL_RCAST(otl_oracle_date *, this->vl[cur_x]->val()); int j; for (j = 0; j < tmp_len; ++j) { convert_date(*int_dt, *ext_dt); ++int_dt; ++ext_dt; } } else memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, tab.val()), OTL_SCAST(size_t, tab.get_elem_size() * tmp_len)); for (i = 0; i < tmp_len; ++i) { if (tab.is_null(i)) this->vl[cur_x]->set_null(i); else this->vl[cur_x]->set_not_null(i); } } check_buf(); } return *this; } #endif #if defined(OTL_PL_TAB) && defined(OTL_STL) OTL_TMPL_OUT_STREAM &operator<<(otl_pl_vec_generic &vec) { if (this->vl_len > 0) { get_next(); if (check_type(vec.get_vtype(), vec.get_elem_size())) { int i, tmp_len; if (vec.len() <= this->vl[cur_x]->get_array_size()) tmp_len = vec.len(); else tmp_len = this->vl[cur_x]->get_array_size(); this->vl[cur_x]->set_pl_tab_len(tmp_len); switch (vec.get_vtype()) { case otl_var_char: int i2; for (i2 = 0; i2 < tmp_len; ++i2) { int overflow; otl_strcpy( OTL_RCAST(unsigned char *, this->vl[cur_x]->val(i2)), OTL_RCAST( unsigned char *, OTL_CCAST(char *, (*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[OTL_SCAST(size_t, i2)] .c_str())), overflow, this->vl[cur_x]->get_elem_size(), OTL_SCAST( int, (*OTL_RCAST( STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[OTL_SCAST(size_t, i2)].length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info, OTL_RCAST( const void *, (*OTL_RCAST( STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[i2].c_str()), OTL_SCAST(int, this->vl[cur_x]->get_elem_size())))); #else OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_4, otl_error_code_4, this->stm_label ? this->stm_label : this->stm_text, temp_var_info))); #endif } } break; case otl_var_timestamp: { otl_oracle_date *int_dt = OTL_RCAST(otl_oracle_date *, this->vl[cur_x]->val()); int j; otl_datetime *ext_dt; for (j = 0; j < tmp_len; ++j) { ext_dt = OTL_RCAST( otl_datetime *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[OTL_SCAST(size_t, j)]); convert_date(*int_dt, *ext_dt); ++int_dt; } } break; case otl_var_int: if (tmp_len > 0) memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), sizeof(int) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_double: if (tmp_len > 0) memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), sizeof(double) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_bdouble: if (tmp_len > 0) memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), sizeof(double) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_float: if (tmp_len > 0) memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), sizeof(float) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_bfloat: if (tmp_len > 0) memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), sizeof(float) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_unsigned_int: if (tmp_len > 0) memcpy( OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), sizeof(unsigned) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_short: if (tmp_len > 0) memcpy(OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), sizeof(short) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_long_int: if (tmp_len > 0) memcpy( OTL_RCAST(char *, this->vl[cur_x]->val()), OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), sizeof(long int) * OTL_SCAST(size_t, tmp_len)); break; } for (i = 0; i < tmp_len; ++i) { if (vec.is_null(i)) this->vl[cur_x]->set_null(i); else this->vl[cur_x]->set_not_null(i); } } check_buf(); } return *this; } #endif OTL_TMPL_OUT_STREAM &operator<<(OTL_NULL_PARM /* n */) { if (this->vl_len > 0) { get_next(); this->vl[cur_x]->set_null(cur_y); check_buf(); } return *this; } OTL_TMPL_OUT_STREAM &operator<<(const TTimestampStruct &t) { if (this->vl_len > 0) { get_next(); if (check_type(otl_var_timestamp, sizeof(TTimestampStruct))) { TTimestampStruct *tm = OTL_RCAST(TTimestampStruct *, this->vl[cur_x]->val(cur_y)); this->vl[cur_x]->set_not_null(cur_y); int rc = this->vl[cur_x]->get_var_struct().write_dt( tm, &t, sizeof(TTimestampStruct)); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } } check_buf(); } return *this; } OTL_TMPL_OUT_STREAM &operator<<(const otl_long_string &s) { if (this->vl_len > 0) { get_next(); switch (this->vl[cur_x]->get_ftype()) { case otl_var_varchar_long: case otl_var_raw_long: case otl_var_raw: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && this->vl[cur_x]->get_ftype() == otl_var_varchar_long) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && this->vl[cur_x]->get_ftype() != otl_var_varchar_long) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } unsigned char *c = OTL_RCAST(unsigned char *, this->vl[cur_x]->val(cur_y)); int len = OTL_CCAST(otl_long_string *, &s)->len(); this->vl[cur_x]->set_not_null(cur_y); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } if ((this->vl[cur_x]->get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_ora8_adapter) && this->vl[cur_x]->get_ftype() == otl_var_raw) { otl_memcpy(c + sizeof(unsigned short), s.v, len, this->vl[cur_x]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_x]->val(cur_y)) = OTL_SCAST(unsigned short, len); this->vl[cur_x]->set_len(len, cur_y); } else { otl_memcpy(c, s.v, len, this->vl[cur_x]->get_ftype()); this->vl[cur_x]->set_len(len, cur_y); } } break; case otl_var_blob: case otl_var_clob: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && this->vl[cur_x]->get_ftype() == otl_var_clob) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && this->vl[cur_x]->get_ftype() == otl_var_blob) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } int len = OTL_CCAST(otl_long_string *, &s)->len(); if (len > this->vl[cur_x]->actual_elem_size()) { otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_x]->set_not_null(cur_y); (void)this->vl[cur_x]->get_var_struct().save_blob(s.v, len, s.get_extern_buffer_flag()); } break; } check_buf(); } return *this; } #if defined(OTL_ORA8) || defined(OTL_ODBC) #define OTL_TMPL_CUR_DUMMY OTL_TMPL_CURSOR OTL_TMPL_OUT_STREAM &operator<<(otl_lob_stream_generic &s) { if (this->vl_len > 0) { get_next(); if (((s.get_ora_lob() && this->vl[cur_x]->get_ftype() == otl_var_blob) || this->vl[cur_x]->get_ftype() == otl_var_clob) || (this->vl[cur_x]->get_ftype() == otl_var_varchar_long || this->vl[cur_x]->get_ftype() == otl_var_raw_long)) { s.init(this->vl[cur_x], this->adb, OTL_RCAST(OTL_TMPL_CUR_DUMMY *, this), 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)); if (!s.get_ora_lob()) this->vl[cur_x]->set_not_null(cur_y); } check_buf(); } else { char temp_var_info[256]; otl_var_info_var(this->vl[cur_x]->get_name(), this->vl[cur_x]->get_ftype(), otl_var_long_string, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, temp_var_info))); } return *this; } #undef OTL_TMPL_CUR_DUMMY #endif #if defined(OTL_ORA_SDO_GEOMETRY) OTL_TMPL_OUT_STREAM &operator << (const oci_spatial_geometry &s){ if(this->vl_len > 0){ get_next(); if(check_type(otl_var_sdo_geometry, this->adb->get_max_long_size())){ int rc = this->vl[cur_x]->get_var_struct().write_geometry(s, cur_y); if(rc == 0){ OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } } this->vl[cur_x]->set_not_null(cur_y); check_buf(); } return *this; } #endif otl_tmpl_out_stream() : OTL_TMPL_CURSOR(), auto_commit_flag(0), dirty(0), cur_x(0), cur_y(0), array_size(0), in_exception_flag(0), in_destruct_flag(0), should_delete_flag(0), var_info(), flush_flag(0), flush_flag2(0), lob_stream_mode(0), master_stream_ptr_(nullptr) {} private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_out_stream(const otl_tmpl_out_stream &) = delete; otl_tmpl_out_stream &operator=(const otl_tmpl_out_stream &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_out_stream(otl_tmpl_out_stream &&) = delete; otl_tmpl_out_stream &operator=(otl_tmpl_out_stream &&) = delete; #endif private: #else otl_tmpl_out_stream(const otl_tmpl_out_stream &) : OTL_TMPL_CURSOR(), auto_commit_flag(0), dirty(0), cur_x(0), cur_y(0), array_size(0), in_exception_flag(0), in_destruct_flag(0), should_delete_flag(0), var_info(), flush_flag(0), flush_flag2(0), lob_stream_mode(0), master_stream_ptr_(nullptr) {} otl_tmpl_out_stream &operator=(const otl_tmpl_out_stream &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_out_stream(otl_tmpl_out_stream &&) : OTL_TMPL_CURSOR(), auto_commit_flag(0), dirty(0), cur_x(0), cur_y(0), array_size(0), in_exception_flag(0), in_destruct_flag(0), should_delete_flag(0), var_info(), flush_flag(0), flush_flag2(0), lob_stream_mode(0), master_stream_ptr_(nullptr) {} otl_tmpl_out_stream &operator=(otl_tmpl_out_stream &&) { return *this; } #endif #endif }; template class otl_tmpl_inout_stream : public OTL_TMPL_OUT_STREAM { protected: otl_tmpl_variable **in_vl; int iv_len; int cur_in_x; int cur_in_y; int in_y_len; int null_fetched; otl_tmpl_variable **avl; int avl_len; char var_info[256]; public: void set_batch_error_mode(const bool batch_error_mode) { OTL_TMPL_CURSOR::set_batch_error_mode(batch_error_mode); } OTL_NODISCARD int get_iv_len() const { return iv_len; } OTL_NODISCARD otl_tmpl_variable **get_in_vl() { return in_vl; } void cleanup(void) { int i; for (i = 0; i < avl_len; ++i) { delete avl[i]; } delete[] avl; delete[] in_vl; } otl_tmpl_inout_stream(otl_stream_buffer_size_type arr_size, const char *sqlstm, OTL_TMPL_CONNECT &pdb, void *master_stream_ptr, const bool alob_stream_mode = false, const char *sqlstm_label = nullptr) : OTL_TMPL_OUT_STREAM(pdb, master_stream_ptr, alob_stream_mode, sqlstm_label), in_vl(nullptr), iv_len(0), cur_in_x(0), cur_in_y(0), in_y_len(0), null_fetched(0), avl(nullptr), avl_len(0), var_info() { int i, j; this->dirty = 0; this->auto_commit_flag = 1; this->adb = &pdb; this->in_exception_flag = 0; this->stm_text = nullptr; this->array_size = arr_size; this->should_delete_flag = 0; { size_t len = strlen(sqlstm) + 1; this->stm_text = new char[len]; OTL_STRCPY_S(this->stm_text, len, sqlstm); otl_tmpl_ext_hv_decl hvd(this->stm_text, arr_size); if (hvd.has_plsql_tabs_or_refcur() && arr_size > 1) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_33, otl_error_code_33, this->stm_label ? this->stm_label : this->stm_text))); } if (hvd.has_space_in_bind_variable()) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_36, otl_error_code_36, this->stm_label ? this->stm_label : this->stm_text))); } if (hvd.bind_var_terminator_is_missing()) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_43, otl_error_code_43, this->stm_label ? this->stm_label : this->stm_text))); } if (hvd.get_vst(otl_tmpl_ext_hv_decl< TVariableStruct, TTimestampStruct, TExceptionStruct, TConnectStruct, TCursorStruct>::def) == hvd.get_len()) { this->should_delete_flag = 1; hvd.alloc_host_var_list(this->vl, this->vl_len, pdb); } else { for (i = 0; i < hvd.get_len(); ++i) { if (hvd.get_inout(i) == otl_tmpl_ext_hv_decl::in) ++this->vl_len; else if (hvd.get_inout(i) == otl_tmpl_ext_hv_decl::out) ++iv_len; else if (hvd.get_inout(i) == otl_tmpl_ext_hv_decl::io) { ++this->vl_len; ++iv_len; } } if (this->vl_len > 0) { this->vl = new otl_tmpl_variable *[OTL_SCAST(size_t,this->vl_len)]; } if (iv_len > 0) in_vl = new otl_tmpl_variable *[OTL_SCAST(size_t,iv_len)]; avl_len = hvd.get_len(); if (hvd.get_len() > 0) avl = new otl_tmpl_variable *[OTL_SCAST(size_t,avl_len)]; iv_len = 0; this->vl_len = 0; for (j = 0; j < avl_len; ++j) { #if defined(OTL_STREAM_LEGACY_BUFFER_SIZE_TYPE) if (hvd.pl_tab_size[j] > 32767) { char tmp_var_info[256]; otl_var_info_var(hvd[j], otl_var_none, otl_var_none, tmp_var_info, sizeof(tmp_var_info)); OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_6, otl_error_code_6, this->stm_label ? this->stm_label : this->stm_text, tmp_var_info))); } #endif otl_tmpl_variable *v = hvd.alloc_var( hvd[j], hvd.get_inout(j), otl_tmpl_ext_hv_decl::def, pdb, hvd.get_pl_tab_size(j)); if (v == nullptr) { int k; if (avl != nullptr) for (k = 0; k < j; ++k) { delete avl[k]; avl[k] = nullptr; } delete[] avl; avl = nullptr; this->vl_len = 0; OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_12, otl_error_code_12, hvd.stm_label() ? hvd.stm_label() : hvd.stm_text(), hvd[j]))); } if (v != nullptr) v->set_name_pos(j + 1); if (avl != nullptr) avl[j] = v; if (hvd.get_inout(j) == otl_tmpl_ext_hv_decl::in) { ++this->vl_len; this->vl[this->vl_len - 1] = v; v->set_param_type(otl_input_param); } else if (hvd.get_inout(j) == otl_tmpl_ext_hv_decl::out) { if (in_vl != nullptr){ ++iv_len; in_vl[iv_len - 1] = v; } v->set_param_type(otl_output_param); } else if (hvd.get_inout(j) == otl_tmpl_ext_hv_decl::io) { ++this->vl_len; ++iv_len; this->vl[this->vl_len - 1] = v; if (in_vl != nullptr) in_vl[iv_len - 1] = v; v->set_param_type(otl_inout_param); }else{ delete v; #if !defined(__BORLANDC__) v = nullptr; #endif if (avl != nullptr) for (int k = 0; k < j; ++k) { delete avl[k]; avl[k] = nullptr; } delete[] avl; avl = nullptr; this->vl_len = 0; OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_12, otl_error_code_12, hvd.stm_label() ? hvd.stm_label() : hvd.stm_text(), hvd[j]))); } } } } try { this->parse(); for (i = 0; i < this->vl_len; ++i) { if (this->vl[i]->get_var_struct().get_otl_adapter() == OTL_ADAPTER_ENUM otl_odbc_adapter) { this->vl[i]->get_var_struct().set_lob_stream_mode( this->lob_stream_mode); this->vl[i]->get_var_struct().set_vparam_type( this->vl[i]->get_param_type()); if (this->vl[i]->get_ftype() == otl_var_varchar_long || this->vl[i]->get_ftype() == otl_var_raw_long) { this->vl[i]->set_not_null(0); } } this->bind(*(this->vl[i])); } for (j = 0; j < iv_len; ++j) this->bind(*in_vl[j]); rewind(); } catch (OTL_CONST_EXCEPTION OTL_TMPL_EXCEPTION &) { cleanup(); throw; } } virtual ~otl_tmpl_inout_stream() OTL_THROWS_OTL_EXCEPTION3 { this->in_destructor = 1; if (!this->in_exception_flag) flush(); cleanup(); } OTL_NODISCARD int eof(void) { if (iv_len == 0) return 1; if (in_y_len == 0) return 1; if (cur_in_y <= in_y_len - 1) return 0; return 1; } void flush(const int rowoff = 0, const bool force_flush = false) { if (this->vl_len == 0) return; in_y_len = this->cur_y + 1; cur_in_y = 0; cur_in_x = 0; if (!this->in_exception_flag) OTL_TMPL_OUT_STREAM::flush(rowoff, force_flush); } void clean(const int clean_up_error_flag = 0) { if (this->vl_len != 0) { in_y_len = this->cur_y + 1; cur_in_y = 0; cur_in_x = 0; } OTL_TMPL_OUT_STREAM::clean(clean_up_error_flag); } void rewind(void) { flush(); cur_in_x = 0; cur_in_y = 0; this->cur_x = -1; this->cur_y = 0; in_y_len = 0; null_fetched = 0; if (this->vl_len == 0) { this->exec(this->array_size, 0, otl_sql_exec_from_cursor_class); in_y_len = this->array_size; cur_in_y = 0; cur_in_x = 0; } } OTL_NODISCARD int is_null(void) { return null_fetched; } void skip_to_end_of_row() { if (eof()) return; if (iv_len == 0) return; if (in_y_len == 0) return; if (cur_in_y < in_y_len - 1) { ++cur_in_y; cur_in_x = 0; } else { cur_in_y = 0; cur_in_x = 0; in_y_len = 0; } } void skip_to_next_var() { if(eof())return; if(iv_len==0)return; if(in_y_len==0)return; if(cur_in_yin_exception_flag = 1; otl_var_info_var(in_vl[cur_in_x]->get_name(), in_vl[cur_in_x]->get_ftype(), type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, var_info))); } OTL_NODISCARD int check_in_type(int type_code, int tsize) { switch (in_vl[cur_in_x]->get_ftype()) { case otl_var_refcur: if (type_code == otl_var_refcur) return 1; break; case otl_var_db2time: case otl_var_db2date: if (type_code == otl_var_timestamp) return 1; break; case otl_var_char: if (type_code == otl_var_char) return 1; break; case otl_var_bdouble: if (type_code == otl_var_double) return 1; break; case otl_var_bfloat: if (type_code == otl_var_float) return 1; break; default: #if defined(OTL_CHECK_OUT_TYPE_FUNC) if ((in_vl[cur_in_x]->get_ftype() == type_code && in_vl[cur_in_x]->get_elem_size() == tsize) || OTL_CHECK_OUT_TYPE_FUNC(in_vl[cur_in_x]->get_ftype(),type_code)) return 1; break; #else if (in_vl[cur_in_x]->get_ftype() == type_code && in_vl[cur_in_x]->get_elem_size() == tsize) return 1; break; #endif } return check_in_type_throw(type_code); } OTL_NODISCARD int is_null_intern(void) { if (iv_len == 0) return 0; if (in_y_len == 0) return 0; if (in_y_len > 0) return in_vl[cur_in_x]->is_null(cur_in_y); return 0; } OTL_TMPL_INOUT_STREAM &operator>>(char &c) { if (eof()) return *this; if (check_in_type(otl_var_char, 1)) { c = *OTL_RCAST(char *, in_vl[cur_in_x]->val(cur_in_y)); null_fetched = is_null_intern(); } get_in_next(); return *this; } OTL_TMPL_INOUT_STREAM &operator>>(unsigned char &c) { if (eof()) return *this; if (check_in_type(otl_var_char, 1)) { c = *OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y)); null_fetched = is_null_intern(); } get_in_next(); return *this; } #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) OTL_TMPL_INOUT_STREAM &operator>>(OTL_STRING_CONTAINER &s) { if (eof()) return *this; switch (in_vl[cur_in_x]->get_ftype()) { case otl_var_char: { #if defined(OTL_ACE) s.set(OTL_RCAST(char *, in_vl[cur_in_x]->val(cur_in_y)), 1); #else s = OTL_RCAST(char *, in_vl[cur_in_x]->val(cur_in_y)); #endif null_fetched = is_null_intern(); } break; #if defined(USER_DEFINED_STRING_CLASS) || defined(OTL_STL) || defined(OTL_ACE) case otl_var_varchar_long: case otl_var_raw_long: { unsigned char *c = OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y)); int len = in_vl[cur_in_x]->get_len(); #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(USER_DEFINED_STRING_CLASS)) s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len)); #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, c), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, c), len, 1); #endif null_fetched = is_null_intern(); } break; case otl_var_blob: case otl_var_clob: { int len = 0; int max_long_sz = this->adb->get_max_long_size(); otl_auto_array_ptr loc_ptr(max_long_sz); unsigned char *temp_buf = loc_ptr.get_ptr(); int rc = in_vl[cur_in_x]->get_var_struct().get_blob(cur_in_y, temp_buf, max_long_sz, len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(USER_DEFINED_STRING_CLASS)) s.assign(OTL_RCAST(char *, temp_buf), OTL_SCAST(size_t, len)); #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, temp_buf), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, temp_buf), len, 1); #endif null_fetched = is_null_intern(); } break; #endif default: (void)check_in_type(otl_var_char, 1); break; } // switch get_in_next(); return *this; } #endif OTL_TMPL_INOUT_STREAM &operator>>(char *s) { if (eof()) return *this; if (check_in_type(otl_var_char, 1)) { otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, in_vl[cur_in_x]->val(cur_in_y))); null_fetched = is_null_intern(); } get_in_next(); return *this; } void getString(char *s, int max_size) { if (eof()) return; if (check_in_type(otl_var_char, 1)) { otl_var_info_var(in_vl[cur_in_x]->get_name(), in_vl[cur_in_x]->get_ftype(), const_STD_CHAR_ARRAY_code, var_info, sizeof(var_info)); if(max_sizeget_len(cur_in_y)){ OTL_THROW((otl_tmpl_exception(otl_error_msg_45, otl_error_code_45, this->stm_label ? this->stm_label : this->stm_text, this->var_info))); } otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, in_vl[cur_in_x]->val(cur_in_y))); null_fetched = is_null_intern(); } get_in_next(); } #if defined(OTL_UNICODE_STRING_TYPE) OTL_TMPL_INOUT_STREAM &operator>>(OTL_UNICODE_STRING_TYPE &s) { if (eof()) return *this; if (check_in_type(otl_var_char, 1)) { #if defined(OTL_ODBC) || defined(DB2_CLI) s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, in_vl[cur_in_x]->val(cur_in_y)); #else #if defined(OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR) OTL_UNICODE_CHAR_TYPE *temp_s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, in_vl[cur_in_x]->val(cur_in_y)); OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR(s, temp_s + 1, *temp_s); #else OTL_UNICODE_CHAR_TYPE *temp_s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, in_vl[cur_in_x]->val(cur_in_y)); s.assign(temp_s + 1, *temp_s); #endif #endif null_fetched = is_null_intern(); } get_in_next(); return *this; } #endif OTL_TMPL_INOUT_STREAM &operator>>(unsigned char *s) { if (eof()) return *this; if (check_in_type(otl_var_char, 1)) { otl_strcpy2(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y)), in_vl[cur_in_x]->get_len(cur_in_y)); null_fetched = is_null_intern(); } get_in_next(); return *this; } #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE) void getString(char16_t *s, int max_size) { if (eof()) return; if (check_in_type(otl_var_char, 1)) { if(max_sizeget_len(cur_in_y)) OTL_THROW((otl_tmpl_exception(otl_error_msg_46, otl_error_code_46, this->stm_label ? this->stm_label : this->stm_text, this->var_info))); otl_strcpy2(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y)), in_vl[cur_in_x]->get_len(cur_in_y)); null_fetched = is_null_intern(); } get_in_next(); } #endif #if !defined(OTL_D4) #define OTL_D4(T, T_type) \ OTL_TMPL_INOUT_STREAM &operator>>(T &n) { \ if (eof()) \ return *this; \ if (check_in_type(T_type, sizeof(T))) { \ n = *OTL_RCAST(T *, in_vl[cur_in_x]->val(cur_in_y)); \ null_fetched = is_null_intern(); \ } \ get_in_next(); \ return *this; \ } #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) OTL_D4(int, otl_var_int) OTL_D4(unsigned, otl_var_unsigned_int) #if defined(OTL_BIGINT) OTL_D4(OTL_BIGINT, otl_var_bigint) #endif #if defined(OTL_UBIGINT) OTL_D4(OTL_UBIGINT, otl_var_ubigint) #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) OTL_D4(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1) #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) OTL_D4(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2) #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) OTL_D4(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3) #endif OTL_D4(long, otl_var_long_int) OTL_D4(short, otl_var_short) OTL_D4(float, otl_var_float) OTL_D4(double, otl_var_double) #else template OTL_D4(T,T_type) #endif #if defined(OTL_PL_TAB) OTL_TMPL_INOUT_STREAM &operator>>(otl_pl_tab_generic &tab) { if (eof()) return *this; if (check_in_type(tab.get_vtype(), tab.get_elem_size())) { int i, tmp_len; tmp_len = in_vl[cur_in_x]->get_pl_tab_len(); if (tab.get_tab_size() < tmp_len) tmp_len = tab.get_tab_size(); tab.set_len(tmp_len); if (tab.get_vtype() == otl_var_char) { for (i = 0; i < tmp_len; ++i) { int overflow; otl_strcpy3(OTL_RCAST(unsigned char *, tab.val(i)), OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(i)), in_vl[cur_in_x]->get_len(i), overflow, tab.get_elem_size()); } } else if (tab.get_vtype() == otl_var_timestamp) { otl_datetime *ext_dt = OTL_RCAST(otl_datetime *, tab.get_p_v()); otl_oracle_date *int_dt = OTL_RCAST(otl_oracle_date *, in_vl[cur_in_x]->val()); int j; for (j = 0; j < tmp_len; ++j) { convert_date(*ext_dt, *int_dt); ++int_dt; ++ext_dt; } } else memcpy(OTL_RCAST(char *, tab.val()), OTL_RCAST(char *, in_vl[cur_in_x]->val()), OTL_SCAST(size_t, tab.get_elem_size() * tmp_len)); for (i = 0; i < tmp_len; ++i) { if (in_vl[cur_in_x]->is_null(i)) tab.set_null(i); else tab.set_non_null(i); } null_fetched = 0; } get_in_next(); return *this; } #endif #if defined(OTL_PL_TAB) && defined(OTL_STL) OTL_TMPL_INOUT_STREAM &operator>>(otl_pl_vec_generic &vec) { if (eof()) return *this; if (check_in_type(vec.get_vtype(), vec.get_elem_size())) { int i, tmp_len; tmp_len = in_vl[cur_in_x]->get_pl_tab_len(); vec.set_len(tmp_len); if (tmp_len > 0) { switch (vec.get_vtype()) { case otl_var_char: for (i = 0; i < tmp_len; ++i) { (*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[OTL_SCAST(size_t, i)] = OTL_RCAST(char *, in_vl[cur_in_x]->val(i)); } break; case otl_var_timestamp: { otl_datetime *ext_dt; otl_oracle_date *int_dt = OTL_RCAST(otl_oracle_date *, in_vl[cur_in_x]->val()); int j; for (j = 0; j < tmp_len; ++j) { ext_dt = OTL_RCAST( otl_datetime *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[OTL_SCAST(size_t, j)]); convert_date(*ext_dt, *int_dt); ++int_dt; } } break; case otl_var_int: memcpy( OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), OTL_RCAST(char *, in_vl[cur_in_x]->val()), sizeof(int) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_double: memcpy(OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), OTL_RCAST(char *, in_vl[cur_in_x]->val()), sizeof(double) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_bdouble: memcpy(OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), OTL_RCAST(char *, in_vl[cur_in_x]->val()), sizeof(double) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_float: memcpy(OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), OTL_RCAST(char *, in_vl[cur_in_x]->val()), sizeof(float) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_bfloat: memcpy(OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), OTL_RCAST(char *, in_vl[cur_in_x]->val()), sizeof(float) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_unsigned_int: memcpy(OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), OTL_RCAST(char *, in_vl[cur_in_x]->val()), sizeof(unsigned) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_short: memcpy(OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), OTL_RCAST(char *, in_vl[cur_in_x]->val()), sizeof(short) * OTL_SCAST(size_t, tmp_len)); break; case otl_var_long_int: memcpy(OTL_RCAST(char *, &(*OTL_RCAST(STD_NAMESPACE_PREFIX vector *, vec.get_p_v()))[0]), OTL_RCAST(char *, in_vl[cur_in_x]->val()), sizeof(long int) * OTL_SCAST(size_t, tmp_len)); break; } } for (i = 0; i < tmp_len; ++i) { if (in_vl[cur_in_x]->is_null(i)) vec.set_null(i); else vec.set_non_null(i); } null_fetched = 0; } get_in_next(); return *this; } #endif OTL_TMPL_INOUT_STREAM &operator>>(TTimestampStruct &t) { if (eof()) return *this; if (check_in_type(otl_var_timestamp, sizeof(TTimestampStruct))) { TTimestampStruct *tm = OTL_RCAST(TTimestampStruct *, in_vl[cur_in_x]->val(cur_in_y)); int rc = in_vl[cur_in_x]->get_var_struct().read_dt( &t, tm, sizeof(TTimestampStruct)); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } null_fetched = is_null_intern(); } get_in_next(); return *this; } OTL_TMPL_INOUT_STREAM &operator>>(otl_long_string &s) { int len = 0; if (eof()) return *this; switch (in_vl[cur_in_x]->get_ftype()) { case otl_var_raw: case otl_var_varchar_long: case otl_var_raw_long: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && in_vl[cur_in_x]->get_ftype() == otl_var_varchar_long) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && in_vl[cur_in_x]->get_ftype() != otl_var_varchar_long) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } unsigned char *c = OTL_RCAST(unsigned char *, in_vl[cur_in_x]->val(cur_in_y)); len = in_vl[cur_in_x]->get_len(); if (len > s.get_buf_size()) len = s.get_buf_size(); otl_memcpy(s.v, c, len, in_vl[cur_in_x]->get_ftype()); s.set_len(len); if (in_vl[cur_in_x]->get_ftype() == otl_var_varchar_long) s.null_terminate_string(len); null_fetched = is_null_intern(); } break; case otl_var_clob: case otl_var_blob: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && in_vl[cur_in_x]->get_ftype() == otl_var_clob) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && in_vl[cur_in_x]->get_ftype() == otl_var_blob) { OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } int rc = in_vl[cur_in_x]->get_var_struct().get_blob( cur_in_y, s.v, s.get_buf_size(), len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } if (len > s.get_buf_size()) len = s.get_buf_size(); s.set_len(len); if (in_vl[cur_in_x]->get_ftype() == otl_var_clob) s.null_terminate_string(len); null_fetched = is_null_intern(); } break; default: { char temp_var_info[256]; otl_var_info_var(in_vl[cur_in_x]->get_name(), in_vl[cur_in_x]->get_ftype(), otl_var_long_string, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, temp_var_info))); } } get_in_next(); return *this; } #if defined(OTL_ORA8) || defined(OTL_ODBC) OTL_TMPL_INOUT_STREAM &operator>>(otl_lob_stream_generic &s) { if (eof()) return *this; if ((s.get_ora_lob() && in_vl[cur_in_x]->get_ftype() == otl_var_clob) || in_vl[cur_in_x]->get_ftype() == otl_var_blob) { null_fetched = is_null_intern(); s.init(OTL_RCAST(void *, in_vl[cur_in_x]), OTL_RCAST(void *, this->adb), OTL_RCAST(void *, this), 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode), this->is_null()); } else if (in_vl[cur_in_x]->get_ftype() == otl_var_varchar_long || in_vl[cur_in_x]->get_ftype() == otl_var_raw_long) { s.init(OTL_RCAST(void *, in_vl[cur_in_x]), OTL_RCAST(void *, this->adb), OTL_RCAST(void *, this), 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)); } else { char tmp_var_info[256]; otl_var_info_var(in_vl[cur_in_x]->get_name(), in_vl[cur_in_x]->get_ftype(), otl_var_long_string, tmp_var_info, sizeof(tmp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, tmp_var_info))); } get_in_next(); return *this; } #endif #if defined(OTL_ORA_SDO_GEOMETRY) OTL_TMPL_INOUT_STREAM &operator >> (oci_spatial_geometry &s){ if(eof()) return *this; if(check_in_type(otl_var_sdo_geometry, this->adb->get_max_long_size())){ int rc = in_vl[cur_in_x]->get_var_struct().read_geometry(s, cur_in_x); if(rc == 0){ OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } null_fetched = is_null_intern(); } get_in_next(); return *this; } #endif otl_tmpl_inout_stream() : OTL_TMPL_OUT_STREAM(), in_vl(nullptr), iv_len(0), cur_in_x(0), cur_in_y(0), in_y_len(0), null_fetched(0), avl(nullptr), avl_len(0), var_info() {} private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_inout_stream(const otl_tmpl_inout_stream &) = delete; otl_tmpl_inout_stream &operator=(const otl_tmpl_inout_stream &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_inout_stream(otl_tmpl_inout_stream &&) = delete; otl_tmpl_inout_stream &operator=(otl_tmpl_inout_stream &&) = delete; #endif private: #else otl_tmpl_inout_stream(const otl_tmpl_inout_stream &) : OTL_TMPL_OUT_STREAM(), in_vl(nullptr), iv_len(0), cur_in_x(0), cur_in_y(0), in_y_len(0), null_fetched(0), avl(nullptr), avl_len(0), var_info() {} otl_tmpl_inout_stream &operator=(const otl_tmpl_inout_stream &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_inout_stream(otl_tmpl_inout_stream &&) : OTL_TMPL_OUT_STREAM(), in_vl(nullptr), iv_len(0), cur_in_x(0), cur_in_y(0), in_y_len(0), null_fetched(0), avl(nullptr), avl_len(0), var_info() {} otl_tmpl_inout_stream &operator=(otl_tmpl_inout_stream &&) { return *this; } #endif #endif }; // ==================== OTL-Adapter for ODBC/CLI ========================= #if defined(OTL_ODBC) // use recommended SQL type codes for temporal ODBC data types when // ODBC 3.x is used #if (defined(ODBCVER) && (ODBCVER >= 0x0300)) #define OTL_SQL_C_TIMESTAMP SQL_C_TYPE_TIMESTAMP #define OTL_SQL_TIMESTAMP SQL_TYPE_TIMESTAMP #define OTL_SQL_C_DATE SQL_C_TYPE_DATE #define OTL_SQL_DATE SQL_TYPE_DATE #define OTL_SQL_C_TIME SQL_C_TYPE_TIME #define OTL_SQL_TIME SQL_TYPE_TIME #else #define OTL_SQL_C_TIMESTAMP SQL_C_TIMESTAMP #define OTL_SQL_TIMESTAMP SQL_TIMESTAMP #define OTL_SQL_C_DATE SQL_C_DATE #define OTL_SQL_DATE SQL_DATE #define OTL_SQL_C_TIME SQL_C_TIME #define OTL_SQL_TIME SQL_TIME #endif #if (defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) && \ !defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON)) #error OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT can only be used when \ OTL_ODBC_SQL_EXTENDED_FETCH_ON is defined #endif #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) #if !defined(OTL_DB2_CLI) #define OTL_SQL_NULL_HANDLE SQL_NULL_HANDLE #define OTL_SQL_NULL_HANDLE_VAL nullptr #else #define OTL_SQL_NULL_HANDLE SQL_NULL_HANDLE #define OTL_SQL_NULL_HANDLE_VAL 0 #endif #else #define OTL_SQL_NULL_HANDLE SQL_NULL_HANDLE #define OTL_SQL_NULL_HANDLE_VAL 0 #endif #if !defined(OTL_DB2_CLI) && !defined(OTL_ODBC_zOS) // in case it's ODBC for Windows (!OTL_ODBC_UNIX), and windows.h is // not included yet (_WINDOWS_ not defined yet), then include the file // explicitly #if !defined(OTL_ODBC_UNIX) && !defined(_WINDOWS_) #include #endif #if defined(OTL_ODBC_UNIX) && defined(OTL_INFORMIX_CLI_64_BIT) #include #define OTL_HENV SQLHANDLE #define OTL_HDBC SQLHANDLE #define OTL_SQLHANDLE SQLHANDLE #define OTL_SQLRETURN SQLRETURN #define OTL_SQLSMALLINT SQLSMALLINT #define OTL_SQLCHAR_PTR SQLCHAR * #define OTL_SQLINTEGER_PTR SQLINTEGER * #define OTL_SQLSMALLINT_PTR SQLSMALLINT * #define OTL_SQLINTEGER SQLINTEGER #define OTL_SQLHSTMT SQLHSTMT #define OTL_SQLUSMALLINT SQLUSMALLINT #define OTL_SQLPOINTER SQLPOINTER #define OTL_SQLCHAR SQLCHAR #define OTL_SQLUINTEGER SQLUINTEGER #define OTL_SQLLEN SQLLEN #define OTL_SQLLEN_PTR SQLLEN * #define OTL_SQLULEN SQLULEN #define OTL_SQLULEN_PTR SQLULEN * #elif defined(OTL_ODBC_UNIX) && defined(OTL_INFORMIX_CLI) #include #define OTL_HENV SQLHANDLE #define OTL_HDBC SQLHANDLE #define OTL_SQLHANDLE SQLHANDLE #define OTL_SQLRETURN SQLRETURN #define OTL_SQLSMALLINT SQLSMALLINT #define OTL_SQLCHAR_PTR SQLCHAR * #define OTL_SQLINTEGER_PTR SQLINTEGER * #define OTL_SQLSMALLINT_PTR SQLSMALLINT * #define OTL_SQLINTEGER SQLINTEGER #define OTL_SQLHSTMT SQLHSTMT #define OTL_SQLUSMALLINT SQLUSMALLINT #define OTL_SQLPOINTER SQLPOINTER #define OTL_SQLCHAR SQLCHAR #define OTL_SQLUINTEGER SQLUINTEGER #define OTL_SQLLEN SQLINTEGER #define OTL_SQLLEN_PTR SQLINTEGER * #define OTL_SQLULEN SQLUINTEGER #define OTL_SQLULEN_PTR SQLUINTEGER * #else #include #include #endif #else #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreserved-id-macro" #endif #include #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306) #pragma clang diagnostic pop #endif #endif #if defined(OTL_ODBC) && !defined(OTL_DB2_CLI) #define OTL_SQL_XML (-152) #endif #if defined(OTL_ODBC) && defined(OTL_DB2_CLI) #if defined(SQL_XML) #define OTL_SQL_XML SQL_XML #else #define OTL_SQL_XML (-370) #endif #endif #if defined(OTL_ODBC) #if (ODBCVER >= 0x0300) #define OTL_SQL_TIMESTAMP_STRUCT SQL_TIMESTAMP_STRUCT #define OTL_SQL_TIME_STRUCT SQL_TIME_STRUCT #define OTL_SQL_DATE_STRUCT SQL_DATE_STRUCT #else #define OTL_SQL_TIMESTAMP_STRUCT TIMESTAMP_STRUCT #define OTL_SQL_TIME_STRUCT TIME_STRUCT #define OTL_SQL_DATE_STRUCT DATE_STRUCT #endif #if defined(OTL_DB2_CLI) #define OTL_HENV SQLHANDLE #define OTL_HDBC SQLHANDLE #define OTL_SQLHANDLE SQLHANDLE #define OTL_SQLRETURN SQLRETURN #define OTL_SQLSMALLINT SQLSMALLINT #define OTL_SQLCHAR_PTR SQLCHAR * #define OTL_SQLINTEGER_PTR SQLINTEGER * #define OTL_SQLSMALLINT_PTR SQLSMALLINT * #define OTL_SQLINTEGER SQLINTEGER #define OTL_SQLHSTMT SQLHSTMT #define OTL_SQLUSMALLINT SQLUSMALLINT #define OTL_SQLPOINTER SQLPOINTER #define OTL_SQLCHAR SQLCHAR #define OTL_SQLUINTEGER SQLUINTEGER #if defined(OTL_IODBC_BSD) || defined(_WIN64) #define OTL_SQLLEN SQLLEN #define OTL_SQLULEN SQLULEN #define OTL_SQLULEN_PTR SQLULEN * #define OTL_SQLLEN_PTR SQLLEN * #else // #if defined(OTL_IODBC_BSD) #define OTL_SQLLEN SQLINTEGER #define OTL_SQLLEN_PTR SQLINTEGER * #define OTL_SQLULEN SQLUINTEGER #define OTL_SQLULEN_PTR SQLUINTEGER * #endif // #if defined(OTL_IODBC_BSD) #else // #if defined(OTL_DB2_CLI) #if (ODBCVER >= 0x0300) #define OTL_HENV SQLHANDLE #define OTL_HDBC SQLHANDLE #define OTL_SQLHANDLE SQLHANDLE #define OTL_SQLRETURN SQLRETURN #define OTL_SQLSMALLINT SQLSMALLINT #define OTL_SQLCHAR_PTR SQLCHAR * #define OTL_SQLINTEGER_PTR SQLINTEGER * #define OTL_SQLSMALLINT_PTR SQLSMALLINT * #define OTL_SQLINTEGER SQLINTEGER #define OTL_SQLHSTMT SQLHSTMT #define OTL_SQLUSMALLINT SQLUSMALLINT #define OTL_SQLPOINTER SQLPOINTER #define OTL_SQLCHAR SQLCHAR #define OTL_SQLUINTEGER SQLUINTEGER #if defined(OTL_IODBC_BSD) #define OTL_SQLLEN SQLLEN #define OTL_SQLLEN_PTR SQLLEN * #define OTL_SQLULEN SQLULEN #define OTL_SQLULEN_PTR SQLULEN * #else // #if defined(OTL_IODBC_BSD) #if defined(__MVS__) // C++ in MVS #define OTL_SQLLEN SQLINTEGER #define OTL_SQLLEN_PTR SQLINTEGER * #define OTL_SQLULEN SQLUINTEGER #define OTL_SQLULEN_PTR SQLUINTEGER * #else #if !defined(OTL_SQLLEN) #define OTL_SQLLEN SQLLEN #define OTL_SQLLEN_PTR SQLLEN * #define OTL_SQLULEN SQLULEN #define OTL_SQLULEN_PTR SQLULEN * #endif #endif #endif // #if defined(OTL_IODBC_BSD) #else // #if (ODBCVER >= 0x0300) #define OTL_HENV HENV #define OTL_HDBC HDBC #define OTL_SQLHANDLE HSTMT #define OTL_SQLRETURN SQLRETURN #define OTL_SQLSMALLINT SQLSMALLINT #define OTL_SQLCHAR_PTR SQLCHAR * #define OTL_SQLINTEGER_PTR SQLINTEGER * #define OTL_SQLSMALLINT_PTR SQLSMALLINT * #define OTL_SQLINTEGER SQLINTEGER #define OTL_SQLHSTMT SQLHSTMT #define OTL_SQLUSMALLINT SQLUSMALLINT #define OTL_SQLPOINTER SQLPOINTER #define OTL_SQLCHAR SQLCHAR #define OTL_SQLUINTEGER SQLUINTEGER #if defined(OTL_IODBC_BSD) #define OTL_SQLLEN SQLLEN #define OTL_SQLLEN_PTR SQLLEN * #define OTL_SQLULEN SQLULEN #define OTL_SQLULEN_PTR SQLULEN * #else // #if defined(OTL_IODBC_BSD) #define OTL_SQLLEN SQLLEN #define OTL_SQLLEN_PTR SQLLEN * #define OTL_SQLULEN SQLULEN #define OTL_SQLULEN_PTR SQLULEN * #endif // #if defined(OTL_IODBC_BSD) #endif #endif #endif OTL_ODBC_NAMESPACE_BEGIN #if (defined(UNICODE) || defined(_UNICODE)) && defined(OTL_ODBC) inline void otl_convert_char_to_SQLWCHAR (SQLWCHAR *dst, const unsigned char *src) { while (*src) *dst++ = OTL_SCAST(SQLWCHAR, *src++); *dst = 0; } inline void otl_convert_SQLWCHAR_to_char (unsigned char *dst, const SQLWCHAR *src) { while (*src) *dst++ = OTL_SCAST(unsigned char, *src++); *dst = 0; } #if defined(OTL_ODBC_CHAR_SQLWCHAR_CONVERSION_FUNCS) OTL_ODBC_CHAR_SQLWCHAR_CONVERSION_FUNCS #else inline void otl_convert_char_to_SQLWCHAR_2 (SQLWCHAR *dst, const unsigned char *src) { while (*src) *dst++ = OTL_SCAST(SQLWCHAR, *src++); *dst = 0; } inline void otl_convert_SQLWCHAR_to_char_2 (unsigned char *dst, const SQLWCHAR *src) { while (*src) *dst++ = OTL_SCAST(unsigned char, *src++); *dst = 0; } #endif OTL_NODISCARD inline size_t otl_strlen(const SQLWCHAR *s) { size_t len = 0; while (*s) { ++s; ++len; } return len; } #endif typedef OTL_SQL_TIMESTAMP_STRUCT otl_time; const int otl_odbc_date_prec = 23; #if defined(OTL_ODBC_MSSQL_2008) const int otl_odbc_date_scale = 7; #elif defined(OTL_ODBC_MSSQL_2005) const int otl_odbc_date_scale = 3; #else const int otl_odbc_date_scale = 0; #endif const int OTL_MAX_MSG_ARR = 512; class otl_exc { public: #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) SQLWCHAR msg[1000]; SQLWCHAR sqlstate[1000]; #if defined(OTL_EXCEPTION_IS_DERIVED_FROM_STD_EXCEPTION) protected: mutable unsigned char char_msg[1000]; public: #endif #else unsigned char msg[1000]; unsigned char sqlstate[1000]; #endif int code; #if defined(OTL_EXTENDED_EXCEPTION) #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) SQLWCHAR **msg_arr; SQLWCHAR **sqlstate_arr; #else char **msg_arr; char **sqlstate_arr; #endif int *code_arr; int arr_len; #endif enum { disabled = 0, enabled = 1 }; otl_exc() : msg(), sqlstate(), code(0) #if defined(OTL_EXTENDED_EXCEPTION) #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) , msg_arr(nullptr), sqlstate_arr(nullptr), #else , msg_arr(nullptr), sqlstate_arr(nullptr), #endif code_arr(nullptr), arr_len(0) #endif { sqlstate[0] = 0; msg[0] = 0; } #if defined(OTL_EXTENDED_EXCEPTION) otl_exc(const otl_exc &ex) : #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) msg(), sqlstate(), #else msg(), sqlstate(), #endif code(0), #if defined(OTL_EXTENDED_EXCEPTION) #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) msg_arr(nullptr), sqlstate_arr(nullptr), #else msg_arr(nullptr), sqlstate_arr(nullptr), #endif code_arr(nullptr), arr_len(0) #endif { #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) otl_strcpy(OTL_RCAST(unsigned char *, msg), OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, ex.msg))); otl_strcpy( OTL_RCAST(unsigned char *, OTL_CCAST(SQLWCHAR *, sqlstate)), OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, ex.sqlstate))); code = ex.code; arr_len = 0; msg_arr = nullptr; sqlstate_arr = nullptr; code_arr = nullptr; if (ex.arr_len > 0) { sqlstate_arr = new SQLWCHAR *[ex.arr_len]; msg_arr = new SQLWCHAR *[ex.arr_len]; code_arr = new int[ex.arr_len]; int i; size_t msg_len, sqlstate_len; for (i = 0; i < ex.arr_len; ++i) { msg_len = otl_strlen(ex.msg_arr[i]); sqlstate_len = otl_strlen(ex.sqlstate_arr[i]); msg_arr[i] = new SQLWCHAR[msg_len + 1]; sqlstate_arr[i] = new SQLWCHAR[sqlstate_len + 1]; otl_strcpy(OTL_RCAST(unsigned char *, msg_arr[i]), OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, ex.msg_arr[i]))); otl_strcpy(OTL_RCAST(unsigned char *, sqlstate_arr[i]), OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, ex.sqlstate_arr[i]))); code_arr[i] = ex.code_arr[i]; } arr_len = ex.arr_len; } #else OTL_STRCPY_S(OTL_RCAST(char *, msg), sizeof(msg), OTL_RCAST(const char *, ex.msg)); OTL_STRCPY_S(OTL_RCAST(char *, sqlstate), sizeof(sqlstate), OTL_RCAST(const char *, ex.sqlstate)); code = ex.code; arr_len = 0; msg_arr = nullptr; sqlstate_arr = nullptr; code_arr = nullptr; if (ex.arr_len > 0) { sqlstate_arr = new char *[OTL_SCAST(size_t,ex.arr_len)]; msg_arr = new char *[OTL_SCAST(size_t,ex.arr_len)]; code_arr = new int[OTL_SCAST(size_t,ex.arr_len)]; int i; size_t msg_len, sqlstate_len; for (i = 0; i < ex.arr_len; ++i) { msg_len = strlen(ex.msg_arr[i]); sqlstate_len = strlen(ex.sqlstate_arr[i]); msg_arr[i] = new char[msg_len + 1]; sqlstate_arr[i] = new char[sqlstate_len + 1]; OTL_STRCPY_S(msg_arr[i], msg_len + 1, ex.msg_arr[i]); OTL_STRCPY_S(sqlstate_arr[i], sqlstate_len + 1, ex.sqlstate_arr[i]); code_arr[i] = ex.code_arr[i]; } arr_len = ex.arr_len; } #endif } #endif void init(const char *amsg, const int acode) { #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) otl_convert_char_to_SQLWCHAR( msg, OTL_RCAST(unsigned char *, OTL_CCAST(char *, amsg))); #else OTL_STRCPY_S(OTL_RCAST(char *, msg), sizeof(msg), amsg); #endif code = acode; sqlstate[0] = 0; #if defined(OTL_EXTENDED_EXCEPTION) msg_arr = nullptr; sqlstate_arr = nullptr; code_arr = nullptr; arr_len = 0; #endif } #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) && \ !defined(OTL_EXTENDED_EXCEPTION) otl_exc(const otl_exc &) = default; #endif virtual ~otl_exc() { #if defined(OTL_EXTENDED_EXCEPTION) int i; if (arr_len > 0) { for (i = 0; i < arr_len; ++i) { delete[] msg_arr[i]; delete[] sqlstate_arr[i]; } delete[] msg_arr; delete[] sqlstate_arr; delete[] code_arr; arr_len = 0; msg_arr = nullptr; sqlstate_arr = nullptr; code_arr = nullptr; } #endif } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_exc &operator=(const otl_exc &) = delete; private: #else otl_exc &operator=(const otl_exc &) { return *this; } #if defined(_MSC_VER) && (_MSC_VER >= 1600) #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_exc(otl_exc &&) : msg(), sqlstate(), code(0) #if defined(OTL_EXTENDED_EXCEPTION) , msg_arr(nullptr), sqlstate_arr(nullptr), code_arr(nullptr), arr_len(0) #endif { } otl_exc &operator=(otl_exc &&) { return *this; } #endif #endif #endif }; #if (ODBCVER >= 0x0300) #if defined(OTL_EXTENDED_EXCEPTION) inline void otl_fill_exception(otl_exc &exception_struct, OTL_SQLHANDLE handle, OTL_SQLSMALLINT htype) { #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) OTL_SQLRETURN rc; OTL_SQLSMALLINT msg_len = 0; SQLWCHAR *tmp_msg_arr[OTL_MAX_MSG_ARR]; SQLWCHAR *tmp_sqlstate_arr[OTL_MAX_MSG_ARR]; int tmp_code_arr[OTL_MAX_MSG_ARR]; int tmp_arr_len = 0; OTL_SQLSMALLINT tmp_msg_len = 0; OTL_SQLSMALLINT tmp_sqlstate_len = 0; int tmp_code; SQLWCHAR tmp_msg[SQL_MAX_MESSAGE_LENGTH]; SQLWCHAR tmp_sqlstate[1000]; otl_strcpy(OTL_RCAST(unsigned char *, tmp_msg), OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, exception_struct.msg))); otl_strcpy(OTL_RCAST(unsigned char *, tmp_sqlstate), OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, exception_struct.sqlstate))); tmp_code = exception_struct.code; do { tmp_sqlstate_len = OTL_SCAST(OTL_SQLSMALLINT, otl_strlen(tmp_sqlstate)); tmp_msg_len = OTL_SCAST(OTL_SQLSMALLINT, otl_strlen(tmp_msg)); ++tmp_arr_len; tmp_msg_arr[tmp_arr_len - 1] = new SQLWCHAR[tmp_msg_len + 1]; tmp_sqlstate_arr[tmp_arr_len - 1] = new SQLWCHAR[tmp_sqlstate_len + 1]; otl_strcpy( OTL_RCAST(unsigned char *, tmp_msg_arr[tmp_arr_len - 1]), OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, tmp_msg))); otl_strcpy( OTL_RCAST(unsigned char *, tmp_sqlstate_arr[tmp_arr_len - 1]), OTL_RCAST(const unsigned char *, OTL_CCAST(SQLWCHAR *, tmp_sqlstate))); tmp_code_arr[tmp_arr_len - 1] = tmp_code; rc = SQLGetDiagRec( htype, handle, OTL_SCAST(OTL_SQLSMALLINT, tmp_arr_len + 1), OTL_RCAST(SQLWCHAR *, tmp_sqlstate), OTL_RCAST(OTL_SQLINTEGER_PTR, &tmp_code), OTL_RCAST(SQLWCHAR *, tmp_msg), SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); tmp_msg[msg_len] = 0; if ((rc == SQL_NO_DATA || rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) && tmp_arr_len == 1) { int i; for (i = 0; i < tmp_arr_len; ++i) { delete[] tmp_msg_arr[i]; delete[] tmp_sqlstate_arr[i]; } return; } } while (rc != SQL_NO_DATA && rc != SQL_INVALID_HANDLE && rc != SQL_ERROR && tmp_arr_len < OTL_MAX_MSG_ARR); exception_struct.arr_len = tmp_arr_len; exception_struct.msg_arr = new SQLWCHAR *[tmp_arr_len]; exception_struct.sqlstate_arr = new SQLWCHAR *[tmp_arr_len]; exception_struct.code_arr = new int[tmp_arr_len]; memcpy(exception_struct.msg_arr, tmp_msg_arr, tmp_arr_len * sizeof(SQLWCHAR *)); memcpy(exception_struct.sqlstate_arr, tmp_sqlstate_arr, tmp_arr_len * sizeof(SQLWCHAR *)); memcpy(exception_struct.code_arr, tmp_code_arr, tmp_arr_len * sizeof(int)); #elif defined(UNICODE) || defined(_UNICODE) OTL_SQLRETURN rc; OTL_SQLSMALLINT msg_len = 0; char *tmp_msg_arr[OTL_MAX_MSG_ARR]; char *tmp_sqlstate_arr[OTL_MAX_MSG_ARR]; int tmp_code_arr[OTL_MAX_MSG_ARR]; int tmp_arr_len = 0; OTL_SQLSMALLINT tmp_msg_len = 0; OTL_SQLSMALLINT tmp_sqlstate_len = 0; int tmp_code; SQLWCHAR tmp_msg[SQL_MAX_MESSAGE_LENGTH]; SQLWCHAR tmp_sqlstate[1000]; otl_convert_char_to_SQLWCHAR( tmp_msg, OTL_RCAST(const unsigned char *, exception_struct.msg)); otl_convert_char_to_SQLWCHAR( tmp_sqlstate, OTL_RCAST(const unsigned char *, exception_struct.sqlstate)); tmp_code = exception_struct.code; do { tmp_sqlstate_len = OTL_SCAST(OTL_SQLSMALLINT, otl_strlen(tmp_sqlstate)); tmp_msg_len = OTL_SCAST(OTL_SQLSMALLINT, otl_strlen(tmp_msg)); ++tmp_arr_len; tmp_msg_arr[tmp_arr_len - 1] = new char[tmp_msg_len + 1]; tmp_sqlstate_arr[tmp_arr_len - 1] = new char[tmp_sqlstate_len + 1]; otl_convert_SQLWCHAR_to_char( OTL_RCAST(unsigned char *, tmp_msg_arr[tmp_arr_len - 1]), tmp_msg); otl_convert_SQLWCHAR_to_char( OTL_RCAST(unsigned char *, tmp_sqlstate_arr[tmp_arr_len - 1]), tmp_sqlstate); tmp_code_arr[tmp_arr_len - 1] = tmp_code; rc = SQLGetDiagRec( htype, handle, OTL_SCAST(OTL_SQLSMALLINT, tmp_arr_len + 1), tmp_sqlstate, OTL_RCAST(OTL_SQLINTEGER_PTR, &tmp_code), tmp_msg, SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); tmp_msg[msg_len] = 0; if ((rc == SQL_NO_DATA || rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) && tmp_arr_len == 1) { int i; for (i = 0; i < tmp_arr_len; ++i) { delete[] tmp_msg_arr[i]; delete[] tmp_sqlstate_arr[i]; } return; } } while (rc != SQL_NO_DATA && rc != SQL_INVALID_HANDLE && rc != SQL_ERROR && tmp_arr_len < OTL_MAX_MSG_ARR); exception_struct.arr_len = tmp_arr_len; exception_struct.msg_arr = new char *[tmp_arr_len]; exception_struct.sqlstate_arr = new char *[tmp_arr_len]; exception_struct.code_arr = new int[tmp_arr_len]; memcpy(exception_struct.msg_arr, tmp_msg_arr, tmp_arr_len * sizeof(char *)); memcpy(exception_struct.sqlstate_arr, tmp_sqlstate_arr, tmp_arr_len * sizeof(char *)); memcpy(exception_struct.code_arr, tmp_code_arr, tmp_arr_len * sizeof(int)); #else OTL_SQLRETURN rc; OTL_SQLSMALLINT msg_len = 0; char *tmp_msg_arr[OTL_MAX_MSG_ARR]; char *tmp_sqlstate_arr[OTL_MAX_MSG_ARR]; int tmp_code_arr[OTL_MAX_MSG_ARR]; int tmp_arr_len = 0; OTL_SQLSMALLINT tmp_msg_len = 0; OTL_SQLSMALLINT tmp_sqlstate_len = 0; int tmp_code; char tmp_msg[SQL_MAX_MESSAGE_LENGTH]; char tmp_sqlstate[1000]; OTL_STRCPY_S(tmp_msg, sizeof(tmp_msg), OTL_RCAST(char *, exception_struct.msg)); OTL_STRCPY_S(tmp_sqlstate, sizeof(tmp_sqlstate), OTL_RCAST(char *, exception_struct.sqlstate)); tmp_code = exception_struct.code; do { tmp_sqlstate_len = OTL_SCAST(OTL_SQLSMALLINT, strlen(tmp_sqlstate)); tmp_msg_len = OTL_SCAST(OTL_SQLSMALLINT, strlen(tmp_msg)); ++tmp_arr_len; tmp_msg_arr[tmp_arr_len - 1] = new char[OTL_SCAST(size_t,tmp_msg_len + 1)]; tmp_sqlstate_arr[tmp_arr_len - 1] = new char[OTL_SCAST(size_t,tmp_sqlstate_len + 1)]; OTL_STRCPY_S(tmp_msg_arr[tmp_arr_len - 1], tmp_msg_len + 1, tmp_msg); OTL_STRCPY_S(tmp_sqlstate_arr[tmp_arr_len - 1], tmp_sqlstate_len + 1, tmp_sqlstate); tmp_code_arr[tmp_arr_len - 1] = tmp_code; void *temp_ptr = &tmp_code; rc = SQLGetDiagRec( htype, handle, OTL_SCAST(OTL_SQLSMALLINT, tmp_arr_len + 1), OTL_RCAST(OTL_SQLCHAR_PTR, tmp_sqlstate), OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr), OTL_RCAST(OTL_SQLCHAR_PTR, tmp_msg), SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); tmp_msg[msg_len] = 0; if ((rc == SQL_NO_DATA || rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) && tmp_arr_len == 1) { int i; for (i = 0; i < tmp_arr_len; ++i) { delete[] tmp_msg_arr[i]; delete[] tmp_sqlstate_arr[i]; } return; } } while (rc != SQL_NO_DATA && rc != SQL_INVALID_HANDLE && rc != SQL_ERROR && tmp_arr_len < OTL_MAX_MSG_ARR); exception_struct.arr_len = tmp_arr_len; exception_struct.msg_arr = new char *[OTL_SCAST(size_t,tmp_arr_len)]; exception_struct.sqlstate_arr = new char *[OTL_SCAST(size_t,tmp_arr_len)]; exception_struct.code_arr = new int[OTL_SCAST(size_t,tmp_arr_len)]; memcpy(exception_struct.msg_arr, tmp_msg_arr, OTL_SCAST(size_t, tmp_arr_len) * sizeof(char *)); memcpy(exception_struct.sqlstate_arr, tmp_sqlstate_arr, OTL_SCAST(size_t, tmp_arr_len) * sizeof(char *)); memcpy(exception_struct.code_arr, tmp_code_arr, OTL_SCAST(size_t, tmp_arr_len) * sizeof(int)); #endif } #endif #endif const int OTL_DEFAULT_ODBC_CONNECT = 1; const int OTL_TIMESTEN_ODBC_CONNECT = 2; const int OTL_MSSQL_2005_ODBC_CONNECT = 3; const int OTL_POSTGRESQL_ODBC_CONNECT = 4; const int OTL_ENTERPRISE_DB_ODBC_CONNECT = 5; const int OTL_MYODBC35_ODBC_CONNECT = 6; const int OTL_MSSQL_2008_ODBC_CONNECT = 7; class otl_cur; class otl_connect; class otl_sel; #if defined(OTL_ENABLE_MSSQL_MARS) #define OTL_SQL_COPT_SS_BASE 1200 #define OTL_SQL_COPT_SS_MARS_ENABLED (OTL_SQL_COPT_SS_BASE + 24) #define OTL_SQL_MARS_ENABLED_YES 1L #endif class otl_conn { protected: friend class otl_connect; friend class otl_cur; friend class otl_sel; OTL_HENV henv; OTL_HDBC hdbc; int timeout; int cursor_type; int status; int long_max_size; bool extern_lda; #if defined(OTL_ODBC_zOS) bool logoff_commit; #endif #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO) bool throws_on_sql_success_with_info; #endif int connection_type; public: enum bigint_type { #if defined(OTL_BIGINT) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR) var_bigint = otl_var_bigint, bigint_size = sizeof(OTL_BIGINT) #else var_bigint = otl_var_char, bigint_size = otl_bigint_str_size #endif }; enum ubigint_type { #if defined(OTL_UBIGINT) var_ubigint = otl_var_ubigint, ubigint_size = sizeof(OTL_UBIGINT) #else var_ubigint = otl_var_char, ubigint_size = otl_ubigint_str_size #endif }; #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__==408) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" #endif void cleanup(void) {} OTL_NODISCARD OTL_HENV &get_henv() { return henv; } OTL_NODISCARD OTL_HDBC &get_hdbc() { return hdbc; } OTL_NODISCARD int get_connection_type(void) { return connection_type; } OTL_NODISCARD static int initialize(const int /* threaded_mode */ = 0) { return 1; } otl_conn() : henv(OTL_SQL_NULL_HANDLE_VAL), hdbc(OTL_SQL_NULL_HANDLE_VAL), timeout(0), cursor_type(0), status(SQL_SUCCESS), long_max_size(otl_short_int_max), extern_lda(false) #if defined(OTL_ODBC_zOS) , logoff_commit(true) #endif #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO) , throws_on_sql_success_with_info(false) #endif , connection_type(OTL_DEFAULT_ODBC_CONNECT) { } #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) OTL_NODISCARD int rlogon(const SQLWCHAR *username, const SQLWCHAR *passwd, const SQLWCHAR *tnsname, const int auto_commit) { if (extern_lda) { extern_lda = false; henv = nullptr; hdbc = nullptr; } OTL_TRACE_RLOGON_ODBC_W(0x1, L"otl_connect", L"rlogon", OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, tnsname), OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, username), OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, passwd), auto_commit); if (henv == nullptr || hdbc == nullptr) { status = SQLAllocHandle(SQL_HANDLE_ENV, OTL_SQL_NULL_HANDLE_VAL, &henv); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; status = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, OTL_RCAST(void *, SQL_OV_ODBC3), SQL_NTS); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; status = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } if (auto_commit) { status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON), SQL_IS_POINTER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } else { #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 500) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=705) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" #endif SQLPOINTER temp = OTL_SCAST(SQLPOINTER,SQL_AUTOCOMMIT_OFF); #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 500) #pragma clang diagnostic pop #endif status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, OTL_RCAST(SQLPOINTER, temp), SQL_IS_POINTER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } if (timeout > 0) { status = SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT, OTL_RCAST(void *, OTL_SCAST(size_t, timeout)), 0); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } #if defined(OTL_DB2_CLI) status = SQLSetConnectAttr(hdbc, SQL_ATTR_LONGDATA_COMPAT, OTL_RCAST(SQLPOINTER, SQL_LD_COMPAT_YES), SQL_IS_INTEGER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif #if defined(OTL_ENABLE_MSSQL_MARS) #if !defined(OTL_DB2_CLI) && (ODBCVER >= 0x0300) status = SQLSetConnectAttr(hdbc, OTL_SQL_COPT_SS_MARS_ENABLED, OTL_RCAST(SQLPOINTER, OTL_SQL_MARS_ENABLED_YES), SQL_IS_UINTEGER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif #endif status = SQLConnect(hdbc, OTL_CCAST(SQLWCHAR *, tnsname), SQL_NTS, OTL_CCAST(SQLWCHAR *, username), SQL_NTS, OTL_CCAST(SQLWCHAR *, passwd), SQL_NTS); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } #endif #if !defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) && \ ((defined(ODBCVER) && ODBCVER >= 0x0300) || defined(OTL_DB2_CLI)) #if defined(OTL_DB2_CLI) #define OTL_RLOGON_SQLHANDLE_NULLPTR OTL_SCAST(SQLHANDLE,0) #else #define OTL_RLOGON_SQLHANDLE_NULLPTR nullptr #endif inline void otl_special_convert_char_to_SQLWCHAR (SQLWCHAR *dst, const char *src){ while (*src) *dst++ = OTL_SCAST(SQLWCHAR, *src++); *dst = 0; } #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 500) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant" #endif OTL_NODISCARD int rlogon(const char*username, const char *passwd, const char *dnsname, const int auto_commit){ if(extern_lda){ extern_lda=false; henv=OTL_RLOGON_SQLHANDLE_NULLPTR; hdbc=OTL_RLOGON_SQLHANDLE_NULLPTR; } OTL_TRACE_RLOGON_ODBC(0x1, "otl_connect", "rlogon", dnsname, username, passwd, auto_commit) if (henv == OTL_RLOGON_SQLHANDLE_NULLPTR || hdbc == OTL_RLOGON_SQLHANDLE_NULLPTR) { status = SQLAllocHandle(SQL_HANDLE_ENV, OTL_SQL_NULL_HANDLE_VAL, &henv); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; status = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, OTL_RCAST(void *, SQL_OV_ODBC3), SQL_NTS); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; status = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } if (auto_commit) { status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON), SQL_IS_POINTER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } else { SQLPOINTER temp = SQL_AUTOCOMMIT_OFF; status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, OTL_RCAST(SQLPOINTER, temp), SQL_IS_POINTER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } if (timeout > 0) { status = SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT, OTL_RCAST(void *, OTL_SCAST(size_t, timeout)), 0); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } #if defined(OTL_DB2_CLI) status = SQLSetConnectAttr(hdbc, SQL_ATTR_LONGDATA_COMPAT, OTL_RCAST(SQLPOINTER, SQL_LD_COMPAT_YES), SQL_IS_INTEGER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif #if defined(OTL_ENABLE_MSSQL_MARS) #if !defined(OTL_DB2_CLI) && (ODBCVER >= 0x0300) status = SQLSetConnectAttr(hdbc, OTL_SQL_COPT_SS_MARS_ENABLED, OTL_RCAST(SQLPOINTER, OTL_SQL_MARS_ENABLED_YES), SQL_IS_UINTEGER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif #endif #if defined(_UNICODE) || defined(UNICODE) { SQLWCHAR *temp_dnsname = new SQLWCHAR[strlen(dnsname) + 1]; SQLWCHAR *temp_username = new SQLWCHAR[strlen(username) + 1]; SQLWCHAR *temp_passwd = new SQLWCHAR[strlen(passwd) + 1]; otl_special_convert_char_to_SQLWCHAR(temp_dnsname,dnsname); otl_special_convert_char_to_SQLWCHAR(temp_username,username); otl_special_convert_char_to_SQLWCHAR(temp_passwd,passwd); status = SQLConnect(hdbc, temp_dnsname, SQL_NTS, temp_username, SQL_NTS, temp_passwd, SQL_NTS); delete[] temp_dnsname; delete[] temp_username; delete[] temp_passwd; } #else status = SQLConnect(hdbc, OTL_RCAST(unsigned char*, OTL_CCAST(char*, dnsname)), SQL_NTS, OTL_RCAST(unsigned char*, OTL_CCAST(char*, username)), SQL_NTS, OTL_RCAST(unsigned char*, OTL_CCAST(char*, passwd)), SQL_NTS); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 500) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif #else OTL_NODISCARD int rlogon(const char* /*username*/, const char* /*passwd*/, const char* /*dnsname*/, const int /*auto_commit*/){ return 0; } #endif #if defined(OTL_DB2_CLI) OTL_NODISCARD int set_prog_name(const char *prog_name) { if (henv == OTL_SQL_NULL_HANDLE_VAL || hdbc == OTL_SQL_NULL_HANDLE_VAL) { status = SQLAllocHandle(SQL_HANDLE_ENV, OTL_SQL_NULL_HANDLE, &henv); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; status = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, OTL_RCAST(void *, SQL_OV_ODBC3), SQL_NTS); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; status = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } #if !defined(SQL_ATTR_INFO_PROGRAMNAME) #define SQL_ATTR_INFO_PROGRAMNAME 2516 #endif status = SQLSetConnectAttr( hdbc, SQL_ATTR_INFO_PROGRAMNAME, OTL_RCAST(SQLPOINTER, OTL_CCAST(char *, prog_name)), SQL_NTS); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } #endif OTL_NODISCARD int ext_logon(OTL_HENV ahenv, OTL_HDBC ahdbc, const int #ifndef OTL_ODBC_MYSQL auto_commit #endif ) { if (!extern_lda) { #if (ODBCVER >= 0x0300) if (hdbc != OTL_SQL_NULL_HANDLE_VAL) { status = SQLFreeHandle(SQL_HANDLE_DBC, hdbc); } #else if (hdbc != nullptr) status = SQLFreeConnect(hdbc); #endif hdbc = OTL_SQL_NULL_HANDLE_VAL; #if (ODBCVER >= 0x0300) if (henv != OTL_SQL_NULL_HANDLE_VAL) { status = SQLFreeHandle(SQL_HANDLE_ENV, henv); } #else if (henv != nullptr) status = SQLFreeEnv(henv); #endif henv = OTL_SQL_NULL_HANDLE_VAL; } extern_lda = true; henv = ahenv; hdbc = ahdbc; #ifndef OTL_ODBC_MYSQL #if (ODBCVER >= 0x0300) if (auto_commit) status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON), SQL_IS_POINTER); else status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) nullptr, #else OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_OFF), #endif SQL_IS_POINTER); #else if (auto_commit) status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 1); else status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 0); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif #if defined(OTL_DB2_CLI) status = SQLSetConnectAttr(hdbc, SQL_ATTR_LONGDATA_COMPAT, OTL_RCAST(SQLPOINTER, SQL_LD_COMPAT_YES), SQL_IS_INTEGER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif return 1; } virtual ~otl_conn() { if (extern_lda) { hdbc = OTL_SQL_NULL_HANDLE_VAL; henv = OTL_SQL_NULL_HANDLE_VAL; extern_lda = false; } else { #if (ODBCVER >= 0x0300) if (hdbc != OTL_SQL_NULL_HANDLE_VAL) { status = SQLFreeHandle(SQL_HANDLE_DBC, hdbc); } #else if (hdbc != nullptr) status = SQLFreeConnect(hdbc); #endif hdbc = OTL_SQL_NULL_HANDLE_VAL; #if (ODBCVER >= 0x0300) if (henv != OTL_SQL_NULL_HANDLE_VAL) { status = SQLFreeHandle(SQL_HANDLE_ENV, henv); } #else if (henv != nullptr) status = SQLFreeEnv(henv); #endif henv = OTL_SQL_NULL_HANDLE_VAL; } } void set_timeout(const int atimeout = 0) { timeout = atimeout; } void set_cursor_type(const int acursor_type = 0) { cursor_type = acursor_type; } OTL_NODISCARD int rlogon(const char *connect_str, const int #ifndef OTL_ODBC_MYSQL auto_commit #endif ) { char username[256]; char passwd[256]; char tnsname[1024]; char *tnsname_ptr = nullptr; char *c = OTL_CCAST(char *, connect_str); char *username_ptr = username; char *passwd_ptr = passwd; char temp_connect_str[512]; if (extern_lda) { extern_lda = false; henv = OTL_SQL_NULL_HANDLE_VAL; hdbc = OTL_SQL_NULL_HANDLE_VAL; } memset(username, 0, sizeof(username)); memset(passwd, 0, sizeof(passwd)); memset(tnsname, 0, sizeof(tnsname)); char *c1 = OTL_CCAST(char *, connect_str); int oracle_format = 0; char prev_c = ' '; while (*c1) { if (*c1 == '@' && prev_c != '\\') { oracle_format = 1; break; } prev_c = *c1; ++c1; } if (oracle_format) { while (*c && *c != '/' && (OTL_SCAST(unsigned, username_ptr - username) < sizeof(username) - 1)) { *username_ptr = *c; ++c; ++username_ptr; } *username_ptr = 0; if (*c == '/') ++c; prev_c = ' '; while (*c && !(*c == '@' && prev_c != '\\') && (OTL_SCAST(unsigned, passwd_ptr - passwd) < sizeof(passwd) - 1)) { if (prev_c == '\\') --passwd_ptr; *passwd_ptr = *c; prev_c = *c; ++c; ++passwd_ptr; } *passwd_ptr = 0; if (*c == '@') { ++c; tnsname_ptr = tnsname; while (*c && (OTL_SCAST(unsigned, tnsname_ptr - tnsname) < sizeof(tnsname) - 1)) { *tnsname_ptr = *c; ++c; ++tnsname_ptr; } *tnsname_ptr = 0; } } else { c1 = OTL_CCAST(char *, connect_str); char *c2 = temp_connect_str; while (*c1 && (OTL_SCAST(unsigned, c2 - temp_connect_str) < sizeof(temp_connect_str) - 1)) { *c2 = otl_to_upper(*c1); ++c1; ++c2; } *c2 = 0; c1 = temp_connect_str; char entry_name[256]; char entry_value[256]; while (*c1 && (OTL_SCAST(unsigned, c1 - temp_connect_str) < sizeof(temp_connect_str) - 1)) { c2 = entry_name; while (*c1 && *c1 != '=' && (OTL_SCAST(unsigned, c1 - temp_connect_str) < sizeof(temp_connect_str) - 1)) { *c2 = *c1; ++c1; ++c2; } *c2 = 0; #if defined(_MSC_VER) && (_MSC_VER == 1600) entry_name[c2 - entry_name] = 0; #endif if (*c1) ++c1; c2 = entry_value; prev_c = ' '; while (*c1 && *c1 != ';' && (OTL_SCAST(unsigned, c2 - entry_value) < sizeof(entry_value) - 1)) { if (prev_c == '\\') --c2; *c2 = *c1; prev_c = *c1; ++c1; ++c2; } *c2 = 0; #if defined(_MSC_VER) && (_MSC_VER == 1600) entry_value[c2 - entry_value] = 0; #endif if (*c1) ++c1; if (strcmp(entry_name, "DSN") == 0) OTL_STRCPY_S(tnsname, sizeof(tnsname), entry_value); if (strcmp(entry_name, "UID") == 0) OTL_STRCPY_S(username, sizeof(username), entry_value); if (strcmp(entry_name, "PWD") == 0) OTL_STRCPY_S(passwd, sizeof(passwd), entry_value); } } #ifndef OTL_ODBC_MYSQL OTL_TRACE_RLOGON_ODBC(0x1, "otl_connect", "rlogon", tnsname, username, passwd, auto_commit) #else OTL_TRACE_RLOGON_ODBC(0x1, "otl_connect", "rlogon", tnsname, username, passwd, 0) #endif if (henv == OTL_SQL_NULL_HANDLE_VAL || hdbc == OTL_SQL_NULL_HANDLE_VAL) { #if (ODBCVER >= 0x0300) status = SQLAllocHandle(SQL_HANDLE_ENV, OTL_SQL_NULL_HANDLE_VAL, &henv); #else status = SQLAllocEnv(&henv); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #if (ODBCVER >= 0x0300) status = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, OTL_RCAST(void *, SQL_OV_ODBC3), SQL_NTS); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif #if (ODBCVER >= 0x0300) status = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc); #else status = SQLAllocConnect(henv, &hdbc); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } else status = SQL_SUCCESS; #ifndef OTL_ODBC_MYSQL #if (ODBCVER >= 0x0300) if (auto_commit) status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON), SQL_IS_POINTER); else status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) nullptr, #else OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_OFF), #endif SQL_IS_POINTER); #else if (auto_commit) status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 1); else status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 0); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif #if (ODBCVER >= 0x0300) if (timeout > 0) status = SQLSetConnectAttr(hdbc, SQL_ATTR_LOGIN_TIMEOUT, OTL_RCAST(void *, OTL_SCAST(size_t, timeout)), 0); #else if (timeout > 0) status = SQLSetConnectOption(hdbc, SQL_LOGIN_TIMEOUT, OTL_SCAST(size_t,timeout)); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #if defined(OTL_DB2_CLI) status = SQLSetConnectAttr(hdbc, SQL_ATTR_LONGDATA_COMPAT, OTL_RCAST(SQLPOINTER, SQL_LD_COMPAT_YES), SQL_IS_INTEGER); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #endif #if defined(OTL_ENABLE_MSSQL_MARS) #if !defined(OTL_DB2_CLI) && (ODBCVER >= 0x0300) status = SQLSetConnectAttr(hdbc, OTL_SQL_COPT_SS_MARS_ENABLED, OTL_RCAST(SQLPOINTER, OTL_SQL_MARS_ENABLED_YES), SQL_IS_UINTEGER); if (status != SQL_SUCCESS_WITH_INFO && status != SQL_SUCCESS) return 0; #endif #endif if (oracle_format) { #if defined(OTL_ODBC_zOS) if (tnsname[0] == 0 && username[0] == 0 && passwd[0] == 0) { status = SQLConnect(hdbc, 0L, SQL_NTS, 0L, SQL_NTS, 0L, SQL_NTS); logoff_commit = false; } else status = SQLConnect(hdbc, OTL_RCAST(unsigned char *, tnsname), SQL_NTS, OTL_RCAST(unsigned char *, username), SQL_NTS, OTL_RCAST(unsigned char *, passwd), SQL_NTS); #else #if defined(UNICODE) || defined(_UNICODE) { SQLWCHAR *temp_tnsname = new SQLWCHAR[strlen(tnsname) + 1]; SQLWCHAR *temp_username = new SQLWCHAR[strlen(username) + 1]; SQLWCHAR *temp_passwd = new SQLWCHAR[strlen(passwd) + 1]; otl_convert_char_to_SQLWCHAR_2(temp_tnsname, OTL_RCAST(unsigned char *, tnsname)); otl_convert_char_to_SQLWCHAR_2(temp_username, OTL_RCAST(unsigned char *, username)); otl_convert_char_to_SQLWCHAR_2(temp_passwd, OTL_RCAST(unsigned char *, passwd)); status = SQLConnect(hdbc, temp_tnsname, SQL_NTS, temp_username, SQL_NTS, temp_passwd, SQL_NTS); delete[] temp_tnsname; delete[] temp_username; delete[] temp_passwd; } #else status = SQLConnect(hdbc, OTL_RCAST(unsigned char *, tnsname), SQL_NTS, OTL_RCAST(unsigned char *, username), SQL_NTS, OTL_RCAST(unsigned char *, passwd), SQL_NTS); #endif #endif } else { char *tc2 = temp_connect_str; const char *tc1 = connect_str; prev_c = ' '; while (*tc1 && (OTL_SCAST(unsigned, tc2 - temp_connect_str) < sizeof(temp_connect_str) - 1)) { if (*tc1 == '@' && prev_c == '\\') --tc2; *tc2 = *tc1; prev_c = *tc1; ++tc1; ++tc2; } *tc2 = 0; #if defined(_MSC_VER) && (_MSC_VER == 1600) temp_connect_str[tc2 - temp_connect_str] = 0; #endif SQLSMALLINT out_len = 0; #if (defined(UNICODE) || defined(_UNICODE)) { size_t len = strlen(temp_connect_str); SQLWCHAR *temp_connect_str2 = new SQLWCHAR[len + 1]; SQLWCHAR out_str[2048]; otl_convert_char_to_SQLWCHAR_2( temp_connect_str2, OTL_RCAST(unsigned char *, temp_connect_str)); status = SQLDriverConnect( hdbc, nullptr, temp_connect_str2, OTL_SCAST(short, len), out_str, OTL_SCAST(OTL_SQLSMALLINT, sizeof(out_str) / sizeof(SQLWCHAR)), &out_len, SQL_DRIVER_NOPROMPT); delete[] temp_connect_str2; } #else SQLCHAR out_str[2048]; status = SQLDriverConnect( hdbc, nullptr, OTL_RCAST(SQLCHAR *, OTL_CCAST(char *, temp_connect_str)), OTL_SCAST(short, strlen(temp_connect_str)), out_str, OTL_SCAST(SQLSMALLINT, sizeof(out_str)), &out_len, SQL_DRIVER_NOPROMPT); #endif } if (status == SQL_SUCCESS_WITH_INFO || status == SQL_SUCCESS) return 1; else return 0; } OTL_NODISCARD int set_transaction_isolation_level(const long int #ifndef OTL_ODBC_MYSQL level #endif ) { #ifndef OTL_ODBC_MYSQL #if (ODBCVER >= 0x0300) status = SQLSetConnectAttr(hdbc, SQL_ATTR_TXN_ISOLATION, OTL_RCAST(SQLPOINTER, OTL_SCAST(size_t, level)), SQL_IS_POINTER); #else status = SQLSetConnectOption(hdbc, SQL_TXN_ISOLATION, OTL_SCAST(size_t,level)); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; #else return 1; #endif } OTL_NODISCARD int auto_commit_on(void) { #if defined(OTL_ODBC_MYSQL) return 1; #else #if (ODBCVER >= 0x0300) status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_ON), SQL_IS_POINTER); #else status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 1); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; #endif } OTL_NODISCARD int auto_commit_off(void) { #if defined(OTL_ODBC_MYSQL) return 1; #else #if (ODBCVER >= 0x0300) status = SQLSetConnectAttr(hdbc, SQL_ATTR_AUTOCOMMIT, #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) nullptr, #else OTL_RCAST(SQLPOINTER, SQL_AUTOCOMMIT_OFF), #endif SQL_IS_POINTER); #else status = SQLSetConnectOption(hdbc, SQL_AUTOCOMMIT, 0); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; #endif } OTL_NODISCARD int logoff(void) { if (extern_lda) { extern_lda = false; henv = OTL_SQL_NULL_HANDLE_VAL; hdbc = OTL_SQL_NULL_HANDLE_VAL; return 1; } else { #if defined(OTL_ODBC_zOS) if (logoff_commit) (void)commit(); #else (void)commit(); #endif status = SQLDisconnect(hdbc); #if defined(OTL_ODBC_LOGOFF_FREES_HANDLES) #if (ODBCVER >= 0x0300) if (hdbc != nullptr) { SQLFreeHandle(SQL_HANDLE_DBC, hdbc); hdbc = nullptr; } if (henv != nullptr) { SQLFreeHandle(SQL_HANDLE_ENV, henv); henv = nullptr; } #else if (hdbc != nullptr) { SQLFreeConnect(hdbc); hdbc = nullptr; } if (henv != nullptr) { SQLFreeEnv(henv); henv = nullptr; } #endif #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } } void error(otl_exc &exception_struct) { OTL_SQLRETURN rc; OTL_SQLSMALLINT msg_len = 0; #if (ODBCVER >= 0x0300) #if (defined(UNICODE) || defined(_UNICODE)) #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) #if defined(__GNUC__)&&defined(__GNUC_MINOR__)&&(__GNUC__ * 100 + __GNUC_MINOR__ >= 407) void* temp_ptr = &exception_struct.code; rc = SQLGetDiagRec #if defined(OTL_ODBC_zOS) (hdbc == nullptr ? SQL_HANDLE_ENV : SQL_HANDLE_DBC, hdbc == nullptr ? henv : hdbc, #else (SQL_HANDLE_DBC, hdbc, #endif 1, &exception_struct.sqlstate[0], OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr), &exception_struct.msg[0], SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #else rc = SQLGetDiagRec #if defined(OTL_ODBC_zOS) (hdbc == nullptr ? SQL_HANDLE_ENV : SQL_HANDLE_DBC, hdbc == nullptr ? henv : hdbc, #else (SQL_HANDLE_DBC, hdbc, #endif 1, &exception_struct.sqlstate[0], OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code), &exception_struct.msg[0], SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #endif exception_struct.msg[msg_len] = 0; #else { SQLWCHAR temp_msg[SQL_MAX_MESSAGE_LENGTH]; SQLWCHAR temp_sqlstate[1000]; rc = SQLGetDiagRec #if defined(OTL_ODBC_zOS) (hdbc == nullptr ? SQL_HANDLE_ENV : SQL_HANDLE_DBC, hdbc == nullptr ? henv : hdbc, #else (SQL_HANDLE_DBC, hdbc, #endif 1, temp_sqlstate, OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code), temp_msg, SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); temp_msg[msg_len] = 0; otl_convert_SQLWCHAR_to_char_2( OTL_RCAST(unsigned char *, &exception_struct.sqlstate[0]), temp_sqlstate); otl_convert_SQLWCHAR_to_char_2( OTL_RCAST(unsigned char *, &exception_struct.msg[0]), temp_msg); } #endif #else void *temp_ptr = &exception_struct.code; rc = SQLGetDiagRec #if defined(OTL_ODBC_zOS) (hdbc == nullptr ? SQL_HANDLE_ENV : SQL_HANDLE_DBC, hdbc == nullptr ? henv : hdbc, #else (SQL_HANDLE_DBC, hdbc, #endif 1, OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]), OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr), OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]), SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #endif #else #if defined(__GNUC__)&&defined(__GNUC_MINOR__)&&(__GNUC__ * 100 + __GNUC_MINOR__ >= 407) void* temp_ptr=&exception_struct.code; rc = SQLError(henv, hdbc, 0, // hstmt OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]), OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr), OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]), SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #else rc = SQLError(henv, hdbc, 0, // hstmt OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]), OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code), OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]), SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #endif #endif exception_struct.msg[msg_len] = 0; if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) exception_struct.msg[0] = 0; #if (ODBCVER >= 0x0300) #if defined(OTL_EXTENDED_EXCEPTION) else if (rc != SQL_NO_DATA) #if defined(OTL_ODBC_zOS) { if (hdbc) otl_fill_exception(exception_struct, hdbc, SQL_HANDLE_DBC); else otl_fill_exception(exception_struct, henv, SQL_HANDLE_ENV); } #else otl_fill_exception(exception_struct, hdbc, SQL_HANDLE_DBC); #endif #endif #endif } OTL_NODISCARD int commit(void) { #ifndef OTL_ODBC_MYSQL #if (ODBCVER >= 0x0300) status = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_COMMIT); #else status = SQLTransact(henv, hdbc, SQL_COMMIT); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; #else return 1; #endif } OTL_NODISCARD int rollback(void) { #ifndef OTL_ODBC_MYSQL #if (ODBCVER >= 0x0300) status = SQLEndTran(SQL_HANDLE_DBC, hdbc, SQL_ROLLBACK); #else status = SQLTransact(henv, hdbc, SQL_ROLLBACK); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; #else return 1; #endif } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_conn(const otl_conn &) = delete; otl_conn &operator=(const otl_conn &) = delete; private: #else otl_conn(const otl_conn &) : henv(OTL_SQL_NULL_HANDLE_VAL), hdbc(OTL_SQL_NULL_HANDLE_VAL), timeout(0), cursor_type(0), status(SQL_SUCCESS), long_max_size(otl_short_int_max), extern_lda(false) #if defined(OTL_ODBC_zOS) , logoff_commit(true) #endif #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO) , throws_on_sql_success_with_info(false) #endif , connection_type(OTL_DEFAULT_ODBC_CONNECT) { } otl_conn &operator=(const otl_conn &) { return *this; } #endif }; class otl_var; class otl_cur; class otl_sel; class otl_cur0 { protected: friend class otl_sel; friend class otl_var; OTL_SQLHSTMT cda; int last_param_data_token; int last_sql_param_data_status; int sql_param_data_count; public: otl_cur0() : cda(OTL_SQL_NULL_HANDLE_VAL), last_param_data_token(0), last_sql_param_data_status(0), sql_param_data_count(0) {} virtual ~otl_cur0() {} OTL_NODISCARD OTL_SQLHSTMT get_cda() { return cda; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_cur0(const otl_cur0 &) = delete; otl_cur0 &operator=(const otl_cur0 &) = delete; private: #else otl_cur0(const otl_cur0 &) : cda(OTL_SQL_NULL_HANDLE_VAL), last_param_data_token(0), last_sql_param_data_status(0), sql_param_data_count(0) {} otl_cur0 &operator=(const otl_cur0 &) { return *this; } #endif }; class otl_cur; class otl_var { private: friend class otl_cur; unsigned char *p_v; OTL_SQLLEN_PTR p_len; int ftype; int act_elem_size; bool lob_stream_mode; int lob_stream_flag; int vparam_type; int lob_len; int lob_pos; int lob_ftype; otl_adapter_enum otl_adapter; bool charz_flag; public: #if defined(OTL_CONTAINER_CLASSES_HAVE_OPTIONAL_MEMBERS) void set_nls_flag(const bool) {} #endif void reset_lob_len() { lob_len = 0; } OTL_NODISCARD otl_adapter_enum get_otl_adapter() const { return otl_adapter; } void set_lob_stream_mode(const bool alob_stream_mode) { lob_stream_mode = alob_stream_mode; } void set_vparam_type(const int avparam_type) { vparam_type = avparam_type; } void set_charz_flag(const bool acharz_flag) { charz_flag = acharz_flag; } otl_var() : p_v(nullptr), p_len(nullptr), ftype(0), act_elem_size(0), lob_stream_mode(false), lob_stream_flag(0), vparam_type(-1), lob_len(0), lob_pos(0), lob_ftype(0), otl_adapter(OTL_ADAPTER_ENUM otl_odbc_adapter), charz_flag(false) {} virtual ~otl_var() { delete[] p_v; delete[] p_len; } OTL_NODISCARD int write_dt(void *trg, const void *src, const int sz) { memcpy(trg, src, OTL_SCAST(unsigned int, sz)); return 1; } OTL_NODISCARD int read_dt(void *trg, const void *src, const int sz) { memcpy(trg, src, OTL_SCAST(unsigned int, sz)); return 1; } void set_lob_stream_flag(const int flg = 1) { lob_stream_flag = flg; } OTL_NODISCARD int get_pl_tab_len(void) { return 0; } OTL_NODISCARD int get_max_pl_tab_len(void) { return 0; } void set_pl_tab_len(const int /* pl_tab_len */) {} OTL_NODISCARD int write_blob(const otl_long_string &s, const int /* alob_len */, int &aoffset, otl_cur0 &cur) { SQLRETURN rc = 0; SQLINTEGER temp_len = 0; SQLPOINTER pToken = nullptr; int param_number = 0; if (!lob_stream_flag && !lob_stream_mode) return 1; if (aoffset == 1) { if (cur.sql_param_data_count == 0) { rc = SQLParamData(cur.cda, &pToken); param_number = OTL_SCAST(int, OTL_RCAST(size_t, pToken)); ++cur.sql_param_data_count; cur.last_sql_param_data_status = rc; cur.last_param_data_token = param_number; if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && rc != SQL_NEED_DATA) return 0; } } if (ftype == otl_var_raw_long) temp_len = s.len(); else temp_len = s.len() * OTL_SCAST(int, sizeof(OTL_CHAR)); rc = SQLPutData(cur.cda, s.v, temp_len); if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO) return 0; else { aoffset += s.len(); return 1; } } OTL_NODISCARD int clob_blob(otl_cur0 &cur) { SQLRETURN rc = 0; SQLPOINTER pToken = nullptr; int param_number = 0; if (!(cur.last_param_data_token == 0 && cur.sql_param_data_count > 0)) { rc = SQLParamData(cur.cda, &pToken); param_number = OTL_SCAST(int, OTL_RCAST(size_t, pToken)); ++cur.sql_param_data_count; cur.last_sql_param_data_status = rc; cur.last_param_data_token = param_number; if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO && #if (ODBCVER >= 0x0300) rc != SQL_NO_DATA && #endif rc != SQL_NEED_DATA) return 0; } return 1; } OTL_NODISCARD int read_blob(otl_cur0 &cur, otl_long_string &s, const int andx, int &aoffset, int &eof_flag) { SQLRETURN rc = 0; OTL_SQLLEN retLen = 0; int chunkLen = 0; if (!lob_stream_flag && !lob_stream_mode) return 1; int buf_size = s.get_buf_size() * OTL_SCAST(int, sizeof(OTL_CHAR)); if (ftype == otl_var_raw_long) buf_size = s.get_buf_size(); rc = SQLGetData(cur.cda, OTL_SCAST(SQLUSMALLINT, lob_pos), OTL_SCAST(SQLSMALLINT, lob_ftype), s.v, buf_size, &retLen); if (rc == SQL_SUCCESS_WITH_INFO || rc == SQL_SUCCESS) { if (retLen == SQL_NULL_DATA) { chunkLen = 0; p_len[andx] = SQL_NULL_DATA; } else if (retLen > buf_size || retLen == SQL_NO_TOTAL) chunkLen = s.get_buf_size(); else { if (ftype == otl_var_raw_long) chunkLen = OTL_SCAST(int, retLen); else chunkLen = OTL_SCAST(int, retLen) / OTL_SCAST(int, sizeof(OTL_CHAR)); } #if defined(OTL_UNICODE) if (lob_ftype == SQL_C_WCHAR) s.set_len(chunkLen - 1); #else if (lob_ftype == SQL_C_CHAR) s.set_len(chunkLen - 1); #endif else s.set_len(chunkLen); if (lob_len == 0 && aoffset == 1 && retLen != SQL_NULL_DATA && retLen != SQL_NO_TOTAL) lob_len = OTL_SCAST(int, retLen); aoffset += chunkLen; if (chunkLen < s.get_buf_size() || rc == SQL_SUCCESS) { s.set_len(chunkLen); eof_flag = 1; } else eof_flag = 0; return 1; } #if (ODBCVER >= 0x0300) else if (rc == SQL_NO_DATA) #else else if (rc == SQL_NO_DATA_FOUND) #endif return 1; else return 0; } OTL_NODISCARD int get_blob_len(const int /* ndx */, int &alen) { alen = lob_len; return 1; } OTL_NODISCARD int put_blob(void) { return 1; } OTL_NODISCARD int get_blob(const int /* ndx */, unsigned char * /* abuf */, const int /* buf_size */, int & /* len */) { return 1; } OTL_NODISCARD int save_blob(const unsigned char * /* abuf */, const int /* len */, const int /* extern_buffer_flag */) { return 1; } OTL_NODISCARD int actual_elem_size(void) { return act_elem_size; } void init(const bool, const int aftype, int &aelem_size, const otl_stream_buffer_size_type aarray_size, const void * /* connect_struct */ = nullptr, const int /*apl_tab_size*/ = 0) { int i; size_t byte_size = 0; ftype = aftype; act_elem_size = aelem_size; byte_size = OTL_SCAST(size_t, aelem_size) * OTL_SCAST(size_t, aarray_size); #if defined(OTL_UNICODE) if (aftype == otl_var_char || aftype == otl_var_varchar_long) { byte_size *= sizeof(OTL_CHAR); p_v = new unsigned char[byte_size]; } else p_v = new unsigned char[byte_size]; #else p_v = new unsigned char[byte_size]; #endif p_len = new OTL_SQLLEN[OTL_SCAST(size_t,aarray_size)]; memset(p_v, 0, byte_size); for (i = 0; i < aarray_size; ++i) { if (ftype == otl_var_char) p_len[i] = OTL_SCAST(OTL_SQLLEN, SQL_NTS); else if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long) p_len[i] = 0; else p_len[i] = OTL_SCAST(OTL_SQLLEN, aelem_size); } } void set_null(int ndx) { p_len[ndx] = SQL_NULL_DATA; } void set_not_null(int ndx, int pelem_size) { set_len(pelem_size, ndx); } void set_len(int len, int ndx) { switch (ftype) { case otl_var_char: p_len[ndx] = SQL_NTS; break; case otl_var_varchar_long: if (lob_stream_mode && (vparam_type == otl_input_param || vparam_type == otl_inout_param)) p_len[ndx] = SQL_DATA_AT_EXEC; else #if defined(OTL_UNICODE) p_len[ndx] = OTL_SCAST(OTL_SQLLEN, len * OTL_SCAST(int, sizeof(OTL_CHAR))); #else p_len[ndx] = OTL_SCAST(OTL_SQLLEN, len); #endif break; case otl_var_raw_long: if (lob_stream_mode && (vparam_type == otl_input_param || vparam_type == otl_inout_param)) p_len[ndx] = SQL_DATA_AT_EXEC; else p_len[ndx] = OTL_SCAST(OTL_SQLLEN, len); break; default: p_len[ndx] = OTL_SCAST(OTL_SQLLEN, len); break; } } OTL_NODISCARD int get_len(int ndx) { if (p_len[ndx] == SQL_NULL_DATA) return 0; else #if defined(OTL_UNICODE) if (ftype == otl_var_varchar_long || ftype == otl_var_char) return OTL_SCAST(int, p_len[ndx]) / OTL_SCAST(int, sizeof(OTL_CHAR)); else return OTL_SCAST(int, p_len[ndx]); #else return OTL_SCAST(int, p_len[ndx]); #endif } OTL_NODISCARD int is_null(int ndx) { return p_len[ndx] == SQL_NULL_DATA; } OTL_NODISCARD void *val(int ndx, int pelem_size) { #if defined(OTL_UNICODE) switch (ftype) { case otl_var_char: case otl_var_varchar_long: return OTL_RCAST(void *, &p_v[(OTL_SCAST(size_t, ndx)) * OTL_SCAST(size_t, pelem_size) * sizeof(OTL_CHAR)]); default: return OTL_RCAST( void *, &p_v[(OTL_SCAST(size_t, ndx)) * OTL_SCAST(size_t, pelem_size)]); } #else return OTL_RCAST( void *, &p_v[(OTL_SCAST(size_t, ndx)) * OTL_SCAST(size_t, pelem_size)]); #endif } #define OTL_SQL_UNICODE_CHAR (-95) #define OTL_SQL_UNICODE_VARCHAR (-96) #define OTL_SQL_UNICODE_LONGVARCHAR (-97) #define OTL_SQL_SS_TIME2 (-154) #define OTL_SQL_SS_TIMESTAMPOFFSET (-155) OTL_NODISCARD static int int2ext(int int_type) { switch (int_type) { #if defined(OTL_UNICODE) case SQL_VARCHAR: return SQL_C_WCHAR; case SQL_WVARCHAR: return SQL_C_WCHAR; case SQL_CHAR: return SQL_C_WCHAR; case SQL_WCHAR: return SQL_C_WCHAR; case SQL_LONGVARCHAR: return SQL_WLONGVARCHAR; case SQL_WLONGVARCHAR: return SQL_WLONGVARCHAR; case OTL_SQL_UNICODE_VARCHAR: return SQL_C_WCHAR; case OTL_SQL_UNICODE_CHAR: return SQL_C_WCHAR; case OTL_SQL_UNICODE_LONGVARCHAR: return SQL_WLONGVARCHAR; #else case SQL_CHAR: return SQL_C_CHAR; case SQL_VARCHAR: return SQL_C_CHAR; #if defined(SQL_WCHAR) case SQL_WCHAR: return SQL_C_CHAR; #else case -8: return SQL_C_CHAR; #endif #if defined(SQL_WVARCHAR) case SQL_WVARCHAR: return SQL_C_CHAR; #else case -9: return SQL_C_CHAR; #endif case SQL_LONGVARCHAR: return SQL_LONGVARCHAR; #if defined(SQL_WLONGVARCHAR) case SQL_WLONGVARCHAR: return SQL_LONGVARCHAR; #else case -10: return SQL_LONGVARCHAR; #endif case OTL_SQL_UNICODE_VARCHAR: return SQL_C_CHAR; case OTL_SQL_UNICODE_CHAR: return SQL_C_CHAR; case OTL_SQL_UNICODE_LONGVARCHAR: return SQL_LONGVARCHAR; #endif #if (ODBCVER >= 0x0300) case SQL_TYPE_DATE: return OTL_SQL_C_TIMESTAMP; case SQL_TYPE_TIMESTAMP: return OTL_SQL_C_TIMESTAMP; case SQL_TYPE_TIME: return OTL_SQL_C_TIMESTAMP; case OTL_SQL_SS_TIME2: return OTL_SQL_C_TIMESTAMP; #if defined(OTL_UNICODE) case OTL_SQL_SS_TIMESTAMPOFFSET: return SQL_C_WCHAR; #else case OTL_SQL_SS_TIMESTAMPOFFSET: return SQL_C_CHAR; #endif #else case OTL_SQL_DATE: return OTL_SQL_C_TIMESTAMP; case OTL_SQL_TIMESTAMP: return OTL_SQL_C_TIMESTAMP; case OTL_SQL_TIME: return OTL_SQL_C_TIMESTAMP; #endif #if defined(OTL_BIGINT) case SQL_BIGINT: return SQL_C_SBIGINT; #else case SQL_BIGINT: return SQL_C_DOUBLE; #endif #if defined(OTL_MAP_SQL_DECIMAL_TO_OTL_BIGINT) && !defined(OTL_BIGINT) #error OTL_BIGINT needs to be defined for OTL_MAP_SQL_DECIMAL_TO_OTL_BIGINT \ to function #elif defined(OTL_MAP_SQL_DECIMAL_TO_OTL_BIGINT) && defined(OTL_BIGINT) case SQL_DECIMAL: return SQL_C_SBIGINT; #else case SQL_DECIMAL: return SQL_C_DOUBLE; #endif case SQL_DOUBLE: return SQL_C_DOUBLE; case SQL_FLOAT: return SQL_C_DOUBLE; case SQL_INTEGER: return SQL_C_SLONG; #if defined(OTL_MAP_SQL_NUMERIC_TO_OTL_BIGINT) && !defined(OTL_BIGINT) #error OTL_BIGINT needs to be defined for OTL_MAP_SQL_NUMERIC_TO_OTL_BIGINT \ to function #elif defined(OTL_MAP_SQL_NUMERIC_TO_OTL_BIGINT) && defined(OTL_BIGINT) case SQL_NUMERIC: return SQL_C_SBIGINT; #elif defined(OTL_MAP_SQL_NUMERIC_TO_OTL_UBIGINT) && !defined(OTL_UBIGINT) #error OTL_UBIGINT needs to be defined for OTL_MAP_SQL_NUMERIC_TO_OTL_UBIGINT \ to function #elif defined(OTL_MAP_SQL_NUMERIC_TO_OTL_UBIGINT) && defined(OTL_UBIGINT) case SQL_NUMERIC: return SQL_C_UBIGINT; #else case SQL_NUMERIC: return SQL_C_DOUBLE; #endif case SQL_REAL: return SQL_C_DOUBLE; case SQL_SMALLINT: return SQL_C_SSHORT; case SQL_BIT: return SQL_C_SSHORT; case SQL_TINYINT: return SQL_C_SSHORT; case SQL_LONGVARBINARY: return SQL_LONGVARBINARY; #if defined(OTL_MAP_SQL_VARBINARY_TO_RAW_LONG) case SQL_VARBINARY: return SQL_LONGVARBINARY; #else case SQL_VARBINARY: return SQL_C_BINARY; #endif #if (ODBCVER >= 0x0350) #if defined(OTL_MAP_SQL_GUID_TO_CHAR) #if defined(OTL_UNICODE) case SQL_GUID: return SQL_C_WCHAR; #else case SQL_GUID: return SQL_C_CHAR; #endif #else case SQL_GUID: return SQL_C_BINARY; #endif #endif #if defined(OTL_MAP_SQL_BINARY_TO_CHAR) #if defined(OTL_UNICODE) case SQL_BINARY: // MS SQL TIMESTAMP, BINARY return SQL_C_WCHAR; #else case SQL_BINARY: // MS SQL TIMESTAMP, BINARY return SQL_C_CHAR; #endif #else case SQL_BINARY: return SQL_C_BINARY; #endif #if (ODBCVER >= 0x0350) case OTL_SQL_XML: #if defined(OTL_UNICODE) return SQL_C_WCHAR; #else return SQL_C_CHAR; #endif #endif default: return otl_unsupported_type; } } OTL_NODISCARD static int datatype_size(int ftype, int maxsz, int int_type, int max_long_size) { switch (ftype) { #if defined(OTL_UNICODE) case SQL_C_WCHAR: #endif case SQL_C_CHAR: switch (int_type) { case SQL_BINARY: // MS SQL TIMESTAMP return 17; #if defined(OTL_UNICODE) case SQL_WLONGVARCHAR: #endif case SQL_LONGVARCHAR: return max_long_size * OTL_SCAST(int, sizeof(OTL_CHAR)); case SQL_LONGVARBINARY: return max_long_size; case OTL_SQL_DATE: return 40; #if (ODBCVER >= 0x0300) case SQL_TYPE_TIMESTAMP: #else case OTL_SQL_TIMESTAMP: #endif return 40; #if (ODBCVER >= 0x0300) case SQL_TYPE_TIME: #else case OTL_SQL_TIME: #endif return 40; #if (ODBCVER >= 0x0350) #if defined(OTL_MAP_SQL_GUID_TO_SQL_VARBINARY) case SQL_GUID: return 16; #else case SQL_GUID: return 40; #endif #endif default: return (maxsz + 1); } #if defined(OTL_BIGINT) case SQL_C_SBIGINT: return sizeof(OTL_BIGINT); #endif #if defined(OTL_UBIGINT) case SQL_C_UBIGINT: return sizeof(OTL_UBIGINT); #endif case SQL_C_DOUBLE: return sizeof(double); case SQL_C_SLONG: return sizeof(int); case SQL_C_SSHORT: return sizeof(short int); case OTL_SQL_C_TIMESTAMP: return sizeof(OTL_SQL_TIMESTAMP_STRUCT); case OTL_SQL_C_TIME: return sizeof(OTL_SQL_TIME_STRUCT); case OTL_SQL_C_DATE: return sizeof(OTL_SQL_DATE_STRUCT); #if defined(OTL_UNICODE) case SQL_WLONGVARCHAR: return max_long_size; #endif case SQL_LONGVARCHAR: return max_long_size; case SQL_LONGVARBINARY: return max_long_size; case SQL_C_BINARY: return maxsz; default: return 0; } } static void map_ftype(otl_column_desc &desc, const int max_long_size, int &ftype, int &elem_size, otl_select_struct_override &a_override, const int column_ndx, const int #if !defined(OTL_ODBC_TIMESTEN) && defined(OTL_ODBC_MULTI_MODE) connection_type #endif ) { int ndx = a_override.find(column_ndx); if (ndx == -1) { #if defined(OTL_ODBC_MSSQL_2005) && !defined(OTL_ODBC_MULTI_MODE) if (desc.prec == 0 && desc.dbtype == SQL_VARBINARY) ftype = SQL_LONGVARBINARY; else #elif defined(OTL_ODBC_MULTI_MODE) if ((connection_type == OTL_MSSQL_2005_ODBC_CONNECT || connection_type == OTL_MSSQL_2008_ODBC_CONNECT) && desc.prec == 0 && desc.dbtype == SQL_VARBINARY) ftype = SQL_LONGVARBINARY; else #endif ftype = int2ext(desc.dbtype); if (desc.dbsize == 0) { #if !defined(OTL_UNICODE) if (ftype == SQL_C_CHAR) ftype = SQL_LONGVARCHAR; #else if (ftype == SQL_C_CHAR) ftype = SQL_LONGVARCHAR; else if (ftype == SQL_C_WCHAR) ftype = SQL_WLONGVARCHAR; #endif elem_size = max_long_size * OTL_SCAST(int, sizeof(OTL_CHAR)); } else { elem_size = datatype_size(ftype, OTL_SCAST(int, desc.dbsize), desc.dbtype, max_long_size); } switch (ftype) { #if defined(OTL_UNICODE) case SQL_C_WCHAR: ftype = otl_var_char; break; case SQL_WLONGVARCHAR: ftype = otl_var_varchar_long; break; #else case SQL_C_CHAR: ftype = otl_var_char; break; case SQL_LONGVARCHAR: ftype = otl_var_varchar_long; break; #endif case SQL_C_DOUBLE: if (a_override.get_all_mask() & otl_all_num2str) { ftype = otl_var_char; elem_size = otl_num_str_size; } else ftype = otl_var_double; break; #if defined(OTL_BIGINT) case SQL_C_SBIGINT: if (a_override.get_all_mask() & otl_all_num2str) { ftype = otl_var_char; elem_size = otl_num_str_size; } else ftype = otl_var_bigint; break; #endif #if defined(OTL_UBIGINT) case SQL_C_UBIGINT: if (a_override.get_all_mask() & otl_all_num2str) { ftype = otl_var_char; elem_size = otl_num_str_size; } else ftype = otl_var_ubigint; break; #endif case SQL_C_SLONG: if (a_override.get_all_mask() & otl_all_num2str) { ftype = otl_var_char; elem_size = otl_num_str_size; } else ftype = otl_var_int; break; case SQL_C_SSHORT: if (a_override.get_all_mask() & otl_all_num2str) { ftype = otl_var_char; elem_size = otl_num_str_size; } else ftype = otl_var_short; break; case SQL_LONGVARBINARY: ftype = otl_var_raw_long; break; case OTL_SQL_C_DATE: case OTL_SQL_C_TIME: case OTL_SQL_C_TIMESTAMP: if (a_override.get_all_mask() & otl_all_date2str) { ftype = otl_var_char; elem_size = otl_date_str_size; } else ftype = otl_var_timestamp; break; case SQL_C_BINARY: ftype = otl_var_raw; break; default: ftype = 0; break; } } else { ftype = a_override.get_col_type(ndx); switch (ftype) { case otl_var_char: elem_size = a_override.get_col_size(ndx) * OTL_SCAST(int, sizeof(OTL_CHAR)); break; case otl_var_raw: elem_size = a_override.get_col_size(ndx); break; case otl_var_double: elem_size = sizeof(double); break; case otl_var_bdouble: elem_size = sizeof(double); break; case otl_var_float: elem_size = sizeof(float); break; case otl_var_bfloat: elem_size = sizeof(float); break; case otl_var_int: elem_size = sizeof(int); break; #if defined(OTL_BIGINT) case otl_var_bigint: elem_size = sizeof(OTL_BIGINT); break; #endif #if defined(OTL_UBIGINT) case otl_var_ubigint: elem_size = sizeof(OTL_UBIGINT); break; #endif case otl_var_unsigned_int: elem_size = sizeof(unsigned); break; case otl_var_short: elem_size = sizeof(short); break; case otl_var_long_int: elem_size = sizeof(double); break; default: elem_size = a_override.get_col_size(ndx); break; } } desc.otl_var_dbtype = ftype; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_var(const otl_var &) = delete; otl_var &operator=(const otl_var &) = delete; private: #else otl_var(const otl_var &) : p_v(nullptr), p_len(nullptr), ftype(0), act_elem_size(0), lob_stream_mode(false), lob_stream_flag(0), vparam_type(-1), lob_len(0), lob_pos(0), lob_ftype(0), otl_adapter(OTL_ADAPTER_ENUM otl_odbc_adapter), charz_flag(false) {} otl_var &operator=(const otl_var &) { return *this; } #endif }; #if defined(OTL_ODBC_zOS) || defined(OTL_ODBC_TIMESTEN) || \ (defined(SQL_TXN_READ_COMMITTED) && \ !defined(SQL_TRANSACTION_READ_COMMITTED)) const long otl_tran_read_uncommitted = SQL_TXN_READ_UNCOMMITTED; const long otl_tran_read_committed = SQL_TXN_READ_COMMITTED; const long otl_tran_repeatable_read = SQL_TXN_REPEATABLE_READ; const long otl_tran_serializable = SQL_TXN_SERIALIZABLE; #else const long otl_tran_read_uncommitted = SQL_TRANSACTION_READ_UNCOMMITTED; const long otl_tran_read_committed = SQL_TRANSACTION_READ_COMMITTED; const long otl_tran_repeatable_read = SQL_TRANSACTION_REPEATABLE_READ; const long otl_tran_serializable = SQL_TRANSACTION_SERIALIZABLE; #endif class otl_sel; class otl_cur : public otl_cur0 { private: friend class otl_sel; int status; otl_conn *adb; int direct_exec_flag; long _rpc; bool canceled; int last_iters; public: void set_batch_error_mode(const bool) {} OTL_NODISCARD int get_number_of_errors_in_batch(int &arc) { arc = 1; return 0; } void get_error(const int, int &, otl_exc &) {} void set_canceled(const bool acanceled) { canceled = acanceled; } void reset_last_param_data_token() { last_param_data_token = 0; } void reset_last_sql_param_data_status() { last_sql_param_data_status = 0; } void reset_sql_param_data_count() { sql_param_data_count = 0; } otl_cur() : otl_cur0(), status(0), adb(nullptr), direct_exec_flag(0), _rpc(0), canceled(false), last_iters(0) { cda = OTL_SQL_NULL_HANDLE_VAL; last_param_data_token = 0; last_sql_param_data_status = 0; sql_param_data_count = 0; } virtual ~otl_cur() {} OTL_NODISCARD int cancel(void) { status = SQLCancel(cda); canceled = true; if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } OTL_NODISCARD int open(otl_conn & /* connect */, otl_var * /* var */) { return 1; } void set_direct_exec(const int flag) { direct_exec_flag = flag; } void set_parse_only(const int /*flag*/) {} OTL_NODISCARD int open(otl_conn &connect) { last_iters = 0; direct_exec_flag = 0; adb = &connect; #if (ODBCVER >= 0x0300) status = SQLAllocHandle(SQL_HANDLE_STMT, connect.hdbc, &cda); #else status = SQLAllocStmt(connect.hdbc, &cda); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; if (connect.timeout > 0) { #if (ODBCVER >= 0x0300) status = SQLSetStmtAttr( cda, SQL_ATTR_QUERY_TIMEOUT, OTL_RCAST(void *, OTL_SCAST(size_t, connect.timeout)), SQL_NTS); #else status = SQLSetStmtOption(cda, SQL_QUERY_TIMEOUT, OTL_SCAST(size_t,connect.timeout)); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } if (connect.cursor_type != 0) { // other than default #if (ODBCVER >= 0x0300) status = SQLSetStmtAttr( cda, SQL_ATTR_CURSOR_TYPE, OTL_RCAST(void *, OTL_SCAST(size_t, connect.cursor_type)), SQL_NTS); #else status = SQLSetStmtOption(cda, SQL_CURSOR_TYPE, OTL_SCAST(size_t,connect.cursor_type)); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } return 1; } OTL_NODISCARD int close(const char = 'N') { last_iters = 0; #if (ODBCVER >= 0x0300) status = SQLFreeHandle(SQL_HANDLE_STMT, cda); #else status = SQLFreeStmt(cda, SQL_DROP); #endif adb = nullptr; cda = OTL_SQL_NULL_HANDLE_VAL; if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } OTL_NODISCARD SQLRETURN sql_row_count(OTL_SQLLEN *total_rpc) { #if defined(OTL_ODBC_ALTERNATE_RPC) OTL_SQLLEN rpc = 0; SQLRETURN rc; do { rc = SQLRowCount(cda, &rpc); if (rc != SQL_SUCCESS) return rc; *total_rpc += rpc; rc = SQLMoreResults(cda); } while (rc == SQL_SUCCESS); return SQL_SUCCESS; #else return SQLRowCount(cda, total_rpc); #endif } void convert(char*& c, short int& in_str, const char* stm_text){ while (*c) { if (*c == '\'') { if (!in_str) in_str = 1; else { if (c[1] == '\'') ++c; else in_str = 0; } } if (*c == ':' && !in_str && ((c > stm_text && *(c - 1) != '\\') || c == stm_text)) { *c = '?'; ++c; while (isalnum(OTL_SCAST(unsigned char, *c)) || *c == '_') { *c = ' '; ++c; } } else if (*c == ':' && !in_str && ((c > stm_text && *(c - 1) == '\\') || c == stm_text)) { char *c_1 = c - 1; char *c_ = c; while (*c_) { *c_1 = *c_; ++c_1; ++c_; } if (c_1 > c - 1) *c_1 = 0; --c; } ++c; } } OTL_NODISCARD int parse(char *stm_text, const int external_direct_exec_flag) { #if !defined(OTL_ODBC_TIMESTEN) short in_str = 0; #endif bool do_not_call_sql_row_count = false; #if defined(OTL_ODBC_SQL_STATEMENT_WITH_DIAG_REC_OUTPUT) if (OTL_ODBC_SQL_STATEMENT_WITH_DIAG_REC_OUTPUT(stm_text)) { do_not_call_sql_row_count = true; direct_exec_flag = 1; } #endif char *c = stm_text; if(external_direct_exec_flag){ direct_exec_flag=1; #if !defined(OTL_ODBC_TIMESTEN) // Converting : notation into ODBC's native notation ? convert(c,in_str,stm_text); #endif } if (*c == '$') { ++c; _rpc = 0; direct_exec_flag = 1; const int ctl_arr_size = 6; struct { OTL_SQLCHAR_PTR name_ptr; OTL_SQLSMALLINT name_len; OTL_SQLCHAR name[512]; } ctl_arr[ctl_arr_size]; #if (defined(UNICODE) || defined(_UNICODE)) struct { SQLWCHAR name_ptr; OTL_SQLSMALLINT name_len; SQLWCHAR name[512]; } ctl_arr_W[ctl_arr_size]; #endif int i = 0; for (i = 0; i < ctl_arr_size; ++i) { ctl_arr[i].name_ptr = nullptr; ctl_arr[i].name_len = 0; ctl_arr[i].name[0] = 0; #if (defined(UNICODE) || defined(_UNICODE)) ctl_arr_W[i].name_ptr = 0; ctl_arr_W[i].name_len = 0; ctl_arr_W[i].name[0] = 0; #endif } char func_name[256]; int par_num = 0; char par_val[512]; size_t par_val_len = 0; size_t fn_len = 0; bool func_found = false; while (*c && *c != ' ' && fn_len < sizeof(func_name)) { ++fn_len; func_name[fn_len - 1] = *c; ++c; } if (fn_len < sizeof(func_name) - 1) { ++fn_len; func_name[fn_len - 1] = 0; } else func_name[sizeof(func_name) - 1] = 0; while (*c == ' ') ++c; while (*c) { if (*c == '$') { ++c; par_num = OTL_SCAST(int, *c - '0') - 1; ++c; while (*c && *c == ' ') ++c; if (*c == ':' && ((c > stm_text && *(c - 1) != '\\') || c == stm_text)) { ++c; while (*c && *c == ' ') ++c; if (*c == '\'') { par_val_len = 0; ++c; while (*c && *c != '\'' && par_val_len < sizeof(par_val)) { ++par_val_len; par_val[par_val_len - 1] = *c; ++c; } if (par_val_len < sizeof(par_val) - 1) { ++par_val_len; par_val[par_val_len - 1] = 0; } else par_val[sizeof(par_val) - 1] = 0; if (par_num >= 0 && par_num < ctl_arr_size) { ctl_arr[par_num].name_ptr = ctl_arr[par_num].name; ctl_arr[par_num].name_len = SQL_NTS; OTL_STRCPY_S(OTL_RCAST(char *, ctl_arr[par_num].name), sizeof(ctl_arr[par_num].name), OTL_RCAST(const char *, par_val)); } } ++c; while (*c && *c == ' ') ++c; } } else ++c; } status = SQL_SUCCESS; if (strcmp(func_name, "SQLTables") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLTables(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS, ctl_arr_W[3].name, SQL_NTS); #else status = SQLTablesA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len); #endif #else status = SQLTables(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len); #endif func_found = true; } else if (strcmp(func_name, "SQLStatistics") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLStatistics(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS, SQL_INDEX_ALL, SQL_QUICK); #else status = SQLStatisticsA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, SQL_INDEX_ALL, SQL_QUICK); #endif #else status = SQLStatistics(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, SQL_INDEX_ALL, SQL_QUICK); #endif func_found = true; } else if (strcmp(func_name, "SQLGetTypeInfo") == 0) { status = SQLGetTypeInfo(cda, SQL_ALL_TYPES); func_found = true; } else if (strcmp(func_name, "SQLColumns") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLColumns(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS, ctl_arr_W[3].name, SQL_NTS); #else status = SQLColumnsA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len); #endif #else status = SQLColumns(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len); #endif func_found = true; } else if (strcmp(func_name, "SQLProcedures") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLProcedures(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS); #else status = SQLProceduresA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len); #endif #else status = SQLProcedures(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len); #endif func_found = true; } else if (strcmp(func_name, "SQLColumnPrivileges") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLColumnPrivileges( cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS, ctl_arr_W[3].name, SQL_NTS); #else status = SQLColumnPrivilegesA( cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len); #endif #else status = SQLColumnPrivileges( cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len); #endif func_found = true; } else if (strcmp(func_name, "SQLTablePrivileges") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLTablePrivileges(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS); #else status = SQLTablePrivilegesA( cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len); #endif #else status = SQLTablePrivileges( cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len); #endif func_found = true; } else if (strcmp(func_name, "SQLPrimaryKeys") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLPrimaryKeys(cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS); #else status = SQLPrimaryKeysA(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len); #endif #else status = SQLPrimaryKeys(cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len); #endif func_found = true; } else if (strcmp(func_name, "SQLProcedureColumns") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLProcedureColumns( cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS, ctl_arr_W[3].name, SQL_NTS); #else status = SQLProcedureColumnsA( cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len); #endif #else status = SQLProcedureColumns( cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len); #endif func_found = true; } else if (strcmp(func_name, "SQLForeignKeys") == 0) { #if (defined(UNICODE) || defined(_UNICODE)) otl_convert_char_to_SQLWCHAR( ctl_arr_W[0].name, OTL_RCAST(unsigned char *, ctl_arr[0].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[1].name, OTL_RCAST(unsigned char *, ctl_arr[1].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[2].name, OTL_RCAST(unsigned char *, ctl_arr[2].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[3].name, OTL_RCAST(unsigned char *, ctl_arr[3].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[4].name, OTL_RCAST(unsigned char *, ctl_arr[4].name)); otl_convert_char_to_SQLWCHAR( ctl_arr_W[5].name, OTL_RCAST(unsigned char *, ctl_arr[5].name)); #if !defined(OTL_UNICODE_USE_ANSI_ODBC_FUNCS_FOR_DATA_DICT) status = SQLForeignKeys( cda, ctl_arr_W[0].name, SQL_NTS, ctl_arr_W[1].name, SQL_NTS, ctl_arr_W[2].name, SQL_NTS, ctl_arr_W[3].name, SQL_NTS, ctl_arr_W[4].name, SQL_NTS, ctl_arr_W[5].name, SQL_NTS); #else status = SQLForeignKeysA( cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len, ctl_arr[4].name_ptr, ctl_arr[4].name_len, ctl_arr[5].name_ptr, ctl_arr[5].name_len); #endif #else status = SQLForeignKeys( cda, ctl_arr[0].name_ptr, ctl_arr[0].name_len, ctl_arr[1].name_ptr, ctl_arr[1].name_len, ctl_arr[2].name_ptr, ctl_arr[2].name_len, ctl_arr[3].name_ptr, ctl_arr[3].name_len, ctl_arr[4].name_ptr, ctl_arr[4].name_len, ctl_arr[5].name_ptr, ctl_arr[5].name_len); #endif func_found = true; } if (!func_found) return 2; if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } if (direct_exec_flag) { _rpc = 0; #if (defined(UNICODE) || defined(_UNICODE)) { SQLWCHAR *temp_stm_text = new SQLWCHAR[strlen(stm_text) + 1]; otl_convert_char_to_SQLWCHAR(temp_stm_text, OTL_RCAST(unsigned char *, stm_text)); status = SQLExecDirect(cda, temp_stm_text, SQL_NTS); delete[] temp_stm_text; #if defined(OTL_ODBC_LEGACY_RPC) _rpc = 0; if (!do_not_call_sql_row_count) { OTL_SQLLEN tmp_rpc = 0; SQLRETURN diag_status = sql_row_count(&tmp_rpc); if (diag_status == SQL_SUCCESS || diag_status == SQL_SUCCESS_WITH_INFO) _rpc = OTL_SCAST(long, tmp_rpc); } #endif } #else status = SQLExecDirect(cda, OTL_RCAST(OTL_SQLCHAR_PTR, stm_text), SQL_NTS); #if defined(OTL_ODBC_LEGACY_RPC) _rpc = 0; if (!do_not_call_sql_row_count) { OTL_SQLLEN tmp_rpc = 0; SQLRETURN diag_status = sql_row_count(&tmp_rpc); if (diag_status == SQL_SUCCESS || diag_status == SQL_SUCCESS_WITH_INFO) _rpc = OTL_SCAST(long, tmp_rpc); } #endif #endif #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO) if (adb && adb->throws_on_sql_success_with_info && status == SQL_SUCCESS_WITH_INFO) return 0; #endif if(status == SQL_ERROR) return 0; // iterate over potentially more than one result set that the // batch executed by SQLExecDirect() may generate. #if (ODBCVER >= 0x0300) while ((status = SQLMoreResults(cda)) != SQL_NO_DATA); #else while ((status = SQLMoreResults(cda)) != SQL_NO_DATA_FOUND); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO && #if (ODBCVER >= 0x0300) status != SQL_NO_DATA #else status != SQL_NO_DATA_FOUND #endif ) return 0; else { #if !defined(OTL_ODBC_LEGACY_RPC) _rpc = 0; if (!do_not_call_sql_row_count) { OTL_SQLLEN tmp_rpc = 0; SQLRETURN diag_status = sql_row_count(&tmp_rpc); if (diag_status == SQL_SUCCESS || diag_status == SQL_SUCCESS_WITH_INFO) _rpc = OTL_SCAST(long, tmp_rpc); } #endif return 1; } } #if !defined(OTL_ODBC_TIMESTEN) // Converting : notation into ODBC's native notation ? convert(c,in_str,stm_text); #endif #if defined(OTL_DB2_CLI) OTL_SQLINTEGER temp_isolation_level = 0; status = SQLGetStmtAttr(cda, SQL_ATTR_TXN_ISOLATION, OTL_RCAST(SQLPOINTER, &temp_isolation_level), SQL_IS_POINTER, nullptr); if (OTL_SCAST(long, temp_isolation_level) == otl_tran_read_committed || OTL_SCAST(long, temp_isolation_level) == otl_tran_read_uncommitted) { status = SQLSetStmtAttr(cda, SQL_ATTR_CLOSE_BEHAVIOR, OTL_RCAST(void *, SQL_CC_RELEASE), SQL_NTS); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } #endif #if (defined(UNICODE) || defined(_UNICODE)) { SQLWCHAR *temp_stm_text = new SQLWCHAR[strlen(stm_text) + 1]; otl_convert_char_to_SQLWCHAR(temp_stm_text, OTL_RCAST(unsigned char *, stm_text)); status = SQLPrepare(cda, temp_stm_text, SQL_NTS); delete[] temp_stm_text; } #else status = SQLPrepare(cda, OTL_RCAST(OTL_SQLCHAR_PTR, stm_text), SQL_NTS); #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } OTL_NODISCARD int exec(const int iters, const int /*rowoff*/, #if defined(OTL_ODBC_ALTERNATE_RPC) const otl_sql_exec_from_enum otl_sql_exec_from_class) #else const otl_sql_exec_from_enum /*otl_sql_exec_from_class*/) #endif { #if (ODBCVER >= 0x0300) #else #if defined(OTL_ODBC_TIMESTEN_WIN) && defined(_WIN64) OTL_SQLULEN irows; #else #if defined(OTL_ODBC_UNIX) #if !defined(BUILD_LEGACY_64_BIT_MODE) && defined(SIZEOF_LONG_INT) && \ (SIZEOF_LONG_INT == 8) OTL_SQLULEN irows; #else OTL_SQLUINTEGER irows; #endif #else OTL_SQLUINTEGER irows; #endif #endif #endif if (direct_exec_flag) { return 1; } else { #if !defined(OTL_ODBC_MYSQL) && !defined(OTL_ODBC_XTG_IBASE6) #if (ODBCVER >= 0x0300) if (last_iters > 1 || iters > 1 || _rpc > 1) { last_iters = iters; size_t temp_iters = OTL_SCAST(size_t, iters); status = SQLSetStmtAttr(cda, SQL_ATTR_PARAMSET_SIZE, OTL_RCAST(void *, temp_iters), SQL_NTS); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } #else if (last_iters > 1 || iters > 1 || _rpc > 1) { last_iters = iters; status = SQLParamOptions(cda, #if defined(OTL_ODBC_UNIX) #if !defined(BUILD_LEGACY_64_BIT_MODE) && defined(SIZEOF_LONG_INT) && \ (SIZEOF_LONG_INT == 8) OTL_SCAST(OTL_SQLULEN, iters), #else OTL_SCAST(OTL_SQLUINTEGER, iters), #endif #else OTL_SCAST(OTL_SQLUINTEGER, iters), #endif &irows); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } #endif #endif _rpc = 0; last_param_data_token = 0; last_sql_param_data_status = 0; sql_param_data_count = 0; status = SQLExecute(cda); if (canceled) return 0; #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO) if (adb && adb->throws_on_sql_success_with_info && status == SQL_SUCCESS_WITH_INFO) return 0; #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO && #if (ODBCVER >= 0x0300) status != SQL_NO_DATA && #else status != SQL_NO_DATA_FOUND && #endif status != SQL_NEED_DATA) return 0; if (status == SQL_NEED_DATA) { _rpc = iters; return 1; } OTL_SQLLEN tmp_rpc = 0; SQLRETURN diag_status = 0; #if defined(OTL_ODBC_ALTERNATE_RPC) if (otl_sql_exec_from_class == otl_sql_exec_from_cursor_class) { diag_status = sql_row_count(&tmp_rpc); if (diag_status == SQL_SUCCESS || diag_status == SQL_SUCCESS_WITH_INFO) _rpc = OTL_SCAST(long, tmp_rpc); return 1; } else { _rpc = 0; return 1; } #else diag_status = sql_row_count(&tmp_rpc); if (diag_status == SQL_SUCCESS || diag_status == SQL_SUCCESS_WITH_INFO) _rpc = OTL_SCAST(long, tmp_rpc); return 1; #endif } } OTL_NODISCARD long get_rpc() OTL_NO_THROW { return _rpc; } OTL_NODISCARD int tmpl_ftype2odbc_ftype(const int ftype) { switch (ftype) { #if defined(OTL_UNICODE) case otl_var_char: return SQL_C_WCHAR; case otl_var_varchar_long: return SQL_WLONGVARCHAR; #else case otl_var_char: return SQL_C_CHAR; case otl_var_varchar_long: return SQL_LONGVARCHAR; #endif case otl_var_double: return SQL_C_DOUBLE; #if defined(OTL_BIGINT) case otl_var_bigint: return SQL_C_SBIGINT; #endif #if defined(OTL_UBIGINT) case otl_var_ubigint: return SQL_C_UBIGINT; #endif case otl_var_float: return SQL_C_FLOAT; case otl_var_int: return SQL_C_SLONG; case otl_var_long_int: #if defined(OTL_MAP_LONG_TO_SQL_C_SBIGINT) && \ ((ODBCVER >= 0x0300) || defined(OTL_ODBC_TIMESTEN)) { static bool long_is_8_bytes = sizeof(long) == 8; if (long_is_8_bytes) return SQL_C_SBIGINT; else return SQL_C_SLONG; } #else return SQL_C_SLONG; #endif case otl_var_unsigned_int: return SQL_C_ULONG; case otl_var_short: return SQL_C_SSHORT; case otl_var_timestamp: case otl_var_db2time: case otl_var_db2date: return OTL_SQL_C_TIMESTAMP; case otl_var_raw_long: return SQL_LONGVARBINARY; case otl_var_raw: return SQL_C_BINARY; default: return 0; } } OTL_NODISCARD int otl_map_ext2int(int ftype) { switch (ftype) { #if defined(OTL_UNICODE) case SQL_WLONGVARCHAR: return SQL_WLONGVARCHAR; case SQL_C_WCHAR: return SQL_WVARCHAR; #else case SQL_LONGVARCHAR: return SQL_LONGVARCHAR; case SQL_C_CHAR: return SQL_VARCHAR; #endif case SQL_LONGVARBINARY: return SQL_LONGVARBINARY; case OTL_SQL_C_DATE: return OTL_SQL_DATE; #if (ODBCVER >= 0x0300) case OTL_SQL_C_TIME: return SQL_TYPE_TIME; case OTL_SQL_C_TIMESTAMP: return SQL_TYPE_TIMESTAMP; #else case OTL_SQL_C_TIME: return OTL_SQL_TIME; case OTL_SQL_C_TIMESTAMP: return OTL_SQL_TIMESTAMP; #endif case SQL_C_DOUBLE: return SQL_DOUBLE; #if defined(OTL_BIGINT) case SQL_C_SBIGINT: return SQL_BIGINT; #endif #if defined(OTL_UBIGINT) case SQL_C_UBIGINT: return SQL_BIGINT; #endif #if defined(OTL_MAPS_SQL_C_FLOAT_TO_SQL_REAL) case SQL_C_FLOAT: return SQL_REAL; #else case SQL_C_FLOAT: return SQL_FLOAT; #endif case SQL_C_SLONG: return SQL_INTEGER; case SQL_C_SSHORT: return SQL_SMALLINT; case SQL_C_ULONG: return SQL_DOUBLE; case SQL_C_BINARY: return SQL_VARBINARY; default: return -1; } } OTL_NODISCARD int bind(const char * /* name */, otl_var &v, const int aelem_size, const int aftype, const int aparam_type, const int name_pos, const int #if !defined(OTL_ODBC_TIMESTEN) && defined(OTL_ODBC_MULTI_MODE) connection_type #endif , const int /* apl_tab_size */) { OTL_SQLSMALLINT ftype = OTL_SCAST(OTL_SQLSMALLINT, tmpl_ftype2odbc_ftype(aftype)); OTL_SQLSMALLINT ftype_save = ftype; int param_type; int parm_pos = name_pos; v.vparam_type = aparam_type; switch (aparam_type) { case otl_input_param: param_type = SQL_PARAM_INPUT; break; case otl_output_param: param_type = SQL_PARAM_OUTPUT; break; case otl_inout_param: param_type = SQL_PARAM_INPUT_OUTPUT; break; default: param_type = SQL_PARAM_INPUT; break; } #if defined(OTL_UNICODE) if (ftype == SQL_WLONGVARCHAR) { ftype = SQL_C_WCHAR; #else if (ftype == SQL_LONGVARCHAR) { ftype = SQL_C_CHAR; #endif } else if (ftype == SQL_LONGVARBINARY) { ftype = SQL_C_BINARY; } int sqltype = otl_map_ext2int(ftype_save); int mapped_sqltype = sqltype; if (aftype == otl_var_db2date) #if (ODBCVER >= 0x0300) mapped_sqltype = SQL_TYPE_DATE; #else mapped_sqltype = OTL_SQL_DATE; #endif else if (aftype == otl_var_db2time) #if (ODBCVER >= 0x0300) mapped_sqltype = SQL_TYPE_TIME; #else mapped_sqltype = SQL_TIME; #endif if (v.lob_stream_mode && (ftype_save == SQL_LONGVARBINARY || #if defined(OTL_UNICODE) ftype_save == SQL_WLONGVARCHAR)) { #else ftype_save == SQL_LONGVARCHAR)) { #endif // in case of "stream mode" the variable // gets bound in a special way #if defined(OTL_ODBC_MSSQL_2005) && !defined(OTL_ODBC_MULTI_MODE) switch (ftype_save) { case SQL_LONGVARBINARY: mapped_sqltype = SQL_VARBINARY; break; #if defined(OTL_UNICODE) case SQL_WLONGVARCHAR: mapped_sqltype = SQL_WVARCHAR; break; #else case SQL_LONGVARCHAR: mapped_sqltype = SQL_VARCHAR; break; #endif } #elif defined(OTL_ODBC_MULTI_MODE) if (connection_type == OTL_MSSQL_2005_ODBC_CONNECT || connection_type == OTL_MSSQL_2008_ODBC_CONNECT) { switch (ftype_save) { case SQL_LONGVARBINARY: mapped_sqltype = SQL_VARBINARY; break; #if defined(OTL_UNICODE) case SQL_WLONGVARCHAR: mapped_sqltype = SQL_WVARCHAR; break; #else case SQL_LONGVARCHAR: mapped_sqltype = SQL_VARCHAR; break; #endif } } #endif int temp_int_val = #if (ODBCVER >= 0x0300) sqltype == SQL_TYPE_TIMESTAMP ? #if defined(OTL_ODBC_MULTI_MODE) ((connection_type == OTL_MSSQL_2008_ODBC_CONNECT) ? 7 : (connection_type == OTL_MSSQL_2005_ODBC_CONNECT) ? 3 : otl_odbc_date_scale) : 0; #else otl_odbc_date_scale : 0; #endif #else sqltype == OTL_SQL_TIMESTAMP ? otl_odbc_date_scale : 0; #endif short int temp_val = OTL_SCAST(OTL_SQLSMALLINT, temp_int_val); status = SQLBindParameter( cda, OTL_SCAST(OTL_SQLUSMALLINT, parm_pos), OTL_SCAST(OTL_SQLSMALLINT, param_type), ftype, OTL_SCAST(OTL_SQLSMALLINT, mapped_sqltype), #if (ODBCVER >= 0x0300) #if defined(OTL_ODBC_MSSQL_2005) && !defined(OTL_ODBC_MULTI_MODE) 0, #elif defined(OTL_ODBC_MULTI_MODE) (connection_type == OTL_MSSQL_2005_ODBC_CONNECT || connection_type == OTL_MSSQL_2008_ODBC_CONNECT) ? 0 : (sqltype == SQL_TYPE_TIMESTAMP ? otl_odbc_date_prec : OTL_SCAST(size_t,aelem_size)), #else sqltype == SQL_TYPE_TIMESTAMP ? otl_odbc_date_prec : OTL_SCAST(OTL_SQLULEN, OTL_SCAST(size_t,aelem_size)), #endif #else sqltype == OTL_SQL_TIMESTAMP ? otl_odbc_date_prec : OTL_SCAST(size_t,aelem_size), #endif temp_val, OTL_RCAST(OTL_SQLPOINTER, OTL_SCAST(size_t, parm_pos)), 0, v.p_len); } else { int temp_column_size = 0; #if (ODBCVER >= 0x0300) if (sqltype == SQL_TYPE_TIMESTAMP) temp_column_size = otl_odbc_date_prec; #if defined(OTL_UNICODE) else if (ftype == SQL_C_WCHAR) temp_column_size = (aelem_size - 1); #else else if (ftype == SQL_C_CHAR) temp_column_size = aelem_size - 1; #endif else temp_column_size = aelem_size; #else if (sqltype == OTL_SQL_TIMESTAMP) temp_column_size = otl_odbc_date_prec; else if (ftype == SQL_C_CHAR) temp_column_size = aelem_size - 1; else temp_column_size = aelem_size; #endif OTL_SQLINTEGER buflen = 0; #if defined(OTL_UNICODE) if (ftype == SQL_C_WCHAR) buflen = aelem_size * OTL_SCAST(int, sizeof(OTL_CHAR)); else #endif buflen = aelem_size; int temp_int_val2 = #if (ODBCVER >= 0x0300) sqltype == SQL_TYPE_TIMESTAMP ? #if defined(OTL_ODBC_MULTI_MODE) ((connection_type == OTL_MSSQL_2008_ODBC_CONNECT) ? 7 : (connection_type == OTL_MSSQL_2005_ODBC_CONNECT) ? 3 : otl_odbc_date_scale) : 0; #else otl_odbc_date_scale : 0; #endif #else sqltype == OTL_SQL_TIMESTAMP ? otl_odbc_date_scale : 0; #endif short int temp_val2 = OTL_SCAST(OTL_SQLSMALLINT, temp_int_val2); status = SQLBindParameter(cda, OTL_SCAST(OTL_SQLUSMALLINT, parm_pos), OTL_SCAST(OTL_SQLSMALLINT, param_type), ftype, OTL_SCAST(OTL_SQLSMALLINT, mapped_sqltype), OTL_SCAST(OTL_SQLULEN, temp_column_size), temp_val2, OTL_RCAST(OTL_SQLPOINTER, v.p_v), buflen, v.p_len); } if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } OTL_NODISCARD int bind(const int column_num, otl_var &v, const int elem_size, const int aftype, const int param_type) { SWORD ftype = OTL_SCAST(SWORD, tmpl_ftype2odbc_ftype(aftype)); v.vparam_type = param_type; SWORD ftype_save = ftype; #if defined(OTL_UNICODE) if (ftype == SQL_WLONGVARCHAR) { ftype = SQL_C_WCHAR; #else if (ftype == SQL_LONGVARCHAR) { ftype = SQL_C_CHAR; #endif } else if (ftype == SQL_LONGVARBINARY) { ftype = SQL_C_BINARY; } if (v.lob_stream_mode && (ftype_save == SQL_LONGVARBINARY || #if defined(OTL_UNICODE) ftype_save == SQL_WLONGVARCHAR)) { #else ftype_save == SQL_LONGVARCHAR)) { #endif // in case of "stream mode" the variable // remains unbound v.lob_ftype = ftype; v.lob_pos = column_num; return 1; } else { SQLINTEGER buflen = elem_size; #if defined(OTL_UNICODE) if (ftype == SQL_C_WCHAR || ftype == SQL_WLONGVARCHAR) buflen = elem_size * OTL_SCAST(SQLINTEGER, sizeof(OTL_CHAR)); #endif status = SQLBindCol(cda, OTL_SCAST(unsigned short, column_num), ftype, OTL_RCAST(PTR, v.p_v), buflen, &v.p_len[0]); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; else return 1; } } OTL_NODISCARD int describe_column(otl_column_desc &col, const int column_num, int &eof_desc) { OTL_SQLCHAR name[256]; OTL_SQLSMALLINT nlen; OTL_SQLSMALLINT dbtype; OTL_SQLLEN dbsize; OTL_SQLSMALLINT scale; OTL_SQLULEN prec; OTL_SQLSMALLINT nullok; OTL_SQLSMALLINT icols; eof_desc = 0; status = SQLNumResultCols(cda, &icols); if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; if (column_num > icols) { eof_desc = 1; return 0; } #if (defined(UNICODE) || defined(_UNICODE)) { SQLWCHAR temp_name[256]; status = SQLDescribeCol( cda, OTL_SCAST(unsigned short, column_num), temp_name, OTL_SCAST(OTL_SQLSMALLINT, sizeof(temp_name) / sizeof(SQLWCHAR)), &nlen, &dbtype, &prec, &scale, &nullok); otl_convert_SQLWCHAR_to_char(OTL_RCAST(unsigned char *, name), temp_name); } #else status = SQLDescribeCol(cda, OTL_SCAST(unsigned short, column_num), name, OTL_SCAST(SQLSMALLINT, sizeof(name)), &nlen, &dbtype, &prec, &scale, &nullok); #endif if (!(status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO)) return 0; dbsize = OTL_SCAST(OTL_SQLLEN, prec); col.set_name(OTL_RCAST(char *, name)); #if defined(OTL_DB2_CLI) && defined(OTL_DB2_CLI_MAP_LONG_VARCHAR_TO_VARCHAR) #if defined(OTL_UNICODE) #error OTL_DB2_CLI_MAP_LONG_VARCHAR_TO_VARCHAR is not supported when \ OTL_UNICODE is defined #else if (dbtype == SQL_LONGVARCHAR && dbsize <= OTL_DB2_CLI_MAP_LONG_VARCHAR_TO_VARCHAR) { dbtype = SQL_VARCHAR; } #endif #endif col.dbtype = dbtype; col.dbsize = OTL_SCAST(int, dbsize); col.scale = scale; col.prec = OTL_SCAST(int, prec); col.nullok = nullok; return 1; } void error(otl_exc &exception_struct) { OTL_SQLRETURN rc; OTL_SQLSMALLINT msg_len = 0; #if (ODBCVER >= 0x0300) #if (defined(UNICODE) || defined(_UNICODE)) { #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) #if defined(__GNUC__)&&defined(__GNUC_MINOR__)&&(__GNUC__ * 100 + __GNUC_MINOR__ >= 407) void* temp_ptr = &exception_struct.code; rc = SQLGetDiagRec(SQL_HANDLE_STMT, cda, 1, &exception_struct.sqlstate[0], OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr), &exception_struct.msg[0], SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #else rc = SQLGetDiagRec(SQL_HANDLE_STMT, cda, 1, &exception_struct.sqlstate[0], OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code), &exception_struct.msg[0], SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #endif exception_struct.msg[msg_len] = 0; #else SQLWCHAR temp_sqlstate[1000]; SQLWCHAR temp_msg[SQL_MAX_MESSAGE_LENGTH]; rc = SQLGetDiagRec(SQL_HANDLE_STMT, cda, 1, temp_sqlstate, OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code), temp_msg, SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); temp_msg[msg_len] = 0; otl_convert_SQLWCHAR_to_char_2( OTL_RCAST(unsigned char *, &exception_struct.sqlstate[0]), temp_sqlstate); otl_convert_SQLWCHAR_to_char_2( OTL_RCAST(unsigned char *, &exception_struct.msg[0]), temp_msg); #endif } #else void *temp_ptr = &exception_struct.code; rc = SQLGetDiagRec( SQL_HANDLE_STMT, cda, 1, OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]), OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr), OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]), SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #endif #else #if defined(__GNUC__)&&defined(__GNUC_MINOR__)&&(__GNUC__ * 100 + __GNUC_MINOR__ >= 407) void* temp_ptr = &exception_struct.code; rc = SQLError(adb->henv, adb->hdbc, cda, OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]), OTL_RCAST(OTL_SQLINTEGER_PTR, temp_ptr), OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]), SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #else rc = SQLError(adb->henv, adb->hdbc, cda, OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.sqlstate[0]), OTL_RCAST(OTL_SQLINTEGER_PTR, &exception_struct.code), OTL_RCAST(OTL_SQLCHAR_PTR, &exception_struct.msg[0]), SQL_MAX_MESSAGE_LENGTH - 1, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); #endif #endif exception_struct.msg[msg_len] = 0; if (rc == SQL_INVALID_HANDLE || rc == SQL_ERROR) exception_struct.msg[0] = 0; #if (ODBCVER >= 0x0300) #if defined(OTL_EXTENDED_EXCEPTION) else if (rc != SQL_NO_DATA) otl_fill_exception(exception_struct, cda, SQL_HANDLE_STMT); #endif #endif } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_cur(const otl_cur &) = delete; otl_cur &operator=(const otl_cur &) = delete; private: #else otl_cur(const otl_cur &) : otl_cur0(), status(0), adb(nullptr), direct_exec_flag(0), _rpc(0), canceled(false), last_iters(0) {} otl_cur &operator=(const otl_cur &) { return *this; } #endif }; class otl_sel { public: #if defined(OTL_ODBC_USES_SQL_FETCH_SCROLL_WHEN_SPECIFIED_IN_OTL_CONNECT) void set_fetch_scroll_flag() { use_fetch_scroll_ = true; } #endif private: #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) bool use_fetch_scroll_; #endif int implicit_cursor; int status; int prefetch_array_size; #if defined(OTL_ODBC_UNIX) #if defined(SIZEOF_LONG) #if (SIZEOF_LONG == 8) #if !defined(BUILD_REAL_64_BIT_MODE) OTL_SQLULEN crow; #else OTL_SQLUINTEGER crow; #endif #else // (SIZEOF_LONG==8) OTL_SQLULEN crow; #endif #else // defined(SIZEOF_LONG) OTL_SQLULEN crow; #endif #else // defined(OTL_ODBC_UNIX) OTL_SQLULEN crow; #endif int in_sequence; #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300) OTL_SQLUSMALLINT *row_status; int row_status_arr_size; #endif public: OTL_NODISCARD int get_implicit_cursor() const { return implicit_cursor; } void set_arr_size(const int input_arr_size, int &out_array_size, int &out_prefetch_array_size) { #if defined(OTL_ODBC_TIMESTEN) out_array_size = 1; out_prefetch_array_size = input_arr_size; #else out_array_size = input_arr_size; out_prefetch_array_size = 0; #endif } OTL_NODISCARD int close_select(otl_cur &cur) { if (!in_sequence) return 1; #if defined(OTL_DB2_CLI) status = SQLCloseCursor(cur.cda); #else status = SQLFreeStmt(cur.cda, SQL_CLOSE); #endif in_sequence = 0; if (status == SQL_ERROR) return 0; else return 1; } otl_sel() : #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) use_fetch_scroll_(false), #endif implicit_cursor(0), status(0), prefetch_array_size(0), crow(0), in_sequence(0) #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300) , row_status(nullptr), row_status_arr_size(0) #endif { } virtual ~otl_sel() { #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300) if (row_status != 0) { delete[] row_status; row_status = nullptr; row_status_arr_size = 0; } #endif } #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300) void alloc_row_status(const int array_size) { if (row_status == nullptr) { row_status = new OTL_SQLUSMALLINT[OTL_SCAST(size_t,array_size)]; row_status_arr_size = array_size; memset(row_status, 0, sizeof(OTL_SQLUSMALLINT) * OTL_SCAST(size_t,array_size)); } else if (row_status != nullptr && array_size != row_status_arr_size) { delete[] row_status; row_status = new OTL_SQLUSMALLINT[OTL_SCAST(size_t,array_size)]; row_status_arr_size = array_size; memset(row_status, 0, sizeof(OTL_SQLUSMALLINT) * OTL_SCAST(size_t,array_size)); } } #endif void set_select_type(const int atype) { implicit_cursor = atype; } void init(const int /* array_size */) {} void set_prefetch_size(const int aprefetch_array_size) { prefetch_array_size = aprefetch_array_size; } OTL_NODISCARD int first(otl_cur &cur, int &cur_row, int &cur_size, int &row_count, int &eof_data, const int #if !defined(OTL_ODBC_XTG_IBASE6) array_size #endif ) { #if defined(OTL_ODBC_XTG_IBASE6) cur_row = -1; eof_data = 0; if (implicit_cursor == otl_explicit_select) { status = SQLExecute(cur.cda); if (cur.canceled) return 0; #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO) if (cur.adb && cur.adb->throws_on_sql_success_with_info && status == SQL_SUCCESS_WITH_INFO) return 0; #endif #if (ODBCVER >= 0x0300) && defined(OTL_DB2_CLI) if (status == SQL_NO_DATA) { status = SQL_SUCCESS; cur.status = SQL_SUCCESS; } #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } crow = 0; status = SQLFetch(cur.cda); if (cur.canceled) return 0; if (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO) { crow = 1; in_sequence = 1; } #else #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) alloc_row_status(array_size); #endif cur_row = -1; eof_data = 0; #if (ODBCVER >= 0x0300) status = SQLSetStmtAttr(cur.cda, SQL_ATTR_ROW_ARRAY_SIZE, OTL_RCAST(void *, OTL_SCAST(size_t, array_size)), SQL_NTS); #else #if defined(OTL_ODBC_TIMESTEN) status = SQLSetStmtOption(cur.cda, TT_PREFETCH_COUNT, prefetch_array_size); #else status = SQLSetStmtOption(cur.cda, SQL_ROWSET_SIZE, OTL_SCAST(size_t,array_size)); #endif #endif if (cur.canceled) return 0; if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) #if (ODBCVER >= 0x0300) if (use_fetch_scroll_) { status = SQLSetStmtAttr(cur.cda, SQL_ATTR_ROWS_FETCHED_PTR, &crow, SQL_NTS); if (cur.canceled) return 0; if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } #endif #else #if (ODBCVER >= 0x0300) status = SQLSetStmtAttr(cur.cda, SQL_ATTR_ROWS_FETCHED_PTR, &crow, SQL_NTS); if (cur.canceled) return 0; if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; #else #endif #endif if (implicit_cursor == otl_explicit_select) { status = SQLExecute(cur.cda); if (cur.canceled) return 0; #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO) if (cur.adb && cur.adb->throws_on_sql_success_with_info && status == SQL_SUCCESS_WITH_INFO) return 0; #endif #if (ODBCVER >= 0x0300) && defined(OTL_DB2_CLI) if (status == SQL_NO_DATA) { status = SQL_SUCCESS; cur.status = SQL_SUCCESS; } #endif if (status != SQL_SUCCESS && status != SQL_SUCCESS_WITH_INFO) return 0; } #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) if (array_size == 1) { crow = 0; status = SQLFetch(cur.cda); if (cur.canceled) return 0; if (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO) { crow = 1; in_sequence = 1; } } else { if (use_fetch_scroll_) { #if (ODBCVER >= 0x0300) status = SQLFetchScroll(cur.cda, SQL_FETCH_NEXT, 1); #endif } else { status = SQLExtendedFetch(cur.cda, SQL_FETCH_NEXT, 1, &crow, row_status); } } #else #if (ODBCVER >= 0x0300) status = SQLFetchScroll(cur.cda, SQL_FETCH_NEXT, 1); #else { alloc_row_status(array_size); status = SQLExtendedFetch(cur.cda, SQL_FETCH_NEXT, 1, &crow, row_status); } #endif #endif #endif in_sequence = 1; if (cur.canceled) return 0; if (status == SQL_ERROR || status == SQL_INVALID_HANDLE) return 0; if (status == SQL_NO_DATA_FOUND) { eof_data = 1; cur_row = -1; crow = 0; row_count = 0; cur_size = 0; #if defined(OTL_DB2_CLI) status = SQLCloseCursor(cur.cda); #else status = SQLFreeStmt(cur.cda, SQL_CLOSE); #endif in_sequence = 0; if (status == SQL_ERROR) return 0; return 1; } row_count = OTL_SCAST(int, crow); cur_size = row_count; if (cur_size != 0) cur_row = 0; return 1; } #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) int next(otl_cur &cur, int &cur_row, int &cur_size, int &row_count, int &eof_data, const int array_size) { alloc_row_status(array_size); #else OTL_NODISCARD int next(otl_cur &cur, int &cur_row, int &cur_size, int &row_count, int &eof_data, #if (ODBCVER >= 0x0300) const int /* array_size */) #else const int array_size) #endif { #endif if (cur_row < cur_size - 1) { ++cur_row; return 1; } else { if (eof_data) { cur_row = -1; cur_size = 0; in_sequence = 0; #if defined(OTL_DB2_CLI) status = SQLCloseCursor(cur.cda); #else status = SQLFreeStmt(cur.cda, SQL_CLOSE); #endif if (status == SQL_ERROR) return 0; return 1; } #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) if (array_size == 1) { crow = 0; status = SQLFetch(cur.cda); if (cur.canceled) return 0; if (status == SQL_SUCCESS || status == SQL_SUCCESS_WITH_INFO) { crow = 1; in_sequence = 1; } } else { if (use_fetch_scroll_) { #if (ODBCVER >= 0x0300) status = SQLFetchScroll(cur.cda, SQL_FETCH_NEXT, 1); #endif } else { status = SQLExtendedFetch(cur.cda, SQL_FETCH_NEXT, 1, &crow, row_status); } } #else #if (ODBCVER >= 0x0300) status = SQLFetchScroll(cur.cda, SQL_FETCH_NEXT, 1); #else { alloc_row_status(array_size); status = SQLExtendedFetch(cur.cda, SQL_FETCH_NEXT, 1, &crow, row_status); } #endif #endif in_sequence = 1; if (cur.canceled) return 0; if (status == SQL_ERROR || // status==SQL_SUCCESS_WITH_INFO|| status == SQL_INVALID_HANDLE) return 0; if (status == SQL_NO_DATA_FOUND) { eof_data = 1; cur_row = -1; cur_size = 0; in_sequence = 0; #if defined(OTL_DB2_CLI) status = SQLCloseCursor(cur.cda); #else status = SQLFreeStmt(cur.cda, SQL_CLOSE); #endif if (status == SQL_ERROR) return 0; return 1; } cur_size = OTL_SCAST(int, crow); row_count += OTL_SCAST(int, crow); if (cur_size != 0) cur_row = 0; return 1; } } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_sel(const otl_sel &) = delete; otl_sel &operator=(const otl_sel &) = delete; private: #else otl_sel(const otl_sel &) : #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) use_fetch_scroll_(false), #endif implicit_cursor(0), status(0), prefetch_array_size(0), crow(0), in_sequence(0) #if defined(OTL_ODBC_SQL_EXTENDED_FETCH_ON) || (ODBCVER < 0x0300) , row_status(nullptr), row_status_arr_size(0) #endif { } otl_sel &operator=(const otl_sel &) { return *this; } #endif }; typedef otl_tmpl_connect otl_odbc_connect; typedef otl_tmpl_cursor otl_cursor; typedef otl_tmpl_exception otl_exception; typedef otl_tmpl_select_stream otl_select_stream; typedef otl_tmpl_inout_stream otl_inout_stream; class otl_stream; class otl_connect : public otl_odbc_connect { public: void set_connection_mode(const int connection_mode) { connect_struct.connection_type = connection_mode; } #if defined(OTL_DB2_CLI) void set_prog_name(const char *prog_name) { retcode = connect_struct.set_prog_name(prog_name); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } #endif int get_connection_mode(void) { return connect_struct.connection_type; } protected: friend class otl_stream; #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) otl_stream_pool sc; bool pool_enabled_; #endif public: #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) void set_stream_pool_size(const int max_size = otl_max_default_pool_size) { sc.init(max_size); } void stream_pool_enable() { pool_enabled_ = true; } void stream_pool_disable() { pool_enabled_ = false; } bool get_stream_pool_enabled_flag() const { return pool_enabled_; } #endif void commit(void) { #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (!auto_commit_) { (*this) << "commit tran"; otl_odbc_connect::commit(); (*this) << "begin tran"; } #else otl_odbc_connect::commit(); #endif } void rollback(void) { #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (!auto_commit_) { (*this) << "rollback tran"; otl_odbc_connect::rollback(); (*this) << "begin tran"; } #else otl_odbc_connect::rollback(); #endif } long direct_exec(const char *sqlstm, const int exception_enabled = 1) OTL_THROWS_OTL_EXCEPTION { return otl_cursor::direct_exec(*this, sqlstm, exception_enabled); } void syntax_check(const char *sqlstm) OTL_THROWS_OTL_EXCEPTION { otl_cursor::syntax_check(*this, sqlstm); } otl_connect() OTL_NO_THROW : otl_odbc_connect(), #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) sc(), pool_enabled_(true), #endif cmd_(nullptr) #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) , auto_commit_(false) #endif { } otl_connect(const char *connect_str, const int aauto_commit = 0) OTL_THROWS_OTL_EXCEPTION: otl_odbc_connect(connect_str, aauto_commit), #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) sc(), pool_enabled_(true), #endif cmd_(nullptr) #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) , auto_commit_(false) #endif { #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (aauto_commit) auto_commit_ = true; else auto_commit_ = false; #endif } otl_connect(OTL_HENV ahenv, OTL_HDBC ahdbc, const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION: otl_odbc_connect(), #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) sc(), pool_enabled_(true), #endif cmd_(nullptr) #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) , auto_commit_(false) #endif { #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (auto_commit) auto_commit_ = true; else auto_commit_ = false; #endif rlogon(ahenv, ahdbc, auto_commit); } OTL_NODISCARD const char *getCmd(void) const { return cmd_; } otl_connect &operator<<(const char *cmd) { if (!connected) { this->rlogon(cmd); } else { otl_cursor::direct_exec(*this, cmd); } return *this; } otl_connect &operator<<=(const char *cmd) { if (cmd_) { delete[] cmd_; cmd_ = nullptr; } size_t cmd_len = strlen(cmd); cmd_ = new char[cmd_len + 1]; OTL_STRCPY_S(cmd_, cmd_len + 1, cmd); return *this; } #if defined(OTL_THROWS_ON_SQL_SUCCESS_WITH_INFO) void set_throw_on_sql_success_with_info(const bool throw_flag = false) { this->get_connect_struct().throws_on_sql_success_with_info = throw_flag; } #endif void rlogon(OTL_HENV ahenv, OTL_HDBC ahdbc, const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION { if (this->connected) { OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30))); } if (cmd_) { delete[] cmd_; cmd_ = nullptr; } #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (auto_commit) auto_commit_ = true; else auto_commit_ = false; #endif retcode = connect_struct.ext_logon(ahenv, ahdbc, auto_commit); if (retcode) connected = 1; else { connected = 0; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (!auto_commit_) { (*this) << "begin tran"; } #endif } #if defined(OTL_UNICODE_EXCEPTION_AND_RLOGON) void rlogon(const OTL_UNICODE_CHAR_TYPE *username, const OTL_UNICODE_CHAR_TYPE *passwd, const OTL_UNICODE_CHAR_TYPE *dns, const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION { if (this->connected) { OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30))); } #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (auto_commit) auto_commit_ = true; else auto_commit_ = false; #endif retcode = connect_struct.rlogon(OTL_RCAST(const SQLWCHAR *, username), OTL_RCAST(const SQLWCHAR *, passwd), OTL_RCAST(const SQLWCHAR *, dns), auto_commit); if (retcode) connected = 1; else { connected = 0; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (!auto_commit_) { (*this) << "begin tran"; } #endif } #endif void rlogon(const char *username, const char *passwd, const char *dns, const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION { if (this->connected) { OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30))); } #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (auto_commit) auto_commit_ = true; else auto_commit_ = false; #endif retcode = connect_struct.rlogon(username, passwd, dns, auto_commit); if (retcode) connected = 1; else { connected = 0; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (!auto_commit_) { (*this) << "begin tran"; } #endif } virtual ~otl_connect() #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW) OTL_THROWS_OTL_EXCEPTION #else OTL_NO_THROW #endif { if (cmd_) { delete[] cmd_; cmd_ = nullptr; } #if defined(OTL_DESTRUCTORS_DO_NOT_THROW) try { #endif logoff(); #if defined(OTL_DESTRUCTORS_DO_NOT_THROW) } catch (OTL_CONST_EXCEPTION otl_exception &) { } #endif } void rlogon(const char *connect_str, const int aauto_commit = 0) OTL_THROWS_OTL_EXCEPTION { if (this->connected) { OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30))); } if (cmd_) { delete[] cmd_; cmd_ = nullptr; } #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (aauto_commit) auto_commit_ = true; else auto_commit_ = false; #endif otl_odbc_connect::rlogon(connect_str, aauto_commit); #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (!auto_commit_) { (*this) << "begin tran"; } #endif } void logoff(void) OTL_THROWS_OTL_EXCEPTION { #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if (connected) sc.init(sc.get_max_size()); #endif #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) if (!auto_commit_ && connected) rollback(); #endif #if defined(OTL_ROLLS_BACK_BEFORE_LOGOFF) otl_odbc_connect::rollback(); #endif otl_odbc_connect::logoff(); } void set_transaction_isolation_level(const long int level) OTL_THROWS_OTL_EXCEPTION { retcode = connect_struct.set_transaction_isolation_level(level); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } private: char *cmd_; #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) bool auto_commit_; #endif #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_connect(const otl_connect &) = delete; otl_connect &operator=(const otl_connect &) = delete; private: #else otl_connect(const otl_connect &) OTL_NO_THROW : otl_odbc_connect(), #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) sc(), pool_enabled_(true), #endif cmd_(nullptr) #if defined(OTL_FREETDS_ODBC_WORKAROUNDS) , auto_commit_(false) #endif { } otl_connect &operator=(const otl_connect &) { return *this; } #endif }; const int otl_odbc_no_stream = 0; const int otl_odbc_io_stream = 1; const int otl_odbc_select_stream = 2; class otl_stream_shell : public otl_stream_shell_generic { public: otl_select_stream *ss; otl_inout_stream *io; otl_connect *adb; int auto_commit_flag; otl_var_desc *iov; int iov_len; int next_iov_ndx; otl_var_desc *ov; int ov_len; int next_ov_ndx; bool flush_flag; int stream_type; bool lob_stream_flag; otl_select_struct_override override_; #if (defined(OTL_STL) || defined(OTL_ACE)) && defined(OTL_STREAM_POOLING_ON) OTL_STRING_CONTAINER orig_sql_stm; #endif #if defined(OTL_UNICODE_STRING_TYPE) && defined(OTL_STREAM_POOLING_ON) std::string orig_sql_stm; #endif otl_stream_shell() : otl_stream_shell_generic(), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(0), iov(nullptr), iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(false), stream_type(otl_odbc_no_stream), lob_stream_flag(0), override_() #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) , orig_sql_stm() #endif { should_delete = 0; } otl_stream_shell(const int ashould_delete) : otl_stream_shell_generic(), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(0), iov(nullptr), iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(true), stream_type(otl_odbc_no_stream), lob_stream_flag(false), override_() #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) , orig_sql_stm() #endif { should_delete = ashould_delete; } virtual ~otl_stream_shell() OTL_THROWS_OTL_EXCEPTION { if (should_delete) { delete[] iov; delete[] ov; iov = nullptr; iov_len = 0; ov = nullptr; ov_len = 0; next_iov_ndx = 0; next_ov_ndx = 0; override_.setLen(0); flush_flag = true; delete ss; delete io; ss = nullptr; io = nullptr; adb = nullptr; } } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_stream_shell(const otl_stream_shell &) = delete; otl_stream_shell &operator=(const otl_stream_shell &) = delete; private: #else otl_stream_shell(const otl_stream_shell &) : otl_stream_shell_generic(), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(0), iov(nullptr), iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(false), stream_type(otl_odbc_no_stream), lob_stream_flag(0), override_() #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) , orig_sql_stm() #endif { should_delete = 0; } otl_stream_shell &operator=(const otl_stream_shell &) { return *this; } #endif }; template class otl_tmpl_lob_stream : public otl_lob_stream_generic { public: typedef otl_tmpl_exception otl_exception; typedef otl_tmpl_variable *p_bind_var; typedef otl_tmpl_connect * p_connect; typedef otl_tmpl_cursor *p_cursor; private: p_bind_var bind_var; p_connect connect; p_cursor cursor; otl_long_string *temp_buf; char *temp_char_buf; bool written_to_flag; bool closed_flag; int last_read_lob_len; public: void reset_last_read_lob_len() { last_read_lob_len = 0; } void init(void *avar, void *aconnect, void *acursor, int andx, int amode, const int alob_is_null = 0) OTL_THROWS_OTL_EXCEPTION { closed_flag = false; if (written_to_flag) { retcode = bind_var->get_var_struct().clob_blob(cursor->get_cursor_struct()); written_to_flag = false; if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); } } connect = OTL_RCAST(p_connect, aconnect); bind_var = OTL_RCAST(p_bind_var, avar); cursor = OTL_RCAST(p_cursor, acursor); mode = amode; retcode = 0; lob_is_null = alob_is_null; ndx = andx; offset = 0; lob_len = 0; eof_flag = 0; in_destructor = 0; if (bind_var) { bind_var->get_var_struct().set_lob_stream_flag(); bind_var->get_var_struct().reset_lob_len(); } } void set_len(void) OTL_NO_THROW {} void set_len(const int /*new_len*/) OTL_NO_THROW {} otl_tmpl_lob_stream() OTL_THROWS_OTL_EXCEPTION : otl_lob_stream_generic(false), bind_var(nullptr), connect(nullptr), cursor(nullptr), temp_buf(nullptr), temp_char_buf(nullptr), written_to_flag(false), closed_flag(false), last_read_lob_len(0) { otl_tmpl_lob_stream::init(nullptr, nullptr, nullptr, 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode)); } ~otl_tmpl_lob_stream() #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW) OTL_THROWS_OTL_EXCEPTION #else OTL_NO_THROW #endif { in_destructor = 1; if (temp_buf) { delete temp_buf; temp_buf = nullptr; } if (temp_char_buf) { delete[] temp_char_buf; temp_char_buf = nullptr; } #if defined(OTL_DESTRUCTORS_DO_NOT_THROW) try { if (!closed_flag) otl_tmpl_lob_stream::close(); } catch (OTL_CONST_EXCEPTION otl_exception &) { } #else if (!closed_flag) otl_tmpl_lob_stream::close(); #endif } #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) otl_lob_stream_generic &operator<<(OTL_STD_STRING_VIEW_CLASS s) OTL_THROWS_OTL_EXCEPTION { otl_long_string temp_s(s.data(), OTL_SCAST(int, s.length()), OTL_SCAST(int, s.length())); (*this) << temp_s; return *this; } #endif #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_USER_DEFINED_STRING_CLASS_ON)) && \ !defined(OTL_UNICODE) otl_lob_stream_generic &operator<<(const OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { otl_long_string temp_s(s.c_str(), OTL_SCAST(int, s.length()), OTL_SCAST(int, s.length())); (*this) << temp_s; return *this; } void setStringBuffer(const int chunk_size) { delete[] temp_char_buf; temp_char_buf = nullptr; delete temp_buf; temp_buf = nullptr; temp_char_buf = new char[OTL_SCAST(size_t,chunk_size + 1)]; temp_buf = new otl_long_string(temp_char_buf, chunk_size); } otl_lob_stream_generic & operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { const int TEMP_BUF_SIZE = 4096; if (!temp_char_buf) temp_char_buf = new char[TEMP_BUF_SIZE]; if (!temp_buf) temp_buf = new otl_long_string(temp_char_buf, TEMP_BUF_SIZE - 1); int iters = 0; while (!this->eof()) { ++iters; (*this) >> (*temp_buf); temp_char_buf[temp_buf->len()] = 0; if (iters > 1) s.append(temp_char_buf, OTL_SCAST(size_t, temp_buf->len())); else #if (defined(OTL_USER_DEFINED_STRING_CLASS_ON) || defined(OTL_STL)) && \ !defined(OTL_ACE) s.assign(temp_char_buf, OTL_SCAST(size_t, temp_buf->len())); #elif defined(OTL_ACE) s.set(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()), 1); #endif } return *this; } #endif otl_lob_stream_generic &operator<<(const otl_long_string &s) OTL_THROWS_OTL_EXCEPTION { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (bind_var && bind_var->get_ftype() == otl_var_raw_long) in_unicode_mode = false; if (s.get_unicode_flag() != in_unicode_mode) { OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_37, otl_error_code_37, "otl_lob_stream_generic::operator<<(const otl_long_string&)"))); } if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) { const char *stm = nullptr; char var_info[256]; var_info[0] = 0; if (cursor != nullptr) { if (cursor->get_stm_label()) stm = cursor->get_stm_label(); else stm = cursor->get_stm_text(); } if (bind_var != nullptr) { otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); } char *vinfo = nullptr; if (var_info[0] != 0) vinfo = &var_info[0]; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_tmpl_exception( otl_error_msg_9, otl_error_code_9, stm, vinfo))); } if (offset == 0) offset = 1; if (bind_var != nullptr) retcode = bind_var->get_var_struct().write_blob( s, lob_len, offset, cursor->get_cursor_struct()); written_to_flag = true; if (retcode) return *this; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); } otl_lob_stream_generic & operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (bind_var && bind_var->get_ftype() == otl_var_raw_long) in_unicode_mode = false; if (s.get_unicode_flag() != in_unicode_mode) { OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_37, otl_error_code_37, "otl_lob_stream_generic::operator>>(otl_long_string&)"))); } if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) { const char *stm = nullptr; char var_info[256]; var_info[0] = 0; if (cursor != nullptr) { if (cursor->get_stm_label()) stm = cursor->get_stm_label(); else stm = cursor->get_stm_text(); } if (bind_var != nullptr) { otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); } char *vinfo = nullptr; if (var_info[0] != 0) vinfo = &var_info[0]; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(otl_error_msg_10, otl_error_code_10, stm, vinfo))); } if (offset == 0) offset = 1; if (bind_var != nullptr) retcode = bind_var->get_var_struct().read_blob( cursor->get_cursor_struct(), s, ndx, offset, eof_flag); if (retcode) (void)len(); if (retcode) { if (eof()) close(); return *this; } OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); } OTL_NODISCARD int eof(void) OTL_NO_THROW { if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) return 1; if (lob_is_null) return 1; return eof_flag; } OTL_NODISCARD int len(void) OTL_THROWS_OTL_EXCEPTION { if (last_read_lob_len > 0) return last_read_lob_len; if (cursor == nullptr || connect == nullptr || bind_var == nullptr || lob_is_null) return 0; int alen; retcode = bind_var->get_var_struct().get_blob_len(ndx, alen); if (retcode) { last_read_lob_len = alen; return alen; } OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((OTL_TMPL_EXCEPTION(connect->get_connect_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); } OTL_NODISCARD bool is_initialized(void) OTL_THROWS_OTL_EXCEPTION { if (cursor == nullptr || connect == nullptr || bind_var == nullptr || lob_is_null) return false; else return true; } void close(bool = false) OTL_THROWS_OTL_EXCEPTION { if (in_destructor) { if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) { bind_var->get_var_struct().set_lob_stream_flag(0); bind_var->set_not_null(0); } if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) { retcode = bind_var->get_var_struct().clob_blob(cursor->get_cursor_struct()); closed_flag = true; written_to_flag = false; if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); } } return; } if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode)) return; if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) { bind_var->get_var_struct().set_lob_stream_flag(0); bind_var->set_not_null(0); init(nullptr, nullptr, nullptr, 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode)); } else { // write mode if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) { retcode = bind_var->get_var_struct().clob_blob(cursor->get_cursor_struct()); written_to_flag = false; closed_flag = true; if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((OTL_TMPL_EXCEPTION(cursor->get_cursor_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); } } bind_var->get_var_struct().set_lob_stream_flag(0); bind_var->set_not_null(0); } } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_lob_stream(const otl_tmpl_lob_stream &) = delete; otl_tmpl_lob_stream &operator=(const otl_tmpl_lob_stream &) = delete; private: #else otl_tmpl_lob_stream(const otl_tmpl_lob_stream &) OTL_NO_THROW : otl_lob_stream_generic(false), bind_var(nullptr), connect(nullptr), cursor(nullptr), temp_buf(nullptr), temp_char_buf(nullptr), written_to_flag(false), closed_flag(false), last_read_lob_len(0) {} otl_tmpl_lob_stream &operator=(const otl_tmpl_lob_stream &) { return *this; } #endif }; typedef otl_tmpl_lob_stream otl_lob_stream; #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) class otl_stream; class otl_for_range_loop_odbc_stream_adapter{ public: otl_for_range_loop_odbc_stream_adapter(): str_(nullptr){} otl_for_range_loop_odbc_stream_adapter(otl_stream& str): str_(&str){} otl_stream& operator*(){ return *str_; } otl_for_range_loop_odbc_stream_adapter& operator++(){ return *this; } otl_stream* str_; }; #endif #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) #include #endif #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) #include #endif #if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_COMPILER_HAS_STD_OPTIONAL) #include #endif #if defined(OTL_STREAM_WITH_STD_SPAN_ON) && defined(OTL_CPP_20_ON) #include #endif class otl_stream { private: otl_stream_shell *shell; otl_ptr shell_pt; int connected; otl_select_stream **ss; otl_inout_stream **io; otl_connect **adb; int *auto_commit_flag; otl_var_desc **iov; int *iov_len; int *next_iov_ndx; otl_var_desc **ov; int *ov_len; int *next_ov_ndx; otl_select_struct_override *override_; int end_marker; int oper_int_called; int last_eof_rc; bool last_oper_was_read_op; #if defined(OTL_STREAM_WITH_STD_TUPLE_ON) && defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED) public: template otl_stream& operator<<(const std::tuple& t){ otl_tuple_helper::write(*this,t); return (*this); } template otl_stream& operator>>(std::tuple& t){ otl_tuple_helper::read(*this,t); return (*this); } #endif #if defined(OTL_STREAM_WITH_STD_SPAN_ON) && defined(OTL_CPP_20_ON) public: template otl_stream& operator<<(std::span v){ for(const auto& e: v){ (*this)< otl_stream& operator<<(const std::variant& v){ bool value_written=false; otl_variant_helper> ::write(*this,v,value_written); return (*this); } template otl_stream& operator>>(std::variant& v){ bool value_read=false; otl_variant_helper> ::read(*this,v,value_read); return (*this); } #endif public: #if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_CPP_14_ON) #if defined(OTL_COMPILER_HAS_STD_OPTIONAL) template otl_stream& operator<<(const std::optional &var) OTL_THROWS_OTL_EXCEPTION { if(var) (*this)<<(*var); else (*this)< otl_stream& operator>>(std::optional &var) OTL_THROWS_OTL_EXCEPTION { if(var){ (*this)>>(*var); if(this->is_null())var=std::optional(); }else{ TData temp_var; (*this)>>temp_var; if(!this->is_null())var.emplace(std::move(temp_var)); } return *this; } #else template class Optional> otl_stream& operator<<(const Optional &var) OTL_THROWS_OTL_EXCEPTION { if(var) (*this)<<(*var); else (*this)< class Optional> otl_stream& operator>>(Optional &var) OTL_THROWS_OTL_EXCEPTION { if(var){ (*this)>>(*var); if(this->is_null())var=Optional(); }else{ TData temp_var; (*this)>>temp_var; if(!this->is_null())var.emplace(std::move(temp_var)); } return *this; } #endif #endif #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) OTL_NODISCARD otl_for_range_loop_odbc_stream_adapter begin(){ if(!eof()) return otl_for_range_loop_odbc_stream_adapter(*this); else return otl_for_range_loop_odbc_stream_adapter(); } otl_for_range_loop_odbc_stream_adapter end(){ return otl_for_range_loop_odbc_stream_adapter(); } OTL_NODISCARD int get_auto_commit_flag() const { if (!auto_commit_flag) return 0; else return *auto_commit_flag; } #endif #if defined(OTL_ODBC_SQL_STATEMENT_WITH_DIAG_REC_OUTPUT) OTL_NODISCARD OTL_SQLHSTMT get_stm_handle() { return (*io)->get_cursor_struct().get_cda(); } #if defined(_UNICODE) || defined(UNICODE) typedef SQLWCHAR sqlchar_type; #else typedef SQLCHAR sqlchar_type; #endif OTL_NODISCARD bool get_next_diag_rec(short int &rec_ndx, sqlchar_type *sqlstate_buf, sqlchar_type *msg_buf, short int msg_buf_size, int &native_err) { OTL_SQLINTEGER rc; SQLSMALLINT msg_len; rc = SQLGetDiagRec(SQL_HANDLE_STMT, get_stm_handle(), OTL_SCAST(OTL_SQLSMALLINT, rec_ndx), OTL_RCAST(sqlchar_type *, sqlstate_buf), OTL_RCAST(OTL_SQLINTEGER_PTR, &native_err), OTL_RCAST(sqlchar_type *, msg_buf), msg_buf_size, OTL_RCAST(OTL_SQLSMALLINT_PTR, &msg_len)); bool result = rc == SQL_NO_DATA || rc < 0; msg_buf[msg_len] = 0; ++rec_ndx; return result; } #endif protected: int buf_size_; void reset_end_marker(void) { last_eof_rc = 0; end_marker = -1; oper_int_called = 0; } OTL_NORETURN void throw_end_of_row() #if defined(__GNUC__) && (__GNUC__ >= 4) __attribute__((noreturn)) #endif { OTL_THROW((otl_exception(otl_error_msg_34, otl_error_code_34, this->get_stm_text()))); } void inc_next_ov(void) { if ((*ov_len) == 0) return; if ((*next_ov_ndx) < (*ov_len) - 1) ++(*next_ov_ndx); else (*next_ov_ndx) = 0; } void inc_next_iov(void) { if ((*iov_len) == 0) return; if ((*next_iov_ndx) < (*iov_len) - 1) ++(*next_iov_ndx); else (*next_iov_ndx) = 0; } public: OTL_NODISCARD int get_prefetched_row_count() const { if (*ss) { return (*ss)->get_prefetched_row_count(); } return 0; } OTL_NODISCARD bool get_lob_stream_flag() const { if (!shell) return false; else return shell->lob_stream_flag; } OTL_NODISCARD int get_adb_max_long_size() const { return this->shell->adb->get_max_long_size(); } void check_end_of_row() { if (next_ov_ndx == nullptr || (*next_ov_ndx) != 0) throw_end_of_row(); if (next_iov_ndx == nullptr || (*next_iov_ndx) != 0) throw_end_of_row(); } OTL_NODISCARD otl_stream_shell *get_shell() { return shell; } OTL_NODISCARD int get_connected() const { return connected; } OTL_NODISCARD int get_dirty_buf_len() const { switch (shell->stream_type) { case otl_odbc_no_stream: return 0; case otl_odbc_io_stream: return (*io)->get_dirty_buf_len(); case otl_odbc_select_stream: return (*ss)->get_select_row_count(); default: return 0; } } OTL_NODISCARD const char *get_stm_text(void) { const char *no_stm_text = OTL_NO_STM_TEXT; switch (shell->stream_type) { case otl_odbc_no_stream: return no_stm_text; case otl_odbc_io_stream: return (*io)->get_stm_label() ? (*io)->get_stm_label() : (*io)->get_stm_text(); case otl_odbc_select_stream: return (*ss)->get_stm_label() ? (*ss)->get_stm_label() : (*ss)->get_stm_text(); default: return no_stm_text; } } void setBufSize(int buf_size) { buf_size_ = buf_size; } OTL_NODISCARD int getBufSize(void) const { return buf_size_; } OTL_NODISCARD long get_rpc() OTL_NO_THROW { if ((*io)) { return (*io)->get_rpc(); } else if ((*ss)) { return (*ss)->get_rfc(); } else return 0; } void skip_to_end_of_row() { if (next_ov_ndx == nullptr) return; if ((*ov_len) == 0) return; last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); (*io)->skip_to_end_of_row(); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); (*ss)->skip_to_end_of_row(); break; } *next_ov_ndx = 0; } void skip_to_next_var() { if(next_ov_ndx==nullptr)return; if((*ov_len)==0)return; last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); (*io)->skip_to_next_var(); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); (*ss)->skip_to_next_var(); break; } if((*next_ov_ndx)<(*ov_len)-1) ++(*next_ov_ndx); } operator int(void) OTL_THROWS_OTL_EXCEPTION { if (shell && shell->lob_stream_flag) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); const char *stm_label = nullptr; const char *stm_text = nullptr; if ((*io)) { stm_label = (*io)->get_stm_label(); stm_text = (*io)->get_stm_text(); } else if ((*ss)) { stm_label = (*ss)->get_stm_label(); stm_text = (*ss)->get_stm_text(); } OTL_THROW((otl_exception(otl_error_msg_24, otl_error_code_24, stm_label ? stm_label : stm_text))); } if (!last_oper_was_read_op) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); const char *stm_label = nullptr; const char *stm_text = nullptr; if ((*io)) { stm_label = (*io)->get_stm_label(); stm_text = (*io)->get_stm_text(); } else if ((*ss)) { stm_label = (*ss)->get_stm_label(); stm_text = (*ss)->get_stm_text(); } OTL_THROW((otl_exception(otl_error_msg_18, otl_error_code_18, stm_label ? stm_label : stm_text))); } if (end_marker == 1) return 0; int rc = 0; int temp_eof = eof(); if (temp_eof && end_marker == -1 && oper_int_called == 0) { end_marker = 1; if (last_eof_rc == 1) rc = 0; else rc = 1; } else if (!temp_eof && end_marker == -1) rc = 1; else if (temp_eof && end_marker == -1) { end_marker = 0; rc = 1; } else if (temp_eof && end_marker == 0) { end_marker = 1; rc = 0; } if (!oper_int_called) oper_int_called = 1; return rc; } void cancel(void) OTL_THROWS_OTL_EXCEPTION { if ((*ss)) { int status = (*ss)->get_cursor_struct().cancel(); if (status == 0) OTL_THROW((otl_exception((*ss)->get_cursor_struct()))); } else if ((*io)) { int status = (*io)->get_cursor_struct().cancel(); if (status == 0) OTL_THROW((otl_exception((*io)->get_cursor_struct()))); } } void create_var_desc(void) { int i; delete[](*iov); delete[](*ov); (*iov) = nullptr; (*iov_len) = 0; (*ov) = nullptr; (*ov_len) = 0; if ((*ss)) { if ((*ss)->get_vl_len() > 0) { (*iov) = new otl_var_desc[OTL_SCAST(size_t,(*ss)->get_vl_len())]; (*iov_len) = (*ss)->get_vl_len(); for (i = 0; i < (*ss)->get_vl_len(); ++i) (*ss)->get_vl()[i]->copy_var_desc((*iov)[i]); } if ((*ss)->get_sl_len() > 0) { (*ov) = new otl_var_desc[OTL_SCAST(size_t,(*ss)->get_sl_len())]; (*ov_len) = (*ss)->get_sl_len(); for (i = 0; i < (*ss)->get_sl_len(); ++i) { (*ss)->get_sl()[i].copy_var_desc((*ov)[i]); if ((*ss)->get_sl_desc() != nullptr){ (*ov)[i].copy_name((*ss)->get_sl_desc()[i].name); (*ov)[i].set_param_type(1); } } } } else if ((*io)) { int temp_vl_len = (*io)->get_vl_len(); int temp_iv_len = (*io)->get_iv_len(); if (temp_vl_len > 0) { (*iov) = new otl_var_desc[OTL_SCAST(size_t,temp_vl_len)]; (*iov_len) = temp_vl_len; for (i = 0; i < temp_vl_len; ++i) (*io)->get_vl()[i]->copy_var_desc((*iov)[i]); } if (temp_iv_len > 0) { (*ov) = new otl_var_desc[OTL_SCAST(size_t,temp_iv_len)]; (*ov_len) = temp_iv_len; for (i = 0; i < temp_iv_len; ++i) (*io)->get_in_vl()[i]->copy_var_desc((*ov)[i]); } } } void set_column_type(const int column_ndx, const int col_type, const int col_size = 0) OTL_NO_THROW { if (shell == nullptr) { init_stream(); shell->flush_flag = true; } override_->add_override(column_ndx, col_type, col_size); } void set_all_column_types(const unsigned mask = 0) OTL_NO_THROW { if (shell == nullptr) { init_stream(); shell->flush_flag = true; } override_->set_all_column_types(mask); } void set_flush(const bool flush_flag = true) OTL_NO_THROW { if (shell == nullptr) init_stream(); shell->flush_flag = flush_flag; } void set_lob_stream_mode(const bool lob_stream_flag = false) OTL_NO_THROW { if (shell == nullptr) return; shell->lob_stream_flag = lob_stream_flag; } OTL_NODISCARD otl_var_desc *describe_in_vars(int &desc_len) OTL_NO_THROW { desc_len = 0; if (shell == nullptr) return nullptr; if (shell->iov == nullptr) return nullptr; desc_len = shell->iov_len; return shell->iov; } OTL_NODISCARD otl_var_desc *describe_out_vars(int &desc_len) OTL_NO_THROW { desc_len = 0; if (shell == nullptr) return nullptr; if (shell->ov == nullptr) return nullptr; desc_len = shell->ov_len; return shell->ov; } OTL_NODISCARD otl_var_desc *describe_next_in_var(void) OTL_NO_THROW { if (shell == nullptr) return nullptr; if (shell->iov == nullptr) return nullptr; return &(shell->iov[shell->next_iov_ndx]); } OTL_NODISCARD otl_var_desc *describe_next_out_var(void) OTL_NO_THROW { if (shell == nullptr) return nullptr; if (shell->ov == nullptr) return nullptr; return &(shell->ov[shell->next_ov_ndx]); } void init_stream(void) { buf_size_ = 1; last_oper_was_read_op = false; shell = nullptr; shell = new otl_stream_shell(0); shell_pt.assign(&shell); connected = 0; ss = &(shell->ss); io = &(shell->io); adb = &(shell->adb); auto_commit_flag = &(shell->auto_commit_flag); iov = &(shell->iov); iov_len = &(shell->iov_len); next_iov_ndx = &(shell->next_iov_ndx); ov = &(shell->ov); ov_len = &(shell->ov_len); next_ov_ndx = &(shell->next_ov_ndx); override_ = &(shell->override_); (*io) = nullptr; (*ss) = nullptr; (*adb) = nullptr; (*ov) = nullptr; (*ov_len) = 0; (*next_iov_ndx) = 0; (*next_ov_ndx) = 0; (*auto_commit_flag) = 1; (*iov) = nullptr; (*iov_len) = 0; } otl_stream(const otl_stream_buffer_size_type arr_size, const char *sqlstm, otl_connect &db, const int implicit_select = otl_explicit_select, const char *sqlstm_label = nullptr) OTL_THROWS_OTL_EXCEPTION: shell(nullptr), shell_pt(), connected(0), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr), next_ov_ndx(nullptr), override_(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0), last_oper_was_read_op(false), buf_size_(0) { init_stream(); (*io) = nullptr; (*ss) = nullptr; (*iov) = nullptr; (*iov_len) = 0; (*ov) = nullptr; (*ov_len) = 0; (*auto_commit_flag) = 1; (*next_iov_ndx) = 0; (*next_ov_ndx) = 0; (*adb) = &db; shell->flush_flag = true; open(arr_size, sqlstm, db, implicit_select, sqlstm_label); } otl_stream() OTL_NO_THROW : shell(nullptr), shell_pt(), connected(0), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr), next_ov_ndx(nullptr), override_(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0), last_oper_was_read_op(false), buf_size_(0) { init_stream(); shell->flush_flag = true; } virtual ~otl_stream() #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW) OTL_THROWS_OTL_EXCEPTION #else OTL_NO_THROW #endif { if (!connected) return; try { if ((*io) != nullptr && shell->flush_flag == false) (*io)->set_flush_flag2(false); close(); if (shell != nullptr) { if ((*io) != nullptr) (*io)->set_flush_flag2(true); } } catch (OTL_CONST_EXCEPTION otl_exception &) { if (shell != nullptr) { if ((*io) != nullptr) (*io)->set_flush_flag2(true); } #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) clean(1); if (shell != nullptr) shell->set_should_delete(1); shell_pt.destroy(); #else shell_pt.destroy(); #endif #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW) throw; #endif } #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if(otl_uncaught_exception()){} #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) if (otl_uncaught_exception()){} #else shell_pt.destroy(); #endif } OTL_NODISCARD int eof(void)OTL_THROWS_OTL_EXCEPTION { if ((*io)) { return (*io)->eof(); } else if ((*ss)) { return (*ss)->eof(); } else return 1; } void reset_to_last_valid_row() { if ((*io)) { (*io)->reset_to_last_valid_row(); } } void flush(void) OTL_THROWS_OTL_EXCEPTION { if ((*io)) { (*io)->flush(); } } OTL_NODISCARD bool get_error_state(void) const { if(otl_uncaught_exception()) return true; else if ((*io)) return (*io)->get_error_state(); else return false; } void clean(const int clean_up_error_flag = 0) OTL_THROWS_OTL_EXCEPTION { if(next_ov_ndx!=nullptr)(*next_ov_ndx)=0; if(next_iov_ndx!=nullptr)(*next_iov_ndx)=0; if ((*io) && shell != nullptr) { (*io)->clean(clean_up_error_flag); } else if ((*ss) && shell != nullptr) { (*ss)->clean(); } } void rewind(void) OTL_THROWS_OTL_EXCEPTION { if ((*io)) { (*io)->rewind(); } else if ((*ss)) { (*ss)->rewind(); } } OTL_NODISCARD int is_null(void) OTL_NO_THROW { if ((*io)) return (*io)->is_null(); else if ((*ss)) return (*ss)->is_null(); else return 0; } void set_commit(int auto_commit = 0) OTL_NO_THROW { (*auto_commit_flag) = auto_commit; if ((*io)) { (*io)->set_commit(auto_commit); } } OTL_NODISCARD const char *assign_stream_type(const char *stm_text, const char *stm_label) { const char *temp_stm_text = nullptr; temp_stm_text = stm_label ? stm_label : stm_text; return temp_stm_text; } void open(const otl_stream_buffer_size_type arr_size, const char *sqlstm, otl_connect &db, const int implicit_select = otl_explicit_select, const char *sqlstm_label = nullptr) OTL_THROWS_OTL_EXCEPTION { if (arr_size <= 0) { OTL_THROW((otl_exception(otl_error_msg_40, otl_error_code_40, sqlstm))); } #if defined(OTL_STREAM_THROWS_NOT_CONNECTED_TO_DATABASE_EXCEPTION) if (!db.connected) { OTL_THROW((otl_exception(otl_error_msg_35, otl_error_code_35, sqlstm))); } #endif reset_end_marker(); otl_stream_buffer_size_type temp_arr_size = arr_size; if (this->good()) { const char *temp_stm_text = assign_stream_type(sqlstm, sqlstm_label); OTL_THROW((otl_exception(otl_error_msg_29, otl_error_code_29, temp_stm_text))); } if (shell == nullptr) init_stream(); buf_size_ = arr_size; OTL_TRACE_STREAM_OPEN #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if (adb != nullptr && *adb == nullptr) *adb = &db; if (adb != nullptr && (*adb) && (**adb).get_stream_pool_enabled_flag()) { char temp_buf[128]; otl_itoa(arr_size, temp_buf); const char delimiter = ';'; #if defined(OTL_STREAM_POOL_USES_STREAM_LABEL_AS_KEY) const char *temp_label = sqlstm_label ? sqlstm_label : sqlstm; #if defined(OTL_UNICODE_STRING_TYPE) std::string sql_stm(temp_label); #else OTL_STRING_CONTAINER sql_stm(temp_label); #endif sql_stm += delimiter; #if defined(OTL_UNICODE_STRING_TYPE) sql_stm += std::string(temp_buf); #else sql_stm += OTL_STRING_CONTAINER(temp_buf); #endif #else #if defined(OTL_UNICODE_STRING_TYPE) std::string sql_stm(sqlstm); #else OTL_STRING_CONTAINER sql_stm(sqlstm); #endif sql_stm += delimiter; #if defined(OTL_UNICODE_STRING_TYPE) sql_stm += std::string(temp_buf); #else sql_stm += OTL_STRING_CONTAINER(temp_buf); #endif #endif if (shell != nullptr) { otl_select_struct_override &temp_override = shell->override_; for (int i = 0; i < temp_override.getLen(); ++i) { otl_itoa(OTL_SCAST(int, temp_override.get_col_type(i)), temp_buf); sql_stm += delimiter; #if defined(OTL_UNICODE_STRING_TYPE) sql_stm += std::string(temp_buf); #else sql_stm += OTL_STRING_CONTAINER(temp_buf); #endif } } otl_stream_shell *temp_shell = OTL_RCAST(otl_stream_shell *, db.sc.find(sql_stm)); if (temp_shell) { if (shell != nullptr) shell_pt.destroy(); shell = temp_shell; ss = &(shell->ss); io = &(shell->io); if ((*io) != nullptr) (*io)->set_flush_flag2(true); adb = &(shell->adb); if (*adb == nullptr) *adb = &db; auto_commit_flag = &(shell->auto_commit_flag); iov = &(shell->iov); iov_len = &(shell->iov_len); next_iov_ndx = &(shell->next_iov_ndx); ov = &(shell->ov); ov_len = &(shell->ov_len); next_ov_ndx = &(shell->next_ov_ndx); override_ = &(shell->override_); try { if ((*iov_len) == 0) this->rewind(); } catch (OTL_CONST_EXCEPTION otl_exception &) { if ((*adb)) (*adb)->sc.remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; throw; } connected = 1; return; } if(shell != nullptr) shell->orig_sql_stm = sql_stm; } #endif delete[](*iov); delete[](*ov); (*iov) = nullptr; (*iov_len) = 0; (*ov) = nullptr; (*ov_len) = 0; (*next_iov_ndx) = 0; (*next_ov_ndx) = 0; char tmp[7]; char *c = OTL_CCAST(char *, sqlstm); override_->set_lob_stream_mode(shell->lob_stream_flag); while (otl_isspace(*c) || (*c) == '(') ++c; OTL_STRNCPY_S(tmp, sizeof(tmp), c, 6); tmp[6] = 0; c = tmp; while (*c) { *c = OTL_SCAST(char, otl_to_upper(*c)); ++c; } adb = &(shell->adb); (*adb) = &db; try { #if (defined(OTL_ODBC_POSTGRESQL) && !defined(OTL_ODBC_ALTERNATE_RPC) || \ defined(OTL_ODBC_SELECT_STM_EXECUTE_BEFORE_DESCRIBE)) && \ !defined(OTL_ODBC_MULTI_MODE) if ((strncmp(tmp, "SELECT", 6) == 0 || strncmp(tmp, "WITH", 4) == 0)) { override_->set_master_stream_ptr(OTL_RCAST(void *, this)); (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, otl_implicit_select, sqlstm_label); shell->stream_type = otl_odbc_select_stream; } #elif defined(OTL_ODBC_MULTI_MODE) #if defined(OTL_ODBC_ALTERNATE_RPC) bool alternate_rpc = true; #else bool alternate_rpc = false; #endif int connect_type = (*adb)->get_connect_struct().get_connection_type(); if (((connect_type == OTL_POSTGRESQL_ODBC_CONNECT && !alternate_rpc) || connect_type == OTL_ENTERPRISE_DB_ODBC_CONNECT || connect_type == OTL_MYODBC35_ODBC_CONNECT) && (strncmp(tmp, "SELECT", 6) == 0 || strncmp(tmp, "WITH", 4) == 0)) { override_->set_master_stream_ptr(OTL_RCAST(void *, this)); (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, otl_implicit_select, sqlstm_label); shell->stream_type = otl_odbc_select_stream; } else if ((strncmp(tmp, "SELECT", 6) == 0 || strncmp(tmp, "WITH", 4) == 0) && implicit_select == otl_explicit_select) { (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, otl_explicit_select, sqlstm_label); shell->stream_type = otl_odbc_select_stream; } #else if ((strncmp(tmp, "SELECT", 6) == 0 || strncmp(tmp, "WITH", 4) == 0) && implicit_select == otl_explicit_select) { #if defined(OTL_ODBC_TIMESTEN) if (temp_arr_size > 128 || temp_arr_size < 0) { const char *temp_stm_text = assign_stream_type(sqlstm, sqlstm_label); OTL_THROW((otl_exception(otl_error_msg_31, otl_error_code_31, temp_stm_text))); } #endif override_->set_master_stream_ptr(OTL_RCAST(void *, this)); (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, otl_explicit_select, sqlstm_label); shell->stream_type = otl_odbc_select_stream; } #endif else if (tmp[0] == '$') { override_->set_master_stream_ptr(OTL_RCAST(void *, this)); (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, 1, sqlstm_label); shell->stream_type = otl_odbc_select_stream; } else { if (implicit_select == otl_implicit_select) { #if defined(OTL_ODBC_TIMESTEN) if (temp_arr_size > 128 || temp_arr_size < 0) { const char *temp_stm_text = assign_stream_type(sqlstm, sqlstm_label); OTL_THROW((otl_exception(otl_error_msg_31, otl_error_code_31, temp_stm_text))); } #endif override_->set_master_stream_ptr(OTL_RCAST(void *, this)); (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, 1, sqlstm_label); shell->stream_type = otl_odbc_select_stream; } else if(implicit_select == otl_direct_exec_select){ override_->set_master_stream_ptr(OTL_RCAST(void *, this)); (*ss) = new otl_select_stream(override_, temp_arr_size, sqlstm, db, 2, sqlstm_label); shell->stream_type = otl_odbc_select_stream; }else { (*io) = new otl_inout_stream(arr_size, sqlstm, db, OTL_RCAST(void *, this), shell->lob_stream_flag, sqlstm_label); (*io)->set_flush_flag(shell->flush_flag); shell->stream_type = otl_odbc_io_stream; } } } catch (OTL_CONST_EXCEPTION otl_exception &) { shell_pt.destroy(); throw; } if ((*io)) (*io)->set_commit((*auto_commit_flag)); create_var_desc(); connected = 1; } void intern_cleanup(void) { delete[](*iov); delete[](*ov); (*iov) = nullptr; (*iov_len) = 0; (*ov) = nullptr; (*ov_len) = 0; (*next_iov_ndx) = 0; (*next_ov_ndx) = 0; override_->setLen(0); override_->set_lob_stream_mode(false); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: try { if ((*io) != nullptr) { (*io)->flush(); (*io)->close(); } } catch (OTL_CONST_EXCEPTION otl_exception &) { clean(1); (*io)->close(); delete (*io); (*io) = nullptr; shell->stream_type = otl_odbc_no_stream; throw; } delete (*io); (*io) = nullptr; shell->stream_type = otl_odbc_no_stream; break; case otl_odbc_select_stream: try { if ((*ss) != nullptr) (*ss)->close(); } catch (OTL_CONST_EXCEPTION otl_exception &) { delete (*ss); (*ss) = nullptr; shell->stream_type = otl_odbc_no_stream; throw; } delete (*ss); (*ss) = nullptr; shell->stream_type = otl_odbc_no_stream; break; } (*ss) = nullptr; (*io) = nullptr; if (adb != nullptr) (*adb) = nullptr; adb = nullptr; } #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) void close(const bool save_in_stream_pool = true) OTL_THROWS_OTL_EXCEPTION #else void close(void) OTL_THROWS_OTL_EXCEPTION #endif { if (shell == nullptr) return; OTL_TRACE_FUNC(0x4, "otl_stream", "close", "") #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if (save_in_stream_pool && (*adb) && (**adb).get_stream_pool_enabled_flag() && !(otl_uncaught_exception())) { try { this->flush(); this->clean(1); } catch (OTL_CONST_EXCEPTION otl_exception &) { this->clean(1); throw; } if (otl_uncaught_exception()) { (*adb)->sc.remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; return; } #if defined(OTL_STL) && defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) if (otl_uncaught_exception()) { if ((*adb)) (*adb)->sc.remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; return; } #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) if (otl_uncaught_exception()) { if ((*adb)) (*adb)->sc.remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; return; } #endif if(shell->io!=nullptr) shell->io->set_commit(1); (*adb)->sc.add(shell, shell->orig_sql_stm.c_str()); shell_pt.disconnect(); connected = 0; } else { if ((*adb)) (*adb)->sc.remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; } #else intern_cleanup(); connected = 0; #endif } OTL_NODISCARD otl_column_desc *describe_select(int &desc_len) OTL_NO_THROW { desc_len = 0; if ((*ss)) { desc_len = (*ss)->get_sl_len(); return (*ss)->get_sl_desc(); } return nullptr; } OTL_NODISCARD int good(void) OTL_NO_THROW { if (!connected) return 0; if ((*io) || (*ss)) { return 1; } else return 0; } otl_stream &operator<<(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); if ((*io)) { (*io)->operator<<(s); inc_next_iov(); } else if (*ss) { OTL_THROW((otl_exception(otl_error_msg_41, otl_error_code_41, (*ss)->get_stm_label() ? (*ss)->get_stm_label() : (*ss)->get_stm_text()))); } return *this; } otl_stream &operator>>(otl_stream &(*pf)(otl_stream &)) { (*pf)(*this); return *this; } otl_stream &operator<<(otl_stream &(*pf)(otl_stream &)) { (*pf)(*this); return *this; } #if defined(OTL_PARANOID_EOF) void throw_if_eof_was_already_reached(const int eof_flag, const char *operator_type = nullptr) { if (eof_flag) { char out_buf[256]; OTL_SPRINTF_S(out_buf, sizeof(out_buf), otl_error_msg_42, operator_type == nullptr ? "" : operator_type); OTL_THROW((otl_exception(out_buf, otl_error_code_42, this->get_stm_text(), this->describe_next_out_var()->name))); } } #endif otl_stream &operator>>(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&"); #endif #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&"); #endif (*io)->operator>>(s); break; case otl_odbc_select_stream: s.reset_last_read_lob_len(); last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&"); #endif (*ss)->operator>>(s); break; } inc_next_ov(); return *this; } otl_stream &operator>>(otl_time &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&"); #endif (*io)->operator>>(s); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&"); #endif (*ss)->operator>>(s); break; } return *this; } otl_stream &operator<<(const otl_time &n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(n); break; case otl_odbc_select_stream: (*ss)->operator<<(n); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } return *this; } otl_stream &operator>>(otl_datetime &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; #if defined(OTL_ODBC_STRING_TO_TIMESTAMP) otl_var_desc *temp_next_var = describe_next_out_var(); if (temp_next_var != nullptr && temp_next_var->ftype == otl_var_char) { #if defined(OTL_UNICODE) #if defined(OTL_UNICODE_CHAR_TYPE) OTL_UNICODE_CHAR_TYPE tmp_str[100]; #else OTL_CHAR tmp_str[100]; #endif #else char tmp_str[100]; #endif (*this) >> tmp_str; #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_DATETIME_NULL_TO_VAL; else OTL_ODBC_STRING_TO_TIMESTAMP(tmp_str, s); #else OTL_ODBC_STRING_TO_TIMESTAMP(tmp_str, s); #endif #if defined(OTL_ODBC_TIME_ZONE) OTL_TRACE_WRITE(OTL_TRACE_FORMAT_TZ_DATETIME(s), "operator >>", "otl_datetime&"); #else OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>", "otl_datetime&"); #endif return *this; } else { otl_time tmp; #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ (__GNUC__ * 100 + __GNUC_MINOR__ >= 405) || \ defined(__clang__) tmp.year = 1900; tmp.month = 1; tmp.day = 1; tmp.hour = 0; tmp.minute = 0; tmp.second = 0; tmp.fraction = 0; #endif (*this) >> tmp; #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_DATETIME_NULL_TO_VAL; else { s.year = tmp.year; s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour; s.minute = tmp.minute; s.second = tmp.second; s.fraction = otl_from_fraction(tmp.fraction, s.frac_precision); } #else s.year = tmp.year; s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour; s.minute = tmp.minute; s.second = tmp.second; s.fraction = otl_from_fraction(tmp.fraction, s.frac_precision); #endif } #else otl_time tmp; #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ (__GNUC__ * 100 + __GNUC_MINOR__ >= 405) || \ defined(__clang__) tmp.year = 1900; tmp.month = 1; tmp.day = 1; tmp.hour = 0; tmp.minute = 0; tmp.second = 0; tmp.fraction = 0; #endif (*this) >> tmp; #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_DATETIME_NULL_TO_VAL; else { s.year = tmp.year; s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour; s.minute = tmp.minute; s.second = tmp.second; s.fraction = otl_from_fraction(tmp.fraction, s.frac_precision); } #else s.year = tmp.year; s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour; s.minute = tmp.minute; s.second = tmp.second; s.fraction = otl_from_fraction(tmp.fraction, s.frac_precision); #endif #endif OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>", "otl_datetime&"); inc_next_ov(); return *this; } otl_stream &operator<<(const otl_datetime &s) OTL_THROWS_OTL_EXCEPTION { otl_time tmp; last_oper_was_read_op = false; reset_end_marker(); #if defined(OTL_ODBC_TIMESTAMP_TO_STRING) otl_var_desc *temp_next_var = describe_next_in_var(); if (temp_next_var != nullptr && temp_next_var->ftype == otl_var_char) { #if defined(OTL_UNICODE) #if defined(OTL_UNICODE_CHAR_TYPE) OTL_UNICODE_CHAR_TYPE tmp_str[100]; #else OTL_CHAR tmp_str[100]; #endif #else char tmp_str[100]; #endif OTL_ODBC_TIMESTAMP_TO_STRING(s, tmp_str); #if defined(OTL_ODBC_TIME_ZONE) OTL_TRACE_READ(OTL_TRACE_FORMAT_TZ_DATETIME(s), "operator <<", "otl_datetime&"); #else OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<", "otl_datetime&"); #endif (*this) << tmp_str; return *this; } else { tmp.year = OTL_SCAST(SQLSMALLINT, s.year); tmp.month = OTL_SCAST(SQLUSMALLINT, s.month); tmp.day = OTL_SCAST(SQLUSMALLINT, s.day); tmp.hour = OTL_SCAST(SQLUSMALLINT, s.hour); tmp.minute = OTL_SCAST(SQLUSMALLINT, s.minute); tmp.second = OTL_SCAST(SQLUSMALLINT, s.second); tmp.fraction = otl_to_fraction(OTL_SCAST(unsigned int, s.fraction), s.frac_precision); (*this) << tmp; OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<", "otl_datetime&"); inc_next_iov(); return *this; } #else tmp.year = OTL_SCAST(SQLSMALLINT, s.year); tmp.month = OTL_SCAST(SQLUSMALLINT, s.month); tmp.day = OTL_SCAST(SQLUSMALLINT, s.day); tmp.hour = OTL_SCAST(SQLUSMALLINT, s.hour); tmp.minute = OTL_SCAST(SQLUSMALLINT, s.minute); tmp.second = OTL_SCAST(SQLUSMALLINT, s.second); tmp.fraction = otl_to_fraction(OTL_SCAST(unsigned int, s.fraction), s.frac_precision); (*this) << tmp; OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<", "otl_datetime&"); inc_next_iov(); return *this; #endif } #if !defined(OTL_UNICODE) otl_stream &operator>>(char &c) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char&"); #endif (*io)->operator>>(c); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char&"); #endif (*ss)->operator>>(c); break; } #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL) if ((*this).is_null()) c = OTL_DEFAULT_CHAR_NULL_TO_VAL; #endif OTL_TRACE_WRITE("'" << c << "'", "operator >>", "char&") inc_next_ov(); return *this; } #endif #if !defined(OTL_UNICODE) otl_stream &operator>>(unsigned char &c) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&"); #endif (*io)->operator>>(c); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&"); #endif (*ss)->operator>>(c); break; } #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL) if ((*this).is_null()) c = OTL_DEFAULT_CHAR_NULL_TO_VAL; #endif OTL_TRACE_WRITE("'" << c << "'", "operator >>", "unsigned char&") inc_next_ov(); return *this; } #endif #if !defined(OTL_UNICODE) #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) otl_stream &operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&"); #endif (*io)->operator>>(s); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&"); #endif (*ss)->operator>>(s); break; } #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL) if ((*this).is_null()) { OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s); } #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_STRING_NULL_TO_VAL; #endif OTL_TRACE_WRITE(s, "operator >>", "OTL_STRING_CONTAINER&") inc_next_ov(); return *this; } #endif #endif #if !defined(OTL_UNICODE) otl_stream &operator>>(char *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif (*io)->operator>>(s); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif (*ss)->operator>>(s); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif OTL_TRACE_WRITE(s, "operator >>", "char*") inc_next_ov(); return *this; } #endif #if !defined(OTL_UNICODE) && defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template otl_stream &operator>>(std::array& s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*io)->getString(s.data(),OTL_SCAST(int,N)); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*ss)->getString(s.data(),OTL_SCAST(int,N)); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy(OTL_RCAST(unsigned char *, s.data()),OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif OTL_TRACE_WRITE(s, "operator >>", "std::array&") inc_next_ov(); return *this; } #endif #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE) template otl_stream &operator>>(std::array& s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*io)->getString(s.data(),OTL_SCAST(int,N)); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*ss)->getString(s.data(),OTL_SCAST(int,N)); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy(OTL_RCAST(unsigned char *, s.data()),OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif OTL_TRACE_WRITE(s, "operator >>", "std::array&") inc_next_ov(); return *this; } #endif #if defined(OTL_UNICODE_STRING_TYPE) otl_stream &operator>>(OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&"); #endif (*io)->operator>>(s); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&"); #endif (*ss)->operator>>(s); break; } #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL) if ((*this).is_null()) { OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s); } #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, OTL_DEFAULT_STRING_NULL_TO_VAL); #endif OTL_TRACE_WRITE(s.c_str(), "operator >>", "OTL_UNICODE_STRING_TYPE&"); inc_next_ov(); return *this; } #endif otl_stream &operator>>(unsigned char *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*"); #endif (*io)->operator>>(s); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*"); #endif (*ss)->operator>>(s); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, OTL_CCAST(char *, OTL_DEFAULT_STRING_NULL_TO_VAL))); #endif #if defined(OTL_UNICODE) OTL_TRACE_WRITE(OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, s), "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*") #else OTL_TRACE_WRITE(s, "operator >>", "unsigned char*") #endif inc_next_ov(); return *this; } #if defined(OTL_UNICODE) otl_stream &operator>>(OTL_UNICODE_CHAR_TYPE &c) OTL_THROWS_OTL_EXCEPTION { OTL_UNICODE_CHAR_TYPE s[1024]; last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&"); #endif (*io)->operator>>(OTL_RCAST(unsigned char *, s)); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&"); #endif (*ss)->operator>>(OTL_RCAST(unsigned char *, s)); break; } #if defined(_MSC_VER) && (_MSC_VER >= 1700) #pragma warning(push) #pragma warning(disable : 6001) #endif c = s[0]; #if defined(_MSC_VER) && (_MSC_VER >= 1700) #pragma warning(pop) #endif #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL) if ((*this).is_null()) c = OTL_DEFAULT_CHAR_NULL_TO_VAL; #endif OTL_TRACE_WRITE(c, "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "") inc_next_ov(); return *this; } otl_stream &operator>>(OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*"); #endif (*io)->operator>>(OTL_RCAST(unsigned char *, s)); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*"); #endif (*ss)->operator>>(OTL_RCAST(unsigned char *, s)); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif OTL_TRACE_WRITE(OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, s), "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*") inc_next_ov(); return *this; } #endif #define OTL_GTGT_OPERATOR_2(T,T_type) \ otl_stream &operator>>(T& v) OTL_THROWS_OTL_EXCEPTION { \ last_oper_was_read_op = true; \ switch (shell->stream_type) { \ case otl_odbc_no_stream: \ break; \ case otl_odbc_io_stream: \ last_eof_rc = (*io)->eof(); \ OTL_PARANOID_EOF_THROW(#T "&"); \ OTL_OPERATOR_1(io,v,T,T_type,>>); \ break; \ case otl_odbc_select_stream: \ last_eof_rc = (*ss)->eof(); \ OTL_PARANOID_EOF_THROW(#T "&"); \ OTL_OPERATOR_1(ss,v,T,T_type,>>); \ break; \ } \ OTL_DEFAULT_NULL_ASSIGN(T,v); \ OTL_TRACE_WRITE(v, "operator >>", #T "&"); \ inc_next_ov(); \ return *this; \ } #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 305) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wextra-semi" #endif OTL_GTGT_OPERATOR_2(int,otl_var_int); OTL_GTGT_OPERATOR_2(unsigned int,otl_var_unsigned_int); OTL_GTGT_OPERATOR_2(short int,otl_var_short); OTL_GTGT_OPERATOR_2(long int,otl_var_long_int); #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) otl_stream &operator>>(OTL_NUMERIC_TYPE_1 &l) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR) { otl_var_desc *var_desc = describe_next_out_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_1_str_size]; #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_1_str_size]; (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val)); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++c; ++uc; } *c = 0; #else (*ss)->operator>>(temp_val); #endif OTL_STR_TO_NUMERIC_TYPE_1(temp_val, l); } else { #if !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS) #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif #else char var_info[256]; otl_var_info_var2(var_desc->name, var_desc->ftype, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0, (*io)->get_stm_label() ? (*io)->get_stm_label() : (*io)->get_stm_text(), var_info))); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif #endif break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR) { otl_var_desc *var_desc = describe_next_out_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_1_str_size]; char temp_val[otl_numeric_type_1_str_size]; (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val)); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++c; ++uc; } *c = 0; OTL_STR_TO_NUMERIC_TYPE_1(temp_val, l); #else char temp_val[otl_numeric_type_1_str_size]; (*ss)->operator>>(temp_val); OTL_STR_TO_NUMERIC_TYPE_1(temp_val, l); #endif } else { #if !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS) #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif #else char var_info[256]; otl_var_info_var2(var_desc->name, var_desc->ftype, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0, (*ss)->get_stm_label() ? (*ss)->get_stm_label() : (*ss)->get_stm_text(), var_info))); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif #endif break; } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) l = OTL_SCAST(OTL_NUMERIC_TYPE_1, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_numeric_type_1_str_size]; OTL_NUMERIC_TYPE_1_TO_STR(l, temp_str); OTL_TRACE_WRITE(temp_str, "operator >>", OTL_NUMERIC_TYPE_1_ID "&") } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_WRITE(l, "operator >>", OTL_NUMERIC_TYPE_1_ID "&") #endif inc_next_ov(); return *this; } #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) otl_stream &operator>>(OTL_NUMERIC_TYPE_2 &l) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR) { otl_var_desc *var_desc = describe_next_out_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_2_str_size]; #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_2_str_size]; (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val)); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++c; ++uc; } *c = 0; #else (*ss)->operator>>(temp_val); #endif OTL_STR_TO_NUMERIC_TYPE_2(temp_val, l); } else { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif #endif break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR) { otl_var_desc *var_desc = describe_next_out_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_2_str_size]; char temp_val[otl_numeric_type_2_str_size]; (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val)); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++c; ++uc; } *c = 0; OTL_STR_TO_NUMERIC_TYPE_2(temp_val, l); #else char temp_val[otl_numeric_type_2_str_size]; (*ss)->operator>>(temp_val); OTL_STR_TO_NUMERIC_TYPE_2(temp_val, l); #endif } else { #if !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS) #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif #else char var_info[256]; otl_var_info_var2(var_desc->name, var_desc->ftype, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0, (*ss)->get_stm_label() ? (*ss)->get_stm_label() : (*ss)->get_stm_text(), var_info))); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif #endif break; } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) l = OTL_SCAST(OTL_NUMERIC_TYPE_2, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_numeric_type_2_str_size]; OTL_NUMERIC_TYPE_2_TO_STR(l, temp_str); OTL_TRACE_WRITE(temp_str, "operator >>", OTL_NUMERIC_TYPE_2_ID "&") } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_WRITE(l, "operator >>", OTL_NUMERIC_TYPE_2_ID "&") #endif inc_next_ov(); return *this; } #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) otl_stream &operator>>(OTL_NUMERIC_TYPE_3 &l) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR) { otl_var_desc *var_desc = describe_next_out_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_3_str_size]; #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_3_str_size]; (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val)); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++c; ++uc; } *c = 0; #else (*ss)->operator>>(temp_val); #endif OTL_STR_TO_NUMERIC_TYPE_3(temp_val, l); } else { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif #endif break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR) { otl_var_desc *var_desc = describe_next_out_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_3_str_size]; char temp_val[otl_numeric_type_3_str_size]; (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val)); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++c; ++uc; } *c = 0; OTL_STR_TO_NUMERIC_TYPE_3(temp_val, l); #else char temp_val[otl_numeric_type_3_str_size]; (*ss)->operator>>(temp_val); OTL_STR_TO_NUMERIC_TYPE_3(temp_val, l); #endif } else { #if !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS) #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif #else char var_info[256]; otl_var_info_var2(var_desc->name, var_desc->ftype, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0, (*ss)->get_stm_label() ? (*ss)->get_stm_label() : (*ss)->get_stm_text(), var_info))); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif #endif break; } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) l = OTL_SCAST(OTL_NUMERIC_TYPE_3, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_numeric_type_3_str_size]; OTL_NUMERIC_TYPE_3_TO_STR(l, temp_str); OTL_TRACE_WRITE(temp_str, "operator >>", OTL_NUMERIC_TYPE_3_ID "&") } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_WRITE(l, "operator >>", OTL_NUMERIC_TYPE_3_ID "&") #endif inc_next_ov(); return *this; } #endif #if defined(OTL_BIGINT) otl_stream &operator>>(OTL_BIGINT &l) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&"); #endif #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR) { otl_var_desc *var_desc = describe_next_out_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_bigint_str_size]; #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_bigint_str_size]; (*ss)->operator>>(OTL_RCAST(unsigned char *, unitemp_val)); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++c; ++uc; } *c = 0; #else (*ss)->operator>>(temp_val); #endif OTL_STR_TO_BIGINT(temp_val, l); } else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif #endif break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&"); #endif #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR) { otl_var_desc *var_desc = describe_next_out_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_bigint_str_size]; (*ss)->operator>>(temp_val); OTL_STR_TO_BIGINT(temp_val, l); } else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif #endif break; } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) l = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_bigint_str_size]; _i64toa(l, temp_str, 10); OTL_TRACE_WRITE(temp_str, "operator >>", "BIGINT&") } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_WRITE(l, "operator >>", "BIGINT&") #endif inc_next_ov(); return *this; } #endif #if defined(OTL_UBIGINT) otl_stream &operator>>(OTL_UBIGINT &l) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&"); #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator>>(l); #else (*io)->operator>>(l); #endif break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&"); #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(l); #else (*ss)->operator>>(l); #endif break; } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) l = OTL_SCAST(OTL_UBIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_ubigint_str_size]; _ui64toa(l, temp_str, 10); OTL_TRACE_WRITE(temp_str, "operator >>", "UBIGINT&") } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_WRITE(l, "operator >>", "UBIGINT&") #endif inc_next_ov(); return *this; } #endif OTL_GTGT_OPERATOR_2(float,otl_var_float); OTL_GTGT_OPERATOR_2(double,otl_var_double); otl_stream &operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_long_string&"); #endif (*io)->operator>>(s); break; case otl_odbc_select_stream: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_long_string&"); #endif (*ss)->operator>>(s); break; } OTL_TRACE_WRITE(" string length: " << s.len(), "operator >>", "otl_long_string&") inc_next_ov(); return *this; } #if defined(OTL_STREAM_CUSTOM_CHAR_LTLT_OPERATORS) OTL_STREAM_CUSTOM_CHAR_LTLT_OPERATORS #else otl_stream &operator<<(const char c) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(c); break; case otl_odbc_select_stream: (*ss)->operator<<(c); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } OTL_TRACE_READ("'" << c << "'", "operator <<", "char"); inc_next_iov(); return *this; } otl_stream &operator<<(const unsigned char c) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("'" << c << "'", "operator <<", "unsigned char"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(c); break; case otl_odbc_select_stream: (*ss)->operator<<(c); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_UNICODE) otl_stream &operator<<(const OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, s) << "\"", "operator <<", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(OTL_RCAST(const unsigned char *, s)); break; case otl_odbc_select_stream: (*ss)->operator<<(OTL_RCAST(const unsigned char *, s)); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } otl_stream &operator<<(const OTL_UNICODE_CHAR_TYPE c) OTL_THROWS_OTL_EXCEPTION { OTL_UNICODE_CHAR_TYPE s[2]; s[0] = c; s[1] = 0; (*this) << s; return *this; } #endif #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) otl_stream &operator<<(OTL_STD_STRING_VIEW_CLASS s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS) OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_THIRD_PARTY_STRING_VIEW_CLASS"); #else OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_STD_STRING_VIEW_CLASS"); #endif switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(s); break; case otl_odbc_select_stream: (*ss)->operator<<(s); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) otl_stream &operator<<(const OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_STRING_CONTAINER&"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(s); break; case otl_odbc_select_stream: (*ss)->operator<<(s); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_UNICODE_STRING_TYPE) otl_stream &operator<<(const OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s.c_str() << "\"", "operator <<", "OTL_UNICODE_STRING_TYPE&"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(s); break; case otl_odbc_select_stream: (*ss)->operator<<(s); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)) otl_stream &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS) OTL_TRACE_READ("\"" << s.data() << "\"", "operator <<", "OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS"); #else OTL_TRACE_READ("\"" << s.data() << "\"", "operator <<", "OTL_STD_UNICODE_STRING_VIEW_CLASS"); #endif switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(s); break; case otl_odbc_select_stream: (*ss)->operator<<(s); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if !defined(OTL_UNICODE) otl_stream &operator<<(const char *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s << "\"", "operator <<", "char*"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(s); break; case otl_odbc_select_stream: (*ss)->operator<<(s); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template otl_stream &operator<<(const std::array& s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array&"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(s); break; case otl_odbc_select_stream: (*ss)->operator<<(s); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE) template otl_stream &operator<<(const std::array& s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array&"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(s); break; case otl_odbc_select_stream: (*ss)->operator<<(s); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif otl_stream &operator<<(const unsigned char *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(OTL_UNICODE) OTL_TRACE_READ("\"" << OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, s) << "\"", "operator <<", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*"); #else OTL_TRACE_READ("\"" << s << "\"", "operator <<", "unsigned char*"); #endif switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(s); break; case otl_odbc_select_stream: (*ss)->operator<<(s); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #define OTL_LTLT_OPERATOR_2(T,T_type) \ otl_stream &operator<<(const T v) OTL_THROWS_OTL_EXCEPTION { \ last_oper_was_read_op = false; \ reset_end_marker(); \ OTL_TRACE_READ(v, "operator <<", #T); \ switch (shell->stream_type) { \ case otl_odbc_no_stream: \ break; \ case otl_odbc_io_stream: \ OTL_OPERATOR_1(io,v,T,T_type,<<); \ break; \ case otl_odbc_select_stream: \ OTL_OPERATOR_1(ss,v,T,T_type,<<); \ if (!(*ov) && (*ss)->get_sl()) \ create_var_desc(); \ break; \ } \ inc_next_iov(); \ return *this; \ } OTL_LTLT_OPERATOR_2(int,otl_var_int); #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) otl_stream &operator<<(const OTL_NUMERIC_TYPE_1 &n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_numeric_type_1_str_size]; OTL_NUMERIC_TYPE_1_TO_STR(n, temp_str); OTL_TRACE_READ(temp_str, "operator <<", OTL_NUMERIC_TYPE_1_ID) } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_READ(n, "operator <<", OTL_NUMERIC_TYPE_1_ID); #endif switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR) { otl_var_desc *var_desc = describe_next_in_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_1_str_size]; OTL_NUMERIC_TYPE_1_TO_STR(n, temp_val); #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_1_str_size]; OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*c) { *uc = OTL_SCAST(OTL_CHAR, *c); ++c; ++uc; } *uc = 0; (*io)->operator<<(OTL_RCAST(const unsigned char *, unitemp_val)); #else (*io)->operator<<(temp_val); #endif } else { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif #endif break; case otl_odbc_select_stream: #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR) { otl_var_desc *var_desc = describe_next_in_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_1_str_size]; OTL_NUMERIC_TYPE_1_TO_STR(n, temp_val); (*ss)->operator<<(temp_val); } else { #if 1 #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif #endif if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) otl_stream &operator<<(const OTL_NUMERIC_TYPE_2 &n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_numeric_type_2_str_size]; OTL_NUMERIC_TYPE_2_TO_STR(n, temp_str); OTL_TRACE_READ(temp_str, "operator <<", OTL_NUMERIC_TYPE_2_ID) } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_READ(n, "operator <<", OTL_NUMERIC_TYPE_2_ID); #endif switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR) { otl_var_desc *var_desc = describe_next_in_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_2_str_size]; OTL_NUMERIC_TYPE_2_TO_STR(n, temp_val); #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_2_str_size]; OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*c) { *uc = OTL_SCAST(OTL_CHAR, *c); ++c; ++uc; } *uc = 0; (*io)->operator<<(OTL_RCAST(const unsigned char *, unitemp_val)); #else (*io)->operator<<(temp_val); #endif } else { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif #endif break; case otl_odbc_select_stream: #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR) { otl_var_desc *var_desc = describe_next_in_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_2_str_size]; OTL_NUMERIC_TYPE_2_TO_STR(n, temp_val); (*ss)->operator<<(temp_val); } else { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif #endif if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) otl_stream &operator<<(const OTL_NUMERIC_TYPE_3 &n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_numeric_type_3_str_size]; OTL_NUMERIC_TYPE_3_TO_STR(n, temp_str); OTL_TRACE_READ(temp_str, "operator <<", OTL_NUMERIC_TYPE_3_ID) } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_READ(n, "operator <<", OTL_NUMERIC_TYPE_3_ID); #endif switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR) { otl_var_desc *var_desc = describe_next_in_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_3_str_size]; OTL_NUMERIC_TYPE_3_TO_STR(n, temp_val); #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_3_str_size]; OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*c) { *uc = OTL_SCAST(OTL_CHAR, *c); ++c; ++uc; } *uc = 0; (*io)->operator<<(OTL_RCAST(const unsigned char *, unitemp_val)); #else (*io)->operator<<(temp_val); #endif } else { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif #endif break; case otl_odbc_select_stream: #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR) { otl_var_desc *var_desc = describe_next_in_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_numeric_type_3_str_size]; OTL_NUMERIC_TYPE_3_TO_STR(n, temp_val); (*ss)->operator<<(temp_val); } else { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif } } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif #endif if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_BIGINT) otl_stream &operator<<(const OTL_BIGINT n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_bigint_str_size]; _i64toa(n, temp_str, 10); OTL_TRACE_READ(temp_str, "operator <<", "BIGINT") } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_READ(n, "operator <<", "BIGINT"); #endif switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR) { otl_var_desc *var_desc = describe_next_in_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_bigint_str_size]; OTL_BIGINT_TO_STR(n, temp_val); #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_bigint_str_size]; OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*c) { *uc = OTL_SCAST(OTL_CHAR, *c); ++c; ++uc; } *uc = 0; (*io)->operator<<(OTL_RCAST(const unsigned char *, unitemp_val)); #else (*io)->operator<<(temp_val); #endif } else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif #endif break; case otl_odbc_select_stream: #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR) { otl_var_desc *var_desc = describe_next_in_var(); if (var_desc) { if (var_desc->ftype == otl_var_char) { char temp_val[otl_bigint_str_size]; OTL_BIGINT_TO_STR(n, temp_val); (*ss)->operator<<(temp_val); } else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif } } #else #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif #endif if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_UBIGINT) otl_stream &operator<<(const OTL_UBIGINT n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) // VC ++ { char temp_str[otl_ubigint_str_size]; _ui64toa(n, temp_str, 10); OTL_TRACE_READ(temp_str, "operator <<", "UBIGINT") } #elif !defined(_MSC_VER) && defined(OTL_TRACE_LEVEL) OTL_TRACE_READ(n, "operator <<", "UBIGINT"); #endif switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*io)->operator<<(n); #else (*io)->operator<<(n); #endif break; case otl_odbc_select_stream: #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif OTL_LTLT_OPERATOR_2(unsigned int,otl_var_unsigned_int); OTL_LTLT_OPERATOR_2(short int,otl_var_short); OTL_LTLT_OPERATOR_2(long int,otl_var_long_int); OTL_LTLT_OPERATOR_2(float,otl_var_float); OTL_LTLT_OPERATOR_2(double,otl_var_double); otl_stream &operator<<(OTL_NULL_PARM n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("NULL", "operator <<", "otl_null&"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(n); break; case otl_odbc_select_stream: (*ss)->operator<<(n); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } otl_stream &operator<<(const otl_long_string &d) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ(" len= " << d.len(), "operator <<", "otl_long_string&"); switch (shell->stream_type) { case otl_odbc_no_stream: break; case otl_odbc_io_stream: (*io)->operator<<(d); break; case otl_odbc_select_stream: (*ss)->operator<<(d); if (!(*ov) && (*ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_stream &operator=(const otl_stream &) = delete; otl_stream(const otl_stream &) = delete; #if !defined(OTL_STREAM_NO_PRIVATE_BOOL_OPERATORS) otl_stream &operator>>(bool &) = delete; otl_stream &operator<<(const bool) = delete; #endif #if !defined(OTL_STREAM_NO_PRIVATE_UNSIGNED_LONG_OPERATORS) otl_stream &operator>>(unsigned long int &) = delete; otl_stream &operator<<(const unsigned long int) = delete; #endif private: #else otl_stream &operator=(const otl_stream &) { return *this; } otl_stream(const otl_stream &) : shell(nullptr), shell_pt(), connected(0), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr), next_ov_ndx(nullptr), override_(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0), last_oper_was_read_op(false), buf_size_(0) {} #if !defined(OTL_STREAM_NO_PRIVATE_BOOL_OPERATORS) otl_stream &operator>>(bool &) OTL_NO_THROW { return *this; } otl_stream &operator<<(const bool) OTL_NO_THROW { return *this; } #endif #if !defined(OTL_STREAM_NO_PRIVATE_UNSIGNED_LONG_OPERATORS) otl_stream &operator>>(unsigned long int &) OTL_NO_THROW { return *this; } otl_stream &operator<<(const unsigned long int) OTL_NO_THROW { return *this; } #endif #endif }; #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) inline bool operator!=(const otl_for_range_loop_odbc_stream_adapter& a1, const otl_for_range_loop_odbc_stream_adapter& /*a2*/){ return a1.str_!=nullptr && !a1.str_->eof(); } #endif inline otl_connect &operator>>(otl_connect &connect, otl_stream &s) { const char *cmd = connect.getCmd(); const char *invalid_cmd = "*** INVALID COMMAND ***"; if (!cmd) cmd = invalid_cmd; s.open(s.getBufSize(), cmd, connect); return connect; } #if (defined(OTL_STL) || defined(OTL_VALUE_TEMPLATE_ON)) && \ defined(OTL_VALUE_TEMPLATE) template inline otl_stream &operator<<(otl_stream &s, const otl_value &var) OTL_THROWS_OTL_EXCEPTION { if (var.is_null()) s << otl_null(); else s << var.v; return s; } template inline otl_stream &operator<< (otl_stream &s, const otl_compact_value &var) OTL_THROWS_OTL_EXCEPTION { if (var.is_null()) s << otl_null(); else s << var.v; return s; } template inline otl_stream &operator>>(otl_stream &s, otl_value &var) OTL_THROWS_OTL_EXCEPTION { s>>var.v; if(s.is_null()) var.set_null(true); else var.set_null(false); return s; } template inline otl_stream &operator>> (otl_stream &s, otl_compact_value &var) OTL_THROWS_OTL_EXCEPTION { s>>var.v; if(s.is_null()) var.set_null(true); else var.set_null(false); return s; } #endif class otl_nocommit_stream : public otl_stream { public: otl_nocommit_stream() OTL_NO_THROW : otl_stream() { set_commit(0); } otl_nocommit_stream(const otl_stream_buffer_size_type arr_size, const char *sqlstm, otl_connect &db, const int implicit_select = otl_explicit_select) OTL_THROWS_OTL_EXCEPTION: otl_stream(arr_size, sqlstm, db, implicit_select) { set_commit(0); } void open(otl_stream_buffer_size_type arr_size, const char *sqlstm, otl_connect &db, const int implicit_select = otl_explicit_select) OTL_THROWS_OTL_EXCEPTION { otl_stream::open(arr_size, sqlstm, db, implicit_select); set_commit(0); } }; inline otl_stream &endr(otl_stream &s) { s.check_end_of_row(); return s; } OTL_ODBC_NAMESPACE_END #endif // ==================== OTL-Adapter for Oracle 8 ===================== #if defined(OTL_ORA8) #if defined(__STDC__) #define OTL_STDC_DEFINED #else #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wreserved-id-macro" #endif #define __STDC__ 1 // making OCI function prototypes show up in oci.h #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306) #pragma clang diagnostic pop #endif #endif #if defined(OTL_ORA_TEXT_ON) #define text OTL_ORA_TEXT #endif #include #if !defined(OTL_ORA_DOES_NOT_UNDEF_MIN_MAX) #if defined(min) #undef min #endif #if defined(max) #undef max #endif #endif #define OTL_UTF8_BYTES_PER_CHAR (4) #if defined(OTL_ORA8_PROC) extern "C" { #include } #endif OTL_ORA8_NAMESPACE_BEGIN const int inVarChar2 = 1; const int inNumber = 2; const int inLong = 8; const int inRowId = 104; const int inDate = 12; const int inRaw = 23; const int inLongRaw = 24; const int inChar = 96; #if defined(OTL_ORA10G) || defined(OTL_ORA10G_R2) const int inBFloat = SQLT_IBFLOAT; const int inBDouble = SQLT_IBDOUBLE; #endif const int inMslabel = 105; const int inUserDefinedType = 108; const int inRef = 111; const int inCLOB = 112; const int inBLOB = 113; #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) const int inTimestamp = SQLT_TIMESTAMP; const int inTimestamp_TZ = SQLT_TIMESTAMP_TZ; const int inTimestamp_LTZ = SQLT_TIMESTAMP_LTZ; const int inIntervalYM = SQLT_INTERVAL_YM; const int inIntervalDS = SQLT_INTERVAL_DS; #endif const int extVarChar2 = 1; const int extNumber = 2; const int extInt = 3; const int extFloat = 4; #if defined(OTL_ORA_MAP_STRINGS_TO_CHARZ) const int extCChar = 97; #else const int extCChar = 5; #endif const int extVarNum = 6; const int extLong = 8; const int extVarChar = 9; const int extRowId = 11; const int extDate = 12; const int extVarRaw = 15; const int extRaw = extVarRaw; const int extLongRaw = 24; const int extUInt = 68; const int extLongVarChar = 94; const int extLongVarRaw = 95; const int extChar = 96; const int extCharZ = 97; const int extMslabel = 105; const int extCLOB = inCLOB; const int extBLOB = inBLOB; #if (defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) && \ !defined(OTL_ORA_LEGACY_NUMERIC_TYPES) const int extBFloat = SQLT_BFLOAT; const int extBDouble = SQLT_BDOUBLE; #endif #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) const int extTimestamp = SQLT_TIMESTAMP; const int extTimestamp_TZ = SQLT_TIMESTAMP_TZ; const int extTimestamp_LTZ = SQLT_TIMESTAMP_LTZ; #endif #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) typedef otl_datetime otl_time0; #else typedef otl_oracle_date otl_time0; #endif class otl_exc { public: unsigned char msg[1000]; int code; char sqlstate[32]; #if defined(OTL_EXCEPTION_ENABLE_ERROR_OFFSET) int error_offset; #endif #if defined(OTL_EXTENDED_EXCEPTION) char **msg_arr; char **sqlstate_arr; int *code_arr; int arr_len; #endif enum { disabled = 0, enabled = 1 }; otl_exc() : msg(), code(0), sqlstate() #if defined(OTL_EXCEPTION_ENABLE_ERROR_OFFSET) , error_offset(-1) #endif #if defined(OTL_EXTENDED_EXCEPTION) , msg_arr(nullptr), sqlstate_arr(nullptr), code_arr(nullptr), arr_len(0) #endif { sqlstate[0] = 0; msg[0] = 0; } #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) && \ !defined(OTL_EXTENDED_EXCEPTION) otl_exc(const otl_exc &) = default; #endif virtual ~otl_exc() {} void init(const char *amsg, const int acode) { OTL_STRCPY_S(OTL_RCAST(char *, msg), sizeof(msg), amsg); code = acode; #if defined(OTL_EXCEPTION_ENABLE_ERROR_OFFSET) error_offset = -1; #endif #if defined(OTL_EXTENDED_EXCEPTION) msg_arr = nullptr; sqlstate_arr = nullptr; code_arr = nullptr; arr_len = 0; #endif } }; class otl_cur; class otl_var; class otl_conn { private: friend class otl_cur; friend class otl_var; OCIEnv *envhp; // OCI environment handle OCIServer *srvhp; // OCI Server handle OCIError *errhp; // OCI Error handle OCISvcCtx *svchp; // OCI Service context handle OCISession *authp; // OCI Session handle int auto_commit; int extern_lda; int attached; int in_session; int char_set_; int session_begin_count; int session_mode_; int ext_cred; int last_status; char *xa_server_external_name; char *xa_server_internal_name; #if defined(OTL_ORA_OCI_ENV_CREATE) bool threaded_mode; #endif #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) int lob_prefetch_size; #endif #if defined(OTL_ORA_SDO_GEOMETRY) OCIType *geometryTDO; #endif public: enum bigint_type { #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) var_bigint = otl_var_bigint, bigint_size = sizeof(OTL_BIGINT) #elif defined(OTL_BIGINT) && defined(OTL_ORA_MAP_BIGINT_TO_LONG) var_bigint = otl_var_long_int, bigint_size = sizeof(long) #else var_bigint = otl_var_char, bigint_size = otl_bigint_str_size #endif }; enum ubigint_type { #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) var_ubigint = otl_var_ubigint, ubigint_size = sizeof(OTL_UBIGINT) #else var_ubigint = otl_var_char, ubigint_size = otl_ubigint_str_size #endif }; #if defined(OTL_ORA_OCI_ENV_CREATE) void set_threaded_mode(const bool athreaded_mode) { threaded_mode = athreaded_mode; } #endif #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) OTL_NODISCARD int set_lob_prefetch_size(const int prefetch_size = 0) { lob_prefetch_size = prefetch_size; ub4 temp_size = OTL_SCAST(ub4, prefetch_size); int status = 0; status = OCIAttrSet(OTL_RCAST(dvoid *, authp), OTL_SCAST(ub4, OCI_HTYPE_SESSION), OTL_RCAST(dvoid *, &temp_size), 0, OCI_ATTR_DEFAULT_LOBPREFETCH_SIZE, errhp); if (status != OCI_SUCCESS) return 0; else return 1; } OTL_NODISCARD int get_lob_prefetch_size() const { return lob_prefetch_size; } #endif void cleanup(void) { (void)session_end(); (void)server_detach(); } OTL_NODISCARD int get_session_begin_count() const { return session_begin_count; } OTL_NODISCARD int get_extern_lda() const { return extern_lda; } OTL_NODISCARD int get_last_status() const { return last_status; } OTL_NODISCARD int get_auto_commit() const { return auto_commit; } OTL_NODISCARD OCIEnv *get_envhp() { return envhp; } OTL_NODISCARD OCIError* get_errhp() { return errhp; } void set_svchp(OCISvcCtx* x) { svchp = x; } void set_srvhp(OCIServer* x) { srvhp = x; } void set_authp(OCISession* x) { authp = x; } OTL_NODISCARD OCISvcCtx *get_svchp() { return svchp; } OTL_NODISCARD OCIServer *get_srvhp() { return srvhp; } OTL_NODISCARD OCISession *get_authp() { return authp; } OTL_NODISCARD int get_char_set() const { return char_set_; } OTL_NODISCARD int get_connection_type(void) { return 0; } #if !defined(OTL_ORA_OCI_ENV_CREATE) OTL_NODISCARD static int initialize(const int threaded_mode = 0) { int status; int mode; if (threaded_mode) mode = OCI_THREADED; else mode = OCI_DEFAULT; status = OCIInitialize(OTL_SCAST(ub4, mode), #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) nullptr, #else OTL_RCAST(dvoid *, 0), #endif nullptr, nullptr, nullptr); if (status != OCI_SUCCESS) return 0; else return 1; #else OTL_NODISCARD static int initialize(const int /*threaded_mode*/) { return 1; #endif } #if defined(OTL_ORA_SDO_GEOMETRY) OTL_NODISCARD OCIType* getGeometryTDO(){ return geometryTDO; } #endif otl_conn() : envhp(nullptr), srvhp(nullptr), errhp(nullptr), svchp(nullptr), authp(nullptr), auto_commit(0), extern_lda(0), attached(0), in_session(0), char_set_(SQLCS_IMPLICIT), session_begin_count(0), session_mode_(OCI_DEFAULT), ext_cred(0), last_status(OCI_SUCCESS), xa_server_external_name(nullptr), xa_server_internal_name(nullptr) #if defined(OTL_ORA_OCI_ENV_CREATE) , threaded_mode(false) #endif #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) , lob_prefetch_size(0) #endif #if defined(OTL_ORA_SDO_GEOMETRY) , geometryTDO(nullptr) #endif { } #if defined(OTL_ORA_OCI_ENV_CREATE) void set_connect_mode(bool mode) { threaded_mode = mode; } #endif void set_char_set(const int char_set) { char_set_ = char_set; } void set_xa_server_external_name(const char *name) { if (xa_server_external_name) { delete[] xa_server_external_name; xa_server_external_name = nullptr; } size_t len = strlen(name) + 1; xa_server_external_name = new char[len]; OTL_STRCPY_S(xa_server_external_name, len, name); } void set_xa_server_internal_name(const char *name) { if (xa_server_internal_name) { delete[] xa_server_internal_name; xa_server_internal_name = nullptr; } size_t len = strlen(name) + 1; xa_server_internal_name = new char[len]; OTL_STRCPY_S(xa_server_internal_name, len, name); } void delete_xa_strings(void) { if (xa_server_external_name) { delete[] xa_server_external_name; xa_server_external_name = nullptr; } if (xa_server_internal_name) { delete[] xa_server_internal_name; xa_server_internal_name = nullptr; } } virtual ~otl_conn() { delete_xa_strings(); } void set_timeout(const int /*atimeout*/ = 0) {} void set_cursor_type(const int /*acursor_type*/ = 0) {} OTL_NODISCARD int cancel(void) { int status; status = OCIBreak(srvhp, errhp); if (status) return 0; else return 1; } OTL_NODISCARD int server_attach(const char *tnsname) { int &status = last_status; envhp = nullptr; srvhp = nullptr; errhp = nullptr; svchp = nullptr; authp = nullptr; extern_lda = 0; attached = 0; in_session = 0; session_begin_count = 0; #if !defined(OTL_ORA_OCI_ENV_CREATE) status = OCIEnvInit(OTL_RCAST(OCIEnv **, &envhp), OCI_DEFAULT, 0, nullptr); #else status = OCIEnvCreate(OTL_RCAST(OCIEnv **, &envhp), #if defined(OTL_ORA_OCI_ENV_CREATE_MODE) OTL_ORA_OCI_ENV_CREATE_MODE, #else threaded_mode ? OCI_THREADED : OCI_DEFAULT, #endif nullptr, nullptr, nullptr, nullptr, 0, nullptr); #endif if (status) return 0; #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_errhp = &errhp; #endif status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_errhp), #else OTL_RCAST(dvoid **, &errhp), #endif OCI_HTYPE_ERROR, 0, nullptr); if (status) return 0; #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_srvhp = &srvhp; #endif status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_srvhp), #else OTL_RCAST(dvoid **, &srvhp), #endif OCI_HTYPE_SERVER, 0, nullptr); if (status) return 0; #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_svchp = &svchp; #endif status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_svchp), #else OTL_RCAST(dvoid **, &svchp), #endif OCI_HTYPE_SVCCTX, 0, nullptr); if (status) return 0; status = OCIServerAttach( srvhp, errhp, tnsname == nullptr ? OTL_RCAST(text *, OTL_CCAST(char *, "")) : OTL_RCAST(text *, OTL_CCAST(char *, tnsname)), tnsname == nullptr ? 0 : OTL_SCAST(sb4, strlen(OTL_CCAST(char *, tnsname))), 0); if (status) return 0; status = OCIAttrSet(OTL_RCAST(dvoid *, svchp), OCI_HTYPE_SVCCTX, OTL_RCAST(dvoid *, srvhp), 0, OCI_ATTR_SERVER, OTL_RCAST(OCIError *, errhp)); if (status) return 0; if (xa_server_external_name != nullptr && xa_server_internal_name != nullptr) { status = OCIAttrSet(OTL_RCAST(dvoid *, srvhp), OCI_HTYPE_SERVER, OTL_RCAST(dvoid *, xa_server_external_name), 0, OCI_ATTR_EXTERNAL_NAME, errhp); if (status) return 0; status = OCIAttrSet(OTL_RCAST(dvoid *, srvhp), OCI_HTYPE_SERVER, OTL_RCAST(dvoid *, xa_server_internal_name), 0, OCI_ATTR_INTERNAL_NAME, errhp); if (status) return 0; } #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_authp = &authp; #endif status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_authp), #else OTL_RCAST(dvoid **, &authp), #endif OTL_SCAST(ub4, OCI_HTYPE_SESSION), 0, nullptr); if (status) return 0; attached = 1; return 1; } OTL_NODISCARD int session_begin(const int aauto_commit) { int &status = last_status; int cred_type; if (!attached) return 0; if (session_begin_count == 0) return 0; if (ext_cred) cred_type = OCI_CRED_EXT; else cred_type = OCI_CRED_RDBMS; status = OCISessionBegin(svchp, errhp, authp, OTL_SCAST(unsigned, cred_type), OTL_SCAST(ub4, session_mode_)); if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) return 0; in_session = 1; auto_commit = aauto_commit; ++session_begin_count; return 1; } OTL_NODISCARD int session_begin(const char *userid, const char *password, const int aauto_commit, const int session_mode = OCI_DEFAULT, OCISession* authp2 = nullptr) { int &status = last_status; int cred_type; OCISession* authp1 = authp; if (authp2) authp1 = authp2; if (!attached) return 0; if (userid[0] == 0 && password[0] == 0) { ext_cred = 1; cred_type = OCI_CRED_EXT; } else { ext_cred = 0; cred_type = OCI_CRED_RDBMS; status = OCIAttrSet(OTL_RCAST(dvoid *, authp1), OTL_SCAST(ub4, OCI_HTYPE_SESSION), OTL_RCAST(dvoid *, OTL_CCAST(char *, userid)), OTL_SCAST(ub4, strlen(OTL_CCAST(char *, userid))), OTL_SCAST(ub4, OCI_ATTR_USERNAME), errhp); if (status) return 0; status = OCIAttrSet(OTL_RCAST(dvoid *, authp1), OTL_SCAST(ub4, OCI_HTYPE_SESSION), OTL_RCAST(dvoid *, OTL_CCAST(char *, password)), OTL_SCAST(ub4, strlen(OTL_CCAST(char *, password))), OTL_SCAST(ub4, OCI_ATTR_PASSWORD), errhp); if (status) return 0; } session_mode_ = session_mode; status = OCISessionBegin(svchp, errhp, authp1, OTL_SCAST(unsigned, cred_type), OTL_SCAST(ub4, session_mode_)); if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO) return 0; status = OCIAttrSet( OTL_RCAST(dvoid *, svchp), OTL_SCAST(ub4, OCI_HTYPE_SVCCTX), OTL_RCAST(dvoid *, authp1), 0, OTL_SCAST(ub4, OCI_ATTR_SESSION), errhp); if (status)return 0; #if defined(OTL_ORA_SDO_GEOMETRY) OCIParam *paramp = nullptr; OCIRef *type_ref = nullptr; OCIDescribe *dschp = nullptr; void* temp_ptr2=OTL_RCAST(void*, &dschp); status = OCIHandleAlloc( OTL_RCAST(dvoid *, envhp), OTL_RCAST(dvoid**,temp_ptr2), OTL_SCAST(ub4, OCI_HTYPE_DESCRIBE), 0, nullptr); if(status)return 0; text objptr[] = "MDSYS.SDO_GEOMETRY"; size_t objp_len = strlen(OTL_RCAST(char*,objptr)); status = OCIDescribeAny( svchp, errhp, OTL_RCAST(dvoid *, objptr), OTL_SCAST(ub4, objp_len), OTL_SCAST(ub1, OCI_OTYPE_NAME), OTL_SCAST(ub1, OCI_DEFAULT), OTL_SCAST(ub1, OCI_PTYPE_TYPE), dschp); if(status)return 0; status = OCIAttrGet( OTL_RCAST(dvoid *, dschp), OTL_SCAST(ub4, OCI_HTYPE_DESCRIBE), OTL_RCAST(dvoid *, ¶mp), nullptr, OTL_SCAST(ub4, OCI_ATTR_PARAM), errhp); if(status)return 0; status = OCIAttrGet( OTL_RCAST(dvoid *, paramp), OTL_SCAST(ub4, OCI_DTYPE_PARAM), OTL_RCAST(dvoid *, &type_ref), nullptr, OTL_SCAST(ub4, OCI_ATTR_REF_TDO), errhp); if(status)return 0; #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif void* temp_ptr=OTL_RCAST(void*,&geometryTDO); status = OCIObjectPin( envhp, errhp, type_ref, nullptr, /*OCIPinOpt::*/OCI_PIN_ANY, OTL_SCAST(ub2, OCI_DURATION_SESSION), /*OCILockOpt::*/OCI_LOCK_NONE, OTL_RCAST(dvoid**,temp_ptr)); if(status)return 0; #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif #endif in_session = 1; auto_commit = aauto_commit; ++session_begin_count; return 1; } #if defined(OTL_ORA8I) || defined(OTL_ORA9I) OTL_NODISCARD int change_password(const char *user_name, const char *password, const char *new_password) { int &status = last_status; OCIAttrSet(OTL_RCAST(dvoid *, svchp), OTL_SCAST(ub4, OCI_HTYPE_SVCCTX), OTL_RCAST(dvoid *, authp), 0, OTL_SCAST(ub4, OCI_ATTR_SESSION), errhp); status = OCIPasswordChange( svchp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, user_name)), OTL_SCAST(ub4, strlen(user_name)), OTL_RCAST(text *, OTL_CCAST(char *, password)), OTL_SCAST(ub4, strlen(password)), OTL_RCAST(text *, OTL_CCAST(char *, new_password)), OTL_SCAST(ub4, strlen(new_password)), OCI_AUTH); if (status) return 0; else return 1; } #endif OTL_NODISCARD int server_detach(void) { int rc = 0; if (attached) { OCIServerDetach(srvhp, errhp, OTL_SCAST(ub4, OCI_DEFAULT)); rc = 1; } if (authp != nullptr) OCIHandleFree(OTL_RCAST(dvoid *, authp), OTL_SCAST(ub4, OCI_HTYPE_SESSION)); if (errhp != nullptr) OCIHandleFree(OTL_RCAST(dvoid *, errhp), OTL_SCAST(ub4, OCI_HTYPE_ERROR)); if (svchp != nullptr) OCIHandleFree(OTL_RCAST(dvoid *, svchp), OTL_SCAST(ub4, OCI_HTYPE_SVCCTX)); if (srvhp != nullptr) OCIHandleFree(OTL_RCAST(dvoid *, srvhp), OTL_SCAST(ub4, OCI_HTYPE_SERVER)); if (envhp != nullptr) OCIHandleFree(OTL_RCAST(dvoid *, envhp), OTL_SCAST(ub4, OCI_HTYPE_ENV)); auto_commit = 0; attached = 0; in_session = 0; envhp = nullptr; srvhp = nullptr; errhp = nullptr; svchp = nullptr; authp = nullptr; delete_xa_strings(); return rc; } OTL_NODISCARD int session_end(void) { int &status = last_status; if (!in_session) return 0; status = OCISessionEnd(svchp, errhp, authp, 0); if (status) return 0; in_session = 0; auto_commit = 0; return 1; } OTL_NODISCARD int auto_commit_on(void) { auto_commit = 1; return 1; } OTL_NODISCARD int auto_commit_off(void) { auto_commit = 0; return 1; } OTL_NODISCARD int rlogon(const char *connect_str, const int aauto_commit) { int status; char username[256]; char passwd[256]; char tnsname[1024]; char *tnsname_ptr = nullptr; char *username_ptr = username; char *c = OTL_CCAST(char *, connect_str); char *passwd_ptr = passwd; char prev_c = ' '; auto_commit = aauto_commit; username[0] = 0; passwd[0] = 0; tnsname[0] = 0; while (*c && *c != '/' && (OTL_SCAST(unsigned, username_ptr - username) < sizeof(username) - 1)) { *username_ptr = *c; ++c; ++username_ptr; } *username_ptr = 0; if (*c == '/') ++c; prev_c = ' '; while (*c && !(*c == '@' && prev_c != '\\') && (OTL_SCAST(unsigned, passwd_ptr - passwd) < sizeof(passwd) - 1)) { if (prev_c == '\\') --passwd_ptr; *passwd_ptr = *c; prev_c = *c; ++c; ++passwd_ptr; } *passwd_ptr = 0; if (*c == '@') { ++c; tnsname_ptr = tnsname; while (*c && (OTL_SCAST(unsigned, tnsname_ptr - tnsname) < sizeof(tnsname) - 1)) { *tnsname_ptr = *c; ++c; ++tnsname_ptr; } *tnsname_ptr = 0; } envhp = nullptr; srvhp = nullptr; errhp = nullptr; svchp = nullptr; authp = nullptr; extern_lda = 0; attached = 0; in_session = 0; OTL_TRACE_RLOGON_ORA8(0x1, "otl_connect", "rlogon", tnsname, username, passwd, auto_commit) status = server_attach(tnsname); if (!status) return 0; status = session_begin(username, passwd, aauto_commit); if (!status) return 0; return 1; } OTL_NODISCARD int ext_logon(OCIEnv *a_envhp, OCISvcCtx *a_svchp, const int aauto_commit = 0) { int &status = last_status; envhp = a_envhp; svchp = a_svchp; errhp = nullptr; srvhp = nullptr; authp = nullptr; extern_lda = 1; auto_commit = aauto_commit; #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_errhp = &errhp; #endif status = OCIHandleAlloc(OTL_RCAST(dvoid *, envhp), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_errhp), #else OTL_RCAST(dvoid **, &errhp), #endif OCI_HTYPE_ERROR, 0, nullptr); if (status) return 0; return 1; } OTL_NODISCARD int logoff(void) { int rc; if (extern_lda) { OCIHandleFree(OTL_RCAST(dvoid *, errhp), OTL_SCAST(ub4, OCI_HTYPE_ERROR)); envhp = nullptr; svchp = nullptr; errhp = nullptr; extern_lda = 0; } else { rc = session_end(); if (!rc) return 0; rc = server_detach(); if (!rc) return 0; } auto_commit = 0; return 1; } void error(otl_exc &exception_struct) { sb4 errcode; size_t len; OCIErrorGet(errhp ? OTL_RCAST(dvoid *, errhp) : OTL_RCAST(dvoid*, envhp), OTL_SCAST(ub4, 1), nullptr, &errcode, OTL_RCAST(text *, exception_struct.msg), OTL_SCAST(ub4, sizeof(exception_struct.msg)), (errhp ? OCI_HTYPE_ERROR : OCI_HTYPE_ENV)); exception_struct.code = errcode; len = strlen(OTL_RCAST(char *, exception_struct.msg)); exception_struct.msg[len] = 0; } OTL_NODISCARD int commit(void) { last_status = OCITransCommit(svchp, errhp, OTL_SCAST(ub4, OCI_DEFAULT)); return !last_status; } #if defined(OTL_ORA10G_R2) OTL_NODISCARD int commit_nowait(void) { #if defined(OCI_TRANS_WRITENOWAIT) last_status = OCITransCommit(svchp, errhp, OTL_SCAST(ub4, OCI_TRANS_WRITENOWAIT)); #else last_status = OCITransCommit(svchp, errhp, OTL_SCAST(ub4, 0x00000008)); #endif return !last_status; } #endif OTL_NODISCARD int rollback(void) { last_status = OCITransRollback(svchp, errhp, OTL_SCAST(ub4, OCI_DEFAULT)); return !last_status; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_conn(const otl_conn &) = delete; otl_conn &operator=(const otl_conn &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_conn(otl_conn &&) = delete; otl_conn &operator=(otl_conn &&) = delete; #endif private: #else otl_conn(const otl_conn &) : envhp(nullptr), srvhp(nullptr), errhp(nullptr), svchp(nullptr), authp(nullptr), auto_commit(0), extern_lda(0), attached(0), in_session(0), char_set_(SQLCS_IMPLICIT), session_begin_count(0), session_mode_(OCI_DEFAULT), ext_cred(0), last_status(OCI_SUCCESS), xa_server_external_name(nullptr), xa_server_internal_name(nullptr) #if defined(OTL_ORA_OCI_ENV_CREATE) , threaded_mode(false) #endif #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) , lob_prefetch_size(0) #endif { } otl_conn &operator=(const otl_conn &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_conn(otl_conn &&) : envhp(nullptr), srvhp(nullptr), errhp(nullptr), svchp(nullptr), authp(nullptr), auto_commit(0), extern_lda(0), attached(0), in_session(0), char_set_(SQLCS_IMPLICIT), session_begin_count(0), session_mode_(OCI_DEFAULT), ext_cred(0), last_status(OCI_SUCCESS), xa_server_external_name(nullptr), xa_server_internal_name(nullptr) #if defined(OTL_ORA_OCI_ENV_CREATE) , threaded_mode(false) #endif #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) , lob_prefetch_size(0) #endif { } otl_conn &operator=(otl_conn &&) { return *this; } #endif #endif }; class otl_cur0 { public: virtual ~otl_cur0() {} }; class otl_cur; class otl_inout_stream; class otl_refcur_stream; class otl_ref_select_stream; #if defined(OTL_ORA_SDO_GEOMETRY) struct oci_spatial_geometry{ bool isNull; unsigned int gtype; int srid; double x, y, z; STD_NAMESPACE_PREFIX vector eleminfo; STD_NAMESPACE_PREFIX vector ordinates; }; #endif class otl_var { private: friend class otl_cur; friend class otl_inout_stream; friend class otl_refcur_stream; friend class otl_ref_select_stream; ub1 *p_v; sb2 *p_ind; ub2 *p_rlen; ub2 *p_rcode; int ftype; int array_size; int elem_size; bool nls_flag; OCILobLocator **lob; #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) OCIDateTime **timestamp; #endif OCIStmt *cda; otl_conn *connect; ub1 *buf; int buf_len; int real_buf_len; int ext_buf_flag; int act_elem_size; ub4 max_tab_len; ub4 cur_tab_len; int pl_tab_flag; int lob_stream_flag; int vparam_type; otl_adapter_enum otl_adapter; bool lob_stream_mode; #if defined(OTL_UNICODE) sb4 unicode_var_len; #endif ub2 csid; #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8) ub1 csfrm; #endif ub4 read_blob_amt; ub4 total_read_blob_amt; bool charz_flag; bool select_stm_flag; #if defined(OTL_ORA_SDO_GEOMETRY) OCIType *oraOCIType; struct OCISDOPointObj{ OCINumber x; OCINumber y; OCINumber z; }; struct OCISDOGeometryObj{ OCINumber gtype; OCINumber srid; OCISDOPointObj point; OCIArray *elem_info; OCIArray *ordinates; }; struct OCISDOPointInd{ OCIInd _atomic; OCIInd x; OCIInd y; OCIInd z; }; struct OCISDOGeometryInd{ OCIInd _atomic; OCIInd gtype; OCIInd srid; OCISDOPointInd point; OCIInd elem_info; OCIInd ordinates; }; OCISDOGeometryObj **sdoobj; OCISDOGeometryInd **sdoind; bool needFree; #endif public: void set_total_read_blob_amt(const int new_total_read_blob_amt) { total_read_blob_amt = OTL_SCAST(ub4, new_total_read_blob_amt); } OTL_NODISCARD otl_adapter_enum get_otl_adapter() const { return otl_adapter; } OTL_NODISCARD OCIStmt *get_cda() { return cda; } OTL_NODISCARD OCIStmt **get_cda_ptr() { return &cda; } void set_nls_flag(const bool anls_flag) { nls_flag = anls_flag; } void set_lob_stream_mode(const bool alob_stream_mode) { lob_stream_mode = alob_stream_mode; } void set_vparam_type(const int avparam_type) { vparam_type = avparam_type; } void set_charz_flag(const bool acharz_flag) { charz_flag = acharz_flag; } #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif otl_var() : p_v(nullptr), p_ind(nullptr), p_rlen(nullptr), p_rcode(nullptr), ftype(0), array_size(0), elem_size(0), nls_flag(false), lob(nullptr), #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) timestamp(nullptr), #endif cda(nullptr), connect(nullptr), buf(nullptr), buf_len(0), real_buf_len(0), ext_buf_flag(0), act_elem_size(0), max_tab_len(0), cur_tab_len(0), pl_tab_flag(0), lob_stream_flag(0), vparam_type(-1), otl_adapter(OTL_ADAPTER_ENUM otl_ora8_adapter), lob_stream_mode(false), #if defined(OTL_UNICODE) unicode_var_len(0), #endif csid(0), #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8) csfrm(SQLCS_IMPLICIT), #endif read_blob_amt(0), total_read_blob_amt(0), charz_flag(false), select_stm_flag(false) #if defined(OTL_ORA_SDO_GEOMETRY) ,oraOCIType(nullptr) ,sdoobj(nullptr) ,sdoind(nullptr) #endif { } virtual ~otl_var() { if (ftype == otl_var_refcur && cda != nullptr) { OCIHandleFree(OTL_RCAST(dvoid *, cda), OCI_HTYPE_STMT); cda = nullptr; } if (ftype == otl_var_blob || (ftype == otl_var_clob && lob != nullptr)) { #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C) OCIArrayDescriptorFree(OTL_RCAST(dvoid**,lob), OTL_SCAST(ub4, OCI_DTYPE_LOB)); #else for (int i = 0; i < array_size; ++i) OCIDescriptorFree(OTL_RCAST(dvoid *, lob[i]), OTL_SCAST(ub4, OCI_DTYPE_LOB)); #endif } #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) if ((ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp || ((ftype == otl_var_ltz_timestamp) && timestamp != nullptr))) { ub4 dtype = 0; switch (ftype) { case otl_var_timestamp: dtype = OCI_DTYPE_TIMESTAMP; break; case otl_var_ltz_timestamp: dtype = OCI_DTYPE_TIMESTAMP_LTZ; break; case otl_var_tz_timestamp: dtype = OCI_DTYPE_TIMESTAMP_TZ; break; } #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C) OCIArrayDescriptorFree(OTL_RCAST(dvoid**,timestamp),dtype); #else for (int i = 0; i < array_size; ++i) OCIDescriptorFree(OTL_RCAST(dvoid *, timestamp[i]), dtype); #endif } #endif if(p_v) delete[] p_v; if(p_ind) delete[] p_ind; if(p_rlen) delete[] p_rlen; if(p_rcode) delete[] p_rcode; if (!ext_buf_flag) delete[] buf; #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(OTL_ORA_SDO_GEOMETRY) if(sdoobj){ if(needFree){ for(int i = 0;i < array_size;i++){ OCIObjectFree(connect->get_envhp(), connect->get_errhp(), OTL_RCAST(dvoid*, sdoobj[i]), OCI_OBJECTFREE_FORCE); } } delete[] sdoobj; } if(sdoind)delete[] sdoind; #endif #if defined(__clang__) #pragma clang diagnostic pop #endif } #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif OTL_NODISCARD int write_dt(void *trg, const void *src, const int #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) #else sz #endif ) { #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) OCIDateTime *trg_ptr = OTL_RCAST(OCIDateTime *, trg); otl_datetime *src_ptr = OTL_RCAST(otl_datetime *, OTL_CCAST(void *, src)); int rc = 0; if (ftype != otl_var_tz_timestamp) { rc = OCIDateTimeConstruct( connect->envhp, connect->errhp, trg_ptr, OTL_SCAST(sb2, src_ptr->year), OTL_SCAST(ub1, src_ptr->month), OTL_SCAST(ub1, src_ptr->day), OTL_SCAST(ub1, src_ptr->hour), OTL_SCAST(ub1, src_ptr->minute), OTL_SCAST(ub1, src_ptr->second), OTL_SCAST(ub4, otl_to_fraction(OTL_SCAST(unsigned int, src_ptr->fraction), src_ptr->frac_precision)), nullptr, 0); } else { int tz_hour = src_ptr->tz_hour; int tz_minute = src_ptr->tz_minute; char tz_str[60]; char *tzc = otl_itoa(tz_hour, tz_str); *tzc = ':'; ++tzc; tzc = otl_itoa(tz_minute, tzc); size_t tz_len = OTL_SCAST(size_t, tzc - tz_str); rc = OCIDateTimeConstruct( connect->envhp, connect->errhp, trg_ptr, OTL_SCAST(sb2, src_ptr->year), OTL_SCAST(ub1, src_ptr->month), OTL_SCAST(ub1, src_ptr->day), OTL_SCAST(ub1, src_ptr->hour), OTL_SCAST(ub1, src_ptr->minute), OTL_SCAST(ub1, src_ptr->second), OTL_SCAST(ub4, otl_to_fraction(OTL_SCAST(unsigned int, src_ptr->fraction), src_ptr->frac_precision)), OTL_RCAST(text *, tz_str), tz_len); } if (rc != 0) return 0; return 1; #else memcpy(trg, src, OTL_SCAST(size_t, sz)); return 1; #endif } OTL_NODISCARD int read_dt(void *trg, const void *src, const int #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) #else sz #endif ) { #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) OCIDateTime *src_ptr = OTL_RCAST(OCIDateTime *, OTL_CCAST(void *, src)); otl_datetime *trg_ptr = OTL_RCAST(otl_datetime *, OTL_CCAST(void *, trg)); sb2 year; ub1 month, day, hour, minute, sec; ub4 fsec; sb1 tz_hour; sb1 tz_minute; int rc = OCIDateTimeGetDate(connect->envhp, connect->errhp, src_ptr, &year, &month, &day); if (rc != 0) return 0; rc = OCIDateTimeGetTime(connect->envhp, connect->errhp, src_ptr, &hour, &minute, &sec, &fsec); if (rc != 0) return 0; trg_ptr->year = year; trg_ptr->month = month; trg_ptr->day = day; trg_ptr->hour = hour; trg_ptr->minute = minute; trg_ptr->second = sec; trg_ptr->fraction = otl_from_fraction(fsec, trg_ptr->frac_precision); trg_ptr->tz_hour = 0; trg_ptr->tz_minute = 0; if (ftype == otl_var_tz_timestamp || ftype == otl_var_ltz_timestamp) { rc = OCIDateTimeGetTimeZoneOffset(connect->envhp, connect->errhp, src_ptr, &tz_hour, &tz_minute); if (rc != 0) return 0; trg_ptr->tz_hour = tz_hour; trg_ptr->tz_minute = tz_minute; } return 1; #else memcpy(trg, src, OTL_SCAST(size_t, sz)); return 1; #endif } #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 1000) #if !defined(__has_warning) || __has_warning("-Wmisleading-indentation") #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmisleading-indentation" #endif #endif OTL_NODISCARD int actual_elem_size(void) { return act_elem_size; } void init(const bool aselect_stm_flag, const int aftype, int &aelem_size, const otl_stream_buffer_size_type aarray_size, const void *connect_struct = nullptr, const int apl_tab_flag = 0 #if defined(OTL_ORA_SDO_GEOMETRY) ,OCIType* oraOCIType_ =nullptr #endif ) { int i; ub4 lobEmpty = 0; select_stm_flag = aselect_stm_flag; connect = OTL_RCAST(otl_conn *, OTL_CCAST(void *, connect_struct)); ftype = aftype; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) if (ftype == otl_var_nchar) { ftype = otl_var_char; nls_flag = true; } else if (ftype == otl_var_nclob) { ftype = otl_var_clob; nls_flag = true; } #endif pl_tab_flag = apl_tab_flag; act_elem_size = aelem_size; #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) if ((ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp || ftype == otl_var_ltz_timestamp) && apl_tab_flag) act_elem_size = sizeof(otl_oracle_date); #endif #if defined(OTL_ORA_SDO_GEOMETRY) if(ftype == otl_var_sdo_geometry){ array_size = aarray_size; elem_size = aelem_size; oraOCIType = oraOCIType_; lob = nullptr; p_v = nullptr; p_ind = nullptr; p_rlen = nullptr; p_rcode = nullptr; if(oraOCIType){ sdoind = new OCISDOGeometryInd*[OTL_SCAST(size_t, array_size)]; sdoobj = new OCISDOGeometryObj*[OTL_SCAST(size_t, array_size)]; p_ind = new sb2[OTL_SCAST(size_t, array_size)]; for(size_t j = 0;j < OTL_SCAST(size_t, array_size);j++){ sdoind[j] = nullptr; sdoobj[j] = nullptr; p_ind[j] = 0; } }else{ sdoind = nullptr; sdoobj = nullptr; } }else #endif if (ftype == otl_var_refcur) { array_size = aarray_size; elem_size = 1; #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_cda = &cda; #endif OCIHandleAlloc(OTL_RCAST(dvoid *, connect->get_envhp()), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_cda), #else OTL_RCAST(dvoid **, &cda), #endif OCI_HTYPE_STMT, 0, nullptr); #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) } else if ((ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp || ftype == otl_var_ltz_timestamp) && !apl_tab_flag) { array_size = aarray_size; elem_size = sizeof(OCIDateTime *); act_elem_size = elem_size; timestamp = new OCIDateTime *[OTL_SCAST(size_t,array_size)]; p_v = OTL_RCAST(ub1 *, timestamp); p_ind = new sb2[OTL_SCAST(size_t,array_size)]; p_rlen = new ub2[OTL_SCAST(size_t,array_size)]; p_rcode = new ub2[OTL_SCAST(size_t,array_size)]; for (i = 0; i < array_size; ++i) { p_ind[i] = OTL_SCAST(short, elem_size); p_rlen[i] = OTL_SCAST(unsigned short, elem_size); p_rcode[i] = 0; } if (connect != nullptr) { otl_datetime dt; ub4 dtype = 0; switch (ftype) { case otl_var_timestamp: dtype = OCI_DTYPE_TIMESTAMP; break; case otl_var_ltz_timestamp: dtype = OCI_DTYPE_TIMESTAMP_LTZ; break; case otl_var_tz_timestamp: dtype = OCI_DTYPE_TIMESTAMP_TZ; break; } #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C) OCIArrayDescriptorAlloc (OTL_RCAST(dvoid*,connect->envhp), OTL_RCAST(dvoid**,×tamp[0]), dtype, OTL_SCAST(ub4,array_size), 0, nullptr); #endif for (i = 0; i < array_size; ++i) { #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C) #else OCIDescriptorAlloc(OTL_RCAST(dvoid *, connect->envhp), OTL_RCAST(dvoid **, ×tamp[i]), dtype, 0, nullptr); #endif (void)write_dt(timestamp[i], &dt, 1); } } else timestamp = nullptr; #endif } else if (ftype == otl_var_blob || ftype == otl_var_clob) { array_size = aarray_size; elem_size = aelem_size; lob = new OCILobLocator *[OTL_SCAST(size_t,array_size)]; p_v = OTL_RCAST(ub1 *, lob); p_ind = new sb2[OTL_SCAST(size_t,array_size)]; p_rlen = nullptr; p_rcode = nullptr; #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C) if (connect != nullptr){ OCIArrayDescriptorAlloc (OTL_RCAST(dvoid*,connect->envhp), OTL_RCAST(dvoid**,&lob[0]), OTL_SCAST(ub4, OCI_DTYPE_LOB), OTL_SCAST(ub4,array_size), 0, nullptr); } #endif if (connect != nullptr) { for (i = 0; i < array_size; ++i) { #if defined(OTL_ORA11G)||defined(OTL_ORA11G_R2)||defined(OTL_ORA12C) #else OCIDescriptorAlloc(OTL_RCAST(dvoid *, connect->get_envhp()), OTL_RCAST(dvoid **, &lob[i]), OTL_SCAST(ub4, OCI_DTYPE_LOB), 0, nullptr); #endif lobEmpty = 0; OCIAttrSet(OTL_RCAST(dvoid *, lob[i]), OCI_DTYPE_LOB, OTL_RCAST(dvoid *, &lobEmpty), 0, OCI_ATTR_LOBEMPTY, OTL_RCAST(OCIError *, connect->get_errhp())); } } else lob = nullptr; } else { if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long) { elem_size = aelem_size + OTL_SCAST(int, sizeof(sb4)); array_size = 1; } else if (ftype == otl_var_raw) { elem_size = aelem_size + OTL_SCAST(int, sizeof(short int)); array_size = aarray_size; } else { elem_size = aelem_size; array_size = aarray_size; #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) if ((ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp || ftype == otl_var_ltz_timestamp) && apl_tab_flag) { elem_size = sizeof(otl_oracle_date); aelem_size = elem_size; // sending feedback back to the template class } #endif } #if defined(OTL_UNICODE) if (ftype == otl_var_char) { unsigned int unicode_buffer_size = OTL_SCAST(unsigned int, OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size) * sizeof(OTL_WCHAR)); p_v = new ub1[unicode_buffer_size]; memset(p_v, 0, unicode_buffer_size); } else if (ftype == otl_var_varchar_long) { unsigned int unicode_buffer_size = OTL_SCAST(unsigned, elem_size); p_v = new ub1[unicode_buffer_size]; memset(p_v, 0, unicode_buffer_size); } else { p_v = new ub1 [OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size)]; memset(p_v, 0, OTL_SCAST(size_t, elem_size) * OTL_SCAST(unsigned, array_size)); } #elif defined(OTL_ORA_UTF8) if (ftype == otl_var_char) { unsigned int buffer_size = OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size); if (select_stm_flag) buffer_size *= OTL_UTF8_BYTES_PER_CHAR; // 3 bytes per UTF8 char on // SELECT by default p_v = new ub1[buffer_size]; memset(p_v, 0, buffer_size); } else if (ftype == otl_var_varchar_long) { p_v = new ub1[OTL_SCAST(size_t,elem_size)]; memset(p_v, 0, OTL_SCAST(size_t, elem_size)); } else { p_v = new ub1 [OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size)]; memset(p_v, 0, OTL_SCAST(size_t, elem_size) * OTL_SCAST(unsigned, array_size)); } #else p_v = new ub1[OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size)]; memset(p_v, 0, OTL_SCAST(unsigned, elem_size) * OTL_SCAST(unsigned, array_size)); #endif p_ind = new sb2[OTL_SCAST(size_t,array_size)]; p_rlen = new ub2[OTL_SCAST(size_t,array_size)]; p_rcode = new ub2[OTL_SCAST(size_t,array_size)]; if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long || ftype == otl_var_raw) { if (aelem_size > otl_short_int_max) p_ind[0] = 0; else p_ind[0] = OTL_SCAST(short, aelem_size); p_rcode[0] = 0; } else { for (i = 0; i < array_size; ++i) { #if defined(OTL_UNICODE) if (ftype == otl_var_char) { p_ind[i] = OTL_SCAST(sb2, elem_size * OTL_SCAST(short, sizeof(OTL_WCHAR))); p_rlen[i] = OTL_SCAST(ub2, elem_size * OTL_SCAST(short, sizeof(OTL_WCHAR))); p_rcode[i] = 0; } else { p_ind[i] = OTL_SCAST(short, elem_size); p_rlen[i] = OTL_SCAST(unsigned short, elem_size); p_rcode[i] = 0; } #else if (ftype == otl_var_raw) { p_ind[i] = OTL_SCAST(short, elem_size); p_rlen[i] = OTL_SCAST(unsigned short, elem_size); p_rcode[i] = 0; } else { if (elem_size > otl_short_int_max) p_ind[i] = 0; else { p_ind[i] = OTL_SCAST(short, elem_size); p_rlen[i] = OTL_SCAST(unsigned short, elem_size); } p_rcode[i] = 0; } #endif } } } max_tab_len = OTL_SCAST(ub4, array_size); cur_tab_len = 0; } void set_pl_tab_len(const int apl_tab_len) { max_tab_len = OTL_SCAST(ub4, array_size); cur_tab_len = OTL_SCAST(ub4, apl_tab_len); } OTL_NODISCARD int get_pl_tab_len(void) { return OTL_SCAST(int, cur_tab_len); } OTL_NODISCARD int get_max_pl_tab_len(void) { return OTL_SCAST(int, max_tab_len); } OTL_NODISCARD int get_blob_len(const int ndx, int &alen) { ub4 blen = 0; int rc; alen = 0; rc = OCILobGetLength(connect->get_svchp(), connect->get_errhp(), lob[ndx], &blen); alen = OTL_SCAST(int, blen); if (rc != OCI_SUCCESS) return 0; return 1; } OTL_NODISCARD int is_blob_initialized(const int ndx, int &is_init) { int rc; is_init = 0; rc = OCILobLocatorIsInit(connect->get_envhp(), connect->get_errhp(), lob[ndx], &is_init); if (rc != OCI_SUCCESS) return 0; else return 1; } OTL_NODISCARD int get_blob(const int ndx, unsigned char *abuf, const int buf_size, int &len) { int byte_buf_size = buf_size; #if defined(OTL_UNICODE) if (ftype == otl_var_clob) byte_buf_size = OTL_SCAST(int, buf_size * OTL_SCAST(int, sizeof(OTL_CHAR))); #endif ub4 amt = OTL_SCAST(ub4, byte_buf_size); ub4 offset = 1; int rc; #if defined(OTL_UNICODE) if (ftype == otl_var_clob || ftype == otl_var_nclob) memset(OTL_RCAST(void *, abuf), 0, OTL_SCAST(size_t, buf_size)); #endif int is_init = 0; rc = OCILobLocatorIsInit(connect->get_envhp(), connect->get_errhp(), lob[ndx], &is_init); if (rc != 0) return 0; if (!is_init) { len = 0; return 1; } #if defined(OTL_UNICODE) if (ftype == otl_var_clob) csid = OTL_UNICODE_ID; else csid = 0; #else csid = 0; #endif do { rc = OCILobRead( connect->get_svchp(), connect->get_errhp(), lob[ndx], &amt, offset, OTL_RCAST(dvoid *, abuf + offset - 1), OTL_SCAST(ub4, byte_buf_size) - offset + 1, nullptr, nullptr, csid, OTL_SCAST(ub1, nls_flag ? SQLCS_NCHAR : connect->get_char_set())); offset += amt; } while (rc == OCI_NEED_DATA); len = OTL_SCAST(int, offset) - 1; if (rc != OCI_SUCCESS) { len = 0; return 0; } return 1; } void set_lob_stream_flag(const int flg = 1) { lob_stream_flag = flg; } OTL_NODISCARD int close_lob(void) { #if defined(OTL_ORA8I) || defined(OTL_ORA9I) int rc; boolean flag = 0; rc = OCILobIsOpen(connect->get_svchp(), connect->get_errhp(), lob[0], &flag); if (rc != OCI_SUCCESS) return 0; if (flag != TRUE) return 1; rc = OCILobClose(connect->get_svchp(), connect->get_errhp(), lob[0]); if (rc != OCI_SUCCESS) return 0; #endif return 1; } void close_temporary_lob(void) { #ifdef OTL_ORA_CUSTOM_FREE_TEMP_LOB OCILobFreeTemporary(connect->svchp, connect->errhp, lob[0]); #endif } OTL_NODISCARD int put_blob(void) { if ((ftype != otl_var_clob && ftype != otl_var_blob) || lob_stream_flag || buf == nullptr || buf_len == 0) return 1; int rc; int byte_buf_len = buf_len; #if defined(OTL_UNICODE) if (ftype == otl_var_clob) byte_buf_len = OTL_SCAST(int, buf_len * OTL_SCAST(int, sizeof(OTL_CHAR))); #endif ub4 amt = OTL_SCAST(ub4, buf_len); ub4 offset = 1; #if defined(OTL_UNICODE) if (ftype == otl_var_clob) csid = OTL_UNICODE_ID; else csid = 0; #else csid = 0; #endif rc = OCILobWrite( connect->get_svchp(), connect->get_errhp(), lob[0], &amt, offset, OTL_RCAST(dvoid *, buf), OTL_SCAST(ub4, byte_buf_len), OCI_ONE_PIECE, nullptr, nullptr, csid, OTL_SCAST(ub1, nls_flag ? SQLCS_NCHAR : connect->get_char_set())); if (rc != 0) return 0; return 1; } OTL_NODISCARD int read_blob(otl_long_string &s, const int andx, int &aoffset, int alob_len) { ub4 byte_buf_size = OTL_SCAST(ub4, s.get_buf_size()); #if defined(OTL_UNICODE) if (ftype == otl_var_clob) byte_buf_size = OTL_SCAST(ub4, byte_buf_size * sizeof(OTL_CHAR)); #endif ub4 &amt = read_blob_amt; amt = 0; if (aoffset == 1) total_read_blob_amt = 0; ub4 &offset = total_read_blob_amt; if (offset == 0) offset = 1; int rc; int is_init = 0; rc = OCILobLocatorIsInit(connect->get_envhp(), connect->get_errhp(), lob[andx], &is_init); if (rc != OCI_SUCCESS) return 0; if (!is_init) { s.set_len(0); return 1; } #if defined(OTL_UNICODE) if (ftype == otl_var_clob) csid = OTL_UNICODE_ID; else csid = 0; #else csid = 0; #endif #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) if (connect->get_lob_prefetch_size() > 0) { ub4 pom_blen = 0; rc = OCILobGetLength(connect->get_svchp(), connect->get_errhp(), lob[andx], &pom_blen); if (rc != OCI_SUCCESS) return 0; amt = pom_blen; } #endif rc = OCILobRead( connect->get_svchp(), connect->get_errhp(), lob[andx], &amt, offset, OTL_RCAST(dvoid *, s.v), OTL_SCAST(ub4, byte_buf_size), nullptr, nullptr, csid, OTL_SCAST(ub1, nls_flag ? SQLCS_NCHAR : connect->get_char_set())); #if defined(OTL_UNICODE) if (ftype == otl_var_clob && aoffset > 1 && amt == byte_buf_size) amt /= OTL_SCAST(ub4, sizeof(OTL_CHAR)); #endif #if defined(OTL_ORA_UTF8) switch (rc) { case OCI_SUCCESS: s.set_len(OTL_SCAST(int, amt)); offset += amt; if (ftype == otl_var_blob) aoffset += s.len(); else aoffset = alob_len + 1; return 1; case OCI_NEED_DATA: s.set_len(OTL_SCAST(int, amt)); offset += amt; if (ftype == otl_var_blob) aoffset += s.len(); else aoffset = 2; return 1; case OCI_ERROR: default: s.set_len(0); return 0; } #else switch (rc) { case OCI_SUCCESS: if (aoffset == 1) s.set_len(alob_len); else s.set_len(alob_len - aoffset + 1); break; case OCI_NEED_DATA: s.set_len(OTL_SCAST(int, amt)); break; case OCI_ERROR: s.set_len(0); break; } if (rc == OCI_NEED_DATA || rc == OCI_SUCCESS) { aoffset += s.len(); return 1; } else return 0; #endif } OTL_NODISCARD int write_blob(const otl_long_string &s, const int alob_len, int &aoffset, otl_cur0 & /* cur */) { if (!lob_stream_flag) return 1; int rc; int byte_s_length = s.len(); #if defined(OTL_UNICODE) if (ftype == otl_var_clob) byte_s_length = OTL_SCAST(int, s.len() * OTL_SCAST(int, sizeof(OTL_CHAR))); #endif ub4 offset = OTL_SCAST(ub4, aoffset); ub4 amt = 0; ub1 mode; if (aoffset == 1 && alob_len > s.len()) mode = OCI_FIRST_PIECE; else if (aoffset == 1 && alob_len <= s.len()) { mode = OCI_ONE_PIECE; amt = OTL_SCAST(ub4, s.len()); } else if ((aoffset - 1) + s.len() < alob_len) mode = OCI_NEXT_PIECE; else mode = OCI_LAST_PIECE; #if defined(OTL_UNICODE) if (ftype == otl_var_clob) csid = OTL_UNICODE_ID; else csid = 0; #else csid = 0; #endif if (mode == OCI_FIRST_PIECE || mode == OCI_ONE_PIECE) { rc = OCILobTrim(connect->get_svchp(), connect->get_errhp(), lob[0], 0); if (rc != OCI_SUCCESS) return 0; } if (alob_len == 0) return 1; rc = OCILobWrite( connect->get_svchp(), connect->get_errhp(), lob[0], OTL_RCAST(ub4 *, &amt), offset, OTL_RCAST(dvoid *, s.v), OTL_SCAST(ub4, byte_s_length), mode, nullptr, nullptr, csid, OTL_SCAST(ub1, nls_flag ? SQLCS_NCHAR : connect->get_char_set())); if (rc == OCI_NEED_DATA || rc == OCI_SUCCESS || rc == OCI_SUCCESS_WITH_INFO) { aoffset += s.len(); return 1; } return 0; } OTL_NODISCARD int save_blob(const unsigned char *abuf, const int len, const int extern_buffer_flag) { if (extern_buffer_flag) { if (buf != nullptr && !ext_buf_flag) { delete[] buf; buf = nullptr; } ext_buf_flag = 1; buf_len = len; real_buf_len = len; buf = OTL_CCAST(unsigned char *, abuf); } else { if (!ext_buf_flag && buf != nullptr && real_buf_len >= len) { ext_buf_flag = 0; buf_len = len; #if defined(OTL_UNICODE) memcpy(buf, abuf, OTL_SCAST(size_t, buf_len) * sizeof(OTL_CHAR)); #else memcpy(buf, abuf, OTL_SCAST(size_t, buf_len)); #endif } else { if (buf != nullptr && !ext_buf_flag) { delete[] buf; buf = nullptr; } ext_buf_flag = 0; buf_len = len; real_buf_len = len; #if defined(OTL_UNICODE) buf = new ub1[OTL_SCAST(size_t, buf_len) * sizeof(OTL_CHAR)]; memcpy(buf, abuf, OTL_SCAST(size_t, buf_len) * sizeof(OTL_CHAR)); #else buf = new ub1[OTL_SCAST(size_t,buf_len)]; memcpy(buf, abuf, OTL_SCAST(size_t, buf_len)); #endif } } return 1; } #if defined(OTL_ORA_SDO_GEOMETRY) OTL_NODISCARD bool getValue(OCINumber *num, unsigned int &value){ int status = OCINumberToInt(connect->get_errhp(), num, sizeof(unsigned int), OCI_NUMBER_UNSIGNED, OTL_RCAST(dvoid*, &value)); if(status) return false; else return true; } OTL_NODISCARD bool getValue(OCINumber *num, int &value){ int status = OCINumberToInt(connect->get_errhp(), num, sizeof(int), OCI_NUMBER_SIGNED, OTL_RCAST(dvoid*, &value)); if(status) return false; else return true; } OTL_NODISCARD bool getValue(OCINumber *num, double &value){ int status = OCINumberToReal(connect->get_errhp(), num, sizeof(double), OTL_RCAST(dvoid*, &value)); if(status) return false; else return true; } OTL_NODISCARD bool getArraySize(OCIColl *coll, int &nSize){ int status = OCICollSize(connect->get_envhp(), connect->get_errhp(), coll, OTL_RCAST(sb4*, &nSize)); if(status) return false; else return true; } OTL_NODISCARD int read_geometry(oci_spatial_geometry& geometry, int ndx){ if(!sdoobj || !sdoind || !sdoobj[ndx] || !sdoind[ndx]){ geometry.isNull = true; return 0; } #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif if(sdoind[ndx]->_atomic == OCI_IND_NULL){ geometry.isNull = true; return 1; } #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif if(!getValue(&sdoobj[ndx]->gtype, geometry.gtype)){ geometry.isNull = true; return 0; } int iType = geometry.gtype % 100; if(iType == 0){ geometry.isNull = true; return 0; } #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif if(sdoind[ndx]->srid == OCI_IND_NOTNULL){ if(!getValue(&sdoobj[ndx]->srid, geometry.srid)){ geometry.isNull = true; return 0; } #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif } #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif if(sdoind[ndx]->point.x == OCI_IND_NOTNULL){ if(!getValue(&sdoobj[ndx]->point.x, geometry.x)){ geometry.isNull = true; return 0; } } if(sdoind[ndx]->point.y == OCI_IND_NOTNULL){ if(!getValue(&sdoobj[ndx]->point.y, geometry.y)){ geometry.isNull = true; return 0; } } if(sdoind[ndx]->point.z == OCI_IND_NOTNULL){ if(!getValue(&sdoobj[ndx]->point.z, geometry.z)){ geometry.isNull = true; return 0; } } if(sdoind[ndx]->elem_info == OCI_IND_NOTNULL){ int nElems; if(!getArraySize(sdoobj[ndx]->elem_info, nElems)){ geometry.isNull = true; return 0; } #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif geometry.eleminfo.resize(OTL_SCAST(size_t, nElems)); #if defined(OTL_ORA10G_R2) { uword nelems = OTL_SCAST(uword, nElems); std::vector exists(OTL_SCAST(size_t, nElems)); std::vector numbers(OTL_SCAST(size_t, nElems)); int result = OCICollGetElemArray(connect->get_envhp(), connect->get_errhp(), sdoobj[ndx]->elem_info, OTL_SCAST(sb4, 0), &exists[0], OTL_RCAST(void**, &numbers[0]), nullptr, &nelems); if(result || !exists[0]){ geometry.isNull = true; return 0; } for(unsigned int i = 0; i < nelems; i++){ if(!getValue(numbers[i], geometry.eleminfo[i])){ geometry.isNull = true; return 0; } } } #else for(int i = 0; i < nElems;i++){ boolean exists(true); OCINumber* numbers; int result = OCICollGetElem(connect->get_envhp(), connect->get_errhp(), sdoobj[ndx]->elem_info, i, &exists, (void**)&numbers, 0); if(result || !exists){ geometry.isNull = true; return 0; } if(!getValue(numbers, geometry.eleminfo[i])){ geometry.isNull = true; return 0; } } #endif } #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif if(sdoind[ndx]->ordinates == OCI_IND_NOTNULL){ int nOrds; if(!getArraySize(sdoobj[ndx]->ordinates, nOrds)){ geometry.isNull = true; return 0; } geometry.ordinates.resize(OTL_SCAST(size_t,nOrds)); #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif #if defined(OTL_ORA10G_R2) { std::vector exists(OTL_SCAST(size_t,nOrds)); std::vector numbers(OTL_SCAST(size_t,nOrds)); uword nords = OTL_SCAST(uword,nOrds); int result = OCICollGetElemArray(connect->get_envhp(), connect->get_errhp(), sdoobj[ndx]->ordinates, OTL_SCAST(sb4, 0), &exists[0], OTL_RCAST(void**, &numbers[0]), nullptr, &nords); if(result != OCI_SUCCESS || !exists[0]){ geometry.isNull = true; return 0; } result = OCINumberToRealArray(connect->get_errhp(), OTL_CCAST(const OCINumber **,&numbers[0]), nords, sizeof(double), &geometry.ordinates[0]); if(result != OCI_SUCCESS){ geometry.isNull = true; return 0; } } #else for(int i = 0; i < nOrds;i++){ boolean exists(true); void* numbers; int result = OCICollGetElem(connect->get_envhp(), connect->get_errhp(), sdoobj[ndx]->ordinates, i, &exists, (void**)&numbers, 0); if(result || !exists){ geometry.isNull = true; return 0; } if(!getValue((OCINumber*)numbers, geometry.ordinates[i])){ geometry.isNull = true; return 0; } } #endif } geometry.isNull = false; return 1; } OTL_NODISCARD int write_geometry(const oci_spatial_geometry& g, int ndx){ sb4 n; int status = OCICollSize(connect->get_envhp(), connect->get_errhp(), sdoobj[ndx]->elem_info, &n); if(status)return 0; status = OCICollTrim(connect->get_envhp(), connect->get_errhp(), n, sdoobj[ndx]->elem_info); if(status)return 0; status = OCICollSize(connect->get_envhp(), connect->get_errhp(), sdoobj[ndx]->ordinates, &n); if(status)return 0; status = OCICollTrim(connect->get_envhp(), connect->get_errhp(), n, sdoobj[ndx]->ordinates); if(status)return 0; if(g.isNull){ #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif sdoind[ndx]->_atomic = OCI_IND_NULL; #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif }else{ #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif sdoind[ndx]->_atomic = OCI_IND_NOTNULL; sdoind[ndx]->gtype = OCI_IND_NOTNULL; sdoind[ndx]->srid = OCI_IND_NOTNULL; #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif status = OCINumberFromInt(connect->get_errhp(), OTL_RCAST(CONST dvoid*, &g.gtype), sizeof(unsigned int), OCI_NUMBER_UNSIGNED, &sdoobj[ndx]->gtype); if(status)return 0; status = OCINumberFromInt(connect->get_errhp(), OTL_RCAST(CONST dvoid*, &g.srid), sizeof(int), OCI_NUMBER_SIGNED, &sdoobj[ndx]->srid); if(status)return 0; if(g.gtype % 100 == 1){ #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif sdoind[ndx]->point._atomic = OCI_IND_NOTNULL; sdoind[ndx]->point.x = OCI_IND_NOTNULL; sdoind[ndx]->point.y = OCI_IND_NOTNULL; sdoind[ndx]->elem_info = OCI_IND_NULL; sdoind[ndx]->ordinates = OCI_IND_NULL; #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif status = OCINumberFromReal(connect->get_errhp(), OTL_RCAST(CONST dvoid*, &g.x), sizeof(double), &sdoobj[ndx]->point.x); if(status)return 0; status = OCINumberFromReal(connect->get_errhp(), OTL_RCAST(CONST dvoid*, &g.y), sizeof(double), &sdoobj[ndx]->point.y); if(status)return 0; if((g.gtype / 1000 % 10) == 3){ #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif sdoind[ndx]->point.z = OCI_IND_NOTNULL; #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif status = OCINumberFromReal(connect->get_errhp(), OTL_RCAST(CONST dvoid*, &g.z), sizeof(double), &sdoobj[ndx]->point.z); if(status)return 0; }else #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif sdoind[ndx]->point.z = OCI_IND_NULL; #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif }else{ #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif sdoind[ndx]->point._atomic = OCI_IND_NULL; sdoind[ndx]->elem_info = g.eleminfo.size() == 0 ? OCI_IND_NULL : OCI_IND_NOTNULL; sdoind[ndx]->ordinates = g.ordinates.size() == 0 ? OCI_IND_NULL : OCI_IND_NOTNULL; #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif for(std::size_t ind_elem = 0;ind_elem < g.eleminfo.size();ind_elem++){ OCINumber n2; status = OCINumberFromInt(connect->get_errhp(), OTL_RCAST(CONST dvoid*, &g.eleminfo[ind_elem]), sizeof(int), OCI_NUMBER_SIGNED, &n2); if(status)return 0; status = OCICollAppend(connect->get_envhp(), connect->get_errhp(), OTL_RCAST(CONST dvoid*, &n2), nullptr, sdoobj[ndx]->elem_info); if(status)return 0; } for(std::size_t ind_elem = 0;ind_elem < g.ordinates.size();ind_elem++){ OCINumber n2; status = OCINumberFromReal(connect->get_errhp(), OTL_RCAST(CONST dvoid*, &g.ordinates[ind_elem]), sizeof(double), &n2); if(status)return 0; status = OCICollAppend(connect->get_envhp(), connect->get_errhp(), OTL_RCAST(CONST dvoid*, &n2), nullptr, sdoobj[ndx]->ordinates); if(status)return 0; } } } return 1; } #endif void set_null(int ndx) { p_ind[ndx] = -1; } void set_not_null(int ndx, int pelem_size) { switch (ftype) { case otl_var_char: if (pelem_size > otl_short_int_max) p_ind[ndx] = 0; else p_ind[ndx] = OTL_SCAST(short, pelem_size); break; case otl_var_varchar_long: case otl_var_raw_long: p_ind[0] = 0; break; case otl_var_raw: if (pelem_size > otl_short_int_max) p_ind[ndx] = 0; else p_ind[ndx] = OTL_SCAST(short, pelem_size); break; case otl_var_clob: case otl_var_blob: if (lob_stream_flag == 0) { ub4 lobEmpty = 0; OCIAttrSet(OTL_RCAST(dvoid *, lob[ndx]), OCI_DTYPE_LOB, OTL_RCAST(dvoid *, &lobEmpty), 0, OCI_ATTR_LOBEMPTY, OTL_RCAST(OCIError *, connect->get_errhp())); } break; default: p_ind[ndx] = OTL_SCAST(short, pelem_size); break; } } void set_len(int len, int ndx) { if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long) { #if defined(OTL_UNICODE) if (ftype == otl_var_varchar_long) *OTL_RCAST(sb4 *, p_v) = len * OTL_SCAST(sb4, sizeof(OTL_CHAR)); else *OTL_RCAST(sb4 *, p_v) = len; #else *OTL_RCAST(sb4 *, p_v) = len; #endif } else p_rlen[ndx] = OTL_SCAST(unsigned short, len); } int get_len(int ndx) { if (ftype == otl_var_varchar_long || ftype == otl_var_raw_long) { if (p_ind[0] == -1) return 0; else { #if defined(OTL_UNICODE) #if defined(OTL_ORA_UNICODE_LONG_LENGTH_IN_BYTES) if (ftype == otl_var_varchar_long) return *OTL_RCAST(sb4 *, p_v); else return *OTL_RCAST(sb4 *, p_v); #else if (ftype == otl_var_varchar_long) return (*OTL_RCAST(sb4 *, p_v)) / sizeof(OTL_CHAR); else return *OTL_RCAST(sb4 *, p_v); #endif #else return *OTL_RCAST(sb4 *, p_v); #endif } } else return p_rlen[ndx]; } OTL_NODISCARD int is_null(int ndx) { return p_ind[ndx] == -1; } OTL_NODISCARD void *val(int ndx, int pelem_size) { switch (ftype) { #if defined(OTL_UNICODE) case otl_var_char: return OTL_RCAST( void *, &p_v[OTL_SCAST(unsigned, ndx * pelem_size) * sizeof(OTL_WCHAR)]); #endif #if defined(OTL_ORA_UTF8) case otl_var_char: if (select_stm_flag) return OTL_RCAST(void *, &p_v[OTL_SCAST(unsigned, ndx * pelem_size) * OTL_UTF8_BYTES_PER_CHAR]); else return OTL_RCAST(void *, &p_v[OTL_SCAST(unsigned, ndx * pelem_size)]); #endif case otl_var_raw: return OTL_RCAST( void *, &p_v[(OTL_SCAST(unsigned, ndx)) * (OTL_SCAST(unsigned, pelem_size) + sizeof(short int))]); case otl_var_varchar_long: case otl_var_raw_long: return OTL_RCAST(void *, p_v + sizeof(sb4)); #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) case otl_var_timestamp: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: if (!pl_tab_flag) return OTL_RCAST(void *, timestamp[ndx]); #endif default: return OTL_RCAST( void *, &p_v[OTL_SCAST(unsigned, ndx) * OTL_SCAST(unsigned, pelem_size)]); } } OTL_NODISCARD static int int2ext(int int_type) { switch (int_type) { case inVarChar2: return extCChar; case inNumber: return extFloat; case inLong: return extLongVarChar; case inRowId: return extCChar; #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) case inDate: return extTimestamp; case inTimestamp: return extTimestamp; case inTimestamp_TZ: return extTimestamp_TZ; case inTimestamp_LTZ: return extTimestamp_LTZ; case inIntervalYM: return extCChar; case inIntervalDS: return extCChar; #else case inDate: return extDate; #endif case inRaw: return extRaw; case inLongRaw: return extLongVarRaw; case inChar: return extCChar; #if defined(OTL_ORA10G) || defined(OTL_ORA10G_R2) #if defined(OTL_ORA_NATIVE_TYPES) && !defined(OTL_ORA_LEGACY_NUMERIC_TYPES) case inBFloat: return extBFloat; case inBDouble: return extBDouble; #else case inBFloat: return extFloat; case inBDouble: return extFloat; #endif #endif case inCLOB: return extCLOB; case inBLOB: return extBLOB; default: return otl_unsupported_type; } } OTL_NODISCARD static int datatype_size(int aftype, int maxsz, int int_type, int max_long_size) { switch (aftype) { case extCChar: switch (int_type) { #if defined(OTL_ORA_TIMESTAMP) case inIntervalYM: return 30; case inIntervalDS: return 30; #endif case inRowId: return 30; case inDate: return otl_oracle_date_size; case inRaw: return max_long_size; default: return maxsz + 1; } #if (defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) && \ defined(OTL_ORA_NATIVE_TYPES) && !defined(OTL_ORA_LEGACY_NUMERIC_TYPES) case extBFloat: case extBDouble: return sizeof(double); #endif case extLongVarChar: return max_long_size; case extLongVarRaw: return max_long_size; case extRaw: return maxsz; case extCLOB: return max_long_size; case extBLOB: return max_long_size; case extFloat: return sizeof(double); #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) case extDate: return sizeof(OCIDateTime *); case extTimestamp: case extTimestamp_TZ: case extTimestamp_LTZ: return sizeof(OCIDateTime *); #else case extDate: return otl_oracle_date_size; #endif default: return 0; } } static void map_ftype(otl_column_desc &desc, const int max_long_size, int &aftype, int &aelem_size, otl_select_struct_override &a_override, const int column_ndx, const int /*connection_type*/) { int ndx = a_override.find(column_ndx); if (ndx == -1) { aftype = int2ext(desc.dbtype); aelem_size = datatype_size(aftype, OTL_SCAST(int, desc.dbsize), desc.dbtype, max_long_size); switch (aftype) { #if (defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) && \ defined(OTL_ORA_NATIVE_TYPES) && !defined(OTL_ORA_LEGACY_NUMERIC_TYPES) case extBFloat: case extBDouble: if (a_override.get_all_mask() & otl_all_num2str) { aftype = otl_var_char; aelem_size = otl_num_str_size; } else aftype = otl_var_double; break; #endif case extCChar: aftype = otl_var_char; break; case extRaw: aftype = otl_var_raw; break; case extFloat: if (a_override.get_all_mask() & otl_all_num2str) { aftype = otl_var_char; aelem_size = otl_num_str_size; } else { #if defined(OTL_ORA_CUSTOM_MAP_NUMBER_ON_SELECT) OTL_ORA_CUSTOM_MAP_NUMBER_ON_SELECT(aftype, aelem_size, desc); #else aftype = otl_var_double; #endif } break; case extLongVarChar: aftype = otl_var_varchar_long; break; case extLongVarRaw: aftype = otl_var_raw_long; break; case extCLOB: aftype = otl_var_clob; break; case extBLOB: aftype = otl_var_blob; break; #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) case extDate: case extTimestamp: if (a_override.get_all_mask() & otl_all_date2str) { aftype = otl_var_char; aelem_size = otl_date_str_size; } else aftype = otl_var_timestamp; break; case extTimestamp_TZ: if (a_override.get_all_mask() & otl_all_date2str) { aftype = otl_var_char; aelem_size = otl_date_str_size; } else aftype = otl_var_tz_timestamp; break; case extTimestamp_LTZ: if (a_override.get_all_mask() & otl_all_date2str) { aftype = otl_var_char; aelem_size = otl_date_str_size; } else aftype = otl_var_ltz_timestamp; break; #else case extDate: if (a_override.get_all_mask() & otl_all_date2str) { aftype = otl_var_char; aelem_size = otl_date_str_size; } else aftype = otl_var_timestamp; break; #endif #if defined(OTL_ORA_SDO_GEOMETRY) case otl_unsupported_type: if(strcmp(desc.name_type, "SDO_GEOMETRY") == 0) { aftype = otl_var_sdo_geometry; aelem_size = max_long_size; } break; #endif } } else { aftype = a_override.get_col_type(ndx); switch (aftype) { #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) case otl_var_nchar: #endif case otl_var_char: aelem_size = a_override.get_col_size(ndx); break; case otl_var_raw: aelem_size = a_override.get_col_size(ndx); break; case otl_var_double: aelem_size = sizeof(double); break; case otl_var_float: aelem_size = sizeof(float); break; case otl_var_int: aelem_size = sizeof(int); break; #if defined(OTL_BIGINT) && defined(OTL_ORA11G_R2) case otl_var_bigint: aelem_size = sizeof(OTL_BIGINT); break; #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) case otl_var_ubigint: aelem_size = sizeof(OTL_UBIGINT); break; #endif case otl_var_unsigned_int: aelem_size = sizeof(unsigned); break; case otl_var_short: aelem_size = sizeof(short); break; case otl_var_long_int: aelem_size = sizeof(long); break; default: aelem_size = a_override.get_col_size(ndx); break; } } desc.otl_var_dbtype = aftype; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_var(const otl_var &) = delete; otl_var &operator=(const otl_var &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_var(otl_var &&) = delete; otl_var &operator=(otl_var &&) = delete; #endif private: #else otl_var(const otl_var &) : p_v(nullptr), p_ind(nullptr), p_rlen(nullptr), p_rcode(nullptr), ftype(0), array_size(0), elem_size(0), nls_flag(false), lob(nullptr), #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) timestamp(nullptr), #endif cda(nullptr), connect(nullptr), buf(nullptr), buf_len(0), real_buf_len(0), ext_buf_flag(0), act_elem_size(0), max_tab_len(0), cur_tab_len(0), pl_tab_flag(0), lob_stream_flag(0), vparam_type(-1), otl_adapter(OTL_ADAPTER_ENUM otl_ora8_adapter), lob_stream_mode(false), #if defined(OTL_UNICODE) unicode_var_len(0), #endif csid(0), #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8) csfrm(SQLCS_IMPLICIT), #endif read_blob_amt(0), total_read_blob_amt(0), charz_flag(false), select_stm_flag(false) { } otl_var &operator=(const otl_var &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_var(otl_var &&) : p_v(nullptr), p_ind(nullptr), p_rlen(nullptr), p_rcode(nullptr), ftype(0), array_size(0), elem_size(0), nls_flag(false), lob(nullptr), #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) timestamp(nullptr), #endif cda(nullptr), connect(nullptr), buf(nullptr), buf_len(0), real_buf_len(0), ext_buf_flag(0), act_elem_size(0), max_tab_len(0), cur_tab_len(0), pl_tab_flag(0), lob_stream_flag(0), vparam_type(-1), otl_adapter(OTL_ADAPTER_ENUM otl_ora8_adapter), lob_stream_mode(false), #if defined(OTL_UNICODE) unicode_var_len(0), #endif csid(0), #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8) csfrm(SQLCS_IMPLICIT), #endif read_blob_amt(0), total_read_blob_amt(0), charz_flag(false), select_stm_flag(false) { } otl_var &operator=(otl_var &&) { return *this; } #endif #endif }; class otl_sel; class otl_refcur_base_cursor; class otl_refcur_stream; class otl_ref_cursor; class otl_ref_select_stream; #if defined(OTL_ORA_SUBSCRIBE) class otl_subscriber; #endif class otl_cur : public otl_cur0 { private: #if defined(OTL_ORA_SUBSCRIBE) friend class otl_subscriber; #endif friend class otl_sel; friend class otl_refcur_base_cursor; friend class otl_refcur_stream; friend class otl_ref_cursor; friend class otl_ref_select_stream; OCIStmt *cda; // Statement handle OCIError *errhp; // Error handle bool extern_cda; int status; int eof_status; otl_conn *db; int straight_select; int pos_nbr; int commit_on_success; int last_param_data_token; int last_sql_param_data_status; int sql_param_data_count; bool canceled; int direct_exec_flag; int parse_only_flag; int stm_executed; bool batch_error_mode_; OCIError *errhndl_; OCIError *errhp2_; public: OTL_NODISCARD int get_number_of_errors_in_batch(int &rc) { rc = 1; ub4 num_errs = 0; sword oci_rc = OCIAttrGet(cda, OCI_HTYPE_STMT, &num_errs, nullptr, OCI_ATTR_NUM_DML_ERRORS, errhp); if (oci_rc != OCI_SUCCESS) { rc = 0; return 0; } else return OTL_SCAST(int, num_errs); } OTL_NODISCARD int get_error(const int ndx, int &dml_row_offset, otl_exc &exception_struct) { sword rc = OCI_SUCCESS; dml_row_offset = -1; exception_struct.code = 0; exception_struct.msg[0] = 0; ub4 row_offset = 0; sb4 errcode = 0; if (errhp2_ == nullptr) { #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_errhp2 = &errhp2_; #endif rc = OCIHandleAlloc(OTL_RCAST(dvoid *, db->get_envhp()), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_errhp2), #else OTL_RCAST(dvoid **, &errhp2_), #endif OCI_HTYPE_ERROR, 0, nullptr); if (rc != OCI_SUCCESS) return 0; } if (errhndl_ == nullptr) { #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_errhndl = &errhndl_; #endif rc = OCIHandleAlloc(OTL_RCAST(dvoid *, db->get_envhp()), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_errhndl), #else OTL_RCAST(dvoid **, &errhndl_), #endif OCI_HTYPE_ERROR, 0, nullptr); if (rc != OCI_SUCCESS) return 0; } #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_errhndl = &errhndl_; #endif rc = OCIParamGet(errhp, OCI_HTYPE_ERROR, errhp2_, #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_errhndl), #else OTL_RCAST(dvoid **, &errhndl_), #endif OTL_SCAST(ub4, ndx)); if (rc != OCI_SUCCESS) return 0; rc = OCIAttrGet(errhndl_, OCI_HTYPE_ERROR, &row_offset, nullptr, OCI_ATTR_DML_ROW_OFFSET, errhp2_); if (rc != OCI_SUCCESS) return 0; dml_row_offset = OTL_SCAST(int, row_offset); rc = OCIErrorGet(OTL_RCAST(dvoid *, errhndl_), OTL_SCAST(ub4, 1), nullptr, &errcode, OTL_RCAST(text *, exception_struct.msg), OTL_SCAST(ub4, sizeof(exception_struct.msg)), OCI_HTYPE_ERROR); if (rc != OCI_SUCCESS) { exception_struct.code = 0; exception_struct.msg[0] = 0; return 0; } exception_struct.code = errcode; return 1; } void set_batch_error_mode(const bool batch_error_mode = false) { batch_error_mode_ = batch_error_mode; } void set_canceled(const bool acanceld) { canceled = acanceld; } void reset_last_param_data_token() { last_param_data_token = 0; } void reset_last_sql_param_data_status() { last_sql_param_data_status = 0; } void reset_sql_param_data_count() { sql_param_data_count = 0; } otl_cur() : cda(nullptr), errhp(nullptr), extern_cda(false), status(0), eof_status(0), db(nullptr), straight_select(1), pos_nbr(0), commit_on_success(0), last_param_data_token(0), last_sql_param_data_status(0), sql_param_data_count(0), canceled(false), direct_exec_flag(0), parse_only_flag(0), stm_executed(0), batch_error_mode_(false), errhndl_(nullptr), errhp2_(nullptr) {} virtual ~otl_cur() {} void set_direct_exec(const int flag) { direct_exec_flag = flag; } void set_parse_only(const int flag) { parse_only_flag = flag; } ub4 rpc(void) { sb4 arpc; status = OCIAttrGet(OTL_RCAST(dvoid *, cda), OTL_SCAST(ub4, OCI_HTYPE_STMT), OTL_RCAST(dvoid *, &arpc), nullptr, OTL_SCAST(ub4, OCI_ATTR_ROW_COUNT), errhp); if (status) return 0; return OTL_SCAST(ub4, arpc); } OTL_NODISCARD int open(otl_conn &connect, otl_var *var = nullptr) { db = &connect; commit_on_success = db->get_auto_commit(); if (var != nullptr) { extern_cda = true; cda = var->get_cda(); status = OCI_SUCCESS; } else { #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_cda = &cda; #endif status = OCIHandleAlloc(OTL_RCAST(dvoid *, db->get_envhp()), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_cda), #else OTL_RCAST(dvoid **, &cda), #endif OCI_HTYPE_STMT, 0, nullptr); if (status) return 0; } #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_errhp = &errhp; #endif status = OCIHandleAlloc(OTL_RCAST(dvoid *, db->get_envhp()), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_errhp), #else OTL_RCAST(dvoid **, &errhp), #endif OCI_HTYPE_ERROR, 0, nullptr); if (status) return 0; straight_select = 1; pos_nbr = 0; return 1; } OTL_NODISCARD int close(const char #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) force_handle_free #endif = 'N') { if (!extern_cda) { #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) if (force_handle_free == 'Y') status = OCIHandleFree(OTL_RCAST(dvoid *, cda), OCI_HTYPE_STMT); else status = OCIStmtRelease(cda, errhp, nullptr, 0, OCI_DEFAULT); #else status = OCIHandleFree(OTL_RCAST(dvoid *, cda), OCI_HTYPE_STMT); #endif } status = OCIHandleFree(OTL_RCAST(dvoid *, errhp), OCI_HTYPE_ERROR); cda = nullptr; errhp = nullptr; if (errhp2_ != nullptr) { status = OCIHandleFree(OTL_RCAST(dvoid *, errhp2_), OCI_HTYPE_ERROR); errhp2_ = nullptr; } if (errhndl_ != nullptr) { status = OCIHandleFree(OTL_RCAST(dvoid *, errhndl_), OCI_HTYPE_ERROR); errhndl_ = nullptr; } commit_on_success = 0; return 1; } OTL_NODISCARD int parse(const char *stm_text, const int /*external_direct_flag*/) { #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) if (cda != nullptr) { status = OCIHandleFree(OTL_RCAST(dvoid *, cda), OCI_HTYPE_STMT); cda = nullptr; if (status) return 0; } status = OCIStmtPrepare2(db->get_svchp(), &cda, errhp, OTL_RCAST(text *, OTL_CCAST(char *, stm_text)), OTL_SCAST(ub4, strlen(stm_text)), nullptr, 0, OTL_SCAST(ub4, OCI_NTV_SYNTAX), OTL_SCAST(ub4, OCI_DEFAULT)); #else status = OCIStmtPrepare( cda, errhp, OTL_RCAST(text *, OTL_CCAST(char *, stm_text)), OTL_SCAST(ub4, strlen(stm_text)), OTL_SCAST(ub4, OCI_NTV_SYNTAX), OTL_SCAST(ub4, OCI_DEFAULT)); #endif if (status) return 0; if (direct_exec_flag && parse_only_flag) { #if !defined(OCI_PARSE_ONLY) status = OCIStmtExecute(db->svchp, cda, errhp, OTL_SCAST(ub4, 1), OTL_SCAST(ub4, 0), 0, 0, 0x100); #else status = OCIStmtExecute(db->get_svchp(), cda, errhp, OTL_SCAST(ub4, 0), OTL_SCAST(ub4, 0), nullptr, nullptr, OCI_PARSE_ONLY); #endif if (status) return 0; else return 1; } else if (direct_exec_flag && !parse_only_flag) { ub4 mode; if (commit_on_success) mode = OCI_COMMIT_ON_SUCCESS; else mode = OCI_DEFAULT; status = OCIStmtExecute(db->get_svchp(), cda, errhp, OTL_SCAST(ub4, 1), OTL_SCAST(ub4, 0), nullptr, nullptr, mode); stm_executed = 1; if (status) return 0; else return 1; } return 1; } OTL_NODISCARD int exec(const int iters, const int rowoff, const otl_sql_exec_from_enum /*otl_sql_exec_from_class*/) { if (parse_only_flag) { parse_only_flag = 0; return 1; } else if (!stm_executed) { ub4 mode; if (commit_on_success) mode = OCI_COMMIT_ON_SUCCESS; else mode = OCI_DEFAULT; if (batch_error_mode_) mode |= OCI_BATCH_ERRORS; status = OCIStmtExecute(db->get_svchp(), cda, errhp, OTL_SCAST(ub4, iters), OTL_SCAST(ub4, rowoff), nullptr, nullptr, mode); stm_executed = 0; if (status != OCI_SUCCESS) return 0; return 1; } return 1; } OTL_NODISCARD long get_rpc() OTL_NO_THROW { return OTL_SCAST(long,rpc()); } OTL_NODISCARD int fetch(const otl_stream_buffer_size_type iters, int &eof_data) { eof_data = 0; #if defined(OTL_ORA9I) || defined(OTL_ORA10G) || defined(OTL_ORA10G_R2) || \ defined(OTL_ORA11G) || defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) status = OCIStmtFetch2( cda, errhp, OTL_SCAST(ub4, iters), OTL_SCAST(ub4, OCI_FETCH_NEXT), OTL_SCAST(sb4, OCI_FETCH_NEXT), OTL_SCAST(ub4, OCI_DEFAULT)); #else status = OCIStmtFetch(cda, errhp, OTL_SCAST(ub4, iters), OTL_SCAST(ub4, OCI_FETCH_NEXT), OTL_SCAST(ub4, OCI_DEFAULT)); #endif eof_status = status; if (status != OCI_SUCCESS && status != OCI_SUCCESS_WITH_INFO && status != OCI_NO_DATA) return 0; if (status == OCI_NO_DATA) { eof_data = 1; return 1; } return 1; } OTL_NODISCARD int tmpl_ftype2ora_ftype(const int ftype) { switch (ftype) { case otl_var_char: return extCChar; #if (defined(OTL_ORA10G) || defined(OTL_ORA10G_R2)) && \ defined(OTL_ORA_NATIVE_TYPES) && !defined(OTL_ORA_LEGACY_NUMERIC_TYPES) case otl_var_double: return extBDouble; case otl_var_bdouble: return extBDouble; case otl_var_float: return extBFloat; case otl_var_bfloat: return extBFloat; #else case otl_var_double: return extFloat; case otl_var_float: return extFloat; #endif case otl_var_int: return extInt; case otl_var_unsigned_int: return extUInt; case otl_var_short: return extInt; case otl_var_long_int: return extInt; #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) case otl_var_bigint: return extInt; #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) case otl_var_ubigint: return extUInt; #endif #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) case otl_var_timestamp: return extTimestamp; case otl_var_tz_timestamp: return extTimestamp_TZ; case otl_var_ltz_timestamp: return extTimestamp_LTZ; #else case otl_var_timestamp: return extDate; #endif case otl_var_varchar_long: return extLongVarChar; case otl_var_raw_long: return extLongVarRaw; case otl_var_raw: return extRaw; case otl_var_clob: return SQLT_CLOB; case otl_var_blob: return SQLT_BLOB; #if defined(OTL_ORA_SDO_GEOMETRY) case otl_var_sdo_geometry: return SQLT_NTY; #endif default: return 0; } } OTL_NODISCARD int bind(const char *name, otl_var &v, const int elem_size, const int ftype, const int /*param_type*/, const int /*name_pos*/, const int /*connection_type*/, const int apl_tab_flag) { OCIBind *bindpp; int db_ftype = 0; #if defined(OTL_ORA_SDO_GEOMETRY) if(ftype == otl_var_sdo_geometry){ if(v.sdoobj && v.array_size > 0 && !v.sdoobj[0]){ v.needFree = true; for(int i = 0;i=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif status = OCIObjectNew( db->get_envhp(), errhp, db->get_svchp(), OTL_SCAST(ub2, OCI_TYPECODE_OBJECT), v.oraOCIType, nullptr, OTL_SCAST(ub2, OCI_DURATION_SESSION), 1, OTL_RCAST(dvoid **, &v.sdoobj[i])); #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif if(status)return 0; status = OCIObjectGetInd(db->get_envhp(), errhp, OTL_RCAST(dvoid *, v.sdoobj[i]), OTL_RCAST(dvoid **, &v.sdoind[i])); if(status)return 0; } } status = OCIBindByName( cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)), OTL_SCAST(sb4, strlen(name)), nullptr, OTL_SCAST(sb4, 0), OTL_SCAST(ub2, tmpl_ftype2ora_ftype(ftype)), OTL_RCAST(dvoid *, v.p_ind), nullptr, nullptr, OTL_SCAST(ub4, 0), nullptr, OTL_SCAST(ub4, OCI_DEFAULT)); if(status)return 0; status = OCIBindObject(bindpp, errhp, v.oraOCIType, OTL_RCAST(dvoid **, v.sdoobj), nullptr, OTL_RCAST(dvoid **, v.sdoind), nullptr); if(status)return 0; }else #endif if (ftype == otl_var_refcur) { status = OCIBindByName( cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)), OTL_SCAST(sb4, strlen(name)), OTL_RCAST(dvoid *, v.get_cda_ptr()), 0, SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr, OTL_SCAST(ub4, OCI_DEFAULT)); } else if (ftype != otl_var_clob && ftype != otl_var_blob) { int var_elem_size; #if defined(OTL_UNICODE) if (ftype == otl_var_char) { var_elem_size = elem_size * OTL_SCAST(int, sizeof(OTL_WCHAR)); } else if (ftype == otl_var_varchar_long) var_elem_size = elem_size; else var_elem_size = elem_size; #else if (ftype == otl_var_varchar_long) var_elem_size = elem_size + OTL_SCAST(int, sizeof(sb4)); else var_elem_size = elem_size; #endif db_ftype = tmpl_ftype2ora_ftype(ftype); #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) if (ftype == otl_var_timestamp || ftype == otl_var_tz_timestamp || ftype == otl_var_ltz_timestamp) { if (!apl_tab_flag) var_elem_size = sizeof(OCIDateTime *); else if (db_ftype == extTimestamp) db_ftype = extDate; } #endif #if defined(OTL_UNICODE) if (ftype == otl_var_char) db_ftype = SQLT_VCS; #endif if (apl_tab_flag) { if (ftype == otl_var_float || ftype == otl_var_double) db_ftype = extFloat; status = OCIBindByName( cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)), OTL_SCAST(sb4, strlen(name)), OTL_RCAST(dvoid *, v.p_v), OTL_SCAST(sb4, ftype == otl_var_raw ? OTL_SCAST(size_t, var_elem_size) + sizeof(short) : OTL_SCAST(size_t, var_elem_size)), OTL_SCAST(ub2, v.charz_flag ? extCharZ : db_ftype), OTL_RCAST(dvoid *, v.p_ind), nullptr, nullptr, OTL_SCAST(ub4, v.max_tab_len), OTL_RCAST(ub4 *, &v.cur_tab_len), OTL_SCAST(ub4, OCI_DEFAULT)); } else { status = OCIBindByName( cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)), OTL_SCAST(sb4, strlen(name)), OTL_RCAST(dvoid *, v.p_v), OTL_SCAST(sb4, ftype == otl_var_raw ? OTL_SCAST(size_t, var_elem_size) + sizeof(short) : OTL_SCAST(size_t, var_elem_size)), OTL_SCAST(ub2, db_ftype), OTL_RCAST(dvoid *, v.p_ind), nullptr, nullptr, 0, nullptr, OTL_SCAST(ub4, OCI_DEFAULT)); } if (status)return 0; #if defined(OTL_UNICODE) if (ftype == otl_var_char || ftype == otl_var_varchar_long) { if (ftype != otl_var_varchar_long) { if (v.nls_flag) v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR); else v.csfrm = OTL_SCAST(ub1, db->char_set_); status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csfrm, 0, OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp); if (status) return 0; } v.csid = OTL_UNICODE_ID; status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csid, 0, OCI_ATTR_CHARSET_ID, errhp); if (status)return 0; if (ftype == otl_var_varchar_long) v.unicode_var_len = elem_size - OTL_SCAST(int, sizeof(sb4)); else { #if defined(OTL_ORA_MAX_UNICODE_VARCHAR_SIZE) if (var_elem_size > OTL_ORA_MAX_UNICODE_VARCHAR_SIZE) v.unicode_var_len = OTL_ORA_MAX_UNICODE_VARCHAR_SIZE; else v.unicode_var_len = var_elem_size; #else v.unicode_var_len = var_elem_size; #endif } status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.unicode_var_len, 0, OCI_ATTR_MAXDATA_SIZE, errhp); if (status)return 0; } #endif #if defined(OTL_ORA_UTF8) if (ftype == otl_var_char) { if (v.nls_flag) v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR); else v.csfrm = OTL_SCAST(ub1, db->char_set_); status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csfrm, 0, OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp); if (status)return 0; } #endif return 1; } else { status = OCIBindByName( cda, &bindpp, errhp, OTL_RCAST(text *, OTL_CCAST(char *, name)), OTL_SCAST(sb4, strlen(name)), OTL_RCAST(dvoid *, v.p_v), OTL_SCAST(sb4, -1), OTL_SCAST(ub2, tmpl_ftype2ora_ftype(ftype)), OTL_RCAST(dvoid *, v.p_ind), nullptr, nullptr, 0, nullptr, OTL_SCAST(ub4, OCI_DEFAULT)); if (status) return 0; #if defined(OTL_UNICODE) if (ftype == otl_var_clob) { v.csid = OTL_UNICODE_ID; status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csid, 0, OCI_ATTR_CHARSET_ID, errhp); if (status) return 0; if (v.nls_flag) v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR); else v.csfrm = OTL_SCAST(ub1, db->char_set_); status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csfrm, 0, OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp); if (status) return 0; } #endif #if defined(OTL_ORA_UTF8) if (ftype == otl_var_clob) { if (v.nls_flag) v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR); else v.csfrm = OTL_SCAST(ub1, db->char_set_); status = OCIAttrSet(bindpp, OCI_HTYPE_BIND, &v.csfrm, 0, OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp); if (status) return 0; } #endif return 1; } if (status) return 0; return 1; } OTL_NODISCARD int bind(const int column_num, otl_var &v, const int elem_size, const int ftype, const int /*param_type*/) { OCIDefine *defnp; int db_ftype = 0; #if defined(OTL_ORA_SDO_GEOMETRY) if(ftype == otl_var_sdo_geometry){ v.needFree = false; status = OCIDefineByPos(cda, &defnp, errhp, OTL_SCAST(ub4, column_num), OTL_RCAST(dvoid *, v.sdoobj), OTL_SCAST(sb4, 0), OTL_SCAST(ub2, tmpl_ftype2ora_ftype(ftype)), OTL_RCAST(dvoid *, v.p_ind), OTL_RCAST(ub2 *, v.p_rlen), OTL_RCAST(ub2 *, v.p_rcode), OTL_SCAST(ub4, OCI_DEFAULT)); if(status) return 0; status = OCIDefineObject(defnp, errhp, v.oraOCIType, OTL_RCAST(dvoid **, v.sdoobj), nullptr, OTL_RCAST(dvoid **, v.sdoind), nullptr ); if(status) return 0; else return 1; }else #endif if (ftype != otl_var_clob && ftype != otl_var_blob) { int var_elem_size; #if defined(OTL_UNICODE) if (ftype == otl_var_char) var_elem_size = elem_size * OTL_SCAST(int, sizeof(OTL_WCHAR)); else if (ftype == otl_var_varchar_long) var_elem_size = elem_size + OTL_SCAST(int, sizeof(sb4)); else var_elem_size = elem_size; #elif defined(OTL_ORA_UTF8) if (ftype == otl_var_char && v.select_stm_flag) var_elem_size = elem_size * OTL_UTF8_BYTES_PER_CHAR; // 3 bytes per UTF8 char else if (ftype == otl_var_varchar_long) var_elem_size = elem_size + OTL_SCAST(int, sizeof(sb4)); else var_elem_size = elem_size; #else if (ftype == otl_var_varchar_long) var_elem_size = elem_size + OTL_SCAST(int, sizeof(sb4)); else var_elem_size = elem_size; #endif db_ftype = tmpl_ftype2ora_ftype(ftype); #if defined(OTL_UNICODE) if (ftype == otl_var_char) db_ftype = SQLT_VCS; #endif status = OCIDefineByPos( cda, &defnp, errhp, OTL_SCAST(ub4, column_num), OTL_RCAST(dvoid *, v.p_v), OTL_SCAST(sb4, ftype == otl_var_raw ? OTL_SCAST(size_t, var_elem_size) + sizeof(short) : OTL_SCAST(size_t, var_elem_size)), OTL_SCAST(ub2, db_ftype), OTL_RCAST(dvoid *, v.p_ind), OTL_RCAST(ub2 *, v.p_rlen), OTL_RCAST(ub2 *, v.p_rcode), OCI_DEFAULT); if (status) return 0; #if defined(OTL_ORA_UTF8) if (ftype == otl_var_char || ftype == otl_var_varchar_long) { if (v.nls_flag) v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR); else v.csfrm = OTL_SCAST(ub1, db->char_set_); status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE, OTL_RCAST(void *, &v.csfrm), OTL_SCAST(ub4, 0), OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp); if (status) return 0; } #endif #if defined(OTL_UNICODE) if (ftype == otl_var_char || ftype == otl_var_varchar_long) { if (v.nls_flag) v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR); else v.csfrm = OTL_SCAST(ub1, db->char_set_); status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE, OTL_RCAST(void *, &v.csfrm), OTL_SCAST(ub4, 0), OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp); if (status) return 0; v.csid = OTL_UNICODE_ID; status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE, &v.csid, 0, OCI_ATTR_CHARSET_ID, errhp); if (status) return 0; } #endif return 1; } else { status = OCIDefineByPos(cda, &defnp, errhp, OTL_SCAST(ub4, column_num), OTL_RCAST(dvoid *, v.p_v), OTL_SCAST(sb4, -1), OTL_SCAST(ub2, tmpl_ftype2ora_ftype(ftype)), OTL_RCAST(dvoid *, v.p_ind), OTL_RCAST(ub2 *, v.p_rlen), OTL_RCAST(ub2 *, v.p_rcode), OCI_DEFAULT); if (status) return 0; #if defined(OTL_UNICODE) if (ftype == otl_var_char || ftype == otl_var_varchar_long) { v.csid = OTL_UNICODE_ID; status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE, &v.csid, 0, OCI_ATTR_CHARSET_ID, errhp); if (status) return 0; } #endif #if defined(OTL_ORA_UTF8) if (ftype == otl_var_clob) { if (v.nls_flag) v.csfrm = OTL_SCAST(ub1, SQLCS_NCHAR); else v.csfrm = OTL_SCAST(ub1, db->char_set_); status = OCIAttrSet(defnp, OCI_HTYPE_DEFINE, OTL_RCAST(void *, &v.csfrm), OTL_SCAST(ub4, 0), OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), errhp); if (status) return 0; } #endif return 1; } } void set_select_type(const int select_type) { straight_select = select_type; } OTL_NODISCARD int describe_column(otl_column_desc &col, const int column_num, int &eof_desc) { OCIParam *pard; ub2 dtype; ub2 dbsize; sb2 prec; #if defined(OTL_ORA8_8I_DESC_COLUMN_SCALE) ub1 scale; #else sb2 scale; #endif ub1 nullok; text *col_name; ub4 col_name_len; ub4 pos_num; #ifdef OTL_ORA_SDO_GEOMETRY text *col_type_name; ub4 col_type_name_len; #endif // OTL_ORA_SDO_GEOMETRY eof_desc = 0; if (straight_select && pos_nbr == 0) { status = OCIStmtExecute(db->get_svchp(), cda, errhp, 0, 0, nullptr, nullptr, OCI_DESCRIBE_ONLY); if (status != OCI_SUCCESS) return 0; status = OCIAttrGet(cda, OCI_HTYPE_STMT, OTL_RCAST(ub4 *, &pos_num), nullptr, OTL_SCAST(ub4, OCI_ATTR_PARAM_COUNT), errhp); if (status != OCI_SUCCESS) return 0; pos_nbr = OTL_SCAST(int, pos_num); } if (!straight_select && pos_nbr == 0) { status = OCIAttrGet(cda, OCI_HTYPE_STMT, OTL_RCAST(ub4 *, &pos_num), nullptr, OTL_SCAST(ub4, OCI_ATTR_PARAM_COUNT), errhp); if (status != OCI_SUCCESS) return 0; pos_nbr = OTL_SCAST(int, pos_num); } if (column_num < 1 || column_num > pos_nbr) { eof_desc = 1; return 0; } #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_pard = &pard; #endif status = OCIParamGet(cda, OCI_HTYPE_STMT, errhp, #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(void **, temp_pard), #else OTL_RCAST(void **, &pard), #endif OTL_SCAST(ub4, column_num)); if (status != OCI_SUCCESS && status != OCI_NO_DATA) return 0; if (status == OCI_NO_DATA) { eof_desc = 1; return 1; } status = OCIAttrGet( OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), OTL_RCAST(dvoid *, &dtype), nullptr, OTL_SCAST(ub4, OCI_ATTR_DATA_TYPE), OTL_RCAST(OCIError *, errhp)); if (status != OCI_SUCCESS) return 0; #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) #if !defined(OTL_ORA8I) ub1 charset_form; status = OCIAttrGet( OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), OTL_RCAST(dvoid *, &charset_form), nullptr, OTL_SCAST(ub4, OCI_ATTR_CHARSET_FORM), OTL_RCAST(OCIError *, errhp)); if (status != OCI_SUCCESS) return 0; col.charset_form = OTL_SCAST(int, charset_form); ub2 char_size; status = OCIAttrGet( OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), OTL_RCAST(dvoid *, &char_size), nullptr, OTL_SCAST(ub4, OCI_ATTR_CHAR_SIZE), OTL_RCAST(OCIError *, errhp)); if (status != OCI_SUCCESS) return 0; col.char_size = OTL_SCAST(int, char_size); #else col.char_size = 0; #endif #endif col.dbtype = dtype; #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_col_name = &col_name; #endif status = OCIAttrGet(OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_col_name), #else OTL_RCAST(dvoid **, &col_name), #endif OTL_RCAST(ub4 *, &col_name_len), OTL_SCAST(ub4, OCI_ATTR_NAME), OTL_RCAST(OCIError *, errhp)); if (status != OCI_SUCCESS) return 0; col.set_name(OTL_RCAST(char *, col_name), OTL_SCAST(int, col_name_len)); status = OCIAttrGet( OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), OTL_RCAST(dvoid *, &dbsize), #if defined(OTL_ANSI_CPP_11_NULLPTR_SUPPORT) nullptr, #else OTL_RCAST(ub4 *, 0), #endif OTL_SCAST(ub4, OCI_ATTR_DATA_SIZE), OTL_RCAST(OCIError *, errhp)); if (status != OCI_SUCCESS) return 0; col.dbsize = dbsize; status = OCIAttrGet( OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), OTL_RCAST(dvoid *, &prec), nullptr, OTL_SCAST(ub4, OCI_ATTR_PRECISION), OTL_RCAST(OCIError *, errhp)); if (status != OCI_SUCCESS) return 0; col.prec = prec; status = OCIAttrGet( OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), OTL_RCAST(dvoid *, &scale), nullptr, OTL_SCAST(ub4, OCI_ATTR_SCALE), OTL_RCAST(OCIError *, errhp)); if (status != OCI_SUCCESS) return 0; col.scale = scale; status = OCIAttrGet( OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), OTL_RCAST(dvoid *, &nullok), nullptr, OTL_SCAST(ub4, OCI_ATTR_IS_NULL), OTL_RCAST(OCIError *, errhp)); if (status != OCI_SUCCESS) return 0; col.nullok = nullok; #ifdef OTL_ORA_SDO_GEOMETRY #if defined(__GNUC__) && (__GNUC__ >= 4) void *temp_col_type_name = &col_type_name; #endif if(col.dbtype == SQLT_NTY){ status=OCIAttrGet(OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), #if defined(__GNUC__) && (__GNUC__ >= 4) OTL_RCAST(dvoid **, temp_col_type_name), #else OTL_RCAST(dvoid **, &col_type_name), #endif OTL_RCAST(ub4 *, &col_type_name_len), OTL_SCAST(ub4, OCI_ATTR_TYPE_NAME), OTL_RCAST(OCIError *, errhp)); if(status != OCI_SUCCESS) return 0; col.set_name_type(OTL_RCAST(char *, col_type_name), OTL_SCAST(int, col_type_name_len)); OCIRef *typeRef = nullptr; void* temp_ptr=OTL_RCAST(void*, &typeRef); status = OCIAttrGet( OTL_RCAST(dvoid *, pard), OTL_SCAST(ub4, OCI_DTYPE_PARAM), temp_ptr, nullptr, OTL_SCAST(ub4, OCI_ATTR_REF_TDO), OTL_RCAST(OCIError *, errhp)); if(status != OCI_SUCCESS) return 0; #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wold-style-cast" #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif void* temp_ptr3=OTL_RCAST(void*,&col.colOCIType); status = OCIObjectPin(db->get_envhp(), db->get_errhp(), typeRef, nullptr, OCI_PIN_ANY, OCI_DURATION_SESSION, OCI_LOCK_NONE, (void**)temp_ptr3); #if defined(__clang__) #pragma clang diagnostic pop #endif #if defined(__GNUC__) && defined(__GNUC_MINOR__) && (__GNUC__*100+__GNUC_MINOR__>=407) #pragma GCC diagnostic pop #endif if(status != OCI_SUCCESS) return 0; } #endif return 1; } void error(otl_exc &exception_struct) { sb4 errcode; size_t len; OTL_STRCPY_S(OTL_RCAST(char *, exception_struct.msg), sizeof(exception_struct.msg), "123456789"); OCIErrorGet(OTL_RCAST(dvoid *, errhp), OTL_SCAST(ub4, 1), nullptr, &errcode, OTL_RCAST(text *, exception_struct.msg), OTL_SCAST(ub4, sizeof(exception_struct.msg)), OCI_HTYPE_ERROR); exception_struct.code = errcode; len = strlen(OTL_RCAST(char *, exception_struct.msg)); exception_struct.msg[len] = 0; #if defined(OTL_EXCEPTION_ENABLE_ERROR_OFFSET) ub2 error_offset; if (OCIAttrGet(cda, OCI_HTYPE_STMT, OTL_RCAST(ub2 *, &error_offset), 0, OTL_SCAST(ub4, OCI_ATTR_PARSE_ERROR_OFFSET), errhp) == OCI_SUCCESS) exception_struct.error_offset = OTL_SCAST(int, error_offset); #endif } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_cur(const otl_cur &) = delete; otl_cur &operator=(const otl_cur &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_cur(otl_cur &&) = delete; otl_cur &operator=(otl_cur &&) = delete; #endif private: #else otl_cur(const otl_cur &) : otl_cur0(), cda(nullptr), errhp(nullptr), extern_cda(false), status(0), eof_status(0), db(nullptr), straight_select(1), pos_nbr(0), commit_on_success(0), last_param_data_token(0), last_sql_param_data_status(0), sql_param_data_count(0), canceled(false), direct_exec_flag(0), parse_only_flag(0), stm_executed(0), batch_error_mode_(false), errhndl_(nullptr), errhp2_(nullptr) {} otl_cur &operator=(const otl_cur &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_cur(otl_cur &&) : otl_cur0(), cda(nullptr), errhp(nullptr), extern_cda(false), status(0), eof_status(0), db(nullptr), straight_select(1), pos_nbr(0), commit_on_success(0), last_param_data_token(0), last_sql_param_data_status(0), sql_param_data_count(0), canceled(false), direct_exec_flag(0), parse_only_flag(0), stm_executed(0), batch_error_mode_(false), errhndl_(nullptr), errhp2_(nullptr) {} otl_cur &operator=(otl_cur &&) { return *this; } #endif #endif }; class otl_ref_cursor; class otl_sel { private: friend class otl_ref_cursor; int implicit_cursor; public: OTL_NODISCARD int get_implicit_cursor() const { return implicit_cursor; } void set_arr_size(const int input_arr_size, int &out_array_size, int &out_prefetch_array_size) { out_array_size = input_arr_size; out_prefetch_array_size = 0; } void set_prefetch_size(const int /*aprefetch_array_size*/) {} OTL_NODISCARD int close_select(otl_cur & /*cur*/) { return 1; } otl_sel() : implicit_cursor(0) {} virtual ~otl_sel() {} void set_select_type(const int /*atype*/) { implicit_cursor = 0; } void init(const int /*array_size*/) {} OTL_NODISCARD int first(otl_cur &cur, int &cur_row, int &cur_size, int &row_count, int &eof_data, const int array_size) { int rc; eof_data = 0; cur_row = -1; cur.commit_on_success = 0; rc = cur.exec(0, 0, otl_sql_exec_from_select_cursor_class); if (rc == 0) return 0; rc = cur.fetch(OTL_SCAST(otl_stream_buffer_size_type, array_size), eof_data); if (rc == 0) return 0; row_count = OTL_SCAST(int, cur.rpc()); cur_size = row_count; if (cur_size != 0) cur_row = 0; return 1; } OTL_NODISCARD int next(otl_cur &cur, int &cur_row, int &cur_size, int &row_count, int &eof_data, const int array_size) { int rc; if (cur_row < cur_size - 1) { ++cur_row; return 1; } else { if (eof_data) { cur_row = -1; cur_size = 0; return 1; } cur.commit_on_success = 0; rc = cur.fetch(OTL_SCAST(otl_stream_buffer_size_type, array_size), eof_data); if (rc == 0) return 0; int temp_rpc = OTL_SCAST(int, cur.rpc()); cur_size = temp_rpc - row_count; row_count = temp_rpc; if (cur_size != 0) cur_row = 0; return 1; } } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_sel(const otl_sel &) = delete; otl_sel &operator=(const otl_sel &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_sel(otl_sel &&) = delete; otl_sel &operator=(otl_sel &&) = delete; #endif private: #else otl_sel(const otl_sel &) : implicit_cursor(0) {} otl_sel &operator=(const otl_sel &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_sel(otl_sel &&) : implicit_cursor(0) {} otl_sel &operator=(otl_sel &&) { return *this; } #endif #endif }; typedef otl_tmpl_connect otl_ora8_connect; typedef otl_tmpl_cursor otl_cursor; template class otl_tmpl_lob_stream : public otl_lob_stream_generic { public: typedef otl_tmpl_exception otl_exception; typedef otl_tmpl_variable *p_bind_var; typedef otl_tmpl_connect * p_connect; typedef otl_tmpl_cursor *p_cursor; private: p_bind_var bind_var; p_connect connect; p_cursor cursor; otl_long_string *temp_buf; char *temp_char_buf; public: void setInitialReadOffset(const int initial_offset) { if (lob_len == 0) lob_len = len(); if ((initial_offset - 1) >= lob_len) { eof_flag = 1; return; } offset = initial_offset + 1; if (bind_var) bind_var->get_var_struct().set_total_read_blob_amt(initial_offset + 1); } void init(void *avar, void *aconnect, void *acursor, int andx, int amode, const int alob_is_null = 0) OTL_NO_THROW { connect = OTL_RCAST(p_connect, aconnect); bind_var = OTL_RCAST(p_bind_var, avar); cursor = OTL_RCAST(p_cursor, acursor); mode = amode; retcode = 0; lob_is_null = alob_is_null; ndx = andx; offset = 0; if (amode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) lob_len = 2147483647; else lob_len = 0; eof_flag = 0; in_destructor = 0; if (bind_var) bind_var->get_var_struct().set_lob_stream_flag(); } void set_len(const int new_len = 0) OTL_NO_THROW { lob_len = new_len; } otl_tmpl_lob_stream() OTL_NO_THROW : otl_lob_stream_generic(true), bind_var(nullptr), connect(nullptr), cursor(nullptr), temp_buf(nullptr), temp_char_buf(nullptr) { otl_tmpl_lob_stream::init(nullptr, nullptr, nullptr, 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode)); } virtual ~otl_tmpl_lob_stream() #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW) OTL_THROWS_OTL_EXCEPTION #else OTL_NO_THROW #endif { in_destructor = 1; if (temp_buf) { delete temp_buf; temp_buf = nullptr; } if (temp_char_buf) { delete[] temp_char_buf; temp_char_buf = nullptr; } #if defined(OTL_DESTRUCTORS_DO_NOT_THROW) try { otl_tmpl_lob_stream::close(); } catch (OTL_CONST_EXCEPTION otl_exception &) { } #else otl_tmpl_lob_stream::close(); #endif } #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) otl_lob_stream_generic &operator<<(OTL_STD_STRING_VIEW_CLASS s) OTL_THROWS_OTL_EXCEPTION { otl_long_string temp_s(s.data(), OTL_SCAST(int, s.length()), OTL_SCAST(int, s.length())); (*this) << temp_s; return *this; } #endif #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_USER_DEFINED_STRING_CLASS_ON)) && \ !defined(OTL_UNICODE) otl_lob_stream_generic &operator<<(const OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { otl_long_string temp_s(s.c_str(), OTL_SCAST(int, s.length()), OTL_SCAST(int, s.length())); (*this) << temp_s; return *this; } void setStringBuffer(const int chunk_size) { delete[] temp_char_buf; temp_char_buf = nullptr; delete temp_buf; temp_buf = nullptr; temp_char_buf = new char[OTL_SCAST(size_t,chunk_size + 1)]; temp_buf = new otl_long_string(temp_char_buf, chunk_size); } otl_lob_stream_generic & operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { const int TEMP_BUF_SIZE = 4096; if (!temp_char_buf) temp_char_buf = new char[TEMP_BUF_SIZE]; if (!temp_buf) temp_buf = new otl_long_string(temp_char_buf, TEMP_BUF_SIZE - 1); int iters = 0; while (!this->eof()) { ++iters; (*this) >> (*temp_buf); temp_char_buf[temp_buf->len()] = 0; if (iters > 1) { #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(OTL_USER_DEFINED_STRING_CLASS_ON)) s.append(temp_char_buf, OTL_SCAST(size_t, temp_buf->len())); #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE)) s.append(temp_char_buf, temp_buf->len()); #elif defined(OTL_ACE) s.append(temp_char_buf, OTL_SCAST(size_t, temp_buf->len())); #endif } else #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(OTL_USER_DEFINED_STRING_CLASS_ON)) s.assign(temp_char_buf, OTL_SCAST(size_t, temp_buf->len())); #elif(defined(OTL_USER_DEFINED_STRING_CLASS_ON) && !defined(OTL_ACE)) s.assign(temp_char_buf, temp_buf->len()); #elif defined(OTL_ACE) s.set(temp_char_buf, OTL_SCAST(size_t, temp_buf->len()), 1); #endif } return *this; } #endif otl_lob_stream_generic &operator<<(const otl_long_string &s) OTL_THROWS_OTL_EXCEPTION { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (bind_var && bind_var->get_ftype() == otl_var_blob) in_unicode_mode = false; if (s.get_unicode_flag() != in_unicode_mode) { OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_37, otl_error_code_37, "otl_lob_stream_generic::operator<<(const otl_long_string&)"))); } if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_write_mode)) { const char *stm = nullptr; char var_info[256]; var_info[0] = 0; if (cursor != nullptr) { if (cursor->get_stm_label()) stm = cursor->get_stm_label(); else stm = cursor->get_stm_text(); } if (bind_var != nullptr) { otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); } char *vinfo = nullptr; if (var_info[0] != 0) vinfo = &var_info[0]; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_tmpl_exception( otl_error_msg_9, otl_error_code_9, stm, vinfo))); } if (offset == 0) offset = 1; if ((offset - 1) + s.len() > lob_len) { char var_info[256]; if (bind_var != nullptr) otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); char err_msg[1024]; char temp_num[64]; OTL_STRCPY_S(err_msg, sizeof(err_msg), otl_error_msg_7); OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, ", trying to store "); otl_itoa(s.len(), temp_num); OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, temp_num); #if defined(OTL_UNICODE) OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, " Unicode characters at offset "); #else OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, " bytes at offset "); #endif otl_itoa(offset, temp_num); OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, temp_num); OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, ". New length: "); otl_itoa((offset - 1) + s.len(), temp_num); OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, temp_num); OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, " would be bigger than length of lob: "); otl_itoa(lob_len, temp_num); OTL_STRCAT_S(err_msg, sizeof(err_msg)-strlen(err_msg)-1, temp_num); OTL_THROW((otl_tmpl_exception( err_msg, otl_error_code_7, cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text(), var_info))); } if (s.is_last_piece()) lob_len = (offset + s.len() - 1); if (bind_var != nullptr) retcode = bind_var->get_var_struct().write_blob( s, lob_len, offset, cursor->get_cursor_struct()); if (retcode) { if ((offset - 1) == lob_len) close(); return *this; } OTL_UNCAUGHT_EXCEPTION_RETURN(*this); if(connect) OTL_THROW((otl_tmpl_exception (connect->get_connect_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); else return *this; } otl_lob_stream_generic & operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (bind_var && bind_var->get_ftype() == otl_var_blob) in_unicode_mode = false; if (s.get_unicode_flag() != in_unicode_mode) { OTL_THROW((OTL_TMPL_EXCEPTION( otl_error_msg_37, otl_error_code_37, "otl_lob_stream_generic::operator>>(otl_long_string&)"))); } if (mode != OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) { const char *stm = nullptr; char var_info[256]; var_info[0] = 0; if (cursor != nullptr) { if (cursor->get_stm_label()) stm = cursor->get_stm_label(); else stm = cursor->get_stm_text(); } if (bind_var != nullptr) { otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); } char *vinfo = nullptr; if (var_info[0] != 0) vinfo = &var_info[0]; OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_tmpl_exception( otl_error_msg_10, otl_error_code_10, stm, vinfo))); } if (offset == 0 && lob_len == 0) lob_len = len(); if (lob_len == 0 || (offset - 1) == lob_len) { s.set_len(0); eof_flag = 1; return *this; } if (offset == 0) offset = 1; if (bind_var != nullptr) retcode = bind_var->get_var_struct().read_blob(s, ndx, offset, lob_len); if ((offset - 1) == lob_len) eof_flag = 1; if (retcode) { if (eof()) { close(); eof_flag = 1; } return *this; } OTL_UNCAUGHT_EXCEPTION_RETURN(*this); if(connect) OTL_THROW((otl_tmpl_exception (connect->get_connect_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); else return *this; } OTL_NODISCARD int eof(void) OTL_NO_THROW { if (lob_is_null) return 1; return eof_flag; } OTL_NODISCARD bool is_initialized(void) OTL_THROWS_OTL_EXCEPTION { if (cursor == nullptr || connect == nullptr || bind_var == nullptr || lob_is_null) return false; int is_init = 0; retcode = bind_var->get_var_struct().is_blob_initialized(ndx, is_init); if (retcode) return is_init != 0; OTL_UNCAUGHT_EXCEPTION_RETURN(false); OTL_THROW((OTL_TMPL_EXCEPTION(connect->get_connect_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); } OTL_NODISCARD int len(void) OTL_THROWS_OTL_EXCEPTION { if (cursor == nullptr || connect == nullptr || bind_var == nullptr || lob_is_null) return 0; int alen; retcode = bind_var->get_var_struct().get_blob_len(ndx, alen); if (retcode) return alen; OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_tmpl_exception( connect->get_connect_struct(), cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text()))); } void close(bool dont_throw_size_doesnt_match_exception = false) OTL_THROWS_OTL_EXCEPTION { if (in_destructor) { if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) { if(bind_var){ bind_var->get_var_struct().set_lob_stream_flag(0); bind_var->set_not_null(0); } } return; } if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode)) return; if (mode == OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode)) { if(bind_var){ if (offset < lob_len - 1) (void)bind_var->get_var_struct().close_lob(); bind_var->get_var_struct().close_temporary_lob(); bind_var->get_var_struct().set_lob_stream_flag(0); bind_var->set_not_null(0); init(nullptr, nullptr, nullptr, 0, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_zero_mode)); } } else { // write mode if (!(offset == 0 && lob_len == 0) && (offset - 1) != lob_len && !dont_throw_size_doesnt_match_exception) { (void)bind_var->get_var_struct().close_lob(); char var_info[256]; char msg_buf[1024]; OTL_STRCPY_S(msg_buf, sizeof(msg_buf), otl_error_msg_8); otl_var_info_var(bind_var->get_name(), bind_var->get_ftype(), otl_var_long_string, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_tmpl_exception(msg_buf, otl_error_code_8, cursor->get_stm_label() ? cursor->get_stm_label() : cursor->get_stm_text(), var_info))); } if(bind_var){ bind_var->get_var_struct().set_lob_stream_flag(0); bind_var->set_not_null(0); } } } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_tmpl_lob_stream(const otl_tmpl_lob_stream &) = delete; otl_tmpl_lob_stream &operator=(const otl_tmpl_lob_stream &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_lob_stream(otl_tmpl_lob_stream &&) = delete; otl_tmpl_lob_stream &operator=(otl_tmpl_lob_stream &&) = delete; #endif private: #else otl_tmpl_lob_stream(const otl_tmpl_lob_stream &) OTL_NO_THROW : otl_lob_stream_generic(true), bind_var(nullptr), connect(nullptr), cursor(nullptr), temp_buf(nullptr), temp_char_buf(nullptr) {} otl_tmpl_lob_stream &operator=(const otl_tmpl_lob_stream &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_tmpl_lob_stream(otl_tmpl_lob_stream &&) OTL_NO_THROW : otl_lob_stream_generic(true), bind_var(nullptr), connect(nullptr), cursor(nullptr), temp_buf(nullptr), temp_char_buf(nullptr) {} otl_tmpl_lob_stream &operator=(otl_tmpl_lob_stream &&) { return *this; } #endif #endif }; typedef otl_tmpl_lob_stream otl_lob_stream; typedef otl_tmpl_exception otl_exception; typedef otl_tmpl_inout_stream otl_ora8_inout_stream; typedef otl_tmpl_select_stream otl_select_stream; typedef otl_tmpl_ext_hv_decl otl_ext_hv_decl; const int otl_no_stream_type = 0; const int otl_inout_stream_type = 1; const int otl_refcur_stream_type = 2; const int otl_select_stream_type = 3; const int otl_constant_sql_type = 4; const int otl_mixed_refcur_stream_type = 5; class otl_connect : public otl_ora8_connect { protected: #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) otl_stream_pool sc; bool pool_enabled_; #endif public: #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) void set_lob_prefetch_size(const int prefetch_size = 0) OTL_THROWS_OTL_EXCEPTION { if (!connected) return; retcode = connect_struct.set_lob_prefetch_size(prefetch_size); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } #endif #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) otl_stream_pool &get_sc() { return sc; } void set_stream_pool_size(const int max_size = otl_max_default_pool_size) { sc.init(max_size); } void stream_pool_enable() { pool_enabled_ = true; } void stream_pool_disable() { pool_enabled_ = false; } OTL_NODISCARD bool get_stream_pool_enabled_flag() const { return pool_enabled_; } #endif public: long direct_exec(const char *sqlstm, const int exception_enabled = 1) OTL_THROWS_OTL_EXCEPTION { return otl_cursor::direct_exec(*this, sqlstm, exception_enabled); } void syntax_check(const char *sqlstm) OTL_THROWS_OTL_EXCEPTION { otl_cursor::syntax_check(*this, sqlstm); } otl_connect() OTL_NO_THROW : otl_ora8_connect(), #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) sc(), pool_enabled_(true), #endif cmd_(nullptr) { } #if defined(OTL_ORA_OCI_ENV_CREATE) void set_connect_mode(bool threaded_mode = false) { connect_struct.set_threaded_mode(threaded_mode); } #endif #if defined(OTL_UNICODE) || defined(OTL_ORA_UTF8) void set_character_set(const int char_set = SQLCS_IMPLICIT) OTL_THROWS_OTL_EXCEPTION { connect_struct.set_char_set(char_set); } #endif otl_connect(const char *connect_str, const int aauto_commit = 0 #if defined(OTL_ORA_OCI_ENV_CREATE) , bool threaded_mode = false #endif ) OTL_THROWS_OTL_EXCEPTION: otl_ora8_connect(), #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) sc(), pool_enabled_(true), #endif cmd_(nullptr) { #if defined(OTL_ORA_OCI_ENV_CREATE) set_connect_mode(threaded_mode); #endif rlogon(connect_str, aauto_commit); } virtual ~otl_connect() #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW) OTL_THROWS_OTL_EXCEPTION #else OTL_NO_THROW #endif { if (cmd_) { delete[] cmd_; cmd_ = nullptr; } #if defined(OTL_DESTRUCTORS_DO_NOT_THROW) try { #endif logoff(); #if defined(OTL_DESTRUCTORS_DO_NOT_THROW) } catch (OTL_CONST_EXCEPTION otl_exception &) { } #endif } OTL_NODISCARD const char *getCmd(void) const { return cmd_; } otl_connect &operator<<(const char *cmd) { if (!connected) { this->rlogon(cmd); } else { otl_cursor::direct_exec(*this, cmd); } return *this; } otl_connect &operator<<=(const char *cmd) { if (cmd_) { delete[] cmd_; cmd_ = nullptr; } size_t cmd_len = strlen(cmd); cmd_ = new char[cmd_len + 1]; OTL_STRCPY_S(cmd_, cmd_len + 1, cmd); return *this; } OTL_NODISCARD static int otl_terminate(void) OTL_THROWS_OTL_EXCEPTION { #if defined(OTL_ORA8) && !defined(OTL_ORA8I) && !defined(OTL_ORA9I) return 1; #else return OCITerminate(OCI_DEFAULT) == OCI_SUCCESS; #endif } void cancel(void) OTL_THROWS_OTL_EXCEPTION { if (!connected) return; retcode = connect_struct.cancel(); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } #if defined(OTL_ORA10G_R2) void commit_nowait(void) OTL_THROWS_OTL_EXCEPTION { if (!connected) return; retcode = connect_struct.commit_nowait(); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } #endif #if defined(OTL_ORA8I) || defined(OTL_ORA9I) void change_password(const char *user_name, const char *old_password, const char *new_password) OTL_THROWS_OTL_EXCEPTION { retcode = connect_struct.change_password(user_name, old_password, new_password); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } #endif void auto_commit_off(void) OTL_THROWS_OTL_EXCEPTION { otl_ora8_connect::auto_commit_off(); } void auto_commit_on(void) OTL_THROWS_OTL_EXCEPTION { otl_ora8_connect::auto_commit_on(); } void rlogon(OCIEnv *envhp, OCISvcCtx *svchp) OTL_THROWS_OTL_EXCEPTION { if (this->connected) { OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30))); } if (cmd_) { delete[] cmd_; cmd_ = nullptr; } connected = 0; long_max_size = otl_short_int_max; retcode = connect_struct.ext_logon(envhp, svchp, 0); if (retcode) connected = 1; else { connected = 0; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } void rlogon(const char *connect_str, const int aauto_commit = 0, const char *xa_server_external_name = nullptr, const char *xa_server_internal_name = nullptr #if defined(OTL_ORA_OCI_ENV_CREATE) , bool threaded_mode = false #endif ) OTL_THROWS_OTL_EXCEPTION { const char* c=connect_str; while(*c){ if(*c=='@') break; ++c; } if(*c=='@' && *(c+1)==0){ OTL_THROW((otl_exception(otl_error_msg_44, otl_error_code_44))); } if (this->connected) { OTL_THROW((otl_exception(otl_error_msg_30, otl_error_code_30))); } if (cmd_) { delete[] cmd_; cmd_ = nullptr; } if (xa_server_external_name != nullptr && xa_server_internal_name != nullptr) { connect_struct.set_xa_server_external_name(xa_server_external_name); connect_struct.set_xa_server_internal_name(xa_server_internal_name); } #if defined(OTL_ORA_OCI_ENV_CREATE) set_connect_mode(threaded_mode); #endif otl_ora8_connect::rlogon(connect_str, aauto_commit); if (connect_struct.get_last_status() == OCI_SUCCESS_WITH_INFO) { otl_exception ex(connect_struct); if (ex.code != 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((ex)); } } } void logoff(void) OTL_THROWS_OTL_EXCEPTION { #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if (connected) sc.init(sc.get_max_size()); #endif if (!connected) { (void)connect_struct.session_end(); (void)connect_struct.server_detach(); } else { #if defined(OTL_ROLLS_BACK_BEFORE_LOGOFF) otl_ora8_connect::rollback(); #endif OTL_TRACE_FUNC(0x1, "otl_connect", "logoff", "") if (connect_struct.get_extern_lda()) (void)connect_struct.logoff(); else { session_end(); server_detach(); } connected = 0; } } void server_attach(const char *tnsname = nullptr, const char *xa_server_external_name = nullptr, const char *xa_server_internal_name = nullptr #if defined(OTL_ORA_OCI_ENV_CREATE) , bool threaded_mode = false #endif ) OTL_THROWS_OTL_EXCEPTION { if (cmd_) { delete[] cmd_; cmd_ = nullptr; } if (xa_server_external_name != nullptr && xa_server_internal_name != nullptr) { connect_struct.set_xa_server_external_name(xa_server_external_name); connect_struct.set_xa_server_internal_name(xa_server_internal_name); } connected = 0; long_max_size = otl_short_int_max; #if defined(OTL_ORA_OCI_ENV_CREATE) set_connect_mode(threaded_mode); #endif retcode = connect_struct.server_attach(tnsname); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } void server_detach(void) OTL_THROWS_OTL_EXCEPTION { retcode = connect_struct.server_detach(); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } void session_begin( const char *username, const char *password, const int auto_commit = 0, const int session_mode = OCI_DEFAULT, // OCI_SYSDBA -- in this mode, the user is authenticated for SYSDBA // access. // OCI_SYSOPER -- in this mode, the user is authenticated // for SYSOPER access. OCISession* authp1 = nullptr ) OTL_THROWS_OTL_EXCEPTION { if (cmd_) { delete[] cmd_; cmd_ = nullptr; } retcode = connect_struct.session_begin(username, password, auto_commit, session_mode, authp1); if (retcode) connected = 1; else { connected = 0; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } if (connect_struct.get_last_status() == OCI_SUCCESS_WITH_INFO) { otl_exception ex(connect_struct); if (ex.code != 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((ex)); } } } void session_reopen(const int auto_commit = 0) OTL_THROWS_OTL_EXCEPTION { if (connect_struct.get_session_begin_count() == 0) { connected = 0; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(otl_error_msg_11, otl_error_code_11))); } retcode = connect_struct.session_begin(auto_commit); if (retcode) connected = 1; else { connected = 0; OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } if (connect_struct.get_last_status() == OCI_SUCCESS_WITH_INFO) { otl_exception ex(connect_struct); if (ex.code != 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((ex)); } } } void session_end(void) OTL_THROWS_OTL_EXCEPTION { #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if (connected) sc.init(sc.get_max_size()); #endif connected = 0; retcode = connect_struct.session_end(); if (!retcode) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(connect_struct))); } } private: char *cmd_; #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_connect &operator=(const otl_connect &) = delete; otl_connect(const otl_connect &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_connect &operator=(otl_connect &&) = delete; otl_connect(otl_connect &&) = delete; #endif private: #else otl_connect &operator=(const otl_connect &) { return *this; } otl_connect(const otl_connect &) : otl_ora8_connect(), #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) sc(), pool_enabled_(true), #endif cmd_(nullptr) { } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_connect &operator=(otl_connect &&) { return *this; } otl_connect(otl_connect &&) : otl_ora8_connect(), #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) sc(), pool_enabled_(true), #endif cmd_(nullptr) { } #endif #endif }; typedef otl_tmpl_variable otl_generic_variable; typedef otl_generic_variable *otl_p_generic_variable; class otl_refcur_base_cursor : public otl_tmpl_cursor { protected: int cur_row; int cur_size; int row_count; int array_size; public: otl_refcur_base_cursor(otl_connect &db, otl_var *var, const char *master_plsql_block, const otl_stream_buffer_size_type arr_size = 1) : otl_tmpl_cursor(db, var), cur_row(-1), cur_size(0), row_count(0), array_size(arr_size) { size_t len = strlen(master_plsql_block) + 1; stm_text = new char[len]; OTL_STRCPY_S(stm_text, len, master_plsql_block); } otl_refcur_base_cursor() : otl_tmpl_cursor(), cur_row(-1), cur_size(0), row_count(0), array_size(0) {} virtual ~otl_refcur_base_cursor() { delete[] stm_text; stm_text = nullptr; } void open(otl_connect &db, otl_var *var, const char *master_plsql_block, const otl_stream_buffer_size_type arr_size = 1) { cur_row = -1; row_count = 0; cur_size = 0; array_size = arr_size; otl_tmpl_cursor::open(db, var); size_t len = strlen(master_plsql_block) + 1; stm_text = new char[len]; OTL_STRCPY_S(stm_text, len, master_plsql_block); } void close(const char = 'N') { delete[] stm_text; stm_text = nullptr; otl_tmpl_cursor::close(); } OTL_NODISCARD int first(void) { int rc; cur_row = -1; rc = cursor_struct.fetch(OTL_SCAST(otl_stream_buffer_size_type, array_size), eof_data); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text))); } row_count = OTL_SCAST(int, cursor_struct.rpc()); cur_size = row_count; if (cur_size != 0) cur_row = 0; return cur_size != 0; } OTL_NODISCARD int next(void) { int rc; if (cur_row < 0) return first(); if (cur_row < cur_size - 1) ++cur_row; else { if (otl_tmpl_cursor::eof()) { cur_row = -1; return 0; } rc = cursor_struct.fetch( OTL_SCAST(otl_stream_buffer_size_type, array_size), eof_data); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text))); } cur_size = OTL_SCAST(int, cursor_struct.rpc()) - row_count; row_count = OTL_SCAST(int, cursor_struct.rpc()); if (cur_size != 0) cur_row = 0; } return cur_size != 0; } void bind_col(const int column_num, otl_generic_variable &v) { if (!connected) return; v.set_pos(column_num); otl_refcur_base_cursor::bind(column_num, v); } OTL_NODISCARD int describe_select(otl_column_desc *desc, int &desc_len) { int i; desc_len = 0; cursor_struct.straight_select = 0; for (i = 1; describe_column(desc[i - 1], i); ++i) ++desc_len; return 1; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_refcur_base_cursor(const otl_refcur_base_cursor &) = delete; otl_refcur_base_cursor &operator=(const otl_refcur_base_cursor &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_refcur_base_cursor(otl_refcur_base_cursor &&) = delete; otl_refcur_base_cursor &operator=(otl_refcur_base_cursor &&) = delete; #endif private: #else otl_refcur_base_cursor(const otl_refcur_base_cursor &) : otl_tmpl_cursor(), cur_row(-1), cur_size(0), row_count(0), array_size(0) {} otl_refcur_base_cursor &operator=(const otl_refcur_base_cursor &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_refcur_base_cursor(otl_refcur_base_cursor &&) : otl_tmpl_cursor(), cur_row(-1), cur_size(0), row_count(0), array_size(0) {} otl_refcur_base_cursor &operator=(otl_refcur_base_cursor &&) { return *this; } #endif #endif }; #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) #define OTL_ORA_COMMON_READ_STREAM otl_read_stream_interface #define OTL_ORA_REFCUR_COMMON_READ_STREAM otl_read_stream_interface class otl_read_stream_interface { public: virtual ~otl_read_stream_interface() OTL_THROWS_OTL_EXCEPTION {} OTL_NODISCARD virtual int is_null(void) OTL_NO_THROW = 0; virtual void rewind(void) OTL_THROWS_OTL_EXCEPTION = 0; OTL_NODISCARD virtual int eof(void) OTL_THROWS_OTL_EXCEPTION = 0; virtual void skip_to_end_of_row(void) OTL_THROWS_OTL_EXCEPTION = 0; virtual void skip_to_next_var(void) OTL_THROWS_OTL_EXCEPTION = 0; OTL_NODISCARD virtual otl_var_desc *describe_out_vars(int &desc_len) OTL_NO_THROW = 0; OTL_NODISCARD virtual otl_var_desc *describe_next_out_var(void) OTL_NO_THROW = 0; virtual otl_read_stream_interface & operator>>(otl_datetime &s) OTL_THROWS_OTL_EXCEPTION = 0; #if !defined(OTL_UNICODE) virtual otl_read_stream_interface & operator>>(char &c) OTL_THROWS_OTL_EXCEPTION = 0; #endif virtual otl_read_stream_interface & operator>>(unsigned char &c) OTL_THROWS_OTL_EXCEPTION = 0; #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) virtual otl_read_stream_interface & operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION = 0; #endif #if defined(OTL_UNICODE_STRING_TYPE) virtual otl_read_stream_interface & operator>>(OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION = 0; #endif #if !defined(OTL_UNICODE) virtual otl_read_stream_interface & operator>>(char *s) OTL_THROWS_OTL_EXCEPTION = 0; #endif #if defined(OTL_UNICODE) virtual otl_read_stream_interface & operator>>(OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION = 0; #endif virtual otl_read_stream_interface & operator>>(unsigned char *s) OTL_THROWS_OTL_EXCEPTION = 0; #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) virtual otl_read_stream_interface & operator>>(OTL_NUMERIC_TYPE_1 &f) OTL_THROWS_OTL_EXCEPTION = 0; #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) virtual otl_read_stream_interface & operator>>(OTL_NUMERIC_TYPE_2 &f) OTL_THROWS_OTL_EXCEPTION = 0; #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) virtual otl_read_stream_interface & operator>>(OTL_NUMERIC_TYPE_3 &f) OTL_THROWS_OTL_EXCEPTION = 0; #endif #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) virtual otl_read_stream_interface & operator>>(OTL_BIGINT &f) OTL_THROWS_OTL_EXCEPTION = 0; #endif #if defined(OTL_BIGINT) && defined(OTL_STR_TO_BIGINT) && \ defined(OTL_BIGINT_TO_STR) virtual otl_read_stream_interface & operator>>(OTL_BIGINT &f) OTL_THROWS_OTL_EXCEPTION = 0; #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) virtual otl_read_stream_interface & operator>>(OTL_UBIGINT &f) OTL_THROWS_OTL_EXCEPTION = 0; #endif virtual otl_read_stream_interface & operator>>(int &n) OTL_THROWS_OTL_EXCEPTION = 0; virtual otl_read_stream_interface & operator>>(unsigned &u) OTL_THROWS_OTL_EXCEPTION = 0; virtual otl_read_stream_interface & operator>>(short &sh) OTL_THROWS_OTL_EXCEPTION = 0; virtual otl_read_stream_interface & operator>>(long int &l) OTL_THROWS_OTL_EXCEPTION = 0; virtual otl_read_stream_interface & operator>>(float &f) OTL_THROWS_OTL_EXCEPTION = 0; virtual otl_read_stream_interface & operator>>(double &d) OTL_THROWS_OTL_EXCEPTION = 0; virtual otl_read_stream_interface & operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION = 0; virtual otl_read_stream_interface & operator>>(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION = 0; virtual otl_column_desc *describe_select(int &desc_len) OTL_NO_THROW = 0; }; #else #define OTL_ORA_COMMON_READ_STREAM otl_stream #define OTL_ORA_REFCUR_COMMON_READ_STREAM otl_refcur_stream #endif class otl_refcur_stream : #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) public otl_read_stream_interface, #endif public otl_refcur_base_cursor { protected: int delay_next; int same_sl_flag; otl_select_struct_override override_; otl_var_desc *ov; int ov_len; int next_ov_ndx; void inc_next_ov(void) { if (ov_len == 0) return; if (next_ov_ndx < ov_len - 1) ++next_ov_ndx; else next_ov_ndx = 0; } public: void skip_to_end_of_row() OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof()) return; while (cur_col < sl_len - 1) { ++cur_col; null_fetched = sl[cur_col].is_null(this->cur_row); } ret_code = this->next(); cur_col = 0; if (!eof()) cur_col = -1; } void skip_to_next_var() { check_if_executed(); if (eof_intern()) return; get_next(); look_ahead(); } OTL_NODISCARD bool good() const { return get_connected() == 1; } OTL_NODISCARD bool get_lob_stream_flag() const { return true; } OTL_NODISCARD int get_adb_max_long_size() const { return this->adb->get_max_long_size(); } void set_column_type(const int column_ndx, const int col_type, const int col_size = 0) OTL_NO_THROW { override_.add_override(column_ndx, col_type, col_size); } void set_all_column_types(const unsigned mask = 0) OTL_NO_THROW { override_.set_all_column_types(mask); } void cleanup(void) { int i; delete[] sl; delete[] ov; for (i = 0; i < vl_len; ++i) delete vl[i]; delete[] vl; delete[] sl_desc; } otl_refcur_stream() OTL_NO_THROW : otl_refcur_base_cursor(), delay_next(0), same_sl_flag(0), override_(), ov(nullptr), ov_len(0), next_ov_ndx(0), sl_desc(nullptr), sl_len(), sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() { init(); } otl_refcur_stream(const otl_stream_buffer_size_type arr_size, const char *master_plsql_block, otl_var *var, otl_connect &db) OTL_THROWS_OTL_EXCEPTION: otl_refcur_base_cursor(db, var, master_plsql_block, arr_size), delay_next(0), same_sl_flag(0), override_(), ov(nullptr), ov_len(0), next_ov_ndx(0), sl_desc(nullptr), sl_len(), sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() { init(); try { rewind(); null_fetched = 0; } catch (OTL_CONST_EXCEPTION otl_exception &) { cleanup(); throw; } } virtual ~otl_refcur_stream() OTL_THROWS_OTL_EXCEPTION { cleanup(); otl_refcur_stream::close(); } OTL_NODISCARD int is_null(void) OTL_NO_THROW { return null_fetched; } OTL_NODISCARD int eof(void) #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH) OTL_THROWS_OTL_EXCEPTION #else OTL_THROWS_OTL_EXCEPTION #endif { #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH) if (cur_col == sl_len - 1) { get_next(); cur_col = -1; } else { if (delay_next) { look_ahead(); delay_next = 0; } } return !ret_code; #else if (delay_next) { look_ahead(); delay_next = 0; } return !ret_code; #endif } OTL_NODISCARD int eof_intern(void) { return !ret_code; } void check_if_executed(void) {} void open(otl_connect &db, otl_var *var, const char *master_plsql_block, const otl_stream_buffer_size_type arr_size = 1) OTL_THROWS_OTL_EXCEPTION { otl_refcur_base_cursor::open(db, var, master_plsql_block, arr_size); get_select_list(); rewind(); delete[] ov; ov = new otl_var_desc[OTL_SCAST(size_t,sl_len)]; ov_len = sl_len; for (int i = 0; i < sl_len; ++i) { sl[i].copy_var_desc(ov[i]); if (sl_desc != nullptr){ ov[i].copy_name(sl_desc[i].name); ov[i].set_param_type(1); } } } void close(const char = 'N') OTL_THROWS_OTL_EXCEPTION { override_.reset(); otl_refcur_base_cursor::close(); } otl_refcur_stream &operator>>(otl_time0 &t) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_timestamp) && !eof_intern()) { #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) void *tm = OTL_RCAST(void *, sl[cur_col].val(this->cur_row)); int rc = sl[cur_col].get_var_struct().read_dt(&t, tm, sizeof(otl_time0)); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(adb->get_connect_struct(), stm_label ? stm_label : stm_text))); } #else otl_time0 *tm = OTL_RCAST(otl_time0 *, sl[cur_col].val(cur_row)); memcpy(OTL_RCAST(void *, &t), tm, otl_oracle_date_size); #endif look_ahead(); } inc_next_ov(); return *this; } #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) // already declared #else OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(otl_datetime &s) OTL_THROWS_OTL_EXCEPTION { otl_time0 tmp; (*this) >> tmp; #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_DATETIME_NULL_TO_VAL; else { s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 + (OTL_SCAST(int, tmp.year) - 100); s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour - 1; s.minute = tmp.minute - 1; s.second = tmp.second - 1; } #else s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 + (OTL_SCAST(int, tmp.year) - 100); s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour - 1; s.minute = tmp.minute - 1; s.second = tmp.second - 1; #endif inc_next_ov(); return *this; } #endif #if defined(OTL_ORA_SDO_GEOMETRY) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(oci_spatial_geometry &s) OTL_THROWS_OTL_EXCEPTION{ check_if_executed(); if (eof_intern()) return *this; get_next(); if ((sl[cur_col].get_ftype() == otl_var_sdo_geometry) && !eof_intern()){ (void)sl[cur_col].get_var_struct().read_geometry(s, this->cur_row); look_ahead(); } inc_next_ov(); return *this; } #endif OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(char &c) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { c = *OTL_RCAST(char *, sl[cur_col].val(cur_row)); #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL) if ((*this).is_null()) c = OTL_DEFAULT_CHAR_NULL_TO_VAL; #endif look_ahead(); } inc_next_ov(); return *this; } OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(unsigned char &c) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { c = *OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)); #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL) if ((*this).is_null()) c = OTL_DEFAULT_CHAR_NULL_TO_VAL; #endif look_ahead(); } inc_next_ov(); return *this; } #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); switch (sl[cur_col].get_ftype()) { case otl_var_char: if (!eof_intern()) { #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL) if ((*this).is_null()) { OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s); } else #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_STRING_NULL_TO_VAL; else #endif #if defined(OTL_ACE) s.set(OTL_RCAST(char *, sl[cur_col].val(cur_row)), 1); #else s = OTL_RCAST(char *, sl[cur_col].val(cur_row)); #endif look_ahead(); } break; #if defined(USER_DEFINED_STRING_CLASS) || defined(OTL_STL) || defined(OTL_ACE) case otl_var_varchar_long: case otl_var_raw_long: if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)); int len = sl[cur_col].get_len(cur_row); #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(USER_DEFINED_STRING_CLASS)) s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len)); #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, c), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, c), len, 1); #endif look_ahead(); } break; case otl_var_blob: case otl_var_clob: if (!eof_intern()) { int len = 0; int max_long_sz = this->adb->get_max_long_size(); otl_auto_array_ptr loc_ptr(max_long_sz); unsigned char *temp_buf = loc_ptr.get_ptr(); int rc = sl[cur_col].get_var_struct().get_blob(cur_row, temp_buf, max_long_sz, len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(adb->get_connect_struct(), stm_label ? stm_label : stm_text))); } #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(USER_DEFINED_STRING_CLASS)) s.assign(OTL_RCAST(char *, temp_buf), OTL_SCAST(size_t, len)); #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, temp_buf), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, temp_buf), len, 1); #endif look_ahead(); } break; #endif default: (void)check_type(otl_var_char); } // switch inc_next_ov(); return *this; } #endif OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(char *s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { otl_strcpy(OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, sl[cur_col].val(cur_row))); #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif look_ahead(); } inc_next_ov(); return *this; } #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(std::array& s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { if(Nget_stm_text(), this->describe_next_out_var()->name))); otl_strcpy(OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, sl[cur_col].val(cur_row))); #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s.data()), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif look_ahead(); } inc_next_ov(); return *this; } #endif #if defined(OTL_UNICODE_STRING_TYPE) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { #if defined(OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR) OTL_UNICODE_CHAR_TYPE *temp_s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(cur_row)); OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR(s, temp_s + 1, *temp_s); #else OTL_UNICODE_CHAR_TYPE *temp_s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(cur_row)); s.assign(temp_s + 1, *temp_s); #endif #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) s = OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, OTL_DEFAULT_STRING_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } #endif #if defined(OTL_UNICODE) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { otl_strcpy2(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)), sl[cur_col].get_len(cur_row)); #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif look_ahead(); } inc_next_ov(); return *this; } #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(std::array& s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { if(Nget_stm_text(), this->describe_next_out_var()->name))); otl_strcpy2(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)), sl[cur_col].get_len(cur_row)); #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s.data()), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif look_ahead(); } inc_next_ov(); return *this; } #endif #endif OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(unsigned char *s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { otl_strcpy2(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)), sl[cur_col].get_len(cur_row)); #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif look_ahead(); } inc_next_ov(); return *this; } OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(int &n) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_int)) n = OTL_PCONV(int, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) n = OTL_SCAST(int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(OTL_NUMERIC_TYPE_1 &n) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_int)) n = OTL_PCONV(OTL_NUMERIC_TYPE_1, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) n = OTL_SCAST(OTL_NUMERIC_TYPE_1, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(OTL_NUMERIC_TYPE_2 &n) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_int)) n = OTL_PCONV(OTL_NUMERIC_TYPE_2, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) n = OTL_SCAST(OTL_NUMERIC_TYPE_2, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(OTL_NUMERIC_TYPE_3 &n) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_int)) n = OTL_PCONV(OTL_NUMERIC_TYPE_3, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) n = OTL_SCAST(OTL_NUMERIC_TYPE_3, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } #endif #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_int)) n = OTL_PCONV(OTL_BIGINT, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } #endif #if defined(OTL_BIGINT) && defined(OTL_STR_TO_BIGINT) && \ defined(OTL_BIGINT_TO_STR) otl_refcur_stream &operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION { char temp_val[otl_bigint_str_size]; (*this) >> temp_val; if (this->is_null()) { #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (this->is_null()) n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif return *this; } OTL_STR_TO_BIGINT(temp_val, n) return *this; } #elif defined(OTL_BIGINT) && defined(OTL_ORA_MAP_BIGINT_TO_LONG) otl_refcur_stream &operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION { long temp_val; (*this) >> temp_val; if (this->is_null()) { #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (this->is_null()) n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif return *this; } n = OTL_SCAST(OTL_BIGINT, temp_val); return *this; } #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(OTL_UBIGINT &n) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_int)) n = OTL_PCONV(OTL_UBIGINT, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) n = OTL_SCAST(OTL_UBIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } #endif OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(unsigned &u) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), u); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), u); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_unsigned_int)) u = OTL_PCONV(unsigned, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) u = OTL_SCAST(unsigned int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(short &sh) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), sh); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), sh); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_short)) sh = OTL_PCONV(short, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) sh = OTL_SCAST(short int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(long int &l) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), l); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), l); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_long_int)) l = OTL_PCONV(long int, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) l = OTL_SCAST(long int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(float &f) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), f); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), f); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_float)) f = OTL_PCONV(float, double, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) f = OTL_SCAST(float, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(double &d) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T2(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), d); #else int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), d); #endif if (!match_found) { if (check_type(otl_var_double, otl_var_double)) d = *OTL_RCAST(double *, sl[cur_col].val(cur_row)); } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) d = OTL_SCAST(double, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif look_ahead(); } inc_next_ov(); return *this; } OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if (!eof_intern()) { switch (sl[cur_col].get_ftype()) { case otl_var_raw_long: case otl_var_varchar_long: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && sl[cur_col].get_ftype() == otl_var_varchar_long) { OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && sl[cur_col].get_ftype() == otl_var_raw_long) { OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)); int len = sl[cur_col].get_len(cur_row); if (len > s.get_buf_size()) len = s.get_buf_size(); otl_memcpy(s.v, c, len, sl[cur_col].get_ftype()); if (sl[cur_col].get_ftype() == otl_var_varchar_long) s.null_terminate_string(len); s.set_len(len); look_ahead(); } break; case otl_var_blob: case otl_var_clob: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && sl[cur_col].get_ftype() == otl_var_clob) { OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && sl[cur_col].get_ftype() == otl_var_blob) { OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } int len; int rc = sl[cur_col].get_var_struct().get_blob(cur_row, s.v, s.get_buf_size(), len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(adb->get_connect_struct(), stm_label ? stm_label : stm_text))); } s.set_len(len); if (sl[cur_col].get_ftype() == otl_var_clob) s.null_terminate_string(len); look_ahead(); } break; case otl_var_raw: { if (s.get_unicode_flag()) { OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(this->cur_row)); int len2 = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c)); otl_memcpy(s.v, c + sizeof(short int), len2, sl[cur_col].get_ftype()); s.set_len(len2); look_ahead(); } break; } } inc_next_ov(); return *this; } OTL_ORA_REFCUR_COMMON_READ_STREAM & operator>>(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION { check_if_executed(); if (eof_intern()) return *this; get_next(); if ((sl[cur_col].get_ftype() == otl_var_blob || sl[cur_col].get_ftype() == otl_var_clob) && !eof_intern()) { s.init(&sl[cur_col], adb, OTL_SCAST(otl_refcur_base_cursor *, this), cur_row, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode), this->is_null()); delay_next = 1; } inc_next_ov(); return *this; } otl_var_desc *describe_out_vars(int &desc_len) OTL_NO_THROW { desc_len = 0; if (ov == nullptr) return nullptr; desc_len = ov_len; return ov; } otl_var_desc *describe_next_out_var(void) OTL_NO_THROW { if (ov == nullptr) return nullptr; return &ov[next_ov_ndx]; } int select_list_len(void) OTL_NO_THROW { return sl_len; } int column_ftype(int ndx = 0) OTL_NO_THROW { return sl[ndx].get_ftype(); } int column_size(int ndx = 0) OTL_NO_THROW { return sl[ndx].get_elem_size(); } otl_column_desc *describe_select(int &desc_len) OTL_NO_THROW { desc_len = 0; desc_len = sl_len; return sl_desc; } protected: otl_column_desc *sl_desc; int sl_len; otl_generic_variable *sl; int null_fetched; int ret_code; int cur_col; int cur_in; int executed; char var_info[256]; void init(void) { ov = nullptr; ov_len = 0; next_ov_ndx = 0; same_sl_flag = 0; sl = nullptr; sl_len = 0; null_fetched = 0; ret_code = 0; sl_desc = nullptr; executed = 0; cur_in = 0; cur_col = -1; executed = 1; stm_text = nullptr; delay_next = 0; } void get_next(void) { if (cur_col < sl_len - 1) { ++cur_col; null_fetched = sl[cur_col].is_null(cur_row); } else { ret_code = next(); cur_col = 0; } } OTL_NODISCARD int check_type_throw(int type_code, int actual_data_type) { int out_type_code; if (actual_data_type != 0) out_type_code = actual_data_type; else out_type_code = type_code; otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), out_type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0, stm_label ? stm_label : stm_text, var_info))); } OTL_NODISCARD int check_type(int type_code, int actual_data_type = 0) { switch (sl[cur_col].get_ftype()) { case otl_var_timestamp: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: if (type_code == otl_var_timestamp) return 1; break; default: #if defined(OTL_CHECK_OUT_TYPE_FUNC) if ((sl[cur_col].get_ftype() == type_code) || OTL_CHECK_OUT_TYPE_FUNC(sl[cur_col].get_ftype(),type_code)) return 1; break; #else if (sl[cur_col].get_ftype() == type_code) return 1; break; #endif } return check_type_throw(type_code, actual_data_type); } void look_ahead(void) { #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH) #else if (cur_col == sl_len - 1) { ret_code = next(); cur_col = -1; } #endif } void get_select_list(void) { int i, j; otl_auto_array_ptr loc_ptr(otl_var_list_size); otl_column_desc *sl_desc_tmp = loc_ptr.get_ptr(); int sld_tmp_len = 0; int ftype, elem_size; sld_tmp_len = 0; cursor_struct.straight_select = 0; for (i = 1; describe_column(sl_desc_tmp[i - 1], i); ++i) { ++sld_tmp_len; if (sld_tmp_len == loc_ptr.get_arr_size()) { loc_ptr.double_size(); sl_desc_tmp = loc_ptr.get_ptr(); } } sl_len = sld_tmp_len; if (sl) { delete[] sl; sl = nullptr; } sl = new otl_generic_variable[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)]; int max_long_size = this->adb->get_max_long_size(); for (j = 0; j < sl_len; ++j) { otl_generic_variable::map_ftype( sl_desc_tmp[j], max_long_size, ftype, elem_size, override_, j + 1, this->adb->get_connect_struct().get_connection_type()); sl[j].copy_pos(j + 1); #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) if (sl_desc_tmp[j].charset_form == 2) sl[j].get_var_struct().nls_flag = true; #endif sl[j].init(true, ftype, elem_size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb->get_connect_struct() #if defined(OTL_ORA_SDO_GEOMETRY) , 0, sl_desc_tmp[j].colOCIType #endif ); } if (sl_desc) { delete[] sl_desc; sl_desc = nullptr; } sl_desc = new otl_column_desc[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)]; for (i = 0; i < sl_len; ++i) sl_desc[i] = sl_desc_tmp[i]; for (i = 0; i < sl_len; ++i) bind_col(i + 1, sl[i]); } private: void rewind(void) OTL_THROWS_OTL_EXCEPTION { ret_code = first(); null_fetched = 0; cur_col = -1; cur_in = 0; executed = 1; delay_next = 0; } #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_refcur_stream &operator=(const otl_refcur_stream &) = delete; otl_refcur_stream(const otl_refcur_stream &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_refcur_stream &operator=(otl_refcur_stream &&) = delete; otl_refcur_stream(otl_refcur_stream &&) = delete; #endif private: #else otl_refcur_stream &operator=(const otl_refcur_stream &) { return *this; } otl_refcur_stream(const otl_refcur_stream &) : #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) otl_read_stream_interface(), #endif otl_refcur_base_cursor(), delay_next(0), same_sl_flag(0), override_(), ov(nullptr), ov_len(0), next_ov_ndx(0), sl_desc(nullptr), sl_len(), sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() { } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_refcur_stream &operator=(otl_refcur_stream &&) { return *this; } otl_refcur_stream(otl_refcur_stream &&) : #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) otl_read_stream_interface(), #endif otl_refcur_base_cursor(), delay_next(0), same_sl_flag(0), override_(), ov(nullptr), ov_len(0), next_ov_ndx(0), sl_desc(nullptr), sl_len(), sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() { } #endif #endif }; class otl_inout_stream : public otl_ora8_inout_stream { public: otl_inout_stream(otl_stream_buffer_size_type arr_size, const char *sqlstm, otl_connect &db, void *master_stream_ptr, const bool alob_stream_mode = false, const char *sqlstm_label = nullptr) : otl_ora8_inout_stream(arr_size, sqlstm, db, master_stream_ptr, alob_stream_mode, sqlstm_label), adb2(&db) {} otl_inout_stream &operator>>(otl_refcur_stream &str) { if (eof()) return *this; if (check_in_type(otl_var_refcur, 1)) { if (str.get_connected()) str.close(); str.open(*adb2, &(in_vl[cur_in_x]->get_var_struct()), stm_text, OTL_SCAST(/*const*/ otl_stream_buffer_size_type, in_vl[cur_in_x]->get_var_struct().array_size)); null_fetched = 0; } get_in_next(); return *this; } #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) otl_inout_stream &operator<<(OTL_STD_STRING_VIEW_CLASS s) { otl_ora8_inout_stream::operator<<(s); return *this; } #endif #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) otl_inout_stream &operator>>(OTL_STRING_CONTAINER &s) { otl_ora8_inout_stream::operator>>(s); return *this; } otl_inout_stream &operator<<(const OTL_STRING_CONTAINER &s) { otl_ora8_inout_stream::operator<<(s); return *this; } #endif otl_inout_stream &operator<<(OTL_NULL_PARM n) { otl_ora8_inout_stream::operator<<(n); return *this; } #if defined(OTL_PL_TAB) && defined(OTL_STL) otl_inout_stream &operator>>(otl_pl_vec_generic &tab) { otl_ora8_inout_stream::operator>>(tab); return *this; } otl_inout_stream &operator<<(otl_pl_vec_generic &tab) { otl_ora8_inout_stream::operator<<(tab); return *this; } #endif otl_inout_stream &operator>>(otl_pl_tab_generic &tab) { otl_ora8_inout_stream::operator>>(tab); return *this; } otl_inout_stream &operator<<(otl_pl_tab_generic &tab) { otl_ora8_inout_stream::operator<<(tab); return *this; } otl_inout_stream &operator>>(otl_time0 &s) { otl_ora8_inout_stream::operator>>(s); return *this; } otl_inout_stream &operator<<(const otl_time0 &s) { otl_ora8_inout_stream::operator<<(s); return *this; } otl_inout_stream &operator>>(char &c) { otl_ora8_inout_stream::operator>>(c); return *this; } otl_inout_stream &operator<<(const char c) { otl_ora8_inout_stream::operator<<(c); return *this; } otl_inout_stream &operator>>(unsigned char &c) { otl_ora8_inout_stream::operator>>(c); return *this; } #if defined(OTL_UNICODE_STRING_TYPE) otl_inout_stream &operator>>(OTL_UNICODE_STRING_TYPE &s) { otl_ora8_inout_stream::operator>>(s); return *this; } otl_inout_stream &operator<<(const OTL_UNICODE_STRING_TYPE &s) { otl_ora8_inout_stream::operator<<(s); return *this; } #endif #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)) otl_inout_stream &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) { otl_ora8_inout_stream::operator<<(s); return *this; } #endif otl_inout_stream &operator<<(const unsigned char c) { otl_ora8_inout_stream::operator<<(c); return *this; } otl_inout_stream &operator>>(char *s) { otl_ora8_inout_stream::operator>>(s); return *this; } otl_inout_stream &operator<<(const char *s) { otl_ora8_inout_stream::operator<<(s); return *this; } #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template otl_inout_stream &operator>>(std::array& s) { otl_ora8_inout_stream::getString(s.data(),OTL_SCAST(int,s.size())); return *this; } template otl_inout_stream &operator<<(const std::array& s) { otl_ora8_inout_stream::operator<<(s); return *this; } #endif #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE) template otl_inout_stream &operator>>(std::array& s) { otl_ora8_inout_stream::getString(s.data(),OTL_SCAST(int,s.size())); return *this; } template otl_inout_stream &operator<<(const std::array& s) { otl_ora8_inout_stream::operator<<(s); return *this; } #endif otl_inout_stream &operator>>(unsigned char *s) { otl_ora8_inout_stream::operator>>(s); return *this; } otl_inout_stream &operator<<(const unsigned char *s) { otl_ora8_inout_stream::operator<<(s); return *this; } #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) otl_inout_stream &operator>>(OTL_BIGINT &n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator>>(n); #else otl_ora8_inout_stream::operator>>(n); #endif return *this; } #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) otl_inout_stream &operator>>(OTL_UBIGINT &n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator>>(n); #else otl_ora8_inout_stream::operator>>(n); #endif return *this; } #endif otl_inout_stream &operator>>(int &n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator>>(n); #else otl_ora8_inout_stream::operator>>(n); #endif return *this; } #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) otl_inout_stream &operator<<(const OTL_BIGINT n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator<<(n); #else otl_ora8_inout_stream::operator<<(n); #endif return *this; } #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) otl_inout_stream &operator<<(const OTL_UBIGINT n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator<<(n); #else otl_ora8_inout_stream::operator<<(n); #endif return *this; } #endif otl_inout_stream &operator<<(const int n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator<<(n); #else otl_ora8_inout_stream::operator<<(n); #endif return *this; } otl_inout_stream &operator>>(float &n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator>>(n); #else otl_ora8_inout_stream::operator>>(n); #endif return *this; } otl_inout_stream &operator<<(const float n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator<<(n); #else otl_ora8_inout_stream::operator<<(n); #endif return *this; } otl_inout_stream &operator>>(double &n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator>>(n); #else otl_ora8_inout_stream::operator>>(n); #endif return *this; } otl_inout_stream &operator<<(const double n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator<<(n); #else otl_ora8_inout_stream::operator<<(n); #endif return *this; } otl_inout_stream &operator>>(short int &n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator>>(n); #else otl_ora8_inout_stream::operator>>(n); #endif return *this; } otl_inout_stream &operator<<(const short int n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator<<(n); #else otl_ora8_inout_stream::operator<<(n); #endif return *this; } otl_inout_stream &operator>>(unsigned int &n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator>>(n); #else otl_ora8_inout_stream::operator>>(n); #endif return *this; } otl_inout_stream &operator<<(const unsigned int n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator<<(n); #else otl_ora8_inout_stream::operator<<(n); #endif return *this; } otl_inout_stream &operator>>(long int &n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator>>(n); #else otl_ora8_inout_stream::operator>>(n); #endif return *this; } otl_inout_stream &operator<<(const long int n) { #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) otl_ora8_inout_stream::operator<<(n); #else otl_ora8_inout_stream::operator<<(n); #endif return *this; } otl_inout_stream &operator>>(otl_long_string &n) { otl_ora8_inout_stream::operator>>(n); return *this; } otl_inout_stream &operator<<(const otl_long_string &n) { otl_ora8_inout_stream::operator<<(n); return *this; } otl_inout_stream &operator>>(otl_lob_stream &n) { otl_ora8_inout_stream::operator>>(n); return *this; } otl_inout_stream &operator<<(otl_lob_stream &s) { otl_ora8_inout_stream::operator<<(s); return *this; } #if defined(OTL_ORA_SDO_GEOMETRY) otl_inout_stream &operator >> (oci_spatial_geometry &n){ otl_ora8_inout_stream::operator >> (n); return *this; } otl_inout_stream &operator<<(const oci_spatial_geometry &s){ otl_ora8_inout_stream::operator<< (s); return *this; } #endif protected: otl_connect *adb2; private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_inout_stream(const otl_inout_stream &) = delete; otl_inout_stream &operator=(const otl_inout_stream &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_inout_stream(otl_inout_stream &&) = delete; otl_inout_stream &operator=(otl_inout_stream &&) = delete; #endif private: #else otl_inout_stream(const otl_inout_stream &) : otl_ora8_inout_stream(), adb2(nullptr) {} otl_inout_stream &operator=(const otl_inout_stream &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_inout_stream(otl_inout_stream &&) : otl_ora8_inout_stream(), adb2(nullptr) {} otl_inout_stream &operator=(otl_inout_stream &&) { return *this; } #endif #endif }; // ============ OTL Reference Cursor Streams for Oracle 8 ================= class otl_cur; class otl_ref_cursor : public otl_tmpl_cursor { protected: friend class otl_cur; int cur_row; int cur_size; int row_count; int array_size; otl_select_struct_override local_override; public: otl_ref_cursor(otl_connect &db, const char *cur_placeholder_name, void *master_stream_ptr, const otl_stream_buffer_size_type arr_size = 1) : otl_tmpl_cursor(db), cur_row(-1), cur_size(0), row_count(0), array_size(arr_size), local_override(), sel_cur(), rvl_len(otl_var_list_size), rvl(new otl_p_generic_variable[OTL_SCAST(size_t,rvl_len)]), vl_cur_len(0), cur_placeholder(), master_stream_ptr_(master_stream_ptr) { int i; local_override.reset(); for (i = 0; i < rvl_len; ++i) rvl[i] = nullptr; OTL_STRCPY_S(cur_placeholder, sizeof(cur_placeholder), cur_placeholder_name); } otl_ref_cursor() : otl_tmpl_cursor(), cur_row(-1), cur_size(0), row_count(0), array_size(0), local_override(), sel_cur(), rvl_len(0), rvl(nullptr), vl_cur_len(0), cur_placeholder(), master_stream_ptr_(nullptr) { local_override.reset(); } virtual ~otl_ref_cursor() { delete[] rvl; rvl = nullptr; } void open(otl_connect &db, const char *cur_placeholder_name, const otl_stream_buffer_size_type arr_size = 1) { int i; local_override.reset(); cur_row = -1; row_count = 0; cur_size = 0; array_size = arr_size; rvl_len = otl_var_list_size; vl_cur_len = 0; rvl = new otl_p_generic_variable[OTL_SCAST(size_t,rvl_len)]; for (i = 0; i < rvl_len; ++i) rvl[i] = nullptr; OTL_STRCPY_S(cur_placeholder, sizeof(cur_placeholder), cur_placeholder_name); if (!sel_cur.get_connected()) sel_cur.open(db); otl_tmpl_cursor::open(db); } void release_sel_cur(void) { #if defined(OTL_ORA8_8I_REFCUR) return; #else char tmp_buf[256]; OCIBind *bindpp; int rc; if (!sel_cur.get_connected()) return; OTL_STRCPY_S(tmp_buf, sizeof(tmp_buf), "begin close "); OTL_STRCAT_S(tmp_buf, sizeof(tmp_buf)-strlen(tmp_buf)-1, cur_placeholder); OTL_STRCAT_S(tmp_buf, sizeof(tmp_buf)-strlen(tmp_buf)-1, "; end;"); otl_tmpl_cursor::parse(tmp_buf); rc = OCIBindByName(cursor_struct.cda, &bindpp, cursor_struct.errhp, OTL_RCAST(text *, cur_placeholder), OTL_SCAST(sb4, strlen(cur_placeholder)), OTL_RCAST(dvoid *, &sel_cur.get_cursor_struct().cda), 0, SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr, OTL_SCAST(ub4, OCI_DEFAULT)); if (rc != 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text))); } otl_tmpl_cursor::exec( 1, 0, otl_sql_exec_from_select_cursor_class); #endif } void close(const char = 'N') { local_override.reset(); delete[] rvl; rvl = nullptr; release_sel_cur(); sel_cur.close('Y'); otl_tmpl_cursor::close(); } OTL_NODISCARD int first(void) { int i, rc; OCIBind *bindpp; if (!sel_cur.get_connected()) { sel_cur.open(*adb); rc = OCIBindByName(cursor_struct.cda, &bindpp, cursor_struct.errhp, OTL_RCAST(text *, cur_placeholder), OTL_SCAST(sb4, strlen(cur_placeholder)), OTL_RCAST(dvoid *, &sel_cur.get_cursor_struct().cda), 0, SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr, OTL_SCAST(ub4, OCI_DEFAULT)); if (rc != 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text))); } } if (cur_row == -2) ; // Special case -- calling describe_select() between parse() and first() else { // Executing the PLSQL master block exec(1, 0, otl_sql_exec_from_select_cursor_class); sel_cur.set_connected(1); } cur_row = -1; for (i = 0; i < vl_cur_len; ++i) sel_cur.bind(i + 1, *rvl[i]); rc = sel_cur.get_cursor_struct().fetch( OTL_SCAST(otl_stream_buffer_size_type, array_size), sel_cur.get_eof_data_ref()); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(sel_cur.get_cursor_struct(), stm_label ? stm_label : stm_text))); } row_count = OTL_SCAST(int, sel_cur.get_cursor_struct().rpc()); OTL_TRACE_FIRST_FETCH cur_size = row_count; if (cur_size != 0) cur_row = 0; return cur_size != 0; } OTL_NODISCARD int next(void) { int rc; if (cur_row < 0) return first(); if (cur_row < cur_size - 1) ++cur_row; else { if (sel_cur.eof()) { cur_row = -1; return 0; } rc = sel_cur.get_cursor_struct().fetch( OTL_SCAST(otl_stream_buffer_size_type, array_size), sel_cur.get_eof_data_ref()); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(sel_cur.get_cursor_struct(), stm_label ? stm_label : stm_text))); } cur_size = OTL_SCAST(int, sel_cur.get_cursor_struct().rpc()) - row_count; row_count = OTL_SCAST(int, sel_cur.get_cursor_struct().rpc()); OTL_TRACE_NEXT_FETCH2 if (cur_size != 0) cur_row = 0; } return cur_size != 0; } void bind(const int column_num, otl_generic_variable &v) { if (!connected) return; ++vl_cur_len; if (vl_cur_len == rvl_len) { int temp_rvl_len = rvl_len * 2; otl_p_generic_variable *temp_rvl = new otl_p_generic_variable[OTL_SCAST(size_t,temp_rvl_len)]; int i; for (i = 0; i < rvl_len; ++i) temp_rvl[i] = rvl[i]; for (i = rvl_len + 1; i < temp_rvl_len; ++i) temp_rvl[i] = nullptr; delete[] rvl; rvl = temp_rvl; rvl_len = temp_rvl_len; } rvl[vl_cur_len - 1] = &v; v.set_pos(column_num); } void bind(otl_generic_variable &v) { if (v.get_pos()) bind(v.get_pos(), v); else if (v.get_name()) otl_tmpl_cursor::bind(v); } void bind(const char *name, otl_generic_variable &v) { otl_tmpl_cursor::bind(name, v); } OTL_NODISCARD int describe_select(otl_column_desc *desc, int &desc_len) { int i, rc; OCIBind *bindpp; if (!sel_cur.get_connected()) { sel_cur.open(*adb); rc = OCIBindByName(cursor_struct.cda, &bindpp, cursor_struct.errhp, OTL_RCAST(text *, cur_placeholder), OTL_SCAST(sb4, strlen(cur_placeholder)), OTL_RCAST(dvoid *, &sel_cur.get_cursor_struct().cda), 0, SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr, OTL_SCAST(ub4, OCI_DEFAULT)); if (rc != 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text))); } } // Executing the PLSQL master block exec(1, 0, otl_sql_exec_from_select_cursor_class); sel_cur.set_connected(1); cur_row = -2; // Special case -- describe_select() before first() or next() desc_len = 0; sel_cur.get_cursor_struct().straight_select = 0; for (i = 1; sel_cur.describe_column(desc[i - 1], i); ++i) ++desc_len; return 1; } public: otl_cursor sel_cur; protected: int rvl_len; otl_p_generic_variable *rvl; int vl_cur_len; char cur_placeholder[64]; void *master_stream_ptr_; private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_ref_cursor(const otl_ref_cursor &) = delete; otl_ref_cursor &operator=(const otl_ref_cursor &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_ref_cursor(otl_ref_cursor &&) = delete; otl_ref_cursor &operator=(otl_ref_cursor &&) = delete; #endif private: #else otl_ref_cursor(const otl_ref_cursor &) : otl_tmpl_cursor(), cur_row(-1), cur_size(0), row_count(0), array_size(0), local_override(), sel_cur(), rvl_len(0), rvl(nullptr), vl_cur_len(0), cur_placeholder(), master_stream_ptr_(nullptr) {} otl_ref_cursor &operator=(const otl_ref_cursor &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_ref_cursor(otl_ref_cursor &&) : otl_tmpl_cursor(), cur_row(-1), cur_size(0), row_count(0), array_size(0), local_override(), sel_cur(), rvl_len(0), rvl(nullptr), vl_cur_len(0), cur_placeholder(), master_stream_ptr_(nullptr) {} otl_ref_cursor &operator=(otl_ref_cursor &&) { return *this; } #endif #endif }; class otl_ref_select_stream : public otl_ref_cursor { protected: otl_select_struct_override *override_; int delay_next; int same_sl_flag; long _rfc; public: void skip_to_end_of_row() { check_if_executed(); if (eof()) return; while (cur_col < sl_len - 1) { ++cur_col; null_fetched = sl[cur_col].is_null(this->cur_row); } ret_code = this->next(); cur_col = 0; if (!eof()) cur_col = -1; ++_rfc; } void skip_to_next_var() { check_if_executed(); if (eof_intern()) return; get_next(); look_ahead(); } OTL_NODISCARD int get_select_row_count() const { return this->cur_row == -1 ? 0 : this->cur_size - this->cur_row; } OTL_NODISCARD int get_prefetched_row_count() const { return this->row_count; } OTL_NODISCARD long get_rfc() const { return _rfc; } void cleanup(void) { int i; delete[] sl; for (i = 0; i < vl_len; ++i) delete vl[i]; delete[] vl; delete[] sl_desc; } otl_ref_select_stream(otl_select_struct_override *aoverride, const otl_stream_buffer_size_type arr_size, const char *sqlstm, const char *acur_placeholder, otl_connect &db, const char *sqlstm_label = nullptr) : otl_ref_cursor(db, acur_placeholder, aoverride->get_master_stream_ptr(), arr_size), override_(nullptr), delay_next(0), same_sl_flag(0), _rfc(0), sl_desc(nullptr), sl_len(0), sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() { if (sqlstm_label != nullptr) { if (stm_label != nullptr) { delete[] stm_label; stm_label = nullptr; } size_t len = strlen(sqlstm_label) + 1; stm_label = new char[len]; OTL_STRCPY_S(stm_label, len, sqlstm_label); } init(); override_ = aoverride; { size_t len = strlen(sqlstm) + 1; stm_text = new char[len]; OTL_STRCPY_S(stm_text, len, sqlstm); otl_select_struct_override *temp_local_override = &this->local_override; otl_ext_hv_decl hvd(this->stm_text, 1, this->stm_label, &temp_local_override, adb); hvd.alloc_host_var_list(vl, vl_len, *adb); if (temp_local_override != &this->local_override) delete temp_local_override; } try { parse(); if (vl_len == 0) { rewind(); null_fetched = 0; } } catch (OTL_CONST_EXCEPTION otl_exception &) { cleanup(); throw; } } virtual ~otl_ref_select_stream() OTL_THROWS_OTL_EXCEPTION { cleanup(); close(); } void rewind(void) { OTL_TRACE_STREAM_EXECUTION _rfc = 0; get_select_list(); ret_code = first(); null_fetched = 0; cur_col = -1; cur_in = 0; executed = 1; delay_next = 0; } void clean(void) { _rfc = 0; null_fetched = 0; cur_col = -1; cur_in = 0; executed = 0; delay_next = 0; } OTL_NODISCARD int is_null(void) { return null_fetched; } OTL_NODISCARD int eof(void) { #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH) if (cur_col == sl_len - 1) { get_next(); cur_col = -1; } else { if (delay_next) { look_ahead(); delay_next = 0; } } return !ret_code; #else if (delay_next) { look_ahead(); delay_next = 0; } return !ret_code; #endif } OTL_NODISCARD int eof_intern(void) { return !ret_code; } otl_ref_select_stream &operator>>(otl_time0 &t) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_timestamp) && !eof_intern()) { #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) void *tm = OTL_RCAST(void *, sl[cur_col].val(this->cur_row)); int rc = sl[cur_col].get_var_struct().read_dt(&t, tm, sizeof(otl_time0)); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(adb->get_connect_struct(), stm_label ? stm_label : stm_text))); } #else otl_time0 *tm = OTL_RCAST(otl_time0 *, sl[cur_col].val(cur_row)); memcpy(OTL_RCAST(void *, &t), tm, otl_oracle_date_size); #endif look_ahead(); } return *this; } otl_ref_select_stream &operator<<(const otl_time0 &t) { check_in_var(); if (check_in_type(otl_var_timestamp, otl_oracle_date_size)) { #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) void *tm = OTL_RCAST(void *, vl[cur_in]->val()); int rc = vl[cur_in]->get_var_struct().write_dt(tm, &t, sizeof(otl_time0)); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(adb->get_connect_struct(), stm_label ? stm_label : stm_text))); } #else otl_time0 *tm = OTL_RCAST(otl_time0 *, vl[cur_in]->val()); otl_time0 *tp = OTL_CCAST(otl_time0 *, &t); *tm=*tp; #endif } this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } otl_ref_select_stream &operator<<(const otl_long_string &s) { if (s.get_unicode_flag()) { OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } check_in_var(); if (check_in_type(otl_var_raw, 1)) { unsigned char *c = OTL_RCAST(unsigned char *, vl[cur_in]->val()); int len = OTL_CCAST(otl_long_string *, &s)->len(); if (len > this->vl[cur_in]->actual_elem_size()) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_raw, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_in]->set_not_null(0); otl_memcpy(c + sizeof(unsigned short), s.v, len, this->vl[cur_in]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) = OTL_SCAST(unsigned short, len); this->vl[cur_in]->set_len(len, 0); } get_in_next(); return *this; } otl_ref_select_stream &operator>>(char &c) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { c = *OTL_RCAST(char *, sl[cur_col].val(cur_row)); look_ahead(); } return *this; } otl_ref_select_stream &operator>>(unsigned char &c) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { c = *OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)); look_ahead(); } return *this; } #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) otl_ref_select_stream &operator>>(OTL_STRING_CONTAINER &s) { check_if_executed(); if (eof_intern()) return *this; get_next(); switch (sl[cur_col].get_ftype()) { case otl_var_char: if (!eof_intern()) { #if defined(OTL_ACE) s.set(OTL_RCAST(char *, sl[cur_col].val(cur_row)), 1); #else s = OTL_RCAST(char *, sl[cur_col].val(cur_row)); #endif look_ahead(); } break; #if defined(USER_DEFINED_STRING_CLASS) || defined(OTL_STL) || defined(OTL_ACE) case otl_var_varchar_long: case otl_var_raw_long: if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)); int len = sl[cur_col].get_len(cur_row); #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(USER_DEFINED_STRING_CLASS)) s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len)); #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, c), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, c), len, 1); #endif look_ahead(); } break; case otl_var_raw: { if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)); int len = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c)); c += sizeof(short int); #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(USER_DEFINED_STRING_CLASS)) s.assign(OTL_RCAST(char *, c), OTL_SCAST(size_t, len)); #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, c), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, c), len, 1); #endif look_ahead(); } } break; case otl_var_blob: case otl_var_clob: if (!eof_intern()) { int len = 0; int max_long_sz = this->adb->get_max_long_size(); otl_auto_array_ptr loc_ptr(max_long_sz); unsigned char *temp_buf = loc_ptr.get_ptr(); int rc = sl[cur_col].get_var_struct().get_blob(cur_row, temp_buf, max_long_sz, len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(adb->get_connect_struct(), stm_label ? stm_label : stm_text))); } #if (defined(OTL_STL) && !defined(OTL_ACE) && \ !defined(USER_DEFINED_STRING_CLASS)) s.assign(OTL_RCAST(char *, temp_buf), OTL_SCAST(size_t, len)); #elif(defined(USER_DEFINED_STRING_CLASS) && !defined(OTL_ACE)) s.assign(OTL_RCAST(char *, temp_buf), len); #elif defined(OTL_ACE) s.set(OTL_RCAST(char *, temp_buf), len, 1); #endif look_ahead(); } break; #endif default: (void)check_type(otl_var_char); } // switch return *this; } #endif otl_ref_select_stream &operator>>(char *s) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { otl_strcpy(OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, sl[cur_col].val(cur_row))); look_ahead(); } return *this; } #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template otl_ref_select_stream &operator>>(std::array& s) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { if(OTL_SCAST(int,N)stm_label ? this->stm_label : this->stm_text, var_info))); } otl_strcpy(OTL_RCAST(unsigned char*, s.data()), OTL_RCAST(const unsigned char *, sl[cur_col].val(cur_row))); look_ahead(); } return *this; } template otl_ref_select_stream &operator<<(const std::array& s){ (*this)<>(OTL_UNICODE_STRING_TYPE &s) { check_if_executed(); if (eof_intern()) return *this; get_next(); switch (sl[cur_col].get_ftype()) { case otl_var_char: if (!eof_intern()) { #if defined(OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR) OTL_UNICODE_CHAR_TYPE *temp_s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row)); OTL_UNICODE_STRING_TYPE_CAST_FROM_CHAR(s, temp_s + 1, *temp_s); #else OTL_UNICODE_CHAR_TYPE *temp_s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row)); s.assign(temp_s + 1, *temp_s); #endif look_ahead(); } break; case otl_var_varchar_long: if (!eof_intern()) { s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, sl[cur_col].val(this->cur_row)); look_ahead(); } break; case otl_var_clob: if (!eof_intern()) { int len = 0; int max_long_sz = this->adb->get_max_long_size(); otl_auto_array_ptr loc_ptr(max_long_sz); unsigned char *temp_buf = OTL_RCAST(unsigned char *, loc_ptr.get_ptr()); int rc = sl[cur_col].get_var_struct().get_blob(this->cur_row, temp_buf, max_long_sz, len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(this->adb->get_connect_struct(), this->stm_label ? this->stm_label : this->stm_text))); } s = OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, temp_buf); look_ahead(); } break; default: (void)check_type(otl_var_char); } return *this; } #endif otl_ref_select_stream &operator>>(unsigned char *s) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { otl_strcpy2(OTL_RCAST(unsigned char *, s), OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)), sl[cur_col].get_len(cur_row)); look_ahead(); } return *this; } #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE) template otl_ref_select_stream &operator>>(std::array& s) { check_if_executed(); if (eof_intern()) return *this; get_next(); if (check_type(otl_var_char) && !eof_intern()) { if(OTL_SCAST(int,N)stm_label ? this->stm_label : this->stm_text, var_info))); } otl_strcpy2(OTL_RCAST(unsigned char *, s.data()), OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)), sl[cur_col].get_len(cur_row)); look_ahead(); } return *this; } #endif #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) #if !defined(OTL_D7) #define OTL_D7(T, T_type) \ otl_ref_select_stream &operator>>(T &n) { \ check_if_executed(); \ if (eof_intern()) \ return *this; \ get_next(); \ if (!eof_intern()) { \ int match_found = otl_numeric_convert_T( \ sl[cur_col].get_ftype(), sl[cur_col].val(cur_row), n); \ if (!match_found) \ strict_check_throw(T_type); \ look_ahead(); \ } \ return *this; \ } #endif #else #if !defined(OTL_D7) #define OTL_D7(T, T_type) \ otl_ref_select_stream &operator>>(T &n) { \ check_if_executed(); \ if (eof_intern()) \ return *this; \ get_next(); \ if (!eof_intern()) { \ int match_found = otl_numeric_convert_T(sl[cur_col].get_ftype(), \ sl[cur_col].val(cur_row), n); \ if (!match_found) { \ if (check_type(otl_var_double, T_type)) \ n = OTL_PCONV(T, double, sl[cur_col].val(cur_row)); \ } \ look_ahead(); \ } \ return *this; \ } #endif #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) OTL_D7(int, otl_var_int) OTL_D7(unsigned, otl_var_unsigned_int) OTL_D7(long, otl_var_long_int) OTL_D7(short, otl_var_short) OTL_D7(float, otl_var_float) OTL_D7(double, otl_var_double) #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) OTL_D7(OTL_BIGINT, otl_var_bigint) #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) OTL_D7(OTL_UBIGINT, otl_var_ubigint) #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) && \ !defined(OTL_NUMERIC_TYPE_1_NO_NUMERIC_STATIC_CASTS) OTL_D7(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1) #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) && \ !defined(OTL_NUMERIC_TYPE_2_NO_NUMERIC_STATIC_CASTS) OTL_D7(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2) #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) && \ !defined(OTL_NUMERIC_TYPE_3_NO_NUMERIC_STATIC_CASTS) OTL_D7(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3) #endif #else template OTL_D7(T,T_type) #endif otl_ref_select_stream &operator>>(otl_long_string &s) { check_if_executed(); if (eof_intern()) return *this; get_next(); switch (sl[cur_col].get_ftype()) { case otl_var_varchar_long: case otl_var_raw_long: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && sl[cur_col].get_ftype() == otl_var_varchar_long) { OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && sl[cur_col].get_ftype() == otl_var_raw_long) { OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)); int len = sl[cur_col].get_len(cur_row); if (len > s.get_buf_size()) len = s.get_buf_size(); otl_memcpy(s.v, c, len, sl[cur_col].get_ftype()); s.v[len] = 0; s.set_len(len); look_ahead(); } } break; case otl_var_raw: { if (s.get_unicode_flag()) { OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } if (!eof_intern()) { unsigned char *c = OTL_RCAST(unsigned char *, sl[cur_col].val(cur_row)); int len = OTL_SCAST(int, *OTL_RCAST(unsigned short *, c)); if (len > s.get_buf_size()) len = s.get_buf_size(); otl_memcpy(s.v, c + sizeof(short int), len, sl[cur_col].get_ftype()); s.set_len(len); look_ahead(); } } break; case otl_var_blob: case otl_var_clob: { bool in_unicode_mode = sizeof(OTL_CHAR) > 1; if (!s.get_unicode_flag() && in_unicode_mode && sl[cur_col].get_ftype() == otl_var_clob) { OTL_THROW((otl_exception(otl_error_msg_37, otl_error_code_37, this->stm_label ? this->stm_label : this->stm_text))); } else if (s.get_unicode_flag() && sl[cur_col].get_ftype() == otl_var_blob) { OTL_THROW((otl_exception(otl_error_msg_38, otl_error_code_38, this->stm_label ? this->stm_label : this->stm_text))); } if (!eof_intern()) { int len; int rc = sl[cur_col].get_var_struct().get_blob(cur_row, s.v, s.get_buf_size(), len); if (rc == 0) { OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(adb->get_connect_struct(), stm_label ? stm_label : stm_text))); } s.set_len(len); if (sl[cur_col].get_ftype() == otl_var_clob) s.null_terminate_string(len); look_ahead(); } } break; } return *this; } otl_ref_select_stream &operator>>(otl_lob_stream &s) { check_if_executed(); if (eof_intern()) return *this; get_next(); if ((sl[cur_col].get_ftype() == otl_var_blob || sl[cur_col].get_ftype() == otl_var_clob) && !eof_intern()) { s.init(&sl[cur_col], adb, OTL_RCAST(otl_ref_cursor *, this), cur_row, OTL_SCAST(int,OTL_LOB_STREAM_MODE_ENUM otl_lob_stream_read_mode), this->is_null()); delay_next = 1; } return *this; } #if defined(OTL_ORA_SDO_GEOMETRY) otl_ref_select_stream &operator >> (oci_spatial_geometry &s){ check_if_executed(); if(eof_intern()) return *this; get_next(); if(check_type(otl_var_sdo_geometry) && !eof_intern()){ (void)sl[cur_col].get_var_struct().read_geometry(s, cur_row); look_ahead(); } return *this; } #endif otl_ref_select_stream &operator<<(OTL_NULL_PARM /*n*/) { check_in_var(); this->vl[cur_in]->set_null(0); get_in_next(); return *this; } otl_ref_select_stream &operator<<(const char c) { check_in_var(); if (check_in_type(otl_var_char, 1)) { char *tmp = OTL_RCAST(char *, vl[cur_in]->val()); tmp[0] = c; tmp[1] = 0; } this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } otl_ref_select_stream &operator<<(const unsigned char c) { check_in_var(); if (check_in_type(otl_var_char, 1)) { unsigned char *tmp = OTL_RCAST(unsigned char *, vl[cur_in]->val()); tmp[0] = c; tmp[1] = 0; } this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) otl_ref_select_stream &operator<<(OTL_STD_STRING_VIEW_CLASS s) { check_in_var(); if (this->vl[cur_in]->get_ftype() == otl_var_raw) { unsigned char *c = OTL_RCAST(unsigned char *, vl[cur_in]->val()); int len = OTL_SCAST(int, s.length()); if (len > this->vl[cur_in]->actual_elem_size()) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_raw, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_in]->set_not_null(0); otl_memcpy(c + sizeof(unsigned short), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), len, this->vl[cur_in]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) = OTL_SCAST(unsigned short, len); this->vl[cur_in]->set_len(len, 0); } else if (this->vl[cur_in]->get_ftype() == otl_var_char) { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.data())), overflow, vl[cur_in]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info, OTL_RCAST(const void *, s.data()), OTL_SCAST(int, vl[cur_in]->get_elem_size())))); #else OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info))); #endif } } else (void)check_in_type_throw(otl_var_char); this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } #endif #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) otl_ref_select_stream &operator<<(const OTL_STRING_CONTAINER &s) { check_in_var(); if (this->vl[cur_in]->get_ftype() == otl_var_raw) { unsigned char *c = OTL_RCAST(unsigned char *, vl[cur_in]->val()); int len = OTL_SCAST(int, s.length()); if (len > this->vl[cur_in]->actual_elem_size()) { otl_var_info_var(this->vl[cur_in]->get_name(), this->vl[cur_in]->get_ftype(), otl_var_raw, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); OTL_THROW((otl_exception(otl_error_msg_5, otl_error_code_5, this->stm_label ? this->stm_label : this->stm_text, var_info))); } this->vl[cur_in]->set_not_null(0); otl_memcpy(c + sizeof(unsigned short), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), len, this->vl[cur_in]->get_ftype()); *OTL_RCAST(unsigned short *, this->vl[cur_in]->val(0)) = OTL_SCAST(unsigned short, len); this->vl[cur_in]->set_len(len, 0); } else if (this->vl[cur_in]->get_ftype() == otl_var_char) { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s.c_str())), overflow, vl[cur_in]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info, OTL_RCAST(const void *, s.c_str()), OTL_SCAST(int, vl[cur_in]->get_elem_size())))); #else OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info))); #endif } } else (void)check_in_type_throw(otl_var_char); this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } #endif #if defined(OTL_UNICODE_STRING_TYPE) otl_ref_select_stream &operator<<(const OTL_UNICODE_STRING_TYPE &s) { check_in_var(); if (check_in_type(otl_var_char, 1)) { int overflow; #if defined(OTL_C_STR_FOR_UNICODE_STRING_TYPE) otl_strcpy4(OTL_RCAST(unsigned char *, vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.OTL_C_STR_FOR_UNICODE_STRING_TYPE())), #else otl_strcpy4(OTL_RCAST(unsigned char *, vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.c_str())), #endif overflow, vl[cur_in]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info, OTL_RCAST(const void *, s.c_str()), OTL_SCAST(int, vl[cur_in]->get_elem_size())))); #else OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info))); #endif } } this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } #endif #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)) otl_ref_select_stream &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) { check_in_var(); if (check_in_type(otl_var_char, 1)) { int overflow; otl_strcpy4(OTL_RCAST(unsigned char *, vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(OTL_UNICODE_CHAR_TYPE *, s.data())), overflow, vl[cur_in]->get_elem_size(), OTL_SCAST(int, s.length())); if (overflow) { char temp_var_info[256]; otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info, OTL_RCAST(const void *, s.data()), OTL_SCAST(int, vl[cur_in]->get_elem_size())))); #else OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info))); #endif } } this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } #endif otl_ref_select_stream &operator<<(const char *s) { check_in_var(); if (check_in_type(otl_var_char, 1)) { int overflow; otl_strcpy(OTL_RCAST(unsigned char *, vl[cur_in]->val()), OTL_RCAST(unsigned char *, OTL_CCAST(char *, s)), overflow, vl[cur_in]->get_elem_size()); if (overflow) { char temp_var_info[256]; otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info, OTL_RCAST(const void *, s), OTL_SCAST(int, vl[cur_in]->get_elem_size())))); #else OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info))); #endif } } this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } otl_ref_select_stream &operator<<(const unsigned char *s) { check_in_var(); if (check_in_type(otl_var_char, 1)) { int overflow; otl_strcpy4(OTL_RCAST(unsigned char *, vl[cur_in]->val()), OTL_CCAST(unsigned char *, s), overflow, vl[cur_in]->get_elem_size()); if (overflow) { char temp_var_info[256]; otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info, OTL_RCAST(const void *, s), OTL_SCAST(int, vl[cur_in]->get_elem_size())))); #else OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info))); #endif } } this->vl[cur_in]->set_not_null(0); get_in_next(); return *this; } #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE) template otl_ref_select_stream &operator<<(const std::array& s){ (*this)<adb->get_max_long_size())){ int rc = this->vl[cur_in]->get_var_struct().write_geometry(s, cur_in); if(rc == 0){ char temp_var_info[256]; otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), otl_var_char, temp_var_info, sizeof(temp_var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(*this); #if defined(OTL_EXCEPTION_COPIES_INPUT_STRING_IN_CASE_OF_OVERFLOW) OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info, OTL_RCAST(const void *, s), OTL_SCAST(int, vl[cur_in]->get_elem_size())))); #else OTL_THROW((otl_exception(otl_error_msg_4, otl_error_code_4, stm_label ? stm_label : stm_text, temp_var_info))); #endif } } get_in_next(); return *this; } #endif #if !defined(OTL_D8) #define OTL_D8(T, T_type) \ otl_ref_select_stream &operator<<(const T n) { \ check_in_var(); \ if (check_in_type(T_type, sizeof(T))) { \ *OTL_RCAST(T *, vl[cur_in]->val()) = n; \ } \ this->vl[cur_in]->set_not_null(0); \ get_in_next(); \ return *this; \ } #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) OTL_D8(int, otl_var_int) OTL_D8(unsigned, otl_var_unsigned_int) OTL_D8(long, otl_var_long_int) OTL_D8(short, otl_var_short) OTL_D8(float, otl_var_float) OTL_D8(double, otl_var_double) #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) OTL_D8(OTL_BIGINT, otl_var_bigint) #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) OTL_D8(OTL_UBIGINT, otl_var_ubigint) #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) OTL_D8(OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1) #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) OTL_D8(OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2) #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) OTL_D8(OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3) #endif #else template OTL_D8(T, T_type) #endif OTL_NODISCARD int select_list_len(void) const { return sl_len; } OTL_NODISCARD int column_ftype(int ndx = 0) const { return sl[ndx].get_ftype(); } OTL_NODISCARD int column_size(int ndx = 0) const { return sl[ndx].get_elem_size(); } OTL_NODISCARD int get_sl_len() const { return sl_len; } OTL_NODISCARD otl_generic_variable *get_sl() const { return sl; } OTL_NODISCARD otl_column_desc *get_sl_desc() const { return sl_desc; } protected: otl_column_desc *sl_desc; int sl_len; otl_generic_variable *sl; int null_fetched; int ret_code; int cur_col; int cur_in; int executed; char var_info[256]; void init(void) { same_sl_flag = 0; sl = nullptr; sl_len = 0; null_fetched = 0; ret_code = 0; sl_desc = nullptr; executed = 0; cur_in = 0; stm_text = nullptr; } void get_next(void) { if (cur_col < sl_len - 1) { ++cur_col; null_fetched = sl[cur_col].is_null(cur_row); } else { ret_code = next(); cur_col = 0; } } OTL_NODISCARD int check_type_throw(int type_code, int actual_data_type) { int out_type_code; if (actual_data_type != 0) out_type_code = actual_data_type; else out_type_code = type_code; otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), out_type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0, stm_label ? stm_label : stm_text, var_info))); } OTL_NODISCARD int check_type(int type_code, int actual_data_type = 0) { switch (sl[cur_col].get_ftype()) { case otl_var_timestamp: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: if (type_code == otl_var_timestamp) return 1; break; default: #if defined(OTL_CHECK_OUT_TYPE_FUNC) if ((sl[cur_col].get_ftype() == type_code) || OTL_CHECK_OUT_TYPE_FUNC(sl[cur_col].get_ftype(),type_code)) return 1; break; #else if (sl[cur_col].get_ftype() == type_code) return 1; break; #endif } return check_type_throw(type_code, actual_data_type); } void look_ahead(void) { if (cur_col == sl_len - 1) { #if defined(OTL_SELECT_STREAM_ALTERNATE_FETCH) #else ret_code = next(); cur_col = -1; #endif ++_rfc; } } void get_select_list(void) { int i, j, rc; otl_auto_array_ptr loc_ptr(otl_var_list_size); otl_column_desc *sl_desc_tmp = loc_ptr.get_ptr(); int sld_tmp_len = 0; int ftype, elem_size; OCIBind *bindpp; if (!sel_cur.get_connected()) { sel_cur.open(*adb); rc = OCIBindByName(cursor_struct.cda, &bindpp, cursor_struct.errhp, OTL_RCAST(text *, cur_placeholder), OTL_SCAST(sb4, strlen(cur_placeholder)), OTL_RCAST(dvoid *, &sel_cur.get_cursor_struct().cda), 0, SQLT_RSET, nullptr, nullptr, nullptr, 0, nullptr, OTL_SCAST(ub4, OCI_DEFAULT)); if (rc != 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(cursor_struct, stm_label ? stm_label : stm_text))); } } for (i = 0; i < vl_len; ++i) otl_tmpl_cursor::bind(*vl[i]); // Executing the PLSQL master block otl_tmpl_cursor::exec( 1, 0, otl_sql_exec_from_select_cursor_class); sel_cur.set_connected(1); cur_row = -2; if (same_sl_flag && sl) { // assuming that ref.cur's select list is the same as // in previous executions of the master block. for (i = 0; i < sl_len; ++i) sel_cur.bind(sl[i]); return; } else { sld_tmp_len = 0; sel_cur.get_cursor_struct().straight_select = 0; for (i = 1; sel_cur.describe_column(sl_desc_tmp[i - 1], i); ++i) { ++sld_tmp_len; if (sld_tmp_len == loc_ptr.get_arr_size()) { loc_ptr.double_size(); sl_desc_tmp = loc_ptr.get_ptr(); } } sl_len = sld_tmp_len; if (sl) { delete[] sl; sl = nullptr; } sl = new otl_generic_variable[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)]; int max_long_size = this->adb->get_max_long_size(); for (j = 0; j < sl_len; ++j) { otl_generic_variable::map_ftype( sl_desc_tmp[j], max_long_size, ftype, elem_size, this->local_override.getLen() > 0 ? this->local_override : *override_, j + 1, this->adb->get_connect_struct().get_connection_type()); sl[j].copy_pos(j + 1); #if defined(OTL_ORA_UNICODE) || defined(OTL_ORA_UTF8) if (sl_desc_tmp[j].charset_form == 2) sl[j].get_var_struct().nls_flag = true; #endif sl[j].init(true, ftype, elem_size, OTL_SCAST(otl_stream_buffer_size_type, array_size), &adb->get_connect_struct() #if defined(OTL_ORA_SDO_GEOMETRY) , 0, sl_desc_tmp[j].colOCIType #endif ); } if (sl_desc) { delete[] sl_desc; sl_desc = nullptr; } sl_desc = new otl_column_desc[OTL_SCAST(size_t,sl_len == 0 ? 1 : sl_len)]; for (i = 0; i < sl_len; ++i) sl_desc[i] = sl_desc_tmp[i]; for (i = 0; i < sl_len; ++i) sel_cur.bind(sl[i]); #if defined(OTL_ORA_STREAM_POOL_ASSUMES_SAME_REF_CUR_STRUCT_ON_REUSE) same_sl_flag = 1; #endif } } void get_in_next(void) { if (cur_in == vl_len - 1) rewind(); else { ++cur_in; executed = 0; } } OTL_NODISCARD int check_in_type_throw(int type_code) { otl_var_info_var(vl[cur_in]->get_name(), vl[cur_in]->get_ftype(), type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_RETURN(0); OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0, stm_label ? stm_label : stm_text, var_info))); } OTL_NODISCARD int check_in_type(int type_code, int tsize) { switch (vl[cur_in]->get_ftype()) { case otl_var_char: if (type_code == otl_var_char) return 1; break; case otl_var_raw: if (type_code == otl_var_raw) return 1; break; case otl_var_timestamp: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: if (type_code == otl_var_timestamp) return 1; break; default: #if defined(OTL_CHECK_IN_TYPE_FUNC) if ((vl[cur_in]->get_ftype() == type_code && vl[cur_in]->get_elem_size() == tsize) || OTL_CHECK_IN_TYPE_FUNC(vl[cur_in]->get_ftype(),type_code)) return 1; break; #else if (vl[cur_in]->get_ftype() == type_code && vl[cur_in]->get_elem_size() == tsize) return 1; break; #endif } return check_in_type_throw(type_code); } void check_in_var(void) { if (vl_len == 0) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(otl_error_msg_1, otl_error_code_1, stm_label ? stm_label : stm_text, nullptr))); } } void check_if_executed(void) { if (!executed) { OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(otl_error_msg_2, otl_error_code_2, stm_label ? stm_label : stm_text, nullptr))); } } #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) void strict_check_throw(int type_code) { otl_var_info_col(sl[cur_col].get_pos(), sl[cur_col].get_ftype(), type_code, var_info, sizeof(var_info)); OTL_UNCAUGHT_EXCEPTION_NORETURN; OTL_THROW((otl_exception(otl_error_msg_0, otl_error_code_0, this->stm_label ? this->stm_label : this->stm_text, var_info))); } #endif private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_ref_select_stream(const otl_ref_select_stream &) = delete; otl_ref_select_stream &operator=(const otl_ref_select_stream &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_ref_select_stream(otl_ref_select_stream &&) = delete; otl_ref_select_stream &operator=(otl_ref_select_stream &&) = delete; #endif private: #else otl_ref_select_stream(const otl_ref_select_stream &) : otl_ref_cursor(), override_(nullptr), delay_next(0), same_sl_flag(0), _rfc(0), sl_desc(nullptr), sl_len(0), sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() {} otl_ref_select_stream &operator=(const otl_ref_select_stream &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_ref_select_stream(otl_ref_select_stream &&) : otl_ref_cursor(), override_(nullptr), delay_next(0), same_sl_flag(0), _rfc(0), sl_desc(nullptr), sl_len(0), sl(nullptr), null_fetched(0), ret_code(0), cur_col(0), cur_in(0), executed(0), var_info() {} otl_ref_select_stream &operator=(otl_ref_select_stream &&) { return *this; } #endif #endif }; class otl_stream_shell : public otl_stream_shell_generic { public: otl_ref_select_stream *ref_ss; otl_select_stream *ss; otl_inout_stream *io; otl_connect *adb; int auto_commit_flag; bool lob_stream_flag; otl_var_desc *iov; int iov_len; int next_iov_ndx; otl_var_desc *ov; int ov_len; int next_ov_ndx; bool flush_flag; int stream_type; otl_select_struct_override override_; #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) #if defined(OTL_UNICODE_STRING_TYPE) std::string orig_sql_stm; #else OTL_STRING_CONTAINER orig_sql_stm; #endif #endif otl_stream_shell() : otl_stream_shell_generic(), ref_ss(nullptr), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(0), lob_stream_flag(false), iov(nullptr), iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(false), stream_type(otl_no_stream_type), override_() #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) , orig_sql_stm() #endif { should_delete = 0; } otl_stream_shell(const int ashould_delete) : otl_stream_shell_generic(), ref_ss(nullptr), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(0), lob_stream_flag(false), iov(nullptr), iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(true), stream_type(otl_no_stream_type), override_() #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) , orig_sql_stm() #endif { should_delete = ashould_delete; } virtual ~otl_stream_shell() OTL_THROWS_OTL_EXCEPTION { if (should_delete) { delete[] iov; delete[] ov; iov = nullptr; iov_len = 0; ov = nullptr; ov_len = 0; next_iov_ndx = 0; next_ov_ndx = 0; override_.setLen(0); flush_flag = true; delete ss; delete io; delete ref_ss; ss = nullptr; io = nullptr; ref_ss = nullptr; adb = nullptr; } } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_stream_shell(const otl_stream_shell &) = delete; otl_stream_shell &operator=(const otl_stream_shell &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_stream_shell(otl_stream_shell &&) = delete; otl_stream_shell &operator=(otl_stream_shell &&) = delete; #endif private: #else otl_stream_shell(const otl_stream_shell &) : otl_stream_shell_generic(), ref_ss(nullptr), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(0), lob_stream_flag(false), iov(nullptr), iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(false), stream_type(otl_no_stream_type), override_() #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) , orig_sql_stm() #endif { } otl_stream_shell &operator=(const otl_stream_shell &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_stream_shell(otl_stream_shell &&) : otl_stream_shell_generic(), ref_ss(nullptr), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(0), lob_stream_flag(false), iov(nullptr), iov_len(0), next_iov_ndx(0), ov(nullptr), ov_len(0), next_ov_ndx(0), flush_flag(false), stream_type(otl_no_stream_type), override_() #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) , orig_sql_stm() #endif { } otl_stream_shell &operator=(otl_stream_shell &&) { return *this; } #endif #endif }; class otl_sp_parm_desc { public: int position; char arg_name[40]; char in_out[20]; char data_type[40]; char bind_var[128]; otl_sp_parm_desc() : position(-1), arg_name(), in_out(), data_type(), bind_var() { arg_name[0] = 0; in_out[0] = 0; data_type[0] = 0; bind_var[0] = 0; } otl_sp_parm_desc(const otl_sp_parm_desc &r) : position(-1), arg_name(), in_out(), data_type(), bind_var() { copy(r); } otl_sp_parm_desc &operator=(const otl_sp_parm_desc &r) { copy(r); return *this; } ~otl_sp_parm_desc() {} protected: void copy(const otl_sp_parm_desc &r) { position = r.position; OTL_STRCPY_S(arg_name, sizeof(arg_name), r.arg_name); OTL_STRCPY_S(in_out, sizeof(in_out), r.in_out); OTL_STRCPY_S(data_type, sizeof(data_type), r.data_type); OTL_STRCPY_S(bind_var, sizeof(bind_var), r.bind_var); } }; #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) class otl_stream; class otl_for_range_loop_ora_stream_adapter{ public: otl_for_range_loop_ora_stream_adapter(): str_(nullptr){} otl_for_range_loop_ora_stream_adapter(otl_stream& str): str_(&str){} otl_stream& operator*(){ return *str_; } otl_for_range_loop_ora_stream_adapter& operator++(){ return *this; } otl_stream* str_; }; #endif #if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) #include #endif #if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) #include #endif #if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_COMPILER_HAS_STD_OPTIONAL) #include #endif #if defined(OTL_STREAM_WITH_STD_SPAN_ON) && defined(OTL_CPP_20_ON) #include #endif class otl_stream #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) : public otl_read_stream_interface #endif { protected: otl_stream_shell *shell; otl_ptr shell_pt; int connected; otl_ref_select_stream **ref_ss; otl_select_stream **ss; otl_inout_stream **io; otl_connect **adb; int *auto_commit_flag; otl_var_desc **iov; int *iov_len; int *next_iov_ndx; otl_var_desc **ov; int *ov_len; int *next_ov_ndx; int end_marker; int oper_int_called; int last_eof_rc; bool last_oper_was_read_op; otl_select_struct_override *override_; int buf_size_; void inc_next_ov(void) { if ((*ov_len) == 0) return; if ((*next_ov_ndx) < (*ov_len) - 1) ++(*next_ov_ndx); else (*next_ov_ndx) = 0; } void inc_next_iov(void) { if ((*iov_len) == 0) return; if ((*next_iov_ndx) < (*iov_len) - 1) ++(*next_iov_ndx); else (*next_iov_ndx) = 0; } void reset_end_marker(void) { last_eof_rc = 0; end_marker = -1; oper_int_called = 0; } static void convert_bind_var_datatype(char *out_buf, const size_t out_buf_sz, const char *datatype, const int varchar_size, const int all_num2type, const int refcur_buf_size) { out_buf[0] = 0; if (strcmp(datatype, "BINARY_INTEGER") == 0 || strcmp(datatype, "NATIVE INTEGER") == 0 || strcmp(datatype, "BINARY_FLOAT") == 0 || strcmp(datatype, "BINARY_DOUBLE") == 0 || strcmp(datatype, "FLOAT") == 0 || strcmp(datatype, "NUMBER") == 0) { switch (all_num2type) { case otl_var_char: OTL_STRCPY_S(out_buf, out_buf_sz, "char[50]"); break; case otl_var_double: OTL_STRCPY_S(out_buf, out_buf_sz, "double"); break; case otl_var_float: OTL_STRCPY_S(out_buf, out_buf_sz, "float"); break; case otl_var_long_int: OTL_STRCPY_S(out_buf, out_buf_sz, "long"); break; case otl_var_int: OTL_STRCPY_S(out_buf, out_buf_sz, "int"); break; case otl_var_unsigned_int: OTL_STRCPY_S(out_buf, out_buf_sz, "unsigned"); break; case otl_var_short: OTL_STRCPY_S(out_buf, out_buf_sz, "short"); break; case otl_var_bfloat: OTL_STRCPY_S(out_buf, out_buf_sz, "bfloat"); break; case otl_var_bdouble: OTL_STRCPY_S(out_buf, out_buf_sz, "bdouble"); break; default: break; } } else if (strcmp(datatype, "RAW") == 0) { #if defined(OTL_ORA_CREATE_STORED_PROC_CALL_MAPS_RAW_TO_RAW_LONG) OTL_STRCPY_S(out_buf, out_buf_sz, "raw_long"); #elif defined(OTL_ORA_CREATE_STORED_PROC_CALL_MAPS_RAW_TO_RAW) OTL_SPRINTF_S(out_buf, out_buf_sz, "raw[%d]", varchar_size); #else #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(out_buf, out_buf_sz, "char[%d]", varchar_size); #if defined(__clang__) #pragma clang diagnostic pop #endif #endif } else if (strcmp(datatype, "LONG RAW") == 0) { OTL_STRCPY_S(out_buf, out_buf_sz, "raw_long"); } else if (strcmp(datatype, "DATE") == 0) OTL_STRCPY_S(out_buf, out_buf_sz, "timestamp"); #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) else if (strcmp(datatype, "TIMESTAMP") == 0) OTL_STRCPY_S(out_buf, out_buf_sz, "timestamp"); #endif else if (strcmp(datatype, "VARCHAR2") == 0) #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(out_buf, out_buf_sz, "char[%d]", varchar_size); #if defined(__clang__) #pragma clang diagnostic pop #endif else if (strcmp(datatype, "CHAR") == 0) #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(out_buf, out_buf_sz, "char[%d]", varchar_size); #if defined(__clang__) #pragma clang diagnostic pop #endif else if (strcmp(datatype, "REF CURSOR") == 0) #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(out_buf, out_buf_sz, "refcur,out[%d]", refcur_buf_size); #if defined(__clang__) #pragma clang diagnostic pop #endif } void throw_end_of_row() #if defined(__GNUC__) && (__GNUC__ >= 4) __attribute__((noreturn)) #endif { OTL_THROW((otl_exception(otl_error_msg_34, otl_error_code_34, this->get_stm_text()))); } public: #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) otl_for_range_loop_ora_stream_adapter begin(){ if(!eof()) return otl_for_range_loop_ora_stream_adapter(*this); else return otl_for_range_loop_ora_stream_adapter(); } otl_for_range_loop_ora_stream_adapter end(){ return otl_for_range_loop_ora_stream_adapter(); } #endif void set_batch_error_mode(const bool batch_error_mode) { if (shell && shell->stream_type == otl_inout_stream_type) (*io)->set_batch_error_mode(batch_error_mode); } OTL_NODISCARD int get_number_of_errors_in_batch() { if (shell && shell->stream_type == otl_inout_stream_type) return (*io)->get_number_of_errors_in_batch(); else return 0; } void get_error(const int error_ndx, int &dml_row_offset, otl_exception &exception) { if (shell && shell->stream_type == otl_inout_stream_type) (*io)->get_error(error_ndx, dml_row_offset, exception); } OTL_NODISCARD int get_auto_commit_flag() const { if (!auto_commit_flag) return 0; else return *auto_commit_flag; } OTL_NODISCARD bool get_lob_stream_flag() const { if (!shell) return false; else return shell->lob_stream_flag; } OTL_NODISCARD int get_adb_max_long_size() const { return this->shell->adb->get_max_long_size(); } void check_end_of_row() { if (next_ov_ndx == nullptr || (*next_ov_ndx) != 0) throw_end_of_row(); if (next_iov_ndx == nullptr || (*next_iov_ndx) != 0) throw_end_of_row(); } OTL_NODISCARD int get_prefetched_row_count() const { switch (shell->stream_type) { case otl_no_stream_type: case otl_inout_stream_type: return 0; case otl_select_stream_type: return (*ss)->get_prefetched_row_count(); case otl_refcur_stream_type: return (*ref_ss)->get_prefetched_row_count(); default: return 0; } } OTL_NODISCARD int get_dirty_buf_len() const { switch (shell->stream_type) { case otl_no_stream_type: return 0; case otl_inout_stream_type: return (*io)->get_dirty_buf_len(); case otl_select_stream_type: { int rc = (*ss)->get_select_row_count(); if (rc < 0) return 0; else return rc; } case otl_refcur_stream_type: return (*ref_ss)->get_select_row_count(); default: return 0; } } OTL_NODISCARD otl_stream_shell *get_shell() { return shell; } OTL_NODISCARD int get_connected() const { return connected; } void setBufSize(int buf_size) { buf_size_ = buf_size; } OTL_NODISCARD int getBufSize(void) const { return buf_size_; } operator int(void) OTL_THROWS_OTL_EXCEPTION { if (shell && shell->lob_stream_flag) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); const char *stm_label = nullptr; const char *stm_text = nullptr; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: stm_label = (*io)->get_stm_label(); stm_text = (*io)->get_stm_text(); break; case otl_select_stream_type: stm_label = (*ss)->get_stm_label(); stm_text = (*ss)->get_stm_text(); break; case otl_refcur_stream_type: stm_label = (*ref_ss)->get_stm_label(); stm_text = (*ref_ss)->get_stm_text(); break; } OTL_THROW((otl_exception(otl_error_msg_24, otl_error_code_24, stm_label ? stm_label : stm_text))); } if (!last_oper_was_read_op) { OTL_UNCAUGHT_EXCEPTION_RETURN(0); const char *stm_label = nullptr; const char *stm_text = nullptr; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: stm_label = (*io)->get_stm_label(); stm_text = (*io)->get_stm_text(); break; case otl_select_stream_type: stm_label = (*ss)->get_stm_label(); stm_text = (*ss)->get_stm_text(); break; case otl_refcur_stream_type: stm_label = (*ref_ss)->get_stm_label(); stm_text = (*ref_ss)->get_stm_text(); break; } OTL_THROW((otl_exception(otl_error_msg_18, otl_error_code_18, stm_label ? stm_label : stm_text))); } if (end_marker == 1) return 0; int rc = 0; int temp_eof = eof(); if (temp_eof && end_marker == -1 && oper_int_called == 0) { end_marker = 1; if (last_eof_rc == 1) rc = 0; else rc = 1; } else if (!temp_eof && end_marker == -1) rc = 1; else if (temp_eof && end_marker == -1) { end_marker = 0; rc = 1; } else if (temp_eof && end_marker == 0) { end_marker = 1; rc = 0; } if (!oper_int_called) oper_int_called = 1; return rc; } #if !defined(OTL_UNICODE) static void create_stored_proc_call( otl_connect &db, otl_stream &args_strm, char *sql_stm, int &stm_type, char *refcur_placeholder, const char *proc_name, const char *package_name, const char *schema_name = nullptr, const bool schema_name_included = false, const int varchar_size = 2001, const int all_num2type = otl_var_double, const int refcur_buf_size = 1) { sql_stm[0] = 0; stm_type = otl_no_stream_type; refcur_placeholder[0] = 0; char full_name[1024]; char temp_buf[1024]; char temp_buf2[1024]; int i; if (package_name == nullptr) #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(full_name, sizeof(full_name), "%s", proc_name); #if defined(__clang__) #pragma clang diagnostic pop #endif else #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(full_name, sizeof(full_name), "%s.%s", package_name, proc_name); #if defined(__clang__) #pragma clang diagnostic pop #endif if (schema_name_included && schema_name != nullptr) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "%s.%s", schema_name, full_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_STRCPY_S(full_name, sizeof(full_name), temp_buf); } if (!args_strm.good()) { args_strm.open( 50, #if defined(OTL_ORA11G) || defined(OTL_ORA11G_R2) "select nvl(position,1) position, " " lower(':'||nvl(argument_name,'rc__')) argument_name, " " in_out, " " nvl(data_type,'*') data_type, " " ':'||lower(nvl(argument_name,'rc__'))|| " " decode(data_type,'REF CURSOR',' ', " " '<'||'%s,'|| " " decode(in_out,'IN','in', " " 'OUT','out', " " 'IN/OUT','inout', " " 'xxx') " " ||'>' " " ) || decode(position,0,' := ',' ') " " bind_var " "from all_arguments a, all_procedures p " "where upper(:obj_name/*char[50]*/) in " "(p.procedure_name,p.object_name) " "and (:pkg_name/*char[50]*/ is null and " " p.procedure_name is null or " " :pkg_name is not NULL and " " (p.object_name=upper(:pkg_name) or " " p.object_name = " " (select package_name from " " (select table_name as package_name " " from user_synonyms " " where synonym_name=upper(:pkg_name) " " union all " " select table_name as package_name " " from all_synonyms " " where synonym_name=upper(:pkg_name) " " ) " " where rownum = 1) " ")) " "and ((:owner/*char[50]*/ is null " " and p.owner = " " (select owner from " " (select user as owner " " from user_objects " " where object_name = upper(nvl(:pkg_name, :obj_name)) " " and object_type in ('PACKAGE','FUNCTION','PROCEDURE') " " union all " " select table_owner as owner " " from user_synonyms " " where synonym_name = upper(nvl(:pkg_name, :obj_name)) " " union all " " select table_owner as owner " " from all_synonyms " " where synonym_name = upper(nvl(:pkg_name, :obj_name)) " " ) " " where rownum = 1) " " or " " (:owner is not null and p.owner=upper(:owner))) " " and a.data_level(+)=0 " " ) " "and a.object_id(+) = p.object_id " "and a.subprogram_id(+) = p.subprogram_id " "and a.owner(+) = p.owner " "order by a.position ", #else "select position, " " lower(':'||nvl(argument_name,'rc__')) argument_name, " " in_out, " " nvl(data_type,'*') data_type, " " ':'||lower(nvl(argument_name,'rc__'))|| " " decode(data_type,'REF CURSOR',' ', " " '<'||'%s,'|| " " decode(in_out,'IN','in', " " 'OUT','out', " " 'IN/OUT','inout', " " 'xxx') " " ||'>' " " ) || decode(position,0,' := ',' ') " " bind_var " "from all_arguments " "where object_name=upper(:obj_name) " " and (:pkg_name is null and package_name is null or " " :pkg_name is not null " " and (package_name=upper(:pkg_name) " " or package_name = " " (select package_name from " " (select table_name as package_name " " from user_synonyms " " where synonym_name=upper(:pkg_name) " " union all " " select table_name as package_name " " from all_synonyms " " where synonym_name=upper(:pkg_name) " " )" " where rownum = 1)" " )) " " and ((:owner is null " " and owner= " " (select owner from " " (select user as owner " " from user_objects " " where (:pkg_name is not null " " and object_name = upper(:pkg_name) " " and object_type = 'PACKAGE') " " or (:pkg_name is null " " and object_name = upper(:obj_name) " " and object_type in ('FUNCTION','PROCEDURE')) " " union all " " select table_owner as owner " " from user_synonyms " " where (:pkg_name is not null " " and synonym_name = upper(:pkg_name)) " " or (:pkg_name is null " " and synonym_name = upper(:obj_name)) " " union all " " select table_owner as owner " " from all_synonyms " " where (:pkg_name is not null " " and synonym_name = upper(:pkg_name)) " " or (:pkg_name is null " " and synonym_name = upper(:obj_name)) " " ) " " where rownum = 1) " " or " " (:owner is not null and owner=upper(:owner))) " " and data_level=0 )" "order by position", #endif db); } otl_auto_array_ptr > desc(otl_var_list_size); int desc_len = 0; otl_sp_parm_desc parm; args_strm << proc_name; if (package_name == nullptr) args_strm << otl_null(); else args_strm << package_name; if (schema_name == nullptr) args_strm << otl_null(); else args_strm << schema_name; while (!args_strm.eof()) { args_strm >> parm.position; args_strm >> parm.arg_name; args_strm >> parm.in_out; args_strm >> parm.data_type; args_strm >> parm.bind_var; ++desc_len; if (desc_len == desc.get_arr_size()) { int j; for (j = 0; j < desc.get_arr_size(); ++j) desc.get_ptr()[j].set_do_not_destroy(true); desc.double_size(); for (j = 0; j < desc.get_arr_size(); ++j) desc.get_ptr()[j].set_do_not_destroy(false); } desc.get_ptr()[desc_len - 1].assign(new otl_sp_parm_desc(parm)); } if (desc_len == 0) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s", full_name); #if defined(__clang__) #pragma clang diagnostic pop #endif { // last ditch attemp to identify a global SP with no parms bool global_sp_no_parms = false; if (schema_name == nullptr) { // schema name is not specified otl_stream s2(1, "select 1 cnt " "from user_procedures " "where object_name=UPPER(:obj_name) " " and procedure_name is null " #if defined(OTL_ORA11G) || defined(OTL_ORA11G_R2) " and object_type='PROCEDURE' " #endif "union all " "select 1 cnt " "from user_synonyms syn " "where syn.synonym_name=UPPER(:obj_name) " " and exists " " (select 'x' " " from all_procedures proc " " where proc.owner=syn.table_owner " " and proc.object_name=syn.table_name) " "union all " "select 1 cnt " "from all_synonyms syn " "where syn.synonym_name=UPPER(:obj_name) " " and syn.owner='PUBLIC' " " and exists " " (select 'x' " " from all_procedures proc " " where proc.owner=syn.table_owner " " and proc.object_name=syn.table_name)", db); s2 << proc_name; global_sp_no_parms = !s2.eof(); } else { // schema name is specified otl_stream s2(1, "select object_name " "from all_procedures " "where object_name=UPPER(:obj_name) " " and procedure_name is null " " and object_type='PROCEDURE' " " AND owner=UPPER(:owner) " "union all " "select synonym_name " "from all_synonyms syn " "where syn.synonym_name=UPPER(:obj_name) " " AND syn.owner=UPPER(:owner) " " and exists " " (select 'x' " " from all_procedures proc " " where proc.owner=syn.table_owner " " and proc.object_name=syn.table_name)", db); s2 << proc_name; s2 << schema_name; global_sp_no_parms = !s2.eof(); } if (global_sp_no_parms) { // procedure without any parameters otl_strcat(sql_stm, "BEGIN "); otl_strcat(sql_stm, full_name); otl_strcat(sql_stm, "; END;"); stm_type = otl_constant_sql_type; return; } else { OTL_THROW((otl_exception(otl_error_msg_13, otl_error_code_13, temp_buf))); } } } if (desc_len == 1) { if (desc.get_ptr()[0].get_ptr()->position == 1 && desc.get_ptr()[0].get_ptr()->data_type[0] == '*') { // procedure without any parameters otl_strcat(sql_stm, "BEGIN "); otl_strcat(sql_stm, full_name); otl_strcat(sql_stm, "; END;"); stm_type = otl_constant_sql_type; return; } if (desc.get_ptr()[0].get_ptr()->position == 1 && desc.get_ptr()[0].get_ptr()->data_type[0] != '*') { // procedure with one parameter if (strcmp(desc.get_ptr()[0].get_ptr()->data_type, "REF CURSOR") == 0) { // procedure with one parameter of refcur type if (strcmp(desc.get_ptr()[0].get_ptr()->in_out, "IN") == 0) { // refcur parameter should be either OUT or IN OUT, not IN. #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s", full_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(otl_error_msg_15, otl_error_code_15, temp_buf, nullptr))); } otl_strcat(sql_stm, "BEGIN "); otl_strcat(sql_stm, full_name); otl_strcat(sql_stm, "("); otl_strcat(sql_stm, desc.get_ptr()[0].get_ptr()->bind_var); otl_strcat(sql_stm, "); END;"); stm_type = otl_refcur_stream_type; otl_strcpy(OTL_RCAST(unsigned char *, refcur_placeholder), OTL_RCAST(const unsigned char *, desc.get_ptr()[0].get_ptr()->arg_name)); return; } else { // procedure with one scalar parameter convert_bind_var_datatype(temp_buf, sizeof(temp_buf), desc.get_ptr()[0].get_ptr()->data_type, varchar_size, all_num2type, refcur_buf_size); if (temp_buf[0] == 0) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s", full_name, desc.get_ptr()[0].get_ptr()->arg_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf, nullptr))); } #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #pragma clang diagnostic ignored "-Wformat-nonliteral" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wformat-nonliteral" #elif defined(_MSC_VER ) #pragma warning( push ) #endif OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), desc.get_ptr()[0].get_ptr()->bind_var, temp_buf); #if defined(__clang__) #pragma clang diagnostic pop #elif defined(__GNUC__) #pragma GCC diagnostic pop #elif defined(_MSC_VER ) #pragma warning( pop ) #endif otl_strcat(sql_stm, "BEGIN "); otl_strcat(sql_stm, full_name); otl_strcat(sql_stm, "("); otl_strcat(sql_stm, temp_buf2); otl_strcat(sql_stm, "); END;"); stm_type = otl_inout_stream_type; refcur_placeholder[0] = 0; return; } } else if (desc.get_ptr()[0].get_ptr()->position == 0) { if (strcmp(desc.get_ptr()[0].get_ptr()->data_type, "REF CURSOR") == 0) { // refcur function without any parameters otl_strcat(sql_stm, "BEGIN "); otl_strcat(sql_stm, desc.get_ptr()[0].get_ptr()->bind_var); otl_strcat(sql_stm, " "); otl_strcat(sql_stm, full_name); otl_strcat(sql_stm, "; END;"); stm_type = otl_refcur_stream_type; otl_strcpy(OTL_RCAST(unsigned char *, refcur_placeholder), OTL_RCAST(const unsigned char *, desc.get_ptr()[0].get_ptr()->arg_name)); return; } else { // scalar function without any parameters convert_bind_var_datatype(temp_buf, sizeof(temp_buf), desc.get_ptr()[0].get_ptr()->data_type, varchar_size, all_num2type, refcur_buf_size); if (temp_buf[0] == 0) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s", full_name, desc.get_ptr()[0].get_ptr()->arg_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf, nullptr))); } #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #pragma clang diagnostic ignored "-Wformat-nonliteral" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wformat-nonliteral" #elif defined(_MSC_VER ) #pragma warning( push ) #endif OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), desc.get_ptr()[0].get_ptr()->bind_var, temp_buf); #if defined(__clang__) #pragma clang diagnostic pop #elif defined(__GNUC__) #pragma GCC diagnostic pop #elif defined(_MSC_VER ) #pragma warning( pop ) #endif otl_strcat(sql_stm, "BEGIN "); otl_strcat(sql_stm, temp_buf2); otl_strcat(sql_stm, " "); otl_strcat(sql_stm, full_name); otl_strcat(sql_stm, "; END;"); stm_type = otl_inout_stream_type; refcur_placeholder[0] = 0; return; } } } // Checking if the procedure is of the "refcur" type bool refcur_flag = false; bool refcur_outpar = false; int refcur_count = 0; bool inpar_only = true; for (i = 0; i < desc_len; ++i) { if (inpar_only && strcmp(desc.get_ptr()[i].get_ptr()->in_out, "IN") != 0 && strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") != 0) inpar_only = false; if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") == 0) { ++refcur_count; refcur_flag = true; if (refcur_count > 1) { if (refcur_outpar) refcur_outpar = strcmp(desc.get_ptr()[i].get_ptr()->in_out, "IN") != 0; } else refcur_outpar = strcmp(desc.get_ptr()[i].get_ptr()->in_out, "IN") != 0; } } if (refcur_flag) { if (!refcur_outpar) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s", full_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(otl_error_msg_15, otl_error_code_15, temp_buf, nullptr))); } stm_type = otl_refcur_stream_type; if (!inpar_only || refcur_count > 1) stm_type = otl_mixed_refcur_stream_type; refcur_placeholder[0] = 0; sql_stm[0] = 0; bool full_name_printed = false; for (i = 0; i < desc_len; ++i) { if (i == 0) otl_strcat(sql_stm, "BEGIN "); if (stm_type == otl_refcur_stream_type) { // otl_refcur_stream_type if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") == 0) otl_strcpy(OTL_RCAST(unsigned char *, refcur_placeholder), OTL_RCAST(const unsigned char *, desc.get_ptr()[i].get_ptr()->arg_name)); } // in case of a function, function's return code if (desc.get_ptr()[i].get_ptr()->position == 0) { convert_bind_var_datatype(temp_buf, sizeof(temp_buf), desc.get_ptr()[i].get_ptr()->data_type, varchar_size, all_num2type, refcur_buf_size); if (temp_buf[0] == 0 && strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") != 0) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s", full_name, desc.get_ptr()[i].get_ptr()->arg_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf, nullptr))); } if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") == 0 && stm_type == otl_refcur_stream_type) OTL_STRCPY_S(temp_buf2, sizeof(temp_buf2), desc.get_ptr()[i].get_ptr()->bind_var); else if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") == 0 && stm_type == otl_mixed_refcur_stream_type) { desc.get_ptr()[i].get_ptr()->bind_var [strlen(desc.get_ptr()[i].get_ptr()->bind_var) - 5] = 0; #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), "%s<%s> := ", desc.get_ptr()[i].get_ptr()->bind_var, temp_buf); #if defined(__clang__) #pragma clang diagnostic pop #endif } else #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #pragma clang diagnostic ignored "-Wformat-nonliteral" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wformat-nonliteral" #elif defined(_MSC_VER ) #pragma warning( push ) #endif OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), desc.get_ptr()[i].get_ptr()->bind_var, temp_buf); #if defined(__clang__) #pragma clang diagnostic pop #elif defined(__GNUC__) #pragma GCC diagnostic pop #elif defined(_MSC_VER ) #pragma warning( pop ) #endif otl_strcat(sql_stm, temp_buf2); } // procedure/function's name if (!full_name_printed) { otl_strcat(sql_stm, full_name); otl_strcat(sql_stm, "("); full_name_printed = true; } if (desc.get_ptr()[i].get_ptr()->position != 0) { // normal parameters convert_bind_var_datatype(temp_buf, sizeof(temp_buf), desc.get_ptr()[i].get_ptr()->data_type, varchar_size, all_num2type, refcur_buf_size); if (temp_buf[0] == 0 && strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") != 0) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s", full_name, desc.get_ptr()[i].get_ptr()->arg_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf, nullptr))); } if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") == 0 && stm_type == otl_refcur_stream_type) OTL_STRCPY_S(temp_buf2, sizeof(temp_buf2), desc.get_ptr()[i].get_ptr()->bind_var); else if (strcmp(desc.get_ptr()[i].get_ptr()->data_type, "REF CURSOR") == 0 && stm_type == otl_mixed_refcur_stream_type) { desc.get_ptr()[i].get_ptr()->bind_var [strlen(desc.get_ptr()[i].get_ptr()->bind_var) - 2] = 0; #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), "%s<%s>", desc.get_ptr()[i].get_ptr()->bind_var, temp_buf); #if defined(__clang__) #pragma clang diagnostic pop #endif } else #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #pragma clang diagnostic ignored "-Wformat-nonliteral" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wformat-nonliteral" #elif defined(_MSC_VER ) #pragma warning( push ) #endif OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), desc.get_ptr()[i].get_ptr()->bind_var, temp_buf); #if defined(__clang__) #pragma clang diagnostic pop #elif defined(__GNUC__) #pragma GCC diagnostic pop #elif defined(_MSC_VER ) #pragma warning( pop ) #endif otl_strcat(sql_stm, temp_buf2); } if (i < desc_len - 1 && desc.get_ptr()[i].get_ptr()->position != 0) otl_strcat(sql_stm, ","); else if (i == desc_len - 1) otl_strcat(sql_stm, "); "); } otl_strcat(sql_stm, " END;"); return; } // The procedure is of the "general" type stm_type = otl_inout_stream_type; refcur_placeholder[0] = 0; sql_stm[0] = 0; bool full_name_printed = false; for (i = 0; i < desc_len; ++i) { if (i == 0) otl_strcat(sql_stm, "BEGIN "); // in case of a function, function's return code if (desc.get_ptr()[i].get_ptr()->position == 0) { convert_bind_var_datatype(temp_buf, sizeof(temp_buf), desc.get_ptr()[i].get_ptr()->data_type, varchar_size, all_num2type, refcur_buf_size); if (temp_buf[0] == 0) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s", full_name, desc.get_ptr()[i].get_ptr()->arg_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf, nullptr))); } #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #pragma clang diagnostic ignored "-Wformat-nonliteral" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wformat-nonliteral" #elif defined(_MSC_VER ) #pragma warning( push ) #endif OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), desc.get_ptr()[i].get_ptr()->bind_var, temp_buf); #if defined(__clang__) #pragma clang diagnostic pop #elif defined(__GNUC__) #pragma GCC diagnostic pop #elif defined(_MSC_VER ) #pragma warning( pop ) #endif otl_strcat(sql_stm, temp_buf2); } // procedure/function's name if (!full_name_printed) { otl_strcat(sql_stm, full_name); otl_strcat(sql_stm, "("); full_name_printed = true; } if (desc.get_ptr()[i].get_ptr()->position != 0) { // normal parameters convert_bind_var_datatype(temp_buf, sizeof(temp_buf), desc.get_ptr()[i].get_ptr()->data_type, varchar_size, all_num2type, refcur_buf_size); if (temp_buf[0] == 0) { #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(temp_buf, sizeof(temp_buf), "procedure %s, parameter %s", full_name, desc.get_ptr()[i].get_ptr()->arg_name); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(otl_error_msg_14, otl_error_code_14, temp_buf, nullptr))); } #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #pragma clang diagnostic ignored "-Wformat-nonliteral" #elif defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-value" #pragma GCC diagnostic ignored "-Wformat-nonliteral" #elif defined(_MSC_VER ) #pragma warning( push ) #endif OTL_SPRINTF_S(temp_buf2, sizeof(temp_buf2), desc.get_ptr()[i].get_ptr()->bind_var, temp_buf); #if defined(__clang__) #pragma clang diagnostic pop #elif defined(__GNUC__) #pragma GCC diagnostic pop #elif defined(_MSC_VER ) #pragma warning( pop ) #endif otl_strcat(sql_stm, temp_buf2); } if (i < desc_len - 1 && desc.get_ptr()[i].get_ptr()->position != 0) otl_strcat(sql_stm, ","); else if (i == desc_len - 1) otl_strcat(sql_stm, "); "); } otl_strcat(sql_stm, " END;"); } #endif OTL_NODISCARD int get_stream_type(void) OTL_NO_THROW { if (shell == nullptr) return otl_no_stream_type; else return shell->stream_type; } void set_column_type(const int column_ndx, const int col_type, const int col_size = 0) OTL_NO_THROW { if (shell == nullptr) { init_stream(); shell->flush_flag = true; } override_->add_override(column_ndx, col_type, col_size); } void set_all_column_types(const unsigned mask = 0) OTL_NO_THROW { if (shell == nullptr) { init_stream(); shell->flush_flag = true; } override_->set_all_column_types(mask); } void set_flush(const bool flush_flag = true) OTL_NO_THROW { if (shell == nullptr) init_stream(); shell->flush_flag = flush_flag; } void set_lob_stream_mode(const bool lob_stream_flag = false) OTL_NO_THROW { if (shell == nullptr) return; shell->lob_stream_flag = lob_stream_flag; } OTL_NODISCARD otl_var_desc *describe_in_vars(int &desc_len) OTL_NO_THROW { desc_len = 0; if (shell == nullptr) return nullptr; if (shell->iov == nullptr) return nullptr; desc_len = shell->iov_len; return shell->iov; } OTL_NODISCARD otl_var_desc *describe_out_vars(int &desc_len) OTL_NO_THROW { desc_len = 0; if (shell == nullptr) return nullptr; if (shell->ov == nullptr) return nullptr; desc_len = shell->ov_len; return shell->ov; } OTL_NODISCARD otl_var_desc *describe_next_in_var(void) OTL_NO_THROW { if (shell == nullptr) return nullptr; if (shell->iov == nullptr) return nullptr; return &(shell->iov[shell->next_iov_ndx]); } OTL_NODISCARD otl_var_desc *describe_next_out_var(void) OTL_NO_THROW { if (shell == nullptr) return nullptr; if (shell->ov == nullptr) return nullptr; return &(shell->ov[shell->next_ov_ndx]); } OTL_NODISCARD const char *get_stm_text(void) { const char *no_stm_text = OTL_NO_STM_TEXT; switch (shell->stream_type) { case otl_no_stream_type: return no_stm_text; case otl_inout_stream_type: return (*io)->get_stm_label() ? (*io)->get_stm_label() : (*io)->get_stm_text(); case otl_select_stream_type: return (*ss)->get_stm_label() ? (*ss)->get_stm_label() : (*ss)->get_stm_text(); case otl_refcur_stream_type: return (*ref_ss)->get_stm_label() ? (*ref_ss)->get_stm_label() : (*ref_ss)->get_stm_text(); default: return no_stm_text; } } OTL_NODISCARD long get_rpc() OTL_NO_THROW { switch (shell->stream_type) { case otl_no_stream_type: return 0; case otl_inout_stream_type: return (*io)->get_rpc(); case otl_select_stream_type: return (*ss)->get_rfc(); case otl_refcur_stream_type: return (*ref_ss)->get_rfc(); default: return 0; } } void create_var_desc(void) { int i; delete[](*iov); delete[](*ov); (*iov) = nullptr; (*iov_len) = 0; (*ov) = nullptr; (*ov_len) = 0; if ((*ss)) { if ((*ss)->get_vl_len() > 0) { (*iov) = new otl_var_desc[OTL_SCAST(size_t,(*ss)->get_vl_len())]; (*iov_len) = (*ss)->get_vl_len(); for (i = 0; i < (*ss)->get_vl_len(); ++i) (*ss)->get_vl()[i]->copy_var_desc((*iov)[i]); } if ((*ss)->get_sl_len() > 0) { (*ov) = new otl_var_desc[OTL_SCAST(size_t,(*ss)->get_sl_len())]; (*ov_len) = (*ss)->get_sl_len(); for (i = 0; i < (*ss)->get_sl_len(); ++i) { (*ss)->get_sl()[i].copy_var_desc((*ov)[i]); (*ov)[i].copy_name((*ss)->get_sl_desc()[i].name); (*ov)[i].set_param_type(1); } } } else if ((*io)) { if ((*io)->get_vl_len() > 0) { (*iov) = new otl_var_desc[OTL_SCAST(size_t,(*io)->get_vl_len())]; (*iov_len) = (*io)->get_vl_len(); for (i = 0; i < (*io)->get_vl_len(); ++i) (*io)->get_vl()[i]->copy_var_desc((*iov)[i]); } if ((*io)->get_iv_len() > 0) { (*ov) = new otl_var_desc[OTL_SCAST(size_t,(*io)->get_iv_len())]; (*ov_len) = (*io)->get_iv_len(); for (i = 0; i < (*io)->get_iv_len(); ++i) (*io)->get_in_vl()[i]->copy_var_desc((*ov)[i]); } } else if ((*ref_ss)) { if ((*ref_ss)->get_vl_len() > 0) { (*iov) = new otl_var_desc[OTL_SCAST(size_t,(*ref_ss)->get_vl_len())]; (*iov_len) = (*ref_ss)->get_vl_len(); for (i = 0; i < (*ref_ss)->get_vl_len(); ++i) (*ref_ss)->get_vl()[i]->copy_var_desc((*iov)[i]); } if ((*ref_ss)->get_sl_len() > 0) { int temp_sl_len = (*ref_ss)->get_sl_len(); (*ov) = new otl_var_desc[OTL_SCAST(size_t,temp_sl_len)]; (*ov_len) = temp_sl_len; for (i = 0; i < temp_sl_len; ++i) { (*ref_ss)->get_sl()[i].copy_var_desc((*ov)[i]); (*ov)[i].copy_name((*ref_ss)->get_sl_desc()[i].name); } } } } void init_stream(void) { buf_size_ = 1; last_oper_was_read_op = false; shell = nullptr; shell = new otl_stream_shell(0); shell_pt.assign(&shell); connected = 0; ref_ss = &(shell->ref_ss); ss = &(shell->ss); io = &(shell->io); adb = &(shell->adb); auto_commit_flag = &(shell->auto_commit_flag); iov = &(shell->iov); iov_len = &(shell->iov_len); next_iov_ndx = &(shell->next_iov_ndx); ov = &(shell->ov); ov_len = &(shell->ov_len); next_ov_ndx = &(shell->next_ov_ndx); override_ = &(shell->override_); (*ref_ss) = nullptr; (*io) = nullptr; (*ss) = nullptr; (*adb) = nullptr; (*ov) = nullptr; (*ov_len) = 0; (*next_iov_ndx) = 0; (*next_ov_ndx) = 0; (*auto_commit_flag) = 1; (*iov) = nullptr; (*iov_len) = 0; } otl_stream(const otl_stream_buffer_size_type arr_size, const char *sqlstm, otl_connect &db, const char *ref_cur_placeholder = nullptr, const char *sqlstm_label = nullptr) OTL_THROWS_OTL_EXCEPTION: #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) otl_read_stream_interface(), #endif shell(nullptr), shell_pt(), connected(0), ref_ss(nullptr), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr), next_ov_ndx(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0), last_oper_was_read_op(false), override_(nullptr), buf_size_(0) { init_stream(); (*io) = nullptr; (*ss) = nullptr; (*ref_ss) = nullptr; (*iov) = nullptr; (*iov_len) = 0; (*ov) = nullptr; (*ov_len) = 0; (*auto_commit_flag) = 1; (*next_iov_ndx) = 0; (*next_ov_ndx) = 0; (*adb) = &db; shell->flush_flag = true; open(arr_size, sqlstm, db, ref_cur_placeholder, sqlstm_label); } otl_stream() OTL_NO_THROW : #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) otl_read_stream_interface(), #endif shell(nullptr), shell_pt(), connected(0), ref_ss(nullptr), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr), next_ov_ndx(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0), last_oper_was_read_op(false), override_(nullptr), buf_size_(0) { init_stream(); shell->flush_flag = true; } virtual ~otl_stream() #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW) OTL_THROWS_OTL_EXCEPTION #else OTL_NO_THROW #endif { if (!connected) return; try { if ((*io) != nullptr && shell->flush_flag == false) (*io)->set_flush_flag2(false); close(); if (shell != nullptr) { if ((*io) != nullptr) (*io)->set_flush_flag2(true); } } catch (OTL_CONST_EXCEPTION otl_exception &) { if (shell != nullptr) { if ((*io) != nullptr) (*io)->set_flush_flag2(true); } #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) clean(1); if (shell != nullptr) shell->set_should_delete(1); shell_pt.destroy(); #else shell_pt.destroy(); #endif #if !defined(OTL_DESTRUCTORS_DO_NOT_THROW) throw; #endif } #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if(otl_uncaught_exception()){} #else shell_pt.destroy(); #endif } OTL_NODISCARD int eof(void) OTL_THROWS_OTL_EXCEPTION{ if ((*io)) { return (*io)->eof(); } else if ((*ss)) { return (*ss)->eof(); } else if ((*ref_ss)) { return (*ref_ss)->eof(); } else return 1; } void skip_to_end_of_row() OTL_NO_THROW { if (next_ov_ndx == nullptr) return; if ((*ov_len) == 0) return; last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); (*io)->skip_to_end_of_row(); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); (*ss)->skip_to_end_of_row(); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); (*ref_ss)->skip_to_end_of_row(); break; } *next_ov_ndx = 0; } void skip_to_next_var() OTL_NO_THROW { if (next_ov_ndx == nullptr) return; if ((*ov_len) == 0) return; last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); (*io)->skip_to_next_var(); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); (*ss)->skip_to_next_var(); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); (*ref_ss)->skip_to_next_var(); break; } if((*next_ov_ndx)<(*ov_len)-1) ++(*next_ov_ndx); } void reset_to_last_valid_row() { if ((*io)) { (*io)->reset_to_last_valid_row(); } } void flush(const int rowoff = 0, const bool force_flush = false) OTL_THROWS_OTL_EXCEPTION { if ((*io)) { (*io)->flush(rowoff, force_flush); } } OTL_NODISCARD bool get_error_state(void) const { if (otl_uncaught_exception()) return true; else if ((*io)) return (*io)->get_error_state(); else return false; } void clean(const int clean_up_error_flag = 0) OTL_THROWS_OTL_EXCEPTION { if(next_ov_ndx!=nullptr)(*next_ov_ndx)=0; if(next_iov_ndx!=nullptr)(*next_iov_ndx)=0; if ((*io)) { (*io)->clean(clean_up_error_flag); } else if (*ss) { (*ss)->clean(); } else if (*ref_ss) { (*ref_ss)->clean(); } } void rewind(void) OTL_THROWS_OTL_EXCEPTION { if ((*io)) { (*io)->rewind(); } else if ((*ss)) { (*ss)->rewind(); } else if ((*ref_ss)) { (*ref_ss)->rewind(); } } OTL_NODISCARD int is_null(void) OTL_NO_THROW { if ((*io)) return (*io)->is_null(); else if ((*ss)) return (*ss)->is_null(); else if ((*ref_ss)) return (*ref_ss)->is_null(); else return 0; } void set_commit(int auto_commit = 0) OTL_NO_THROW { (*auto_commit_flag) = auto_commit; if ((*io)) { (*io)->set_commit(auto_commit); } } void open(const otl_stream_buffer_size_type arr_size, const char *sqlstm, otl_connect &db, const char *ref_cur_placeholder = nullptr, const char *sqlstm_label = nullptr) OTL_THROWS_OTL_EXCEPTION { if (arr_size <= 0) { OTL_THROW((otl_exception(otl_error_msg_40, otl_error_code_40, sqlstm))); } #if defined(OTL_STREAM_THROWS_NOT_CONNECTED_TO_DATABASE_EXCEPTION) if (!db.connected) { OTL_THROW((otl_exception(otl_error_msg_35, otl_error_code_35, sqlstm))); } #endif reset_end_marker(); if (this->good()) { const char *temp_stm_text = nullptr; switch (shell->stream_type) { case otl_no_stream_type: temp_stm_text = OTL_NO_STM_TEXT; break; case otl_inout_stream_type: temp_stm_text = (*io)->get_stm_label() ? (*io)->get_stm_label() : (*io)->get_stm_text(); break; case otl_select_stream_type: temp_stm_text = (*ss)->get_stm_label() ? (*ss)->get_stm_label() : (*ss)->get_stm_text(); break; case otl_refcur_stream_type: temp_stm_text = (*ref_ss)->get_stm_label() ? (*ref_ss)->get_stm_label() : (*ref_ss)->get_stm_text(); break; default: temp_stm_text = OTL_NO_STM_TEXT; break; } OTL_THROW((otl_exception(otl_error_msg_29, otl_error_code_29, temp_stm_text))); } if (shell == nullptr) init_stream(); buf_size_ = arr_size; OTL_TRACE_STREAM_OPEN2 #if (defined(OTL_STL) || defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if (adb != nullptr && *adb == nullptr) *adb = &db; if (adb != nullptr && (*adb) && (**adb).get_stream_pool_enabled_flag()) { char temp_buf[128]; otl_itoa(arr_size, temp_buf); const char delimiter = ';'; #if defined(OTL_STREAM_POOL_USES_STREAM_LABEL_AS_KEY) const char *temp_label = sqlstm_label ? sqlstm_label : sqlstm; #if defined(OTL_UNICODE_STRING_TYPE) std::string sql_stm(temp_label); sql_stm += delimiter; sql_stm += std::string(temp_buf); #else OTL_STRING_CONTAINER sql_stm(temp_label); sql_stm += delimiter; sql_stm += OTL_STRING_CONTAINER(temp_buf); #endif #else #if defined(OTL_UNICODE_STRING_TYPE) std::string sql_stm(sqlstm); #else OTL_STRING_CONTAINER sql_stm(sqlstm); #endif sql_stm += delimiter; #if defined(OTL_UNICODE_STRING_TYPE) sql_stm += std::string(temp_buf); #else sql_stm += OTL_STRING_CONTAINER(temp_buf); #endif #endif if (shell != nullptr) { otl_select_struct_override &temp_override = shell->override_; for (int i = 0; i < temp_override.getLen(); ++i) { otl_itoa(OTL_SCAST(int, temp_override.get_col_type(i)), temp_buf); sql_stm += delimiter; #if defined(OTL_UNICODE_STRING_TYPE) sql_stm += std::string(temp_buf); #else sql_stm += OTL_STRING_CONTAINER(temp_buf); #endif } } otl_stream_shell_generic *temp_shell = db.get_sc().find(sql_stm); if (temp_shell) { if (shell != nullptr) shell_pt.destroy(); shell = OTL_RCAST(otl_stream_shell *, temp_shell); ref_ss = &(shell->ref_ss); ss = &(shell->ss); io = &(shell->io); if ((*io) != nullptr){ (*io)->set_flush_flag2(true); } adb = &(shell->adb); auto_commit_flag = &(shell->auto_commit_flag); iov = &(shell->iov); iov_len = &(shell->iov_len); next_iov_ndx = &(shell->next_iov_ndx); ov = &(shell->ov); ov_len = &(shell->ov_len); next_ov_ndx = &(shell->next_ov_ndx); override_ = &(shell->override_); override_->set_master_stream_ptr(OTL_RCAST(void *, this)); try { if ((*iov_len) == 0) this->rewind(); } catch (OTL_CONST_EXCEPTION otl_exception &) { if ((*adb)) (*adb)->get_sc().remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; throw; } connected = 1; return; } if(shell != nullptr) shell->orig_sql_stm = sql_stm; } #endif delete[](*iov); delete[](*ov); (*iov) = nullptr; (*iov_len) = 0; (*ov) = nullptr; (*ov_len) = 0; (*next_iov_ndx) = 0; (*next_ov_ndx) = 0; char tmp[7]; char *c = OTL_CCAST(char *, sqlstm); while (otl_isspace(*c) || (*c) == '(') ++c; OTL_STRNCPY_S(tmp, sizeof(tmp), c, 6); tmp[6] = 0; c = tmp; while (*c) { *c = OTL_SCAST(char, otl_to_upper(*c)); ++c; } adb = &(shell->adb); (*adb) = &db; try { if ((strncmp(tmp, "SELECT", 6) == 0 || strncmp(tmp, "WITH", 4) == 0) && ref_cur_placeholder == nullptr) { override_->set_master_stream_ptr(OTL_RCAST(void *, this)); (*ss) = new otl_select_stream(override_, arr_size, sqlstm, db, otl_explicit_select, sqlstm_label); shell->stream_type = otl_select_stream_type; } else if (ref_cur_placeholder != nullptr) { override_->set_master_stream_ptr(OTL_RCAST(void *, this)); (*ref_ss) = new otl_ref_select_stream( override_, arr_size, sqlstm, ref_cur_placeholder, db, sqlstm_label); shell->stream_type = otl_refcur_stream_type; } else { (*io) = new otl_inout_stream( arr_size, sqlstm, db, OTL_RCAST(void *, this), false, sqlstm_label); (*io)->set_flush_flag(shell->flush_flag); shell->stream_type = otl_inout_stream_type; } } catch (OTL_CONST_EXCEPTION otl_exception &) { shell_pt.destroy(); throw; } if ((*io)) (*io)->set_commit((*auto_commit_flag)); create_var_desc(); connected = 1; } void intern_cleanup(void) { delete[](*iov); delete[](*ov); (*iov) = nullptr; (*iov_len) = 0; (*ov) = nullptr; (*ov_len) = 0; (*next_iov_ndx) = 0; (*next_ov_ndx) = 0; override_->setLen(0); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: try { if ((*io) != nullptr) { (*io)->flush(); (*io)->close(); } } catch (OTL_CONST_EXCEPTION otl_exception &) { clean(1); (*io)->close(); delete (*io); (*io) = nullptr; shell->stream_type = otl_no_stream_type; throw; } delete (*io); (*io) = nullptr; shell->stream_type = otl_no_stream_type; break; case otl_select_stream_type: try { if ((*ss) != nullptr) (*ss)->close(); } catch (OTL_CONST_EXCEPTION otl_exception &) { delete (*ss); (*ss) = nullptr; shell->stream_type = otl_no_stream_type; throw; } delete (*ss); (*ss) = nullptr; shell->stream_type = otl_no_stream_type; break; case otl_refcur_stream_type: try { if ((*ref_ss) != nullptr) (*ref_ss)->close(); } catch (OTL_CONST_EXCEPTION otl_exception &) { delete (*ref_ss); (*ref_ss) = nullptr; shell->stream_type = otl_no_stream_type; throw; } delete (*ref_ss); (*ref_ss) = nullptr; shell->stream_type = otl_no_stream_type; break; } (*ss) = nullptr; (*io) = nullptr; (*ref_ss) = nullptr; if (adb != nullptr) (*adb) = nullptr; adb = nullptr; } #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) void close(const bool save_in_stream_pool = true) #else void close(void) #endif { if (shell == nullptr) return; OTL_TRACE_FUNC(0x4, "otl_stream", "close", "") #if (defined(OTL_STL) || defined(OTL_ACE) || \ defined(OTL_UNICODE_STRING_TYPE)) && \ defined(OTL_STREAM_POOLING_ON) if (save_in_stream_pool && (*adb) && (**adb).get_stream_pool_enabled_flag() && !otl_uncaught_exception()) { try { this->flush(); this->clean(1); } catch (OTL_CONST_EXCEPTION otl_exception &) { this->clean(1); throw; } if (otl_uncaught_exception()) { (*adb)->get_sc().remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; return; } #if defined(OTL_STL) && defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) if (otl_uncaught_exception()) { if ((*adb)) (*adb)->get_sc().remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; return; } #elif defined(OTL_INTERNAL_UNCAUGHT_EXCEPTION_ON) if (otl_uncaught_exception()) { if ((*adb)) (*adb)->get_sc().remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; return; } #endif if(shell->io!=nullptr) shell->io->set_commit(1); (*adb)->get_sc().add(shell, shell->orig_sql_stm.c_str()); shell_pt.disconnect(); connected = 0; } else { if ((*adb)) (*adb)->get_sc().remove(shell, shell->orig_sql_stm); intern_cleanup(); shell_pt.destroy(); connected = 0; } #else intern_cleanup(); connected = 0; #endif } OTL_NODISCARD otl_column_desc *describe_select(int &desc_len) OTL_NO_THROW { desc_len = 0; switch (shell->stream_type) { case otl_no_stream_type: return nullptr; case otl_inout_stream_type: return nullptr; case otl_select_stream_type: desc_len = (*ss)->get_sl_len(); return (*ss)->get_sl_desc(); case otl_refcur_stream_type: desc_len = (*ref_ss)->get_sl_len(); return (*ref_ss)->get_sl_desc(); default: return nullptr; } } OTL_NODISCARD int good(void) OTL_NO_THROW { if (!connected) return 0; if ((*io) || (*ss) || (*ref_ss)) { return 1; } else return 0; } otl_stream &operator>>(otl_stream &(*pf)(otl_stream &)) { (*pf)(*this); return *this; } otl_stream &operator<<(otl_stream &(*pf)(otl_stream &)) { (*pf)(*this); return *this; } #if defined(OTL_STREAM_WITH_STD_TUPLE_ON) && defined(OTL_ANSI_CPP_11_TUPLE_IS_SUPPORTED) public: template otl_stream& operator<<(const std::tuple& t){ otl_tuple_helper::write(*this,t); return (*this); } template otl_stream& operator>>(std::tuple& t){ otl_tuple_helper::read(*this,t); return (*this); } #endif #if defined(OTL_STREAM_WITH_STD_SPAN_ON) && defined(OTL_CPP_20_ON) public: template otl_stream& operator<<(std::span v){ for(const auto& e: v){ (*this)< otl_stream& operator<<(const std::variant& v){ bool value_written=false; otl_variant_helper> ::write(*this,v,value_written); return (*this); } template otl_stream& operator>>(std::variant& v){ bool value_read=false; otl_variant_helper> ::read(*this,v,value_read); return (*this); } #endif #if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_CPP_14_ON) #if defined(OTL_COMPILER_HAS_STD_OPTIONAL) template otl_stream& operator<<(const std::optional &var) OTL_THROWS_OTL_EXCEPTION { if(var) (*this)<<(*var); else (*this)< otl_stream& operator>>(std::optional &var) OTL_THROWS_OTL_EXCEPTION { if(var){ (*this)>>(*var); if(this->is_null())var=std::optional(); }else{ TData temp_var; (*this)>>temp_var; if(!this->is_null())var.emplace(std::move(temp_var)); } return *this; } #else template class Optional> otl_stream& operator<<(const Optional &var) OTL_THROWS_OTL_EXCEPTION { if(var) (*this)<<(*var); else (*this)< class Optional> otl_stream& operator>>(Optional &var) OTL_THROWS_OTL_EXCEPTION { if(var){ (*this)>>(*var); if(this->is_null())var=Optional(); }else{ TData temp_var; (*this)>>temp_var; if(!this->is_null())var.emplace(std::move(temp_var)); } return *this; } #endif #endif #if defined(OTL_PARANOID_EOF) void throw_if_eof_was_already_reached(const int eof_flag, const char *operator_type = nullptr) { if (eof_flag) { char out_buf[256]; #if defined(__clang__) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-value" #endif OTL_SPRINTF_S(out_buf, sizeof(out_buf), otl_error_msg_42, operator_type == nullptr ? "" : operator_type); #if defined(__clang__) #pragma clang diagnostic pop #endif OTL_THROW((otl_exception(out_buf, otl_error_code_42, this->get_stm_text(), this->describe_next_out_var()->name))); } } #endif otl_stream &operator>>(otl_pl_tab_generic &tab) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; if ((*io)) { last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_pl_tab_generic&"); #endif (*io)->operator>>(tab); OTL_TRACE_WRITE(", tab len=" << tab.len(), "operator >>", "PL/SQL Tab&") inc_next_ov(); } return *this; } otl_stream &operator>>(otl_refcur_stream &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; if ((*io)) { last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_refcur_stream&"); #endif (*io)->operator>>(s); OTL_TRACE_WRITE(" ref.cur.stream", "operator >>", "otl_refcur_stream&") inc_next_ov(); } return *this; } otl_stream &operator<<(otl_pl_tab_generic &tab) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); if ((*io)) { (*io)->operator<<(tab); OTL_TRACE_READ(", tab len=" << tab.len(), "operator <<", "PL/SQL Tab&") inc_next_iov(); } return *this; } #if defined(OTL_PL_TAB) && defined(OTL_STL) otl_stream &operator>>(otl_pl_vec_generic &vec) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; if ((*io)) { last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_pl_tab_generic&"); #endif (*io)->operator>>(vec); OTL_TRACE_WRITE(", tab len=" << vec.len(), "operator >>", "PL/SQL Tab&") inc_next_ov(); } return *this; } otl_stream &operator<<(otl_pl_vec_generic &vec) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); if ((*io)) { (*io)->operator<<(vec); OTL_TRACE_READ(", tab len=" << vec.len(), "operator <<", "PL/SQL Tab&") inc_next_iov(); } return *this; } #endif otl_stream &operator<<(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); if ((*io)) { (*io)->operator<<(s); OTL_TRACE_READ(", lob stream", "operator <<", "PL/otl_lob_stream&") inc_next_iov(); } return *this; } otl_stream &operator>>(otl_time0 &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: { last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&"); #endif (*io)->operator>>(s); #if defined(OTL_ORA_TIMESTAMP) OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>", "otl_datetime&"); #endif break; } case otl_select_stream_type: { last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&"); #endif (*ss)->operator>>(s); #if defined(OTL_ORA_TIMESTAMP) OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>", "otl_datetime&"); #endif break; } case otl_refcur_stream_type: { last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_datetime&"); #endif (*ref_ss)->operator>>(s); #if defined(OTL_ORA_TIMESTAMP) OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>", "otl_datetime&"); #endif break; } } #if defined(OTL_ORA_TIMESTAMP) inc_next_ov(); #endif return *this; } otl_stream &operator<<(const otl_time0 &n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: { (*io)->operator<<(n); #if defined(OTL_ORA_TIMESTAMP) OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(n), "operator <<", "otl_datetime&"); #endif break; } case otl_select_stream_type: { (*ss)->operator<<(n); #if defined(OTL_ORA_TIMESTAMP) OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(n), "operator <<", "otl_datetime&"); #endif break; } case otl_refcur_stream_type: { (*ref_ss)->operator<<(n); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); #if defined(OTL_ORA_TIMESTAMP) OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(n), "operator <<", "otl_datetime&"); #endif break; } } #if defined(OTL_ORA_TIMESTAMP) inc_next_iov(); #endif return *this; } #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) // already declared #else OTL_ORA_COMMON_READ_STREAM & operator>>(otl_datetime &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; #if defined(OTL_ORA7_STRING_TO_TIMESTAMP) otl_var_desc *temp_next_var = describe_next_out_var(); if (temp_next_var != nullptr && temp_next_var->ftype == otl_var_char) { #if defined(OTL_UNICODE) OTL_CHAR tmp_str[100]; #elif defined(OTL_UNICODE) && defined(OTL_UNICODE_CHAR_TYPE) OTL_UNICODE_CHAR_TYPE tmp_str[100]; #else char tmp_str[100]; #endif (*this) >> tmp_str; #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_DATETIME_NULL_TO_VAL; else OTL_ORA7_STRING_TO_TIMESTAMP(tmp_str, s); #else OTL_ORA7_STRING_TO_TIMESTAMP(tmp_str, s); #endif OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>", "otl_datetime&"); return *this; } else { otl_time0 tmp; (*this) >> tmp; #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_DATETIME_NULL_TO_VAL; else { s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 + (OTL_SCAST(int, tmp.year) - 100); s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour - 1; s.minute = tmp.minute - 1; s.second = tmp.second - 1; } #else s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 + (OTL_SCAST(int, tmp.year) - 100); s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour - 1; s.minute = tmp.minute - 1; s.second = tmp.second - 1; #endif OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>", "otl_datetime&") inc_next_ov(); return *this; } #else otl_time0 tmp; (*this) >> tmp; #if defined(OTL_DEFAULT_DATETIME_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_DATETIME_NULL_TO_VAL; else { s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 + (OTL_SCAST(int, tmp.year) - 100); s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour - 1; s.minute = tmp.minute - 1; s.second = tmp.second - 1; } #else s.year = (OTL_SCAST(int, tmp.century) - 100) * 100 + (OTL_SCAST(int, tmp.year) - 100); s.month = tmp.month; s.day = tmp.day; s.hour = tmp.hour - 1; s.minute = tmp.minute - 1; s.second = tmp.second - 1; #endif OTL_TRACE_WRITE(OTL_TRACE_FORMAT_DATETIME(s), "operator >>", "otl_datetime&"); inc_next_ov(); return *this; #endif } #endif #if (defined(OTL_ORA8I) || defined(OTL_ORA9I)) && defined(OTL_ORA_TIMESTAMP) // already declared #else otl_stream &operator<<(const otl_datetime &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(OTL_ORA7_TIMESTAMP_TO_STRING) otl_var_desc *temp_next_var = describe_next_in_var(); if (temp_next_var != nullptr && temp_next_var->ftype == otl_var_char) { #if defined(OTL_UNICODE) OTL_CHAR tmp_str[100]; #elif defined(OTL_UNICODE) && defined(OTL_UNICODE_CHAR_TYPE) OTL_UNICODE_CHAR_TYPE tmp_str[100]; #else char tmp_str[100]; #endif OTL_ORA7_TIMESTAMP_TO_STRING(s, tmp_str); OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<", "otl_datetime&"); (*this) << tmp_str; return *this; } else { otl_time0 tmp; tmp.year = OTL_SCAST(unsigned char, ((s.year % 100) + 100)); tmp.century = OTL_SCAST(unsigned char, ((s.year / 100) + 100)); tmp.month = OTL_SCAST(unsigned char, s.month); tmp.day = OTL_SCAST(unsigned char, s.day); tmp.hour = OTL_SCAST(unsigned char, (s.hour + 1)); tmp.minute = OTL_SCAST(unsigned char, (s.minute + 1)); tmp.second = OTL_SCAST(unsigned char, (s.second + 1)); OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<", "otl_datetime&"); (*this) << tmp; inc_next_iov(); return *this; } #else otl_time0 tmp; tmp.year = OTL_SCAST(unsigned char, ((s.year % 100) + 100)); tmp.century = OTL_SCAST(unsigned char, ((s.year / 100) + 100)); tmp.month = OTL_SCAST(unsigned char, s.month); tmp.day = OTL_SCAST(unsigned char, s.day); tmp.hour = OTL_SCAST(unsigned char, (s.hour + 1)); tmp.minute = OTL_SCAST(unsigned char, (s.minute + 1)); tmp.second = OTL_SCAST(unsigned char, (s.second + 1)); OTL_TRACE_READ(OTL_TRACE_FORMAT_DATETIME(s), "operator <<", "otl_datetime&"); (*this) << tmp; inc_next_iov(); return *this; #endif } #endif #if !defined(OTL_UNICODE) OTL_ORA_COMMON_READ_STREAM &operator>>(char &c) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char&"); #endif (*io)->operator>>(c); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char&"); #endif (*ss)->operator>>(c); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char&"); #endif (*ref_ss)->operator>>(c); break; } #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL) if ((*this).is_null()) c = OTL_DEFAULT_CHAR_NULL_TO_VAL; #endif OTL_TRACE_WRITE("'" << c << "'", "operator >>", "char&") inc_next_ov(); return *this; } #endif OTL_ORA_COMMON_READ_STREAM & operator>>(unsigned char &c) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&"); #endif (*io)->operator>>(c); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&"); #endif (*ss)->operator>>(c); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char&"); #endif (*ref_ss)->operator>>(c); break; } #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL) if ((*this).is_null()) c = OTL_DEFAULT_CHAR_NULL_TO_VAL; #endif OTL_TRACE_WRITE("'" << c << "'", "operator >>", "unsigned char&") inc_next_ov(); return *this; } #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) OTL_ORA_COMMON_READ_STREAM & operator>>(OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&"); #endif (*io)->operator>>(s); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&"); #endif (*ss)->operator>>(s); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_STRING_CONTAINER&"); #endif (*ref_ss)->operator>>(s); break; } #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL) if ((*this).is_null()) { OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s); } #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) s = OTL_DEFAULT_STRING_NULL_TO_VAL; #endif OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "OTL_STRING_CONTAINER&") inc_next_ov(); return *this; } #endif #if !defined(OTL_UNICODE) OTL_ORA_COMMON_READ_STREAM &operator>>(char *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif (*io)->operator>>(s); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif (*ss)->operator>>(s); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "char*"); #endif (*ref_ss)->operator>>(s); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "char*") inc_next_ov(); return *this; } #endif #if !defined(OTL_UNICODE) && defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template OTL_ORA_COMMON_READ_STREAM &operator>>(std::array& s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*io)->operator>>(s); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*ss)->getString(s.data(),OTL_SCAST(int,s.size())); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*ref_ss)->operator>>(s); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "std::array&") inc_next_ov(); return *this; } template otl_stream &operator<<(const std::array& s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array&"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_UNICODE) && defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) template OTL_ORA_COMMON_READ_STREAM &operator>>(std::array& s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*io)->operator>>(s); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*ss)->getString(s.data(),OTL_SCAST(int,s.size())); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "std::array&"); #endif (*ref_ss)->operator>>(s); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "std::array&") inc_next_ov(); return *this; } template otl_stream &operator<<(const std::array& s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array&"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_UNICODE_STRING_TYPE) OTL_ORA_COMMON_READ_STREAM & operator>>(OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&"); #endif (*io)->operator>>(s); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&"); #endif (*ss)->operator>>(s); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_STRING_TYPE&"); #endif (*ref_ss)->operator>>(s); break; } #if defined(OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL) if ((*this).is_null()) { OTL_USER_DEFINED_STRING_CLASS_DEFAULT_NULL_TO_VAL(s); } #elif defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) s = OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, OTL_DEFAULT_STRING_NULL_TO_VAL); #endif OTL_TRACE_WRITE("\"" << s.c_str() << "\"", "operator >>", "OTL_UNICODE_STRING_TYPE&"); inc_next_ov(); return *this; } otl_stream &operator<<(const OTL_UNICODE_STRING_TYPE &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s.c_str() << "\"", "operator <<", "OTL_UNICODE_STRING_TYPE&"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_STD_UNICODE_STRING_VIEW_CLASS) && defined(OTL_UNICODE_CHAR_TYPE) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS)) otl_stream &operator<<(OTL_STD_UNICODE_STRING_VIEW_CLASS s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS) OTL_TRACE_READ("\"" << s.data() << "\"", "operator <<", "OTL_THIRD_PARTY_UNICODE_STRING_VIEW_CLASS"); #else OTL_TRACE_READ("\"" << s.data() << "\"", "operator <<", "OTL_STD_UNICODE_STRING_VIEW_CLASS"); #endif switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif OTL_ORA_COMMON_READ_STREAM & operator>>(unsigned char *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*"); #endif (*io)->operator>>(s); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*"); #endif (*ss)->operator>>(s); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "unsigned char*"); #endif (*ref_ss)->operator>>(s); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif #if defined(OTL_UNICODE) OTL_TRACE_WRITE("\"" << OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, s) << "\"", "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*") #else OTL_TRACE_WRITE("\"" << s << "\"", "operator >>", "unsigned char*") #endif inc_next_ov(); return *this; } #if defined(OTL_UNICODE) OTL_ORA_COMMON_READ_STREAM & operator>>(OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*"); #endif (*io)->operator>>(OTL_RCAST(unsigned char *, s)); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*"); #endif (*ss)->operator>>(OTL_RCAST(unsigned char *, s)); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE*"); #endif (*ref_ss)->operator>>(OTL_RCAST(unsigned char *, s)); break; } #if defined(OTL_DEFAULT_STRING_NULL_TO_VAL) if ((*this).is_null()) otl_strcpy( OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, OTL_DEFAULT_STRING_NULL_TO_VAL)); #endif OTL_TRACE_WRITE(OTL_RCAST(OTL_UNICODE_CHAR_TYPE *, s), "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*") inc_next_ov(); return *this; } OTL_ORA_COMMON_READ_STREAM & operator>>(OTL_UNICODE_CHAR_TYPE &c) OTL_THROWS_OTL_EXCEPTION { OTL_UNICODE_CHAR_TYPE s[1024]; last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&"); #endif (*io)->operator>>(OTL_RCAST(unsigned char *, s)); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&"); #endif (*ss)->operator>>(OTL_RCAST(unsigned char *, s)); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UNICODE_CHAR_TYPE&"); #endif (*ref_ss)->operator>>(OTL_RCAST(unsigned char *, s)); break; } #if defined(_MSC_VER) && (_MSC_VER >= 1700) #pragma warning(push) #pragma warning(disable : 6001) #endif c = s[0]; #if defined(_MSC_VER) && (_MSC_VER >= 1700) #pragma warning(pop) #endif #if defined(OTL_DEFAULT_CHAR_NULL_TO_VAL) if ((*this).is_null()) c = OTL_DEFAULT_CHAR_NULL_TO_VAL; #endif OTL_TRACE_WRITE(c, "operator >>", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "") inc_next_ov(); return *this; } #endif #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) OTL_ORA_COMMON_READ_STREAM & operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&"); #endif (*io)->operator>>(n); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&"); #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(n); #else (*ss)->operator>>(n); #endif break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_BIGINT&"); #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ref_ss)->operator>>(n); #else (*ref_ss)->operator>>(n); #endif break; } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) n = OTL_SCAST(int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif OTL_TRACE_WRITE(n, "operator >>", "OTL_BIGINT&") inc_next_ov(); return *this; } #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) OTL_ORA_COMMON_READ_STREAM & operator>>(OTL_UBIGINT &n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&"); #endif (*io)->operator>>(n); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&"); #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator>>(n); #else (*ss)->operator>>(n); #endif break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "OTL_UBIGINT&"); #endif #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ref_ss)->operator>>(n); #else (*ref_ss)->operator>>(n); #endif break; } #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if ((*this).is_null()) n = OTL_SCAST(int, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif OTL_TRACE_WRITE(n, "operator >>", "OTL_UBIGINT&") inc_next_ov(); return *this; } #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) otl_stream &operator>>(OTL_NUMERIC_TYPE_1 &n) OTL_THROWS_OTL_EXCEPTION { char temp_val[otl_numeric_type_1_str_size]; #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_1_str_size]; (*this) >> OTL_RCAST(unsigned char *, unitemp_val); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++uc; ++c; } *c = 0; #else (*this) >> temp_val; #endif if (this->is_null()) { #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (this->is_null()) n = OTL_SCAST(OTL_NUMERIC_TYPE_1, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif return *this; } OTL_STR_TO_NUMERIC_TYPE_1(temp_val, n) return *this; } otl_stream &operator<<(const OTL_NUMERIC_TYPE_1 &n) OTL_THROWS_OTL_EXCEPTION { #if defined(OTL_UNICODE) char temp_val[otl_numeric_type_1_str_size]; OTL_NUMERIC_TYPE_1_TO_STR(n, temp_val) OTL_CHAR unitemp_val[otl_numeric_type_1_str_size]; OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*c) { *uc = OTL_SCAST(OTL_CHAR, *c); ++uc; ++c; } *uc = 0; (*this) << OTL_RCAST(unsigned char *, unitemp_val); #else char temp_val[otl_numeric_type_1_str_size]; OTL_NUMERIC_TYPE_1_TO_STR(n, temp_val) (*this) << temp_val; #endif return *this; } #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) otl_stream &operator>>(OTL_NUMERIC_TYPE_2 &n) OTL_THROWS_OTL_EXCEPTION { char temp_val[otl_numeric_type_2_str_size]; #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_2_str_size]; (*this) >> OTL_RCAST(unsigned char *, unitemp_val); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++uc; ++c; } *c = 0; #else (*this) >> temp_val; #endif if (this->is_null()) { #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (this->is_null()) n = OTL_SCAST(OTL_NUMERIC_TYPE_2, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif return *this; } OTL_STR_TO_NUMERIC_TYPE_2(temp_val, n) return *this; } otl_stream &operator<<(const OTL_NUMERIC_TYPE_2 &n) OTL_THROWS_OTL_EXCEPTION { #if defined(OTL_UNICODE) char temp_val[otl_numeric_type_2_str_size]; OTL_NUMERIC_TYPE_2_TO_STR(n, temp_val) OTL_CHAR unitemp_val[otl_numeric_type_2_str_size]; OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*c) { *uc = OTL_SCAST(OTL_CHAR, *c); ++uc; ++c; } *uc = 0; (*this) << OTL_RCAST(unsigned char *, unitemp_val); #else char temp_val[otl_numeric_type_2_str_size]; OTL_NUMERIC_TYPE_2_TO_STR(n, temp_val) (*this) << temp_val; #endif return *this; } #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) otl_stream &operator>>(OTL_NUMERIC_TYPE_3 &n) OTL_THROWS_OTL_EXCEPTION { char temp_val[otl_numeric_type_3_str_size]; #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_numeric_type_3_str_size]; (*this) >> OTL_RCAST(unsigned char *, unitemp_val); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++uc; ++c; } *c = 0; #else (*this) >> temp_val; #endif if (this->is_null()) { #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (this->is_null()) n = OTL_SCAST(OTL_NUMERIC_TYPE_3, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif return *this; } OTL_STR_TO_NUMERIC_TYPE_3(temp_val, n) return *this; } otl_stream &operator<<(const OTL_NUMERIC_TYPE_3 &n) OTL_THROWS_OTL_EXCEPTION { #if defined(OTL_UNICODE) char temp_val[otl_numeric_type_3_str_size]; OTL_NUMERIC_TYPE_3_TO_STR(n, temp_val) OTL_CHAR unitemp_val[otl_numeric_type_3_str_size]; OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*c) { *uc = OTL_SCAST(OTL_CHAR, *c); ++uc; ++c; } *uc = 0; (*this) << OTL_RCAST(unsigned char *, unitemp_val); #else char temp_val[otl_numeric_type_3_str_size]; OTL_NUMERIC_TYPE_3_TO_STR(n, temp_val) (*this) << temp_val; #endif return *this; } #endif #if defined(OTL_BIGINT) && defined(OTL_STR_TO_BIGINT) && \ defined(OTL_BIGINT_TO_STR) otl_stream &operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION { char temp_val[otl_bigint_str_size]; #if defined(OTL_UNICODE) OTL_CHAR unitemp_val[otl_bigint_str_size]; (*this) >> OTL_RCAST(unsigned char *, unitemp_val); OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*uc) { *c = OTL_SCAST(char, *uc); ++uc; ++c; } *c = 0; #else (*this) >> temp_val; #endif if (this->is_null()) { #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (this->is_null()) n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif return *this; } OTL_STR_TO_BIGINT(temp_val, n) return *this; } otl_stream &operator<<(const OTL_BIGINT n) OTL_THROWS_OTL_EXCEPTION { #if defined(OTL_UNICODE) char temp_val[otl_bigint_str_size]; OTL_BIGINT_TO_STR(n, temp_val) OTL_CHAR unitemp_val[otl_bigint_str_size]; OTL_CHAR *uc = unitemp_val; char *c = temp_val; while (*c) { *uc = OTL_SCAST(OTL_CHAR, *c); ++uc; ++c; } *uc = 0; (*this) << OTL_RCAST(unsigned char *, unitemp_val); #else char temp_val[otl_bigint_str_size]; OTL_BIGINT_TO_STR(n, temp_val) (*this) << temp_val; #endif return *this; } #elif defined(OTL_BIGINT) && defined(OTL_ORA_MAP_BIGINT_TO_LONG) otl_stream &operator>>(OTL_BIGINT &n) OTL_THROWS_OTL_EXCEPTION { long temp_val; (*this) >> temp_val; if (this->is_null()) { #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (this->is_null()) n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); #endif return *this; } n = OTL_SCAST(OTL_BIGINT, temp_val); return *this; } otl_stream &operator<<(const OTL_BIGINT n) OTL_THROWS_OTL_EXCEPTION { long temp_val = OTL_SCAST(long, n); (*this) << temp_val; return *this; } #endif #define OTL_GTGT_OPERATOR_3(T,T_type) \ OTL_ORA_COMMON_READ_STREAM &operator>>(T& n) OTL_THROWS_OTL_EXCEPTION{\ last_oper_was_read_op = true; \ switch (shell->stream_type) { \ case otl_no_stream_type: \ break; \ case otl_inout_stream_type: \ last_eof_rc = (*io)->eof(); \ OTL_PARANOID_EOF_THROW(#T "&"); \ (*io)->operator>>(n); \ break; \ case otl_select_stream_type: \ last_eof_rc = (*ss)->eof(); \ OTL_PARANOID_EOF_THROW(#T "&"); \ OTL_OPERATOR_1(ss,n,T,T_type,>>); \ break; \ case otl_refcur_stream_type: \ last_eof_rc = (*ref_ss)->eof(); \ OTL_PARANOID_EOF_THROW(#T "&"); \ OTL_OPERATOR_1(ref_ss,n,T,T_type,>>); \ break; \ } \ OTL_DEFAULT_NULL_ASSIGN(T,n); \ OTL_TRACE_WRITE(n, "operator >>", #T "&"); \ inc_next_ov(); \ return *this; \ } #if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 305) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wextra-semi" #endif OTL_GTGT_OPERATOR_3(int,otl_var_int); OTL_GTGT_OPERATOR_3(unsigned int,otl_var_unsigned_int); OTL_GTGT_OPERATOR_3(short int,otl_var_short); OTL_GTGT_OPERATOR_3(long int,otl_var_long_int); OTL_GTGT_OPERATOR_3(float,otl_var_float); OTL_GTGT_OPERATOR_3(double,otl_var_double); OTL_ORA_COMMON_READ_STREAM & operator>>(otl_long_string &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator>>(s); break; case otl_select_stream_type: (*ss)->operator>>(s); break; case otl_refcur_stream_type: (*ref_ss)->operator>>(s); break; } OTL_TRACE_WRITE(" len=" << s.len(), "operator >>", "otl_long_string&") inc_next_ov(); return *this; } OTL_ORA_COMMON_READ_STREAM & operator>>(otl_lob_stream &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = true; switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&"); #endif (*io)->operator>>(s); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&"); #endif (*ss)->operator>>(s); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "otl_lob_stream&"); #endif (*ref_ss)->operator>>(s); break; } shell->lob_stream_flag = true; OTL_TRACE_WRITE(" lob stream", "operator >>", "otl_lob_stream&") inc_next_ov(); return *this; } #if defined(OTL_ORA_SDO_GEOMETRY) OTL_ORA_COMMON_READ_STREAM & operator >> (oci_spatial_geometry &s) OTL_THROWS_OTL_EXCEPTION{ last_oper_was_read_op = true; switch(shell->stream_type){ case otl_no_stream_type: break; case otl_inout_stream_type: last_eof_rc = (*io)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "oci_spatial_geometry&"); #endif (*io)->operator >> (s); break; case otl_select_stream_type: last_eof_rc = (*ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "oci_spatial_geometry&"); #endif (*ss)->operator >> (s); break; case otl_refcur_stream_type: last_eof_rc = (*ref_ss)->eof(); #if defined(OTL_PARANOID_EOF) throw_if_eof_was_already_reached(last_eof_rc, "oci_spatial_geometry&"); #endif (*ref_ss)->operator >> (s); break; } shell->lob_stream_flag = true; OTL_TRACE_WRITE(" lob stream", "operator >>", "oci_spatial_geometry&") inc_next_ov(); return *this; } #endif #if defined(OTL_STREAM_CUSTOM_CHAR_LTLT_OPERATORS) OTL_STREAM_CUSTOM_CHAR_LTLT_OPERATORS #else #if !defined(OTL_UNICODE) otl_stream &operator<<(const char c) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("'" << c << "'", "operator <<", "char"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(c); break; case otl_select_stream_type: (*ss)->operator<<(c); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(c); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif otl_stream &operator<<(const unsigned char c) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("'" << c << "'", "operator <<", "unsigned char"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(c); break; case otl_select_stream_type: (*ss)->operator<<(c); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(c); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_STD_STRING_VIEW_CLASS) && (defined(OTL_CPP_14_ON) || defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS)) otl_stream &operator<<(OTL_STD_STRING_VIEW_CLASS s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(OTL_THIRD_PARTY_STRING_VIEW_CLASS) OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_THIRD_PARTY_STRING_VIEW_CLASS"); #else OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_STD_STRING_VIEW_CLASS"); #endif switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) otl_stream &operator<<(const OTL_STRING_CONTAINER &s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s << "\"", "operator <<", "OTL_STRING_CONTAINER&"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if !defined(OTL_UNICODE) otl_stream &operator<<(const char *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << s << "\"", "operator <<", "char*"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif otl_stream &operator<<(const unsigned char *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); #if defined(OTL_UNICODE) OTL_TRACE_READ("\"" << OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, s) << "\"", "operator <<", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*"); #else OTL_TRACE_READ("\"" << s << "\"", "operator <<", "unsigned char*"); #endif switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #if defined(OTL_UNICODE) otl_stream &operator<<(const OTL_UNICODE_CHAR_TYPE *s) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("\"" << OTL_RCAST(const OTL_UNICODE_CHAR_TYPE *, s) << "\"", "operator <<", OTL_UNICODE_CHAR_TYPE_TRACE_NAME "*"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(OTL_RCAST(const unsigned char *, s)); break; case otl_select_stream_type: (*ss)->operator<<(OTL_RCAST(const unsigned char *, s)); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(OTL_RCAST(const unsigned char *, s)); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } otl_stream &operator<<(const OTL_UNICODE_CHAR_TYPE c) OTL_THROWS_OTL_EXCEPTION { OTL_UNICODE_CHAR_TYPE s[2]; s[0] = c; s[1] = 0; (*this) << s; return *this; } #endif #if defined(OTL_BIGINT) && \ (defined(OTL_ORA11G_R2) && !defined(OTL_STR_TO_BIGINT) && \ !defined(OTL_BIGINT_TO_STR)) otl_stream &operator<<(const OTL_BIGINT n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ(n, "operator <<", "OTL_BIGINT"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(n); break; case otl_select_stream_type: #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif break; case otl_refcur_stream_type: #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ref_ss)->operator<<(n); #else (*ref_ss)->operator<<(n); #endif if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #if defined(OTL_UBIGINT) && defined(OTL_ORA11G_R2) otl_stream &operator<<(const OTL_UBIGINT n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ(n, "operator <<", "OTL_UBIGINT"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(n); break; case otl_select_stream_type: #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ss)->operator<<(n); #else (*ss)->operator<<(n); #endif break; case otl_refcur_stream_type: #if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT) (*ref_ss)->operator<<(n); #else (*ref_ss)->operator<<(n); #endif if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif #define OTL_LTLT_OPERATOR_3(T,T_type) \ otl_stream &operator<<(const T n) OTL_THROWS_OTL_EXCEPTION { \ last_oper_was_read_op = false; \ reset_end_marker(); \ OTL_TRACE_READ(n, "operator <<", #T); \ switch (shell->stream_type) { \ case otl_no_stream_type: \ break; \ case otl_inout_stream_type: \ (*io)->operator<<(n); \ break; \ case otl_select_stream_type: \ OTL_OPERATOR_1(ss,n,T,T_type,<<); \ break; \ case otl_refcur_stream_type: \ OTL_OPERATOR_1(ref_ss,n,T,T_type,<<); \ if (!(*ov) && (*ref_ss)->get_sl()) \ create_var_desc(); \ break; \ } \ inc_next_iov(); \ return *this; \ } OTL_LTLT_OPERATOR_3(int,otl_var_int); OTL_LTLT_OPERATOR_3(unsigned int,otl_var_unsigned_int); OTL_LTLT_OPERATOR_3(short int,otl_var_short); OTL_LTLT_OPERATOR_3(long int,otl_var_long_int); OTL_LTLT_OPERATOR_3(float,otl_var_float); OTL_LTLT_OPERATOR_3(double,otl_var_double); otl_stream &operator<<(OTL_NULL_PARM n) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("NULL", "operator <<", "otl_null&"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(n); break; case otl_select_stream_type: (*ss)->operator<<(n); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(n); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } otl_stream &operator<<(const otl_long_string &d) OTL_THROWS_OTL_EXCEPTION { last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ(" len=" << d.len(), "operator <<", "otl_long_string&"); switch (shell->stream_type) { case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(d); break; case otl_select_stream_type: (*ss)->operator<<(d); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(d); if (!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #if defined(OTL_ORA_SDO_GEOMETRY) OTL_ORA_COMMON_READ_STREAM & operator << (oci_spatial_geometry &s) OTL_THROWS_OTL_EXCEPTION{ last_oper_was_read_op = false; reset_end_marker(); OTL_TRACE_READ("geometry", "operator <<", "oci_spatial_geometry&"); switch(shell->stream_type){ case otl_no_stream_type: break; case otl_inout_stream_type: (*io)->operator<<(s); break; case otl_select_stream_type: (*ss)->operator<<(s); break; case otl_refcur_stream_type: (*ref_ss)->operator<<(s); if(!(*ov) && (*ref_ss)->get_sl()) create_var_desc(); break; } inc_next_iov(); return *this; } #endif private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_stream &operator=(const otl_stream &) = delete; otl_stream(const otl_stream &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_stream &operator=(otl_stream &&) = delete; otl_stream(otl_stream &&) = delete; #endif #if !defined(OTL_STREAM_NO_PRIVATE_BOOL_OPERATORS) otl_stream &operator>>(bool &) = delete; otl_stream &operator<<(const bool) = delete; #endif #if !defined(OTL_STREAM_NO_PRIVATE_UNSIGNED_LONG_OPERATORS) otl_stream &operator>>(unsigned long int &) = delete; otl_stream &operator<<(const unsigned long int) = delete; #endif private: #else otl_stream &operator=(const otl_stream &) { return *this; } otl_stream(const otl_stream &) : #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) otl_read_stream_interface(), #endif shell(nullptr), shell_pt(), connected(0), ref_ss(nullptr), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr), next_ov_ndx(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0), last_oper_was_read_op(false), override_(nullptr), buf_size_(0) { } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_stream &operator=(otl_stream &&) { return *this; } otl_stream(otl_stream &&) : #if defined(OTL_ORA_DECLARE_COMMON_READ_STREAM_INTERFACE) otl_read_stream_interface(), #endif shell(nullptr), shell_pt(), connected(0), ref_ss(nullptr), ss(nullptr), io(nullptr), adb(nullptr), auto_commit_flag(nullptr), iov(nullptr), iov_len(nullptr), next_iov_ndx(nullptr), ov(nullptr), ov_len(nullptr), next_ov_ndx(nullptr), end_marker(0), oper_int_called(0), last_eof_rc(0), last_oper_was_read_op(false), override_(nullptr), buf_size_(0) { } #endif #if !defined(OTL_STREAM_NO_PRIVATE_BOOL_OPERATORS) otl_stream &operator>>(bool &) OTL_NO_THROW { return *this; } otl_stream &operator<<(const bool) OTL_NO_THROW { return *this; } #endif #if !defined(OTL_STREAM_NO_PRIVATE_UNSIGNED_LONG_OPERATORS) otl_stream &operator>>(unsigned long int &) OTL_NO_THROW { return *this; } otl_stream &operator<<(const unsigned long int) OTL_NO_THROW { return *this; } #endif #endif }; #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) inline bool operator!=(const otl_for_range_loop_ora_stream_adapter& a1, const otl_for_range_loop_ora_stream_adapter& /*a2*/){ return a1.str_!=nullptr && !a1.str_->eof(); } #endif #if defined(OTL_ORA_SUBSCRIBE) #if !defined(OTL_ORA_OCI_ENV_CREATE) #error OTL_ORA_SUBSCRIBE requires #define OTL_ORA_OCI_ENV_CREATE to be enabled #endif #if !defined(OTL_ORA_OCI_ENV_CREATE_MODE) #error OTL_ORA_SUBSCRIBE requires #define OTL_ORA_OCI_ENV_CREATE_MODE to be \ enabled and to have OCI_THREADED|OCI_OBJECT|OCI_EVENTS #endif class otl_subscriber { public: otl_subscriber(otl_connect *adb = nullptr) : db(adb), subscrhp(nullptr) {} virtual ~otl_subscriber(void) OTL_THROWS_OTL_EXCEPTION4 { unsubscribe(); } void subscribe(const char *name = nullptr, int port = 0, int timeout = 1800 #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) , const char *ipaddr = nullptr) #else ) #endif { if (subscrhp) unsubscribe(); if (!db || (db && !db->connected)) OTL_THROW((otl_exception(otl_error_msg_32, otl_error_code_32))); OCIEnv *envhp = db->get_connect_struct().get_envhp(); OCIError *errhp = db->get_connect_struct().get_errhp(); OCISvcCtx *svchp = db->get_connect_struct().get_svchp(); if (port) check(OCIAttrSet(OTL_RCAST(dvoid *, envhp), OTL_SCAST(ub4, OCI_HTYPE_ENV), OTL_RCAST(dvoid *, &port), 0, OCI_ATTR_SUBSCR_PORTNO, errhp)); #if defined(OTL_ORA11G_R2) || defined(OTL_ORA12C) if (ipaddr) check(OCIAttrSet(OTL_RCAST(dvoid *, envhp), OTL_SCAST(ub4, OCI_HTYPE_ENV), OTL_RCAST(dvoid *, OTL_CCAST(char *, ipaddr)), OTL_SCAST(ub4, strlen(ipaddr)), OCI_ATTR_SUBSCR_IPADDR, errhp)); #endif OCISubscription **temp_subscrhp = &subscrhp; check(OCIHandleAlloc( OTL_RCAST(dvoid *, envhp), OTL_RCAST(dvoid **, temp_subscrhp), OCI_HTYPE_SUBSCRIPTION, OTL_SCAST(size_t, 0), nullptr)); if (name && *name) check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION, OTL_RCAST(void *, OTL_CCAST(char *, name)), OTL_SCAST(ub4, strlen(name)), OCI_ATTR_SUBSCR_NAME, errhp)); ub4 nspace = OCI_SUBSCR_NAMESPACE_DBCHANGE; check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION, OTL_RCAST(dvoid *, &nspace), sizeof(ub4), OCI_ATTR_SUBSCR_NAMESPACE, errhp)); check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION, #if defined(__GNUC__) && (__GNUC__ < 4) (void *)common_notification_callback, #else OTL_RCAST(void *, common_notification_callback), #endif 0, OCI_ATTR_SUBSCR_CALLBACK, errhp)); int rowids_needed = 1; check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION, OTL_RCAST(dvoid *, &rowids_needed), sizeof(ub4), OCI_ATTR_CHNF_ROWIDS, errhp)); check(OCIAttrSet(subscrhp, OTL_SCAST(ub4, OCI_HTYPE_SUBSCRIPTION), OTL_RCAST(dvoid *, this), 0, OCI_ATTR_SUBSCR_CTX, errhp)); if (timeout) check(OCIAttrSet(subscrhp, OCI_HTYPE_SUBSCRIPTION, OTL_RCAST(dvoid *, &timeout), 0, OCI_ATTR_SUBSCR_TIMEOUT, errhp)); check(OCISubscriptionRegister(svchp, &subscrhp, 1, errhp, OCI_DEFAULT)); } void unsubscribe(void) { if (!subscrhp) return; if (!db || (db && !db->connected)) OTL_THROW((otl_exception(otl_error_msg_32, otl_error_code_32))); OCIError *errhp = db->get_connect_struct().get_errhp(); OCISvcCtx *svchp = db->get_connect_struct().get_svchp(); OCISubscriptionUnRegister(svchp, subscrhp, errhp, OCI_DEFAULT); OCIHandleFree(OTL_RCAST(dvoid *, subscrhp), OCI_HTYPE_SUBSCRIPTION); subscrhp = nullptr; } void associate_table(const char *table_name) { if (!db || (db && !db->connected)) OTL_THROW((otl_exception(otl_error_msg_32, otl_error_code_32))); char sql_stmt[1024]; OTL_STRCPY_S(sql_stmt, sizeof(sql_stmt), "select :i from "); OTL_STRCAT_S(sql_stmt, sizeof(sql_stmt)-strlen(sql_stmt)-1, table_name); int arg = 0; otl_stream s(1, sql_stmt, *db); if (!s.get_shell() || !s.get_shell()->ss) OTL_THROW((otl_exception(db->get_connect_struct(), sql_stmt))); OCIError *errhp = db->get_connect_struct().get_errhp(); OCIStmt *stmthp = s.get_shell()->ss->get_cursor_struct().cda; check(OCIAttrSet(stmthp, OCI_HTYPE_STMT, subscrhp, 0, OCI_ATTR_CHNF_REGHANDLE, errhp)); s << arg; } void associate_query(const char *stmt) { if (!db || (db && !db->connected)) OTL_THROW((otl_exception(otl_error_msg_32, otl_error_code_32))); otl_stream s(1, stmt, *db); if (!s.get_shell() || !s.get_shell()->ss) OTL_THROW((otl_exception(db->get_connect_struct(), stmt))); OCIError *errhp = db->get_connect_struct().get_errhp(); OCIStmt *stmthp = s.get_shell()->ss->get_cursor_struct().cda; check(OCIAttrSet(stmthp, OCI_HTYPE_STMT, subscrhp, 0, OCI_ATTR_CHNF_REGHANDLE, errhp)); s << 0; } protected: void check(int ret_code) { if (ret_code != OCI_SUCCESS) OTL_THROW((otl_exception(db->get_connect_struct()))); } virtual void OnException(OTL_CONST_EXCEPTION otl_exception &e) = 0; virtual void OnDeRegistration(void) = 0; //--- DB events: virtual void OnStartup(void) = 0; virtual void OnInstanceShutdown(void) = 0; virtual void OnAnyInstanceShutdown(void) = 0; //--- Table events: virtual void OnTableInvalidate(text *table_name) = 0; virtual void OnTableAlter(text *table_name, bool all_rows = false) = 0; virtual void OnTableDrop(text *table_name, bool all_rows = false) = 0; virtual void OnTableChange(text *table_name, bool all_rows = false) = 0; //--- Row events: virtual void OnRowInsert(text *table_name, text *row_id) = 0; virtual void OnRowUpdate(text *table_name, text *row_id) = 0; virtual void OnRowDelete(text *table_name, text *row_id) = 0; protected: otl_connect *db; private: OCISubscription *subscrhp; void notification_callback(dvoid * /*payload*/, ub4 /*paylen*/, dvoid *desc, ub4 /*mode*/) { if (!db || (db && !db->connected)) return; ub4 num_rows = 0; OCIColl *row_changes = nullptr; dvoid *row_desc, **row_descp; dvoid ***temp_row_descp = &row_descp; text *row_id; ub4 rowid_size; ub4 row_op; unsigned int j; try { OCIEnv *envhp = db->get_connect_struct().get_envhp(); OCIError *errhp = db->get_connect_struct().get_errhp(); //---------------- ub4 notify_type; check(OCIAttrGet(desc, OCI_DTYPE_CHDES, ¬ify_type, nullptr, OCI_ATTR_CHDES_NFYTYPE, errhp)); switch (notify_type) { case OCI_EVENT_STARTUP: OnStartup(); return; case OCI_EVENT_SHUTDOWN: OnInstanceShutdown(); return; case OCI_EVENT_SHUTDOWN_ANY: OnAnyInstanceShutdown(); return; case OCI_EVENT_DEREG: OnDeRegistration(); return; case OCI_EVENT_OBJCHANGE: break; default: return; } OCIColl *table_changes = nullptr; check(OCIAttrGet(desc, OCI_DTYPE_CHDES, &table_changes, nullptr, OCI_ATTR_CHDES_TABLE_CHANGES, errhp)); if (!table_changes) return; ub4 num_tables = 0; check(OCICollSize(envhp, errhp, OTL_RCAST(CONST OCIColl *, table_changes), OTL_RCAST(sb4 *, &num_tables))); if (!num_tables) return; for (unsigned int i = 0; i < num_tables; i++) { int exist; dvoid *elemind = nullptr, *table_desc, **table_descp; dvoid ***temp_table_descp = &table_descp; check(OCICollGetElem(envhp, errhp, table_changes, OTL_SCAST(sb4, i), &exist, OTL_RCAST(dvoid **, temp_table_descp), &elemind)); table_desc = *table_descp; text *table_name; check(OCIAttrGet(table_desc, OCI_DTYPE_TABLE_CHDES, &table_name, nullptr, OCI_ATTR_CHDES_TABLE_NAME, errhp)); ub4 table_op; check(OCIAttrGet(table_desc, OCI_DTYPE_TABLE_CHDES, OTL_RCAST(dvoid *, &table_op), nullptr, OCI_ATTR_CHDES_TABLE_OPFLAGS, errhp)); bool all_rows = table_op & OCI_OPCODE_ALLROWS; switch (table_op) { case OCI_OPCODE_ALLROWS: OnTableInvalidate(table_name); continue; case OCI_OPCODE_ALTER: case(OCI_OPCODE_ALTER + OCI_OPCODE_ALLROWS) : OnTableAlter(table_name, all_rows); continue; case OCI_OPCODE_DROP: case(OCI_OPCODE_DROP + OCI_OPCODE_ALLROWS) : OnTableDrop(table_name, all_rows); continue; case(OCI_OPCODE_INSERT + OCI_OPCODE_ALLROWS) : case(OCI_OPCODE_UPDATE + OCI_OPCODE_ALLROWS) : case(OCI_OPCODE_DELETE + OCI_OPCODE_ALLROWS) : case(OCI_OPCODE_INSERT + OCI_OPCODE_UPDATE + OCI_OPCODE_ALLROWS) : case(OCI_OPCODE_INSERT + OCI_OPCODE_DELETE + OCI_OPCODE_ALLROWS) : case(OCI_OPCODE_UPDATE + OCI_OPCODE_DELETE + OCI_OPCODE_ALLROWS) : case(OCI_OPCODE_INSERT + OCI_OPCODE_UPDATE + OCI_OPCODE_DELETE + OCI_OPCODE_ALLROWS) : case(OCI_OPCODE_UNKNOWN + OCI_OPCODE_ALLROWS) : OnTableChange(table_name, all_rows); continue; case OCI_OPCODE_INSERT: case OCI_OPCODE_UPDATE: case OCI_OPCODE_DELETE: OnTableChange(table_name, all_rows); break; } row_changes = nullptr; check(OCIAttrGet(table_desc, OCI_DTYPE_TABLE_CHDES, &row_changes, nullptr, OCI_ATTR_CHDES_TABLE_ROW_CHANGES, errhp)); if (!row_changes) continue; num_rows = 0; check(OCICollSize(envhp, errhp, row_changes, OTL_RCAST(sb4 *, &num_rows))); for (j = 0; j < num_rows; j++) { elemind = nullptr; check(OCICollGetElem(envhp, errhp, row_changes, OTL_SCAST(sb4, j), &exist, OTL_RCAST(dvoid **, temp_row_descp), &elemind)); row_desc = *row_descp; check(OCIAttrGet(row_desc, OCI_DTYPE_ROW_CHDES, OTL_RCAST(dvoid *, &row_id), &rowid_size, OCI_ATTR_CHDES_ROW_ROWID, errhp)); check(OCIAttrGet(row_desc, OCI_DTYPE_ROW_CHDES, OTL_RCAST(dvoid *, &row_op), nullptr, OCI_ATTR_CHDES_ROW_OPFLAGS, errhp)); if (row_op == OCI_OPCODE_INSERT) OnRowInsert(table_name, row_id); else if (row_op == OCI_OPCODE_DELETE) OnRowDelete(table_name, row_id); else if (row_op == OCI_OPCODE_UPDATE) OnRowUpdate(table_name, row_id); } } } catch (OTL_CONST_EXCEPTION otl_exception &e) { OnException(e); } } static void common_notification_callback(dvoid *ctx, OCISubscription * /*subscrhp*/, dvoid *payload, ub4 paylen, dvoid *desc, ub4 mode) { if (!ctx) return; (OTL_RCAST(otl_subscriber *, ctx)) ->notification_callback(payload, paylen, desc, mode); } public: OTL_NODISCARD bool is_online(void) { return subscrhp != nullptr; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_subscriber(const otl_subscriber &) = delete; otl_subscriber &operator=(const otl_subscriber &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_subscriber(otl_subscriber &&) = delete; otl_subscriber &operator=(otl_subscriber &&) = delete; #endif private: #else otl_subscriber(const otl_subscriber &) : db(nullptr), subscrhp(nullptr) {} otl_subscriber &operator=(const otl_subscriber &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_subscriber(otl_subscriber &&) : db(nullptr), subscrhp(nullptr) {} otl_subscriber &operator=(otl_subscriber &&) { return *this; } #endif #endif }; #endif inline otl_connect &operator>>(otl_connect &connect, otl_stream &s) { const char *cmd = connect.getCmd(); const char *invalid_cmd = "*** INVALID COMMAND ***"; if (!cmd) cmd = invalid_cmd; s.open(s.getBufSize(), cmd, connect); return connect; } #if (defined(OTL_STL) || defined(OTL_VALUE_TEMPLATE_ON)) && \ defined(OTL_VALUE_TEMPLATE) template inline otl_stream &operator<<(otl_stream &s, const otl_value &var) OTL_THROWS_OTL_EXCEPTION { if (var.is_null()) s << otl_null(); else s << var.v; return s; } template inline otl_stream &operator>>(otl_stream &s, otl_value &var) OTL_THROWS_OTL_EXCEPTION { s >> var.v; if(s.is_null()) var.set_null(true); else var.set_null(false); return s; } template inline otl_refcur_stream &operator>>(otl_refcur_stream &s, otl_value &var) OTL_THROWS_OTL_EXCEPTION { s >> var.v; if(s.is_null()) var.set_null(true); else var.set_null(false); return s; } template inline otl_stream &operator<< (otl_stream &s, const otl_compact_value &var) OTL_THROWS_OTL_EXCEPTION { if (var.is_null()) s << otl_null(); else s << var.v; return s; } template inline otl_stream &operator>> (otl_stream &s, otl_compact_value &var) OTL_THROWS_OTL_EXCEPTION { s >> var.v; if(s.is_null()) var.set_null(true); else var.set_null(false); return s; } template inline otl_refcur_stream &operator>> (otl_refcur_stream &s, otl_compact_value &var) OTL_THROWS_OTL_EXCEPTION { s >> var.v; if(s.is_null()) var.set_null(true); else var.set_null(false); return s; } #endif typedef otl_tmpl_nocommit_stream otl_nocommit_stream; inline otl_stream &endr(otl_stream &s) { s.check_end_of_row(); return s; } OTL_ORA8_NAMESPACE_END #ifndef OTL_STDC_DEFINED #undef __STDC__ #endif #endif #if defined(OTL_STL) && !defined(OTL_STLPORT) #define STL_INPUT_ITERATOR_TO_DERIVE_FROM #if defined (_MSC_VER) && defined(_HAS_TR1_NAMESPACE) && (_HAS_TR1_NAMESPACE==1) #define OTL_VC_TR1_NAMESPACE tr1:: #else #define OTL_VC_TR1_NAMESPACE #endif #if defined(_MSC_VER) && (_MSC_VER >= 1600) && defined(_SECURE_SCL) && \ (_SECURE_SCL == 1) && !defined(OTL_STLPORT) #define OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(namespace_name) \ _STD_BEGIN template \ struct _Is_checked_helper< \ namespace_name otl_output_iterator > : \ public _STD OTL_VC_TR1_NAMESPACE true_type {}; \ _STD_END #if defined(_MSC_VER) && (_MSC_VER >= 1911) // Visual Studio 2017 Update 3 or higher #define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM #else #define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM : public _STD _Outit #endif #else #define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM #define OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(namespace_name) #endif #elif defined(OTL_STLPORT) #define OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(namespace_name) #define STL_INPUT_ITERATOR_TO_DERIVE_FROM \ : public STD_NAMESPACE_PREFIX iterator \ #define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM \ : public STD_NAMESPACE_PREFIX iterator \ #endif #if defined(OTL_STL) || defined(OTL_STLPORT) #if defined(__GNUC__) && defined(__GNUC_MINOR__) && \ (__GNUC__ * 100 + __GNUC_MINOR__ >= 406) || \ (defined(__clang__) && __clang_major__ * 100 + __clang_minor__ >= 306) #define OTL_ITER_DISTANCE Distance = STD_NAMESPACE_PREFIX ptrdiff_t #else #define OTL_ITER_DISTANCE Distance = ptrdiff_t #endif #define OTL_ITERATORS \ template \ class otl_input_iterator STL_INPUT_ITERATOR_TO_DERIVE_FROM { \ public: \ typedef STD_NAMESPACE_PREFIX input_iterator_tag iterator_category; \ typedef T value_type; \ typedef Distance difference_type; \ typedef const T *pointer; \ typedef const T &reference; \ \ otl_stream *stream; \ T value; \ int end_marker; \ \ void read() { \ if (!stream) { \ end_marker = -1; \ return; \ } \ if (stream->eof()) { \ end_marker = -1; \ return; \ } \ end_marker = stream->eof(); \ if (!end_marker) \ *stream >> value; \ if (stream->eof()) \ end_marker = 1; \ } \ \ otl_input_iterator() : stream(nullptr), value(), end_marker(-1) {} \ otl_input_iterator(otl_stream &s) : stream(&s), value(), end_marker(0) { \ read(); \ } \ \ const T &operator*() const { return value; } \ \ otl_input_iterator &operator++() { \ read(); \ return *this; \ } \ \ otl_input_iterator operator++(int) { \ otl_input_iterator tmp = *this; \ read(); \ return tmp; \ } \ \ otl_input_iterator(const otl_input_iterator &src) \ : stream(src.stream), value(src.value), end_marker(src.end_marker) {} \ \ otl_input_iterator &operator=(const otl_input_iterator &src) { \ stream = src.stream; \ value = src.value; \ end_marker = src.end_marker; \ return *this; \ } \ }; \ template \ inline STD_NAMESPACE_PREFIX input_iterator_tag \ iterator_category(const otl_input_iterator &) { \ return STD_NAMESPACE_PREFIX input_iterator_tag(); \ } \ template \ inline T *value_type(const otl_input_iterator &) { \ return nullptr; \ } \ template \ inline Distance *distance_type(const otl_input_iterator &) { \ return nullptr; \ } \ template \ bool operator==(const otl_input_iterator &x, \ const otl_input_iterator &y) { \ return (x.stream == y.stream && x.end_marker == y.end_marker) || \ (x.end_marker == -1 && y.end_marker == -1); \ } \ template \ bool operator!=(const otl_input_iterator &x, \ const otl_input_iterator &y) { \ return !(x == y); \ } \ template \ class otl_output_iterator STL_OUTPUT_ITERATOR_TO_DERIVE_FROM { \ protected: \ otl_stream *stream; \ \ public: \ typedef STD_NAMESPACE_PREFIX output_iterator_tag iterator_category; \ typedef void value_type; \ typedef void difference_type; \ typedef void pointer; \ typedef void reference; \ \ otl_output_iterator(otl_stream &s) : stream(&s) {} \ otl_output_iterator &operator=(const T &value) { \ *stream << value; \ return *this; \ } \ otl_output_iterator &operator*() { return *this; } \ otl_output_iterator &operator++() { return *this; } \ otl_output_iterator operator++(int) { return *this; } \ }; #define OTL_ITERATOR_TAG(namespace_name) \ template \ inline STD_NAMESPACE_PREFIX output_iterator_tag \ iterator_category(const namespace_name otl_output_iterator &) { \ return STD_NAMESPACE_PREFIX output_iterator_tag(); \ } #if defined(OTL_ORA8) OTL_ORA8_NAMESPACE_BEGIN OTL_ITERATORS OTL_ORA8_NAMESPACE_END OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(OTL_ORA8_NAMESPACE_PREFIX) OTL_ITERATOR_TAG(OTL_ORA8_NAMESPACE_PREFIX) #endif #if defined(OTL_ODBC) OTL_ODBC_NAMESPACE_BEGIN OTL_ITERATORS OTL_ODBC_NAMESPACE_END OTL_VC10_STL_OUTPUT_ITERATOR_HELPER(OTL_ODBC_NAMESPACE_PREFIX) OTL_ITERATOR_TAG(OTL_ODBC_NAMESPACE_PREFIX) #endif #endif #if defined(OTL_STREAM_READ_ITERATOR_ON) #if defined(OTL_UNICODE) #error UNICODE is not supported when #define OTL_STREAM_READ_ITERATOR_ON is enabled #endif #if defined(OTL_STL) #include #endif #if defined(OTL_ACE) #include #include #include #include #include #endif #if defined(OTL_STL) || defined(OTL_ACE) class otl_ltcharstar { public: #if defined(OTL_STL) bool #else int #endif operator()(const char *s1, const char *s2) const { #if defined(__BORLANDC__) || (defined(_MSC_VER) && !defined(__clang__)) return stricmp(s1, s2) < 0; #elif (defined(_MSC_VER) && defined(__clang__)) return _stricmp(s1, s2) < 0; #else #if defined(__STRICT_ANSI__) while (otl_to_upper(*s1) == otl_to_upper(*s2) && *s1) { ++s1; ++s2; } return *s1 < *s2; #else return strcasecmp(s1, s2) < 0; #endif #endif } }; #endif #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) template class otl_stream_read_iterator; template class otl_for_range_loop_adapter{ public: typedef otl_stream_read_iterator read_iter_type; otl_for_range_loop_adapter(read_iter_type& iter):iter_(&iter){} otl_for_range_loop_adapter():iter_(nullptr) {} bool operator!=(const otl_for_range_loop_adapter& /*that*/){ return iter_!=nullptr && !iter_->get_last_eof(); } read_iter_type& operator*(){ return *iter_; } otl_for_range_loop_adapter& operator++(){ (void)iter_->next_row(); return *this; } private: read_iter_type* iter_; }; #endif template class otl_stream_read_iterator { public: #if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT) typedef otl_for_range_loop_adapter FRL_type; OTL_NODISCARD FRL_type begin(){ (void)next_row(); if(!last_eof_) return FRL_type(*this); else return FRL_type(); } OTL_NODISCARD FRL_type end(){ return FRL_type(); } #endif otl_stream_read_iterator(OTLStream &s) { set(); attach(s); } otl_stream_read_iterator() : out_vars_(nullptr), out_vars_len_(0), str_(nullptr), out_vars_arr_(nullptr), out_vars_null_arr_(nullptr), out_vars_constructed_(false), lob_stream_mode_flag_(false), last_eof_(false) #if defined(OTL_STL) , var_name2pos_map_() #endif #if defined(OTL_ACE) , var_name2pos_map_() #endif { set(); } ~otl_stream_read_iterator() OTL_THROWS_OTL_EXCEPTION { reset(); } void attach(OTLStream &s) { reset(); str_ = &s; if (!str_->good()) { str_ = nullptr; OTL_THROW((OTLException(otl_error_msg_19, otl_error_code_19))); } out_vars_ = str_->describe_out_vars(out_vars_len_); if (!out_vars_) { OTL_THROW((OTLException(otl_error_msg_21, otl_error_code_21))); } lob_stream_mode_flag_ = str_->get_lob_stream_flag(); allocate_arrays(); } void reattach() { if (!str_->good()) { reset(); OTL_THROW((OTLException(otl_error_msg_19, otl_error_code_19))); } out_vars_ = str_->describe_out_vars(out_vars_len_); if (!out_vars_) { reset(); OTL_THROW((OTLException(otl_error_msg_21, otl_error_code_21))); } else { #if defined(OTL_STL) var_name2pos_map_.clear(); for (int i = 0; i < out_vars_len_; ++i) { const otl_var_desc &curr_var = out_vars_[i]; var_name2pos_map_[curr_var.name] = i; } #endif #if defined(OTL_ACE) var_name2pos_map_.close(); for (int i = 0; i < out_vars_len_; ++i) { const otl_var_desc &curr_var = out_vars_[i]; var_name2pos_map_.bind(curr_var.name, i); } #endif } lob_stream_mode_flag_ = str_->get_lob_stream_flag(); } void detach(void) { reset(); } OTL_NODISCARD const otl_var_desc *describe(int &var_desc_len) { var_desc_len = out_vars_len_; return out_vars_; } OTL_NODISCARD bool next_row(void) { if (str_->eof()){ last_eof_=true; return false; } for (int i = 0; i < out_vars_len_; ++i) { otl_var_desc &curr_var = out_vars_[i]; unsigned char *curr_ptr = out_vars_arr_[i]; switch (curr_var.ftype) { case otl_var_char: (*str_) >> OTL_RCAST(char *, curr_ptr); break; case otl_var_double: (*str_) >> *OTL_RCAST(double *, curr_ptr); break; case otl_var_float: (*str_) >> *OTL_RCAST(float *, curr_ptr); break; case otl_var_int: (*str_) >> *OTL_RCAST(int *, curr_ptr); break; case otl_var_unsigned_int: (*str_) >> *OTL_RCAST(unsigned *, curr_ptr); break; case otl_var_short: (*str_) >> *OTL_RCAST(short int *, curr_ptr); break; case otl_var_long_int: (*str_) >> *OTL_RCAST(long int *, curr_ptr); break; case otl_var_raw: (*str_) >> *OTL_RCAST(otl_long_string *, curr_ptr); break; case otl_var_timestamp: case otl_var_db2time: case otl_var_db2date: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: (*str_) >> *OTL_RCAST(otl_datetime *, curr_ptr); break; case otl_var_varchar_long: case otl_var_raw_long: case otl_var_clob: case otl_var_blob: if (lob_stream_mode_flag_) (*str_) >> *OTL_RCAST(OTLLobStream *, curr_ptr); else (*str_) >> *OTL_RCAST(otl_long_string *, curr_ptr); break; #if defined(OTL_BIGINT) case otl_var_bigint: (*str_) >> *OTL_RCAST(OTL_BIGINT *, curr_ptr); break; #endif #if defined(OTL_UBIGINT) case otl_var_ubigint: (*str_) >> *OTL_RCAST(OTL_UBIGINT *, curr_ptr); break; #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) case otl_var_numeric_type_1: (*str_) >> *OTL_RCAST(OTL_NUMERIC_TYPE_1 *, curr_ptr); break; #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) case otl_var_numeric_type_2: (*str_) >> *OTL_RCAST(OTL_NUMERIC_TYPE_2 *, curr_ptr); break; #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) case otl_var_numeric_type_3: (*str_) >> *OTL_RCAST(OTL_NUMERIC_TYPE_3 *, curr_ptr); break; #endif } out_vars_null_arr_[i] = str_->is_null() == 1; } last_eof_=false; return true; } void get(const int pos, OTLLobStream *&s) { check_pos(pos); check_type(pos, otl_var_long_string, true); if (!lob_stream_mode_flag_) { char var_info[255]; otl_var_info_var3(out_vars_[pos - 1].name, out_vars_[pos - 1].ftype, otl_var_lob_stream, var_info, sizeof(var_info)); OTL_THROW((OTLException(otl_error_msg_25, otl_error_code_25, str_->get_stm_text(), var_info))); } unsigned char *curr_ptr = out_vars_arr_[pos - 1]; s = OTL_RCAST(OTLLobStream *, curr_ptr); } #if defined(OTL_STL) void get(const char *var_name, OTLLobStream *&n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, OTLLobStream *&n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, char &c) { check_pos(pos); check_type(pos, otl_var_char); unsigned char *curr_ptr = out_vars_arr_[pos - 1]; c = OTL_SCAST(char, *curr_ptr); } #if defined(OTL_STL) void get(const char *var_name, char &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, char &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, unsigned char &c) { check_pos(pos); check_type(pos, otl_var_char); unsigned char *curr_ptr = out_vars_arr_[pos - 1]; c = *curr_ptr; } #if defined(OTL_STL) void get(const char *var_name, unsigned char &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, unsigned char &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, char *s) { check_pos(pos); check_type(pos, otl_var_char); unsigned char *curr_ptr = out_vars_arr_[pos - 1]; otl_strcpy(OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, curr_ptr)); } #if defined(OTL_STL) void get(const char *var_name, char *n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, char *n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, unsigned char *s) { check_pos(pos); check_type(pos, otl_var_char); unsigned char *curr_ptr = out_vars_arr_[pos - 1]; otl_strcpy(OTL_RCAST(unsigned char *, s), OTL_RCAST(const unsigned char *, curr_ptr)); } #if defined(OTL_STL) void get(const char *var_name, unsigned char *n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, unsigned char *n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, unsigned int &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; check_type(pos, otl_var_unsigned_int); } #if defined(OTL_STL) void get(const char *var_name, unsigned int &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, unsigned int &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, int &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; check_type(pos, otl_var_unsigned_int); } #if defined(OTL_STL) void get(const char *var_name, int &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, int &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, short int &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; check_type(pos, otl_var_short); } #if defined(OTL_STL) void get(const char *var_name, short int &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, short int &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, long int &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; check_type(pos, otl_var_long_int); } #if defined(OTL_STL) void get(const char *var_name, long int &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, long int &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, float &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; check_type(pos, otl_var_double); } #if defined(OTL_STL) void get(const char *var_name, float &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, float &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, double &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; check_type(pos, otl_var_double); } #if defined(OTL_STL) void get(const char *var_name, double &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, double &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) void get(const int pos, OTL_NUMERIC_TYPE_1 &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; #if defined(OTL_STR_TO_NUMERIC_TYPE_1) && defined(OTL_NUMERIC_TYPE_1_TO_STR) if (out_vars_[pos - 1].ftype == otl_var_char) { char *temp_val = OTL_RCAST(char *, curr_ptr); #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (is_null(pos)) { n = OTL_SCAST(OTL_NUMERIC_TYPE_1, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); return; } #endif OTL_STR_TO_NUMERIC_TYPE_1(temp_val, n); return; } check_type(pos, otl_var_numeric_type_1); #else check_type(pos, otl_var_numeric_type_1); #endif } #if defined(OTL_STL) void get(const char *var_name, OTL_NUMERIC_TYPE_1 &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, OTL_NUMERIC_TYPE_1 &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) void get(const int pos, OTL_NUMERIC_TYPE_2 &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; #if defined(OTL_STR_TO_NUMERIC_TYPE_2) && defined(OTL_NUMERIC_TYPE_2_TO_STR) if (out_vars_[pos - 1].ftype == otl_var_char) { char *temp_val = OTL_RCAST(char *, curr_ptr); #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (is_null(pos)) { n = OTL_SCAST(OTL_NUMERIC_TYPE_2, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); return; } #endif OTL_STR_TO_NUMERIC_TYPE_2(temp_val, n); return; } check_type(pos, otl_var_numeric_type_2); #else check_type(pos, otl_var_numeric_type_2); #endif } #if defined(OTL_STL) void get(const char *var_name, OTL_NUMERIC_TYPE_2 &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, OTL_NUMERIC_TYPE_2 &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) void get(const int pos, OTL_NUMERIC_TYPE_3 &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; #if defined(OTL_STR_TO_NUMERIC_TYPE_3) && defined(OTL_NUMERIC_TYPE_3_TO_STR) if (out_vars_[pos - 1].ftype == otl_var_char) { char *temp_val = OTL_RCAST(char *, curr_ptr); #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (is_null(pos)) { n = OTL_SCAST(OTL_NUMERIC_TYPE_3, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); return; } #endif OTL_STR_TO_NUMERIC_TYPE_3(temp_val, n); return; } check_type(pos, otl_var_numeric_type_3); #else check_type(pos, otl_var_numeric_type_3); #endif } #if defined(OTL_STL) void get(const char *var_name, OTL_NUMERIC_TYPE_3 &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, OTL_NUMERIC_TYPE_3 &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif #endif #if defined(OTL_BIGINT) void get(const int pos, OTL_BIGINT &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; #if defined(OTL_STR_TO_BIGINT) && defined(OTL_BIGINT_TO_STR) if (out_vars_[pos - 1].ftype == otl_var_char) { char *temp_val = OTL_RCAST(char *, curr_ptr); #if defined(OTL_DEFAULT_NUMERIC_NULL_TO_VAL) if (is_null(pos)) { n = OTL_SCAST(OTL_BIGINT, OTL_DEFAULT_NUMERIC_NULL_TO_VAL); return; } #endif OTL_STR_TO_BIGINT(temp_val, n); return; } check_type(pos, otl_var_bigint); #else check_type(pos, otl_var_bigint); #endif } #if defined(OTL_STL) void get(const char *var_name, OTL_BIGINT &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, OTL_BIGINT &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif #endif #if defined(OTL_UBIGINT) void get(const int pos, OTL_UBIGINT &n) { check_pos(pos); void *curr_ptr = out_vars_arr_[pos - 1]; #if defined(OTL_STRICT_NUMERIC_TYPE_CHECK_ON_SELECT) int match_found = otl_numeric_convert_T( out_vars_[pos - 1].ftype, curr_ptr, n); #else int match_found = otl_numeric_convert_T(out_vars_[pos - 1].ftype, curr_ptr, n); #endif if (match_found) return; check_type(pos, otl_var_ubigint); } #if defined(OTL_STL) void get(const char *var_name, OTL_UBIGINT &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, OTL_UBIGINT &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif #endif OTL_NODISCARD bool is_null(const int pos) { check_pos(pos); return out_vars_null_arr_[pos - 1]; } #if defined(OTL_STL) OTL_NODISCARD bool is_null(const char *var_name) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); return is_null((*it).second + 1); } #endif #if defined(OTL_ACE) OTL_NODISCARD bool is_null(const char *var_name) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); return is_null(it->item() + 1); } #endif #if defined(OTL_STL) || defined(USER_DEFINED_STRING_CLASS) void get(const int pos, OTL_STRING_CONTAINER &s) { check_pos(pos); otl_var_desc &curr_var = out_vars_[pos - 1]; unsigned char *curr_ptr = out_vars_arr_[pos - 1]; switch (curr_var.ftype) { case otl_var_varchar_long: case otl_var_raw_long: case otl_var_clob: case otl_var_blob: { otl_long_string *ls = OTL_RCAST(otl_long_string *, curr_ptr); int len = ls->len(); #if defined(OTL_STL) && !defined(USER_DEFINED_STRING_CLASS) s.assign(OTL_RCAST(char *, ls->v), OTL_SCAST(size_t, len)); #else s.assign(OTL_RCAST(char *, ls->v), len); #endif } break; case otl_var_char: s = OTL_RCAST(char *, curr_ptr); break; default: { char var_info[255]; otl_var_info_var3(out_vars_[pos - 1].name, out_vars_[pos - 1].ftype, otl_var_char, var_info, sizeof(var_info)); OTL_THROW((OTLException(otl_error_msg_23, otl_error_code_23, str_->get_stm_text(), var_info))); } } } #endif #if defined(OTL_STL) void get(const char *var_name, OTL_STRING_CONTAINER &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, OTL_STRING_CONTAINER &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, otl_long_string &s) { check_pos(pos); check_type(pos, otl_var_long_string); unsigned char *curr_ptr = out_vars_arr_[pos - 1]; s = *OTL_RCAST(otl_long_string *, curr_ptr); } #if defined(OTL_STL) void get(const char *var_name, otl_long_string &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, otl_long_string &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, otl_long_string *&s) { check_pos(pos); check_type(pos, otl_var_long_string); unsigned char *curr_ptr = out_vars_arr_[pos - 1]; s = OTL_RCAST(otl_long_string *, curr_ptr); } #if defined(OTL_STL) void get(const char *var_name, otl_long_string *&n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, otl_long_string *&n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif void get(const int pos, otl_datetime &s) { check_pos(pos); check_type(pos, otl_var_timestamp); unsigned char *curr_ptr = out_vars_arr_[pos - 1]; s = *OTL_RCAST(otl_datetime *, curr_ptr); } #if defined(OTL_STL) void get(const char *var_name, otl_datetime &n) { var_name2pos_map_type::iterator it = var_name2pos_map_.find(var_name); check_name(it, var_name); get((*it).second + 1, n); } #endif #if defined(OTL_ACE) void get(const char *var_name, otl_datetime &n) { var_name2pos_map_type::ENTRY *it = nullptr; var_name2pos_map_.find(var_name, it); check_name(it, var_name); get(it->item() + 1, n); } #endif OTL_NODISCARD bool get_last_eof(){ return last_eof_; } protected: otl_var_desc *out_vars_; int out_vars_len_; OTLStream *str_; unsigned char **out_vars_arr_; bool *out_vars_null_arr_; bool out_vars_constructed_; bool lob_stream_mode_flag_; bool last_eof_; #if defined(OTL_STL) typedef STD_NAMESPACE_PREFIX map var_name2pos_map_type; var_name2pos_map_type var_name2pos_map_; #endif #if defined(OTL_ACE) typedef ACE_RB_Tree var_name2pos_map_type; var_name2pos_map_type var_name2pos_map_; #endif void check_pos(const int pos) { int actual_pos = pos - 1; if (actual_pos < 0 || actual_pos > out_vars_len_ - 1) { OTL_THROW((OTLException(otl_error_msg_22, otl_error_code_22, str_->get_stm_text()))); } } #if defined(OTL_STL) void check_name(var_name2pos_map_type::iterator &it, const char *var_name) { if (it == var_name2pos_map_.end()) OTL_THROW((OTLException(otl_error_msg_26, otl_error_code_26, str_->get_stm_text(), var_name))); } #endif #if defined(OTL_ACE) void check_name(var_name2pos_map_type::ENTRY *it, const char *var_name) { if (!it) { OTL_THROW((OTLException(otl_error_msg_26, otl_error_code_26, str_->get_stm_text(), var_name))); } } #endif void check_type(const int pos, const int type_code, const bool lob_stream_arg = false) { switch (out_vars_[pos - 1].ftype) { case otl_var_timestamp: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: if (type_code == otl_var_timestamp) return; break; case otl_var_varchar_long: case otl_var_raw_long: case otl_var_clob: case otl_var_blob: if (type_code == otl_var_long_string) return; break; case otl_var_raw: if (type_code == otl_var_long_string && lob_stream_mode_flag_ && lob_stream_arg) { char var_info1[255]; otl_var_info_var4(out_vars_[pos - 1].name, out_vars_[pos - 1].ftype, otl_var_lob_stream, var_info1, sizeof(var_info1)); OTL_THROW((OTLException(otl_error_msg_28, otl_error_code_28, str_->get_stm_text(), var_info1))); } else return; default: if (out_vars_[pos - 1].ftype == type_code) return; break; } char var_info2[255]; otl_var_info_var3(out_vars_[pos - 1].name, out_vars_[pos - 1].ftype, type_code, var_info2, sizeof(var_info2)); OTL_THROW((OTLException(otl_error_msg_23, otl_error_code_23, str_->get_stm_text(), var_info2))); } void set(void) { out_vars_ = nullptr; out_vars_len_ = 0; str_ = nullptr; out_vars_arr_ = nullptr; out_vars_null_arr_ = nullptr; out_vars_constructed_ = false; lob_stream_mode_flag_ = false; } void reset(void) { if (out_vars_constructed_) { for (int i = 0; i < out_vars_len_; ++i) { switch (out_vars_[i].ftype) { case otl_var_char: delete[] OTL_RCAST(char *, out_vars_arr_[i]); break; case otl_var_double: delete OTL_RCAST(double *, out_vars_arr_[i]); break; case otl_var_float: delete OTL_RCAST(float *, out_vars_arr_[i]); break; case otl_var_int: delete OTL_RCAST(int *, out_vars_arr_[i]); break; case otl_var_unsigned_int: delete OTL_RCAST(unsigned *, out_vars_arr_[i]); break; case otl_var_short: delete OTL_RCAST(short int *, out_vars_arr_[i]); break; case otl_var_long_int: delete OTL_RCAST(long int *, out_vars_arr_[i]); break; #if defined(OTL_BIGINT) case otl_var_bigint: delete OTL_RCAST(OTL_BIGINT *, out_vars_arr_[i]); break; #endif #if defined(OTL_UBIGINT) case otl_var_ubigint: delete OTL_RCAST(OTL_UBIGINT *, out_vars_arr_[i]); break; #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) case otl_var_numeric_type_1: delete OTL_RCAST(OTL_NUMERIC_TYPE_1 *, out_vars_arr_[i]); break; #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) case otl_var_numeric_type_2: delete OTL_RCAST(OTL_NUMERIC_TYPE_2 *, out_vars_arr_[i]); break; #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) case otl_var_numeric_type_3: delete OTL_RCAST(OTL_NUMERIC_TYPE_3 *, out_vars_arr_[i]); break; #endif case otl_var_raw: delete OTL_RCAST(otl_long_string *, out_vars_arr_[i]); break; case otl_var_varchar_long: case otl_var_raw_long: case otl_var_clob: case otl_var_blob: if (lob_stream_mode_flag_) delete OTL_RCAST(OTLLobStream *, out_vars_arr_[i]); else delete OTL_RCAST(otl_long_string *, out_vars_arr_[i]); break; case otl_var_timestamp: delete OTL_RCAST(otl_datetime *, out_vars_arr_[i]); break; default: break; } out_vars_arr_[i] = nullptr; } out_vars_constructed_ = false; } delete[] out_vars_arr_; delete[] out_vars_null_arr_; #if defined(OTL_STL) || defined(OTL_ACE) var_name2pos_map_.clear(); #endif set(); } OTL_NODISCARD int calculate_buffer_size(const otl_var_desc *var, const int vars_len) { for (int i = 0; i < vars_len; ++i) { const otl_var_desc &curr_var = var[i]; if (curr_var.ftype == otl_var_refcur || curr_var.pl_tab_flag) OTL_THROW((OTLException(otl_error_msg_20, otl_error_code_20))); } return vars_len; } void allocate_arrays(void) { if (out_vars_) { out_vars_null_arr_ = new bool[OTL_SCAST(size_t,out_vars_len_)]; int buf_size = calculate_buffer_size(out_vars_, out_vars_len_); out_vars_arr_ = new unsigned char *[OTL_SCAST(size_t,buf_size)]; construct_elements(); } } void construct_elements(void) { for (int i = 0; i < out_vars_len_; ++i) { out_vars_null_arr_[i] = true; const otl_var_desc &curr_var = out_vars_[i]; switch (curr_var.ftype) { case otl_var_char: { char *ptr = new char[OTL_SCAST(size_t,curr_var.elem_size)]; *ptr = 0; out_vars_arr_[i] = OTL_RCAST(unsigned char *, ptr); } break; case otl_var_raw: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new otl_long_string(curr_var.elem_size)); break; case otl_var_double: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new double(0)); break; case otl_var_float: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new float(0)); break; case otl_var_int: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new int(0)); break; case otl_var_unsigned_int: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new unsigned(0)); break; case otl_var_short: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new short(0)); break; case otl_var_long_int: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new long(0)); break; case otl_var_timestamp: case otl_var_db2time: case otl_var_db2date: case otl_var_tz_timestamp: case otl_var_ltz_timestamp: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new otl_datetime); break; case otl_var_varchar_long: case otl_var_raw_long: case otl_var_clob: case otl_var_blob: if (lob_stream_mode_flag_) out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTLLobStream()); else out_vars_arr_[i] = OTL_RCAST(unsigned char *, new otl_long_string(str_->get_adb_max_long_size())); break; #if defined(OTL_BIGINT) case otl_var_bigint: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTL_BIGINT(0)); break; #endif #if defined(OTL_UBIGINT) case otl_var_ubigint: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTL_UBIGINT(0)); break; #endif #if defined(OTL_NUMERIC_TYPE_1) && defined(OTL_STR_TO_NUMERIC_TYPE_1) && \ defined(OTL_NUMERIC_TYPE_1_TO_STR) && defined(OTL_NUMERIC_TYPE_1_ID) case otl_var_numeric_type_1: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTL_NUMERIC_TYPE_1(0)); break; #endif #if defined(OTL_NUMERIC_TYPE_2) && defined(OTL_STR_TO_NUMERIC_TYPE_2) && \ defined(OTL_NUMERIC_TYPE_2_TO_STR) && defined(OTL_NUMERIC_TYPE_2_ID) case otl_var_numeric_type_2: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTL_NUMERIC_TYPE_2(0)); break; #endif #if defined(OTL_NUMERIC_TYPE_3) && defined(OTL_STR_TO_NUMERIC_TYPE_3) && \ defined(OTL_NUMERIC_TYPE_3_TO_STR) && defined(OTL_NUMERIC_TYPE_3_ID) case otl_var_numeric_type_3: out_vars_arr_[i] = OTL_RCAST(unsigned char *, new OTL_NUMERIC_TYPE_3(0)); break; #endif } #if defined(OTL_STL) var_name2pos_map_[curr_var.name] = i; #endif #if defined(OTL_ACE) var_name2pos_map_.bind(curr_var.name, i); #endif } out_vars_constructed_ = true; } private: #if defined(OTL_ANSI_CPP_11_DELETE_SPEC_SUPPORT) public: otl_stream_read_iterator(const otl_stream_read_iterator &) = delete; otl_stream_read_iterator &operator=(const otl_stream_read_iterator &) = delete; #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_stream_read_iterator(otl_stream_read_iterator &&) = delete; otl_stream_read_iterator &operator=(otl_stream_read_iterator &&) = delete; #endif private: #else otl_stream_read_iterator(const otl_stream_read_iterator &) : out_vars_(nullptr), out_vars_len_(0), str_(nullptr), out_vars_arr_(nullptr), out_vars_null_arr_(nullptr), out_vars_constructed_(nullptr), lob_stream_mode_flag_(false) #if defined(OTL_STL) , var_name2pos_map_() #endif #if defined(OTL_ACE) , var_name2pos_map_() #endif { } otl_stream_read_iterator &operator=(const otl_stream_read_iterator &) { return *this; } #if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT otl_stream_read_iterator(otl_stream_read_iterator &&) : out_vars_(nullptr), out_vars_len_(0), str_(nullptr), out_vars_arr_(nullptr), out_vars_null_arr_(nullptr), out_vars_constructed_(false), lob_stream_mode_flag_(false) #if defined(OTL_STL) , var_name2pos_map_() #endif #if defined(OTL_ACE) , var_name2pos_map_() #endif { } otl_stream_read_iterator &operator=(otl_stream_read_iterator &&) { return *this; } #endif #endif }; #endif template inline void otl_read_from_stream (OTLStreamType &s, OutputIterator result, size_t max_number_of_rows_to_read=0) OTL_THROWS_OTL_EXCEPTION { typename OutputIterator::container_type::value_type v; if(max_number_of_rows_to_read == 0){ while (!s.eof()) { s >> v; #if defined(OTL_CPP_11_ON) *result++ = std::move(v); #else *result++ = v; #endif } }else{ size_t rpc=0; while (!s.eof()) { s >> v; ++rpc; if(rpc > max_number_of_rows_to_read) return; #if defined(OTL_CPP_11_ON) *result++ = std::move(v); #else *result++ = v; #endif } } } template inline void otl_write_to_stream(InputIterator first, InputIterator last, OTLStreamType &s) OTL_THROWS_OTL_EXCEPTION { while (first != last) { s << (*first++); } } #if defined(OTL_ANSI_CPP_11_VARIADIC_TEMPLATES) #if defined(OTL_ANSI_CPP_17_FOLD_EXPRESSIONS) && defined(OTL_ANSI_CPP_17_CONSTEXPR_IF) template inline void otl_read_row(OTLStreamType &s, Arg1& arg1, Args&...args) OTL_THROWS_OTL_EXCEPTION { s>>arg1; if constexpr(sizeof...(args)>0) (s>>...>>args); s.check_end_of_row(); } template inline void otl_write_row(OTLStreamType &s, Arg1&& arg1, Args&&...args) OTL_THROWS_OTL_EXCEPTION { s<(arg1); if constexpr(sizeof...(args)>0) (s<<...<(args)); s.check_end_of_row(); } #else template inline void __otl_read_row(OTLStreamType &s) OTL_THROWS_OTL_EXCEPTION { s.check_end_of_row(); } template inline void __otl_read_row(OTLStreamType &s, Arg1 &arg1, Args &... args) OTL_THROWS_OTL_EXCEPTION { s >> arg1; __otl_read_row(s, args...); } template inline void otl_read_row(OTLStreamType &s, Arg1 &arg1, Args &... args) OTL_THROWS_OTL_EXCEPTION { s >> arg1; __otl_read_row(s, args...); } template inline void __otl_write_row(OTLStreamType &s) OTL_THROWS_OTL_EXCEPTION { s.check_end_of_row(); } template inline void __otl_write_row(OTLStreamType &s, Arg1 &&arg1, Args &&... args) OTL_THROWS_OTL_EXCEPTION { s << std::forward(arg1); __otl_write_row(s, std::forward(args)...); } template inline void otl_write_row(OTLStreamType &s, Arg1 &&arg1, Args &&... args) OTL_THROWS_OTL_EXCEPTION { s << std::forward(arg1); __otl_write_row(s, std::forward(args)...); } #endif #else template inline void otl_read_row(S &s, T1 &t1) OTL_THROWS_OTL_EXCEPTION { s >> t1; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s >> t8; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s >> t8; s >> t9; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s >> t8; s >> t9; s >> t10; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s >> t8; s >> t9; s >> t10; s >> t11; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s >> t8; s >> t9; s >> t10; s >> t11; s >> t12; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12, T13 &t13) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s >> t8; s >> t9; s >> t10; s >> t11; s >> t12; s >> t13; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12, T13 &t13, T14 &t14) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s >> t8; s >> t9; s >> t10; s >> t11; s >> t12; s >> t13; s >> t14; s.check_end_of_row(); } template inline void otl_read_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12, T13 &t13, T14 &t14, T15 &t15) OTL_THROWS_OTL_EXCEPTION { s >> t1; s >> t2; s >> t3; s >> t4; s >> t5; s >> t6; s >> t7; s >> t8; s >> t9; s >> t10; s >> t11; s >> t12; s >> t13; s >> t14; s >> t15; s.check_end_of_row(); } #if defined(_MSC_VER) && ((_MSC_VER == 1600) || (_MSC_VER == 1700)) // VC++ 2010, VC++ 2012: universal references are supported template inline void otl_write_row(S &s, T1 &&t1) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6, T7 &&t7) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6, T7 &&t7, T8 &&t8) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s << std::forward(t8); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s << std::forward(t8); s << std::forward(t9); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s << std::forward(t8); s << std::forward(t9); s << std::forward(t10); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10, T11 &&t11) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s << std::forward(t8); s << std::forward(t9); s << std::forward(t10); s << std::forward(t11); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10, T11 &&t11, T12 &&t12) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s << std::forward(t8); s << std::forward(t9); s << std::forward(t10); s << std::forward(t11); s << std::forward(t12); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12, T13 &t13) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s << std::forward(t8); s << std::forward(t9); s << std::forward(t10); s << std::forward(t11); s << std::forward(t12); s << std::forward(t13); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10, T11 &&t11, T12 &&t12, T13 &&t13, T14 &&t14) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s << std::forward(t8); s << std::forward(t9); s << std::forward(t10); s << std::forward(t11); s << std::forward(t12); s << std::forward(t13); s << std::forward(t14); s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3, T4 &&t4, T5 &&t5, T6 &&t6, T7 &&t7, T8 &&t8, T9 &&t9, T10 &&t10, T11 &&t11, T12 &&t12, T13 &&t13, T14 &&t14, T15 &&t15) OTL_THROWS_OTL_EXCEPTION { s << std::forward(t1); s << std::forward(t2); s << std::forward(t3); s << std::forward(t4); s << std::forward(t5); s << std::forward(t6); s << std::forward(t7); s << std::forward(t8); s << std::forward(t9); s << std::forward(t10); s << std::forward(t11); s << std::forward(t12); s << std::forward(t13); s << std::forward(t14); s << std::forward(t15); s.check_end_of_row(); } #else template inline void otl_write_row(S &s, T1 &t1) OTL_THROWS_OTL_EXCEPTION { s << t1; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s << t12; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12, T13 &t13) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s << t12; s << t13; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12, T13 &t13, T14 &t14) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s << t12; s << t13; s << t14; s.check_end_of_row(); } template inline void otl_write_row(S &s, T1 &t1, T2 &t2, T3 &t3, T4 &t4, T5 &t5, T6 &t6, T7 &t7, T8 &t8, T9 &t9, T10 &t10, T11 &t11, T12 &t12, T13 &t13, T14 &t14, T15 &t15) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s << t12; s << t13; s << t14; s << t15; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1) OTL_THROWS_OTL_EXCEPTION { s << t1; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9, const T10 &t10) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9, const T10 &t10, const T11 &t11) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9, const T10 &t10, const T11 &t11, const T12 &t12) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s << t12; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9, const T10 &t10, const T11 &t11, const T12 &t12, const T13 &t13) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s << t12; s << t13; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9, const T10 &t10, const T11 &t11, const T12 &t12, const T13 &t13, const T14 &t14) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s << t12; s << t13; s << t14; s.check_end_of_row(); } template inline void otl_write_row(S &s, const T1 &t1, const T2 &t2, const T3 &t3, const T4 &t4, const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9, const T10 &t10, const T11 &t11, const T12 &t12, const T13 &t13, const T14 &t14, const T15 &t15) OTL_THROWS_OTL_EXCEPTION { s << t1; s << t2; s << t3; s << t4; s << t5; s << t6; s << t7; s << t8; s << t9; s << t10; s << t11; s << t12; s << t13; s << t14; s << t15; s.check_end_of_row(); } #endif #endif #if (defined(OTL_CPP_11_ON) || defined(_MSC_VER) && (_MSC_VER >= 1700)) && \ defined(OTL_CONNECT_POOL_ON) #include #include #include #if defined(OTL_CLANG_THREAD_SAFETY_ON) #define OTL_THREAD_ANNOTATION_ATTRIBUTE(x) __attribute__((x)) #else #define OTL_THREAD_ANNOTATION_ATTRIBUTE(x) #endif #define OTL_CAPABILITY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(capability(x)) #define OTL_SCOPED_CAPABILITY OTL_THREAD_ANNOTATION_ATTRIBUTE(scoped_lockable) #define OTL_GUARDED_BY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(guarded_by(x)) #define OTL_PT_GUARDED_BY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(pt_guarded_by(x)) #define OTL_ACQUIRED_BEFORE(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(acquired_before(__VA_ARGS__)) #define OTL_ACQUIRED_AFTER(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(acquired_after(__VA_ARGS__)) #define OTL_REQUIRES(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(requires_capability(__VA_ARGS__)) #define OTL_REQUIRES_SHARED(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(requires_shared_capability(__VA_ARGS__)) #define OTL_ACQUIRE(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(acquire_capability(__VA_ARGS__)) #define OTL_ACQUIRE_SHARED(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(acquire_shared_capability(__VA_ARGS__)) #define OTL_RELEASE(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(release_capability(__VA_ARGS__)) #define OTL_RELEASE_SHARED(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(release_shared_capability(__VA_ARGS__)) #define OTL_TRY_ACQUIRE(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(try_acquire_capability(__VA_ARGS__)) #define OTL_TRY_ACQUIRE_SHARED(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(try_acquire_shared_capability(__VA_ARGS__)) #define OTL_EXCLUDES(...) OTL_THREAD_ANNOTATION_ATTRIBUTE(locks_excluded(__VA_ARGS__)) #define OTL_ASSERT_CAPABILITY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(assert_capability(x)) #define OTL_ASSERT_SHARED_CAPABILITY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(assert_shared_capability(x)) #define OTL_RETURN_CAPABILITY(x) OTL_THREAD_ANNOTATION_ATTRIBUTE(lock_returned(x)) #define OTL_NO_THREAD_SAFETY_ANALYSIS OTL_THREAD_ANNOTATION_ATTRIBUTE(no_thread_safety_analysis) class OTL_CAPABILITY("mutex") otl_recursive_mutex{ private: std::recursive_mutex mutex_; public: otl_recursive_mutex(): mutex_(){} ~otl_recursive_mutex(){} void lock() OTL_ACQUIRE(){mutex_.lock();} void unlock() OTL_RELEASE(){mutex_.unlock();} std::recursive_mutex& get_mutex(){return mutex_;} const otl_recursive_mutex& operator!() const {return *this;} }; class OTL_SCOPED_CAPABILITY otl_recursive_mutex_guard { public: otl_recursive_mutex_guard(otl_recursive_mutex* mut) OTL_ACQUIRE(mut) : mutex_ptr_(mut) { mutex_ptr_->lock(); } ~otl_recursive_mutex_guard() OTL_RELEASE() { mutex_ptr_->unlock(); } otl_recursive_mutex_guard(const otl_recursive_mutex_guard& src) : mutex_ptr_(src.mutex_ptr_){} otl_recursive_mutex_guard(otl_recursive_mutex_guard&& src) : mutex_ptr_(src.mutex_ptr_){} otl_recursive_mutex_guard& operator=(const otl_recursive_mutex_guard& src) { mutex_ptr_=src.mutex_ptr_; return *this; } otl_recursive_mutex_guard& operator=(otl_recursive_mutex_guard&& src) { mutex_ptr_=src.mutex_ptr_; return *this; } private: otl_recursive_mutex* mutex_ptr_; }; template class otl_connect_pool{ public: typedef std::unique_ptr connect_ptr; // Default constructor otl_connect_pool() OTL_NO_THROW : pool_open_(false), min_pool_size_(0), max_pool_size_(0), connects_in_use_(0), auto_commit_(false), connect_str_(nullptr), grow_pool_in_increments_(1), pool_(), mutex_(){ } // Prepopulate the pool to the specified minimum size. otl_connect_pool (const char* connect_str, const bool auto_commit=false, const size_t new_min_pool_size=8, const size_t new_max_pool_size=32, const size_t grow_pool_in_increments=1) OTL_THROWS_OTL_EXCEPTION : otl_connect_pool(){ open(connect_str, auto_commit, new_min_pool_size, new_max_pool_size, grow_pool_in_increments); } // Open the pool and prepopulate it to the specified minimum // size. If the pool was already opened, close it first void open(const char* connect_str, const bool auto_commit=false, const size_t new_min_pool_size=8, const size_t new_max_pool_size=32, const size_t grow_pool_in_increments=1) OTL_THROWS_OTL_EXCEPTION{ otl_recursive_mutex_guard guard(&mutex_); if(pool_open_)close(true); pool_open_=true; connects_in_use_=0; min_pool_size_=new_min_pool_size; max_pool_size_=new_max_pool_size; grow_pool_in_increments_=grow_pool_in_increments; pool_.clear(); size_t connect_str_len=strlen(connect_str); connect_str_=new char[connect_str_len+1]; OTL_STRCPY_S(connect_str_,connect_str_len+1,connect_str); auto_commit_=auto_commit; for(size_t i=0;i()); #else pool_.push_back(connect_ptr(new OTLConnect())); #endif pool_.back()->rlogon(connect_str,auto_commit); } } // Get a connect object from the pool. The ownership of the // connect object is transferred / moved to the caller. If the // pool is empty / already at its maximum size or closed, return // an empty unique pointer. connect_ptr get(const bool ignore_errors=true) OTL_THROWS_OTL_EXCEPTION{ connect_ptr ptr; otl_recursive_mutex_guard guard(&mutex_); if(pool_open_ && pool_.size()==0){ // populate connects in the pool to the maximum size exception_ptr ret_exc; size_t iters=grow_pool_in_increments_; size_t total_allowed_connects=max_pool_size_-connects_in_use_; if(iters>total_allowed_connects) iters=total_allowed_connects; for(size_t i=0; i()); #else pool_.push_back(connect_ptr(new OTLConnect())); #endif try{ pool_.back()->rlogon(connect_str_,auto_commit_); }catch(const OTLException& ex){ // save the first error and throw it as an exception at // the end of the function if ignore_errors is set to // false if(!ret_exc) #if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED) ret_exc=std::make_unique(ex); #else ret_exc.reset(new OTLException(ex)); #endif } } if(!ignore_errors && ret_exc) OTL_THROW(*ret_exc); } if(pool_open_ && pool_.size()>0){ // if the pool is not empty, return an element from the // the end of the pool. ptr=std::move(pool_.back()); pool_.pop_back(); ++connects_in_use_; } return ptr; } // Put a connect object into the pool. The ownership of the object // is transferred / moved from the caller to the pool. Return // false if the pool is full or closed. bool put(connect_ptr&& p) OTL_NO_THROW{ otl_recursive_mutex_guard guard(&mutex_); if(!pool_open_)return false; if(pool_.size()new_min_pool_size && pool_.size()>0){ auto& last_element=pool_.back(); if(last_element){ try{ last_element->logoff(); }catch(const OTLException& ex){ // save the first error and throw it as an exception at // the end of the function if ignore_errors is set to // false if(!ret_exc) #if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED) ret_exc=std::make_unique(ex); #else ret_exc.reset(new OTLException(ex)); #endif } last_element.reset(nullptr); } pool_.pop_back(); } min_pool_size_=new_min_pool_size; if(!ignore_errors && ret_exc) OTL_THROW(*ret_exc); } // change max pool size void change_max_pool_size(const size_t new_max_pool_size) OTL_THROWS_OTL_EXCEPTION { otl_recursive_mutex_guard guard(&mutex_); if(max_pool_size_new_max_pool_size){ // if new_max_pool_size is smaller than the current pool size, // then shrink the pool to the new max size. if(pool_.size()>new_max_pool_size) shrink_pool(new_max_pool_size); max_pool_size_=new_max_pool_size; } } // Close the pool void close(const bool ignore_errors=false) OTL_THROWS_OTL_EXCEPTION{ otl_recursive_mutex_guard guard(&mutex_); if(!pool_open_)return; exception_ptr ret_exc; for(auto& i:pool_){ if(i){ try{ i->logoff(); }catch(const OTLException& ex){ if(!ret_exc) #if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED) ret_exc=std::make_unique(ex); #else ret_exc.reset(new OTLException(ex)); #endif } } i.reset(nullptr); } pool_.clear(); pool_open_=false; min_pool_size_=0; max_pool_size_=0; delete[] connect_str_; connect_str_=nullptr; if(!ignore_errors && ret_exc) OTL_THROW(*ret_exc); } // Destructor. Disconnect all idle database connections first, and // then destroy the pool. ~otl_connect_pool() OTL_NO_THROW{ close(true); } // Get the maximum pool size size_t max_pool_size() const OTL_NO_THROW{ otl_recursive_mutex_guard guard(&mutex_); return max_pool_size_; } // Get the minimum pool size size_t min_pool_size() const OTL_NO_THROW{ otl_recursive_mutex_guard guard(&mutex_); return min_pool_size_; } // Get the current / dynamic pool size size_t current_pool_size() const OTL_NO_THROW{ otl_recursive_mutex_guard guard(&mutex_); return pool_.size(); } // Return "pool is open" flag bool is_open() const OTL_NO_THROW{ otl_recursive_mutex_guard guard(&mutex_); return pool_open_; } // Get the underlying mutex when a sequence of more than one call // needs to be done under a single mutex lock for consistency. std::recursive_mutex& get_mutex() OTL_NO_THROW{ return mutex_.get_mutex(); } private: typedef std::unique_ptr exception_ptr; bool pool_open_ OTL_GUARDED_BY(mutex_); size_t min_pool_size_ OTL_GUARDED_BY(mutex_); size_t max_pool_size_ OTL_GUARDED_BY(mutex_); size_t connects_in_use_ OTL_GUARDED_BY(mutex_); bool auto_commit_ OTL_GUARDED_BY(mutex_); char* connect_str_ OTL_GUARDED_BY(mutex_); size_t grow_pool_in_increments_ OTL_GUARDED_BY(mutex_); std::vector pool_ OTL_GUARDED_BY(mutex_); mutable otl_recursive_mutex mutex_; }; #endif #if defined(OTL_ORA_TEXT_ON) && defined(text) #undef text #endif #endif