Files
microser/include/otlv4.h
2025-01-16 16:17:01 +08:00

34463 lines
1.1 MiB

// =================================================================================
// 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 <tuple>
#include <utility>
template<typename streamType, typename Tuple, const size_t N>
struct otl_tuple_helper{
static void write(streamType& s, const Tuple& t){
otl_tuple_helper<streamType,Tuple,N-1>::write(s,t);
s<<std::get<N-1>(t);
}
static void read(streamType& s, Tuple& t){
otl_tuple_helper<streamType,Tuple,N-1>::read(s,t);
s>>std::get<N-1>(t);
}
};
template<typename streamType, typename Tuple>
struct otl_tuple_helper<streamType,Tuple,1>{
static void write(streamType& s, const Tuple& t) {
s<<std::get<0>(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<std::size_t>(dest_sz-1)))
#endif // OTL_STRCAT_S
#ifndef OTL_STRCPY_S
#define OTL_STRCPY_S(dest, dest_sz, src) (strncpy(dest, src, static_cast<std::size_t>(dest_sz-1)),dest[static_cast<std::size_t>(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<std::size_t>(count)]=0)
#endif // OTL_STRNCPY_S
#ifndef OTL_SPRINTF_S
#include <stdarg.h>
#include <stdio.h>
#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 <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
//======================= 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 <iostream>
#include <iomanip>
#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 <timesten.h>
#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 <timesten.h>
#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 <new>
#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 <ace/SString.h>
#include <ace/Containers_T.h>
#include <ace/Null_Mutex.h>
#include <ace/Functor.h>
#include <ace/RB_Tree.h>
#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 <OTL_TYPE_NAME T> class otl_tmpl_vector : public ACE_Array<T> {
public:
otl_tmpl_vector(const int init_size = otl_tmpl_vector_default_size)
: ACE_Array<T>(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<T>::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<T>::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 <exception>
#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 <iostream>
#include <iomanip>
#else
#include <iostream.h>
#include <iomanip.h>
#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 <string>
#include <iterator>
#include <vector>
#ifndef OTL_STL_NOSTD_NAMESPACE
#include <iostream>
#include <iomanip>
#else
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
#include <iostream>
#include <iomanip>
#else
#include <iostream.h>
#include <iomanip.h>
#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<char,...> container is too small"
const int otl_error_code_46 = 32047;
#define otl_error_msg_46 "target std::array<char16_t,...> 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 <OTL_TYPE_NAME T> 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<T> &)
: ptr(nullptr), arr_size_(0) {}
otl_auto_array_ptr<T> &operator=(const otl_auto_array_ptr<T> &) {
return *this;
}
#if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
otl_auto_array_ptr(otl_auto_array_ptr<T> &&) : ptr(nullptr), arr_size_(0) {}
otl_auto_array_ptr<T> &operator=(otl_auto_array_ptr<T> &&) { return *this; }
#endif
};
template <OTL_TYPE_NAME T> 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 <OTL_TYPE_NAME T> 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 <type_traits>
#include <variant>
template<const size_t I, typename Variant>
struct otl_convert_type_to_code_helper{
static int convert(){
using currType=typename std::variant_alternative<I,Variant>::type;
if constexpr(std::is_same_v<int,currType>)
return otl_var_int;
if constexpr(std::is_same_v<double,currType>)
return otl_var_double;
if constexpr(std::is_same_v<float,currType>)
return otl_var_float;
if constexpr(std::is_same_v<unsigned int,currType>)
return otl_var_unsigned_int;
if constexpr(std::is_same_v<short int,currType>)
return otl_var_short;
if constexpr(std::is_same_v<long int,currType>)
return otl_var_long_int;
if constexpr(std::is_same_v<otl_datetime,currType>)
return otl_var_timestamp;
#if defined(OTL_BIGINT)
if constexpr(std::is_same_v<OTL_BIGINT,currType>)
return otl_var_bigint;
#endif
#if defined(OTL_UBIGINT)
if constexpr(std::is_same_v<OTL_UBIGINT,currType>)
return otl_var_ubigint;
#endif
}
};
template<typename streamType, const size_t N, typename Variant>
struct otl_variant_helper{
static void write(streamType& s, const Variant& v, bool& value_written){
otl_variant_helper<streamType,N-1,Variant>::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<N-1,Variant>::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<<std::get<N-1>(v);
value_written=true;
}
}
static void read(streamType& s, Variant& v, bool& value_read){
otl_variant_helper<streamType,N-1,Variant>::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<N-1,Variant>::convert()){
using currType=typename std::variant_alternative<N-1,Variant>::type;
currType val;
s>>val;
v=val;
value_read=true;
}
}
};
template<typename streamType, typename Variant>
struct otl_variant_helper<streamType,1,Variant>{
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<<std::get<0>(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<char,...>";
const char *const_STD_UNICODE_CHAR_ARRAY = "std::array<char16_t,...>";
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 <OTL_TYPE_NAME T, const int T_type>
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 <OTL_TYPE_NAME T>
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 <OTL_TYPE_NAME T>
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 <string>
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 <map>
#include <vector>
#endif
class otl_stream_pool;
class otl_stream_pool_entry {
public:
friend class otl_stream_pool;
#if defined(OTL_ACE)
otl_tmpl_vector<otl_stream_shell_generic *> s;
#elif defined(OTL_UNICODE_STRING_TYPE)
std::vector<otl_stream_shell_generic *> s;
#else
STD_NAMESPACE_PREFIX vector<otl_stream_shell_generic *> 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<OTL_STRING_CONTAINER, cache_entry_type,
ACE_Less_Than<OTL_STRING_CONTAINER>,
ACE_Null_Mutex> sc_type;
typedef otl_tmpl_vector<otl_stream_shell_generic *> vec_type;
typedef ACE_RB_Tree_Node<OTL_STRING_CONTAINER, cache_entry_type>
ace_map_entry;
#elif defined(OTL_UNICODE_STRING_TYPE)
typedef std::map<std::string, cache_entry_type, otl_ltstr> sc_type;
typedef std::vector<otl_stream_shell_generic *> vec_type;
#else
typedef STD_NAMESPACE_PREFIX
map<OTL_STRING_CONTAINER, cache_entry_type, otl_ltstr> sc_type;
typedef STD_NAMESPACE_PREFIX vector<otl_stream_shell_generic *> 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 <OTL_TYPE_NAME TData> class otl_value {
public:
TData v;
bool ind;
otl_value() : v(), ind(true) {}
~otl_value() {}
otl_value(const otl_value<TData> &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<TData> &operator=(const otl_value<TData> &var) {
v = var.v;
ind = var.ind;
return *this;
}
otl_value<TData> &operator=(const TData &var) {
v = var;
ind = false;
return *this;
}
otl_value<TData> &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 <OTL_TYPE_NAME TData, const TData null_value> class otl_compact_value {
public:
TData v;
otl_compact_value() : v(null_value) {}
~otl_compact_value(){}
otl_compact_value(const otl_compact_value<TData,null_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<TData,null_value> &operator=(const otl_compact_value<TData,null_value> &var) {
v = var.v;
return *this;
}
otl_compact_value<TData,null_value> &operator=(const TData &var) {
v = var;
return *this;
}
otl_compact_value<TData,null_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 <OTL_TYPE_NAME TData>
inline STD_NAMESPACE_PREFIX ostream &operator<<(STD_NAMESPACE_PREFIX ostream &s,
const otl_value<TData> &var) {
if(var.is_null())
s<<"NULL";
else
s<<var.v;
return s;
}
template <OTL_TYPE_NAME TData, const TData null_value>
inline STD_NAMESPACE_PREFIX ostream &operator<<
(STD_NAMESPACE_PREFIX ostream &s,
const otl_compact_value<TData,null_value> &var) {
if(var.is_null())
s<<"NULL";
else
s<<var.v;
return s;
}
#if defined(OTL_DISABLE_OPERATOR_GT_GT_FOR_OTL_VALUE_OTL_DATETIME)
#else
inline STD_NAMESPACE_PREFIX ostream &operator<<(
STD_NAMESPACE_PREFIX ostream &s, const otl_value<otl_datetime> &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 <OTL_TYPE_NAME OTLStream, OTL_TYPE_NAME OTLConnect,
OTL_TYPE_NAME otl_exception>
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<bool> 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 <OTL_TYPE_NAME T, const int type_code, const int T_sz>
class otl_T_vec : public otl_pl_vec_generic {
public:
STD_NAMESPACE_PREFIX vector<T> 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<double, otl_var_double, sizeof(double)> otl_double_vec;
typedef otl_T_vec<float, otl_var_float, sizeof(float)> otl_float_vec;
typedef otl_T_vec<int, otl_var_int, sizeof(int)> otl_int_vec;
typedef otl_T_vec<short, otl_var_short, sizeof(short)> otl_short_vec;
typedef otl_T_vec<long, otl_var_long_int, sizeof(long)> otl_long_int_vec;
typedef otl_T_vec<otl_datetime, otl_var_timestamp, sizeof(otl_oracle_date)>
otl_datetime_vec;
typedef otl_T_vec<OTL_STRING_CONTAINER, otl_var_char, 1> otl_string_vec;
#endif
template <OTL_TYPE_NAME T, const int atab_size, const int avtype>
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 <const int atab_size>
class otl_int_tab : public otl_tmpl_pl_tab<int, atab_size, otl_var_int> {
public:
otl_int_tab() : otl_tmpl_pl_tab<int, atab_size, otl_var_int>() {}
};
template <const int atab_size>
class otl_double_tab
: public otl_tmpl_pl_tab<double, atab_size, otl_var_double> {
public:
otl_double_tab() : otl_tmpl_pl_tab<double, atab_size, otl_var_double>() {}
};
template <const int atab_size>
class otl_float_tab : public otl_tmpl_pl_tab<float, atab_size, otl_var_float> {
public:
otl_float_tab() : otl_tmpl_pl_tab<float, atab_size, otl_var_float>() {}
};
template <const int atab_size>
class otl_unsigned_tab
: public otl_tmpl_pl_tab<unsigned, atab_size, otl_var_unsigned_int> {
public:
otl_unsigned_tab()
: otl_tmpl_pl_tab<unsigned, atab_size, otl_var_unsigned_int>() {}
};
template <const int atab_size>
class otl_short_tab : public otl_tmpl_pl_tab<short, atab_size, otl_var_short> {
public:
otl_short_tab() : otl_tmpl_pl_tab<short, atab_size, otl_var_short>() {}
};
template <const int atab_size>
class otl_long_int_tab
: public otl_tmpl_pl_tab<long, atab_size, otl_var_long_int> {
public:
otl_long_int_tab() : otl_tmpl_pl_tab<long, atab_size, otl_var_long_int>() {}
};
template <const int atab_size, const int str_size>
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 <const int atab_size>
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 <OTL_TYPE_NAME T, const int avtype>
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<T, avtype> &) = delete;
otl_tmpl_dyn_pl_tab<T, avtype> &
operator=(const otl_tmpl_dyn_pl_tab<T, avtype> &) = delete;
#if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
otl_tmpl_dyn_pl_tab(otl_tmpl_dyn_pl_tab<T, avtype> &&) = delete;
otl_tmpl_dyn_pl_tab<T, avtype> &operator=(otl_tmpl_dyn_pl_tab<T, avtype> &&) =
delete;
#endif
private:
#else
otl_tmpl_dyn_pl_tab(const otl_tmpl_dyn_pl_tab<T, avtype> &)
: v(nullptr), null_flag(nullptr) {}
otl_tmpl_dyn_pl_tab<T, avtype> &
operator=(const otl_tmpl_dyn_pl_tab<T, avtype> &) {
return *this;
}
#if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
otl_tmpl_dyn_pl_tab(otl_tmpl_dyn_pl_tab<T, avtype> &&)
: v(nullptr), null_flag(nullptr) {}
otl_tmpl_dyn_pl_tab<T, avtype> &operator=(otl_tmpl_dyn_pl_tab<T, avtype> &&) {
return *this;
}
#endif
#endif
};
class otl_dynamic_int_tab : public otl_tmpl_dyn_pl_tab<int, otl_var_int> {
public:
otl_dynamic_int_tab(const int atab_size = 1)
: otl_tmpl_dyn_pl_tab<int, otl_var_int>(atab_size) {}
};
class otl_dynamic_double_tab
: public otl_tmpl_dyn_pl_tab<double, otl_var_double> {
public:
otl_dynamic_double_tab(const int atab_size = 1)
: otl_tmpl_dyn_pl_tab<double, otl_var_double>(atab_size) {}
};
class otl_dynamic_float_tab : public otl_tmpl_dyn_pl_tab<float, otl_var_float> {
public:
otl_dynamic_float_tab(const int atab_size = 1)
: otl_tmpl_dyn_pl_tab<float, otl_var_float>(atab_size) {}
};
class otl_dynamic_unsigned_tab
: public otl_tmpl_dyn_pl_tab<unsigned, otl_var_unsigned_int> {
public:
otl_dynamic_unsigned_tab(const int atab_size = 1)
: otl_tmpl_dyn_pl_tab<unsigned, otl_var_unsigned_int>(atab_size) {}
};
class otl_dynamic_short_tab : public otl_tmpl_dyn_pl_tab<short, otl_var_short> {
public:
otl_dynamic_short_tab(const int atab_size = 1)
: otl_tmpl_dyn_pl_tab<short, otl_var_short>(atab_size) {}
};
class otl_dynamic_long_int_tab
: public otl_tmpl_dyn_pl_tab<long, otl_var_long_int> {
public:
otl_dynamic_long_int_tab(const int atab_size = 1)
: otl_tmpl_dyn_pl_tab<long, otl_var_long_int>(atab_size) {}
};
template <const int str_size>
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<TExceptionStruct, TConnectStruct, TCursorStruct>
#define OTL_TMPL_CONNECT \
otl_tmpl_connect<TExceptionStruct, TConnectStruct, TCursorStruct>
#define OTL_TMPL_CURSOR \
otl_tmpl_cursor<TExceptionStruct, TConnectStruct, TCursorStruct, \
TVariableStruct>
#define OTL_TMPL_OUT_STREAM \
otl_tmpl_out_stream<TExceptionStruct, TConnectStruct, TCursorStruct, \
TVariableStruct, TTimestampStruct>
#define OTL_TMPL_SELECT_CURSOR \
otl_tmpl_select_cursor<TExceptionStruct, TConnectStruct, TCursorStruct, \
TVariableStruct, TSelectCursorStruct>
#define OTL_TMPL_INOUT_STREAM \
otl_tmpl_inout_stream<TExceptionStruct, TConnectStruct, TCursorStruct, \
TVariableStruct, TTimestampStruct>
#define OTL_TMPL_SELECT_STREAM \
otl_tmpl_select_stream<TExceptionStruct, TConnectStruct, TCursorStruct, \
TVariableStruct, TSelectCursorStruct, \
TTimestampStruct>
#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<const char *>(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<const char *>(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<const char *>(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<const char *>(this->msg); \
}
#else
#define OTL_EXCEPTION_HAS_MEMBERS \
virtual const char *what() const throw() { \
return reinterpret_cast<const char *>(this->msg); \
}
#endif
#else
#define OTL_EXCEPTION_HAS_MEMBERS \
virtual const char *what() const throw() { \
return reinterpret_cast<const char *>(this->msg); \
}
#endif
#endif
#endif
template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct>
#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 <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct>
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 <OTL_TYPE_NAME TVariableStruct> 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 <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct>
class otl_tmpl_cursor {
protected:
int connected;
char *stm_text;
char *stm_label;
TCursorStruct cursor_struct;
int vl_len;
otl_tmpl_variable<TVariableStruct> **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<TVariableStruct> **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<TVariableStruct> &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<TVariableStruct> &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<TVariableStruct> &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<TVariableStruct> &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 <OTL_TYPE_NAME TVariableStruct, OTL_TYPE_NAME TTimestampStruct,
OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct>
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<TVariableStruct> *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 <char> 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 <char[XXX]> 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<TVariableStruct> *v =
new otl_tmpl_variable<TVariableStruct>;
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<TVariableStruct> **&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<otl_tmpl_variable<TVariableStruct> *> loc_ptr(
container_size_);
otl_tmpl_variable<TVariableStruct> **tmp_vl = loc_ptr.get_ptr();
int i = 0;
while (hv[i]) {
otl_tmpl_variable<TVariableStruct> *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<TVariableStruct> *[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<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct> &
operator=(const otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct> &) = delete;
#if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
otl_tmpl_ext_hv_decl(
otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct> &&) = delete;
otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct> &
operator=(
otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct> &&) = 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<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct> &
operator=(const otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct> &) {
return *this;
}
#if defined OTL_ANSI_CPP_11_RVAL_REF_SUPPORT
otl_tmpl_ext_hv_decl(
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<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct> &
operator=(
otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct> &&) {
return *this;
}
#endif
#endif
};
template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct,
OTL_TYPE_NAME TSelectCursorStruct>
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<T, T_type>(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 <array>
#endif
template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct,
OTL_TYPE_NAME TSelectCursorStruct, OTL_TYPE_NAME TTimestampStruct>
class otl_tmpl_select_stream : public OTL_TMPL_SELECT_CURSOR {
protected:
otl_column_desc *sl_desc;
otl_tmpl_variable<TVariableStruct> *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<TVariableStruct> *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<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct>
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<otl_column_desc> 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<TVariableStruct>::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<TVariableStruct>[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<TVariableStruct>::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<unsigned char> 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_size<sl[cur_col].get_len(this->cur_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<TExceptionStruct, TConnectStruct,
TCursorStruct>(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<unsigned short> 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_size<sl[cur_col].get_len(this->cur_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<TExceptionStruct, TConnectStruct,
TCursorStruct>(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<T, T_type>( \
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_TYPE_NAME T,const int T_type> 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<const size_t N>
OTL_TMPL_SELECT_STREAM &operator<<(const std::array<char,N>& s){
(*this)<<s.data();
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<const size_t N>
OTL_TMPL_SELECT_STREAM &operator<<(const std::array<char16_t,N>& s){
(*this)<<OTL_RCAST(unsigned char*,OTL_CCAST(char16_t*,s.data()));
return *this;
}
#endif
OTL_TMPL_SELECT_STREAM &operator<<(const otl_long_string &s) {
check_in_var();
switch (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_TYPE_NAME T,const int T_type> 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 <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct,
OTL_TYPE_NAME TTimestampStruct>
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<const size_t N>
OTL_TMPL_OUT_STREAM &operator<<(const std::array<char16_t,N>& s){
(*this)<<OTL_RCAST(const unsigned char*,s.data());
return *this;
}
#endif
#if defined(OTL_STREAM_WITH_STD_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
template<const size_t N>
OTL_TMPL_OUT_STREAM &operator<<(const std::array<char,N>& s){
(*this)<<s.data();
return *this;
}
#endif
OTL_TMPL_OUT_STREAM &operator<<(const unsigned char *s) {
if (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_TYPE_NAME T,const int T_type> 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<OTL_STRING_CONTAINER> *,
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<OTL_STRING_CONTAINER> *,
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<OTL_STRING_CONTAINER> *,
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<otl_datetime> *,
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<int> *,
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<double> *,
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<double> *,
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<float> *,
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<float> *,
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<unsigned> *,
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<short> *,
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<long int> *,
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 <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct,
OTL_TYPE_NAME TTimestampStruct>
class otl_tmpl_inout_stream : public OTL_TMPL_OUT_STREAM {
protected:
otl_tmpl_variable<TVariableStruct> **in_vl;
int iv_len;
int cur_in_x;
int cur_in_y;
int in_y_len;
int null_fetched;
otl_tmpl_variable<TVariableStruct> **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<TVariableStruct> **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<TVariableStruct, TTimestampStruct, TExceptionStruct,
TConnectStruct, TCursorStruct> 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<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct>::in)
++this->vl_len;
else if (hvd.get_inout(i) ==
otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct>::out)
++iv_len;
else if (hvd.get_inout(i) ==
otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct>::io) {
++this->vl_len;
++iv_len;
}
}
if (this->vl_len > 0) {
this->vl = new otl_tmpl_variable<TVariableStruct> *[OTL_SCAST(size_t,this->vl_len)];
}
if (iv_len > 0)
in_vl = new otl_tmpl_variable<TVariableStruct> *[OTL_SCAST(size_t,iv_len)];
avl_len = hvd.get_len();
if (hvd.get_len() > 0)
avl = new otl_tmpl_variable<TVariableStruct> *[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<TVariableStruct> *v = hvd.alloc_var(
hvd[j], hvd.get_inout(j),
otl_tmpl_ext_hv_decl<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct>::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<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct>::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<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct>::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<TVariableStruct, TTimestampStruct,
TExceptionStruct, TConnectStruct,
TCursorStruct>::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_y<in_y_len-1)
++cur_in_y;
}
void get_in_next(void) {
if (iv_len == 0)
return;
if (in_y_len == 0)
return;
if (cur_in_x < iv_len - 1)
++cur_in_x;
else {
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;
}
}
}
OTL_NODISCARD int check_in_type_throw(int type_code) {
this->in_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<unsigned char> 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_size<in_vl[cur_in_x]->get_len(cur_in_y)){
OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct,
TCursorStruct>(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_size<in_vl[cur_in_x]->get_len(cur_in_y))
OTL_THROW((otl_tmpl_exception<TExceptionStruct, TConnectStruct,
TCursorStruct>(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_TYPE_NAME T,const int T_type> 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<OTL_STRING_CONTAINER> *,
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<otl_datetime> *,
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<int> *,
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<double> *,
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<double> *,
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<float> *,
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<float> *,
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<unsigned> *,
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<short> *,
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<long int> *,
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 <windows.h>
#endif
#if defined(OTL_ODBC_UNIX) && defined(OTL_INFORMIX_CLI_64_BIT)
#include <infxsql.h>
#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 <infxsql.h>
#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 <sql.h>
#include <sqlext.h>
#endif
#else
#if defined(__clang__) && (__clang_major__*100+__clang_minor__ >= 306)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wreserved-id-macro"
#endif
#include <sqlcli1.h>
#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_exc, otl_conn, otl_cur> otl_odbc_connect;
typedef otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var> otl_cursor;
typedef otl_tmpl_exception<otl_exc, otl_conn, otl_cur> otl_exception;
typedef otl_tmpl_select_stream<otl_exc, otl_conn, otl_cur, otl_var, otl_sel,
otl_time> otl_select_stream;
typedef otl_tmpl_inout_stream<otl_exc, otl_conn, otl_cur, otl_var, otl_time>
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 <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct>
class otl_tmpl_lob_stream : public otl_lob_stream_generic {
public:
typedef otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>
otl_exception;
typedef otl_tmpl_variable<TVariableStruct> *p_bind_var;
typedef otl_tmpl_connect<TExceptionStruct, TConnectStruct, TCursorStruct> *
p_connect;
typedef otl_tmpl_cursor<TExceptionStruct, TConnectStruct, TCursorStruct,
TVariableStruct> *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<TExceptionStruct, TConnectStruct, TCursorStruct>(
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_exc, otl_conn, otl_cur, otl_var> 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 <array>
#endif
#if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
#include <array>
#endif
#if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_COMPILER_HAS_STD_OPTIONAL)
#include <optional>
#endif
#if defined(OTL_STREAM_WITH_STD_SPAN_ON) && defined(OTL_CPP_20_ON)
#include <span>
#endif
class otl_stream {
private:
otl_stream_shell *shell;
otl_ptr<otl_stream_shell> 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<typename...T>
otl_stream& operator<<(const std::tuple<T...>& t){
otl_tuple_helper<otl_stream,decltype(t),sizeof...(T)>::write(*this,t);
return (*this);
}
template<typename...T>
otl_stream& operator>>(std::tuple<T...>& t){
otl_tuple_helper<otl_stream,decltype(t),sizeof...(T)>::read(*this,t);
return (*this);
}
#endif
#if defined(OTL_STREAM_WITH_STD_SPAN_ON) && defined(OTL_CPP_20_ON)
public:
template<typename T>
otl_stream& operator<<(std::span<T> v){
for(const auto& e: v){
(*this)<<e;
}
return *this;
}
#endif
#if defined(OTL_STREAM_WITH_STD_VARIANT_ON) && defined(OTL_CPP_17_ON)
public:
template<typename...T>
otl_stream& operator<<(const std::variant<T...>& v){
bool value_written=false;
otl_variant_helper<otl_stream,sizeof...(T),std::variant<T...>>
::write(*this,v,value_written);
return (*this);
}
template<typename...T>
otl_stream& operator>>(std::variant<T...>& v){
bool value_read=false;
otl_variant_helper<otl_stream,sizeof...(T),std::variant<T...>>
::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_TYPE_NAME TData>
otl_stream& operator<<(const std::optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if(var)
(*this)<<(*var);
else
(*this)<<otl_null();
return *this;
}
template<OTL_TYPE_NAME TData>
otl_stream& operator>>(std::optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if(var){
(*this)>>(*var);
if(this->is_null())var=std::optional<TData>();
}else{
TData temp_var;
(*this)>>temp_var;
if(!this->is_null())var.emplace(std::move(temp_var));
}
return *this;
}
#else
template<OTL_TYPE_NAME TData, template <OTL_TYPE_NAME> class Optional>
otl_stream& operator<<(const Optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if(var)
(*this)<<(*var);
else
(*this)<<otl_null();
return *this;
}
template<OTL_TYPE_NAME TData, template <OTL_TYPE_NAME> class Optional>
otl_stream& operator>>(Optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if(var){
(*this)>>(*var);
if(this->is_null())var=Optional<TData>();
}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<const size_t N>
otl_stream &operator>>(std::array<char,N>& 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<char,...>&");
#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<char,...>&");
#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<char,...>&")
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<const size_t N>
otl_stream &operator>>(std::array<char16_t,N>& 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<char16_t,...>&");
#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<char16_t,...>&");
#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<char16_t,...>&")
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>><OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(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>><OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(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>><OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(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>><OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(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>><OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(l);
#endif
}
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*io)->operator>>(l);
#else
(*io)->operator>><OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(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>><OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(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>><OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(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>><OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(l);
#endif
}
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*io)->operator>>(l);
#else
(*io)->operator>><OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(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>><OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(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>><OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(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>><OTL_BIGINT, otl_var_bigint>(l);
#endif
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*io)->operator>>(l);
#else
(*io)->operator>><OTL_BIGINT, otl_var_bigint>(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>><OTL_BIGINT, otl_var_bigint>(l);
#endif
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*ss)->operator>>(l);
#else
(*ss)->operator>><OTL_BIGINT, otl_var_bigint>(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>><OTL_UBIGINT, otl_var_ubigint>(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>><OTL_UBIGINT, otl_var_ubigint>(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<const size_t N>
otl_stream &operator<<(const std::array<char,N>& s) OTL_THROWS_OTL_EXCEPTION {
last_oper_was_read_op = false;
reset_end_marker();
OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array<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_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED) && defined(OTL_UNICODE)
template<const size_t N>
otl_stream &operator<<(const std::array<char16_t,N>& s) OTL_THROWS_OTL_EXCEPTION {
last_oper_was_read_op = false;
reset_end_marker();
OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array<char16_t,...>&");
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<<<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(n);
#endif
}
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*io)->operator<<(n);
#else
(*io)->operator<<<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(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<<<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(n);
#endif
#endif
}
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*ss)->operator<<(n);
#else
(*ss)->operator<<<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(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<<<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(n);
#endif
}
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*io)->operator<<(n);
#else
(*io)->operator<<<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(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<<<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(n);
#endif
}
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*ss)->operator<<(n);
#else
(*ss)->operator<<<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(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<<<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(n);
#endif
}
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*io)->operator<<(n);
#else
(*io)->operator<<<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(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<<<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(n);
#endif
}
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*ss)->operator<<(n);
#else
(*ss)->operator<<<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(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<<<OTL_BIGINT, otl_var_bigint>(n);
#endif
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*io)->operator<<(n);
#else
(*io)->operator<<<OTL_BIGINT, otl_var_bigint>(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<<<OTL_BIGINT, otl_var_bigint>(n);
#endif
}
}
#else
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*ss)->operator<<(n);
#else
(*ss)->operator<<<OTL_BIGINT, otl_var_bigint>(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<<<OTL_UBIGINT, otl_var_ubigint>(n);
#endif
break;
case otl_odbc_select_stream:
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*ss)->operator<<(n);
#else
(*ss)->operator<<<OTL_UBIGINT, otl_var_ubigint>(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 <OTL_TYPE_NAME TData>
inline otl_stream &operator<<(otl_stream &s,
const otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if (var.is_null())
s << otl_null();
else
s << var.v;
return s;
}
template <OTL_TYPE_NAME TData, const TData null_value>
inline otl_stream &operator<<
(otl_stream &s,
const otl_compact_value<TData,null_value> &var) OTL_THROWS_OTL_EXCEPTION {
if (var.is_null())
s << otl_null();
else
s << var.v;
return s;
}
template <OTL_TYPE_NAME TData>
inline otl_stream &operator>>(otl_stream &s,
otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
s>>var.v;
if(s.is_null())
var.set_null(true);
else
var.set_null(false);
return s;
}
template <OTL_TYPE_NAME TData, const TData null_value>
inline otl_stream &operator>>
(otl_stream &s,
otl_compact_value<TData,null_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 <oci.h>
#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 <sql2oci.h>
}
#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 *, &paramp),
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<int> eleminfo;
STD_NAMESPACE_PREFIX vector<double> 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**,&timestamp[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 **, &timestamp[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<boolean> exists(OTL_SCAST(size_t, nElems));
std::vector<OCINumber*> 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<boolean> exists(OTL_SCAST(size_t,nOrds));
std::vector<OCINumber*> 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<v.array_size;i++){
#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
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_exc, otl_conn, otl_cur> otl_ora8_connect;
typedef otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var> otl_cursor;
template <OTL_TYPE_NAME TExceptionStruct, OTL_TYPE_NAME TConnectStruct,
OTL_TYPE_NAME TCursorStruct, OTL_TYPE_NAME TVariableStruct>
class otl_tmpl_lob_stream : public otl_lob_stream_generic {
public:
typedef otl_tmpl_exception<TExceptionStruct, TConnectStruct, TCursorStruct>
otl_exception;
typedef otl_tmpl_variable<TVariableStruct> *p_bind_var;
typedef otl_tmpl_connect<TExceptionStruct, TConnectStruct, TCursorStruct> *
p_connect;
typedef otl_tmpl_cursor<TExceptionStruct, TConnectStruct, TCursorStruct,
TVariableStruct> *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<TExceptionStruct, TConnectStruct, TCursorStruct>(
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<TExceptionStruct, TConnectStruct, TCursorStruct>(
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<TExceptionStruct, TConnectStruct, TCursorStruct>
(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<TExceptionStruct, TConnectStruct, TCursorStruct>(
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<TExceptionStruct, TConnectStruct, TCursorStruct>
(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<TExceptionStruct, TConnectStruct, TCursorStruct>(
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<TExceptionStruct, TConnectStruct,
TCursorStruct>(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_exc, otl_conn, otl_cur, otl_var> otl_lob_stream;
typedef otl_tmpl_exception<otl_exc, otl_conn, otl_cur> otl_exception;
typedef otl_tmpl_inout_stream<otl_exc, otl_conn, otl_cur, otl_var, otl_time0>
otl_ora8_inout_stream;
typedef otl_tmpl_select_stream<otl_exc, otl_conn, otl_cur, otl_var, otl_sel,
otl_time0> otl_select_stream;
typedef otl_tmpl_ext_hv_decl<otl_var, otl_time0, otl_exc, otl_conn, otl_cur>
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_var> otl_generic_variable;
typedef otl_generic_variable *otl_p_generic_variable;
class otl_refcur_base_cursor
: public otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var> {
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<otl_exc, otl_conn, otl_cur, otl_var>(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<otl_exc, otl_conn, otl_cur, otl_var>(), 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<otl_exc, otl_conn, otl_cur, otl_var>::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<otl_exc, otl_conn, otl_cur, otl_var>::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<otl_exc, otl_conn, otl_cur, otl_var>::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<otl_exc, otl_conn, otl_cur, otl_var>(), 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<otl_exc, otl_conn, otl_cur, otl_var>(), 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<unsigned char> 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<const size_t N>
OTL_ORA_REFCUR_COMMON_READ_STREAM &
operator>>(std::array<char,N>& s) OTL_THROWS_OTL_EXCEPTION {
check_if_executed();
if (eof_intern())
return *this;
get_next();
if (check_type(otl_var_char) && !eof_intern()) {
if(N<sl[cur_col].get_len(cur_row))
OTL_THROW((otl_exception(otl_error_msg_45,
otl_error_code_45,
this->get_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<const size_t N>
OTL_ORA_REFCUR_COMMON_READ_STREAM &
operator>>(std::array<char16_t,N>& s) OTL_THROWS_OTL_EXCEPTION {
check_if_executed();
if (eof_intern())
return *this;
get_next();
if (check_type(otl_var_char) && !eof_intern()) {
if(N<sl[cur_col].get_len(cur_row))
OTL_THROW((otl_exception(otl_error_msg_46,
otl_error_code_46,
this->get_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<otl_column_desc> 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<const size_t N>
otl_inout_stream &operator>>(std::array<char,N>& s) {
otl_ora8_inout_stream::getString(s.data(),OTL_SCAST(int,s.size()));
return *this;
}
template<const size_t N>
otl_inout_stream &operator<<(const std::array<char,N>& 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<const size_t N>
otl_inout_stream &operator>>(std::array<char16_t,N>& s) {
otl_ora8_inout_stream::getString(s.data(),OTL_SCAST(int,s.size()));
return *this;
}
template<const size_t N>
otl_inout_stream &operator<<(const std::array<char16_t,N>& 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>><OTL_BIGINT, otl_var_bigint>(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>><OTL_UBIGINT, otl_var_ubigint>(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>><int, otl_var_int>(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<<<OTL_BIGINT, otl_var_bigint>(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<<<OTL_UBIGINT, otl_var_ubigint>(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<<<int, otl_var_int>(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>><float, otl_var_float>(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<<<float, otl_var_float>(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>><double, otl_var_double>(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<<<double, otl_var_double>(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>><short, otl_var_short>(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<<<short, otl_var_short>(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>><unsigned, otl_var_unsigned_int>(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<<<unsigned, otl_var_unsigned_int>(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>><long, otl_var_long_int>(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<<<long, otl_var_long_int>(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<otl_exc, otl_conn, otl_cur, otl_var> {
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<otl_exc, otl_conn, otl_cur, otl_var>(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<otl_exc, otl_conn, otl_cur, otl_var>(), 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<otl_exc, otl_conn, otl_cur, otl_var>::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<otl_exc, otl_conn, otl_cur, otl_var>::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<otl_exc, otl_conn, otl_cur, otl_var>::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<otl_exc, otl_conn, otl_cur, otl_var>::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<otl_exc, otl_conn, otl_cur, otl_var>::bind(v);
}
void bind(const char *name, otl_generic_variable &v) {
otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::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<otl_exc, otl_conn, otl_cur, otl_var>(), 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<otl_exc, otl_conn, otl_cur, otl_var>(), 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<unsigned char> 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<const size_t N>
otl_ref_select_stream &operator>>(std::array<char,N>& s) {
check_if_executed();
if (eof_intern())
return *this;
get_next();
if (check_type(otl_var_char) && !eof_intern()) {
if(OTL_SCAST(int,N)<sl[cur_col].get_len(cur_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_exception(otl_error_msg_45,
otl_error_code_45,
this->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<const size_t N>
otl_ref_select_stream &operator<<(const std::array<char,N>& s){
(*this)<<s.data();
return *this;
}
#endif
#if defined(OTL_UNICODE_STRING_TYPE)
otl_ref_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_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<unsigned short> 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<const size_t N>
otl_ref_select_stream &operator>>(std::array<char16_t,N>& s) {
check_if_executed();
if (eof_intern())
return *this;
get_next();
if (check_type(otl_var_char) && !eof_intern()) {
if(OTL_SCAST(int,N)<sl[cur_col].get_len(cur_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_exception(otl_error_msg_46,
otl_error_code_46,
this->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<T, T_type>( \
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_TYPE_NAME T,const int T_type> 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<const size_t N>
otl_ref_select_stream &operator<<(const std::array<char16_t,N>& s){
(*this)<<OTL_RCAST(unsigned char*,OTL_CCAST(char16_t*,s.data()));
return *this;
}
#endif
#if defined(OTL_ORA_SDO_GEOMETRY)
otl_ref_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){
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_TYPE_NAME T, const int T_type>
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<otl_column_desc> 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<otl_exc, otl_conn, otl_cur, otl_var>::bind(*vl[i]);
// Executing the PLSQL master block
otl_tmpl_cursor<otl_exc, otl_conn, otl_cur, otl_var>::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 <array>
#endif
#if defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
#include <array>
#endif
#if defined(OTL_STREAM_WITH_STD_OPTIONAL_ON) && defined(OTL_COMPILER_HAS_STD_OPTIONAL)
#include <optional>
#endif
#if defined(OTL_STREAM_WITH_STD_SPAN_ON) && defined(OTL_CPP_20_ON)
#include <span>
#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<otl_stream_shell> 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<char[50]>) "
" and (:pkg_name<char[50]> 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<char[50]> 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<otl_Tptr<otl_sp_parm_desc> > 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<char[50]>) "
" 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<char[50]>) "
" and procedure_name is null "
" and object_type='PROCEDURE' "
" AND owner=UPPER(:owner<char[50]>) "
"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<typename...T>
otl_stream& operator<<(const std::tuple<T...>& t){
otl_tuple_helper<otl_stream,decltype(t),sizeof...(T)>::write(*this,t);
return (*this);
}
template<typename...T>
otl_stream& operator>>(std::tuple<T...>& t){
otl_tuple_helper<otl_stream,decltype(t),sizeof...(T)>::read(*this,t);
return (*this);
}
#endif
#if defined(OTL_STREAM_WITH_STD_SPAN_ON) && defined(OTL_CPP_20_ON)
public:
template<typename T>
otl_stream& operator<<(std::span<T> v){
for(const auto& e: v){
(*this)<<e;
}
return *this;
}
#endif
#if defined(OTL_STREAM_WITH_STD_VARIANT_ON) && defined(OTL_CPP_17_ON)
public:
template<typename...T>
otl_stream& operator<<(const std::variant<T...>& v){
bool value_written=false;
otl_variant_helper<otl_stream,sizeof...(T),std::variant<T...>>
::write(*this,v,value_written);
return (*this);
}
template<typename...T>
otl_stream& operator>>(std::variant<T...>& v){
bool value_read=false;
otl_variant_helper<otl_stream,sizeof...(T),std::variant<T...>>
::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_TYPE_NAME TData>
otl_stream& operator<<(const std::optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if(var)
(*this)<<(*var);
else
(*this)<<otl_null();
return *this;
}
template<OTL_TYPE_NAME TData>
otl_stream& operator>>(std::optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if(var){
(*this)>>(*var);
if(this->is_null())var=std::optional<TData>();
}else{
TData temp_var;
(*this)>>temp_var;
if(!this->is_null())var.emplace(std::move(temp_var));
}
return *this;
}
#else
template<OTL_TYPE_NAME TData, template <OTL_TYPE_NAME> class Optional>
otl_stream& operator<<(const Optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if(var)
(*this)<<(*var);
else
(*this)<<otl_null();
return *this;
}
template<OTL_TYPE_NAME TData, template <OTL_TYPE_NAME> class Optional>
otl_stream& operator>>(Optional<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if(var){
(*this)>>(*var);
if(this->is_null())var=Optional<TData>();
}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<const size_t N>
OTL_ORA_COMMON_READ_STREAM &operator>>(std::array<char,N>& 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<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, "std::array<char,...>&");
#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<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 >>", "std::array<char,...>&")
inc_next_ov();
return *this;
}
template<const size_t N>
otl_stream &operator<<(const std::array<char,N>& s) OTL_THROWS_OTL_EXCEPTION {
last_oper_was_read_op = false;
reset_end_marker();
OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array<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
#if defined(OTL_UNICODE) && defined(OTL_STREAM_WITH_STD_UNICODE_CHAR_ARRAY_ON) && defined(OTL_ANSI_CPP_11_ARRAY_IS_SUPPORTED)
template<const size_t N>
OTL_ORA_COMMON_READ_STREAM &operator>>(std::array<char16_t,N>& 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<char16_t,...>&");
#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<char16_t,...>&");
#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<char16_t,...>&");
#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<char16_t,...>&")
inc_next_ov();
return *this;
}
template<const size_t N>
otl_stream &operator<<(const std::array<char16_t,N>& s) OTL_THROWS_OTL_EXCEPTION {
last_oper_was_read_op = false;
reset_end_marker();
OTL_TRACE_READ("\"" << s << "\"", "operator <<", "std::array<char16_t,...>&");
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>><OTL_BIGINT, otl_var_bigint>(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>><OTL_BIGINT, otl_var_bigint>(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>><OTL_UBIGINT, otl_var_ubigint>(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>><OTL_UBIGINT, otl_var_ubigint>(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<<<OTL_BIGINT, otl_var_bigint>(n);
#endif
break;
case otl_refcur_stream_type:
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*ref_ss)->operator<<(n);
#else
(*ref_ss)->operator<<<OTL_BIGINT, otl_var_bigint>(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<<<OTL_UBIGINT, otl_var_ubigint>(n);
#endif
break;
case otl_refcur_stream_type:
#if defined(OTL_NO_TMPL_MEMBER_FUNC_SUPPORT)
(*ref_ss)->operator<<(n);
#else
(*ref_ss)->operator<<<OTL_UBIGINT, otl_var_ubigint>(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<int> 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, &notify_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 <OTL_TYPE_NAME TData>
inline otl_stream &operator<<(otl_stream &s,
const otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
if (var.is_null())
s << otl_null();
else
s << var.v;
return s;
}
template <OTL_TYPE_NAME TData>
inline otl_stream &operator>>(otl_stream &s,
otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
s >> var.v;
if(s.is_null())
var.set_null(true);
else
var.set_null(false);
return s;
}
template <OTL_TYPE_NAME TData>
inline otl_refcur_stream &operator>>(otl_refcur_stream &s,
otl_value<TData> &var) OTL_THROWS_OTL_EXCEPTION {
s >> var.v;
if(s.is_null())
var.set_null(true);
else
var.set_null(false);
return s;
}
template <OTL_TYPE_NAME TData, const TData null_value>
inline otl_stream &operator<<
(otl_stream &s,
const otl_compact_value<TData,null_value> &var) OTL_THROWS_OTL_EXCEPTION {
if (var.is_null())
s << otl_null();
else
s << var.v;
return s;
}
template <OTL_TYPE_NAME TData, const TData null_value>
inline otl_stream &operator>>
(otl_stream &s,
otl_compact_value<TData,null_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 <OTL_TYPE_NAME TData, const TData null_value>
inline otl_refcur_stream &operator>>
(otl_refcur_stream &s,
otl_compact_value<TData,null_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_stream, otl_connect, otl_exception>
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 <OTL_TYPE_NAME T> \
struct _Is_checked_helper< \
namespace_name otl_output_iterator<T> > : \
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 \
<STD_NAMESPACE_PREFIX input_iterator_tag, \
T,Distance,T*,T&>
#define STL_OUTPUT_ITERATOR_TO_DERIVE_FROM \
: public STD_NAMESPACE_PREFIX iterator \
<STD_NAMESPACE_PREFIX output_iterator_tag, \
T,void,void,void>
#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 <OTL_TYPE_NAME T, OTL_TYPE_NAME OTL_ITER_DISTANCE> \
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<T, Distance> &operator++() { \
read(); \
return *this; \
} \
\
otl_input_iterator<T, Distance> operator++(int) { \
otl_input_iterator<T, Distance> 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 <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
inline STD_NAMESPACE_PREFIX input_iterator_tag \
iterator_category(const otl_input_iterator<T, Distance> &) { \
return STD_NAMESPACE_PREFIX input_iterator_tag(); \
} \
template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
inline T *value_type(const otl_input_iterator<T, Distance> &) { \
return nullptr; \
} \
template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
inline Distance *distance_type(const otl_input_iterator<T, Distance> &) { \
return nullptr; \
} \
template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
bool operator==(const otl_input_iterator<T, Distance> &x, \
const otl_input_iterator<T, Distance> &y) { \
return (x.stream == y.stream && x.end_marker == y.end_marker) || \
(x.end_marker == -1 && y.end_marker == -1); \
} \
template <OTL_TYPE_NAME T, OTL_TYPE_NAME Distance> \
bool operator!=(const otl_input_iterator<T, Distance> &x, \
const otl_input_iterator<T, Distance> &y) { \
return !(x == y); \
} \
template <OTL_TYPE_NAME T> \
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<T> &operator=(const T &value) { \
*stream << value; \
return *this; \
} \
otl_output_iterator<T> &operator*() { return *this; } \
otl_output_iterator<T> &operator++() { return *this; } \
otl_output_iterator<T> operator++(int) { return *this; } \
};
#define OTL_ITERATOR_TAG(namespace_name) \
template <OTL_TYPE_NAME T> \
inline STD_NAMESPACE_PREFIX output_iterator_tag \
iterator_category(const namespace_name otl_output_iterator<T> &) { \
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 <map>
#endif
#if defined(OTL_ACE)
#include <ace/SString.h>
#include <ace/Array.h>
#include <ace/Functor.h>
#include <ace/RB_Tree.h>
#include <ace/Null_Mutex.h>
#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 OTLStream,
class OTLException,
class OTLLobStream>
class otl_stream_read_iterator;
template <OTL_TYPE_NAME OTLStream,
OTL_TYPE_NAME OTLException,
OTL_TYPE_NAME OTLLobStream>
class otl_for_range_loop_adapter{
public:
typedef otl_stream_read_iterator<OTLStream,OTLException,OTLLobStream> 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 <OTL_TYPE_NAME OTLStream, OTL_TYPE_NAME OTLException,
OTL_TYPE_NAME OTLLobStream>
class otl_stream_read_iterator {
public:
#if defined(OTL_ANSI_CPP_11_RVAL_REF_SUPPORT)
typedef otl_for_range_loop_adapter<OTLStream,OTLException,OTLLobStream> 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<unsigned, otl_var_unsigned_int>(
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<int, otl_var_int>(
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<short, otl_var_short>(
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<long int, otl_var_long_int>(
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<float, otl_var_float>(
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<double, otl_var_double>(
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<OTL_NUMERIC_TYPE_1, otl_var_numeric_type_1>(
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<OTL_NUMERIC_TYPE_2, otl_var_numeric_type_2>(
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<OTL_NUMERIC_TYPE_3, otl_var_numeric_type_3>(
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<OTL_BIGINT, otl_var_bigint>(
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<OTL_UBIGINT, otl_var_ubigint>(
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<const char *, int, otl_ltcharstar>
var_name2pos_map_type;
var_name2pos_map_type var_name2pos_map_;
#endif
#if defined(OTL_ACE)
typedef ACE_RB_Tree<const char *, int, otl_ltcharstar, ACE_Null_Mutex>
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 <OTL_TYPE_NAME OTLStreamType, OTL_TYPE_NAME OutputIterator>
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 <OTL_TYPE_NAME OTLStreamType, OTL_TYPE_NAME InputIterator>
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<typename OTLStreamType, typename Arg1, typename...Args>
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<typename OTLStreamType, typename Arg1, typename... Args>
inline void otl_write_row(OTLStreamType &s, Arg1&& arg1, Args&&...args) OTL_THROWS_OTL_EXCEPTION {
s<<std::forward<Arg1>(arg1);
if constexpr(sizeof...(args)>0) (s<<...<<std::forward<Args>(args));
s.check_end_of_row();
}
#else
template <typename OTLStreamType>
inline void __otl_read_row(OTLStreamType &s) OTL_THROWS_OTL_EXCEPTION {
s.check_end_of_row();
}
template <typename OTLStreamType, typename Arg1, typename... Args>
inline void __otl_read_row(OTLStreamType &s, Arg1 &arg1,
Args &... args) OTL_THROWS_OTL_EXCEPTION {
s >> arg1;
__otl_read_row(s, args...);
}
template <typename OTLStreamType, typename Arg1, typename... Args>
inline void otl_read_row(OTLStreamType &s, Arg1 &arg1,
Args &... args) OTL_THROWS_OTL_EXCEPTION {
s >> arg1;
__otl_read_row(s, args...);
}
template <typename OTLStreamType>
inline void __otl_write_row(OTLStreamType &s) OTL_THROWS_OTL_EXCEPTION {
s.check_end_of_row();
}
template <typename OTLStreamType, typename Arg1, typename... Args>
inline void __otl_write_row(OTLStreamType &s, Arg1 &&arg1,
Args &&... args) OTL_THROWS_OTL_EXCEPTION {
s << std::forward<Arg1>(arg1);
__otl_write_row(s, std::forward<Args>(args)...);
}
template <typename OTLStreamType, typename Arg1, typename... Args>
inline void otl_write_row(OTLStreamType &s, Arg1 &&arg1,
Args &&... args) OTL_THROWS_OTL_EXCEPTION {
s << std::forward<Arg1>(arg1);
__otl_write_row(s, std::forward<Args>(args)...);
}
#endif
#else
template <typename S, typename T1>
inline void otl_read_row(S &s, T1 &t1) OTL_THROWS_OTL_EXCEPTION {
s >> t1;
s.check_end_of_row();
}
template <typename S, typename T1, typename T2>
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 <typename S, typename T1, typename T2, typename T3>
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 <typename S, typename T1, typename T2, typename T3, typename T4>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13, typename T14>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13, typename T14,
typename T15>
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 <typename S, typename T1>
inline void otl_write_row(S &s, T1 &&t1) OTL_THROWS_OTL_EXCEPTION {
s << std::forward<T1>(t1);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2>
inline void otl_write_row(S &s, T1 &&t1, T2 &&t2) OTL_THROWS_OTL_EXCEPTION {
s << std::forward<T1>(t1);
s << std::forward<T2>(t2);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3>
inline void otl_write_row(S &s, T1 &&t1, T2 &&t2,
T3 &&t3) OTL_THROWS_OTL_EXCEPTION {
s << std::forward<T1>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4>
inline void otl_write_row(S &s, T1 &&t1, T2 &&t2, T3 &&t3,
T4 &&t4) OTL_THROWS_OTL_EXCEPTION {
s << std::forward<T1>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s << std::forward<T8>(t8);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s << std::forward<T8>(t8);
s << std::forward<T9>(t9);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s << std::forward<T8>(t8);
s << std::forward<T9>(t9);
s << std::forward<T10>(t10);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s << std::forward<T8>(t8);
s << std::forward<T9>(t9);
s << std::forward<T10>(t10);
s << std::forward<T11>(t11);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s << std::forward<T8>(t8);
s << std::forward<T9>(t9);
s << std::forward<T10>(t10);
s << std::forward<T11>(t11);
s << std::forward<T12>(t12);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s << std::forward<T8>(t8);
s << std::forward<T9>(t9);
s << std::forward<T10>(t10);
s << std::forward<T11>(t11);
s << std::forward<T12>(t12);
s << std::forward<T13>(t13);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13, typename T14>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s << std::forward<T8>(t8);
s << std::forward<T9>(t9);
s << std::forward<T10>(t10);
s << std::forward<T11>(t11);
s << std::forward<T12>(t12);
s << std::forward<T13>(t13);
s << std::forward<T14>(t14);
s.check_end_of_row();
}
template <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13, typename T14,
typename T15>
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>(t1);
s << std::forward<T2>(t2);
s << std::forward<T3>(t3);
s << std::forward<T4>(t4);
s << std::forward<T5>(t5);
s << std::forward<T6>(t6);
s << std::forward<T7>(t7);
s << std::forward<T8>(t8);
s << std::forward<T9>(t9);
s << std::forward<T10>(t10);
s << std::forward<T11>(t11);
s << std::forward<T12>(t12);
s << std::forward<T13>(t13);
s << std::forward<T14>(t14);
s << std::forward<T15>(t15);
s.check_end_of_row();
}
#else
template <typename S, typename T1>
inline void otl_write_row(S &s, T1 &t1) OTL_THROWS_OTL_EXCEPTION {
s << t1;
s.check_end_of_row();
}
template <typename S, typename T1, typename T2>
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 <typename S, typename T1, typename T2, typename T3>
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 <typename S, typename T1, typename T2, typename T3, typename T4>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13, typename T14>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13, typename T14,
typename T15>
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 <typename S, typename T1>
inline void otl_write_row(S &s, const T1 &t1) OTL_THROWS_OTL_EXCEPTION {
s << t1;
s.check_end_of_row();
}
template <typename S, typename T1, typename T2>
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 <typename S, typename T1, typename T2, typename T3>
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 <typename S, typename T1, typename T2, typename T3, typename T4>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13, typename T14>
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 <typename S, typename T1, typename T2, typename T3, typename T4,
typename T5, typename T6, typename T7, typename T8, typename T9,
typename T10, typename T11, typename T12, typename T13, typename T14,
typename T15>
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 <mutex>
#include <memory>
#include <vector>
#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 OTLConnect, class OTLException>
class otl_connect_pool{
public:
typedef std::unique_ptr<OTLConnect> 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<min_pool_size_;++i){
#if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED)
pool_.push_back(std::make_unique<OTLConnect>());
#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<iters;
++i){
#if defined(OTL_MAKE_UNIQUE_IS_SUPPORTED)
pool_.push_back(std::make_unique<OTLConnect>());
#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<OTLException>(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()<max_pool_size_){
// if the pool is not filled up to its maximum size, add the
// object to the pool.
pool_.push_back(std::move(p));
--connects_in_use_;
return true;
}else
// pool is full, return false
return false;
}
// Shrink the pool to the new min_pool_size. This function can be
// called from a timer to reduce the number of idle database
// connections.
void shrink_pool(const size_t new_min_pool_size,
const bool ignore_errors=false) OTL_THROWS_OTL_EXCEPTION{
otl_recursive_mutex_guard guard(&mutex_);
if(!pool_open_)return;
if(pool_.size()<new_min_pool_size)
// if the pool size is already smaller than the specified
// minimum size, there is nothing to do, returning...
return;
exception_ptr ret_exc;
while(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<OTLException>(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){
max_pool_size_=new_max_pool_size;
}else 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<OTLException>(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<OTLException> 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<connect_ptr> pool_ OTL_GUARDED_BY(mutex_);
mutable otl_recursive_mutex mutex_;
};
#endif
#if defined(OTL_ORA_TEXT_ON) && defined(text)
#undef text
#endif
#endif