merge Data changes (ODBC Sybase, PostgreSQL etc)

This commit is contained in:
Alex Fabijanic 2016-02-28 11:06:08 -06:00
parent e84d50dfaa
commit 32f3f4a146
79 changed files with 3174 additions and 1545 deletions

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug_shared|Win32">
@ -32,7 +32,7 @@
<RootNamespace>Data</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
@ -63,27 +63,27 @@
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros"/>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|Win32'">PocoDatad</TargetName>
@ -125,17 +125,18 @@
<AdditionalIncludeDirectories>.\include;..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;Data_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>..\bin\PocoDatad.dll</OutputFile>
@ -163,9 +164,9 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
</ClCompile>
<Link>
@ -186,18 +187,19 @@
<AdditionalIncludeDirectories>.\include;..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<ProgramDataBaseFileName>..\lib\PocoDatamtd.pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib\PocoDatamtd.lib</OutputFile>
@ -218,9 +220,9 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
</ClCompile>
<Lib>
@ -233,18 +235,19 @@
<AdditionalIncludeDirectories>.\include;..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<ProgramDataBaseFileName>..\lib\PocoDatamdd.pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib\PocoDatamdd.lib</OutputFile>
@ -265,10 +268,10 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<ProgramDataBaseFileName>..\lib\PocoDatamd.pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
</ClCompile>
<Lib>
@ -365,6 +368,6 @@
<ClCompile Include="src\Time.cpp"/>
<ClCompile Include="src\Transaction.cpp"/>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug_shared|x64">
@ -32,7 +32,7 @@
<RootNamespace>Data</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
@ -63,27 +63,27 @@
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros"/>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">PocoData64d</TargetName>
@ -125,18 +125,19 @@
<AdditionalIncludeDirectories>.\include;..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;Data_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>..\bin64\PocoData64d.dll</OutputFile>
@ -164,11 +165,12 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<OutputFile>..\bin64\PocoData64.dll</OutputFile>
@ -188,19 +190,20 @@
<AdditionalIncludeDirectories>.\include;..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<ProgramDataBaseFileName>..\lib64\PocoDatamtd.pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib64\PocoDatamtd.lib</OutputFile>
@ -221,11 +224,12 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib64\PocoDatamt.lib</OutputFile>
@ -237,19 +241,20 @@
<AdditionalIncludeDirectories>.\include;..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<ProgramDataBaseFileName>..\lib64\PocoDatamdd.pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib64\PocoDatamdd.lib</OutputFile>
@ -270,11 +275,12 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<AdditionalOptions>/bigobj %(AdditionalOptions)</AdditionalOptions>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib64\PocoDatamd.lib</OutputFile>
@ -370,6 +376,6 @@
<ClCompile Include="src\Time.cpp"/>
<ClCompile Include="src\Transaction.cpp"/>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@ -42,71 +42,71 @@ public:
virtual ~Binder();
/// Destroys the Binder.
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int8.
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt8.
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int16.
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt16.
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int32.
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt32.
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int64.
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt64.
#ifndef POCO_LONG_IS_64_BIT
virtual void bind(std::size_t pos, const long& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const long& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a long.
virtual void bind(std::size_t pos, const unsigned long& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const unsigned long& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an unsigned long.
#endif // POCO_LONG_IS_64_BIT
virtual void bind(std::size_t pos, const bool& val, Direction dir);
virtual void bind(std::size_t pos, const bool& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a boolean.
virtual void bind(std::size_t pos, const float& val, Direction dir);
virtual void bind(std::size_t pos, const float& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a float.
virtual void bind(std::size_t pos, const double& val, Direction dir);
virtual void bind(std::size_t pos, const double& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a double.
virtual void bind(std::size_t pos, const char& val, Direction dir);
virtual void bind(std::size_t pos, const char& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a single character.
virtual void bind(std::size_t pos, const std::string& val, Direction dir);
virtual void bind(std::size_t pos, const std::string& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a string.
virtual void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a BLOB.
virtual void bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir);
virtual void bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a CLOB.
virtual void bind(std::size_t pos, const DateTime& val, Direction dir);
virtual void bind(std::size_t pos, const DateTime& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a DateTime.
virtual void bind(std::size_t pos, const Date& val, Direction dir);
virtual void bind(std::size_t pos, const Date& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a Date.
virtual void bind(std::size_t pos, const Time& val, Direction dir);
virtual void bind(std::size_t pos, const Time& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a Time.
virtual void bind(std::size_t pos, const NullData& val, Direction dir);
virtual void bind(std::size_t pos, const NullData& val, Direction dir, const std::type_info& bindType);
/// Binds a null.
@ -212,11 +212,11 @@ public:
virtual void bind(std::size_t pos, const std::list<Time>& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir, const std::type_info& bindType);
virtual void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir, const std::type_info& bindType);
virtual void bind(std::size_t pos, const std::list<NullData>& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const std::list<NullData>& val, Direction dir, const std::type_info& bindType);
virtual void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir = PD_IN);
@ -237,7 +237,7 @@ private:
Binder(const Binder&);
/// Don't copy the binder
virtual void bind(std::size_t, const char* const&, Direction)
virtual void bind(std::size_t, const char* const&, Direction, const WhenNullCb& )
/// Binds a const char ptr.
/// This is a private no-op in this implementation
/// due to security risk.

View File

@ -54,7 +54,7 @@ protected:
/// Returns the number of affected rows.
/// Used to find out the number of rows affected by insert, delete or update.
virtual const MetaColumn& metaColumn(std::size_t pos) const;
virtual const MetaColumn& metaColumn(std::size_t pos, std::size_t dataSet) const;
/// Returns column meta data.
virtual bool hasNext();

View File

@ -37,56 +37,56 @@ Binder::~Binder()
}
void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_TINY, &val, 0, true);
}
void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_SHORT, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_SHORT, &val, 0, true);
}
void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONG, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONG, &val, 0, true);
}
void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0);
}
void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONGLONG, &val, 0, true);
@ -95,14 +95,14 @@ void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
#ifndef POCO_LONG_IS_64_BIT
void Binder::bind(std::size_t pos, const long& val, Direction dir)
void Binder::bind(std::size_t pos, const long& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONG, &val, 0);
}
void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir)
void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_LONG, &val, 0, true);
@ -111,56 +111,56 @@ void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir)
#endif // POCO_LONG_IS_64_BIT
void Binder::bind(std::size_t pos, const bool& val, Direction dir)
void Binder::bind(std::size_t pos, const bool& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
}
void Binder::bind(std::size_t pos, const float& val, Direction dir)
void Binder::bind(std::size_t pos, const float& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_FLOAT, &val, 0);
}
void Binder::bind(std::size_t pos, const double& val, Direction dir)
void Binder::bind(std::size_t pos, const double& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_DOUBLE, &val, 0);
}
void Binder::bind(std::size_t pos, const char& val, Direction dir)
void Binder::bind(std::size_t pos, const char& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_TINY, &val, 0);
}
void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
void Binder::bind(std::size_t pos, const std::string& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_STRING, val.c_str(), static_cast<int>(val.length()));
}
void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_BLOB, val.rawContent(), static_cast<int>(val.size()));
}
void Binder::bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_BLOB, val.rawContent(), static_cast<int>(val.size()));
}
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
MYSQL_TIME mt = {0};
@ -181,7 +181,7 @@ void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
void Binder::bind(std::size_t pos, const Date& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
MYSQL_TIME mt = {0};
@ -198,7 +198,7 @@ void Binder::bind(std::size_t pos, const Date& val, Direction dir)
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
void Binder::bind(std::size_t pos, const Time& val, Direction dir, const WhenNullCb& nullCb)
{
poco_assert(dir == PD_IN);
MYSQL_TIME mt = {0};
@ -215,7 +215,7 @@ void Binder::bind(std::size_t pos, const Time& val, Direction dir)
}
void Binder::bind(std::size_t pos, const NullData&, Direction dir)
void Binder::bind(std::size_t pos, const NullData&, Direction dir, const std::type_info& bindType)
{
poco_assert(dir == PD_IN);
realBind(pos, MYSQL_TYPE_NULL, 0, 0);
@ -601,19 +601,19 @@ void Binder::bind(std::size_t pos, const std::list<Poco::Data::Time>& val, Direc
}
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::NullData>& val, Direction dir)
void Binder::bind(std::size_t pos, const std::vector<Poco::Data::NullData>& val, Direction dir, const std::type_info& bindType)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::NullData>& val, Direction dir)
void Binder::bind(std::size_t pos, const std::deque<Poco::Data::NullData>& val, Direction dir, const std::type_info& bindType)
{
throw NotImplementedException();
}
void Binder::bind(std::size_t pos, const std::list<Poco::Data::NullData>& val, Direction dir)
void Binder::bind(std::size_t pos, const std::list<Poco::Data::NullData>& val, Direction dir, const std::type_info& bindType)
{
throw NotImplementedException();
}

View File

@ -48,8 +48,10 @@ int MySQLStatementImpl::affectedRowCount() const
}
const MetaColumn& MySQLStatementImpl::metaColumn(std::size_t pos) const
const MetaColumn& MySQLStatementImpl::metaColumn(std::size_t pos, std::size_t dataSet) const
{
// mysql doesn't support multiple result sets
poco_assert_dbg(dataSet == 0);
return _metadata.metaColumn(pos);
}

View File

@ -125,7 +125,8 @@
<AdditionalIncludeDirectories>.\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;THREADSAFE;ODBC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -188,7 +189,8 @@
<AdditionalIncludeDirectories>.\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -235,7 +237,8 @@
<AdditionalIncludeDirectories>.\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug_shared|x64">
@ -32,7 +32,7 @@
<RootNamespace>ODBC</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
@ -63,27 +63,27 @@
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros"/>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">PocoDataODBC64d</TargetName>
@ -125,17 +125,18 @@
<AdditionalIncludeDirectories>.\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;THREADSAFE;ODBC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -164,10 +165,11 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -188,18 +190,19 @@
<AdditionalIncludeDirectories>.\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<ProgramDataBaseFileName>..\..\lib64\PocoDataODBCmtd.pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\..\lib64\PocoDataODBCmtd.lib</OutputFile>
@ -220,10 +223,11 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\..\lib64\PocoDataODBCmt.lib</OutputFile>
@ -235,18 +239,19 @@
<AdditionalIncludeDirectories>.\include;..\..\Foundation\include;..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;THREADSAFE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<ProgramDataBaseFileName>..\..\lib64\PocoDataODBCmdd.pdb</ProgramDataBaseFileName>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\..\lib64\PocoDataODBCmdd.lib</OutputFile>
@ -267,51 +272,52 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\..\lib64\PocoDataODBCmd.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="include\Poco\Data\ODBC\Binder.h"/>
<ClInclude Include="include\Poco\Data\ODBC\ConnectionHandle.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Connector.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Diagnostics.h"/>
<ClInclude Include="include\Poco\Data\ODBC\EnvironmentHandle.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Error.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Extractor.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Handle.h"/>
<ClInclude Include="include\Poco\Data\ODBC\ODBC.h"/>
<ClInclude Include="include\Poco\Data\ODBC\ODBCException.h"/>
<ClInclude Include="include\Poco\Data\ODBC\ODBCMetaColumn.h"/>
<ClInclude Include="include\Poco\Data\ODBC\ODBCStatementImpl.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Parameter.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Preparator.h"/>
<ClInclude Include="include\Poco\Data\ODBC\SessionImpl.h"/>
<ClInclude Include="include\Poco\Data\ODBC\TypeInfo.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Unicode.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Unicode_UNIXODBC.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Unicode_WIN32.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Utility.h"/>
<ClInclude Include="include\Poco\Data\ODBC\Binder.h" />
<ClInclude Include="include\Poco\Data\ODBC\ConnectionHandle.h" />
<ClInclude Include="include\Poco\Data\ODBC\Connector.h" />
<ClInclude Include="include\Poco\Data\ODBC\Diagnostics.h" />
<ClInclude Include="include\Poco\Data\ODBC\EnvironmentHandle.h" />
<ClInclude Include="include\Poco\Data\ODBC\Error.h" />
<ClInclude Include="include\Poco\Data\ODBC\Extractor.h" />
<ClInclude Include="include\Poco\Data\ODBC\Handle.h" />
<ClInclude Include="include\Poco\Data\ODBC\ODBC.h" />
<ClInclude Include="include\Poco\Data\ODBC\ODBCException.h" />
<ClInclude Include="include\Poco\Data\ODBC\ODBCMetaColumn.h" />
<ClInclude Include="include\Poco\Data\ODBC\ODBCStatementImpl.h" />
<ClInclude Include="include\Poco\Data\ODBC\Parameter.h" />
<ClInclude Include="include\Poco\Data\ODBC\Preparator.h" />
<ClInclude Include="include\Poco\Data\ODBC\SessionImpl.h" />
<ClInclude Include="include\Poco\Data\ODBC\TypeInfo.h" />
<ClInclude Include="include\Poco\Data\ODBC\Unicode.h" />
<ClInclude Include="include\Poco\Data\ODBC\Unicode_UNIXODBC.h" />
<ClInclude Include="include\Poco\Data\ODBC\Unicode_WIN32.h" />
<ClInclude Include="include\Poco\Data\ODBC\Utility.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Binder.cpp"/>
<ClCompile Include="src\ConnectionHandle.cpp"/>
<ClCompile Include="src\Connector.cpp"/>
<ClCompile Include="src\EnvironmentHandle.cpp"/>
<ClCompile Include="src\Extractor.cpp"/>
<ClCompile Include="src\ODBCException.cpp"/>
<ClCompile Include="src\ODBCMetaColumn.cpp"/>
<ClCompile Include="src\ODBCStatementImpl.cpp"/>
<ClCompile Include="src\Parameter.cpp"/>
<ClCompile Include="src\Preparator.cpp"/>
<ClCompile Include="src\SessionImpl.cpp"/>
<ClCompile Include="src\TypeInfo.cpp"/>
<ClCompile Include="src\Unicode.cpp"/>
<ClCompile Include="src\Binder.cpp" />
<ClCompile Include="src\ConnectionHandle.cpp" />
<ClCompile Include="src\Connector.cpp" />
<ClCompile Include="src\EnvironmentHandle.cpp" />
<ClCompile Include="src\Extractor.cpp" />
<ClCompile Include="src\ODBCException.cpp" />
<ClCompile Include="src\ODBCMetaColumn.cpp" />
<ClCompile Include="src\ODBCStatementImpl.cpp" />
<ClCompile Include="src\Parameter.cpp" />
<ClCompile Include="src\Preparator.cpp" />
<ClCompile Include="src\SessionImpl.cpp" />
<ClCompile Include="src\TypeInfo.cpp" />
<ClCompile Include="src\Unicode.cpp" />
<ClCompile Include="src\Unicode_UNIXODBC.cpp">
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='debug_static_md|x64'">true</ExcludedFromBuild>
@ -328,8 +334,8 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'">true</ExcludedFromBuild>
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='release_static_mt|x64'">true</ExcludedFromBuild>
</ClCompile>
<ClCompile Include="src\Utility.cpp"/>
<ClCompile Include="src\Utility.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@ -58,12 +58,28 @@ namespace ODBC {
class ODBC_API Binder: public Poco::Data::AbstractBinder
/// Binds placeholders in the sql query to the provided values. Performs data types mapping.
{
struct ParamDescriptor
{
ParamDescriptor() : colSize(0), cDataType(0), decDigits(-1)
{}
ParamDescriptor(SQLINTEGER colSize_, SQLSMALLINT cDataType_, SQLSMALLINT decDigits_) : colSize(colSize_), cDataType(cDataType_), decDigits(decDigits_)
{}
bool defined() const { return cDataType != 0; }
SQLINTEGER colSize;
SQLSMALLINT cDataType;
SQLSMALLINT decDigits;
};
public:
typedef AbstractBinder::Direction Direction;
typedef std::map<SQLPOINTER, SQLLEN> ParamMap;
static const size_t DEFAULT_PARAM_SIZE = 1024;
enum ParameterBinding
{
PB_IMMEDIATE,
@ -72,14 +88,16 @@ public:
Binder(const StatementHandle& rStmt,
std::size_t maxFieldSize,
ParameterBinding dataBinding = PB_IMMEDIATE,
TypeInfo* pDataTypes = 0);
ParameterBinding dataBinding,
TypeInfo* pDataTypes,
ODBCMetaColumn::NumericConversion numericConversion,
bool insertOnly);
/// Creates the Binder.
~Binder();
/// Destroys the Binder.
void bind(std::size_t pos, const Poco::Int8& val, Direction dir);
void bind(std::size_t pos, const Poco::Int8& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int8.
void bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir);
@ -91,7 +109,7 @@ public:
void bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir);
/// Binds an Int8 list.
void bind(std::size_t pos, const Poco::UInt8& val, Direction dir);
void bind(std::size_t pos, const Poco::UInt8& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt8.
void bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir);
@ -103,7 +121,7 @@ public:
void bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir);
/// Binds an UInt8 list.
void bind(std::size_t pos, const Poco::Int16& val, Direction dir);
void bind(std::size_t pos, const Poco::Int16& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int16.
void bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir);
@ -115,7 +133,7 @@ public:
void bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir);
/// Binds an Int16 list.
void bind(std::size_t pos, const Poco::UInt16& val, Direction dir);
void bind(std::size_t pos, const Poco::UInt16& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt16.
void bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir);
@ -127,7 +145,7 @@ public:
void bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir);
/// Binds an UInt16 list.
void bind(std::size_t pos, const Poco::Int32& val, Direction dir);
void bind(std::size_t pos, const Poco::Int32& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int32.
void bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir);
@ -139,7 +157,7 @@ public:
void bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir);
/// Binds an Int32 list.
void bind(std::size_t pos, const Poco::UInt32& val, Direction dir);
void bind(std::size_t pos, const Poco::UInt32& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt32.
void bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir);
@ -151,7 +169,7 @@ public:
void bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir);
/// Binds an UInt32 list.
void bind(std::size_t pos, const Poco::Int64& val, Direction dir);
void bind(std::size_t pos, const Poco::Int64& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int64.
void bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir);
@ -163,7 +181,7 @@ public:
void bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir);
/// Binds an Int64 list.
void bind(std::size_t pos, const Poco::UInt64& val, Direction dir);
void bind(std::size_t pos, const Poco::UInt64& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt64.
void bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir);
@ -176,10 +194,10 @@ public:
/// Binds an UInt64 list.
#ifndef POCO_LONG_IS_64_BIT
void bind(std::size_t pos, const long& val, Direction dir);
void bind(std::size_t pos, const long& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a long.
void bind(std::size_t pos, const unsigned long& val, Direction dir);
void bind(std::size_t pos, const unsigned long& val, Direction dir, const WhenNullCb& nullCb);
/// Binds an unsigned long.
void bind(std::size_t pos, const std::vector<long>& val, Direction dir);
@ -192,7 +210,7 @@ public:
/// Binds a long list.
#endif
void bind(std::size_t pos, const bool& val, Direction dir);
void bind(std::size_t pos, const bool& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a boolean.
void bind(std::size_t pos, const std::vector<bool>& val, Direction dir);
@ -204,7 +222,7 @@ public:
void bind(std::size_t pos, const std::list<bool>& val, Direction dir);
/// Binds a boolean list.
void bind(std::size_t pos, const float& val, Direction dir);
void bind(std::size_t pos, const float& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a float.
void bind(std::size_t pos, const std::vector<float>& val, Direction dir);
@ -216,7 +234,7 @@ public:
void bind(std::size_t pos, const std::list<float>& val, Direction dir);
/// Binds a float list.
void bind(std::size_t pos, const double& val, Direction dir);
void bind(std::size_t pos, const double& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a double.
void bind(std::size_t pos, const std::vector<double>& val, Direction dir);
@ -228,7 +246,7 @@ public:
void bind(std::size_t pos, const std::list<double>& val, Direction dir);
/// Binds a double list.
void bind(std::size_t pos, const char& val, Direction dir);
void bind(std::size_t pos, const char& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a single character.
void bind(std::size_t pos, const std::vector<char>& val, Direction dir);
@ -240,7 +258,7 @@ public:
void bind(std::size_t pos, const std::list<char>& val, Direction dir);
/// Binds a character list.
void bind(std::size_t pos, const std::string& val, Direction dir);
void bind(std::size_t pos, const std::string& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a string.
void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir);
@ -252,7 +270,7 @@ public:
void bind(std::size_t pos, const std::list<std::string>& val, Direction dir);
/// Binds a string list.
void bind(std::size_t pos, const UTF16String& val, Direction dir);
void bind(std::size_t pos, const UTF16String& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a string.
void bind(std::size_t pos, const std::vector<UTF16String>& val, Direction dir);
@ -264,10 +282,10 @@ public:
void bind(std::size_t pos, const std::list<UTF16String>& val, Direction dir);
/// Binds a string list.
void bind(std::size_t pos, const BLOB& val, Direction dir);
void bind(std::size_t pos, const BLOB& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a BLOB. In-bound only.
void bind(std::size_t pos, const CLOB& val, Direction dir);
void bind(std::size_t pos, const CLOB& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a CLOB. In-bound only.
void bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir);
@ -288,7 +306,7 @@ public:
void bind(std::size_t pos, const std::list<CLOB>& val, Direction dir);
/// Binds a CLOB list.
void bind(std::size_t pos, const Date& val, Direction dir);
void bind(std::size_t pos, const Date& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a Date.
void bind(std::size_t pos, const std::vector<Date>& val, Direction dir);
@ -300,7 +318,7 @@ public:
void bind(std::size_t pos, const std::list<Date>& val, Direction dir);
/// Binds a Date list.
void bind(std::size_t pos, const Time& val, Direction dir);
void bind(std::size_t pos, const Time& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a Time.
void bind(std::size_t pos, const std::vector<Time>& val, Direction dir);
@ -312,7 +330,7 @@ public:
void bind(std::size_t pos, const std::list<Time>& val, Direction dir);
/// Binds a Time list.
void bind(std::size_t pos, const DateTime& val, Direction dir);
void bind(std::size_t pos, const DateTime& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a DateTime.
void bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir);
@ -324,16 +342,16 @@ public:
void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir);
/// Binds a DateTime list.
void bind(std::size_t pos, const NullData& val, Direction dir);
void bind(std::size_t pos, const NullData& val, Direction dir, const std::type_info& bindType);
/// Binds a null. In-bound only.
void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir);
void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir, const std::type_info& bindType);
/// Binds a null vector.
void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir);
void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir, const std::type_info& bindType);
/// Binds a null deque.
void bind(std::size_t pos, const std::list<NullData>& val, Direction dir);
void bind(std::size_t pos, const std::list<NullData>& val, Direction dir, const std::type_info& bindType);
/// Binds a null list.
void setDataBinding(ParameterBinding binding);
@ -353,6 +371,7 @@ public:
/// Clears the cached storage.
private:
typedef std::vector<ParamDescriptor> ParameterInfoVec;
typedef std::vector<SQLLEN*> LengthPtrVec;
typedef std::vector<SQLLEN> LengthVec;
typedef std::vector<LengthVec*> LengthVecVec;
@ -365,18 +384,19 @@ private:
typedef std::vector<TimeVec*> TimeVecVec;
typedef std::vector<SQL_TIMESTAMP_STRUCT> DateTimeVec;
typedef std::vector<DateTimeVec*> DateTimeVecVec;
typedef std::vector<Poco::Any> AnyVec;
typedef std::vector<AnyVec> AnyVecVec;
typedef std::vector<Poco::Any*> AnyPtrVec;
typedef std::vector<AnyPtrVec> AnyPtrVecVec;
typedef std::map<char*, std::string*> StringMap;
typedef std::map<UTF16String::value_type*, UTF16String*> UTF16StringMap;
typedef std::map<SQL_DATE_STRUCT*, Date*> DateMap;
typedef std::map<SQL_TIME_STRUCT*, Time*> TimeMap;
typedef std::map<SQL_TIMESTAMP_STRUCT*, DateTime*> TimestampMap;
typedef std::map<SQLLEN*, WhenNullCb> NullCbMap;
void describeParameter(std::size_t pos);
/// Sets the description field for the parameter, if needed.
void bind(std::size_t pos, const char* const& pVal, Direction dir);
void bind(std::size_t pos, const char* const& pVal, Direction dir, const WhenNullCb& nullCb);
/// Binds a const char ptr.
/// This is a private no-op in this implementation
/// due to security risk.
@ -386,13 +406,19 @@ private:
/// specified by user.
template <typename T>
void bindImpl(std::size_t pos, T& val, SQLSMALLINT cDataType, Direction dir)
void bindImpl(std::size_t pos, T& val, SQLSMALLINT cDataType, Direction dir, const WhenNullCb& nullCb)
{
SQLINTEGER colSize = 0;
SQLSMALLINT decDigits = 0;
getColSizeAndPrecision(pos, cDataType, colSize, decDigits);
_lengthIndicator.push_back(0);
SQLLEN* pLenIn = NULL;
if (isOutBound(dir) && nullCb.defined())
{
pLenIn = new SQLLEN;
*pLenIn = SQL_NTS; // microsoft example does that, otherwise no null indicator is returned
_nullCbMap.insert(NullCbMap::value_type(pLenIn, nullCb));
}
_lengthIndicator.push_back(pLenIn);
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT) pos + 1,
@ -401,14 +427,15 @@ private:
Utility::sqlDataType(cDataType),
colSize,
decDigits,
(SQLPOINTER) &val, 0, 0)))
(SQLPOINTER)&val, 0,
_lengthIndicator.back())))
{
throw StatementException(_rStmt, "SQLBindParameter()");
}
}
template <typename L>
void bindImplLOB(std::size_t pos, const L& val, Direction dir)
void bindImplLOB(std::size_t pos, const L& val, Direction dir, const WhenNullCb& nullCb)
{
if (isOutBound(dir) || !isInBound(dir))
throw NotImplementedException("LOB parameter type can only be inbound.");
@ -424,13 +451,17 @@ private:
if (PB_AT_EXEC == _paramBinding)
*pLenIn = SQL_LEN_DATA_AT_EXEC(size);
if (isOutBound(dir) && nullCb.defined())
_nullCbMap.insert(NullCbMap::value_type(pLenIn, nullCb));
_lengthIndicator.push_back(pLenIn);
SQLSMALLINT sqlType = (isInBound(dir) && size <= _maxVarBinColSize) ? SQL_VARBINARY : SQL_LONGVARBINARY;
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT) pos + 1,
SQL_PARAM_INPUT,
SQL_C_BINARY,
SQL_LONGVARBINARY,
sqlType,
(SQLUINTEGER) size,
0,
pVal,
@ -485,9 +516,9 @@ private:
if (_containers.size() <= pos)
_containers.resize(pos + 1);
_containers[pos].push_back(std::vector<Type>());
_containers[pos].push_back( new Any(std::vector<Type>()) );
std::vector<Type>& cont = RefAnyCast<std::vector<Type> >(_containers[pos].back());
std::vector<Type>& cont = RefAnyCast<std::vector<Type> >( *_containers[pos].back() );
cont.assign(val.begin(), val.end());
bindImplVec(pos, cont, cDataType, dir);
}
@ -586,12 +617,13 @@ private:
std::memcpy(_charPtrs[pos] + offset, it->c_str(), strSize);
offset += size;
}
SQLSMALLINT sqlType = (isInBound(dir) && size < _maxCharColLength) ? SQL_VARCHAR : SQL_LONGVARCHAR;
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT) pos + 1,
toODBCDirection(dir),
SQL_C_CHAR,
SQL_LONGVARCHAR,
sqlType,
(SQLUINTEGER) size - 1,
0,
_charPtrs[pos],
@ -652,12 +684,12 @@ private:
std::memcpy(_utf16CharPtrs[pos] + offset, it->data(), strSize);
offset += (size / sizeof(UTF16Char));
}
SQLSMALLINT sqlType = (isInBound(dir) && size < _maxWCharColLength) ? SQL_WVARCHAR : SQL_WLONGVARCHAR;
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT)pos + 1,
toODBCDirection(dir),
SQL_C_WCHAR,
SQL_WLONGVARCHAR,
sqlType,
(SQLUINTEGER)size - 1,
0,
_utf16CharPtrs[pos],
@ -722,12 +754,13 @@ private:
std::memcpy(_charPtrs[pos] + offset, cIt->rawContent(), blobSize * sizeof(CharType));
offset += size;
}
SQLSMALLINT sqlType = (isInBound(dir) && size <= _maxVarBinColSize) ? SQL_VARBINARY : SQL_LONGVARBINARY;
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT) pos + 1,
SQL_PARAM_INPUT,
SQL_C_BINARY,
SQL_LONGVARBINARY,
sqlType,
(SQLUINTEGER) size,
0,
_charPtrs[pos],
@ -754,8 +787,6 @@ private:
setParamSetSize(length);
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_DATE_STRUCT);
if (_vecLengthIndicator.size() <= pos)
{
_vecLengthIndicator.resize(pos + 1, 0);
@ -804,8 +835,6 @@ private:
setParamSetSize(val.size());
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIME_STRUCT);
if (_vecLengthIndicator.size() <= pos)
{
_vecLengthIndicator.resize(pos + 1, 0);
@ -855,8 +884,6 @@ private:
setParamSetSize(length);
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIMESTAMP_STRUCT);
if (_vecLengthIndicator.size() <= pos)
{
_vecLengthIndicator.resize(pos + 1, 0);
@ -891,7 +918,7 @@ private:
}
template<typename C>
void bindImplNullContainer(std::size_t pos, const C& val, Direction dir)
void bindImplNullContainer(std::size_t pos, const C& val, Direction dir, const std::type_info& bindElemType)
{
if (isOutBound(dir) || !isInBound(dir))
throw NotImplementedException("Null container parameter type can only be inbound.");
@ -906,8 +933,6 @@ private:
setParamSetSize(length);
SQLINTEGER size = SQL_NULL_DATA;
if (_vecLengthIndicator.size() <= pos)
{
_vecLengthIndicator.resize(pos + 1, 0);
@ -916,13 +941,14 @@ private:
SQLINTEGER colSize = 0;
SQLSMALLINT decDigits = 0;
getColSizeAndPrecision(pos, SQL_C_STINYINT, colSize, decDigits);
SQLSMALLINT colType = _pTypeInfo->tryTypeidToCType(bindElemType, SQL_C_STINYINT);
getColSizeAndPrecision(pos, colType, colSize, decDigits);
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT) pos + 1,
SQL_PARAM_INPUT,
SQL_C_STINYINT,
Utility::sqlDataType(SQL_C_STINYINT),
colType,
Utility::sqlDataType(colType),
colSize,
decDigits,
0,
@ -957,6 +983,7 @@ private:
void freeMemory();
/// Frees all dynamically allocated memory resources.
template<typename T>
void getMinValueSize(T& val, SQLINTEGER& size)
/// Some ODBC drivers return DB-wide maximum allowed size for variable size columns,
@ -995,6 +1022,7 @@ private:
ParamMap _inParams;
ParamMap _outParams;
ParameterBinding _paramBinding;
ParameterInfoVec _parameters;
DateMap _dates;
TimeMap _times;
@ -1011,16 +1039,22 @@ private:
const TypeInfo* _pTypeInfo;
SQLINTEGER _paramSetSize;
std::size_t _maxFieldSize;
AnyVecVec _containers;
AnyPtrVecVec _containers;
std::size_t _maxCharColLength;
std::size_t _maxWCharColLength;
std::size_t _maxVarBinColSize;
ODBCMetaColumn::NumericConversion _numericConversion;
NullCbMap _nullCbMap;
bool _insertOnly;
};
//
// inlines
//
inline void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::Int8& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_STINYINT, dir);
bindImpl(pos, val, SQL_C_STINYINT, dir, nullCb);
}
@ -1042,9 +1076,9 @@ inline void Binder::bind(std::size_t pos, const std::list<Poco::Int8>& val, Dire
}
inline void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::UInt8& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_UTINYINT, dir);
bindImpl(pos, val, SQL_C_UTINYINT, dir, nullCb);
}
@ -1066,9 +1100,9 @@ inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt8>& val, Dir
}
inline void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::Int16& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_SSHORT, dir);
bindImpl(pos, val, SQL_C_SSHORT, dir, nullCb);
}
@ -1090,9 +1124,9 @@ inline void Binder::bind(std::size_t pos, const std::list<Poco::Int16>& val, Dir
}
inline void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::UInt16& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_USHORT, dir);
bindImpl(pos, val, SQL_C_USHORT, dir, nullCb);
}
@ -1114,9 +1148,9 @@ inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt16>& val, Di
}
inline void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::Int32& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_SLONG, dir);
bindImpl(pos, val, SQL_C_SLONG, dir, nullCb);
}
@ -1138,9 +1172,9 @@ inline void Binder::bind(std::size_t pos, const std::list<Poco::Int32>& val, Dir
}
inline void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::UInt32& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_ULONG, dir);
bindImpl(pos, val, SQL_C_ULONG, dir, nullCb);
}
@ -1162,9 +1196,9 @@ inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt32>& val, Di
}
inline void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::Int64& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_SBIGINT, dir);
bindImpl(pos, val, SQL_C_SBIGINT, dir, nullCb);
}
@ -1186,9 +1220,9 @@ inline void Binder::bind(std::size_t pos, const std::list<Poco::Int64>& val, Dir
}
inline void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::UInt64& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_UBIGINT, dir);
bindImpl(pos, val, SQL_C_UBIGINT, dir, nullCb);
}
@ -1211,15 +1245,15 @@ inline void Binder::bind(std::size_t pos, const std::list<Poco::UInt64>& val, Di
#ifndef POCO_LONG_IS_64_BIT
inline void Binder::bind(std::size_t pos, const long& val, Direction dir)
inline void Binder::bind(std::size_t pos, const long& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_SLONG, dir);
bindImpl(pos, val, SQL_C_SLONG, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir)
inline void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_SLONG, dir);
bindImpl(pos, val, SQL_C_SLONG, dir, nullCb);
}
@ -1242,9 +1276,9 @@ inline void Binder::bind(std::size_t pos, const std::list<long>& val, Direction
#endif
inline void Binder::bind(std::size_t pos, const float& val, Direction dir)
inline void Binder::bind(std::size_t pos, const float& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_FLOAT, dir);
bindImpl(pos, val, SQL_C_FLOAT, dir, nullCb);
}
@ -1266,9 +1300,9 @@ inline void Binder::bind(std::size_t pos, const std::list<float>& val, Direction
}
inline void Binder::bind(std::size_t pos, const double& val, Direction dir)
inline void Binder::bind(std::size_t pos, const double& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_DOUBLE, dir);
bindImpl(pos, val, SQL_C_DOUBLE, dir, nullCb);
}
@ -1290,9 +1324,9 @@ inline void Binder::bind(std::size_t pos, const std::list<double>& val, Directio
}
inline void Binder::bind(std::size_t pos, const bool& val, Direction dir)
inline void Binder::bind(std::size_t pos, const bool& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_BIT, dir);
bindImpl(pos, val, SQL_C_BIT, dir, nullCb);
}
@ -1314,9 +1348,9 @@ inline void Binder::bind(std::size_t pos, const std::list<bool>& val, Direction
}
inline void Binder::bind(std::size_t pos, const char& val, Direction dir)
inline void Binder::bind(std::size_t pos, const char& val, Direction dir, const WhenNullCb& nullCb)
{
bindImpl(pos, val, SQL_C_STINYINT, dir);
bindImpl(pos, val, SQL_C_STINYINT, dir, nullCb);
}
@ -1373,15 +1407,15 @@ inline void Binder::bind(std::size_t pos, const std::list<UTF16String>& val, Dir
bindImplContainerUTF16String(pos, val, dir);
}
inline void Binder::bind(std::size_t pos, const BLOB& val, Direction dir)
inline void Binder::bind(std::size_t pos, const BLOB& val, Direction dir, const WhenNullCb& nullCb)
{
bindImplLOB<BLOB>(pos, val, dir);
bindImplLOB<BLOB>(pos, val, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const CLOB& val, Direction dir)
inline void Binder::bind(std::size_t pos, const CLOB& val, Direction dir, const WhenNullCb& nullCb)
{
bindImplLOB<CLOB>(pos, val, dir);
bindImplLOB<CLOB>(pos, val, dir, nullCb);
}
@ -1475,21 +1509,21 @@ inline void Binder::bind(std::size_t pos, const std::list<DateTime>& val, Direct
}
inline void Binder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir)
inline void Binder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir, const std::type_info& bindElemType)
{
bindImplNullContainer(pos, val, dir);
bindImplNullContainer(pos, val, dir, bindElemType);
}
inline void Binder::bind(std::size_t pos, const std::deque<NullData>& val, Direction dir)
inline void Binder::bind(std::size_t pos, const std::deque<NullData>& val, Direction dir, const std::type_info& bindElemType)
{
bindImplNullContainer(pos, val, dir);
bindImplNullContainer(pos, val, dir, bindElemType);
}
inline void Binder::bind(std::size_t pos, const std::list<NullData>& val, Direction dir)
inline void Binder::bind(std::size_t pos, const std::list<NullData>& val, Direction dir, const std::type_info& bindElemType)
{
bindImplNullContainer(pos, val, dir);
bindImplNullContainer(pos, val, dir, bindElemType);
}

View File

@ -19,7 +19,6 @@
#ifndef Data_ODBC_ConnectionHandle_INCLUDED
#define Data_ODBC_ConnectionHandle_INCLUDED
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/Data/ODBC/EnvironmentHandle.h"
#ifdef POCO_OS_FAMILY_WINDOWS
@ -49,6 +48,9 @@ public:
const SQLHDBC& handle() const;
/// Returns const reference to handle;
operator bool() const;
/// Returns true if the handle is valid
private:
operator SQLHDBC& ();
/// Conversion operator into reference to native type.
@ -59,9 +61,8 @@ private:
ConnectionHandle(const ConnectionHandle&);
const ConnectionHandle& operator=(const ConnectionHandle&);
const EnvironmentHandle* _pEnvironment;
const EnvironmentHandle _environment;
SQLHDBC _hdbc;
bool _ownsEnvironment;
};
@ -92,6 +93,11 @@ inline SQLHDBC& ConnectionHandle::handle()
}
inline ConnectionHandle::operator bool () const
{
return _hdbc != SQL_NULL_HDBC;
}
} } } // namespace Poco::Data::ODBC

View File

@ -59,12 +59,12 @@ public:
typedef std::vector<DiagnosticFields> FieldVec;
typedef typename FieldVec::const_iterator Iterator;
explicit Diagnostics(const H& handle): _handle(handle)
explicit Diagnostics(const H& handle)
/// Creates and initializes the Diagnostics.
{
std::memset(_connectionName, 0, sizeof(_connectionName));
std::memset(_serverName, 0, sizeof(_serverName));
diagnostics();
diagnostics(handle);
}
~Diagnostics()
@ -138,7 +138,7 @@ public:
return _fields.end();
}
const Diagnostics& diagnostics()
const Diagnostics& diagnostics(const H& handle)
{
DiagnosticFields df;
SQLSMALLINT count = 1;
@ -149,7 +149,7 @@ public:
reset();
while (!Utility::isError(SQLGetDiagRec(handleType,
_handle,
handle,
count,
df._sqlState,
&df._nativeError,
@ -163,7 +163,7 @@ public:
// (they fail if connection has not been established yet
// or return empty string if not applicable for the context)
if (Utility::isError(SQLGetDiagField(handleType,
_handle,
handle,
count,
SQL_DIAG_CONNECTION_NAME,
_connectionName,
@ -182,7 +182,7 @@ public:
}
if (Utility::isError(SQLGetDiagField(handleType,
_handle,
handle,
count,
SQL_DIAG_SERVER_NAME,
_serverName,
@ -223,9 +223,6 @@ private:
/// Diagnostics container
FieldVec _fields;
/// Context handle
const H& _handle;
};

View File

@ -39,6 +39,9 @@ public:
EnvironmentHandle();
/// Creates the EnvironmentHandle.
explicit EnvironmentHandle(const SQLHENV* henv);
/// Creates the EnvironmentHandle which doesn't own the handle
~EnvironmentHandle();
/// Destroys the EnvironmentHandle.
@ -52,8 +55,7 @@ private:
operator SQLHENV& ();
/// Conversion operator into reference to native type.
SQLHENV& handle();
/// Returns reference to handle.
void init();
EnvironmentHandle(const EnvironmentHandle&);
const EnvironmentHandle& operator=(const EnvironmentHandle&);
@ -79,12 +81,6 @@ inline const SQLHENV& EnvironmentHandle::handle() const
inline EnvironmentHandle::operator SQLHENV& ()
{
return handle();
}
inline SQLHENV& EnvironmentHandle::handle()
{
return _henv;
}

View File

@ -491,6 +491,9 @@ private:
return true;
}
template<typename T>
bool extractManualLOBImpl(std::size_t pos, Poco::Data::LOB<T>& val, SQLSMALLINT cType);
template <typename T, typename NT>
bool extAny(std::size_t pos, T& val)
{
@ -511,7 +514,7 @@ private:
bool extractImpl(std::size_t pos, T& val)
/// Utility function for extraction of Any and DynamicAny.
{
ODBCMetaColumn column(_rStmt, pos);
ODBCMetaColumn column(_rStmt, pos, _pPreparator->numericConversion());
switch (column.type())
{
@ -717,7 +720,7 @@ inline bool Extractor::isNullLengthIndicator(SQLLEN val) const
inline SQLINTEGER Extractor::columnSize(std::size_t pos) const
{
std::size_t size = ODBCMetaColumn(_rStmt, pos).length();
std::size_t size = ODBCMetaColumn(_rStmt, pos, _pPreparator->numericConversion()).length();
std::size_t maxSize = _pPreparator->maxDataSize(pos);
if (size > maxSize) size = maxSize;
return (SQLINTEGER) size;

View File

@ -43,7 +43,9 @@ template <class H, SQLSMALLINT handleType>
class HandleException: public ODBCException
{
public:
HandleException(const H& handle): _error(handle)
HandleException(const H& handle, int code = 0) :
ODBCException(code),
_error(handle)
/// Creates HandleException
{
message(_error.toString());
@ -129,12 +131,24 @@ public:
_error.toString());
}
std::string errorString() const
/// Returns the error diagnostics string
{
return _error.toString();
}
static std::string errorString(const H& handle)
/// Returns the error diagnostics string for the handle.
{
return Error<H, handleType>(handle).toString();
}
protected:
const Error<H, handleType>& error() const
{
return _error;
}
private:
Error<H, handleType> _error;
};

View File

@ -39,7 +39,15 @@ namespace ODBC {
class ODBC_API ODBCMetaColumn: public MetaColumn
{
public:
explicit ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position);
enum NumericConversion
{
NC_BEST_FIT = 0,
NC_FORCE_STRING = 1,
NC_BEST_FIT_DBL_LIMIT = 2
};
ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position, NumericConversion numericConversion);
/// Creates the ODBCMetaColumn.
~ODBCMetaColumn();
@ -73,6 +81,7 @@ private:
SQLLEN _dataLength;
const StatementHandle& _rStmt;
ColumnDescription _columnDesc;
NumericConversion _numericConversion;
};

View File

@ -60,7 +60,7 @@ protected:
/// Returns the number of affected rows.
/// Used to find out the number of rows affected by insert or update.
const MetaColumn& metaColumn(std::size_t pos) const;
const MetaColumn& metaColumn(std::size_t pos, size_t dataSet) const;
/// Returns column meta data.
bool hasNext();
@ -93,6 +93,10 @@ protected:
std::string nativeSQL();
/// Returns the SQL string as modified by the driver.
protected:
virtual void insertHint();
private:
typedef Poco::Data::AbstractBindingVec Bindings;
typedef Poco::SharedPtr<Binder> BinderPtr;
@ -140,9 +144,10 @@ private:
void getData();
void addPreparator();
void fillColumns();
bool addPreparator(bool addAlways = true);
void fillColumns(size_t dataSetPos);
void checkError(SQLRETURN rc, const std::string& msg="");
bool nextResultSet();
const SQLHDBC& _rConnection;
const StatementHandle _stmt;
@ -155,6 +160,9 @@ private:
bool _prepared;
mutable std::size_t _affectedRowCount;
bool _canCompile;
ODBCMetaColumn::NumericConversion _numericConversion;
bool _isPostgres;
bool _insertHint;
};

View File

@ -101,7 +101,10 @@ public:
Preparator(const StatementHandle& rStmt,
const std::string& statement,
std::size_t maxFieldSize,
DataExtraction dataExtraction = DE_BOUND);
DataExtraction dataExtraction,
ODBCMetaColumn::NumericConversion numericConversion ,
bool isPostgres
);
/// Creates the Preparator.
Preparator(const Preparator& other);
@ -416,6 +419,9 @@ public:
DataExtraction getDataExtraction() const;
/// Returns data extraction mode.
ODBCMetaColumn::NumericConversion numericConversion() const;
/// Tells if numeric values are always converted to string
private:
typedef std::vector<Poco::Any> ValueVec;
typedef std::vector<SQLLEN> LengthVec;
@ -429,7 +435,7 @@ private:
void prepareImpl(std::size_t pos, const C* pVal = 0)
/// Utility function to prepare Any and DynamicAny.
{
ODBCMetaColumn col(_rStmt, pos);
ODBCMetaColumn col(_rStmt, pos, _numericConversion);
switch (col.type())
{
@ -681,6 +687,7 @@ private:
mutable IndexMap _varLengthArrays;
std::size_t _maxFieldSize;
DataExtraction _dataExtraction;
ODBCMetaColumn::NumericConversion _numericConversion;
};
@ -1267,6 +1274,12 @@ inline Poco::Any& Preparator::at(std::size_t pos)
}
inline ODBCMetaColumn::NumericConversion Preparator::numericConversion() const
{
return _numericConversion;
}
} } } // namespace Poco::Data::ODBC

View File

@ -45,6 +45,7 @@ class ODBC_API SessionImpl: public Poco::Data::AbstractSessionImpl<SessionImpl>
{
public:
static const std::size_t ODBC_MAX_FIELD_SIZE = 1024u;
static const char* const NUMERIC_CONVERSION_PROPERTY;
enum TransactionCapability
{
@ -167,10 +168,24 @@ public:
Poco::Any dataTypeInfo(const std::string& rName="");
/// Returns the data types information.
ODBCMetaColumn::NumericConversion numericConversion() const;
/// Tells if NUMERIC values to be always
/// converted to string
void setNumericConversion(ODBCMetaColumn::NumericConversion value);
/// Sets flag to tell if NUMERIC values are always returned as
/// string
private:
void setDataTypeInfo(const std::string& rName, const Poco::Any& rValue);
/// No-op. Throws InvalidAccessException.
void setNumericConversion(const std::string&, const Poco::Any& rValue);
Poco::Any numericConversion(const std::string& nm);
void init();
static const int FUNCTIONS = SQL_API_ODBC3_ALL_FUNCTIONS_SIZE;
void checkError(SQLRETURN rc, const std::string& msg="");
@ -184,6 +199,7 @@ private:
Poco::Any _maxFieldSize;
bool _autoBind;
bool _autoExtract;
ODBCMetaColumn::NumericConversion _numericConversion;
TypeInfo _dataTypes;
char _canTransact;
bool _inTransaction;
@ -286,6 +302,30 @@ inline int SessionImpl::queryTimeout() const
}
inline ODBCMetaColumn::NumericConversion SessionImpl::numericConversion() const
{
return _numericConversion;
}
inline Poco::Any SessionImpl::numericConversion(const std::string&)
{
return numericConversion();
}
inline void SessionImpl::setNumericConversion(ODBCMetaColumn::NumericConversion value)
{
_numericConversion = value;
}
inline void SessionImpl::setNumericConversion(const std::string&, const Poco::Any& rValue)
{
setNumericConversion( Poco::AnyCast<ODBCMetaColumn::NumericConversion>(rValue) );
}
} } } // namespace Poco::Data::ODBC

View File

@ -23,8 +23,10 @@
#include "Poco/Data/ODBC/ODBC.h"
#include "Poco/NamedTuple.h"
#include "Poco/DynamicAny.h"
#include "Poco/Data/AbstractBinder.h"
#include <vector>
#include <map>
#include <typeinfo>
#ifdef POCO_OS_FAMILY_WINDOWS
#include <windows.h>
#endif
@ -71,6 +73,17 @@ public:
SQLINTEGER,
SQLSMALLINT> TypeInfoTup;
typedef std::vector<TypeInfoTup> TypeInfoVec;
typedef const std::type_info* TypeInfoPtr;
struct TypeInfoComp : public std::binary_function<TypeInfoPtr, TypeInfoPtr, bool>
{
bool operator()(const TypeInfoPtr& left, const TypeInfoPtr& right) const
{ // apply operator< to operands
return ( left->before( *right ) );
}
};
typedef std::map<TypeInfoPtr, SQLSMALLINT, TypeInfoComp> CppTypeInfoMap;
explicit TypeInfo(SQLHDBC* pHDBC=0);
/// Creates the TypeInfo.
@ -102,6 +115,13 @@ public:
/// Prints all the types (as reported by the underlying database)
/// to the supplied output stream.
SQLSMALLINT tryTypeidToCType(const std::type_info& ti, SQLSMALLINT defaultVal = SQL_C_TINYINT) const;
/// try to find mapping of the given C++ typeid to the ODBC C-Type Code
/// will return the defaultVal if no match is found
SQLSMALLINT nullDataType(const NullData val) const;
/// Map the null value type to ODBC buffer type
private:
void fillCTypes();
void fillSQLTypes();
@ -109,6 +129,7 @@ private:
DataTypeMap _cDataTypes;
DataTypeMap _sqlDataTypes;
TypeInfoVec _typeInfo;
CppTypeInfoMap _cppDataTypes;
SQLHDBC* _pHDBC;
};

View File

@ -40,13 +40,6 @@ void makeUTF8(Poco::Buffer<SQLWCHAR>& buffer, SQLINTEGER length, SQLPOINTER pTar
/// Utility function for conversion from UTF-16 to UTF-8.
inline void makeUTF8(Poco::Buffer<SQLWCHAR>& buffer, int length, SQLPOINTER pTarget, SQLSMALLINT targetLength)
/// Utility function for conversion from UTF-16 to UTF-8.
{
makeUTF8(buffer, length, pTarget, (SQLINTEGER) targetLength);
}
} } } // namespace Poco::Data::ODBC

View File

@ -27,17 +27,39 @@ namespace Poco {
namespace Data {
namespace ODBC {
static void getProp(const TypeInfo& dataTypes, SQLSMALLINT sqlType, size_t& val)
{
const std::string NM("COLUMN_SIZE");
Poco::DynamicAny r;
if (dataTypes.tryGetInfo(sqlType, NM, r))
{
long sz = r.convert<long>();
// Postgres driver returns SQL_NO_TOTAL(-4) in some cases
if (sz >= 0)
val = static_cast<size_t>(sz);
}
}
Binder::Binder(const StatementHandle& rStmt,
std::size_t maxFieldSize,
Binder::ParameterBinding dataBinding,
TypeInfo* pDataTypes):
TypeInfo* pDataTypes,
ODBCMetaColumn::NumericConversion numericConversion,
bool insertOnly) :
_rStmt(rStmt),
_paramBinding(dataBinding),
_pTypeInfo(pDataTypes),
_paramSetSize(0),
_maxFieldSize(maxFieldSize)
_maxFieldSize(maxFieldSize),
_maxCharColLength(1024),
_maxWCharColLength(1024),
_maxVarBinColSize(1024),
_numericConversion(numericConversion),
_insertOnly(insertOnly)
{
getProp(*_pTypeInfo, SQL_WVARCHAR, _maxWCharColLength);
getProp(*_pTypeInfo, SQL_VARCHAR, _maxCharColLength);
getProp(*_pTypeInfo, SQL_VARBINARY, _maxVarBinColSize);
}
@ -49,61 +71,110 @@ Binder::~Binder()
void Binder::freeMemory()
{
LengthPtrVec::iterator itLen = _lengthIndicator.begin();
LengthPtrVec::iterator itLenEnd = _lengthIndicator.end();
for(; itLen != itLenEnd; ++itLen) delete *itLen;
if (_lengthIndicator.size() > 0)
{
LengthPtrVec::iterator itLen = _lengthIndicator.begin();
LengthPtrVec::iterator itLenEnd = _lengthIndicator.end();
for (; itLen != itLenEnd; ++itLen) delete *itLen;
}
LengthVecVec::iterator itVecLen = _vecLengthIndicator.begin();
LengthVecVec::iterator itVecLenEnd = _vecLengthIndicator.end();
for (; itVecLen != itVecLenEnd; ++itVecLen) delete *itVecLen;
if (_vecLengthIndicator.size() > 0)
{
LengthVecVec::iterator itVecLen = _vecLengthIndicator.begin();
LengthVecVec::iterator itVecLenEnd = _vecLengthIndicator.end();
for (; itVecLen != itVecLenEnd; ++itVecLen) delete *itVecLen;
}
TimeMap::iterator itT = _times.begin();
TimeMap::iterator itTEnd = _times.end();
for(; itT != itTEnd; ++itT) delete itT->first;
if (_times.size() > 0)
{
TimeMap::iterator itT = _times.begin();
TimeMap::iterator itTEnd = _times.end();
for (; itT != itTEnd; ++itT) delete itT->first;
}
DateMap::iterator itD = _dates.begin();
DateMap::iterator itDEnd = _dates.end();
for(; itD != itDEnd; ++itD) delete itD->first;
if (_dates.size() > 0)
{
DateMap::iterator itD = _dates.begin();
DateMap::iterator itDEnd = _dates.end();
for (; itD != itDEnd; ++itD) delete itD->first;
}
TimestampMap::iterator itTS = _timestamps.begin();
TimestampMap::iterator itTSEnd = _timestamps.end();
for(; itTS != itTSEnd; ++itTS) delete itTS->first;
if (_timestamps.size() > 0)
{
TimestampMap::iterator itTS = _timestamps.begin();
TimestampMap::iterator itTSEnd = _timestamps.end();
for (; itTS != itTSEnd; ++itTS) delete itTS->first;
}
StringMap::iterator itStr = _strings.begin();
StringMap::iterator itStrEnd = _strings.end();
for(; itStr != itStrEnd; ++itStr) std::free(itStr->first);
if (_strings.size() > 0)
{
StringMap::iterator itStr = _strings.begin();
StringMap::iterator itStrEnd = _strings.end();
for (; itStr != itStrEnd; ++itStr) std::free(itStr->first);
}
CharPtrVec::iterator itChr = _charPtrs.begin();
CharPtrVec::iterator endChr = _charPtrs.end();
for (; itChr != endChr; ++itChr) std::free(*itChr);
if (_charPtrs.size() > 0)
{
CharPtrVec::iterator itChr = _charPtrs.begin();
CharPtrVec::iterator endChr = _charPtrs.end();
for (; itChr != endChr; ++itChr) std::free(*itChr);
}
UTF16CharPtrVec::iterator itUTF16Chr = _utf16CharPtrs.begin();
UTF16CharPtrVec::iterator endUTF16Chr = _utf16CharPtrs.end();
for (; itUTF16Chr != endUTF16Chr; ++itUTF16Chr) std::free(*itUTF16Chr);
if (_utf16CharPtrs.size() > 0)
{
UTF16CharPtrVec::iterator itUTF16Chr = _utf16CharPtrs.begin();
UTF16CharPtrVec::iterator endUTF16Chr = _utf16CharPtrs.end();
for (; itUTF16Chr != endUTF16Chr; ++itUTF16Chr) std::free(*itUTF16Chr);
}
BoolPtrVec::iterator itBool = _boolPtrs.begin();
BoolPtrVec::iterator endBool = _boolPtrs.end();
for (; itBool != endBool; ++itBool) delete [] *itBool;
if (_boolPtrs.size() > 0)
{
BoolPtrVec::iterator itBool = _boolPtrs.begin();
BoolPtrVec::iterator endBool = _boolPtrs.end();
for (; itBool != endBool; ++itBool) delete[] * itBool;
}
DateVecVec::iterator itDateVec = _dateVecVec.begin();
DateVecVec::iterator itDateVecEnd = _dateVecVec.end();
for (; itDateVec != itDateVecEnd; ++itDateVec) delete *itDateVec;
if (_dateVecVec.size() > 0)
{
DateVecVec::iterator itDateVec = _dateVecVec.begin();
DateVecVec::iterator itDateVecEnd = _dateVecVec.end();
for (; itDateVec != itDateVecEnd; ++itDateVec) delete *itDateVec;
}
TimeVecVec::iterator itTimeVec = _timeVecVec.begin();
TimeVecVec::iterator itTimeVecEnd = _timeVecVec.end();
for (; itTimeVec != itTimeVecEnd; ++itTimeVec) delete *itTimeVec;
if (_timeVecVec.size() > 0)
{
TimeVecVec::iterator itTimeVec = _timeVecVec.begin();
TimeVecVec::iterator itTimeVecEnd = _timeVecVec.end();
for (; itTimeVec != itTimeVecEnd; ++itTimeVec) delete *itTimeVec;
}
DateTimeVecVec::iterator itDateTimeVec = _dateTimeVecVec.begin();
DateTimeVecVec::iterator itDateTimeVecEnd = _dateTimeVecVec.end();
for (; itDateTimeVec != itDateTimeVecEnd; ++itDateTimeVec) delete *itDateTimeVec;
if (_dateTimeVecVec.size() > 0)
{
DateTimeVecVec::iterator itDateTimeVec = _dateTimeVecVec.begin();
DateTimeVecVec::iterator itDateTimeVecEnd = _dateTimeVecVec.end();
for (; itDateTimeVec != itDateTimeVecEnd; ++itDateTimeVec) delete *itDateTimeVec;
}
if (_containers.size() > 0)
{
AnyPtrVecVec::iterator itAnyVec = _containers.begin();
AnyPtrVecVec::iterator itAnyVecEnd = _containers.end();
for (; itAnyVec != itAnyVecEnd; ++itAnyVec)
{
AnyPtrVec::iterator b = itAnyVec->begin();
AnyPtrVec::iterator e = itAnyVec->end();
for (; b != e; ++b) delete *b;
}
}
}
void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
void Binder::bind(std::size_t pos, const std::string& val, Direction dir, const WhenNullCb& nullCb)
{
SQLPOINTER pVal = 0;
SQLINTEGER size = (SQLINTEGER) val.size();
SQLSMALLINT sqType = SQL_LONGVARCHAR;
if (isOutBound(dir))
{
getColumnOrParameterSize(pos, size);
@ -111,16 +182,20 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
pVal = (SQLPOINTER) pChar;
_outParams.insert(ParamMap::value_type(pVal, size));
_strings.insert(StringMap::value_type(pChar, const_cast<std::string*>(&val)));
if (size < _maxCharColLength) sqType = SQL_VARCHAR;
}
else if (isInBound(dir))
{
pVal = (SQLPOINTER) val.c_str();
_inParams.insert(ParamMap::value_type(pVal, size));
if (size < _maxCharColLength) sqType = SQL_VARCHAR;
}
else
throw InvalidArgumentException("Parameter must be [in] OR [out] bound.");
SQLLEN* pLenIn = new SQLLEN;
if (isOutBound(dir) && nullCb.defined())
_nullCbMap.insert(NullCbMap::value_type( pLenIn, nullCb) );
SQLINTEGER colSize = 0;
SQLSMALLINT decDigits = 0;
getColSizeAndPrecision(pos, SQL_C_CHAR, colSize, decDigits);
@ -135,7 +210,7 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
(SQLUSMALLINT) pos + 1,
toODBCDirection(dir),
SQL_C_CHAR,
SQL_LONGVARCHAR,
sqType,
(SQLUINTEGER) colSize,
0,
pVal,
@ -147,13 +222,13 @@ void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
}
void Binder::bind(std::size_t pos, const UTF16String& val, Direction dir)
void Binder::bind(std::size_t pos, const UTF16String& val, Direction dir, const WhenNullCb& nullCb)
{
typedef UTF16String::value_type CharT;
SQLPOINTER pVal = 0;
SQLINTEGER size = (SQLINTEGER)(val.size() * sizeof(CharT));
SQLSMALLINT sqType = (val.size() < _maxWCharColLength) ? SQL_WVARCHAR : SQL_WLONGVARCHAR;
if (isOutBound(dir))
{
getColumnOrParameterSize(pos, size);
@ -171,6 +246,9 @@ void Binder::bind(std::size_t pos, const UTF16String& val, Direction dir)
throw InvalidArgumentException("Parameter must be [in] OR [out] bound.");
SQLLEN* pLenIn = new SQLLEN;
if (isOutBound(dir) && nullCb.defined())
_nullCbMap.insert(NullCbMap::value_type(pLenIn, nullCb));
SQLINTEGER colSize = 0;
SQLSMALLINT decDigits = 0;
getColSizeAndPrecision(pos, SQL_C_WCHAR, colSize, decDigits);
@ -187,7 +265,7 @@ void Binder::bind(std::size_t pos, const UTF16String& val, Direction dir)
(SQLUSMALLINT)pos + 1,
toODBCDirection(dir),
SQL_C_WCHAR,
SQL_WLONGVARCHAR,
sqType,
(SQLUINTEGER)colSize,
0,
pVal,
@ -199,14 +277,14 @@ void Binder::bind(std::size_t pos, const UTF16String& val, Direction dir)
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
void Binder::bind(std::size_t pos, const Date& val, Direction dir, const WhenNullCb& nullCb)
{
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_DATE_STRUCT);
SQLLEN* pLenIn = new SQLLEN;
*pLenIn = size;
*pLenIn = SQL_NTS; // microsoft example does that, otherwise no null indicator is returned
_lengthIndicator.push_back(pLenIn);
if (isOutBound(dir) && nullCb.defined())
_nullCbMap.insert(NullCbMap::value_type(pLenIn, nullCb));
SQL_DATE_STRUCT* pDS = new SQL_DATE_STRUCT;
Utility::dateSync(*pDS, val);
@ -232,11 +310,12 @@ void Binder::bind(std::size_t pos, const Date& val, Direction dir)
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
void Binder::bind(std::size_t pos, const Time& val, Direction dir, const WhenNullCb& nullCb)
{
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIME_STRUCT);
SQLLEN* pLenIn = new SQLLEN;
*pLenIn = size;
*pLenIn = SQL_NTS; // microsoft example does that, otherwise no null indicator is returned
if (isOutBound(dir) && nullCb.defined())
_nullCbMap.insert(NullCbMap::value_type(pLenIn, nullCb));
_lengthIndicator.push_back(pLenIn);
@ -265,11 +344,12 @@ void Binder::bind(std::size_t pos, const Time& val, Direction dir)
}
void Binder::bind(std::size_t pos, const Poco::DateTime& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::DateTime& val, Direction dir, const WhenNullCb& nullCb)
{
SQLINTEGER size = (SQLINTEGER) sizeof(SQL_TIMESTAMP_STRUCT);
SQLLEN* pLenIn = new SQLLEN;
*pLenIn = size;
*pLenIn = SQL_NTS; // microsoft example does that, otherwise no null indicator is returned
if (isOutBound(dir) && nullCb.defined())
_nullCbMap.insert(NullCbMap::value_type(pLenIn, nullCb));
_lengthIndicator.push_back(pLenIn);
@ -298,7 +378,7 @@ void Binder::bind(std::size_t pos, const Poco::DateTime& val, Direction dir)
}
void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
void Binder::bind(std::size_t pos, const NullData& val, Direction dir, const std::type_info& bindType)
{
if (isOutBound(dir) || !isInBound(dir))
throw NotImplementedException("NULL parameter type can only be inbound.");
@ -312,13 +392,16 @@ void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
SQLINTEGER colSize = 0;
SQLSMALLINT decDigits = 0;
getColSizeAndPrecision(pos, SQL_C_STINYINT, colSize, decDigits);
const SQLSMALLINT colType = (bindType == typeid(void) || bindType == typeid(NullData) || bindType == typeid(NullType)) ?
_pTypeInfo->nullDataType(val) : _pTypeInfo->tryTypeidToCType(bindType, SQL_C_TINYINT);
getColSizeAndPrecision(pos, colType, colSize, decDigits);
if (Utility::isError(SQLBindParameter(_rStmt,
(SQLUSMALLINT) pos + 1,
SQL_PARAM_INPUT,
SQL_C_STINYINT,
Utility::sqlDataType(SQL_C_STINYINT),
colType,
Utility::sqlDataType(colType),
colSize,
decDigits,
0,
@ -342,7 +425,7 @@ std::size_t Binder::parameterSize(SQLPOINTER pAddr) const
}
void Binder::bind(std::size_t pos, const char* const &pVal, Direction dir)
void Binder::bind(std::size_t pos, const char* const &pVal, Direction dir, const WhenNullCb& nullCb)
{
throw NotImplementedException("char* binding not implemented, Use std::string instead.");
}
@ -364,6 +447,7 @@ SQLSMALLINT Binder::toODBCDirection(Direction dir) const
void Binder::synchronize()
{
if (_dates.size())
{
DateMap::iterator it = _dates.begin();
@ -395,26 +479,52 @@ void Binder::synchronize()
for(; it != end; ++it)
it->second->assign(it->first, std::strlen(it->first));
}
if (_nullCbMap.size())
{
NullCbMap::iterator it = _nullCbMap.begin();
NullCbMap::iterator end = _nullCbMap.end();
for (; it != end; ++it)
if (*it->first == SQL_NULL_DATA) it->second.onNull();
}
}
void Binder::reset()
{
freeMemory();
LengthPtrVec().swap(_lengthIndicator);
_inParams.clear();
_outParams.clear();
_dates.clear();
_times.clear();
_timestamps.clear();
_strings.clear();
_dateVecVec.clear();
_timeVecVec.clear();
_dateTimeVecVec.clear();
_charPtrs.clear();
_boolPtrs.clear();
_containers.clear();
if (_lengthIndicator.size() > 0)
LengthPtrVec().swap(_lengthIndicator);
if (_inParams.size() > 0)
_inParams.clear();
if (_outParams.size() > 0)
_outParams.clear();
if (_dates.size() > 0)
_dates.clear();
if (_times.size() > 0)
_times.clear();
if (_timestamps.size() > 0)
_timestamps.clear();
if (_strings.size() > 0)
_strings.clear();
if (_dateVecVec.size() > 0)
_dateVecVec.clear();
if (_timeVecVec.size() > 0)
_timeVecVec.clear();
if (_dateTimeVecVec.size() > 0)
_dateTimeVecVec.clear();
if (_charPtrs.size() > 0)
_charPtrs.clear();
if (_boolPtrs.size() > 0)
_boolPtrs.clear();
if (_containers.size() > 0)
_containers.clear();
if (_nullCbMap.size() > 0)
_nullCbMap.clear();
_paramSetSize = 0;
if (!_insertOnly)
_parameters.clear();
}
@ -425,11 +535,11 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
{
// Not all drivers are equally willing to cooperate in this matter.
// Hence the funky flow control.
DynamicAny tmp;
bool found(false);
if (_pTypeInfo)
{
found = _pTypeInfo->tryGetInfo(cDataType, "COLUMN_SIZE", tmp);
DynamicAny tmp;
bool found = _pTypeInfo->tryGetInfo(cDataType, "COLUMN_SIZE", tmp);
if (found) colSize = tmp;
found = _pTypeInfo->tryGetInfo(cDataType, "MINIMUM_SCALE", tmp);
if (found)
@ -439,27 +549,34 @@ void Binder::getColSizeAndPrecision(std::size_t pos,
}
}
try
if (_parameters.size() <= pos || !_parameters[pos].defined())
{
Parameter p(_rStmt, pos);
colSize = (SQLINTEGER) p.columnSize();
decDigits = (SQLSMALLINT) p.decimalDigits();
return;
} catch (StatementException&) { }
if (_parameters.size() <= pos)
_parameters.resize(pos + 1);
_parameters[pos] = ParamDescriptor(0, cDataType, 0);
try
{
ODBCMetaColumn c(_rStmt, pos);
colSize = (SQLINTEGER) c.length();
decDigits = (SQLSMALLINT) c.precision();
return;
} catch (StatementException&) { }
try
{
{
Parameter p(_rStmt, pos);
_parameters[pos] = ParamDescriptor(static_cast<SQLINTEGER>(p.columnSize()), cDataType, static_cast<SQLSMALLINT>(p.decimalDigits()));
}
}
catch (StatementException&)
{
try
{
ODBCMetaColumn c(_rStmt, pos, _numericConversion);
_parameters[pos] = ParamDescriptor(static_cast<SQLINTEGER>(c.length()), cDataType, static_cast<SQLSMALLINT>(c.precision()));
}
catch (StatementException&) {}
}
}
// no success, set to zero and hope for the best
// we may have no success, so use zeros and hope for the best
// (most drivers do not require these most of the times anyway)
colSize = 0;
decDigits = 0;
return;
colSize = _parameters[pos].colSize;
decDigits = _parameters[pos].decDigits;
}
@ -470,7 +587,7 @@ void Binder::getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size)
try
{
ODBCMetaColumn col(_rStmt, pos);
ODBCMetaColumn col(_rStmt, pos, _numericConversion);
colSize = col.length();
}
catch (StatementException&) { }
@ -486,10 +603,10 @@ void Binder::getColumnOrParameterSize(std::size_t pos, SQLINTEGER& size)
//On Linux, PostgreSQL driver segfaults on SQLGetDescField, so this is disabled for now
#ifdef POCO_OS_FAMILY_WINDOWS
SQLHDESC hIPD = 0;
if (!Utility::isError(SQLGetStmtAttr(_rStmt, SQL_ATTR_IMP_PARAM_DESC, &hIPD, SQL_IS_POINTER, 0)))
if (!Utility::isError(Poco::Data::ODBC::SQLGetStmtAttr(_rStmt, SQL_ATTR_IMP_PARAM_DESC, &hIPD, SQL_IS_POINTER, 0)))
{
SQLUINTEGER sz = 0;
if (!Utility::isError(SQLGetDescField(hIPD, (SQLSMALLINT) pos + 1, SQL_DESC_LENGTH, &sz, SQL_IS_UINTEGER, 0)) &&
if (!Utility::isError(Poco::Data::ODBC::SQLGetDescField(hIPD, (SQLSMALLINT)pos + 1, SQL_DESC_LENGTH, &sz, SQL_IS_UINTEGER, 0)) &&
sz > 0)
{
size = sz;

View File

@ -25,12 +25,11 @@ namespace ODBC {
ConnectionHandle::ConnectionHandle(EnvironmentHandle* pEnvironment):
_pEnvironment(pEnvironment ? pEnvironment : new EnvironmentHandle),
_hdbc(SQL_NULL_HDBC),
_ownsEnvironment(pEnvironment ? false : true)
_environment(pEnvironment ? &pEnvironment->handle() : 0),
_hdbc(SQL_NULL_HDBC)
{
if (Utility::isError(SQLAllocHandle(SQL_HANDLE_DBC,
_pEnvironment->handle(),
_environment.handle(),
&_hdbc)))
{
throw ODBCException("Could not allocate connection handle.");
@ -42,12 +41,14 @@ ConnectionHandle::~ConnectionHandle()
{
try
{
SQLDisconnect(_hdbc);
SQLRETURN rc = SQLFreeHandle(SQL_HANDLE_DBC, _hdbc);
if (_hdbc != SQL_NULL_HDBC)
{
SQLDisconnect(_hdbc);
SQLRETURN rc = SQLFreeHandle(SQL_HANDLE_DBC, _hdbc);
_hdbc = SQL_NULL_HDBC;
if (_ownsEnvironment) delete _pEnvironment;
poco_assert (!Utility::isError(rc));
poco_assert(!Utility::isError(rc));
}
}
catch (...)
{

View File

@ -24,27 +24,46 @@ namespace Data {
namespace ODBC {
EnvironmentHandle::EnvironmentHandle(): _henv(SQL_NULL_HENV)
EnvironmentHandle::EnvironmentHandle(): _henv(SQL_NULL_HENV),
_isOwner(false)
{
if (Utility::isError(SQLAllocHandle(SQL_HANDLE_ENV,
SQL_NULL_HANDLE,
&_henv)) ||
Utility::isError(SQLSetEnvAttr(_henv,
SQL_ATTR_ODBC_VERSION,
(SQLPOINTER) SQL_OV_ODBC3,
0)))
init();
}
EnvironmentHandle::EnvironmentHandle(const SQLHENV* henv) : _henv(SQL_NULL_HENV),
_isOwner(false)
{
if (!henv || *henv == SQL_NULL_HENV)
init();
else
_henv = *henv;
}
void EnvironmentHandle::init()
{
if (Utility::isError(SQLAllocHandle(SQL_HANDLE_ENV,
SQL_NULL_HANDLE,
&_henv)) ||
Utility::isError(SQLSetEnvAttr(_henv,
SQL_ATTR_ODBC_VERSION,
(SQLPOINTER)SQL_OV_ODBC3,
0)))
{
throw ODBCException("Could not initialize environment.");
}
_isOwner = true;
}
EnvironmentHandle::~EnvironmentHandle()
{
try
{
SQLRETURN rc = SQLFreeHandle(SQL_HANDLE_ENV, _henv);
poco_assert (!Utility::isError(rc));
if (_isOwner && _henv != SQL_NULL_HENV)
{
SQLRETURN rc = SQLFreeHandle(SQL_HANDLE_ENV, _henv);
_henv = SQL_NULL_HENV;
poco_assert(!Utility::isError(rc));
}
}
catch (...)
{

View File

@ -352,18 +352,37 @@ bool Extractor::extractManualImpl<UTF16String>(std::size_t pos, UTF16String& val
template<>
bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
Poco::Data::CLOB& val,
bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
Poco::Data::CLOB& val,
SQLSMALLINT cType)
{
return extractManualLOBImpl(pos, val, cType);
}
template<>
bool Extractor::extractManualImpl<Poco::Data::BLOB>(std::size_t pos,
Poco::Data::BLOB& val,
SQLSMALLINT cType)
{
return extractManualLOBImpl(pos, val, cType);
}
template<typename T>
bool Extractor::extractManualLOBImpl(std::size_t pos,
Poco::Data::LOB<T>& val,
SQLSMALLINT cType)
{
std::size_t maxSize = _pPreparator->getMaxFieldSize();
std::size_t fetchedSize = 0;
const int bufSize = CHUNK_SIZE;
std::size_t fetchedSize = bufSize;
std::size_t totalSize = 0;
SQLLEN len;
const int bufSize = CHUNK_SIZE;
Poco::Buffer<char> apChar(bufSize);
char* pChar = apChar.begin();
Poco::Buffer<T> apChar(bufSize);
T* pChar = apChar.begin();
SQLRETURN rc = 0;
val.clear();
@ -371,7 +390,9 @@ bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
do
{
std::memset(pChar, 0, bufSize);
// clear out the latest data in the buffer
if (fetchedSize > 0)
std::memset(pChar, 0, fetchedSize);
len = 0;
rc = SQLGetData(_rStmt,
(SQLUSMALLINT) pos + 1,
@ -394,7 +415,7 @@ bool Extractor::extractManualImpl<Poco::Data::CLOB>(std::size_t pos,
if (SQL_NO_DATA == rc || !len)
break;
fetchedSize = len > CHUNK_SIZE ? CHUNK_SIZE : len;
fetchedSize = len > bufSize ? bufSize : len;
totalSize += fetchedSize;
if (totalSize <= maxSize)
val.appendRaw(pChar, fetchedSize);

View File

@ -23,9 +23,10 @@ namespace Data {
namespace ODBC {
ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position) :
ODBCMetaColumn::ODBCMetaColumn(const StatementHandle& rStmt, std::size_t position, NumericConversion numericConversion) :
MetaColumn(position),
_rStmt(rStmt)
_rStmt(rStmt),
_numericConversion(numericConversion)
{
init();
}
@ -92,6 +93,7 @@ void ODBCMetaColumn::init()
case SQL_WCHAR:
case SQL_WVARCHAR:
case SQL_WLONGVARCHAR:
case -350: // IBM DB2 CLOB, which long unicode string
setType(MetaColumn::FDT_WSTRING); break;
case SQL_TINYINT:
@ -112,12 +114,46 @@ void ODBCMetaColumn::init()
case SQL_NUMERIC:
case SQL_DECIMAL:
if (0 == _columnDesc.decimalDigits)
setType(MetaColumn::FDT_INT32);
else
setType(MetaColumn::FDT_DOUBLE);
break;
{
bool toString = false;
switch (_numericConversion)
{
case NC_BEST_FIT:
case NC_BEST_FIT_DBL_LIMIT:
if (0 == _columnDesc.decimalDigits)
{
if (_columnDesc.size <= 9)
setType(MetaColumn::FDT_INT32);
else if (_columnDesc.size <= 18)
setType(MetaColumn::FDT_INT64);
else if (_numericConversion != NC_BEST_FIT_DBL_LIMIT)
toString = true;
else
setType(MetaColumn::FDT_DOUBLE);
}
else
{
// we can't have more than 16 digits in double, but we may be asked to
if (_columnDesc.size > 16 && _numericConversion != NC_BEST_FIT_DBL_LIMIT)
toString = true;
else
setType(MetaColumn::FDT_DOUBLE);
}
break;
case NC_FORCE_STRING:
toString = true;
}
if (toString)
{
setLength(_columnDesc.size + 4);
#if defined(UNICODE)
setType(MetaColumn::FDT_WSTRING);
#else
setType(MetaColumn::FDT_STRING);
#endif
}
}
break;
case SQL_REAL:
setType(MetaColumn::FDT_FLOAT); break;
@ -126,8 +162,12 @@ void ODBCMetaColumn::init()
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
case -98:// IBM DB2 non-standard type
case -370: // IBM DB2 XML, documentation advises to bind it as BLOB, not CLOB
setType(MetaColumn::FDT_BLOB); break;
case -99: // IBM DB2 CLOB
setType(MetaColumn::FDT_CLOB); break;
case SQL_TYPE_DATE:
setType(MetaColumn::FDT_DATE); break;

View File

@ -46,7 +46,10 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
_nextResponse(0),
_prepared(false),
_affectedRowCount(0),
_canCompile(true)
_canCompile(true),
_numericConversion(rSession.numericConversion()),
_isPostgres(false),
_insertHint(false)
{
int queryTimeout = rSession.queryTimeout();
if (queryTimeout >= 0)
@ -57,6 +60,15 @@ ODBCStatementImpl::ODBCStatementImpl(SessionImpl& rSession):
(SQLPOINTER) uqt,
0);
}
SQLSMALLINT t;
SQLRETURN r = Poco::Data::ODBC::SQLGetInfo(_rConnection, SQL_DRIVER_NAME, NULL, 0, &t);
if (!Utility::isError(r) && t > 0)
{
std::string serverString;
serverString.resize(static_cast<std::size_t>(t) + 2);
r = Poco::Data::ODBC::SQLGetInfo(_rConnection, SQL_DRIVER_NAME, &serverString[0], SQLSMALLINT((serverString.length() - 1) * sizeof(serverString[0])), &t);
_isPostgres = (!Utility::isError(r) && Poco::toUpperInPlace(serverString).find("PSQLODBC") == 0);
}
}
@ -95,14 +107,15 @@ void ODBCStatementImpl::compileImpl()
pDT = AnyCast<TypeInfo*>(dti);
}catch (NotSupportedException&) { }
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
const std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
const ODBCMetaColumn::NumericConversion numericConversion = dynamic_cast<SessionImpl&>(session()).numericConversion();
_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT);
_pBinder = new Binder(_stmt, maxFieldSize, bind, pDT, numericConversion, _insertHint);
makeInternalExtractors();
doPrepare();
_canCompile = false;
_canCompile = false;
}
@ -112,7 +125,7 @@ void ODBCStatementImpl::makeInternalExtractors()
{
try
{
fillColumns();
fillColumns(currentDataSet());
} catch (DataFormatException&)
{
if (isStoredProcedure()) return;
@ -125,25 +138,34 @@ void ODBCStatementImpl::makeInternalExtractors()
}
void ODBCStatementImpl::addPreparator()
bool ODBCStatementImpl::addPreparator(bool addAlways)
{
Preparator* prep = 0;
if (0 == _preparations.size())
{
std::string statement(toString());
if (statement.empty())
throw ODBCException("Empty statements are illegal");
Preparator::DataExtraction ext = session().getFeature("autoExtract") ?
Preparator::DataExtraction ext = session().getFeature("autoExtract") ?
Preparator::DE_BOUND : Preparator::DE_MANUAL;
std::size_t maxFieldSize = AnyCast<std::size_t>(session().getProperty("maxFieldSize"));
_preparations.push_back(new Preparator(_stmt, statement, maxFieldSize, ext));
prep = new Preparator(_stmt, statement, maxFieldSize, ext, _numericConversion, _isPostgres);
}
else
_preparations.push_back(new Preparator(*_preparations[0]));
prep = new Preparator(*_preparations[0]);
if (addAlways || prep->columns() > 0)
{
_preparations.push_back(prep);
_extractors.push_back(new Extractor(_stmt, _preparations.back()));
_extractors.push_back(new Extractor(_stmt, _preparations.back()));
return true;
}
delete prep;
return false;
}
@ -214,7 +236,6 @@ void ODBCStatementImpl::doBind()
void ODBCStatementImpl::bindImpl()
{
doBind();
SQLRETURN rc = SQLExecute(_stmt);
if (SQL_NEED_DATA == rc) putData();
@ -279,6 +300,24 @@ void ODBCStatementImpl::clear()
}
}
bool ODBCStatementImpl::nextResultSet()
{
SQLRETURN ret = SQLMoreResults(_stmt);
if (SQL_NO_DATA == ret)
return false;
if (Utility::isError(ret)) {
throw StatementException(_stmt, "SQLMoreResults()");
}
// need to remove old bindings, as Sybase doesn't like old ones
if (Utility::isError(SQLFreeStmt(_stmt, SQL_UNBIND))) {
throw StatementException(_stmt, "SQLFreeStmt(SQL_UNBIND)");
}
return true;
}
bool ODBCStatementImpl::hasNext()
{
@ -296,17 +335,29 @@ bool ODBCStatementImpl::hasNext()
if (!nextRowReady())
{
if (hasMoreDataSets()) activateNextDataSet();
else return false;
if (SQL_NO_DATA == SQLMoreResults(_stmt))
return false;
addPreparator();
doPrepare();
fixupExtraction();
makeStep();
}
// have a loop here, as there could be one or more empty results
do {
if (hasMoreDataSets()) {
activateNextDataSet();
if (!nextResultSet())
return false;
addPreparator();
}
else {
if (nextResultSet()) {
if (!addPreparator(false)) // skip the result set if it has no columns
continue;
fillColumns(currentDataSet() + 1);
makeExtractors(_preparations.back()->columns(), static_cast<Position::PositionType>(currentDataSet() + 1));
activateNextDataSet();
}
else return false;
}
doPrepare();
fixupExtraction();
makeStep();
} while (!nextRowReady());
}
else if (Utility::isError(_nextResponse))
checkError(_nextResponse, "SQLFetch()");
@ -405,15 +456,16 @@ void ODBCStatementImpl::checkError(SQLRETURN rc, const std::string& msg)
}
void ODBCStatementImpl::fillColumns()
void ODBCStatementImpl::fillColumns(size_t dataSetPos)
{
std::size_t colCount = columnsReturned();
std::size_t curDataSet = currentDataSet();
if (curDataSet >= _columnPtrs.size())
_columnPtrs.resize(curDataSet + 1);
poco_assert_dbg(dataSetPos < _preparations.size());
poco_assert_dbg(_preparations[dataSetPos]);
std::size_t colCount = static_cast<std::size_t>(_preparations[dataSetPos]->columns());
if (dataSetPos >= _columnPtrs.size())
_columnPtrs.resize(dataSetPos + 1);
for (int i = 0; i < colCount; ++i)
_columnPtrs[curDataSet].push_back(new ODBCMetaColumn(_stmt, i));
_columnPtrs[dataSetPos].push_back(new ODBCMetaColumn(_stmt, i, _numericConversion));
}
@ -426,17 +478,16 @@ bool ODBCStatementImpl::isStoredProcedure() const
}
const MetaColumn& ODBCStatementImpl::metaColumn(std::size_t pos) const
const MetaColumn& ODBCStatementImpl::metaColumn(std::size_t pos, size_t dataSet) const
{
std::size_t curDataSet = currentDataSet();
poco_assert_dbg (curDataSet < _columnPtrs.size());
poco_assert_dbg(dataSet < _columnPtrs.size());
std::size_t sz = _columnPtrs[curDataSet].size();
std::size_t sz = _columnPtrs[dataSet].size();
if (0 == sz || pos > sz - 1)
throw InvalidAccessException(format("Invalid column number: %u", pos));
return *_columnPtrs[curDataSet][pos];
return *_columnPtrs[dataSet][pos];
}
@ -453,4 +504,10 @@ int ODBCStatementImpl::affectedRowCount() const
}
void ODBCStatementImpl::insertHint()
{
_insertHint = true;
}
} } } // namespace Poco::Data::ODBC

View File

@ -30,21 +30,35 @@ namespace ODBC {
Preparator::Preparator(const StatementHandle& rStmt,
const std::string& statement,
std::size_t maxFieldSize,
DataExtraction dataExtraction):
DataExtraction dataExtraction,
ODBCMetaColumn::NumericConversion numericConversion,
bool isPostgres) :
_rStmt(rStmt),
_maxFieldSize(maxFieldSize),
_dataExtraction(dataExtraction)
_dataExtraction(dataExtraction),
_numericConversion(numericConversion)
{
SQLCHAR* pStr = (SQLCHAR*) statement.c_str();
if (Utility::isError(Poco::Data::ODBC::SQLPrepare(_rStmt, pStr, (SQLINTEGER) statement.length())))
throw StatementException(_rStmt);
// PostgreSQL error swallowing workaround:
// Postgres may execute a statement with sintax error fine,
// but would return error once num of columns requested!
if (isPostgres)
{
SQLSMALLINT t = 0;
SQLRETURN r = SQLNumResultCols(rStmt, &t);
if (r != SQL_NO_DATA && Utility::isError(r))
throw StatementException(rStmt, "Failed to get number of columns");
}
}
Preparator::Preparator(const Preparator& other):
_rStmt(other._rStmt),
_maxFieldSize(other._maxFieldSize),
_dataExtraction(other._dataExtraction)
_dataExtraction(other._dataExtraction),
_numericConversion(other._numericConversion)
{
resize();
}
@ -155,7 +169,7 @@ std::size_t Preparator::maxDataSize(std::size_t pos) const
try
{
ODBCMetaColumn mc(_rStmt, pos);
ODBCMetaColumn mc(_rStmt, pos, _numericConversion);
sz = mc.length();
// accommodate for terminating zero (non-bulk only!)

View File

@ -29,6 +29,8 @@ namespace Data {
namespace ODBC {
const char* const SessionImpl::NUMERIC_CONVERSION_PROPERTY= "numericConversion";
SessionImpl::SessionImpl(const std::string& connect,
std::size_t loginTimeout,
std::size_t maxFieldSize,
@ -39,13 +41,12 @@ SessionImpl::SessionImpl(const std::string& connect,
_maxFieldSize(maxFieldSize),
_autoBind(autoBind),
_autoExtract(autoExtract),
_numericConversion(ODBCMetaColumn::NC_BEST_FIT),
_canTransact(ODBC_TXN_CAPABILITY_UNKNOWN),
_inTransaction(false),
_queryTimeout(-1)
{
setFeature("bulk", true);
open();
setProperty("handle", _db.handle());
init();
}
@ -62,6 +63,15 @@ SessionImpl::SessionImpl(const std::string& connect,
_inTransaction(false),
_queryTimeout(-1)
{
init();
}
void SessionImpl::init()
{
addProperty(NUMERIC_CONVERSION_PROPERTY,
&SessionImpl::setNumericConversion,
&SessionImpl::numericConversion);
setFeature("bulk", true);
open();
setProperty("handle", _db.handle());
@ -72,7 +82,7 @@ SessionImpl::~SessionImpl()
{
try
{
if (isTransaction() && !getFeature("autoCommit"))
if (static_cast<bool>(_db) && isTransaction() && !getFeature("autoCommit"))
{
try { rollback(); }
catch (...) { }
@ -107,13 +117,13 @@ void SessionImpl::open(const std::string& connect)
poco_assert_dbg (!connectionString().empty());
SQLULEN tout = static_cast<SQLULEN>(getLoginTimeout());
if (Utility::isError(SQLSetConnectAttr(_db, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) tout, 0)))
if (Utility::isError(Poco::Data::ODBC::SQLSetConnectAttr(_db, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER)tout, 0)))
{
if (Utility::isError(SQLGetConnectAttr(_db, SQL_ATTR_LOGIN_TIMEOUT, &tout, 0, 0)) ||
if (Utility::isError(Poco::Data::ODBC::SQLGetConnectAttr(_db, SQL_ATTR_LOGIN_TIMEOUT, &tout, 0, 0)) ||
getLoginTimeout() != tout)
{
ConnectionError e(_db);
throw ConnectionFailedException(e.toString());
ConnectionException e(_db);
throw ConnectionFailedException(e.errorString(), e);
}
}
@ -129,10 +139,9 @@ void SessionImpl::open(const std::string& connect)
, &result
, SQL_DRIVER_NOPROMPT)))
{
ConnectionError err(_db);
std::string errStr = err.toString();
ConnectionException e(_db);
close();
throw ConnectionFailedException(errStr);
throw ConnectionFailedException(e.errorString(), e);
}
_dataTypes.fillTypeInfo(_db);
@ -171,7 +180,7 @@ bool SessionImpl::isConnected()
{
SQLULEN value = 0;
if (Utility::isError(Poco::Data::ODBC::SQLGetConnectAttr(_db,
if (!static_cast<bool>(_db) || Utility::isError(Poco::Data::ODBC::SQLGetConnectAttr(_db,
SQL_ATTR_CONNECTION_DEAD,
&value,
0,
@ -211,12 +220,18 @@ bool SessionImpl::canTransact()
if (ODBC_TXN_CAPABILITY_UNKNOWN == _canTransact)
{
SQLUSMALLINT ret;
checkError(Poco::Data::ODBC::SQLGetInfo(_db, SQL_TXN_CAPABLE, &ret, 0, 0),
"Failed to obtain transaction capability info.");
_canTransact = (SQL_TC_NONE != ret) ?
ODBC_TXN_CAPABILITY_TRUE :
ODBC_TXN_CAPABILITY_FALSE;
SQLRETURN res = Poco::Data::ODBC::SQLGetInfo(_db, SQL_TXN_CAPABLE, &ret, 0, 0);
if (!Utility::isError(res))
{
_canTransact = (SQL_TC_NONE != ret) ?
ODBC_TXN_CAPABILITY_TRUE :
ODBC_TXN_CAPABILITY_FALSE;
}
else
{
Error<SQLHDBC, SQL_HANDLE_DBC> err(_db);
_canTransact = ODBC_TXN_CAPABILITY_FALSE;
}
}
return ODBC_TXN_CAPABILITY_TRUE == _canTransact;
@ -239,14 +254,14 @@ void SessionImpl::setTransactionIsolation(Poco::UInt32 ti)
if (ti & Session::TRANSACTION_SERIALIZABLE)
isolation |= SQL_TXN_SERIALIZABLE;
checkError(SQLSetConnectAttr(_db, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER) isolation, 0));
checkError(Poco::Data::ODBC::SQLSetConnectAttr(_db, SQL_ATTR_TXN_ISOLATION, (SQLPOINTER)isolation, 0));
}
Poco::UInt32 SessionImpl::getTransactionIsolation()
{
SQLULEN isolation = 0;
checkError(SQLGetConnectAttr(_db, SQL_ATTR_TXN_ISOLATION,
checkError(Poco::Data::ODBC::SQLGetConnectAttr(_db, SQL_ATTR_TXN_ISOLATION,
&isolation,
0,
0));
@ -271,7 +286,7 @@ bool SessionImpl::hasTransactionIsolation(Poco::UInt32 ti)
Poco::UInt32 SessionImpl::getDefaultTransactionIsolation()
{
SQLUINTEGER isolation = 0;
checkError(SQLGetInfo(_db, SQL_DEFAULT_TXN_ISOLATION,
checkError(Poco::Data::ODBC::SQLGetInfo(_db, SQL_DEFAULT_TXN_ISOLATION,
&isolation,
0,
0));

View File

@ -16,6 +16,7 @@
#include "Poco/Data/ODBC/TypeInfo.h"
#include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/LOB.h"
#include "Poco/Format.h"
#include "Poco/Exception.h"
#include <iostream>
@ -30,6 +31,17 @@ TypeInfo::TypeInfo(SQLHDBC* pHDBC): _pHDBC(pHDBC)
fillCTypes();
fillSQLTypes();
if (_pHDBC) fillTypeInfo(*_pHDBC);
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(std::string), SQL_C_CHAR));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(std::wstring), SQL_C_WCHAR));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(Poco::UTF16String), SQL_C_WCHAR));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(Date), SQL_TYPE_DATE));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(Time), SQL_TYPE_TIME));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(DateTime), SQL_TYPE_TIMESTAMP));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(BLOB), SQL_BINARY));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(float), SQL_REAL));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(double), SQL_DOUBLE));
_cppDataTypes.insert(CppTypeInfoMap::value_type(&typeid(bool), SQL_BIT));
}
@ -102,7 +114,7 @@ void TypeInfo::fillTypeInfo(SQLHDBC pHDBC)
if (!SQL_SUCCEEDED(rc))
throw StatementException(hstmt, "SQLGetData()");
rc = SQLGetTypeInfo(hstmt, SQL_ALL_TYPES);
rc = Poco::Data::ODBC::SQLGetTypeInfo(hstmt, SQL_ALL_TYPES);
if (SQL_SUCCEEDED(rc))
{
while (SQLFetch(hstmt) != SQL_NO_DATA_FOUND)
@ -264,4 +276,43 @@ void TypeInfo::print(std::ostream& ostr)
}
SQLSMALLINT TypeInfo::tryTypeidToCType(const std::type_info& ti, SQLSMALLINT defaultVal) const
{
CppTypeInfoMap::const_iterator res = _cppDataTypes.find(&ti);
if (res == _cppDataTypes.end())
return defaultVal;
return res->second;
}
SQLSMALLINT TypeInfo::nullDataType(const NullData val) const
{
switch (val)
{
case NULL_GENERIC:
case DATA_NULL_INTEGER:
return SQL_C_TINYINT;
case DATA_NULL_STRING:
return SQL_C_CHAR;
case DATA_NULL_DATE:
return SQL_C_TYPE_DATE;
case DATA_NULL_TIME:
return SQL_C_TYPE_TIME;
case DATA_NULL_DATETIME:
return SQL_C_TYPE_TIMESTAMP;
case DATA_NULL_BLOB:
return SQL_C_BINARY;
case DATA_NULL_FLOAT:
return SQL_C_FLOAT;
}
return SQL_C_TINYINT;
}
} } } // namespace Poco::Data::ODBC

View File

@ -31,6 +31,7 @@ using Poco::TextConverter;
using Poco::InvalidArgumentException;
using Poco::NotImplementedException;
#ifdef POCO_ODBC_UNICODE
namespace Poco {
namespace Data {
@ -775,3 +776,4 @@ SQLRETURN SQLDrivers(SQLHENV henv,
} } } // namespace Poco::Data::ODBC
#endif

View File

@ -43,7 +43,7 @@ Utility::DriverMap& Utility::drivers(Utility::DriverMap& driverMap)
SQLSMALLINT len2 = length;
RETCODE rc = 0;
if (!Utility::isError(rc = SQLDrivers(henv,
if (!Utility::isError(rc = Poco::Data::ODBC::SQLDrivers(henv,
SQL_FETCH_FIRST,
desc,
length,
@ -59,7 +59,7 @@ Utility::DriverMap& Utility::drivers(Utility::DriverMap& driverMap)
std::memset(desc, 0, length);
std::memset(attr, 0, length);
len2 = length;
}while (!Utility::isError(rc = SQLDrivers(henv,
}while (!Utility::isError(rc = Poco::Data::ODBC::SQLDrivers(henv,
SQL_FETCH_NEXT,
desc,
length,

View File

@ -29,7 +29,7 @@ endif
objects = ODBCTestSuite Driver \
ODBCDB2Test ODBCMySQLTest ODBCOracleTest ODBCPostgreSQLTest \
ODBCSQLiteTest ODBCSQLServerTest ODBCTest SQLExecutor
ODBCSQLiteTest ODBCSQLServerTest ODBCTest SQLExecutor ODBCSybaseTest
ifeq ($(POCO_CONFIG),MinGW)
objects += ODBCAccessTest

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="UTF-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug_shared|Win32">
@ -129,7 +129,7 @@
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -140,6 +140,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitd.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -189,7 +190,7 @@
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -200,6 +201,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmtd.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -249,7 +251,7 @@
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -260,6 +262,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmdd.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -314,6 +317,7 @@
<ClInclude Include="src\ODBCTest.h"/>
<ClInclude Include="src\ODBCTestSuite.h"/>
<ClInclude Include="src\SQLExecutor.h"/>
<ClInclude Include="src\ODBCSybaseTest.h"/>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Driver.cpp"/>
@ -327,6 +331,7 @@
<ClCompile Include="src\ODBCTest.cpp"/>
<ClCompile Include="src\ODBCTestSuite.cpp"/>
<ClCompile Include="src\SQLExecutor.cpp"/>
<ClCompile Include="src\ODBCSybaseTest.cpp"/>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>

View File

@ -54,8 +54,11 @@
<ClInclude Include="src\SQLExecutor.h">
<Filter>ODBC\Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ODBCSybaseTest.h">
<Filter>ODBC\Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ODBCTestSuite.h">
<Filter>_Suite\Header Files</Filter>
<Filter>ODBC\Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
@ -92,5 +95,8 @@
<ClCompile Include="src\Driver.cpp">
<Filter>_Driver\Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ODBCSybaseTest.cpp">
<Filter>ODBC\Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -322,6 +322,7 @@
<ClInclude Include="src\ODBCTest.h"/>
<ClInclude Include="src\SQLExecutor.h"/>
<ClInclude Include="src\ODBCTestSuite.h"/>
<ClInclude Include="src\ODBCSybaseTest.h"/>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ODBCAccessTest.cpp"/>
@ -334,6 +335,7 @@
<ClCompile Include="src\ODBCTest.cpp"/>
<ClCompile Include="src\SQLExecutor.cpp"/>
<ClCompile Include="src\ODBCTestSuite.cpp"/>
<ClCompile Include="src\/ODBCSybaseTest.cpp"/>
<ClCompile Include="src\WinDriver.cpp"/>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="debug_shared|x64">
@ -32,7 +32,7 @@
<RootNamespace>TestSuite</RootNamespace>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<CharacterSet>MultiByte</CharacterSet>
@ -63,27 +63,27 @@
<CharacterSet>MultiByte</CharacterSet>
<PlatformToolset>v120</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props"/>
<ImportGroup Label="ExtensionSettings"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_md|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_md|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_static_mt|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_static_mt|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='release_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'" Label="PropertySheets">
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props"/>
<Import Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros"/>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<_ProjectFileVersion>12.0.30501.0</_ProjectFileVersion>
<TargetName Condition="'$(Configuration)|$(Platform)'=='debug_shared|x64'">TestSuited</TargetName>
@ -129,17 +129,18 @@
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitd.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -167,10 +168,11 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnit.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -189,17 +191,18 @@
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmtd.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -227,10 +230,11 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmt.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -249,17 +253,18 @@
<AdditionalIncludeDirectories>..\include;..\..\..\CppUnit\include;..\..\..\CppUnit\WinTestRunner\include;..\..\..\Foundation\include;..\..\..\Data\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmdd.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -287,10 +292,11 @@
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
<PrecompiledHeader/>
<PrecompiledHeader />
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmd.lib;iphlpapi.lib;winmm.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -304,30 +310,32 @@
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="src\ODBCAccessTest.h"/>
<ClInclude Include="src\ODBCDB2Test.h"/>
<ClInclude Include="src\ODBCMySQLTest.h"/>
<ClInclude Include="src\ODBCOracleTest.h"/>
<ClInclude Include="src\ODBCPostgreSQLTest.h"/>
<ClInclude Include="src\ODBCSQLiteTest.h"/>
<ClInclude Include="src\ODBCSQLServerTest.h"/>
<ClInclude Include="src\ODBCTest.h"/>
<ClInclude Include="src\ODBCTestSuite.h"/>
<ClInclude Include="src\SQLExecutor.h"/>
<ClInclude Include="src\ODBCAccessTest.h" />
<ClInclude Include="src\ODBCDB2Test.h" />
<ClInclude Include="src\ODBCMySQLTest.h" />
<ClInclude Include="src\ODBCOracleTest.h" />
<ClInclude Include="src\ODBCPostgreSQLTest.h" />
<ClInclude Include="src\ODBCSQLiteTest.h" />
<ClInclude Include="src\ODBCSQLServerTest.h" />
<ClInclude Include="src\ODBCTest.h" />
<ClInclude Include="src\ODBCTestSuite.h" />
<ClInclude Include="src\SQLExecutor.h" />
<ClInclude Include="src\ODBCSybaseTest.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\Driver.cpp"/>
<ClCompile Include="src\ODBCAccessTest.cpp"/>
<ClCompile Include="src\ODBCDB2Test.cpp"/>
<ClCompile Include="src\ODBCMySQLTest.cpp"/>
<ClCompile Include="src\ODBCOracleTest.cpp"/>
<ClCompile Include="src\ODBCPostgreSQLTest.cpp"/>
<ClCompile Include="src\ODBCSQLiteTest.cpp"/>
<ClCompile Include="src\ODBCSQLServerTest.cpp"/>
<ClCompile Include="src\ODBCTest.cpp"/>
<ClCompile Include="src\ODBCTestSuite.cpp"/>
<ClCompile Include="src\SQLExecutor.cpp"/>
<ClCompile Include="src\Driver.cpp" />
<ClCompile Include="src\ODBCAccessTest.cpp" />
<ClCompile Include="src\ODBCDB2Test.cpp" />
<ClCompile Include="src\ODBCMySQLTest.cpp" />
<ClCompile Include="src\ODBCOracleTest.cpp" />
<ClCompile Include="src\ODBCPostgreSQLTest.cpp" />
<ClCompile Include="src\ODBCSQLiteTest.cpp" />
<ClCompile Include="src\ODBCSQLServerTest.cpp" />
<ClCompile Include="src\ODBCTest.cpp" />
<ClCompile Include="src\ODBCTestSuite.cpp" />
<ClCompile Include="src\SQLExecutor.cpp" />
<ClCompile Include="src\ODBCSybaseTest.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets"/>
<ImportGroup Label="ExtensionTargets"/>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@ -57,6 +57,9 @@
<ClInclude Include="src\ODBCTestSuite.h">
<Filter>_Suite\Header Files</Filter>
</ClInclude>
<ClInclude Include="src\ODBCSybaseTest.h">
<Filter>ODBC\Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="src\ODBCAccessTest.cpp">
@ -89,8 +92,14 @@
<ClCompile Include="src\ODBCTestSuite.cpp">
<Filter>_Suite\Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ODBCSybaseTest.cpp">
<Filter>_Suite\Source Files</Filter>
</ClCompile>
<ClCompile Include="src\Driver.cpp">
<Filter>_Driver\Source Files</Filter>
</ClCompile>
<ClCompile Include="src\ODBCSybaseTest.cpp">
<Filter>ODBC\Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -114,8 +114,8 @@ void ODBCAccessTest::dropTable(const std::string& tableName)
void ODBCAccessTest::recreatePersonTable()
{
dropTable("Person");
*_pSession << "CREATE TABLE Person (LastName TEXT(30), FirstName TEXT(30), Address TEXT(30), Age INTEGER)", now;
dropTable(ExecUtil::person());
*_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName TEXT(30), FirstName TEXT(30), Address TEXT(30), Age INTEGER)", now;
}
@ -176,7 +176,7 @@ void ODBCAccessTest::setUp()
void ODBCAccessTest::tearDown()
{
dropTable("Person");
dropTable(ExecUtil::person());
}

View File

@ -21,11 +21,13 @@
#include "Poco/Exception.h"
#include "Poco/Data/LOB.h"
#include "Poco/Data/StatementImpl.h"
#include "Poco/Data/RecordSet.h"
#include "Poco/Data/ODBC/Connector.h"
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/ODBC/Diagnostics.h"
#include "Poco/Data/ODBC/ODBCException.h"
#include "Poco/Data/ODBC/ODBCStatementImpl.h"
#include "Poco/Environment.h"
#include <sqltypes.h>
#include <iostream>
@ -43,29 +45,58 @@ using Poco::AnyCast;
using Poco::DynamicAny;
using Poco::NotFoundException;
static std::string db2Driver()
{
return Poco::Environment::get("POCO_TEST_DB2_DRIVER",
#if defined(POCO_OS_FAMILY_WINDOWS)
"IBM DB2 ODBC DRIVER - DB2COPY1"
#else
"libdb2o.so"
#endif
);
}
static std::string db2Uid()
{
return Poco::Environment::get("POCO_TEST_DB2_UID", "db2admin");
}
static std::string db2Db()
{
return Poco::Environment::get("POCO_TEST_DB2_DB", "POCOTEST");
}
static std::string db2Pwd()
{
return Poco::Environment::get("POCO_TEST_DB2_PWD", "db2admin");
}
static std::string db2Extra()
{
std::string e = Poco::Environment::get("POCO_TEST_DB2_EXTRA", "");
return (e.empty() ? "" : e + ";");
}
#define DB2_ODBC_DRIVER "IBM DB2 ODBC DRIVER - DB2COPY1"
#define DB2_DSN "PocoDataDB2Test"
#define DB2_SERVER POCO_ODBC_TEST_DATABASE_SERVER
#define DB2_PORT "50000"
#define DB2_DB "POCOTEST"
#define DB2_UID "db2admin"
#define DB2_PWD "db2admin"
ODBCTest::SessionPtr ODBCDB2Test::_pSession;
ODBCTest::ExecPtr ODBCDB2Test::_pExecutor;
std::string ODBCDB2Test::_driver = DB2_ODBC_DRIVER;
std::string ODBCDB2Test::_driver = db2Driver();
std::string ODBCDB2Test::_dsn = DB2_DSN;
std::string ODBCDB2Test::_uid = DB2_UID;
std::string ODBCDB2Test::_pwd = DB2_PWD;
std::string ODBCDB2Test::_connectString = "Driver=" DB2_ODBC_DRIVER ";"
"Database=" DB2_DB ";"
std::string ODBCDB2Test::_uid = db2Uid();
std::string ODBCDB2Test::_pwd = db2Pwd();
std::string ODBCDB2Test::_connectString = "Driver=" + db2Driver() + ";"
+ db2Extra() +
"Database=" + db2Db() + ";"
"Hostname=" DB2_SERVER ";"
"Port=" DB2_PORT ";"
"Protocol=TCPIP;"
"Uid=" DB2_UID ";"
"Pwd=" DB2_PWD ";";
"Uid=" + db2Uid() + ";"
"Pwd=" + db2Pwd() + ";"
;
ODBCDB2Test::ODBCDB2Test(const std::string& name):
@ -81,9 +112,9 @@ ODBCDB2Test::~ODBCDB2Test()
void ODBCDB2Test::testBareboneODBC()
{
if (!_pSession) fail ("Test not available.");
if (! &session()) fail ("Test not available.");
std::string tableCreateString = "CREATE TABLE Test "
std::string tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third BLOB,"
@ -91,55 +122,55 @@ void ODBCDB2Test::testBareboneODBC()
"Fifth FLOAT,"
"Sixth TIMESTAMP)";
_pExecutor->bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
_pExecutor->bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
tableCreateString = "CREATE TABLE Test "
tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second INTEGER,"
"Third FLOAT)";
_pExecutor->bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
_pExecutor->bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
executor().bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_MANUAL);
executor().bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_IMMEDIATE, SQLExecutor::DE_BOUND);
executor().bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
executor().bareboneODBCMultiResultTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
}
void ODBCDB2Test::testBLOB()
{
if (!_pSession) fail ("Test not available.");
if (! &session()) fail ("Test not available.");
const std::size_t maxFldSize = 1000000;
_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize-1));
session().setProperty("maxFieldSize", Poco::Any(maxFldSize-1));
recreatePersonBLOBTable();
try
{
_pExecutor->blob(maxFldSize);
executor().blob(maxFldSize);
fail ("must fail");
}
catch (DataException&)
{
_pSession->setProperty("maxFieldSize", Poco::Any(maxFldSize));
session().setProperty("maxFieldSize", Poco::Any(maxFldSize));
}
for (int i = 0; i < 8;)
{
recreatePersonBLOBTable();
_pSession->setFeature("autoBind", bindValue(i));
_pSession->setFeature("autoExtract", bindValue(i+1));
_pExecutor->blob(maxFldSize);
session().setFeature("autoBind", bindValue(i));
session().setFeature("autoExtract", bindValue(i+1));
executor().blob(maxFldSize);
i += 2;
}
recreatePersonBLOBTable();
try
{
_pExecutor->blob(maxFldSize+1);
executor().blob(maxFldSize+1);
fail ("must fail");
}
catch (DataException&) { }
@ -148,14 +179,14 @@ void ODBCDB2Test::testBLOB()
void ODBCDB2Test::testFilter()
{
if (!_pSession) fail ("Test not available.");
if (! &session()) fail ("Test not available.");
for (int i = 0; i < 8;)
{
recreateVectorsTable();
_pSession->setFeature("autoBind", bindValue(i));
_pSession->setFeature("autoExtract", bindValue(i+1));
_pExecutor->filter("SELECT * FROM Vectors ORDER BY i0 ASC", "i0");
session().setFeature("autoBind", bindValue(i));
session().setFeature("autoExtract", bindValue(i+1));
executor().filter("SELECT * FROM " + ExecUtil::vectors() + " ORDER BY i0 ASC", "i0");
i += 2;
}
}
@ -163,50 +194,54 @@ void ODBCDB2Test::testFilter()
void ODBCDB2Test::testStoredProcedure()
{
if (!_pSession) fail ("Test not available.");
if (! &session()) fail ("Test not available.");
const std::string nm = ExecUtil::stored_proc();
dropObject("PROCEDURE", nm + "(INTEGER)");
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
dropObject("PROCEDURE", nm + "(VARCHAR(1000), VARCHAR(1000))");
for (int k = 0; k < 8;)
{
_pSession->setFeature("autoBind", bindValue(k));
_pSession->setFeature("autoExtract", bindValue(k+1));
session().setFeature("autoBind", bindValue(k));
session().setFeature("autoExtract", bindValue(k+1));
dropObject("PROCEDURE", "storedProcedure");
*_pSession << "CREATE PROCEDURE storedProcedure(OUT outParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(OUT outParam INTEGER) "
"BEGIN "
" SET outParam = -1; "
"END" , now;
int i = 0;
*_pSession << "{call storedProcedure(?)}", out(i), now;
session() << "{call " + db2Db() + "." << nm << "(?)}", out(i), now;
dropObject("PROCEDURE", nm + "(INTEGER)");
assert(-1 == i);
dropObject("PROCEDURE", "storedProcedure");
*_pSession << "CREATE PROCEDURE storedProcedure(inParam INTEGER, OUT outParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(inParam INTEGER, OUT outParam INTEGER) "
"BEGIN "
" SET outParam = inParam*inParam; "
"END" , now;
i = 2;
int j = 0;
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
session() << "{call " + db2Db() + "." << nm << "(?, ?)}", in(i), out(j), now;
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
assert(4 == j);
dropObject("PROCEDURE", "storedProcedure");
*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(INOUT ioParam INTEGER) "
"BEGIN "
" SET ioParam = ioParam*ioParam; "
"END" , now;
i = 2;
*_pSession << "{call storedProcedure(?)}", io(i), now;
session() << "{call " + db2Db() + "." << nm << "(?)}", io(i), now;
dropObject("PROCEDURE", nm + "(INTEGER)");
assert(4 == i);
dropObject("PROCEDURE", "storedProcedure");
//TIMESTAMP is not supported as stored procedure parameter in DB2
//(SQL0182N An expression with a datetime value or a labeled duration is not valid.)
*_pSession << "CREATE PROCEDURE storedProcedure(inParam VARCHAR(1000), OUT outParam VARCHAR(1000)) "
session() << "CREATE PROCEDURE " << nm << "(inParam VARCHAR(1000), OUT outParam VARCHAR(1000)) "
"BEGIN "
" SET outParam = inParam; "
"END" , now;
@ -222,9 +257,9 @@ void ODBCDB2Test::testStoredProcedure()
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890"
"1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890";
std::string outParam;
*_pSession << "{call storedProcedure(?,?)}", in(inParam), out(outParam), now;
session() << "{call " + db2Db() + "." << nm << "(?,?)}", in(inParam), out(outParam), now;
dropObject("PROCEDURE", nm + "(VARCHAR(1000), VARCHAR(1000))");
assert(inParam == outParam);
dropObject("PROCEDURE", "storedProcedure");
k += 2;
}
@ -233,35 +268,39 @@ void ODBCDB2Test::testStoredProcedure()
void ODBCDB2Test::testStoredProcedureAny()
{
if (!_pSession) fail ("Test not available.");
if (! &session()) fail ("Test not available.");
const std::string nm = ExecUtil::stored_proc();
dropObject("PROCEDURE", nm + "(INTEGER)");
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
for (int k = 0; k < 8;)
{
_pSession->setFeature("autoBind", bindValue(k));
_pSession->setFeature("autoExtract", bindValue(k+1));
session().setFeature("autoBind", bindValue(k));
session().setFeature("autoExtract", bindValue(k+1));
Any i = 2;
Any j = 0;
*_pSession << "CREATE PROCEDURE storedProcedure(inParam INTEGER, OUT outParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(inParam INTEGER, OUT outParam INTEGER) "
"BEGIN "
" SET outParam = inParam*inParam; "
"END" , now;
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
session() << "{call " + db2Db() + "." << nm << "(?, ?)}", in(i), out(j), now;
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
assert(4 == AnyCast<int>(j));
*_pSession << "DROP PROCEDURE storedProcedure;", now;
*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(INOUT ioParam INTEGER) "
"BEGIN "
" SET ioParam = ioParam*ioParam; "
"END" , now;
i = 2;
*_pSession << "{call storedProcedure(?)}", io(i), now;
session() << "{call " + db2Db() + "." << nm << "(?)}", io(i), now;
dropObject("PROCEDURE", nm + "(INTEGER)");
assert(4 == AnyCast<int>(i));
dropObject("PROCEDURE", "storedProcedure");
k += 2;
}
}
@ -269,33 +308,37 @@ void ODBCDB2Test::testStoredProcedureAny()
void ODBCDB2Test::testStoredProcedureDynamicAny()
{
if (!_pSession) fail ("Test not available.");
if (! &session()) fail ("Test not available.");
const std::string nm = ExecUtil::stored_proc();
dropObject("PROCEDURE", nm + "(INTEGER)");
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
for (int k = 0; k < 8;)
{
_pSession->setFeature("autoBind", bindValue(k));
session().setFeature("autoBind", bindValue(k));
DynamicAny i = 2;
DynamicAny j = 0;
*_pSession << "CREATE PROCEDURE storedProcedure(inParam INTEGER, OUT outParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(inParam INTEGER, OUT outParam INTEGER) "
"BEGIN "
" SET outParam = inParam*inParam; "
"END" , now;
*_pSession << "{call storedProcedure(?, ?)}", in(i), out(j), now;
session() << "{call " + db2Db() + "." << nm << "(?, ?)}", in(i), out(j), now;
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
assert(4 == j);
*_pSession << "DROP PROCEDURE storedProcedure;", now;
*_pSession << "CREATE PROCEDURE storedProcedure(INOUT ioParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(INOUT ioParam INTEGER) "
"BEGIN "
" SET ioParam = ioParam*ioParam; "
"END" , now;
i = 2;
*_pSession << "{call storedProcedure(?)}", io(i), now;
session() << "{call " + db2Db() + "." << nm << "(?)}", io(i), now;
dropObject("PROCEDURE", nm + "(INTEGER)");
assert(4 == i);
dropObject("PROCEDURE", "storedProcedure");
k += 2;
}
@ -304,36 +347,89 @@ void ODBCDB2Test::testStoredProcedureDynamicAny()
void ODBCDB2Test::testStoredFunction()
{
if (!_pSession) fail ("Test not available.");
const std::string nm = ExecUtil::stored_func();
if (! &session()) fail ("Test not available.");
dropObject("PROCEDURE", nm + "()");
dropObject("PROCEDURE", nm + "(INTEGER)");
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
dropObject("PROCEDURE", nm + "(VARCHAR(10), DATE, TIME, TIMESTAMP, INTEGER, SMALLINT, REAL, DOUBLE, VARCHAR(10), INTEGER)");
dropObject("PROCEDURE", nm + "(VARCHAR(10), VARCHAR(10))");
for (int k = 0; k < 8;)
{
_pSession->setFeature("autoBind", bindValue(k));
_pSession->setFeature("autoExtract", bindValue(k+1));
session().setFeature("autoBind", bindValue(k));
session().setFeature("autoExtract", bindValue(k + 1));
dropObject("PROCEDURE", "storedFunction");
*_pSession << "CREATE PROCEDURE storedFunction() "
{
session() << "CREATE PROCEDURE " << nm << "() "
"BEGIN "
" DECLARE C1 CURSOR FOR select * from sysibm.sysdummy1 where 1=2;"
" OPEN C1;"
" RETURN;"
"END", now;
Poco::Data::Statement stat(session());
stat << "{ call " + db2Db() + "." << nm << "()}", now;
Poco::Data::RecordSet rs(stat);
assert(0 == rs.rowCount());
dropObject("PROCEDURE", nm + "()");
}
{
session() << "CREATE PROCEDURE " << nm << "(inp VARCHAR(10), out dt DATE, out tm TIME, out tms TIMESTAMP, out int32 INTEGER, "
"out si SMALLINT, out fl REAL, out dbl DOUBLE, out s2 VARCHAR(10), out an INTEGER)"
"BEGIN "
"set dt =null; set tm =null; set tms =null; set int32 =null; set si =null; set fl =null; set dbl =null; set s2 = inp; set an = inp;"
"END", now;
Poco::Data::Statement stat(session());
Poco::Nullable<std::string> ns;
Poco::Nullable<Poco::Data::Date> nd = Poco::Nullable<Poco::Data::Date>(Poco::Data::Date());
Poco::Nullable<int> n_i(1);
Poco::Nullable<Poco::Data::Time> tm = Poco::Nullable<Poco::Data::Time>(Poco::Data::Time());
Poco::Nullable<Poco::DateTime> tms = Poco::Nullable<Poco::DateTime>(Poco::DateTime());
Poco::Nullable<Poco::Int16> i16(1);
Poco::Nullable<float> flt(1);
Poco::Nullable<double> dbl(1);
Poco::Nullable<std::string> s2("ddd");
Poco::Nullable<Any> an(Any(2));
stat << "{call " + db2Db() + "." << nm << "(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)}", useRef(ns), out(nd), out(tm), out(tms), out(n_i), out(i16), out(flt), out(dbl), out(s2), out(an), now;
dropObject("PROCEDURE", nm + "(VARCHAR(10), DATE, TIME, TIMESTAMP, INTEGER, SMALLINT, REAL, DOUBLE, VARCHAR(10), INTEGER)");
assert(nd.isNull());
assert(n_i.isNull());
assert(tm.isNull());
assert(tms.isNull());
assert(i16.isNull());
assert(flt.isNull());
assert(dbl.isNull());
assert(s2.isNull());
assert(an.isNull());
}
session() << "CREATE PROCEDURE " << nm << "() "
"BEGIN "
" RETURN -1; "
"END" , now;
int i = 0;
*_pSession << "{? = call storedFunction()}", out(i), now;
session() << "{? = call " + db2Db() + "." << nm << "()}", out(i), now;
dropObject("PROCEDURE", nm + "()");
assert(-1 == i);
dropObject("PROCEDURE", "storedFunction");
*_pSession << "CREATE PROCEDURE storedFunction(inParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(inParam INTEGER) "
"BEGIN "
" RETURN inParam*inParam; "
"END" , now;
i = 2;
int result = 0;
*_pSession << "{? = call storedFunction(?)}", out(result), in(i), now;
session() << "{? = call " + db2Db() + "." << nm << "(?)}", out(result), in(i), now;
dropObject("PROCEDURE", nm + "(INTEGER)");
assert(4 == result);
dropObject("PROCEDURE", "storedFunction");
*_pSession << "CREATE PROCEDURE storedFunction(inParam INTEGER, OUT outParam INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(inParam INTEGER, OUT outParam INTEGER) "
"BEGIN "
" SET outParam = inParam*inParam; "
" RETURN outParam; "
@ -342,12 +438,12 @@ void ODBCDB2Test::testStoredFunction()
i = 2;
int j = 0;
result = 0;
*_pSession << "{? = call storedFunction(?, ?)}", out(result), in(i), out(j), now;
session() << "{? = call " + db2Db() + "." << nm << "(?, ?)}", out(result), in(i), out(j), now;
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
assert(4 == j);
assert(j == result);
dropObject("PROCEDURE", "storedFunction");
*_pSession << "CREATE PROCEDURE storedFunction(INOUT param1 INTEGER, INOUT param2 INTEGER) "
session() << "CREATE PROCEDURE " << nm << "(INOUT param1 INTEGER, INOUT param2 INTEGER) "
"BEGIN "
" DECLARE temp INTEGER;"
" SET temp = param1; "
@ -359,7 +455,7 @@ void ODBCDB2Test::testStoredFunction()
i = 1;
j = 2;
result = 0;
*_pSession << "{? = call storedFunction(?, ?)}", out(result), io(i), io(j), now;
session() << "{? = call " + db2Db() + "." << nm << "(?, ?)}", out(result), io(i), io(j), now;
assert(1 == j);
assert(2 == i);
assert(3 == result);
@ -368,16 +464,15 @@ void ODBCDB2Test::testStoredFunction()
assert(1 == params.get<0>());
assert(2 == params.get<1>());
result = 0;
*_pSession << "{? = call storedFunction(?, ?)}", out(result), io(params), now;
session() << "{? = call " + db2Db() + "." << nm << "(?, ?)}", out(result), io(params), now;
dropObject("PROCEDURE", nm + "(INTEGER, INTEGER)");
assert(1 == params.get<1>());
assert(2 == params.get<0>());
assert(3 == result);
dropObject("PROCEDURE", "storedFunction");
session().setFeature("autoBind", true);
_pSession->setFeature("autoBind", true);
*_pSession << "CREATE PROCEDURE storedFunction(inParam VARCHAR(10), OUT outParam VARCHAR(10)) "
session() << "CREATE PROCEDURE " << nm << "(inParam VARCHAR(10), OUT outParam VARCHAR(10)) "
"BEGIN "
" SET outParam = inParam; "
" RETURN LENGTH(outParam);"//DB2 allows only integer as return type
@ -386,21 +481,74 @@ void ODBCDB2Test::testStoredFunction()
std::string inParam = "123456789";
std::string outParam;
int ret;
*_pSession << "{? = call storedFunction(?,?)}", out(ret), in(inParam), out(outParam), now;
session() << "{? = call " + db2Db() + "." << nm << "(?,?)}", out(ret), in(inParam), out(outParam), now;
dropObject("PROCEDURE", nm + "(VARCHAR(10), VARCHAR(10))");
assert(inParam == outParam);
assert(ret == inParam.size());
dropObject("PROCEDURE", "storedFunction");
k += 2;
}
}
void ODBCDB2Test::testXMLColumn()
{
const std::string tbl = ExecUtil::mangleTable("xmlColumn");
dropObject("TABLE", tbl);
try {
const std::string xmlStr = "<a> xml text </a>";
Poco::UTF16String uStr;
for (unsigned c = 0x400; c < 0x409; ++c) uStr.append(3, Poco::UTF16Char(c) );
session() << "CREATE TABLE " << tbl << " (id integer, x XML, cl CLOB, dbcl DBCLOB)", now;
session() << "INSERT INTO " << tbl << " (id , x, cl, dbcl) VALUES(1, '" << xmlStr << "', ?, ?)", bind(xmlStr), bind(uStr), now;
Poco::Data::Statement stat(session());
stat << "SELECT id, x,cl, dbcl FROM " << tbl, now;
Poco::Data::RecordSet rs(stat);
assert(1 == rs.rowCount());
assert(4 == rs.columnCount());
int id = rs.value<int>(0);
assert(1 == id);
Poco::Data::BLOB xml = rs.value<Poco::Data::BLOB>(1);
std::string readStr(reinterpret_cast<const char*>(xml.rawContent()), xml.size());
assert(readStr.find(xmlStr) < readStr.length());
Poco::Data::CLOB cl = rs.value<Poco::Data::CLOB>(2);
assert(xmlStr == std::string(cl.rawContent(), cl.size()));
const Poco::UTF16String us = rs.value<Poco::UTF16String>(3);
assert(uStr == us);
// check nullables
Poco::Nullable<Poco::Data::CLOB> ncl = Poco::Nullable<Poco::Data::CLOB>(Poco::Data::CLOB());
assert(false == ncl.isNull());
Poco::Nullable<Poco::Data::BLOB> nbl = Poco::Nullable<Poco::Data::BLOB>(Poco::Data::BLOB());
assert(false == nbl.isNull());
Poco::Nullable<Poco::UTF16String> usn(Poco::UTF16String(2, Poco::UTF16Char('a')));
assert(false == usn.isNull());
session() << "INSERT INTO " << tbl << " (id) VALUES (99) ", now;
session() << "SELECT x,cl, dbcl FROM " << tbl << " WHERE id > 1", into(nbl), into(ncl), into(usn), now;
assert(true == ncl.isNull());
assert(true == nbl.isNull());
assert(true == usn.isNull());
}
catch (const Poco::Exception& e)
{
dropObject("TABLE", tbl);
std::cerr << e.message() << std::endl;
throw;
}
dropObject("TABLE", tbl);
}
void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
{
try
{
*_pSession << format("DROP %s %s", type, name), now;
session() << format("DROP %s %s", type, name), now;
}
catch (StatementException& ex)
{
@ -408,8 +556,9 @@ void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
const StatementDiagnostics::FieldVec& flds = ex.diagnostics().fields();
StatementDiagnostics::Iterator it = flds.begin();
for (; it != flds.end(); ++it)
{
if (-204 == it->_nativeError)//(table does not exist)
{
//(table does not exist) // procedure not found
if (-204 == it->_nativeError || (-458 == it->_nativeError) )
{
ignoreError = true;
break;
@ -423,17 +572,28 @@ void ODBCDB2Test::dropObject(const std::string& type, const std::string& name)
void ODBCDB2Test::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
dropObject("TABLE", ExecUtil::nullabletest());
try { session() << "CREATE TABLE " << ExecUtil::nullabletest() << " (EmptyString VARCHAR(30), EmptyInteger INTEGER , EmptyFloat FLOAT , EmptyDateTime TIMESTAMP)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
void ODBCDB2Test::recreateNumericTable()
{
dropObject("TABLE", ExecUtil::numeric_tbl());
try {
session() << "CREATE TABLE " << ExecUtil::numeric_tbl() <<
" (id integer, num8 NUMERIC(8), num16_3 NUMERIC(16,3), num18 NUMERIC(18), num18_8 NUMERIC(18,8), num22 NUMERIC(22))", now;
}
catch (ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail("recreateNumericTable()"); }
catch (StatementException& se){ std::cout << se.toString() << std::endl; fail("recreateNumericTable()"); }
}
void ODBCDB2Test::recreatePersonTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() <<" (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -441,8 +601,8 @@ void ODBCDB2Test::recreatePersonTable()
void ODBCDB2Test::recreatePersonBLOBTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() <<" (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
}
@ -450,8 +610,8 @@ void ODBCDB2Test::recreatePersonBLOBTable()
void ODBCDB2Test::recreatePersonDateTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() <<" (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
}
@ -459,8 +619,8 @@ void ODBCDB2Test::recreatePersonDateTable()
void ODBCDB2Test::recreatePersonTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() <<" (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
}
@ -468,8 +628,8 @@ void ODBCDB2Test::recreatePersonTimeTable()
void ODBCDB2Test::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() <<" (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
}
@ -477,8 +637,8 @@ void ODBCDB2Test::recreatePersonDateTimeTable()
void ODBCDB2Test::recreateIntsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() << " (str INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
}
@ -486,8 +646,8 @@ void ODBCDB2Test::recreateIntsTable()
void ODBCDB2Test::recreateStringsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() << " (str VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateStringsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateStringsTable()"); }
}
@ -495,8 +655,8 @@ void ODBCDB2Test::recreateStringsTable()
void ODBCDB2Test::recreateFloatsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str FLOAT)", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() << " (str FLOAT)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
}
@ -504,8 +664,8 @@ void ODBCDB2Test::recreateFloatsTable()
void ODBCDB2Test::recreateTuplesTable()
{
dropObject("TABLE", "Tuples");
try { *_pSession << "CREATE TABLE Tuples "
dropObject("TABLE", ExecUtil::tuples());
try { session() << "CREATE TABLE " << ExecUtil::tuples() <<
"(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
"int7 INTEGER, int8 INTEGER, int9 INTEGER, int10 INTEGER, int11 INTEGER, int12 INTEGER, int13 INTEGER,"
"int14 INTEGER, int15 INTEGER, int16 INTEGER, int17 INTEGER, int18 INTEGER, int19 INTEGER)", now; }
@ -516,8 +676,8 @@ void ODBCDB2Test::recreateTuplesTable()
void ODBCDB2Test::recreateVectorsTable()
{
dropObject("TABLE", "Vectors");
try { *_pSession << "CREATE TABLE Vectors (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::vectors());
try { session() << "CREATE TABLE " << ExecUtil::vectors() << " (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateVectorsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateVectorsTable()"); }
}
@ -525,8 +685,8 @@ void ODBCDB2Test::recreateVectorsTable()
void ODBCDB2Test::recreateAnysTable()
{
dropObject("TABLE", "Anys");
try { *_pSession << "CREATE TABLE Anys (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::anys() );
try { session() << "CREATE TABLE " << ExecUtil::anys() << " (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
}
@ -534,8 +694,8 @@ void ODBCDB2Test::recreateAnysTable()
void ODBCDB2Test::recreateNullsTable(const std::string& notNull)
{
dropObject("TABLE", "NullTest");
try { *_pSession << format("CREATE TABLE NullTest (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)",
dropObject("TABLE", ExecUtil::nulltest());
try { session() << format("CREATE TABLE %s (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)", ExecUtil::nulltest(),
notNull,
notNull,
notNull), now; }
@ -546,10 +706,10 @@ void ODBCDB2Test::recreateNullsTable(const std::string& notNull)
void ODBCDB2Test::recreateMiscTable()
{
dropObject("TABLE", "MiscTest");
dropObject("TABLE", ExecUtil::misctest());
try
{
session() << "CREATE TABLE MiscTest "
session() << "CREATE TABLE " << ExecUtil::misctest() <<
"(First VARCHAR(30),"
"Second BLOB,"
"Third INTEGER,"
@ -562,8 +722,8 @@ void ODBCDB2Test::recreateMiscTable()
void ODBCDB2Test::recreateLogTable()
{
dropObject("TABLE", "T_POCO_LOG");
dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
dropObject("TABLE", ExecUtil::pocolog());;
dropObject("TABLE", ExecUtil::pocolog_a());;
try
{
@ -577,8 +737,8 @@ void ODBCDB2Test::recreateLogTable()
"Text VARCHAR(100),"
"DateTime TIMESTAMP)";
session() << sql, "T_POCO_LOG", now;
session() << sql, "T_POCO_LOG_ARCHIVE", now;
session() << sql, ExecUtil::pocolog(), now;
session() << sql, ExecUtil::pocolog_a(), now;
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
@ -597,6 +757,7 @@ CppUnit::Test* ODBCDB2Test::suite()
CppUnit_addTest(pSuite, ODBCDB2Test, testBareboneODBC);
CppUnit_addTest(pSuite, ODBCDB2Test, testZeroRows);
CppUnit_addTest(pSuite, ODBCDB2Test, testSyntaxError);
CppUnit_addTest(pSuite, ODBCDB2Test, testSimpleAccess);
CppUnit_addTest(pSuite, ODBCDB2Test, testComplexType);
CppUnit_addTest(pSuite, ODBCDB2Test, testSimpleAccessVector);
@ -666,13 +827,20 @@ CppUnit::Test* ODBCDB2Test::suite()
CppUnit_addTest(pSuite, ODBCDB2Test, testAny);
CppUnit_addTest(pSuite, ODBCDB2Test, testDynamicAny);
CppUnit_addTest(pSuite, ODBCDB2Test, testMultipleResults);
CppUnit_addTest(pSuite, ODBCDB2Test, testMultipleResultsNoProj);
CppUnit_addTest(pSuite, ODBCDB2Test, testSQLChannel);
CppUnit_addTest(pSuite, ODBCDB2Test, testSQLLogger);
CppUnit_addTest(pSuite, ODBCDB2Test, testSessionTransaction);
//CppUnit_addTest(pSuite, ODBCDB2Test, testSessionTransaction); // this test fails when connection is fast
CppUnit_addTest(pSuite, ODBCDB2Test, testTransaction);
CppUnit_addTest(pSuite, ODBCDB2Test, testTransactor);
CppUnit_addTest(pSuite, ODBCDB2Test, testNullable);
CppUnit_addTest(pSuite, ODBCDB2Test, testReconnect);
CppUnit_addTest(pSuite, ODBCDB2Test, testNumeric);
CppUnit_addTest(pSuite, ODBCDB2Test, testXMLColumn);
CppUnit_addTest(pSuite, ODBCDB2Test, testInsertStatReuse);
ODBCDB2Test::_pExecutor = 0;
ODBCDB2Test::_pSession = 0;
return pSuite;
}

View File

@ -41,6 +41,7 @@ public:
void testStoredProcedureAny();
void testStoredProcedureDynamicAny();
void testStoredFunction();
void testXMLColumn();
static CppUnit::Test* suite();
@ -61,6 +62,7 @@ private:
void recreateNullsTable(const std::string& notNull = "");
void recreateMiscTable();
void recreateLogTable();
void recreateNumericTable();
static ODBCTest::SessionPtr _pSession;
static ODBCTest::ExecPtr _pExecutor;

View File

@ -77,7 +77,7 @@ void ODBCMySQLTest::testBareboneODBC()
{
if (!_pSession) fail ("Test not available.");
std::string tableCreateString = "CREATE TABLE Test "
std::string tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third VARBINARY(30),"
@ -97,7 +97,7 @@ has different SQL syntax for it and behaves differently
compared to other DBMS systems in regards to SQLMoreResults.
So, we skip this test.
tableCreateString = "CREATE TABLE Test "
tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second INTEGER,"
"Third FLOAT)";
@ -236,7 +236,7 @@ void ODBCMySQLTest::testFilter()
recreateVectorsTable();
_pSession->setFeature("autoBind", bindValue(i));
_pSession->setFeature("autoExtract", bindValue(i+1));
_pExecutor->filter("SELECT * FROM Vectors ORDER BY i0 ASC", "i0");
_pExecutor->filter("SELECT * FROM " + ExecUtil::vectors() + " ORDER BY i0 ASC", "i0");
i += 2;
}
}
@ -250,8 +250,8 @@ void ODBCMySQLTest::dropObject(const std::string& type, const std::string& name)
void ODBCMySQLTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
dropObject("TABLE", ExecUtil::nullabletest());
try { *_pSession << "CREATE TABLE " << ExecUtil::nullabletest() << " (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -259,8 +259,8 @@ void ODBCMySQLTest::recreateNullableTable()
void ODBCMySQLTest::recreatePersonTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -268,8 +268,8 @@ void ODBCMySQLTest::recreatePersonTable()
void ODBCMySQLTest::recreatePersonBLOBTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
}
@ -277,8 +277,8 @@ void ODBCMySQLTest::recreatePersonBLOBTable()
void ODBCMySQLTest::recreatePersonDateTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
}
@ -286,8 +286,8 @@ void ODBCMySQLTest::recreatePersonDateTable()
void ODBCMySQLTest::recreatePersonTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
}
@ -295,8 +295,8 @@ void ODBCMySQLTest::recreatePersonTimeTable()
void ODBCMySQLTest::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born DATETIME)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born DATETIME)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
}
@ -304,8 +304,8 @@ void ODBCMySQLTest::recreatePersonDateTimeTable()
void ODBCMySQLTest::recreateIntsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
dropObject("TABLE", ExecUtil::strings());
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() << " (str INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
}
@ -313,8 +313,8 @@ void ODBCMySQLTest::recreateIntsTable()
void ODBCMySQLTest::recreateStringsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::strings());
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() << " (str VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateStringsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateStringsTable()"); }
}
@ -322,8 +322,8 @@ void ODBCMySQLTest::recreateStringsTable()
void ODBCMySQLTest::recreateFloatsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str FLOAT)", now; }
dropObject("TABLE", ExecUtil::strings());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (str FLOAT)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
}
@ -331,8 +331,8 @@ void ODBCMySQLTest::recreateFloatsTable()
void ODBCMySQLTest::recreateTuplesTable()
{
dropObject("TABLE", "Tuples");
try { *_pSession << "CREATE TABLE Tuples "
dropObject("TABLE", ExecUtil::tuples());
try { *_pSession << "CREATE TABLE " << ExecUtil::tuples() <<
"(i0 INTEGER, i1 INTEGER, i2 INTEGER, i3 INTEGER, i4 INTEGER, i5 INTEGER, i6 INTEGER, "
"i7 INTEGER, i8 INTEGER, i9 INTEGER, i10 INTEGER, i11 INTEGER, i12 INTEGER, i13 INTEGER,"
"i14 INTEGER, i15 INTEGER, i16 INTEGER, i17 INTEGER, i18 INTEGER, i19 INTEGER)", now; }
@ -343,8 +343,8 @@ void ODBCMySQLTest::recreateTuplesTable()
void ODBCMySQLTest::recreateVectorsTable()
{
dropObject("TABLE", "Vectors");
try { *_pSession << "CREATE TABLE Vectors (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::vectors() );
try { *_pSession << "CREATE TABLE " << ExecUtil::vectors() << " (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateVectorsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateVectorsTable()"); }
}
@ -352,8 +352,8 @@ void ODBCMySQLTest::recreateVectorsTable()
void ODBCMySQLTest::recreateAnysTable()
{
dropObject("TABLE", "Anys");
try { *_pSession << "CREATE TABLE Anys (i0 INTEGER, flt0 DOUBLE, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::anys() );
try { *_pSession << "CREATE TABLE " << ExecUtil::anys() << " (i0 INTEGER, flt0 DOUBLE, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
}
@ -361,8 +361,8 @@ void ODBCMySQLTest::recreateAnysTable()
void ODBCMySQLTest::recreateNullsTable(const std::string& notNull)
{
dropObject("TABLE", "NullTest");
try { *_pSession << format("CREATE TABLE NullTest (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)",
dropObject("TABLE", ExecUtil::nulltest());
try { *_pSession << format("CREATE TABLE %s (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)", ExecUtil::nulltest(),
notNull,
notNull,
notNull), now; }
@ -373,8 +373,8 @@ void ODBCMySQLTest::recreateNullsTable(const std::string& notNull)
void ODBCMySQLTest::recreateMiscTable()
{
dropObject("TABLE", "MiscTest");
try { *_pSession << "CREATE TABLE MiscTest "
dropObject("TABLE", ExecUtil::misctest());
try { *_pSession << "CREATE TABLE "<< ExecUtil::misctest() <<
"(First VARCHAR(30),"
"Second VARBINARY(30),"
"Third INTEGER,"
@ -387,8 +387,8 @@ void ODBCMySQLTest::recreateMiscTable()
void ODBCMySQLTest::recreateLogTable()
{
dropObject("TABLE", "T_POCO_LOG");
dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
dropObject("TABLE", ExecUtil::pocolog());;
dropObject("TABLE", ExecUtil::pocolog_a());;
try
{
@ -402,8 +402,8 @@ void ODBCMySQLTest::recreateLogTable()
"Text VARCHAR(100),"
"DateTime DATETIME)";
session() << sql, "T_POCO_LOG", now;
session() << sql, "T_POCO_LOG_ARCHIVE", now;
session() << sql, ExecUtil::pocolog(), now;
session() << sql, ExecUtil::pocolog_a(), now;
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
@ -422,6 +422,7 @@ CppUnit::Test* ODBCMySQLTest::suite()
CppUnit_addTest(pSuite, ODBCMySQLTest, testBareboneODBC);
CppUnit_addTest(pSuite, ODBCMySQLTest, testZeroRows);
CppUnit_addTest(pSuite, ODBCMySQLTest, testSyntaxError);
CppUnit_addTest(pSuite, ODBCMySQLTest, testSimpleAccess);
CppUnit_addTest(pSuite, ODBCMySQLTest, testComplexType);
CppUnit_addTest(pSuite, ODBCMySQLTest, testSimpleAccessVector);

View File

@ -85,11 +85,11 @@ std::string ODBCOracleTest::_connectString = "DRIVER={" ORACLE_ODBC_DRI
const std::string ODBCOracleTest::MULTI_INSERT =
"BEGIN "
"INSERT INTO Test VALUES ('1', 2, 3.5);"
"INSERT INTO Test VALUES ('2', 3, 4.5);"
"INSERT INTO Test VALUES ('3', 4, 5.5);"
"INSERT INTO Test VALUES ('4', 5, 6.5);"
"INSERT INTO Test VALUES ('5', 6, 7.5);"
"INSERT INTO " + ExecUtil::test_tbl() + " VALUES ('1', 2, 3.5);"
"INSERT INTO " + ExecUtil::test_tbl() + " VALUES ('2', 3, 4.5);"
"INSERT INTO " + ExecUtil::test_tbl() + " VALUES ('3', 4, 5.5);"
"INSERT INTO " + ExecUtil::test_tbl() + " VALUES ('4', 5, 6.5);"
"INSERT INTO " + ExecUtil::test_tbl() + " VALUES ('5', 6, 7.5);"
"END;";
const std::string ODBCOracleTest::MULTI_SELECT =
@ -109,7 +109,7 @@ ODBCOracleTest::~ODBCOracleTest()
void ODBCOracleTest::testBarebone()
{
std::string tableCreateString = "CREATE TABLE Test "
std::string tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third BLOB,"
@ -122,7 +122,7 @@ void ODBCOracleTest::testBarebone()
_pExecutor->bareboneODBCTest(_connectString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
_pExecutor->bareboneODBCTest(_connectString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
tableCreateString = "CREATE TABLE Test "
tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second INTEGER,"
"Third NUMBER)";
@ -134,11 +134,11 @@ void ODBCOracleTest::testBarebone()
"ret4 OUT SYS_REFCURSOR,"
"ret5 OUT SYS_REFCURSOR) IS "
"BEGIN "
"OPEN ret1 FOR SELECT * FROM Test WHERE First = '1';"
"OPEN ret2 FOR SELECT * FROM Test WHERE First = '2';"
"OPEN ret3 FOR SELECT * FROM Test WHERE First = '3';"
"OPEN ret4 FOR SELECT * FROM Test WHERE First = '4';"
"OPEN ret5 FOR SELECT * FROM Test WHERE First = '5';"
"OPEN ret1 FOR SELECT * FROM " + ExecUtil::test_tbl() + " WHERE First = '1';"
"OPEN ret2 FOR SELECT * FROM " + ExecUtil::test_tbl() + " WHERE First = '2';"
"OPEN ret3 FOR SELECT * FROM " + ExecUtil::test_tbl() + " WHERE First = '3';"
"OPEN ret4 FOR SELECT * FROM " + ExecUtil::test_tbl() + " WHERE First = '4';"
"OPEN ret5 FOR SELECT * FROM " + ExecUtil::test_tbl() + " WHERE First = '5';"
"END multiResultsProcedure;" , now;
_pExecutor->bareboneODBCMultiResultTest(_connectString,
@ -385,14 +385,14 @@ void ODBCOracleTest::testCursorStoredProcedure()
people.push_back(Person("Simpson", "Homer", "Springfield", 42));
people.push_back(Person("Simpson", "Bart", "Springfield", 12));
people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
*_pSession << "INSERT INTO Person VALUES (?, ?, ?, ?)", use(people), now;
*_pSession << "INSERT INTO " << ExecUtil::person() << " VALUES (?, ?, ?, ?)", use(people), now;
*_pSession << "CREATE OR REPLACE "
"PROCEDURE storedCursorProcedure(ret OUT SYS_REFCURSOR, ageLimit IN NUMBER) IS "
" BEGIN "
" OPEN ret FOR "
" SELECT * "
" FROM Person "
" FROM " << ExecUtil::person() <<
" WHERE Age < ageLimit "
" ORDER BY Age DESC; "
" END storedCursorProcedure;" , now;
@ -413,7 +413,7 @@ void ODBCOracleTest::testCursorStoredProcedure()
assert (rs["Address"] == "Springfield");
assert (rs["Age"] == 12);
dropObject("TABLE", "Person");
dropObject("TABLE", ExecUtil::person());
dropObject("PROCEDURE", "storedCursorProcedure");
k += 2;
@ -523,7 +523,7 @@ void ODBCOracleTest::testCursorStoredFunction()
people.push_back(Person("Simpson", "Homer", "Springfield", 42));
people.push_back(Person("Simpson", "Bart", "Springfield", 12));
people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
*_pSession << "INSERT INTO Person VALUES (?, ?, ?, ?)", use(people), now;
*_pSession << "INSERT INTO " << ExecUtil::person() << " VALUES (?, ?, ?, ?)", use(people), now;
*_pSession << "CREATE OR REPLACE "
"FUNCTION storedCursorFunction(ageLimit IN NUMBER) RETURN SYS_REFCURSOR IS "
@ -531,7 +531,7 @@ void ODBCOracleTest::testCursorStoredFunction()
" BEGIN "
" OPEN ret FOR "
" SELECT * "
" FROM Person "
" FROM " << ExecUtil::person() <<
" WHERE Age < ageLimit "
" ORDER BY Age DESC; "
" RETURN ret; "
@ -553,7 +553,7 @@ void ODBCOracleTest::testCursorStoredFunction()
assert (rs["Address"] == "Springfield");
assert (rs["Age"] == 12);
dropObject("TABLE", "Person");
dropObject("TABLE", ExecUtil::person());
dropObject("FUNCTION", "storedCursorFunction");
k += 2;
@ -571,9 +571,9 @@ void ODBCOracleTest::testMultipleResults()
" ret2 OUT SYS_REFCURSOR,"
" ret3 OUT SYS_REFCURSOR) IS "
"BEGIN "
" OPEN ret1 FOR SELECT * FROM Person WHERE Age = paramAge1;"
" OPEN ret2 FOR SELECT Age FROM Person WHERE FirstName = 'Bart';"
" OPEN ret3 FOR SELECT * FROM Person WHERE Age = paramAge2 OR Age = paramAge3 ORDER BY Age;"
" OPEN ret1 FOR SELECT * FROM " + ExecUtil::person() + " WHERE Age = paramAge1;"
" OPEN ret2 FOR SELECT Age FROM " + ExecUtil::person() + " WHERE FirstName = 'Bart';"
" OPEN ret3 FOR SELECT * FROM " + ExecUtil::person() + " WHERE Age = paramAge2 OR Age = paramAge3 ORDER BY Age;"
"END multiResultsProcedure;";
for (int i = 0; i < 8;)
@ -598,18 +598,18 @@ void ODBCOracleTest::testAutoTransaction()
recreateIntsTable();
session().setFeature("autoCommit", true);
session() << "INSERT INTO Strings VALUES (1)", now;
localSession << "SELECT count(*) FROM Strings", into(count), now;
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
localSession << "SELECT count(*) FROM " << ExecUtil::person() , into(count), now;
assert (1 == count);
session() << "INSERT INTO Strings VALUES (2)", now;
localSession << "SELECT count(*) FROM Strings", into(count), now;
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
assert (2 == count);
session() << "INSERT INTO Strings VALUES (3)", now;
localSession << "SELECT count(*) FROM Strings", into(count), now;
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (3)", now;
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
assert (3 == count);
session() << "DELETE FROM Strings", now;
localSession << "SELECT count(*) FROM Strings", into(count), now;
session() << "DELETE FROM " << ExecUtil::strings(), now;
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
assert (0 == count);
session().setFeature("autoCommit", false);
@ -617,26 +617,26 @@ void ODBCOracleTest::testAutoTransaction()
try
{
AutoTransaction at(session());
session() << "INSERT INTO Strings VALUES (1)", now;
session() << "INSERT INTO Strings VALUES (2)", now;
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
session() << "BAD QUERY", now;
} catch (Poco::Exception&) {}
session() << "SELECT count(*) FROM Strings", into(count), now;
session() << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
assert (0 == count);
AutoTransaction at(session());
session() << "INSERT INTO Strings VALUES (1)", now;
session() << "INSERT INTO Strings VALUES (2)", now;
session() << "INSERT INTO Strings VALUES (3)", now;
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (1)", now;
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (2)", now;
session() << "INSERT INTO " << ExecUtil::strings() << " VALUES (3)", now;
localSession << "SELECT count(*) FROM Strings", into(count), now;
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
assert (0 == count);
at.commit();
localSession << "SELECT count(*) FROM Strings", into(count), now;
localSession << "SELECT count(*) FROM " << ExecUtil::strings(), into(count), now;
assert (3 == count);
session().setFeature("autoCommit", ac);
@ -671,8 +671,8 @@ void ODBCOracleTest::dropObject(const std::string& type, const std::string& name
void ODBCOracleTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR2(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat NUMBER NULL , EmptyDateTime TIMESTAMP NULL)", now; }
dropObject("TABLE", ExecUtil::nullabletest());
try { *_pSession << "CREATE TABLE " << ExecUtil::nullabletest() << " (EmptyString VARCHAR2(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat NUMBER NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -680,8 +680,8 @@ void ODBCOracleTest::recreateNullableTable()
void ODBCOracleTest::recreatePersonTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR2(30), FirstName VARCHAR2(30), Address VARCHAR2(30), Age INTEGER)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR2(30), FirstName VARCHAR2(30), Address VARCHAR2(30), Age INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -689,8 +689,8 @@ void ODBCOracleTest::recreatePersonTable()
void ODBCOracleTest::recreatePersonTupleTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName1 VARCHAR2(30), FirstName1 VARCHAR2(30), Address1 VARCHAR2(30), Age1 INTEGER,"
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName1 VARCHAR2(30), FirstName1 VARCHAR2(30), Address1 VARCHAR2(30), Age1 INTEGER,"
"LastName2 VARCHAR2(30), FirstName2 VARCHAR2(30), Address2 VARCHAR2(30), Age2 INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTupleTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTupleTable()"); }
@ -699,8 +699,8 @@ void ODBCOracleTest::recreatePersonTupleTable()
void ODBCOracleTest::recreatePersonBLOBTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
}
@ -708,8 +708,8 @@ void ODBCOracleTest::recreatePersonBLOBTable()
void ODBCOracleTest::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
}
@ -717,8 +717,8 @@ void ODBCOracleTest::recreatePersonDateTimeTable()
void ODBCOracleTest::recreatePersonDateTable()
{
dropObject("TABLE", "Person");
try { *_pSession << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
dropObject("TABLE", ExecUtil::person());
try { *_pSession << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
}
@ -726,8 +726,8 @@ void ODBCOracleTest::recreatePersonDateTable()
void ODBCOracleTest::recreateIntsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str INTEGER)", now; }
dropObject("TABLE", ExecUtil::strings());
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
}
@ -735,8 +735,8 @@ void ODBCOracleTest::recreateIntsTable()
void ODBCOracleTest::recreateStringsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::strings());
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateStringsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateStringsTable()"); }
}
@ -744,8 +744,8 @@ void ODBCOracleTest::recreateStringsTable()
void ODBCOracleTest::recreateFloatsTable()
{
dropObject("TABLE", "Strings");
try { *_pSession << "CREATE TABLE Strings (str NUMBER)", now; }
dropObject("TABLE", ExecUtil::strings());
try { *_pSession << "CREATE TABLE " << ExecUtil::strings() <<" (str NUMBER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
}
@ -753,8 +753,8 @@ void ODBCOracleTest::recreateFloatsTable()
void ODBCOracleTest::recreateTuplesTable()
{
dropObject("TABLE", "Tuples");
try { *_pSession << "CREATE TABLE Tuples "
dropObject("TABLE", ExecUtil::tuples());
try { *_pSession << "CREATE TABLE " << ExecUtil::tuples() <<
"(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
"int7 INTEGER, int8 INTEGER, int9 INTEGER, int10 INTEGER, int11 INTEGER, int12 INTEGER, int13 INTEGER,"
"int14 INTEGER, int15 INTEGER, int16 INTEGER, int17 INTEGER, int18 INTEGER, int19 INTEGER)", now; }
@ -765,8 +765,8 @@ void ODBCOracleTest::recreateTuplesTable()
void ODBCOracleTest::recreateVectorsTable()
{
dropObject("TABLE", "Vectors");
try { *_pSession << "CREATE TABLE Vectors (int0 INTEGER, flt0 NUMBER(5,2), str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::vectors());
try { *_pSession << "CREATE TABLE " << ExecUtil::vectors() << " (int0 INTEGER, flt0 NUMBER(5,2), str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateVectorsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateVectorsTable()"); }
}
@ -774,8 +774,8 @@ void ODBCOracleTest::recreateVectorsTable()
void ODBCOracleTest::recreateAnysTable()
{
dropObject("TABLE", "Anys");
try { *_pSession << "CREATE TABLE Anys (int0 INTEGER, flt0 NUMBER, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::anys() );
try { *_pSession << "CREATE TABLE " << ExecUtil::anys() << " (int0 INTEGER, flt0 NUMBER, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
}
@ -783,8 +783,8 @@ void ODBCOracleTest::recreateAnysTable()
void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
{
dropObject("TABLE", "NullTest");
try { *_pSession << format("CREATE TABLE NullTest (i INTEGER %s, r NUMBER %s, v VARCHAR(30) %s)",
dropObject("TABLE", ExecUtil::nulltest());
try { *_pSession << format("CREATE TABLE %s (i INTEGER %s, r NUMBER %s, v VARCHAR(30) %s)",ExecUtil::nulltest(),
notNull,
notNull,
notNull), now; }
@ -795,10 +795,10 @@ void ODBCOracleTest::recreateNullsTable(const std::string& notNull)
void ODBCOracleTest::recreateMiscTable()
{
dropObject("TABLE", "MiscTest");
dropObject("TABLE", ExecUtil::misctest());
try
{
session() << "CREATE TABLE MiscTest "
session() << "CREATE TABLE " << ExecUtil::misctest() <<
"(First VARCHAR(30),"
"Second BLOB,"
"Third INTEGER,"
@ -811,8 +811,8 @@ void ODBCOracleTest::recreateMiscTable()
void ODBCOracleTest::recreateLogTable()
{
dropObject("TABLE", "T_POCO_LOG");
dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
dropObject("TABLE", ExecUtil::pocolog());;
dropObject("TABLE", ExecUtil::pocolog_a());;
try
{
@ -826,8 +826,8 @@ void ODBCOracleTest::recreateLogTable()
"Text VARCHAR(100),"
"DateTime TIMESTAMP)";
session() << sql, "T_POCO_LOG", now;
session() << sql, "T_POCO_LOG_ARCHIVE", now;
session() << sql, ExecUtil::pocolog(), now;
session() << sql, ExecUtil::pocolog_a(), now;
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
@ -857,6 +857,7 @@ CppUnit::Test* ODBCOracleTest::suite()
CppUnit_addTest(pSuite, ODBCOracleTest, testBareboneODBC);
CppUnit_addTest(pSuite, ODBCOracleTest, testZeroRows);
CppUnit_addTest(pSuite, ODBCOracleTest, testSyntaxError);
CppUnit_addTest(pSuite, ODBCOracleTest, testSimpleAccess);
CppUnit_addTest(pSuite, ODBCOracleTest, testComplexType);
CppUnit_addTest(pSuite, ODBCOracleTest, testComplexTypeTuple);

View File

@ -21,6 +21,7 @@
#include "Poco/Data/ODBC/Diagnostics.h"
#include "Poco/Data/ODBC/ODBCException.h"
#include <iostream>
#include "Poco/Environment.h"
using namespace Poco::Data::Keywords;
@ -58,12 +59,42 @@ using Poco::DateTime;
#endif
#define POSTGRESQL_SERVER POCO_ODBC_TEST_DATABASE_SERVER
#define POSTGRESQL_PORT "5432"
#define POSTGRESQL_DB "postgres"
#define POSTGRESQL_UID "postgres"
#define POSTGRESQL_PWD "postgres"
static std::string postgreSchema()
{
return Poco::Environment::get("POCO_TEST_POSTGRES_SCHEMA", "public");
}
static std::string postgreDriver()
{
return Poco::Environment::get("POCO_TEST_POSTGRES_DRIVER", POSTGRESQL_ODBC_DRIVER);
}
static std::string postgreSettings()
{
return Poco::Environment::get("POCO_TEST_POSTGRES_SETTINGS", "");
}
#define POSTGRESQL_VERSION "9.3"
static std::string postgreConnParams()
{
return Poco::Environment::get("POCO_TEST_POSTGRES_CONN", "DATABASE=postgres;"
"SERVER=postgres;"
"PORT=5432;");
}
static std::string postgreUid()
{
return Poco::Environment::get("POCO_TEST_POSTGRES_UID", "");
}
static std::string postgrePwd()
{
return Poco::Environment::get("POCO_TEST_POSTGRES_PWD", "");
}
#ifdef POCO_OS_FAMILY_WINDOWS
const std::string ODBCPostgreSQLTest::_libDir = "C:\\\\Program Files\\\\PostgreSQL\\\\" POSTGRESQL_VERSION "\\\\lib\\\\";
#else
@ -73,17 +104,15 @@ const std::string ODBCPostgreSQLTest::_libDir = "/usr/local/pgsql/lib/";
ODBCTest::SessionPtr ODBCPostgreSQLTest::_pSession;
ODBCTest::ExecPtr ODBCPostgreSQLTest::_pExecutor;
std::string ODBCPostgreSQLTest::_driver = POSTGRESQL_ODBC_DRIVER;
std::string ODBCPostgreSQLTest::_driver = postgreDriver();
std::string ODBCPostgreSQLTest::_dsn = POSTGRESQL_DSN;
std::string ODBCPostgreSQLTest::_uid = POSTGRESQL_UID;
std::string ODBCPostgreSQLTest::_pwd = POSTGRESQL_PWD;
std::string ODBCPostgreSQLTest::_connectString =
"DRIVER=" POSTGRESQL_ODBC_DRIVER ";"
"DATABASE=" POSTGRESQL_DB ";"
"SERVER=" POSTGRESQL_SERVER ";"
"PORT=" POSTGRESQL_PORT ";"
"UID=" POSTGRESQL_UID ";"
"PWD=" POSTGRESQL_PWD ";"
std::string ODBCPostgreSQLTest::_uid = postgreUid();
std::string ODBCPostgreSQLTest::_pwd = postgrePwd();
std::string ODBCPostgreSQLTest::_connectString =
"DRIVER=" + postgreDriver() + ";"
+ postgreConnParams() + ";" +
"UID=" + postgreUid() + ";"
"PWD=" + postgrePwd() + ";"
"SSLMODE=prefer;"
"LowerCaseIdentifier=0;"
"UseServerSidePrepare=0;"
@ -108,7 +137,7 @@ std::string ODBCPostgreSQLTest::_connectString =
"UnknownSizes=0;"
"Socket=8192;"
"Fetch=100;"
"ConnSettings=;"
"ConnSettings=" + postgreSettings() + ";"
"ShowSystemTables=0;"
"RowVersioning=0;"
"ShowOidColumn=0;"
@ -129,7 +158,7 @@ ODBCPostgreSQLTest::~ODBCPostgreSQLTest()
void ODBCPostgreSQLTest::testBareboneODBC()
{
std::string tableCreateString = "CREATE TABLE Test "
std::string tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third BYTEA,"
@ -142,7 +171,7 @@ void ODBCPostgreSQLTest::testBareboneODBC()
executor().bareboneODBCTest(_connectString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
executor().bareboneODBCTest(_connectString, tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
tableCreateString = "CREATE TABLE Test "
tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third BYTEA,"
@ -157,7 +186,7 @@ void ODBCPostgreSQLTest::testBareboneODBC()
//neither pSQL ODBC nor Mammoth drivers support multiple results properly
/*
tableCreateString = "CREATE TABLE Test "
tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second INTEGER,"
"Third FLOAT)";
@ -201,17 +230,18 @@ void ODBCPostgreSQLTest::testStoredFunction()
{
configurePLPgSQL();
std::string func("testStoredFunction()");
const std::string func("testStoredFunction()");
const std::string nm = ExecUtil::stored_func();
for (int k = 0; k < 8;)
{
session().setFeature("autoBind", bindValue(k));
session().setFeature("autoExtract", bindValue(k+1));
dropObject("FUNCTION", "storedFunction()");
dropObject("FUNCTION", nm + "()");
try
{
session() << "CREATE FUNCTION storedFunction() RETURNS INTEGER AS '"
session() << "CREATE FUNCTION " << nm << "() RETURNS INTEGER AS '"
"BEGIN "
" return -1; "
"END;'"
@ -221,13 +251,13 @@ void ODBCPostgreSQLTest::testStoredFunction()
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (func); }
int i = 0;
session() << "{? = call storedFunction()}", out(i), now;
session() << "{? = call "<< nm << "()}", out(i), now;
assert(-1 == i);
dropObject("FUNCTION", "storedFunction()");
dropObject("FUNCTION", nm + "(INTEGER)");
try
{
session() << "CREATE FUNCTION storedFunction(INTEGER) RETURNS INTEGER AS '"
session() << "CREATE FUNCTION " << nm << "(INTEGER) RETURNS INTEGER AS '"
"BEGIN "
" RETURN $1 * $1; "
"END;'"
@ -238,14 +268,14 @@ void ODBCPostgreSQLTest::testStoredFunction()
i = 2;
int result = 0;
session() << "{? = call storedFunction(?)}", out(result), in(i), now;
session() << "{? = call " << nm << "(?)}", out(result), in(i), now;
assert(4 == result);
dropObject("FUNCTION", "storedFunction(INTEGER)");
dropObject("FUNCTION", nm + "(INTEGER)");
dropObject("FUNCTION", "storedFunction(TIMESTAMP)");
dropObject("FUNCTION", nm + "(TIMESTAMP)");
try
{
session() << "CREATE FUNCTION storedFunction(TIMESTAMP) RETURNS TIMESTAMP AS '"
session() << "CREATE FUNCTION " << nm << "(TIMESTAMP) RETURNS TIMESTAMP AS '"
"BEGIN "
" RETURN $1; "
"END;'"
@ -256,14 +286,14 @@ void ODBCPostgreSQLTest::testStoredFunction()
DateTime dtIn(1965, 6, 18, 5, 35, 1);
DateTime dtOut;
session() << "{? = call storedFunction(?)}", out(dtOut), in(dtIn), now;
session() << "{? = call " << nm << "(?)}", out(dtOut), in(dtIn), now;
assert(dtOut == dtIn);
dropObject("FUNCTION", "storedFunction(TIMESTAMP)");
dropObject("FUNCTION", nm + "(TIMESTAMP)");
dropObject("FUNCTION", "storedFunction(TEXT, TEXT)");
dropObject("FUNCTION", nm + "(TEXT, TEXT)");
try
{
session() << "CREATE FUNCTION storedFunction(TEXT,TEXT) RETURNS TEXT AS '"
session() << "CREATE FUNCTION " << nm << "(TEXT,TEXT) RETURNS TEXT AS '"
"BEGIN "
" RETURN $1 || '', '' || $2 || ''!'';"
"END;'"
@ -277,13 +307,13 @@ void ODBCPostgreSQLTest::testStoredFunction()
std::string ret;
try
{
session() << "{? = call storedFunction(?,?)}", out(ret), in(param1), in(param2), now;
session() << "{? = call " << nm << "(?,?)}", out(ret), in(param1), in(param2), now;
}
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (func); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (func); }
assert(ret == "Hello, world!");
dropObject("FUNCTION", "storedFunction(TEXT, TEXT)");
dropObject("FUNCTION", nm + "(TEXT, TEXT)");
k += 2;
}
@ -292,7 +322,10 @@ void ODBCPostgreSQLTest::testStoredFunction()
void ODBCPostgreSQLTest::testStoredFunctionAny()
{
session() << "CREATE FUNCTION storedFunction(INTEGER) RETURNS INTEGER AS '"
const std::string nm = ExecUtil::stored_func();
dropObject("FUNCTION", nm + "(INTEGER)");
session() << "CREATE FUNCTION "<< nm << "(INTEGER) RETURNS INTEGER AS '"
"BEGIN "
" RETURN $1 * $1; "
"END;'"
@ -305,19 +338,23 @@ void ODBCPostgreSQLTest::testStoredFunctionAny()
Any i = 2;
Any result = 0;
session() << "{? = call storedFunction(?)}", out(result), in(i), now;
session() << "{? = call " << nm << "(?)}", out(result), in(i), now;
assert(4 == AnyCast<int>(result));
k += 2;
}
dropObject("FUNCTION", "storedFunction(INTEGER)");
dropObject("FUNCTION", nm + "(INTEGER)");
}
void ODBCPostgreSQLTest::testStoredFunctionDynamicAny()
{
session() << "CREATE FUNCTION storedFunction(INTEGER) RETURNS INTEGER AS '"
const std::string nm = ExecUtil::stored_func();
dropObject("FUNCTION", nm + "(INTEGER)");
session() << "CREATE FUNCTION " << nm << "(INTEGER) RETURNS INTEGER AS '"
"BEGIN "
" RETURN $1 * $1; "
"END;'"
@ -330,13 +367,13 @@ void ODBCPostgreSQLTest::testStoredFunctionDynamicAny()
DynamicAny i = 2;
DynamicAny result = 0;
session() << "{? = call storedFunction(?)}", out(result), in(i), now;
session() << "{? = call " << nm << "(?)}", out(result), in(i), now;
assert(4 == result);
k += 2;
}
dropObject("FUNCTION", "storedFunction(INTEGER)");
dropObject("FUNCTION", nm + "(INTEGER)");
}
@ -390,8 +427,8 @@ void ODBCPostgreSQLTest::dropObject(const std::string& type, const std::string&
void ODBCPostgreSQLTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
dropObject("TABLE", ExecUtil::nullabletest());
try { *_pSession << "CREATE TABLE "<< ExecUtil::nullabletest() << " (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -399,8 +436,8 @@ void ODBCPostgreSQLTest::recreateNullableTable()
void ODBCPostgreSQLTest::recreatePersonTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -408,8 +445,8 @@ void ODBCPostgreSQLTest::recreatePersonTable()
void ODBCPostgreSQLTest::recreatePersonBLOBTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BYTEA)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BYTEA)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
}
@ -418,8 +455,8 @@ void ODBCPostgreSQLTest::recreatePersonBLOBTable()
void ODBCPostgreSQLTest::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
}
@ -427,8 +464,8 @@ void ODBCPostgreSQLTest::recreatePersonDateTimeTable()
void ODBCPostgreSQLTest::recreatePersonDateTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornDate DATE)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTable()"); }
}
@ -436,8 +473,8 @@ void ODBCPostgreSQLTest::recreatePersonDateTable()
void ODBCPostgreSQLTest::recreatePersonTimeTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), BornTime TIME)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTimeTable()"); }
}
@ -445,8 +482,8 @@ void ODBCPostgreSQLTest::recreatePersonTimeTable()
void ODBCPostgreSQLTest::recreateIntsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str INTEGER)", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
}
@ -454,8 +491,8 @@ void ODBCPostgreSQLTest::recreateIntsTable()
void ODBCPostgreSQLTest::recreateStringsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateStringsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateStringsTable()"); }
}
@ -463,8 +500,8 @@ void ODBCPostgreSQLTest::recreateStringsTable()
void ODBCPostgreSQLTest::recreateFloatsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str FLOAT)", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str FLOAT)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
}
@ -472,8 +509,8 @@ void ODBCPostgreSQLTest::recreateFloatsTable()
void ODBCPostgreSQLTest::recreateTuplesTable()
{
dropObject("TABLE", "Tuples");
try { session() << "CREATE TABLE Tuples "
dropObject("TABLE", ExecUtil::tuples());
try { session() << "CREATE TABLE " << ExecUtil::tuples() <<
"(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
"int7 INTEGER, int8 INTEGER, int9 INTEGER, int10 INTEGER, int11 INTEGER, int12 INTEGER, int13 INTEGER,"
"int14 INTEGER, int15 INTEGER, int16 INTEGER, int17 INTEGER, int18 INTEGER, int19 INTEGER)", now; }
@ -484,8 +521,8 @@ void ODBCPostgreSQLTest::recreateTuplesTable()
void ODBCPostgreSQLTest::recreateVectorsTable()
{
dropObject("TABLE", "Vectors");
try { session() << "CREATE TABLE Vectors (int0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::vectors());
try { session() << "CREATE TABLE " << ExecUtil::vectors() << " (i0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateVectorsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateVectorsTable()"); }
}
@ -493,8 +530,8 @@ void ODBCPostgreSQLTest::recreateVectorsTable()
void ODBCPostgreSQLTest::recreateAnysTable()
{
dropObject("TABLE", "Anys");
try { session() << "CREATE TABLE Anys (int0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::anys() );
try { session() << "CREATE TABLE " << ExecUtil::anys() << " (int0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
}
@ -502,8 +539,8 @@ void ODBCPostgreSQLTest::recreateAnysTable()
void ODBCPostgreSQLTest::recreateNullsTable(const std::string& notNull)
{
dropObject("TABLE", "NullTest");
try { session() << format("CREATE TABLE NullTest (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)",
dropObject("TABLE", ExecUtil::nulltest());
try { session() << format("CREATE TABLE %s (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)",ExecUtil::nulltest(),
notNull,
notNull,
notNull), now; }
@ -523,11 +560,11 @@ void ODBCPostgreSQLTest::recreateBoolTable()
void ODBCPostgreSQLTest::recreateMiscTable()
{
dropObject("TABLE", "MiscTest");
dropObject("TABLE", ExecUtil::misctest());
try
{
// Mammoth does not bind columns properly
session() << "CREATE TABLE MiscTest "
session() << "CREATE TABLE "<< ExecUtil::misctest() <<
"(First VARCHAR(30),"
"Second BYTEA,"
"Third INTEGER,"
@ -540,8 +577,8 @@ void ODBCPostgreSQLTest::recreateMiscTable()
void ODBCPostgreSQLTest::recreateLogTable()
{
dropObject("TABLE", "T_POCO_LOG");
dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
dropObject("TABLE", ExecUtil::pocolog());;
dropObject("TABLE", ExecUtil::pocolog_a());;
try
{
@ -555,8 +592,8 @@ void ODBCPostgreSQLTest::recreateLogTable()
"Text VARCHAR,"
"DateTime TIMESTAMP)";
session() << sql, "T_POCO_LOG", now;
session() << sql, "T_POCO_LOG_ARCHIVE", now;
session() << sql, ExecUtil::pocolog(), now;
session() << sql, ExecUtil::pocolog_a(), now;
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
@ -580,12 +617,20 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
{
std::cout << "*** Connected to [" << _driver << "] test database." << std::endl;
_pExecutor = new SQLExecutor(_driver + " SQL Executor", _pSession);
std::string initSql;
if (!postgreSchema().empty())
{
initSql = "SET search_path TO " + postgreSchema() + (postgreSchema() != std::string("public") ? ", public;" : ";");
(*_pSession) << initSql, now;
}
_pExecutor = new SQLExecutor(_driver + " SQL Executor", _pSession, initSql, postgreSchema());
CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ODBCPostgreSQLTest");
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testBareboneODBC);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testZeroRows);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSyntaxError);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSimpleAccess);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testComplexType);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSimpleAccessVector);
@ -668,7 +713,8 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testAny);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testDynamicAny);
//neither pSQL ODBC nor Mammoth drivers support multiple results properly
//CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testMultipleResults);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testMultipleResults);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testMultipleResultsNoProj);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSQLChannel);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSQLLogger);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testSessionTransaction);
@ -677,6 +723,7 @@ CppUnit::Test* ODBCPostgreSQLTest::suite()
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testNullable);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testUnicode);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testReconnect);
CppUnit_addTest(pSuite, ODBCPostgreSQLTest, testInsertStatReuse);
return pSuite;
}

View File

@ -121,7 +121,7 @@ ODBCSQLServerTest::~ODBCSQLServerTest()
void ODBCSQLServerTest::testBareboneODBC()
{
std::string tableCreateString = "CREATE TABLE Test "
std::string tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third VARBINARY(30),"
@ -138,7 +138,7 @@ void ODBCSQLServerTest::testBareboneODBC()
executor().bareboneODBCTest(dbConnString(), tableCreateString,
SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND, true, "CONVERT(VARBINARY(30),?)");
tableCreateString = "CREATE TABLE Test "
tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second INTEGER,"
"Third FLOAT)";
@ -334,13 +334,13 @@ void ODBCSQLServerTest::testCursorStoredProcedure()
people.push_back(Person("Simpson", "Homer", "Springfield", 42));
people.push_back(Person("Simpson", "Bart", "Springfield", 12));
people.push_back(Person("Simpson", "Lisa", "Springfield", 10));
session() << "INSERT INTO Person VALUES (?, ?, ?, ?)", use(people), now;
session() << "INSERT INTO " << ExecUtil::person() << " VALUES (?, ?, ?, ?)", use(people), now;
dropObject("PROCEDURE", "storedCursorProcedure");
session() << "CREATE PROCEDURE storedCursorProcedure(@ageLimit int) AS "
"BEGIN "
" SELECT * "
" FROM Person "
" FROM " << ExecUtil::person() <<
" WHERE Age < @ageLimit "
" ORDER BY Age DESC; "
"END;"
@ -362,7 +362,7 @@ void ODBCSQLServerTest::testCursorStoredProcedure()
assert (rs["Address"] == "Springfield");
assert (rs["Age"] == 12);
dropObject("TABLE", "Person");
dropObject("TABLE", ExecUtil::person());
dropObject("PROCEDURE", "storedCursorProcedure");
k += 2;
@ -553,8 +553,8 @@ void ODBCSQLServerTest::dropObject(const std::string& type, const std::string& n
void ODBCSQLServerTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime DATETIME NULL)", now; }
dropObject("TABLE", ExecUtil::nullabletest());
try { *_pSession << "CREATE TABLE " << ExecUtil::nullabletest() << " (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat FLOAT NULL , EmptyDateTime DATETIME NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -562,8 +562,8 @@ void ODBCSQLServerTest::recreateNullableTable()
void ODBCSQLServerTest::recreatePersonTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -571,8 +571,8 @@ void ODBCSQLServerTest::recreatePersonTable()
void ODBCSQLServerTest::recreatePersonBLOBTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image VARBINARY(MAX))", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image VARBINARY(MAX))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
}
@ -580,8 +580,8 @@ void ODBCSQLServerTest::recreatePersonBLOBTable()
void ODBCSQLServerTest::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born DATETIME)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born DATETIME)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
}
@ -589,8 +589,8 @@ void ODBCSQLServerTest::recreatePersonDateTimeTable()
void ODBCSQLServerTest::recreateIntsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str INTEGER)", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
}
@ -598,8 +598,8 @@ void ODBCSQLServerTest::recreateIntsTable()
void ODBCSQLServerTest::recreateStringsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateStringsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateStringsTable()"); }
}
@ -607,8 +607,8 @@ void ODBCSQLServerTest::recreateStringsTable()
void ODBCSQLServerTest::recreateFloatsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str FLOAT)", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str FLOAT)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
}
@ -616,8 +616,8 @@ void ODBCSQLServerTest::recreateFloatsTable()
void ODBCSQLServerTest::recreateTuplesTable()
{
dropObject("TABLE", "Tuples");
try { session() << "CREATE TABLE Tuples "
dropObject("TABLE", ExecUtil::tuples());
try { session() << "CREATE TABLE " << ExecUtil::tuples() <<
"(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
"int7 INTEGER, int8 INTEGER, int9 INTEGER, int10 INTEGER, int11 INTEGER, int12 INTEGER, int13 INTEGER,"
"int14 INTEGER, int15 INTEGER, int16 INTEGER, int17 INTEGER, int18 INTEGER, int19 INTEGER)", now; }
@ -637,8 +637,8 @@ void ODBCSQLServerTest::recreateVectorTable()
void ODBCSQLServerTest::recreateVectorsTable()
{
dropObject("TABLE", "Vectors");
try { session() << "CREATE TABLE Vectors (int0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::vectors());
try { session() << "CREATE TABLE " << ExecUtil::vectors() << " (int0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateVectorsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateVectorsTable()"); }
}
@ -646,8 +646,8 @@ void ODBCSQLServerTest::recreateVectorsTable()
void ODBCSQLServerTest::recreateAnysTable()
{
dropObject("TABLE", "Anys");
try { session() << "CREATE TABLE Anys (int0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::anys() );
try { session() << "CREATE TABLE " << ExecUtil::anys() << " (int0 INTEGER, flt0 FLOAT, str0 VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
}
@ -655,8 +655,8 @@ void ODBCSQLServerTest::recreateAnysTable()
void ODBCSQLServerTest::recreateNullsTable(const std::string& notNull)
{
dropObject("TABLE", "NullTest");
try { session() << format("CREATE TABLE NullTest (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)",
dropObject("TABLE", ExecUtil::nulltest());
try { session() << format("CREATE TABLE %s (i INTEGER %s, r FLOAT %s, v VARCHAR(30) %s)", ExecUtil::nulltest(),
notNull,
notNull,
notNull), now; }
@ -675,10 +675,10 @@ void ODBCSQLServerTest::recreateBoolTable()
void ODBCSQLServerTest::recreateMiscTable()
{
dropObject("TABLE", "MiscTest");
dropObject("TABLE", ExecUtil::misctest());
try
{
session() << "CREATE TABLE MiscTest "
session() << "CREATE TABLE "<< ExecUtil::misctest() <<
"(First VARCHAR(30),"
"Second VARBINARY(30),"
"Third INTEGER,"
@ -692,8 +692,8 @@ void ODBCSQLServerTest::recreateMiscTable()
void ODBCSQLServerTest::recreateLogTable()
{
dropObject("TABLE", "T_POCO_LOG");
dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
dropObject("TABLE", ExecUtil::pocolog());;
dropObject("TABLE", ExecUtil::pocolog_a());;
try
{
@ -707,8 +707,8 @@ void ODBCSQLServerTest::recreateLogTable()
"Text VARCHAR(max),"
"DateTime DATETIME)";
session() << sql, "T_POCO_LOG", now;
session() << sql, "T_POCO_LOG_ARCHIVE", now;
session() << sql, ExecUtil::pocolog(), now;
session() << sql, ExecUtil::pocolog_a(), now;
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
@ -738,6 +738,7 @@ CppUnit::Test* ODBCSQLServerTest::suite()
CppUnit_addTest(pSuite, ODBCSQLServerTest, testBareboneODBC);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testZeroRows);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSyntaxError);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSimpleAccess);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testComplexType);
CppUnit_addTest(pSuite, ODBCSQLServerTest, testSimpleAccessVector);

View File

@ -64,7 +64,7 @@ ODBCSQLiteTest::~ODBCSQLiteTest()
void ODBCSQLiteTest::testBareboneODBC()
{
std::string tableCreateString = "CREATE TABLE Test "
std::string tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third BLOB,"
@ -77,7 +77,7 @@ void ODBCSQLiteTest::testBareboneODBC()
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
tableCreateString = "CREATE TABLE Test "
tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third BLOB,"
@ -90,7 +90,7 @@ void ODBCSQLiteTest::testBareboneODBC()
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_MANUAL);
executor().bareboneODBCTest(dbConnString(), tableCreateString, SQLExecutor::PB_AT_EXEC, SQLExecutor::DE_BOUND);
tableCreateString = "CREATE TABLE Test "
tableCreateString = "CREATE TABLE " + ExecUtil::test_tbl() +
"(First VARCHAR(30),"
"Second VARCHAR(30),"
"Third BLOB,"
@ -169,8 +169,8 @@ void ODBCSQLiteTest::dropObject(const std::string& type, const std::string& name
void ODBCSQLiteTest::recreateNullableTable()
{
dropObject("TABLE", "NullableTest");
try { *_pSession << "CREATE TABLE NullableTest (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat REAL NULL , EmptyDateTime TIMESTAMP NULL)", now; }
dropObject("TABLE", ExecUtil::nullabletest());
try { *_pSession << "CREATE TABLE " << ExecUtil::nullabletest() << " (EmptyString VARCHAR(30) NULL, EmptyInteger INTEGER NULL, EmptyFloat REAL NULL , EmptyDateTime TIMESTAMP NULL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -178,8 +178,8 @@ void ODBCSQLiteTest::recreateNullableTable()
void ODBCSQLiteTest::recreatePersonTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Age INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonTable()"); }
}
@ -187,8 +187,8 @@ void ODBCSQLiteTest::recreatePersonTable()
void ODBCSQLiteTest::recreatePersonBLOBTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Image BLOB)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonBLOBTable()"); }
}
@ -196,8 +196,8 @@ void ODBCSQLiteTest::recreatePersonBLOBTable()
void ODBCSQLiteTest::recreatePersonDateTimeTable()
{
dropObject("TABLE", "Person");
try { session() << "CREATE TABLE Person (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
dropObject("TABLE", ExecUtil::person());
try { session() << "CREATE TABLE " << ExecUtil::person() << " (LastName VARCHAR(30), FirstName VARCHAR(30), Address VARCHAR(30), Born TIMESTAMP)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreatePersonDateTimeTable()"); }
}
@ -205,8 +205,8 @@ void ODBCSQLiteTest::recreatePersonDateTimeTable()
void ODBCSQLiteTest::recreateIntsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str INTEGER)", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str INTEGER)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateIntsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateIntsTable()"); }
}
@ -214,8 +214,8 @@ void ODBCSQLiteTest::recreateIntsTable()
void ODBCSQLiteTest::recreateStringsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str VARCHAR(30))", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str VARCHAR(30))", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateStringsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateStringsTable()"); }
}
@ -223,8 +223,8 @@ void ODBCSQLiteTest::recreateStringsTable()
void ODBCSQLiteTest::recreateFloatsTable()
{
dropObject("TABLE", "Strings");
try { session() << "CREATE TABLE Strings (str REAL)", now; }
dropObject("TABLE", ExecUtil::strings());
try { session() << "CREATE TABLE " << ExecUtil::strings() <<" (str REAL)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateFloatsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateFloatsTable()"); }
}
@ -232,8 +232,8 @@ void ODBCSQLiteTest::recreateFloatsTable()
void ODBCSQLiteTest::recreateTuplesTable()
{
dropObject("TABLE", "Tuples");
try { session() << "CREATE TABLE Tuples "
dropObject("TABLE", ExecUtil::tuples());
try { session() << "CREATE TABLE " << ExecUtil::tuples() <<
"(int0 INTEGER, int1 INTEGER, int2 INTEGER, int3 INTEGER, int4 INTEGER, int5 INTEGER, int6 INTEGER, "
"int7 INTEGER, int8 INTEGER, int9 INTEGER, int10 INTEGER, int11 INTEGER, int12 INTEGER, int13 INTEGER,"
"int14 INTEGER, int15 INTEGER, int16 INTEGER, int17 INTEGER, int18 INTEGER, int19 INTEGER)", now; }
@ -244,8 +244,8 @@ void ODBCSQLiteTest::recreateTuplesTable()
void ODBCSQLiteTest::recreateVectorsTable()
{
dropObject("TABLE", "Vectors");
try { session() << "CREATE TABLE Vectors (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; }
dropObject("TABLE", ExecUtil::vectors() );
try { session() << "CREATE TABLE " << ExecUtil::vectors() << " (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateVectorsTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateVectorsTable()"); }
}
@ -253,8 +253,8 @@ void ODBCSQLiteTest::recreateVectorsTable()
void ODBCSQLiteTest::recreateAnysTable()
{
dropObject("TABLE", "Anys");
try { session() << "CREATE TABLE Anys (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; }
dropObject("TABLE", ExecUtil::anys() );
try { session() << "CREATE TABLE " << ExecUtil::anys() << " (int0 INTEGER, flt0 REAL, str0 VARCHAR)", now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateAnysTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateAnysTable()"); }
}
@ -262,8 +262,8 @@ void ODBCSQLiteTest::recreateAnysTable()
void ODBCSQLiteTest::recreateNullsTable(const std::string& notNull)
{
dropObject("TABLE", "NullTest");
try { session() << format("CREATE TABLE NullTest (i INTEGER %s, r REAL %s, v VARCHAR(30) %s)",
dropObject("TABLE", ExecUtil::nulltest());
try { session() << format("CREATE TABLE %s (i INTEGER %s, r REAL %s, v VARCHAR(30) %s)",ExecUtil::nulltest(),
notNull,
notNull,
notNull), now; }
@ -274,11 +274,11 @@ void ODBCSQLiteTest::recreateNullsTable(const std::string& notNull)
void ODBCSQLiteTest::recreateMiscTable()
{
dropObject("TABLE", "MiscTest");
dropObject("TABLE", ExecUtil::misctest());
try
{
// SQLite fails with BLOB bulk operations
session() << "CREATE TABLE MiscTest "
session() << "CREATE TABLE "<< ExecUtil::misctest() <<
"(First VARCHAR(30),"
//"Second BLOB,"
"Third INTEGER,"
@ -291,8 +291,8 @@ void ODBCSQLiteTest::recreateMiscTable()
void ODBCSQLiteTest::recreateLogTable()
{
dropObject("TABLE", "T_POCO_LOG");
dropObject("TABLE", "T_POCO_LOG_ARCHIVE");
dropObject("TABLE", ExecUtil::pocolog());;
dropObject("TABLE", ExecUtil::pocolog_a());;
try
{
@ -306,8 +306,8 @@ void ODBCSQLiteTest::recreateLogTable()
"Text VARCHAR,"
"DateTime DATETIME)";
session() << sql, "T_POCO_LOG", now;
session() << sql, "T_POCO_LOG_ARCHIVE", now;
session() << sql, ExecUtil::pocolog(), now;
session() << sql, ExecUtil::pocolog_a(), now;
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail ("recreateLogTable()"); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail ("recreateLogTable()"); }
@ -326,6 +326,7 @@ CppUnit::Test* ODBCSQLiteTest::suite()
CppUnit_addTest(pSuite, ODBCSQLiteTest, testBareboneODBC);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testZeroRows);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSyntaxError);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSimpleAccess);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testComplexType);
CppUnit_addTest(pSuite, ODBCSQLiteTest, testSimpleAccessVector);

View File

@ -22,6 +22,7 @@
#include "Poco/Exception.h"
#include "Poco/Data/LOB.h"
#include "Poco/Data/StatementImpl.h"
#include "Poco/Data/RecordSet.h"
#include "Poco/Data/ODBC/Connector.h"
#include "Poco/Data/ODBC/Utility.h"
#include "Poco/Data/ODBC/Diagnostics.h"
@ -41,6 +42,7 @@ using Poco::Data::ODBC::ODBCException;
using Poco::Data::ODBC::ConnectionException;
using Poco::Data::ODBC::StatementException;
using Poco::Data::ODBC::StatementDiagnostics;
using Poco::Data::Statement;
using Poco::format;
using Poco::Tuple;
using Poco::Any;
@ -1029,7 +1031,7 @@ void ODBCTest::testNull()
recreateNullsTable();
_pSession->setFeature("autoBind", bindValue(i));
_pSession->setFeature("autoExtract", bindValue(i+1));
_pExecutor->nulls();
_pExecutor->nulls(emptyStringIsSpace());
i += 2;
}
}
@ -1127,6 +1129,20 @@ void ODBCTest::testMultipleResults()
}
}
void ODBCTest::testMultipleResultsNoProj()
{
if (! &session()) fail("Test not available.");
session().setFeature("autoBind", true); // DB2 fails without that
for (int autoE = 0; autoE < 2; ++autoE)
{
recreatePersonTable();
_pSession->setFeature("autoExtract", autoE != 0);
_pExecutor->multipleResultsNoProj("SELECT * FROM " + ExecUtil::person() + " WHERE Age = ?; "
"SELECT Age FROM " + ExecUtil::person() + " WHERE FirstName = ?; "
"SELECT * FROM " + ExecUtil::person() + " WHERE Age = ? OR Age = ? ORDER BY Age;");
}
}
void ODBCTest::testSQLChannel()
{
@ -1219,6 +1235,46 @@ void ODBCTest::testNullable()
}
}
void ODBCTest::testNumeric()
{
if (!_pSession) fail("Test not available.");
recreateNumericTable();
std::vector<std::string> vals;
vals.push_back("12345678");
vals.push_back("123456789012.123");
vals.push_back("123456789012345678");
vals.push_back("1234567890.12345678");
vals.push_back("1234567890123456789012");
const std::string sqlStr = std::string("INSERT INTO ") + ExecUtil::numeric_tbl() +
"(id, num8, num16_3, num18, num18_8, num22) VALUES (1, " + str2NumExpr(vals[0],8,0) + " , " + str2NumExpr(vals[1],16,3) + ", " + str2NumExpr(vals[2], 18,0)
+ " , " + str2NumExpr(vals[3], 18, 8) + " , " + str2NumExpr(vals[4], 22, 0) + ")";
session() << sqlStr, now;
for (int i = 0; i < 8;)
{
_pSession->setFeature("autoBind", bindValue(i));
_pSession->setFeature("autoExtract", bindValue(i + 1));
_pExecutor->numericTypes(vals);
i += 2;
}
}
void ODBCTest::testInsertStatReuse()
{
for (int i = 0; i < 8; i += 2)
{
recreatePersonTable();
session().setFeature("autoBind", bindValue(i));
session().setFeature("autoExtract", bindValue(i + 1));
_pExecutor->insertStatReuse();
}
}
void ODBCTest::testUnicode()
{
@ -1256,6 +1312,28 @@ void ODBCTest::testReconnect()
}
void ODBCTest::testSyntaxError()
{
try {
session() << "select fro oops", now;
fail("Expected syntax error exception");
}
catch (const StatementException&)
{
}
try {
Statement stat(session());
stat << "select fro oops";
stat.execute();
fail("Expected syntax error exception");
}
catch (const StatementException&)
{
}
}
bool ODBCTest::canConnect(const std::string& driver,
std::string& dsn,
std::string& uid,
@ -1274,7 +1352,7 @@ bool ODBCTest::canConnect(const std::string& driver,
}
}
if (_drivers.end() == itDrv)
if ((_drivers.end() == itDrv) && (driver.length() != 0) && (driver[0] != '/'))
{
dsn = "";
uid = "";

View File

@ -141,6 +141,7 @@ public:
virtual void testDynamicAny();
virtual void testMultipleResults();
virtual void testMultipleResultsNoProj();
virtual void testSQLChannel();
virtual void testSQLLogger();
@ -153,6 +154,9 @@ public:
virtual void testUnicode();
virtual void testReconnect();
virtual void testNumeric();
virtual void testSyntaxError();
virtual void testInsertStatReuse();
protected:
typedef Poco::Data::ODBC::Utility::DriverMap Drivers;
@ -176,6 +180,9 @@ protected:
virtual void recreateMiscTable();
virtual void recreateLogTable();
virtual void recreateUnicodeTable();
virtual void recreateNumericTable();
virtual bool emptyStringIsSpace() { return false; }
virtual std::string str2NumExpr(const std::string& num, unsigned len, unsigned dec) { return num; }
static SessionPtr init(const std::string& driver,
std::string& dsn,
@ -264,6 +271,11 @@ inline void ODBCTest::recreateNullableTable()
throw Poco::NotImplementedException("ODBCTest::recreateNullableTable()");
}
inline void ODBCTest::recreateNumericTable()
{
throw Poco::NotImplementedException("ODBCTest::recreateNumericTable()");
}
inline void ODBCTest::recreatePersonTable()
{

View File

@ -12,6 +12,7 @@
#include "ODBCTestSuite.h"
#include "ODBCDB2Test.h"
#include "ODBCSybaseTest.h"
#include "ODBCMySQLTest.h"
#include "ODBCOracleTest.h"
#include "ODBCPostgreSQLTest.h"
@ -44,6 +45,7 @@ CppUnit::Test* ODBCTestSuite::suite()
addTest(pSuite, ODBCPostgreSQLTest::suite());
addTest(pSuite, ODBCSQLiteTest::suite());
addTest(pSuite, ODBCSQLServerTest::suite());
addTest(pSuite, SybaseODBC::suite());
addTest(pSuite, ODBCDB2Test::suite());
// MS Access driver does not support connection status detection
// disabled for the time being

File diff suppressed because it is too large Load Diff

View File

@ -73,6 +73,81 @@
using Poco::Data::ODBC::ConnectionException; \
using Poco::Data::ODBC::StatementException
struct ExecUtil
{
static std::string mangleTable(const std::string& name);
static std::string person()
{
return mangleTable("Person");
}
static std::string strings()
{
return mangleTable("Strings");
}
static std::string tuples()
{
return mangleTable("Tuples");
}
static std::string vectors()
{
return mangleTable("Vectors");
}
static std::string anys()
{
return mangleTable("Anys");
}
static std::string nulltest()
{
return mangleTable("NullTest");
}
static std::string misctest()
{
return mangleTable("MiscTest");
}
static std::string nullabletest()
{
return mangleTable("NullableTest");
}
static std::string pocolog()
{
return mangleTable("POCO_LOG");
}
static std::string pocolog_a()
{
return mangleTable("POCO_LOG_A");
}
static std::string stored_func()
{
return mangleTable("storedFunc");
}
static std::string stored_proc()
{
return mangleTable("storedProc");
}
static std::string test_tbl()
{
return mangleTable("Test");
}
static std::string numeric_tbl()
{
return mangleTable("numer_t");
}
};
class SQLExecutor: public CppUnit::TestCase
{
@ -89,7 +164,7 @@ public:
DE_BOUND
};
SQLExecutor(const std::string& name, Poco::Data::Session* _pSession);
SQLExecutor(const std::string& name, Poco::Data::Session* _pSession, const std::string& connInitSql = std::string(), const std::string& schemaName = std::string());
~SQLExecutor();
void execute(const std::string& sql);
@ -147,6 +222,8 @@ public:
void limitPrepare();
void limitZero();
void prepare();
void numericTypes(const std::vector<std::string>& vals);
void insertStatReuse();
template <typename C1, typename C2, typename C3, typename C4, typename C5, typename C6>
void doBulkWithBool(Poco::UInt32 size, const std::string& blobPlaceholder="?")
@ -173,7 +250,7 @@ public:
try
{
session() <<
Poco::format("INSERT INTO MiscTest VALUES (?,%s,?,?,?,?)", blobPlaceholder),
Poco::format("INSERT INTO %s VALUES (?,%s,?,?,?,?)", ExecUtil::misctest(), blobPlaceholder),
use(strings),
use(blobs),
use(ints),
@ -183,14 +260,14 @@ public:
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try { session() << "DELETE FROM MiscTest", now; }
try { session() << "DELETE FROM "<< ExecUtil::misctest(), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try
{
session() <<
Poco::format("INSERT INTO MiscTest VALUES (?,%s,?,?,?,?)", blobPlaceholder),
Poco::format("INSERT INTO %s VALUES (?,%s,?,?,?,?)", ExecUtil::misctest(), blobPlaceholder),
use(strings, bulk),
use(blobs, bulk),
use(ints, bulk),
@ -209,7 +286,7 @@ public:
try
{
session() << "SELECT * FROM MiscTest ORDER BY Third",
session() << "SELECT * FROM "<< ExecUtil::misctest() <<" ORDER BY Third",
into(strings),
into(blobs),
into(ints),
@ -239,14 +316,14 @@ public:
try
{
session() << "SELECT First FROM MiscTest", into(ints, bulk(size)), limit(size+1), now;
session() << "SELECT First FROM "<< ExecUtil::misctest(), into(ints, bulk(size)), limit(size+1), now;
fail ("must fail");
}
catch(Poco::InvalidArgumentException&){ }
try
{
session() << "SELECT First FROM MiscTest", into(ints), bulk(size), now;
session() << "SELECT First FROM "<< ExecUtil::misctest(), into(ints), bulk(size), now;
fail ("must fail");
}
catch(Poco::InvalidAccessException&){ }
@ -263,7 +340,7 @@ public:
try
{
session() << "SELECT First, Second, Third, Fourth, Fifth, Sixth FROM MiscTest ORDER BY Third",
session() << "SELECT First, Second, Third, Fourth, Fifth, Sixth FROM "<< ExecUtil::misctest() <<" ORDER BY Third",
into(strings, bulk),
into(blobs, bulk(size)),
into(ints, bulk(size)),
@ -313,7 +390,7 @@ public:
try
{
session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?)",
session() << "INSERT INTO "<< ExecUtil::misctest() <<" VALUES (?,?,?,?,?)",
use(strings),
use(blobs),
use(ints),
@ -322,13 +399,13 @@ public:
} catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try { session() << "DELETE FROM MiscTest", now; }
try { session() << "DELETE FROM "<< ExecUtil::misctest(), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try
{
session() << "INSERT INTO MiscTest VALUES (?,?,?,?,?)",
session() << "INSERT INTO "<< ExecUtil::misctest() <<" VALUES (?,?,?,?,?)",
use(strings, bulk),
use(blobs, bulk),
use(ints, bulk),
@ -345,7 +422,7 @@ public:
try
{
session() << "SELECT * FROM MiscTest ORDER BY First",
session() << "SELECT * FROM "<< ExecUtil::misctest() <<" ORDER BY First",
into(strings),
into(blobs),
into(ints),
@ -372,14 +449,14 @@ public:
try
{
session() << "SELECT First FROM MiscTest", into(ints, bulk(size)), limit(size+1), now;
session() << "SELECT First FROM "<< ExecUtil::misctest(), into(ints, bulk(size)), limit(size+1), now;
fail ("must fail");
}
catch(Poco::InvalidArgumentException&){ }
try
{
session() << "SELECT First FROM MiscTest", into(ints), bulk(size), now;
session() << "SELECT First FROM "<< ExecUtil::misctest(), into(ints), bulk(size), now;
fail ("must fail");
}
catch(Poco::InvalidAccessException&){ }
@ -392,7 +469,7 @@ public:
try
{
session() << "SELECT * FROM MiscTest ORDER BY First",
session() << "SELECT * FROM "<< ExecUtil::misctest() <<" ORDER BY First",
into(strings, bulk(size)),
into(blobs, bulk(size)),
into(ints, bulk(size)),
@ -435,6 +512,17 @@ public:
void singleSelect();
void emptyDB();
void assertImpl(bool condition, const std::string& conditionExpression, long lineNumber, const std::string& fileName)
{
assertImplementation(condition, conditionExpression, lineNumber, fileName);
}
void failImpl(const std::string& message, long lineNumber, const std::string& fileName)
{
fail(message, lineNumber, fileName);
}
void blob(int bigSize = 1024, const std::string& blobPlaceholder = "?");
template <typename C1, typename C2>
@ -448,16 +536,16 @@ public:
C1 address(size, "Address");
C2 img(size, CLOB("0123456789", 10));
int count = 0;
try { session() << "INSERT INTO Person VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(img), now; }
try { session() << "INSERT INTO " << ExecUtil::person() << " VALUES (?,?,?,?)", use(lastName), use(firstName), use(address), use(img), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
try { session() << "SELECT COUNT(*) FROM Person", into(count), now; }
try { session() << "SELECT COUNT(*) FROM " << ExecUtil::person(), into(count), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
assert (count == size);
C2 res;
try { session() << "SELECT Image FROM Person", into(res), now; }
try { session() << "SELECT Image FROM " << ExecUtil::person(), into(res), now; }
catch(ConnectionException& ce){ std::cout << ce.toString() << std::endl; fail (funct); }
catch(StatementException& se){ std::cout << se.toString() << std::endl; fail (funct); }
assert (res.size() == img.size());
@ -476,13 +564,13 @@ public:
void internalExtraction();
void filter(const std::string& query =
"SELECT * FROM Vectors ORDER BY int0 ASC",
const std::string& intFldName = "int0");
"SELECT * FROM " + ExecUtil::vectors() + " ORDER BY i0 ASC",
const std::string& intFldName = "i0");
void internalBulkExtraction();
void internalBulkExtractionUTF16();
void internalStorageType();
void nulls();
void nulls(bool emptyStrIsSpace = false);
void notNulls(const std::string& sqlState = "23502");
void rowIterator();
void stdVectorBool();
@ -493,9 +581,11 @@ public:
void dynamicAny();
void multipleResults(const std::string& sql =
"SELECT * FROM Person WHERE Age = ?; "
"SELECT Age FROM Person WHERE FirstName = 'Bart'; "
"SELECT * FROM Person WHERE Age = ? OR Age = ? ORDER BY Age;");
"SELECT * FROM " + ExecUtil::person() + " WHERE Age = ?; "
"SELECT Age FROM " + ExecUtil::person() +" WHERE FirstName = 'Bart'; "
"SELECT * FROM " + ExecUtil::person() + " WHERE Age = ? OR Age = ? ORDER BY Age;");
void multipleResultsNoProj(const std::string& sql);
void sqlChannel(const std::string& connect);
void sqlLogger(const std::string& connect);
@ -514,9 +604,12 @@ private:
static const std::string MULTI_SELECT;
void setTransactionIsolation(Poco::Data::Session& session, Poco::UInt32 ti);
std::string schemaTable(const std::string& tblName) const;
Poco::Data::Session& session();
Poco::Data::Session* _pSession;
std::string _connInitSql;
std::string _schemaName;
};
@ -527,4 +620,10 @@ inline Poco::Data::Session& SQLExecutor::session()
}
inline std::string SQLExecutor::schemaTable(const std::string& tblName) const
{
return _schemaName.empty() ? tblName : _schemaName + "." + tblName;
}
#endif // SQLExecutor_INCLUDED

View File

@ -43,72 +43,72 @@ public:
~Binder();
/// Destroys the Binder.
void bind(std::size_t pos, const Poco::Int8 &val, Direction dir);
void bind(std::size_t pos, const Poco::Int8 &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int8.
void bind(std::size_t pos, const Poco::UInt8 &val, Direction dir);
void bind(std::size_t pos, const Poco::UInt8 &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt8.
void bind(std::size_t pos, const Poco::Int16 &val, Direction dir);
void bind(std::size_t pos, const Poco::Int16 &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int16.
void bind(std::size_t pos, const Poco::UInt16 &val, Direction dir);
void bind(std::size_t pos, const Poco::UInt16 &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt16.
void bind(std::size_t pos, const Poco::Int32 &val, Direction dir);
void bind(std::size_t pos, const Poco::Int32 &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int32.
void bind(std::size_t pos, const Poco::UInt32 &val, Direction dir);
void bind(std::size_t pos, const Poco::UInt32 &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt32.
void bind(std::size_t pos, const Poco::Int64 &val, Direction dir);
void bind(std::size_t pos, const Poco::Int64 &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an Int64.
void bind(std::size_t pos, const Poco::UInt64 &val, Direction dir);
void bind(std::size_t pos, const Poco::UInt64 &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an UInt64.
#ifndef POCO_LONG_IS_64_BIT
void bind(std::size_t pos, const long &val, Direction dir);
void bind(std::size_t pos, const long &val, Direction dir, const WhenNullCb& nullCb);
/// Binds a long
void bind(std::size_t pos, const unsigned long &val, Direction dir);
void bind(std::size_t pos, const unsigned long &val, Direction dir, const WhenNullCb& nullCb);
/// Binds an unsigned long
#endif
void bind(std::size_t pos, const bool &val, Direction dir);
void bind(std::size_t pos, const bool &val, Direction dir, const WhenNullCb& nullCb);
/// Binds a boolean.
void bind(std::size_t pos, const float &val, Direction dir);
void bind(std::size_t pos, const float &val, Direction dir, const WhenNullCb& nullCb);
/// Binds a float.
void bind(std::size_t pos, const double &val, Direction dir);
void bind(std::size_t pos, const double &val, Direction dir, const WhenNullCb& nullCb);
/// Binds a double.
void bind(std::size_t pos, const char &val, Direction dir);
void bind(std::size_t pos, const char &val, Direction dir, const WhenNullCb& nullCb);
/// Binds a single character.
void bind(std::size_t pos, const char* const &pVal, Direction dir);
void bind(std::size_t pos, const char* const &pVal, Direction dir, const WhenNullCb& nullCb);
/// Binds a const char ptr.
void bind(std::size_t pos, const std::string& val, Direction dir);
void bind(std::size_t pos, const std::string& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a string.
void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir);
void bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a BLOB.
void bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir);
void bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a CLOB.
void bind(std::size_t pos, const Date& val, Direction dir);
void bind(std::size_t pos, const Date& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a Date.
void bind(std::size_t pos, const Time& val, Direction dir);
void bind(std::size_t pos, const Time& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a Time.
void bind(std::size_t pos, const DateTime& val, Direction dir);
void bind(std::size_t pos, const DateTime& val, Direction dir, const WhenNullCb& nullCb);
/// Binds a DateTime.
void bind(std::size_t pos, const NullData& val, Direction dir);
void bind(std::size_t pos, const NullData& val, Direction dir, const std::type_info& bindType);
/// Binds a null.
private:
@ -117,7 +117,7 @@ private:
/// if error has occurred.
template <typename T>
void bindLOB(std::size_t pos, const Poco::Data::LOB<T>& val, Direction dir)
void bindLOB(std::size_t pos, const Poco::Data::LOB<T>& val, Direction dir, const WhenNullCb& nullCb)
{
// convert a blob to a an unsigned char* array
const T* pData = reinterpret_cast<const T*>(val.rawContent());
@ -134,85 +134,85 @@ private:
//
// inlines
//
inline void Binder::bind(std::size_t pos, const Poco::Int8 &val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::Int8 &val, Direction dir, const WhenNullCb& nullCb)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const Poco::UInt8 &val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::UInt8 &val, Direction dir, const WhenNullCb& nullCb)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const Poco::Int16 &val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::Int16 &val, Direction dir, const WhenNullCb& nullCb)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const Poco::UInt16 &val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::UInt16 &val, Direction dir, const WhenNullCb& nullCb)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const Poco::UInt32 &val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::UInt32 &val, Direction dir, const WhenNullCb& nullCb)
{
Poco::Int32 tmp = static_cast<Poco::Int32>(val);
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const Poco::UInt64 &val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::UInt64 &val, Direction dir, const WhenNullCb& nullCb)
{
Poco::Int64 tmp = static_cast<Poco::Int64>(val);
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const bool &val, Direction dir)
inline void Binder::bind(std::size_t pos, const bool &val, Direction dir, const WhenNullCb& nullCb)
{
Poco::Int32 tmp = (val ? 1 : 0);
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const float &val, Direction dir)
inline void Binder::bind(std::size_t pos, const float &val, Direction dir, const WhenNullCb& nullCb)
{
double tmp = val;
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const char &val, Direction dir)
inline void Binder::bind(std::size_t pos, const char &val, Direction dir, const WhenNullCb& nullCb)
{
Poco::Int32 tmp = val;
bind(pos, tmp, dir);
bind(pos, tmp, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const char* const &pVal, Direction dir)
inline void Binder::bind(std::size_t pos, const char* const &pVal, Direction dir, const WhenNullCb& nullCb)
{
std::string val(pVal);
bind(pos, val, dir);
bind(pos, val, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::Data::BLOB& val, Direction dir, const WhenNullCb& nullCb)
{
bindLOB<Poco::Data::BLOB::ValueType>(pos, val, dir);
bindLOB<Poco::Data::BLOB::ValueType>(pos, val, dir, nullCb);
}
inline void Binder::bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir)
inline void Binder::bind(std::size_t pos, const Poco::Data::CLOB& val, Direction dir, const WhenNullCb& nullCb)
{
bindLOB<Poco::Data::CLOB::ValueType>(pos, val, dir);
bindLOB<Poco::Data::CLOB::ValueType>(pos, val, dir, nullCb);
}

View File

@ -60,7 +60,7 @@ protected:
/// All changes are counted, even if they are later undone by a ROLLBACK or ABORT.
/// Changes associated with creating and dropping tables are not counted.
const MetaColumn& metaColumn(std::size_t pos) const;
const MetaColumn& metaColumn(std::size_t pos, std::size_t dataSet) const;
/// Returns column meta data.
bool hasNext();

View File

@ -44,14 +44,14 @@ Binder::~Binder()
}
void Binder::bind(std::size_t pos, const Poco::Int32 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int32 &val, Direction dir, const WhenNullCb& nullCb)
{
int rc = sqlite3_bind_int(_pStmt, (int) pos, val);
checkReturn(rc);
}
void Binder::bind(std::size_t pos, const Poco::Int64 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int64 &val, Direction dir, const WhenNullCb& nullCb)
{
int rc = sqlite3_bind_int64(_pStmt, (int) pos, val);
checkReturn(rc);
@ -59,14 +59,14 @@ void Binder::bind(std::size_t pos, const Poco::Int64 &val, Direction dir)
#ifndef POCO_LONG_IS_64_BIT
void Binder::bind(std::size_t pos, const long &val, Direction dir)
void Binder::bind(std::size_t pos, const long &val, Direction dir, const WhenNullCb& nullCb)
{
long tmp = static_cast<long>(val);
int rc = sqlite3_bind_int(_pStmt, (int) pos, tmp);
checkReturn(rc);
}
void Binder::bind(std::size_t pos, const unsigned long &val, Direction dir)
void Binder::bind(std::size_t pos, const unsigned long &val, Direction dir, const WhenNullCb& nullCb)
{
long tmp = static_cast<long>(val);
int rc = sqlite3_bind_int(_pStmt, (int) pos, tmp);
@ -75,45 +75,45 @@ void Binder::bind(std::size_t pos, const unsigned long &val, Direction dir)
#endif
void Binder::bind(std::size_t pos, const double &val, Direction dir)
void Binder::bind(std::size_t pos, const double &val, Direction dir, const WhenNullCb& nullCb)
{
int rc = sqlite3_bind_double(_pStmt, (int) pos, val);
checkReturn(rc);
}
void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
void Binder::bind(std::size_t pos, const std::string& val, Direction dir, const WhenNullCb& nullCb)
{
int rc = sqlite3_bind_text(_pStmt, (int) pos, val.c_str(), (int) val.size()*sizeof(char), SQLITE_TRANSIENT);
checkReturn(rc);
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
void Binder::bind(std::size_t pos, const Date& val, Direction dir, const WhenNullCb& nullCb)
{
DateTime dt(val.year(), val.month(), val.day());
std::string str(DateTimeFormatter::format(dt, Utility::SQLITE_DATE_FORMAT));
bind(pos, str, dir);
bind(pos, str, dir, nullCb);
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
void Binder::bind(std::size_t pos, const Time& val, Direction dir, const WhenNullCb& nullCb)
{
DateTime dt;
dt.assign(dt.year(), dt.month(), dt.day(), val.hour(), val.minute(), val.second());
std::string str(DateTimeFormatter::format(dt, Utility::SQLITE_TIME_FORMAT));
bind(pos, str, dir);
bind(pos, str, dir, nullCb);
}
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir, const WhenNullCb& nullCb)
{
std::string dt(DateTimeFormatter::format(val, DateTimeFormat::ISO8601_FORMAT));
bind(pos, dt, dir);
bind(pos, dt, dir, nullCb);
}
void Binder::bind(std::size_t pos, const NullData&, Direction)
void Binder::bind(std::size_t pos, const NullData&, Direction, const std::type_info& bindType)
{
sqlite3_bind_null(_pStmt, pos);
}

View File

@ -302,11 +302,10 @@ std::size_t SQLiteStatementImpl::columnsReturned() const
}
const MetaColumn& SQLiteStatementImpl::metaColumn(std::size_t pos) const
const MetaColumn& SQLiteStatementImpl::metaColumn(std::size_t pos, std::size_t dataSet) const
{
std::size_t curDataSet = currentDataSet();
poco_assert (pos >= 0 && pos <= _columns[curDataSet].size());
return _columns[curDataSet][pos];
poco_assert (pos >= 0 && pos <= _columns[dataSet].size());
return _columns[dataSet][pos];
}

View File

@ -39,24 +39,86 @@ namespace Poco {
namespace Data {
typedef NullType NullData;
enum NullData
{
NULL_GENERIC = Poco::NULL_GENERIC,
DATA_NULL_INTEGER = 1,
DATA_NULL_STRING = 2,
DATA_NULL_DATE = 3,
DATA_NULL_TIME = 4,
DATA_NULL_DATETIME = 5,
DATA_NULL_BLOB = 6,
DATA_NULL_FLOAT = 7
};
struct NullValue
{
NullValue()
{}
template <typename T>
operator Poco::Nullable<T>() const
{
return Poco::Nullable<T>();
}
template <typename T>
static NullData nullCode()
{
return Data::NULL_GENERIC;
}
};
namespace Keywords {
static const NullData null = NULL_GENERIC;
static const NullValue null;
} // namespace Keywords
template <typename T>
inline bool operator==(const NullValue& nv, const Nullable<T>& n)
{
return n.isNull();
}
template <typename T>
inline bool operator!=(const NullValue& nv, const Nullable<T>& n)
{
return !n.isNull();
}
class Data_API AbstractBinder
/// Interface for Binding data types to placeholders.
{
public:
typedef SharedPtr<AbstractBinder> Ptr;
struct WhenNullCb
{
WhenNullCb() :_func(NULL)
{}
inline bool defined() const
{
return (_func != NULL);
}
inline void onNull()
{
if (_func) _func(_data);
}
protected:
void* _data;
void (*_func)(void*);
};
enum Direction
/// Binding direction for a parameter.
{
@ -71,7 +133,7 @@ public:
virtual ~AbstractBinder();
/// Destroys the AbstractBinder.
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Poco::Int8& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an Int8.
virtual void bind(std::size_t pos, const std::vector<Poco::Int8>& val, Direction dir = PD_IN);
@ -83,7 +145,7 @@ public:
virtual void bind(std::size_t pos, const std::list<Poco::Int8>& val, Direction dir = PD_IN);
/// Binds an Int8 list.
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Poco::UInt8& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an UInt8.
virtual void bind(std::size_t pos, const std::vector<Poco::UInt8>& val, Direction dir = PD_IN);
@ -95,7 +157,7 @@ public:
virtual void bind(std::size_t pos, const std::list<Poco::UInt8>& val, Direction dir = PD_IN);
/// Binds an UInt8 list.
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Poco::Int16& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an Int16.
virtual void bind(std::size_t pos, const std::vector<Poco::Int16>& val, Direction dir = PD_IN);
@ -107,7 +169,7 @@ public:
virtual void bind(std::size_t pos, const std::list<Poco::Int16>& val, Direction dir = PD_IN);
/// Binds an Int16 list.
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Poco::UInt16& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an UInt16.
virtual void bind(std::size_t pos, const std::vector<Poco::UInt16>& val, Direction dir = PD_IN);
@ -119,7 +181,7 @@ public:
virtual void bind(std::size_t pos, const std::list<Poco::UInt16>& val, Direction dir = PD_IN);
/// Binds an UInt16 list.
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Poco::Int32& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an Int32.
virtual void bind(std::size_t pos, const std::vector<Poco::Int32>& val, Direction dir = PD_IN);
@ -131,7 +193,7 @@ public:
virtual void bind(std::size_t pos, const std::list<Poco::Int32>& val, Direction dir = PD_IN);
/// Binds an Int32 list.
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Poco::UInt32& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an UInt32.
virtual void bind(std::size_t pos, const std::vector<Poco::UInt32>& val, Direction dir = PD_IN);
@ -143,7 +205,7 @@ public:
virtual void bind(std::size_t pos, const std::list<Poco::UInt32>& val, Direction dir = PD_IN);
/// Binds an UInt32 list.
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Poco::Int64& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an Int64.
virtual void bind(std::size_t pos, const std::vector<Poco::Int64>& val, Direction dir = PD_IN);
@ -155,7 +217,7 @@ public:
virtual void bind(std::size_t pos, const std::list<Poco::Int64>& val, Direction dir = PD_IN);
/// Binds an Int64 list.
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Poco::UInt64& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an UInt64.
virtual void bind(std::size_t pos, const std::vector<Poco::UInt64>& val, Direction dir = PD_IN);
@ -168,11 +230,11 @@ public:
/// Binds an UInt64 list.
#ifndef POCO_LONG_IS_64_BIT
virtual void bind(std::size_t pos, const long& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const long& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a long.
virtual void bind(std::size_t pos, const unsigned long& val, Direction dir = PD_IN) = 0;
/// Binds an unsigned long.
virtual void bind(std::size_t pos, const unsigned long& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds an unsiged long.
virtual void bind(std::size_t pos, const std::vector<long>& val, Direction dir = PD_IN);
/// Binds a long vector.
@ -184,7 +246,7 @@ public:
/// Binds a long list.
#endif
virtual void bind(std::size_t pos, const bool& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const bool& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a boolean.
virtual void bind(std::size_t pos, const std::vector<bool>& val, Direction dir = PD_IN);
@ -196,7 +258,7 @@ public:
virtual void bind(std::size_t pos, const std::list<bool>& val, Direction dir = PD_IN);
/// Binds a boolean list.
virtual void bind(std::size_t pos, const float& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const float& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a float.
virtual void bind(std::size_t pos, const std::vector<float>& val, Direction dir = PD_IN);
@ -208,7 +270,7 @@ public:
virtual void bind(std::size_t pos, const std::list<float>& val, Direction dir = PD_IN);
/// Binds a float list.
virtual void bind(std::size_t pos, const double& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const double& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a double.
virtual void bind(std::size_t pos, const std::vector<double>& val, Direction dir = PD_IN);
@ -220,7 +282,7 @@ public:
virtual void bind(std::size_t pos, const std::list<double>& val, Direction dir = PD_IN);
/// Binds a double list.
virtual void bind(std::size_t pos, const char& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const char& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a single character.
virtual void bind(std::size_t pos, const std::vector<char>& val, Direction dir = PD_IN);
@ -232,10 +294,10 @@ public:
virtual void bind(std::size_t pos, const std::list<char>& val, Direction dir = PD_IN);
/// Binds a character list.
virtual void bind(std::size_t pos, const char* const& pVal, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const char* const& pVal, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a const char ptr.
virtual void bind(std::size_t pos, const std::string& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const std::string& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a string.
virtual void bind(std::size_t pos, const std::vector<std::string>& val, Direction dir = PD_IN);
@ -247,7 +309,7 @@ public:
virtual void bind(std::size_t pos, const std::list<std::string>& val, Direction dir = PD_IN);
/// Binds a string list.
virtual void bind(std::size_t pos, const UTF16String& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const UTF16String& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb());
/// Binds a UTF-16 Unicode string.
virtual void bind(std::size_t pos, const std::vector<UTF16String>& val, Direction dir = PD_IN);
@ -259,10 +321,10 @@ public:
virtual void bind(std::size_t pos, const std::list<UTF16String>& val, Direction dir = PD_IN);
/// Binds a UTF-16 Unicode string list.
virtual void bind(std::size_t pos, const BLOB& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const BLOB& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a BLOB.
virtual void bind(std::size_t pos, const CLOB& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const CLOB& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a CLOB.
virtual void bind(std::size_t pos, const std::vector<BLOB>& val, Direction dir = PD_IN);
@ -283,7 +345,7 @@ public:
virtual void bind(std::size_t pos, const std::list<CLOB>& val, Direction dir = PD_IN);
/// Binds a CLOB list.
virtual void bind(std::size_t pos, const DateTime& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const DateTime& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a DateTime.
virtual void bind(std::size_t pos, const std::vector<DateTime>& val, Direction dir = PD_IN);
@ -295,7 +357,7 @@ public:
virtual void bind(std::size_t pos, const std::list<DateTime>& val, Direction dir = PD_IN);
/// Binds a DateTime list.
virtual void bind(std::size_t pos, const Date& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Date& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a Date.
virtual void bind(std::size_t pos, const std::vector<Date>& val, Direction dir = PD_IN);
@ -307,7 +369,7 @@ public:
virtual void bind(std::size_t pos, const std::list<Date>& val, Direction dir = PD_IN);
/// Binds a Date list.
virtual void bind(std::size_t pos, const Time& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const Time& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb()) = 0;
/// Binds a Time.
virtual void bind(std::size_t pos, const std::vector<Time>& val, Direction dir = PD_IN);
@ -319,22 +381,22 @@ public:
virtual void bind(std::size_t pos, const std::list<Time>& val, Direction dir = PD_IN);
/// Binds a Time list.
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN) = 0;
virtual void bind(std::size_t pos, const NullData& val, Direction dir = PD_IN, const std::type_info& bindType = typeid(void)) = 0;
/// Binds a null.
virtual void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const std::vector<NullData>& val, Direction dir = PD_IN, const std::type_info& bindElemType = typeid(void));
/// Binds a null vector.
virtual void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const std::deque<NullData>& val, Direction dir = PD_IN, const std::type_info& bindElemType = typeid(void));
/// Binds a null deque.
virtual void bind(std::size_t pos, const std::list<NullData>& val, Direction dir = PD_IN);
virtual void bind(std::size_t pos, const std::list<NullData>& val, Direction dir = PD_IN, const std::type_info& bindElemType = typeid(void));
/// Binds a null list.
void bind(std::size_t pos, const Any& val, Direction dir = PD_IN);
void bind(std::size_t pos, const Any& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb());
/// Binds an Any.
void bind(std::size_t pos, const Poco::Dynamic::Var& val, Direction dir = PD_IN);
void bind(std::size_t pos, const Poco::Dynamic::Var& val, Direction dir = PD_IN, const WhenNullCb& nullCb = WhenNullCb());
/// Binds a Var.
virtual void reset();

View File

@ -1401,6 +1401,13 @@ inline AbstractBinding::Ptr use(const NullData& t, const std::string& name = "")
return new Binding<NullData>(const_cast<NullData&>(t), name, AbstractBinding::PD_IN);
}
inline AbstractBinding::Ptr use(const NullValue& t, const std::string& name = "")
/// NullData overload.
{
return use(NullValue::nullCode<void>(), name);
}
template <typename T>
inline AbstractBinding::Ptr useRef(T& t, const std::string& name = "")

View File

@ -39,6 +39,43 @@ namespace Poco {
namespace Data {
template <typename CollTp, typename ElemTp = typename CollTp::value_type>
struct DefaultInitializer
{
static void appendElem(CollTp& coll, const ElemTp& defVal)
{
coll.push_back(defVal);
}
};
template <typename CollTp>
struct DefaultInitializer<CollTp, CLOB>
{
static void appendElem(CollTp& coll, const CLOB& defVal)
{
CLOB v(defVal.rawContent(), defVal.size());
coll.push_back(v);
}
};
template <typename CollTp>
struct DefaultInitializer<CollTp, BLOB>
{
static void appendElem(CollTp& coll, const BLOB& defVal)
{
BLOB v(defVal.rawContent(), defVal.size());
coll.push_back(v);
}
};
template <typename CollTp>
inline void appendElem(CollTp& coll, const typename CollTp::value_type& defVal)
{
DefaultInitializer<CollTp, typename CollTp::value_type>::appendElem(coll, defVal);
}
template <class T>
class Extraction: public AbstractExtraction
/// Concrete Data Type specific extraction of values from a query result set.
@ -190,7 +227,7 @@ public:
std::size_t extract(std::size_t pos)
{
AbstractExtractor::Ptr pExt = getExtractor();
_rResult.push_back(_default);
appendElem(_rResult, _default);
TypeHandler<T>::extract(pos, _rResult.back(), _default, pExt);
_nulls.push_back(isValueNull(_rResult.back(), pExt->isNull(pos)));
return 1u;
@ -372,7 +409,7 @@ public:
std::size_t extract(std::size_t pos)
{
AbstractExtractor::Ptr pExt = getExtractor();
_rResult.push_back(_default);
appendElem(_rResult, _default);
TypeHandler<T>::extract(pos, _rResult.back(), _default, pExt);
_nulls.push_back(isValueNull(_rResult.back(), pExt->isNull(pos)));
return 1u;
@ -462,7 +499,7 @@ public:
std::size_t extract(std::size_t pos)
{
AbstractExtractor::Ptr pExt = getExtractor();
_rResult.push_back(_default);
appendElem(_rResult, _default);
TypeHandler<T>::extract(pos, _rResult.back(), _default, pExt);
_nulls.push_back(isValueNull(_rResult.back(), pExt->isNull(pos)));
return 1u;

View File

@ -32,26 +32,28 @@ class Data_API Position
/// indicate the recordset position in batch SQL statements.
{
public:
Position(Poco::UInt32 value);
typedef Poco::UInt32 PositionType;
Position(PositionType value);
/// Creates the Position.
~Position();
/// Destroys the Position.
Poco::UInt32 value() const;
PositionType value() const;
/// Returns the position value.
private:
Position();
Poco::UInt32 _value;
PositionType _value;
};
///
/// inlines
///
inline Poco::UInt32 Position::value() const
inline Position::PositionType Position::value() const
{
return _value;
}

View File

@ -190,6 +190,10 @@ public:
/// Returns reference to row at position pos.
/// Rows are lazy-created and cached.
template <class T>
const T& value(std::size_t col) const;
/// Returns the reference to data value at [col] location.
template <class T>
const T& value(std::size_t col, std::size_t dataRow, bool useFilter = true) const
/// Returns the reference to data value at [col, row] location.
@ -315,16 +319,16 @@ public:
/// Returns true if there is at least one row in the RecordSet,
/// false otherwise.
Poco::Dynamic::Var value(const std::string& name);
Poco::Dynamic::Var value(const std::string& name) const;
/// Returns the value in the named column of the current row.
Poco::Dynamic::Var value(std::size_t index);
Poco::Dynamic::Var value(std::size_t index) const;
/// Returns the value in the given column of the current row.
Poco::Dynamic::Var operator [] (const std::string& name);
Poco::Dynamic::Var operator [] (const std::string& name) const;
/// Returns the value in the named column of the current row.
Poco::Dynamic::Var operator [] (std::size_t index);
Poco::Dynamic::Var operator [] (std::size_t index) const;
/// Returns the value in the named column of the current row.
MetaColumn::ColumnDataType columnType(std::size_t pos) const;
@ -353,6 +357,9 @@ public:
bool isNull(const std::string& name) const;
/// Returns true if column value of the current row is null.
bool isNull(std::size_t& colNo) const;
/// Returns true if column value of the current row is null.
std::ostream& copyNames(std::ostream& os) const;
/// Copies the column names to the target output stream.
/// Copied string is formatted by the current RowFormatter.
@ -457,6 +464,8 @@ private:
}
}
size_t storageRowCount() const;
bool isAllowed(std::size_t row) const;
/// Returns true if the specified row is allowed by the
/// currently active filter.
@ -530,29 +539,35 @@ inline Statement& RecordSet::operator = (const Statement& stmt)
}
inline Poco::Dynamic::Var RecordSet::value(const std::string& name)
inline Poco::Dynamic::Var RecordSet::value(const std::string& name) const
{
return value(name, _currentRow);
}
inline Poco::Dynamic::Var RecordSet::value(std::size_t index)
inline Poco::Dynamic::Var RecordSet::value(std::size_t index) const
{
return value(index, _currentRow);
}
inline Poco::Dynamic::Var RecordSet::operator [] (const std::string& name)
inline Poco::Dynamic::Var RecordSet::operator [] (const std::string& name) const
{
return value(name, _currentRow);
}
inline Poco::Dynamic::Var RecordSet::operator [] (std::size_t index)
inline Poco::Dynamic::Var RecordSet::operator [] (std::size_t index) const
{
return value(index, _currentRow);
}
template <class T>
inline const T& RecordSet::value(std::size_t col) const
{
return value<T>(col, _currentRow);
}
inline MetaColumn::ColumnDataType RecordSet::columnType(std::size_t pos)const
{
@ -602,6 +617,11 @@ inline bool RecordSet::isNull(const std::string& name) const
}
inline bool RecordSet::isNull(std::size_t& colNo) const
{
return isNull(colNo, _currentRow);
}
inline RecordSet::ConstIterator& RecordSet::begin() const
{
return *_pBegin;
@ -638,6 +658,11 @@ inline void RecordSet::formatNames() const
}
inline size_t RecordSet::storageRowCount() const
{
return impl()->rowsExtracted();
}
/* TODO
namespace Keywords {

View File

@ -104,6 +104,15 @@ public:
Poco::Dynamic::Var& operator [] (const std::string& name);
/// Returns the reference to data value at named column location.
const Poco::Dynamic::Var& get(std::size_t col) const;
/// Returns the reference to data value at column location.
const Poco::Dynamic::Var& operator [] (std::size_t col) const;
/// Returns the reference to data value at column location.
const Poco::Dynamic::Var& operator [] (const std::string& name) const;
/// Returns the reference to data value at named column location.
template <typename T>
void append(const std::string& name, const T& val)
/// Appends the value to the row.
@ -225,7 +234,7 @@ private:
ValueVec& values();
/// Returns the reference to values vector.
std::size_t getPosition(const std::string& name);
std::size_t getPosition(const std::string& name) const;
bool isEqualSize(const Row& other) const;
bool isEqualType(const Row& other) const;
@ -287,6 +296,18 @@ inline Poco::Dynamic::Var& Row::operator [] (const std::string& name)
}
inline const Poco::Dynamic::Var& Row::operator [] (std::size_t col) const
{
return get(col);
}
inline const Poco::Dynamic::Var& Row::operator [] (const std::string& name) const
{
return get(getPosition(name));
}
inline const RowFormatter& Row::getFormatter() const
{
return *_pFormatter;

View File

@ -365,10 +365,18 @@ public:
/// Returns false if the current data set index points to the last
/// data set. Otherwise, it returns true.
std::size_t firstDataSet();
/// Activates the first data set
std::size_t currentDataSet() const;
/// Returns the current data set.
void setRowFormatter(RowFormatter::Ptr pRowFormatter);
/// Sets the row formatter for this statement.
/// Statement takes the ownership of the formatter.
void insertHint();
/// Tells the statement that it is an sinsert one
protected:
typedef StatementImpl::Ptr ImplPtr;
@ -670,7 +678,7 @@ inline const AbstractExtractionVec& Statement::extractions() const
inline const MetaColumn& Statement::metaColumn(std::size_t pos) const
{
return _pImpl->metaColumn(pos);
return _pImpl->metaColumn(pos, _pImpl->currentDataSet());
}
@ -770,6 +778,19 @@ inline bool Statement::isBulkExtraction() const
}
inline std::size_t Statement::firstDataSet()
{
_pImpl->firstDataSet();
return 0;
}
inline std::size_t Statement::currentDataSet() const
{
return _pImpl->currentDataSet();
}
inline bool Statement::isAsync() const
{
return _async;
@ -789,6 +810,11 @@ inline const RowFormatter::Ptr& Statement::getRowFormatter()
}
inline void Statement::insertHint()
{
_pImpl->insertHint();
}
inline void swap(Statement& s1, Statement& s2)
{
s1.swap(s2);

View File

@ -44,6 +44,8 @@ namespace Poco {
namespace Data {
class RecordSet;
class Data_API StatementImpl
/// StatementImpl interface that subclasses must implement to define database dependent query execution.
///
@ -157,7 +159,13 @@ public:
std::size_t dataSetCount() const;
/// Returns the number of data sets associated with the statement.
std::size_t currentDataSet() const;
/// Returns the current data set.
protected:
virtual void insertHint();
/// Hints the implementation that it is an insert statement
virtual std::size_t columnsReturned() const = 0;
/// Returns number of columns returned by query.
@ -169,7 +177,7 @@ protected:
/// some ODBC drivers when this function is called after a select statement
/// execution).
virtual const MetaColumn& metaColumn(std::size_t pos) const = 0;
virtual const MetaColumn& metaColumn(std::size_t pos, size_t dataSet) const = 0;
/// Returns column meta data.
const MetaColumn& metaColumn(const std::string& name) const;
@ -252,6 +260,9 @@ protected:
/// - std::vector
/// - std::list
void makeExtractors(std::size_t count, const Position& position);
/// Create extractors for the specified dataset
SessionImpl& session();
/// Returns session associated with this statement.
@ -284,9 +295,6 @@ protected:
/// When connector-specific behavior is desired, it should be overriden
/// by the statement implementation.
std::size_t currentDataSet() const;
/// Returns the current data set.
std::size_t activateNextDataSet();
/// Returns the next data set index, or throws NoDataException if the last
/// data set was reached.
@ -295,10 +303,14 @@ protected:
/// Returns the previous data set index, or throws NoDataException if the last
/// data set was reached.
void firstDataSet();
/// Activate first data set
bool hasMoreDataSets() const;
/// Returns true if there are data sets not activated yet.
private:
void compile();
/// Compiles the statement.
@ -319,26 +331,26 @@ private:
/// Resets extraction so it can be reused again.
template <class C>
SharedPtr<InternalExtraction<C> > createExtract(const MetaColumn& mc)
SharedPtr<InternalExtraction<C> > createExtract(const MetaColumn& mc, size_t position)
{
C* pData = new C;
Column<C>* pCol = new Column<C>(mc, pData);
return new InternalExtraction<C>(*pData, pCol, Poco::UInt32(currentDataSet()));
return new InternalExtraction<C>(*pData, pCol, Poco::UInt32(position));
}
template <class C>
SharedPtr<InternalBulkExtraction<C> > createBulkExtract(const MetaColumn& mc)
SharedPtr<InternalBulkExtraction<C> > createBulkExtract(const MetaColumn& mc, size_t position)
{
C* pData = new C;
Column<C>* pCol = new Column<C>(mc, pData);
return new InternalBulkExtraction<C>(*pData,
pCol,
static_cast<Poco::UInt32>(getExtractionLimit()),
Position(static_cast<Poco::UInt32>(currentDataSet())));
Position(static_cast<Poco::UInt32>(position)));
}
template <class T>
void addInternalExtract(const MetaColumn& mc)
void addInternalExtract(const MetaColumn& mc, size_t position)
/// Creates and adds the internal extraction.
///
/// The decision about internal extraction container is done
@ -370,23 +382,23 @@ private:
if (0 == icompare(DEQUE, storage))
{
if (!isBulkExtraction())
addExtract(createExtract<std::deque<T> >(mc));
addExtract(createExtract<std::deque<T> >(mc, position));
else
addExtract(createBulkExtract<std::deque<T> >(mc));
addExtract(createBulkExtract<std::deque<T> >(mc, position));
}
else if (0 == icompare(VECTOR, storage))
{
if (!isBulkExtraction())
addExtract(createExtract<std::vector<T> >(mc));
addExtract(createExtract<std::vector<T> >(mc, position));
else
addExtract(createBulkExtract<std::vector<T> >(mc));
addExtract(createBulkExtract<std::vector<T> >(mc, position));
}
else if (0 == icompare(LIST, storage))
{
if (!isBulkExtraction())
addExtract(createExtract<std::list<T> >(mc));
addExtract(createExtract<std::list<T> >(mc, position));
else
addExtract(createBulkExtract<std::list<T> >(mc));
addExtract(createBulkExtract<std::list<T> >(mc, position));
}
}
@ -427,7 +439,7 @@ private:
void formatSQL(std::vector<Any>& arguments);
/// Formats the SQL string by filling in placeholders with values from supplied vector.
void assignSubTotal(bool reset);
void assignSubTotal(bool reset, size_t firstDs);
StatementImpl(const StatementImpl& stmt);
StatementImpl& operator = (const StatementImpl& stmt);
@ -444,11 +456,13 @@ private:
AbstractBindingVec _bindings;
AbstractExtractionVecVec _extractors;
std::size_t _curDataSet;
std::size_t _pendingDSNo;
BulkType _bulkBinding;
BulkType _bulkExtraction;
CountVec _subTotalRowCount;
friend class Statement;
friend class RecordSet;
};
@ -627,6 +641,13 @@ inline bool StatementImpl::hasMoreDataSets() const
}
inline void StatementImpl::firstDataSet()
{
_curDataSet = 0;
_pendingDSNo = 0;
}
} } // namespace Poco::Data

View File

@ -254,6 +254,21 @@ template <typename T>
class TypeHandler<Nullable<T> >
/// Specialization of type handler for Nullable.
{
class NullHandler : public AbstractBinder::WhenNullCb
{
public:
explicit NullHandler(const Nullable<T>& obj)
{
_data = &const_cast<Nullable<T>&>(obj);
_func = handle;
}
private:
static void handle(void* ptr)
{
reinterpret_cast<Nullable<T>*>(ptr)->clear();
}
};
public:
static void bind(std::size_t pos, const Nullable<T>& obj, AbstractBinder::Ptr pBinder, AbstractBinder::Direction dir)
@ -261,11 +276,14 @@ public:
poco_assert_dbg (!pBinder.isNull());
if (obj.isNull())
{
pBinder->bind(pos++, Poco::Data::Keywords::null, dir);
pBinder->bind(pos++, NullValue::nullCode<T>(), dir, typeid(T));
}
else
{
pBinder->bind(pos++, obj.value(), dir);
if (AbstractBinder::isOutBound(dir))
pBinder->bind(pos++, obj.value(), dir, NullHandler(obj));
else
pBinder->bind(pos++, obj.value(), dir);
}
}
@ -274,7 +292,7 @@ public:
poco_assert_dbg (!pPreparator.isNull());
if (obj.isNull())
{
pPreparator->prepare(pos++, Poco::Data::Keywords::null);
pPreparator->prepare(pos++, NullValue::nullCode<T>());
}
else
{

View File

@ -292,7 +292,7 @@ void AbstractBinder::bind(std::size_t pos, const std::list<std::string>& val, Di
}
void AbstractBinder::bind(std::size_t pos, const UTF16String& val, Direction dir)
void AbstractBinder::bind(std::size_t pos, const UTF16String& val, Direction dir, const WhenNullCb& nullCb)
{
throw NotImplementedException("UTF16String binder must be implemented.");
}
@ -406,120 +406,124 @@ void AbstractBinder::bind(std::size_t pos, const std::list<Time>& val, Direction
}
void AbstractBinder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir)
void AbstractBinder::bind(std::size_t pos, const std::vector<NullData>& val, Direction dir, const std::type_info& bindElemType)
{
throw NotImplementedException("std::vector binder must be implemented.");
}
void AbstractBinder::bind(std::size_t pos, const std::deque<NullData>& val, Direction dir)
void AbstractBinder::bind(std::size_t pos, const std::deque<NullData>& val, Direction dir, const std::type_info& bindElemType)
{
throw NotImplementedException("std::deque binder must be implemented.");
}
void AbstractBinder::bind(std::size_t pos, const std::list<NullData>& val, Direction dir)
void AbstractBinder::bind(std::size_t pos, const std::list<NullData>& val, Direction dir, const std::type_info& bindElemType)
{
throw NotImplementedException("std::list binder must be implemented.");
}
void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir)
void AbstractBinder::bind(std::size_t pos, const Any& val, Direction dir, const WhenNullCb& nullCb)
{
const std::type_info& type = val.type();
if(type == typeid(Int32))
bind(pos, RefAnyCast<Int32>(val), dir);
bind(pos, RefAnyCast<Int32>(val), dir, nullCb);
else if(type == typeid(std::string))
bind(pos, RefAnyCast<std::string>(val), dir);
bind(pos, RefAnyCast<std::string>(val), dir, nullCb);
else if (type == typeid(Poco::UTF16String))
bind(pos, RefAnyCast<Poco::UTF16String>(val), dir);
bind(pos, RefAnyCast<Poco::UTF16String>(val), dir, nullCb);
else if (type == typeid(bool))
bind(pos, RefAnyCast<bool>(val), dir);
bind(pos, RefAnyCast<bool>(val), dir, nullCb);
else if(type == typeid(char))
bind(pos, RefAnyCast<char>(val), dir);
bind(pos, RefAnyCast<char>(val), dir, nullCb);
else if(type == typeid(Int8))
bind(pos, RefAnyCast<Int8>(val), dir);
bind(pos, RefAnyCast<Int8>(val), dir, nullCb);
else if(type == typeid(UInt8))
bind(pos, RefAnyCast<UInt8>(val), dir);
bind(pos, RefAnyCast<UInt8>(val), dir, nullCb);
else if(type == typeid(Int16))
bind(pos, RefAnyCast<Int16>(val), dir);
bind(pos, RefAnyCast<Int16>(val), dir, nullCb);
else if(type == typeid(UInt16))
bind(pos, RefAnyCast<UInt16>(val), dir);
bind(pos, RefAnyCast<UInt16>(val), dir, nullCb);
else if(type == typeid(UInt32))
bind(pos, RefAnyCast<UInt32>(val), dir);
bind(pos, RefAnyCast<UInt32>(val), dir, nullCb);
else if(type == typeid(Int64))
bind(pos, RefAnyCast<Int64>(val), dir);
bind(pos, RefAnyCast<Int64>(val), dir, nullCb);
else if(type == typeid(UInt64))
bind(pos, RefAnyCast<UInt64>(val), dir);
bind(pos, RefAnyCast<UInt64>(val), dir, nullCb);
else if(type == typeid(float))
bind(pos, RefAnyCast<float>(val), dir);
bind(pos, RefAnyCast<float>(val), dir, nullCb);
else if(type == typeid(double))
bind(pos, RefAnyCast<double>(val), dir);
bind(pos, RefAnyCast<double>(val), dir, nullCb);
else if(type == typeid(DateTime))
bind(pos, RefAnyCast<DateTime>(val), dir);
bind(pos, RefAnyCast<DateTime>(val), dir, nullCb);
else if(type == typeid(Date))
bind(pos, RefAnyCast<Date>(val), dir);
bind(pos, RefAnyCast<Date>(val), dir, nullCb);
else if(type == typeid(Time))
bind(pos, RefAnyCast<Time>(val), dir);
bind(pos, RefAnyCast<Time>(val), dir, nullCb);
else if(type == typeid(BLOB))
bind(pos, RefAnyCast<BLOB>(val), dir);
bind(pos, RefAnyCast<BLOB>(val), dir, nullCb);
else if(type == typeid(void))
bind(pos, Keywords::null, dir);
bind(pos, NULL_GENERIC, dir, type);
#ifndef POCO_LONG_IS_64_BIT
else if(type == typeid(long))
bind(pos, RefAnyCast<long>(val), dir);
bind(pos, RefAnyCast<long>(val), dir, nullCb);
#endif
else
throw UnknownTypeException(std::string(val.type().name()));
}
void AbstractBinder::bind(std::size_t pos, const Poco::Dynamic::Var& val, Direction dir)
void AbstractBinder::bind(std::size_t pos, const Poco::Dynamic::Var& val, Direction dir, const WhenNullCb& nullCb)
{
const std::type_info& type = val.type();
if(type == typeid(Int32))
bind(pos, val.extract<Int32>(), dir);
bind(pos, val.extract<Int32>(), dir, nullCb);
else if(type == typeid(std::string))
bind(pos, val.extract<std::string>(), dir);
bind(pos, val.extract<std::string>(), dir, nullCb);
else if (type == typeid(Poco::UTF16String))
bind(pos, val.extract<Poco::UTF16String>(), dir);
bind(pos, val.extract<Poco::UTF16String>(), dir, nullCb);
else if (type == typeid(bool))
bind(pos, val.extract<bool>(), dir);
bind(pos, val.extract<bool>(), dir, nullCb);
else if(type == typeid(char))
bind(pos, val.extract<char>(), dir);
bind(pos, val.extract<char>(), dir, nullCb);
else if(type == typeid(Int8))
bind(pos, val.extract<Int8>(), dir);
bind(pos, val.extract<Int8>(), dir, nullCb);
else if(type == typeid(UInt8))
bind(pos, val.extract<UInt8>(), dir);
bind(pos, val.extract<UInt8>(), dir, nullCb);
else if(type == typeid(Int16))
bind(pos, val.extract<Int16>(), dir);
bind(pos, val.extract<Int16>(), dir, nullCb);
else if(type == typeid(UInt16))
bind(pos, val.extract<UInt16>(), dir);
bind(pos, val.extract<UInt16>(), dir, nullCb);
else if(type == typeid(UInt32))
bind(pos, val.extract<UInt32>(), dir);
bind(pos, val.extract<UInt32>(), dir, nullCb);
else if(type == typeid(Int64))
bind(pos, val.extract<Int64>(), dir);
bind(pos, val.extract<Int64>(), dir, nullCb);
else if(type == typeid(UInt64))
bind(pos, val.extract<UInt64>(), dir);
bind(pos, val.extract<UInt64>(), dir, nullCb);
else if(type == typeid(float))
bind(pos, val.extract<float>(), dir);
bind(pos, val.extract<float>(), dir, nullCb);
else if(type == typeid(double))
bind(pos, val.extract<double>(), dir);
bind(pos, val.extract<double>(), dir, nullCb);
else if(type == typeid(DateTime))
bind(pos, val.extract<DateTime>(), dir);
bind(pos, val.extract<DateTime>(), dir, nullCb);
else if(type == typeid(Date))
bind(pos, val.extract<Date>(), dir);
bind(pos, val.extract<Date>(), dir, nullCb);
else if(type == typeid(Time))
bind(pos, val.extract<Time>(), dir);
bind(pos, val.extract<Time>(), dir, nullCb);
else if(type == typeid(BLOB))
bind(pos, val.extract<BLOB>(), dir);
bind(pos, val.extract<BLOB>(), dir, nullCb);
else if(type == typeid(void))
bind(pos, Keywords::null, dir);
bind(pos, NULL_GENERIC, dir, type);
else if (type == typeid(NullData))
bind(pos, val.extract<NullData>(), dir, type);
else if (type == typeid(NullType))
bind(pos, static_cast<NullData>(val.extract<NullType>()), dir, type);
#ifndef POCO_LONG_IS_64_BIT
else if(type == typeid(long))
bind(pos, val.extract<long>(), dir);
bind(pos, val.extract<long>(), dir, nullCb);
#endif
else
throw UnknownTypeException(std::string(val.type().name()));

View File

@ -200,8 +200,10 @@ Row& RecordSet::row(std::size_t pos)
std::size_t RecordSet::rowCount() const
{
if (0 == extractions().size() && 0 == columnsExtracted())
return 0;
poco_assert (extractions().size());
std::size_t rc = subTotalRowCount();
std::size_t rc = storageRowCount();
if (!isFiltered()) return rc;
std::size_t counter = 0;
@ -223,7 +225,8 @@ bool RecordSet::isAllowed(std::size_t dataRow) const
bool RecordSet::moveFirst()
{
if (subTotalRowCount() > 0)
const size_t rc = storageRowCount();
if (rc > 0)
{
if (!isFiltered())
{
@ -235,7 +238,7 @@ bool RecordSet::moveFirst()
currentRow = 0;
while (!isAllowed(currentRow))
{
if (currentRow >= subTotalRowCount() - 1) return false;
if (currentRow >= rc - 1) return false;
++currentRow;
}
@ -251,7 +254,7 @@ bool RecordSet::moveNext()
std::size_t currentRow = _currentRow;
do
{
if (currentRow >= subTotalRowCount() - 1) return false;
if (currentRow >= storageRowCount() -1) return false;
++currentRow;
} while (isFiltered() && !isAllowed(currentRow));
@ -276,10 +279,10 @@ bool RecordSet::movePrevious()
bool RecordSet::moveLast()
{
if (subTotalRowCount() > 0)
if (storageRowCount() > 0)
{
std::size_t currentRow = _currentRow;
currentRow = subTotalRowCount() - 1;
currentRow = storageRowCount() - 1;
if (!isFiltered())
{
_currentRow = currentRow;

View File

@ -94,7 +94,20 @@ Poco::Dynamic::Var& Row::get(std::size_t col)
}
std::size_t Row::getPosition(const std::string& name)
const Poco::Dynamic::Var& Row::get(std::size_t col) const
{
try
{
return _values.at(col);
}
catch (std::out_of_range& re)
{
throw RangeException(re.what());
}
}
std::size_t Row::getPosition(const std::string& name) const
{
if (!_pNames)
throw NullPointerException();

View File

@ -69,7 +69,7 @@ void RowIterator::increment() const
if (POSITION_END == _position)
throw RangeException("End of iterator reached.");
if (_position < _pRecordSet->subTotalRowCount() - 1)
if (_position < _pRecordSet->storageRowCount() - 1)
++_position;
else
_position = POSITION_END;
@ -90,7 +90,7 @@ void RowIterator::decrement() const
if (0 == _position)
throw RangeException("Beginning of iterator reached.");
else if (POSITION_END == _position)
_position = _pRecordSet->subTotalRowCount() - 1;
_position = _pRecordSet->storageRowCount() - 1;
else
--_position;
@ -126,15 +126,15 @@ void RowIterator::setPosition(std::size_t pos) const
std::size_t end = pos - _position;
for (; start < end; ++start)
{
if (_pRecordSet->subTotalRowCount() != pos) ++pos;
if (_pRecordSet->storageRowCount() != pos) ++pos;
else throw RangeException("Invalid position argument.");
}
}
}
if (pos < _pRecordSet->subTotalRowCount())
if (pos < _pRecordSet->storageRowCount())
_position = pos;
else if (pos == _pRecordSet->subTotalRowCount())
else if (pos == _pRecordSet->storageRowCount())
_position = POSITION_END;
else
throw RangeException("Invalid position argument.");

View File

@ -52,6 +52,7 @@ StatementImpl::StatementImpl(SessionImpl& rSession):
_storage(STORAGE_UNKNOWN_IMPL),
_ostr(),
_curDataSet(0),
_pendingDSNo(0),
_bulkBinding(BULK_UNDEFINED),
_bulkExtraction(BULK_UNDEFINED)
{
@ -83,6 +84,10 @@ std::size_t StatementImpl::execute(const bool& rReset)
if (_lowerLimit > _extrLimit.value())
throw LimitException("Illegal Statement state. Upper limit must not be smaller than the lower limit.");
size_t pds = _pendingDSNo;
while (pds > currentDataSet()) activateNextDataSet();
const size_t savedDs = currentDataSet();
do
{
compile();
@ -92,25 +97,30 @@ std::size_t StatementImpl::execute(const bool& rReset)
lim += executeWithLimit();
} while (canCompile());
// rewind ds back here!!!!
pds = currentDataSet();
while (savedDs < currentDataSet()) activatePreviousDataSet();
_pendingDSNo = pds;
if (_extrLimit.value() == Limit::LIMIT_UNLIMITED)
_state = ST_DONE;
assignSubTotal(rReset, savedDs);
if (lim < _lowerLimit)
throw LimitException("Did not receive enough data.");
assignSubTotal(rReset);
return lim;
}
void StatementImpl::assignSubTotal(bool doReset)
void StatementImpl::assignSubTotal(bool doReset, size_t firstDs)
{
if (_extractors.size() == _subTotalRowCount.size())
{
CountVec::iterator it = _subTotalRowCount.begin();
CountVec::iterator it = _subTotalRowCount.begin() + firstDs;
CountVec::iterator end = _subTotalRowCount.end();
for (int counter = 0; it != end; ++it, ++counter)
for (size_t counter = firstDs; it != end; ++it, ++counter)
{
if (_extractors[counter].size())
{
@ -137,9 +147,9 @@ std::size_t StatementImpl::executeWithLimit()
count += next();
} while (count < limit && canBind());
if (!canBind() && (!hasNext() || limit == 0))
if (!canBind() && (!hasNext() || limit == 0))
_state = ST_DONE;
else if (hasNext() && limit == count && _extrLimit.isHardLimit())
else if (limit == count && _extrLimit.isHardLimit() && hasNext())
throw LimitException("HardLimit reached (retrieved more data than requested).");
else
_state = ST_PAUSED;
@ -246,10 +256,6 @@ void StatementImpl::setBulkExtraction(const Bulk& b)
void StatementImpl::fixupExtraction()
{
CountVec::iterator sIt = _subTotalRowCount.begin();
CountVec::iterator sEnd = _subTotalRowCount.end();
for (; sIt != sEnd; ++sIt) *sIt = 0;
if (_curDataSet >= _columnsExtracted.size())
{
_columnsExtracted.resize(_curDataSet + 1, 0);
@ -311,46 +317,54 @@ void StatementImpl::setStorage(const std::string& storage)
void StatementImpl::makeExtractors(std::size_t count)
{
// type cast is needed when size_t is 64 bit
makeExtractors(count, static_cast<Position::PositionType>(currentDataSet()));
}
void StatementImpl::makeExtractors(std::size_t count, const Position& position)
{
for (int i = 0; i < count; ++i)
{
const MetaColumn& mc = metaColumn(i);
const MetaColumn& mc = metaColumn(i, position.value());
switch (mc.type())
{
case MetaColumn::FDT_BOOL:
addInternalExtract<bool>(mc); break;
addInternalExtract<bool>(mc, position.value()); break;
case MetaColumn::FDT_INT8:
addInternalExtract<Int8>(mc); break;
addInternalExtract<Int8>(mc, position.value()); break;
case MetaColumn::FDT_UINT8:
addInternalExtract<UInt8>(mc); break;
addInternalExtract<UInt8>(mc, position.value()); break;
case MetaColumn::FDT_INT16:
addInternalExtract<Int16>(mc); break;
addInternalExtract<Int16>(mc, position.value()); break;
case MetaColumn::FDT_UINT16:
addInternalExtract<UInt16>(mc); break;
addInternalExtract<UInt16>(mc, position.value()); break;
case MetaColumn::FDT_INT32:
addInternalExtract<Int32>(mc); break;
addInternalExtract<Int32>(mc, position.value()); break;
case MetaColumn::FDT_UINT32:
addInternalExtract<UInt32>(mc); break;
addInternalExtract<UInt32>(mc, position.value()); break;
case MetaColumn::FDT_INT64:
addInternalExtract<Int64>(mc); break;
addInternalExtract<Int64>(mc, position.value()); break;
case MetaColumn::FDT_UINT64:
addInternalExtract<UInt64>(mc); break;
addInternalExtract<UInt64>(mc, position.value()); break;
case MetaColumn::FDT_FLOAT:
addInternalExtract<float>(mc); break;
addInternalExtract<float>(mc, position.value()); break;
case MetaColumn::FDT_DOUBLE:
addInternalExtract<double>(mc); break;
addInternalExtract<double>(mc, position.value()); break;
case MetaColumn::FDT_STRING:
addInternalExtract<std::string>(mc); break;
addInternalExtract<std::string>(mc, position.value()); break;
case MetaColumn::FDT_WSTRING:
addInternalExtract<Poco::UTF16String>(mc); break;
case MetaColumn::FDT_BLOB:
addInternalExtract<BLOB>(mc); break;
addInternalExtract<Poco::UTF16String>(mc, position.value()); break;
case MetaColumn::FDT_BLOB:
addInternalExtract<BLOB>(mc, position.value()); break;
case MetaColumn::FDT_CLOB:
addInternalExtract<CLOB>(mc, position.value()); break;
case MetaColumn::FDT_DATE:
addInternalExtract<Date>(mc); break;
addInternalExtract<Date>(mc, position.value()); break;
case MetaColumn::FDT_TIME:
addInternalExtract<Time>(mc); break;
addInternalExtract<Time>(mc, position.value()); break;
case MetaColumn::FDT_TIMESTAMP:
addInternalExtract<DateTime>(mc); break;
addInternalExtract<DateTime>(mc, position.value()); break;
default:
throw Poco::InvalidArgumentException("Data type not supported.");
}
@ -363,7 +377,7 @@ const MetaColumn& StatementImpl::metaColumn(const std::string& name) const
std::size_t cols = columnsReturned();
for (std::size_t i = 0; i < cols; ++i)
{
const MetaColumn& column = metaColumn(i);
const MetaColumn& column = metaColumn(i, currentDataSet());
if (0 == icompare(column.name(), name)) return column;
}
@ -374,7 +388,10 @@ const MetaColumn& StatementImpl::metaColumn(const std::string& name) const
std::size_t StatementImpl::activateNextDataSet()
{
if (_curDataSet + 1 < dataSetCount())
return ++_curDataSet;
{
_pendingDSNo = ++_curDataSet;
return _curDataSet;
}
else
throw NoDataException("End of data sets reached.");
}
@ -383,7 +400,10 @@ std::size_t StatementImpl::activateNextDataSet()
std::size_t StatementImpl::activatePreviousDataSet()
{
if (_curDataSet > 0)
return --_curDataSet;
{
_pendingDSNo = --_curDataSet;
return _curDataSet;
}
else
throw NoDataException("Beginning of data sets reached.");
}
@ -475,4 +495,8 @@ void StatementImpl::formatSQL(std::vector<Any>& arguments)
}
void StatementImpl::insertHint()
{
}
} } // namespace Poco::Data

View File

@ -129,7 +129,7 @@
<AdditionalIncludeDirectories>..\include;..\..\CppUnit\include;..\..\CppUnit\WinTestRunner\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -140,6 +140,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitd.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -171,6 +172,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnit.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -189,7 +191,7 @@
<AdditionalIncludeDirectories>..\include;..\..\CppUnit\include;..\..\CppUnit\WinTestRunner\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -200,6 +202,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmtd.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -231,6 +234,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmt.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -249,7 +253,7 @@
<AdditionalIncludeDirectories>..\include;..\..\CppUnit\include;..\..\CppUnit\WinTestRunner\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -260,6 +264,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmdd.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -291,6 +296,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmd.lib;iphlpapi.lib;winmm.lib;%(AdditionalDependencies)</AdditionalDependencies>

View File

@ -30,119 +30,119 @@ Binder::~Binder()
}
void Binder::bind(std::size_t pos, const Poco::Int8 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int8 &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Poco::UInt8 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UInt8 &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Poco::Int16 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int16 &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Poco::UInt16 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UInt16 &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Poco::Int32 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int32 &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Poco::UInt32 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UInt32 &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Poco::Int64 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::Int64 &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Poco::UInt64 &val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UInt64 &val, Direction dir, const WhenNullCb& nullCb)
{
}
#ifndef POCO_LONG_IS_64_BIT
void Binder::bind(std::size_t pos, const long& val, Direction dir)
void Binder::bind(std::size_t pos, const long& val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir)
void Binder::bind(std::size_t pos, const unsigned long& val, Direction dir, const WhenNullCb& nullCb)
{
}
#endif
void Binder::bind(std::size_t pos, const bool &val, Direction dir)
void Binder::bind(std::size_t pos, const bool &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const float &val, Direction dir)
void Binder::bind(std::size_t pos, const float &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const double &val, Direction dir)
void Binder::bind(std::size_t pos, const double &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const char &val, Direction dir)
void Binder::bind(std::size_t pos, const char &val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const char* const &pVal, Direction dir)
void Binder::bind(std::size_t pos, const char* const &pVal, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const std::string& val, Direction dir)
void Binder::bind(std::size_t pos, const std::string& val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Poco::UTF16String& val, Direction dir)
void Binder::bind(std::size_t pos, const Poco::UTF16String& val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const BLOB& val, Direction dir)
void Binder::bind(std::size_t pos, const BLOB& val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const CLOB& val, Direction dir)
void Binder::bind(std::size_t pos, const CLOB& val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Date& val, Direction dir)
void Binder::bind(std::size_t pos, const Date& val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const Time& val, Direction dir)
void Binder::bind(std::size_t pos, const Time& val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir)
void Binder::bind(std::size_t pos, const DateTime& val, Direction dir, const WhenNullCb& nullCb)
{
}
void Binder::bind(std::size_t pos, const NullData& val, Direction dir)
void Binder::bind(std::size_t pos, const NullData& val, Direction dir, const std::type_info& bindType)
{
}

View File

@ -34,75 +34,75 @@ public:
~Binder();
/// Destroys the Binder.
void bind(std::size_t pos, const Poco::Int8 &val, Direction dir);
void bind(std::size_t pos, const Poco::Int8 &val, Direction dir, const WhenNullCb& cb);
/// Binds an Int8.
void bind(std::size_t pos, const Poco::UInt8 &val, Direction dir);
void bind(std::size_t pos, const Poco::UInt8 &val, Direction dir, const WhenNullCb& cb);
/// Binds an UInt8.
void bind(std::size_t pos, const Poco::Int16 &val, Direction dir);
void bind(std::size_t pos, const Poco::Int16 &val, Direction dir, const WhenNullCb& cb);
/// Binds an Int16.
void bind(std::size_t pos, const Poco::UInt16 &val, Direction dir);
void bind(std::size_t pos, const Poco::UInt16 &val, Direction dir, const WhenNullCb& cb);
/// Binds an UInt16.
void bind(std::size_t pos, const Poco::Int32 &val, Direction dir);
void bind(std::size_t pos, const Poco::Int32 &val, Direction dir, const WhenNullCb& cb);
/// Binds an Int32.
void bind(std::size_t pos, const Poco::UInt32 &val, Direction dir);
void bind(std::size_t pos, const Poco::UInt32 &val, Direction dir, const WhenNullCb& cb);
/// Binds an UInt32.
void bind(std::size_t pos, const Poco::Int64 &val, Direction dir);
void bind(std::size_t pos, const Poco::Int64 &val, Direction dir, const WhenNullCb& cb);
/// Binds an Int64.
void bind(std::size_t pos, const Poco::UInt64 &val, Direction dir);
void bind(std::size_t pos, const Poco::UInt64 &val, Direction dir, const WhenNullCb& cb);
/// Binds an UInt64.
#ifndef POCO_LONG_IS_64_BIT
void bind(std::size_t pos, const long& val, Direction dir);
void bind(std::size_t pos, const long& val, Direction dir, const WhenNullCb& cb);
/// Binds a long.
void bind(std::size_t pos, const unsigned long& val, Direction dir);
void bind(std::size_t pos, const unsigned long& val, Direction dir, const WhenNullCb& cb);
/// Binds an unsigned long.
#endif
void bind(std::size_t pos, const bool &val, Direction dir);
void bind(std::size_t pos, const bool &val, Direction dir, const WhenNullCb& cb);
/// Binds a boolean.
void bind(std::size_t pos, const float &val, Direction dir);
void bind(std::size_t pos, const float &val, Direction dir, const WhenNullCb& cb);
/// Binds a float.
void bind(std::size_t pos, const double &val, Direction dir);
void bind(std::size_t pos, const double &val, Direction dir, const WhenNullCb& cb);
/// Binds a double.
void bind(std::size_t pos, const char &val, Direction dir);
void bind(std::size_t pos, const char &val, Direction dir, const WhenNullCb& cb);
/// Binds a single character.
void bind(std::size_t pos, const char* const &pVal, Direction dir);
void bind(std::size_t pos, const char* const &pVal, Direction dir, const WhenNullCb& cb);
/// Binds a const char ptr.
void bind(std::size_t pos, const std::string& val, Direction dir);
void bind(std::size_t pos, const std::string& val, Direction dir, const WhenNullCb& cb);
/// Binds a string.
void bind(std::size_t pos, const Poco::UTF16String& val, Direction dir);
void bind(std::size_t pos, const Poco::UTF16String& val, Direction dir, const WhenNullCb& cb);
/// Binds a UTF16String.
void bind(std::size_t pos, const BLOB& val, Direction dir);
void bind(std::size_t pos, const BLOB& val, Direction dir, const WhenNullCb& cb);
/// Binds a BLOB.
void bind(std::size_t pos, const CLOB& val, Direction dir);
void bind(std::size_t pos, const CLOB& val, Direction dir, const WhenNullCb& cb);
/// Binds a CLOB.
void bind(std::size_t pos, const Date& val, Direction dir);
void bind(std::size_t pos, const Date& val, Direction dir, const WhenNullCb& cb);
/// Binds a Date.
void bind(std::size_t pos, const Time& val, Direction dir);
void bind(std::size_t pos, const Time& val, Direction dir, const WhenNullCb& cb);
/// Binds a Time.
void bind(std::size_t pos, const DateTime& val, Direction dir);
void bind(std::size_t pos, const DateTime& val, Direction dir, const WhenNullCb& cb);
/// Binds a DateTime.
void bind(std::size_t pos, const NullData& val, Direction dir);
void bind(std::size_t pos, const NullData& val, Direction dir, const std::type_info& bindType);
/// Binds a DateTime.
void reset();

View File

@ -904,6 +904,11 @@ void DataTest::testRow()
assert (row[3] == 3);
assert (row[4] == 4);
const Row& cr = row;
assert(cr["field0"] == 0);
assert(cr[0] == 0);
assert(cr.get(0) == 0);
try
{
int i; i = row[5].convert<int>(); // to silence gcc

View File

@ -72,7 +72,7 @@ std::size_t TestStatementImpl::columnsReturned() const
}
const MetaColumn& TestStatementImpl::metaColumn(std::size_t pos) const
const MetaColumn& TestStatementImpl::metaColumn(std::size_t pos, std::size_t /*rsPos*/) const
{
static MetaColumn c(pos, "", MetaColumn::FDT_BOOL, 0);
return c;

View File

@ -50,7 +50,7 @@ protected:
/// Returns the number of affected rows.
/// Used to find out the number of rows affected by insert or update.
const MetaColumn& metaColumn(std::size_t pos) const;
const MetaColumn& metaColumn(std::size_t pos, std::size_t rsPos) const;
/// Returns column meta data.
bool hasNext();

View File

@ -125,7 +125,7 @@
<AdditionalIncludeDirectories>.\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;Foundation_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -136,6 +136,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>ws2_32.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -215,6 +216,7 @@
<AdditionalIncludeDirectories>.\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>false</MinimalRebuild>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
@ -224,6 +226,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib\PocoFoundationmt.lib</OutputFile>
@ -235,7 +238,7 @@
<AdditionalIncludeDirectories>.\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -247,6 +250,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib\PocoFoundationmdd.lib</OutputFile>

View File

@ -125,7 +125,7 @@
<AdditionalIncludeDirectories>.\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;Foundation_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -136,6 +136,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -168,6 +169,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -200,6 +202,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib64\PocoFoundationmtd.lib</OutputFile>
@ -217,6 +220,7 @@
<StringPooling>true</StringPooling>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<BufferSecurityCheck>false</BufferSecurityCheck>
<MinimalRebuild>false</MinimalRebuild>
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<RuntimeTypeInfo>true</RuntimeTypeInfo>
@ -224,6 +228,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib64\PocoFoundationmt.lib</OutputFile>
@ -235,7 +240,7 @@
<AdditionalIncludeDirectories>.\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -247,6 +252,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib64\PocoFoundationmdd.lib</OutputFile>
@ -271,6 +277,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Lib>
<OutputFile>..\lib64\PocoFoundationmd.lib</OutputFile>

View File

@ -129,7 +129,7 @@
<AdditionalIncludeDirectories>..\include;..\..\CppUnit\include;..\..\CppUnit\WinTestRunner\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -140,6 +140,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitd.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -249,7 +250,7 @@
<AdditionalIncludeDirectories>..\include;..\..\CppUnit\include;..\..\CppUnit\WinTestRunner\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -260,6 +261,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmdd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -291,6 +293,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat />
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -589,4 +592,4 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>
</Project>

View File

@ -129,7 +129,7 @@
<AdditionalIncludeDirectories>..\include;..\..\CppUnit\include;..\..\CppUnit\WinTestRunner\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -140,6 +140,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitd.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -171,6 +172,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnit.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -231,6 +233,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmt.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -249,7 +252,7 @@
<AdditionalIncludeDirectories>..\include;..\..\CppUnit\include;..\..\CppUnit\WinTestRunner\include;..\..\Foundation\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;WINVER=0x0600;POCO_STATIC;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MinimalRebuild>true</MinimalRebuild>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
@ -260,6 +263,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmdd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
@ -291,6 +295,7 @@
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat/>
<CompileAs>Default</CompileAs>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
<AdditionalDependencies>CppUnitmd.lib;iphlpapi.lib;winmm.lib;iphlpapi.lib;%(AdditionalDependencies)</AdditionalDependencies>

View File

@ -195,8 +195,8 @@ function Process-Input
}
# NB: this won't work in PowerShell ISE
Write-Host "Press Ctrl-C to exit or any other key to continue ..."
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp")
# Write-Host "Press Ctrl-C to exit or any other key to continue ..."
# $x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyUp")
}
}