http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/odbc-test/src/utility_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/odbc-test/src/utility_test.cpp b/modules/platforms/cpp/odbc/odbc-test/src/utility_test.cpp deleted file mode 100644 index 6c4d104..0000000 --- a/modules/platforms/cpp/odbc/odbc-test/src/utility_test.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef _MSC_VER -# define BOOST_TEST_DYN_LINK -#endif - -#include <boost/test/unit_test.hpp> - -#include <ignite/impl/binary/binary_writer_impl.h> - -#include <ignite/odbc/utility.h> - -using namespace ignite::utility; - -BOOST_AUTO_TEST_SUITE(UtilityTestSuite) - -BOOST_AUTO_TEST_CASE(TestUtilityRemoveSurroundingSpaces) -{ - std::string inStr(" \r \n \t some meaningfull data \n\n \t \r "); - std::string expectedOutStr("some meaningfull data"); - - std::string realOutStr(RemoveSurroundingSpaces(inStr.begin(), inStr.end())); - - BOOST_REQUIRE(expectedOutStr == realOutStr); -} - -BOOST_AUTO_TEST_CASE(TestUtilityCopyStringToBuffer) -{ - char buffer[1024]; - - std::string str("Some data. And some more data here."); - - CopyStringToBuffer(str, buffer, sizeof(buffer)); - - BOOST_REQUIRE(!strcmp(buffer, str.c_str())); - - CopyStringToBuffer(str, buffer, 11); - - BOOST_REQUIRE(!strcmp(buffer, str.substr(0, 10).c_str())); -} - -BOOST_AUTO_TEST_CASE(TestUtilityReadString) -{ - using namespace ignite::impl::binary; - using namespace ignite::impl::interop; - - std::string inputStr("Hello World!"); - std::string outputStr; - - ignite::impl::interop::InteropUnpooledMemory mem(1024); - InteropOutputStream outStream(&mem); - BinaryWriterImpl writer(&outStream, 0); - - writer.WriteString(inputStr.data(), static_cast<int32_t>(inputStr.size())); - - outStream.Synchronize(); - - InteropInputStream inStream(&mem); - BinaryReaderImpl reader(&inStream); - - ReadString(reader, outputStr); - - BOOST_REQUIRE(inputStr == outputStr); -} - -BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/os/linux/src/system/socket_client.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/os/linux/src/system/socket_client.cpp b/modules/platforms/cpp/odbc/os/linux/src/system/socket_client.cpp new file mode 100644 index 0000000..a355625 --- /dev/null +++ b/modules/platforms/cpp/odbc/os/linux/src/system/socket_client.cpp @@ -0,0 +1,120 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <sys/socket.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netdb.h> +#include <unistd.h> + +#include <cstring> + +#include <sstream> + +#include "ignite/odbc/system/socket_client.h" +#include "ignite/odbc/utility.h" + +#define SOCKET_ERROR (-1) + +namespace ignite +{ + namespace odbc + { + namespace tcp + { + + SocketClient::SocketClient() : socketHandle(SOCKET_ERROR) + { + // No-op. + } + + SocketClient::~SocketClient() + { + Close(); + } + + bool SocketClient::Connect(const char* hostname, uint16_t port) + { + LOG_MSG("Host: %s, port: %d\n", hostname, port); + + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + std::stringstream converter; + converter << port; + + // Resolve the server address and port + addrinfo *result = NULL; + int res = getaddrinfo(hostname, converter.str().c_str(), &hints, &result); + + if (res != 0) + return false; + + // Attempt to connect to an address until one succeeds + for (addrinfo *it = result; it != NULL; it = it->ai_next) + { + LOG_MSG("Addr: %u.%u.%u.%u\n", it->ai_addr->sa_data[2], it->ai_addr->sa_data[3], + it->ai_addr->sa_data[4], it->ai_addr->sa_data[5]); + + // Create a SOCKET for connecting to server + socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol); + + if (socketHandle == SOCKET_ERROR) + return false; + + // Connect to server. + res = connect(socketHandle, it->ai_addr, (int)it->ai_addrlen); + if (res == SOCKET_ERROR) + { + Close(); + + continue; + } + break; + } + + freeaddrinfo(result); + + return socketHandle != SOCKET_ERROR; + } + + void SocketClient::Close() + { + if (socketHandle != SOCKET_ERROR) + { + close(socketHandle); + + socketHandle = SOCKET_ERROR; + } + } + + int SocketClient::Send(const int8_t* data, size_t size) + { + return send(socketHandle, reinterpret_cast<const char*>(data), static_cast<int>(size), 0); + } + + int SocketClient::Receive(int8_t* buffer, size_t size) + { + return recv(socketHandle, reinterpret_cast<char*>(buffer), static_cast<int>(size), 0); + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp b/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp new file mode 100644 index 0000000..bc4cdc0 --- /dev/null +++ b/modules/platforms/cpp/odbc/os/win/src/system/socket_client.cpp @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define WIN32_LEAN_AND_MEAN +#define _WINSOCKAPI_ + +#include <windows.h> +#include <winsock2.h> +#include <ws2tcpip.h> + +#include <cstring> + +#include <sstream> + +#include "ignite/odbc/system/socket_client.h" +#include "ignite/odbc/utility.h" + +namespace ignite +{ + namespace odbc + { + namespace tcp + { + + SocketClient::SocketClient() : socketHandle(INVALID_SOCKET) + { + // No-op. + } + + SocketClient::~SocketClient() + { + Close(); + } + + bool SocketClient::Connect(const char* hostname, uint16_t port) + { + static bool networkInited = false; + + // Initing networking if is not inited. + if (!networkInited) + { + WSADATA wsaData; + + networkInited = (WSAStartup(MAKEWORD(2, 2), &wsaData) == 0); + + if (!networkInited) + return false; + } + + addrinfo *result = NULL; + addrinfo hints; + + LOG_MSG("Host: %s, port: %d\n", hostname, port); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + std::stringstream converter; + converter << port; + + // Resolve the server address and port + int res = getaddrinfo(hostname, converter.str().c_str(), &hints, &result); + + if (res != 0) + return false; + + // Attempt to connect to an address until one succeeds + for (addrinfo *it = result; it != NULL; it = it->ai_next) + { + LOG_MSG("Addr: %u.%u.%u.%u\n", it->ai_addr->sa_data[2], it->ai_addr->sa_data[3], + it->ai_addr->sa_data[4], it->ai_addr->sa_data[5]); + + // Create a SOCKET for connecting to server + socketHandle = socket(it->ai_family, it->ai_socktype, it->ai_protocol); + + if (socketHandle == INVALID_SOCKET) + return false; + + // Connect to server. + res = connect(socketHandle, it->ai_addr, static_cast<int>(it->ai_addrlen)); + if (res == SOCKET_ERROR) + { + Close(); + + continue; + } + break; + } + + freeaddrinfo(result); + + return socketHandle != INVALID_SOCKET; + } + + void SocketClient::Close() + { + if (socketHandle != INVALID_SOCKET) + { + closesocket(socketHandle); + + socketHandle = INVALID_SOCKET; + } + } + + int SocketClient::Send(const int8_t* data, size_t size) + { + return send(socketHandle, reinterpret_cast<const char*>(data), static_cast<int>(size), 0); + } + + int SocketClient::Receive(int8_t* buffer, size_t size) + { + return recv(socketHandle, reinterpret_cast<char*>(buffer), static_cast<int>(size), 0); + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/project/README.TXT ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/project/README.TXT b/modules/platforms/cpp/odbc/project/README.TXT new file mode 100644 index 0000000..97f4c64 --- /dev/null +++ b/modules/platforms/cpp/odbc/project/README.TXT @@ -0,0 +1 @@ +Contains IDE projects artifacts. http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/project/vs/README.TXT ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/project/vs/README.TXT b/modules/platforms/cpp/odbc/project/vs/README.TXT new file mode 100644 index 0000000..f4fb456 --- /dev/null +++ b/modules/platforms/cpp/odbc/project/vs/README.TXT @@ -0,0 +1 @@ +Contains Visual Studio project artifacts. \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/project/vs/module.def ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/project/vs/module.def b/modules/platforms/cpp/odbc/project/vs/module.def new file mode 100644 index 0000000..9da4b35 --- /dev/null +++ b/modules/platforms/cpp/odbc/project/vs/module.def @@ -0,0 +1,69 @@ + +LIBRARY odbc +EXPORTS + ConfigDSN + SQLAllocConnect + SQLAllocEnv + SQLAllocStmt + SQLAllocHandle + SQLFreeConnect + SQLFreeEnv + SQLFreeStmt + SQLBindCol + SQLCancel + SQLConnect + SQLDescribeCol + SQLDisconnect + SQLError + SQLExecDirect + SQLExecute + SQLExtendedFetch + SQLFetch + SQLGetCursorName + SQLNumResultCols + SQLPrepare + SQLRowCount + SQLSetCursorName + SQLColumns + SQLDriverConnect + SQLGetData + SQLGetInfo + SQLGetTypeInfo + SQLParamData + SQLPutData + SQLStatistics + SQLTables + SQLBrowseConnect + SQLColumnPrivileges + SQLDescribeParam + SQLForeignKeys + SQLMoreResults + SQLNativeSql + SQLNumParams + SQLPrimaryKeys + SQLProcedureColumns + SQLProcedures + SQLSetPos + SQLTablePrivileges + SQLBindParameter + SQLCloseCursor + SQLColAttribute + SQLCopyDesc + SQLEndTran + SQLFetchScroll + SQLFreeHandle + SQLGetConnectAttr + SQLGetDescField + SQLGetDescRec + SQLGetDiagField + SQLGetDiagRec + SQLGetEnvAttr + SQLGetStmtAttr + SQLSetConnectAttr + SQLSetDescField + SQLSetDescRec + SQLSetEnvAttr + SQLSetStmtAttr + SQLBulkOperations + SQLSpecialColumns + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/project/vs/odbc.sln ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.sln b/modules/platforms/cpp/odbc/project/vs/odbc.sln deleted file mode 100644 index 89144a3..0000000 --- a/modules/platforms/cpp/odbc/project/vs/odbc.sln +++ /dev/null @@ -1,56 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 11.00 -# Visual Studio 2010 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc-driver", "..\..\odbc-driver\project\vs\odbc-driver.vcxproj", "{12F77E12-38FE-42D3-B1DA-7E5979362961}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "odbc-test", "..\..\odbc-test\project\vs\odbc-test.vcxproj", "{309BEA40-495D-463F-98D5-4657F03F6D8F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "common", "..\..\..\common\project\vs\common.vcxproj", "{4F7E4917-4612-4B96-9838-025711ADE391}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "binary", "..\..\..\binary\project\vs\binary.vcxproj", "{4F15669B-92EB-49F0-B774-8F19BAE0B960}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Debug|Win32 = Debug|Win32 - Release|x64 = Release|x64 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|x64.ActiveCfg = Debug|x64 - {12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|x64.Build.0 = Debug|x64 - {12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|Win32.ActiveCfg = Debug|Win32 - {12F77E12-38FE-42D3-B1DA-7E5979362961}.Debug|Win32.Build.0 = Debug|Win32 - {12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|x64.ActiveCfg = Release|x64 - {12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|x64.Build.0 = Release|x64 - {12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|Win32.ActiveCfg = Release|Win32 - {12F77E12-38FE-42D3-B1DA-7E5979362961}.Release|Win32.Build.0 = Release|Win32 - {309BEA40-495D-463F-98D5-4657F03F6D8F}.Debug|x64.ActiveCfg = Debug|x64 - {309BEA40-495D-463F-98D5-4657F03F6D8F}.Debug|x64.Build.0 = Debug|x64 - {309BEA40-495D-463F-98D5-4657F03F6D8F}.Debug|Win32.ActiveCfg = Debug|Win32 - {309BEA40-495D-463F-98D5-4657F03F6D8F}.Debug|Win32.Build.0 = Debug|Win32 - {309BEA40-495D-463F-98D5-4657F03F6D8F}.Release|x64.ActiveCfg = Release|x64 - {309BEA40-495D-463F-98D5-4657F03F6D8F}.Release|x64.Build.0 = Release|x64 - {309BEA40-495D-463F-98D5-4657F03F6D8F}.Release|Win32.ActiveCfg = Release|Win32 - {309BEA40-495D-463F-98D5-4657F03F6D8F}.Release|Win32.Build.0 = Release|Win32 - {4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.ActiveCfg = Debug|x64 - {4F7E4917-4612-4B96-9838-025711ADE391}.Debug|x64.Build.0 = Debug|x64 - {4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.ActiveCfg = Debug|Win32 - {4F7E4917-4612-4B96-9838-025711ADE391}.Debug|Win32.Build.0 = Debug|Win32 - {4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.ActiveCfg = Release|x64 - {4F7E4917-4612-4B96-9838-025711ADE391}.Release|x64.Build.0 = Release|x64 - {4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.ActiveCfg = Release|Win32 - {4F7E4917-4612-4B96-9838-025711ADE391}.Release|Win32.Build.0 = Release|Win32 - {4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|x64.ActiveCfg = Debug|x64 - {4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|x64.Build.0 = Debug|x64 - {4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|Win32.ActiveCfg = Debug|Win32 - {4F15669B-92EB-49F0-B774-8F19BAE0B960}.Debug|Win32.Build.0 = Debug|Win32 - {4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|x64.ActiveCfg = Release|x64 - {4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|x64.Build.0 = Release|x64 - {4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|Win32.ActiveCfg = Release|Win32 - {4F15669B-92EB-49F0-B774-8F19BAE0B960}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj new file mode 100644 index 0000000..f22b0b1 --- /dev/null +++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj @@ -0,0 +1,233 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{12F77E12-38FE-42D3-B1DA-7E5979362961}</ProjectGuid> + <RootNamespace>odbc</RootNamespace> + <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> + <ConfigurationType>DynamicLibrary</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <PlatformToolset>v100</PlatformToolset> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>MultiByte</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="Shared"> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir> + <IntDir>$(Platform)\$(Configuration)\</IntDir> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>false</SDLCheck> + <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\src;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;ODBC_DEBUG;ODBC_LOG_PATH="D:\\odbc.log";_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ModuleDefinitionFile>module.def</ModuleDefinitionFile> + <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <SDLCheck>false</SDLCheck> + <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\src;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;ODBC_DEBUG;ODBC_LOG_PATH="D:\\odbc.log";_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <ModuleDefinitionFile>module.def</ModuleDefinitionFile> + <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>false</SDLCheck> + <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\src;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;ODBC_DEBUG;ODBC_LOG_PATH="D:\\odbc.log";%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <ModuleDefinitionFile>module.def</ModuleDefinitionFile> + <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>false</SDLCheck> + <AdditionalIncludeDirectories>$(ProjectDir)\..\..\..\common\include;$(ProjectDir)\..\..\..\common\os\win\include;$(ProjectDir)\..\..\src;$(ProjectDir)\..\..\os\win;$(ProjectDir)\..\..\..\binary\include;$(ProjectDir)\..\..\..\binary\os\win\include;$(ProjectDir)\..\..\include</AdditionalIncludeDirectories> + <PreprocessorDefinitions>_CRT_SECURE_NO_WARNINGS;IGNITE_IMPL;IGNITE_FRIEND;ODBC_DEBUG;ODBC_LOG_PATH="D:\\odbc.log";%(PreprocessorDefinitions)</PreprocessorDefinitions> + </ClCompile> + <Link> + <GenerateDebugInformation>true</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + <ModuleDefinitionFile>module.def</ModuleDefinitionFile> + <AdditionalDependencies>Ws2_32.lib;Mswsock.lib;Advapi32.lib;%(AdditionalDependencies)</AdditionalDependencies> + </Link> + </ItemDefinitionGroup> + <ItemGroup> + <ClCompile Include="..\..\os\win\src\system\socket_client.cpp" /> + <ClCompile Include="..\..\src\app\application_data_buffer.cpp" /> + <ClCompile Include="..\..\src\app\parameter.cpp" /> + <ClCompile Include="..\..\src\column.cpp" /> + <ClCompile Include="..\..\src\common_types.cpp" /> + <ClCompile Include="..\..\src\config\configuration.cpp" /> + <ClCompile Include="..\..\src\config\connection_info.cpp" /> + <ClCompile Include="..\..\src\connection.cpp" /> + <ClCompile Include="..\..\src\cursor.cpp" /> + <ClCompile Include="..\..\src\decimal.cpp" /> + <ClCompile Include="..\..\src\diagnostic\diagnosable_adapter.cpp" /> + <ClCompile Include="..\..\src\diagnostic\diagnostic_record.cpp" /> + <ClCompile Include="..\..\src\diagnostic\diagnostic_record_storage.cpp" /> + <ClCompile Include="..\..\src\environment.cpp" /> + <ClCompile Include="..\..\src\meta\column_meta.cpp" /> + <ClCompile Include="..\..\src\meta\table_meta.cpp" /> + <ClCompile Include="..\..\src\odbc.cpp" /> + <ClCompile Include="..\..\src\query\data_query.cpp" /> + <ClCompile Include="..\..\src\query\column_metadata_query.cpp" /> + <ClCompile Include="..\..\src\query\foreign_keys_query.cpp" /> + <ClCompile Include="..\..\src\query\primary_keys_query.cpp" /> + <ClCompile Include="..\..\src\query\special_columns_query.cpp" /> + <ClCompile Include="..\..\src\query\table_metadata_query.cpp" /> + <ClCompile Include="..\..\src\query\type_info_query.cpp" /> + <ClCompile Include="..\..\src\result_page.cpp" /> + <ClCompile Include="..\..\src\row.cpp" /> + <ClCompile Include="..\..\src\statement.cpp" /> + <ClCompile Include="..\..\src\type_traits.cpp" /> + <ClCompile Include="..\..\src\utility.cpp" /> + </ItemGroup> + <ItemGroup> + <None Include="module.def" /> + </ItemGroup> + <ItemGroup> + <ClInclude Include="..\..\include\ignite\odbc\app\application_data_buffer.h" /> + <ClInclude Include="..\..\include\ignite\odbc\app\parameter.h" /> + <ClInclude Include="..\..\include\ignite\odbc\column.h" /> + <ClInclude Include="..\..\include\ignite\odbc\common_types.h" /> + <ClInclude Include="..\..\include\ignite\odbc\config\configuration.h" /> + <ClInclude Include="..\..\include\ignite\odbc\config\connection_info.h" /> + <ClInclude Include="..\..\include\ignite\odbc\connection.h" /> + <ClInclude Include="..\..\include\ignite\odbc\cursor.h" /> + <ClInclude Include="..\..\include\ignite\odbc\decimal.h" /> + <ClInclude Include="..\..\include\ignite\odbc\diagnostic\diagnosable.h" /> + <ClInclude Include="..\..\include\ignite\odbc\diagnostic\diagnosable_adapter.h" /> + <ClInclude Include="..\..\include\ignite\odbc\diagnostic\diagnostic_record.h" /> + <ClInclude Include="..\..\include\ignite\odbc\diagnostic\diagnostic_record_storage.h" /> + <ClInclude Include="..\..\include\ignite\odbc\environment.h" /> + <ClInclude Include="..\..\include\ignite\odbc\message.h" /> + <ClInclude Include="..\..\include\ignite\odbc\meta\column_meta.h" /> + <ClInclude Include="..\..\include\ignite\odbc\meta\primary_key_meta.h" /> + <ClInclude Include="..\..\include\ignite\odbc\meta\table_meta.h" /> + <ClInclude Include="..\..\include\ignite\odbc\parser.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\data_query.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\column_metadata_query.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\foreign_keys_query.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\primary_keys_query.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\query.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\special_columns_query.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\table_metadata_query.h" /> + <ClInclude Include="..\..\include\ignite\odbc\query\type_info_query.h" /> + <ClInclude Include="..\..\include\ignite\odbc\result_page.h" /> + <ClInclude Include="..\..\include\ignite\odbc\row.h" /> + <ClInclude Include="..\..\include\ignite\odbc\statement.h" /> + <ClInclude Include="..\..\include\ignite\odbc\system\odbc_constants.h" /> + <ClInclude Include="..\..\include\ignite\odbc\system\socket_client.h" /> + <ClInclude Include="..\..\include\ignite\odbc\type_traits.h" /> + <ClInclude Include="..\..\include\ignite\odbc\utility.h" /> + <ClInclude Include="result_page.h" /> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="..\..\..\binary\project\vs\binary.vcxproj"> + <Project>{4f15669b-92eb-49f0-b774-8f19bae0b960}</Project> + </ProjectReference> + <ProjectReference Include="..\..\..\common\project\vs\common.vcxproj"> + <Project>{4f7e4917-4612-4b96-9838-025711ade391}</Project> + </ProjectReference> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + </ImportGroup> +</Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters new file mode 100644 index 0000000..d47684a --- /dev/null +++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters @@ -0,0 +1,229 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <Filter Include="Code"> + <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier> + <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx;h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions> + </Filter> + <Filter Include="Misc"> + <UniqueIdentifier>{3f714d15-6347-46a7-bc59-d87c1aea900c}</UniqueIdentifier> + </Filter> + <Filter Include="Code\query"> + <UniqueIdentifier>{b09a6b2e-c30c-4727-8e85-4b315e757706}</UniqueIdentifier> + </Filter> + <Filter Include="Code\meta"> + <UniqueIdentifier>{71d6243f-e8c9-4f21-a5a3-3dc89641af28}</UniqueIdentifier> + </Filter> + <Filter Include="Code\config"> + <UniqueIdentifier>{71117941-fa47-4768-afe8-901c94d431c7}</UniqueIdentifier> + </Filter> + <Filter Include="Code\app"> + <UniqueIdentifier>{dbe40149-df23-4b89-92e4-16817775cd0e}</UniqueIdentifier> + </Filter> + <Filter Include="Code\system"> + <UniqueIdentifier>{7ab279dc-6586-4b32-aca7-0add0c0ab68a}</UniqueIdentifier> + </Filter> + <Filter Include="Code\diagnostic"> + <UniqueIdentifier>{df33e506-b5d8-423f-bcc5-1825242a3e28}</UniqueIdentifier> + </Filter> + </ItemGroup> + <ItemGroup> + <ClCompile Include="..\..\src\odbc.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\connection.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\environment.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\statement.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\type_traits.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\common_types.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\utility.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\cursor.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\result_page.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\row.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\query\data_query.cpp"> + <Filter>Code\query</Filter> + </ClCompile> + <ClCompile Include="..\..\src\query\column_metadata_query.cpp"> + <Filter>Code\query</Filter> + </ClCompile> + <ClCompile Include="..\..\src\query\table_metadata_query.cpp"> + <Filter>Code\query</Filter> + </ClCompile> + <ClCompile Include="..\..\src\meta\column_meta.cpp"> + <Filter>Code\meta</Filter> + </ClCompile> + <ClCompile Include="..\..\src\meta\table_meta.cpp"> + <Filter>Code\meta</Filter> + </ClCompile> + <ClCompile Include="..\..\src\config\configuration.cpp"> + <Filter>Code\config</Filter> + </ClCompile> + <ClCompile Include="..\..\src\config\connection_info.cpp"> + <Filter>Code\config</Filter> + </ClCompile> + <ClCompile Include="..\..\src\app\application_data_buffer.cpp"> + <Filter>Code\app</Filter> + </ClCompile> + <ClCompile Include="..\..\src\app\parameter.cpp"> + <Filter>Code\app</Filter> + </ClCompile> + <ClCompile Include="..\..\src\query\foreign_keys_query.cpp"> + <Filter>Code\query</Filter> + </ClCompile> + <ClCompile Include="..\..\src\query\primary_keys_query.cpp"> + <Filter>Code\query</Filter> + </ClCompile> + <ClCompile Include="..\..\src\diagnostic\diagnostic_record.cpp"> + <Filter>Code\diagnostic</Filter> + </ClCompile> + <ClCompile Include="..\..\src\diagnostic\diagnostic_record_storage.cpp"> + <Filter>Code\diagnostic</Filter> + </ClCompile> + <ClCompile Include="..\..\src\diagnostic\diagnosable_adapter.cpp"> + <Filter>Code\diagnostic</Filter> + </ClCompile> + <ClCompile Include="..\..\os\win\src\system\socket_client.cpp"> + <Filter>Code\system</Filter> + </ClCompile> + <ClCompile Include="..\..\src\decimal.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\query\type_info_query.cpp"> + <Filter>Code\query</Filter> + </ClCompile> + <ClCompile Include="..\..\src\column.cpp"> + <Filter>Code</Filter> + </ClCompile> + <ClCompile Include="..\..\src\query\special_columns_query.cpp"> + <Filter>Code\query</Filter> + </ClCompile> + </ItemGroup> + <ItemGroup> + <None Include="module.def"> + <Filter>Misc</Filter> + </None> + </ItemGroup> + <ItemGroup> + <ClInclude Include="result_page.h" /> + <ClInclude Include="..\..\include\ignite\odbc\common_types.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\connection.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\cursor.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\environment.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\message.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\parser.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\result_page.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\row.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\statement.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\type_traits.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\utility.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\query.h"> + <Filter>Code\query</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\data_query.h"> + <Filter>Code\query</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\column_metadata_query.h"> + <Filter>Code\query</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\table_metadata_query.h"> + <Filter>Code\query</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\meta\column_meta.h"> + <Filter>Code\meta</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\meta\table_meta.h"> + <Filter>Code\meta</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\config\configuration.h"> + <Filter>Code\config</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\config\connection_info.h"> + <Filter>Code\config</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\app\application_data_buffer.h"> + <Filter>Code\app</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\app\parameter.h"> + <Filter>Code\app</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\foreign_keys_query.h"> + <Filter>Code\query</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\primary_keys_query.h"> + <Filter>Code\query</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\meta\primary_key_meta.h"> + <Filter>Code\meta</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\diagnostic\diagnostic_record.h"> + <Filter>Code\diagnostic</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\diagnostic\diagnostic_record_storage.h"> + <Filter>Code\diagnostic</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\diagnostic\diagnosable.h"> + <Filter>Code\diagnostic</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\diagnostic\diagnosable_adapter.h"> + <Filter>Code\diagnostic</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\system\odbc_constants.h"> + <Filter>Code\system</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\system\socket_client.h"> + <Filter>Code\system</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\decimal.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\type_info_query.h"> + <Filter>Code\query</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\column.h"> + <Filter>Code</Filter> + </ClInclude> + <ClInclude Include="..\..\include\ignite\odbc\query\special_columns_query.h"> + <Filter>Code\query</Filter> + </ClInclude> + </ItemGroup> +</Project> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp b/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp new file mode 100644 index 0000000..e10011b --- /dev/null +++ b/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp @@ -0,0 +1,834 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <string> +#include <sstream> + +#include "ignite/odbc/system/odbc_constants.h" +#include "ignite/odbc/app/application_data_buffer.h" +#include "ignite/odbc/utility.h" + +namespace ignite +{ + namespace odbc + { + namespace app + { + ApplicationDataBuffer::ApplicationDataBuffer() : + type(type_traits::IGNITE_ODBC_C_TYPE_UNSUPPORTED), buffer(0), buflen(0), reslen(0), offset(0) + { + // No-op. + } + + ApplicationDataBuffer::ApplicationDataBuffer(type_traits::IgniteSqlType type, + void* buffer, SqlLen buflen, SqlLen* reslen, size_t** offset) : + type(type), buffer(buffer), buflen(buflen), reslen(reslen), offset(offset) + { + // No-op. + } + + ApplicationDataBuffer::ApplicationDataBuffer(const ApplicationDataBuffer & other) : + type(other.type), buffer(other.buffer), buflen(other.buflen), reslen(other.reslen), offset(other.offset) + { + // No-op. + } + + ApplicationDataBuffer::~ApplicationDataBuffer() + { + // No-op. + } + + ApplicationDataBuffer & ApplicationDataBuffer::operator=(const ApplicationDataBuffer & other) + { + type = other.type; + buffer = other.buffer; + buflen = other.buflen; + reslen = other.reslen; + offset = other.offset; + + return *this; + } + + template<typename T> + void ApplicationDataBuffer::PutNum(T value) + { + using namespace type_traits; + switch (type) + { + case IGNITE_ODBC_C_TYPE_SIGNED_TINYINT: + { + PutNumToNumBuffer<signed char>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_BIT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_TINYINT: + { + PutNumToNumBuffer<unsigned char>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_SHORT: + { + PutNumToNumBuffer<short>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_UNSIGNED_SHORT: + { + PutNumToNumBuffer<unsigned short>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_LONG: + { + PutNumToNumBuffer<long>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_UNSIGNED_LONG: + { + PutNumToNumBuffer<unsigned long>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_BIGINT: + { + PutNumToNumBuffer<int64_t>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT: + { + PutNumToNumBuffer<uint64_t>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_FLOAT: + { + PutNumToNumBuffer<float>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_DOUBLE: + { + PutNumToNumBuffer<double>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_CHAR: + { + PutValToStrBuffer<char>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_WCHAR: + { + PutValToStrBuffer<wchar_t>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_NUMERIC: + { + if (GetData()) + { + SQL_NUMERIC_STRUCT* out = + reinterpret_cast<SQL_NUMERIC_STRUCT*>(GetData()); + + out->precision = 0; + out->scale = 0; + out->sign = value > 0 ? 1 : 0; + + memset(out->val, 0, SQL_MAX_NUMERIC_LEN); + + // TODO: implement propper conversation to numeric type. + int64_t intVal = static_cast<int64_t>(std::abs(value)); + + memcpy(out->val, &intVal, std::min<int>(SQL_MAX_NUMERIC_LEN, sizeof(intVal))); + } + break; + } + + case IGNITE_ODBC_C_TYPE_BINARY: + case IGNITE_ODBC_C_TYPE_DEFAULT: + { + if (GetData()) + { + if (buflen >= sizeof(value)) + { + memcpy(GetData(), &value, sizeof(value)); + + if (GetResLen()) + *GetResLen() = sizeof(value); + } + else + { + memcpy(GetData(), &value, static_cast<size_t>(buflen)); + + if (GetResLen()) + *GetResLen() = SQL_NO_TOTAL; + } + } + else if (GetResLen()) + { + *GetResLen() = sizeof(value); + } + break; + } + + default: + { + if (GetResLen()) + *GetResLen() = SQL_NO_TOTAL; + } + } + } + + template<typename Tbuf, typename Tin> + void ApplicationDataBuffer::PutNumToNumBuffer(Tin value) + { + if (GetData()) + { + Tbuf* out = reinterpret_cast<Tbuf*>(GetData()); + *out = static_cast<Tbuf>(value); + } + } + + template<typename CharT, typename Tin> + void ApplicationDataBuffer::PutValToStrBuffer(const Tin & value) + { + typedef std::basic_stringstream<CharT> ConverterType; + + ConverterType converter; + + converter << value; + + PutStrToStrBuffer<CharT>(converter.str()); + } + + template<typename CharT> + void ApplicationDataBuffer::PutValToStrBuffer(const int8_t & value) + { + typedef std::basic_stringstream<CharT> ConverterType; + + ConverterType converter; + + converter << static_cast<int>(value); + + PutStrToStrBuffer<CharT>(converter.str()); + } + + template<typename OutCharT, typename InCharT> + void ApplicationDataBuffer::PutStrToStrBuffer(const std::basic_string<InCharT>& value) + { + SqlLen charSize = static_cast<SqlLen>(sizeof(OutCharT)); + + if (GetData()) + { + if (buflen >= charSize) + { + OutCharT* out = reinterpret_cast<OutCharT*>(GetData()); + + SqlLen outLen = (buflen / charSize) - 1; + + SqlLen toCopy = std::min<size_t>(outLen, value.size()); + + for (SqlLen i = 0; i < toCopy; ++i) + out[i] = value[i]; + + out[toCopy] = 0; + } + + if (GetResLen()) + { + if (buflen >= static_cast<SqlLen>((value.size() + 1) * charSize)) + *GetResLen() = static_cast<SqlLen>(value.size()); + else + *GetResLen() = SQL_NO_TOTAL; + } + } + else if (GetResLen()) + *GetResLen() = value.size(); + } + + void ApplicationDataBuffer::PutRawDataToBuffer(void *data, size_t len) + { + SqlLen ilen = static_cast<SqlLen>(len); + + if (GetData()) + { + size_t toCopy = static_cast<size_t>(std::min(buflen, ilen)); + + memcpy(GetData(), data, toCopy); + + if (GetResLen()) + { + if (buflen >= ilen) + *GetResLen() = ilen; + else + *GetResLen() = SQL_NO_TOTAL; + } + } + else if (GetResLen()) + *GetResLen() = ilen; + } + + void ApplicationDataBuffer::PutInt8(int8_t value) + { + PutNum(value); + } + + void ApplicationDataBuffer::PutInt16(int16_t value) + { + PutNum(value); + } + + void ApplicationDataBuffer::PutInt32(int32_t value) + { + PutNum(value); + } + + void ApplicationDataBuffer::PutInt64(int64_t value) + { + PutNum(value); + } + + void ApplicationDataBuffer::PutFloat(float value) + { + PutNum(value); + } + + void ApplicationDataBuffer::PutDouble(double value) + { + PutNum(value); + } + + int32_t ApplicationDataBuffer::PutString(const std::string & value) + { + using namespace type_traits; + + int32_t used = 0; + + switch (type) + { + case IGNITE_ODBC_C_TYPE_SIGNED_TINYINT: + case IGNITE_ODBC_C_TYPE_BIT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_TINYINT: + case IGNITE_ODBC_C_TYPE_SIGNED_SHORT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_SHORT: + case IGNITE_ODBC_C_TYPE_SIGNED_LONG: + case IGNITE_ODBC_C_TYPE_UNSIGNED_LONG: + case IGNITE_ODBC_C_TYPE_SIGNED_BIGINT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT: + case IGNITE_ODBC_C_TYPE_NUMERIC: + { + std::stringstream converter(value); + + int64_t numValue; + + converter >> numValue; + + PutNum(numValue); + + used = static_cast<int32_t>(value.size()); + + break; + } + + case IGNITE_ODBC_C_TYPE_FLOAT: + case IGNITE_ODBC_C_TYPE_DOUBLE: + { + std::stringstream converter(value); + + double numValue; + + converter >> numValue; + + PutNum(numValue); + + used = static_cast<int32_t>(value.size()); + + break; + } + + case IGNITE_ODBC_C_TYPE_CHAR: + case IGNITE_ODBC_C_TYPE_BINARY: + case IGNITE_ODBC_C_TYPE_DEFAULT: + { + PutStrToStrBuffer<char>(value); + + used = static_cast<int32_t>(GetSize()) - 1; + + break; + } + + case IGNITE_ODBC_C_TYPE_WCHAR: + { + PutStrToStrBuffer<wchar_t>(value); + + used = (static_cast<int32_t>(GetSize()) / 2) - 1; + + break; + } + + default: + { + if (GetResLen()) + *GetResLen() = SQL_NO_TOTAL; + } + } + + return used < 0 ? 0 : used; + } + + void ApplicationDataBuffer::PutGuid(const Guid & value) + { + using namespace type_traits; + + switch (type) + { + case IGNITE_ODBC_C_TYPE_CHAR: + case IGNITE_ODBC_C_TYPE_BINARY: + case IGNITE_ODBC_C_TYPE_DEFAULT: + { + PutValToStrBuffer<char>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_WCHAR: + { + PutValToStrBuffer<wchar_t>(value); + break; + } + + case IGNITE_ODBC_C_TYPE_GUID: + { + SQLGUID* guid = reinterpret_cast<SQLGUID*>(GetData()); + + guid->Data1 = static_cast<uint32_t>(value.GetMostSignificantBits() >> 32); + guid->Data2 = static_cast<uint16_t>(value.GetMostSignificantBits() >> 16); + guid->Data3 = static_cast<uint16_t>(value.GetMostSignificantBits()); + + uint64_t lsb = value.GetLeastSignificantBits(); + for (size_t i = 0; i < sizeof(guid->Data4); ++i) + guid->Data4[i] = (lsb >> (sizeof(guid->Data4) - i - 1) * 8) & 0xFF; + + break; + } + + default: + { + if (GetResLen()) + *GetResLen() = SQL_NO_TOTAL; + } + } + } + + int32_t ApplicationDataBuffer::PutBinaryData(void *data, size_t len) + { + using namespace type_traits; + + int32_t used = 0; + + switch (type) + { + case IGNITE_ODBC_C_TYPE_BINARY: + case IGNITE_ODBC_C_TYPE_DEFAULT: + { + PutRawDataToBuffer(data, len); + + used = static_cast<int32_t>(GetSize()); + + break; + } + + case IGNITE_ODBC_C_TYPE_CHAR: + { + std::stringstream converter; + + uint8_t *dataBytes = reinterpret_cast<uint8_t*>(data); + + for (size_t i = 0; i < len; ++i) + { + converter << std::hex + << std::setfill('0') + << std::setw(2) + << static_cast<unsigned>(dataBytes[i]); + } + + PutStrToStrBuffer<char>(converter.str()); + + used = static_cast<int32_t>(GetSize()) - 1; + + break; + } + + case IGNITE_ODBC_C_TYPE_WCHAR: + { + std::wstringstream converter; + + uint8_t *dataBytes = reinterpret_cast<uint8_t*>(data); + + for (size_t i = 0; i < len; ++i) + { + converter << std::hex + << std::setfill<wchar_t>('0') + << std::setw(2) + << static_cast<unsigned>(dataBytes[i]); + } + + PutStrToStrBuffer<wchar_t>(converter.str()); + + used = static_cast<int32_t>(GetSize() / 2) - 1; + + break; + } + + default: + { + if (GetResLen()) + *GetResLen() = SQL_NO_TOTAL; + } + } + + return used < 0 ? 0 : used; + } + + void ApplicationDataBuffer::PutNull() + { + if (GetResLen()) + *GetResLen() = SQL_NULL_DATA; + } + + void ApplicationDataBuffer::PutDecimal(const Decimal& value) + { + using namespace type_traits; + switch (type) + { + case IGNITE_ODBC_C_TYPE_SIGNED_TINYINT: + case IGNITE_ODBC_C_TYPE_BIT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_TINYINT: + case IGNITE_ODBC_C_TYPE_SIGNED_SHORT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_SHORT: + case IGNITE_ODBC_C_TYPE_SIGNED_LONG: + case IGNITE_ODBC_C_TYPE_UNSIGNED_LONG: + case IGNITE_ODBC_C_TYPE_SIGNED_BIGINT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT: + case IGNITE_ODBC_C_TYPE_FLOAT: + case IGNITE_ODBC_C_TYPE_DOUBLE: + case IGNITE_ODBC_C_TYPE_CHAR: + case IGNITE_ODBC_C_TYPE_WCHAR: + { + PutNum<double>(static_cast<double>(value)); + + break; + } + + case IGNITE_ODBC_C_TYPE_NUMERIC: + { + if (GetData()) + { + SQL_NUMERIC_STRUCT* numeric = + reinterpret_cast<SQL_NUMERIC_STRUCT*>(GetData()); + + numeric->sign = value.IsNegative() ? 1 : 0; + numeric->precision = 0; + numeric->scale = value.GetScale(); + memcpy(numeric->val, value.GetMagnitude(), std::min<size_t>(SQL_MAX_NUMERIC_LEN, value.GetLength())); + } + + break; + } + + case IGNITE_ODBC_C_TYPE_DEFAULT: + { + if (GetData()) + memcpy(GetData(), &value, std::min(static_cast<size_t>(buflen), sizeof(value))); + + if (GetResLen()) + *GetResLen() = sizeof(value); + + break; + } + + case IGNITE_ODBC_C_TYPE_BINARY: + default: + { + if (GetResLen()) + *GetResLen() = SQL_NO_TOTAL; + } + } + } + + std::string ApplicationDataBuffer::GetString(size_t maxLen) const + { + using namespace type_traits; + std::string res; + + switch (type) + { + case IGNITE_ODBC_C_TYPE_CHAR: + { + res.assign(reinterpret_cast<const char*>(GetData()), + std::min(maxLen, static_cast<size_t>(buflen))); + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_TINYINT: + case IGNITE_ODBC_C_TYPE_SIGNED_SHORT: + case IGNITE_ODBC_C_TYPE_SIGNED_LONG: + case IGNITE_ODBC_C_TYPE_SIGNED_BIGINT: + { + std::stringstream converter; + + converter << GetNum<int64_t>(); + + res = converter.str(); + + break; + } + + case IGNITE_ODBC_C_TYPE_BIT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_TINYINT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_SHORT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_LONG: + case IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT: + { + std::stringstream converter; + + converter << GetNum<uint64_t>(); + + res = converter.str(); + + break; + } + + case IGNITE_ODBC_C_TYPE_FLOAT: + { + std::stringstream converter; + + converter << GetNum<float>(); + + res = converter.str(); + + break; + } + + case IGNITE_ODBC_C_TYPE_NUMERIC: + case IGNITE_ODBC_C_TYPE_DOUBLE: + { + std::stringstream converter; + + converter << GetNum<double>(); + + res = converter.str(); + + break; + } + + default: + break; + } + + return res; + } + + int8_t ApplicationDataBuffer::GetInt8() const + { + return GetNum<int8_t>(); + } + + int16_t ApplicationDataBuffer::GetInt16() const + { + return GetNum<int16_t>(); + } + + int32_t ApplicationDataBuffer::GetInt32() const + { + return GetNum<int32_t>(); + } + + int64_t ApplicationDataBuffer::GetInt64() const + { + return GetNum<int64_t>(); + } + + float ApplicationDataBuffer::GetFloat() const + { + return GetNum<float>(); + } + + double ApplicationDataBuffer::GetDouble() const + { + return GetNum<double>(); + } + + const void* ApplicationDataBuffer::GetData() const + { + return ApplyOffset(buffer); + } + + const SqlLen* ApplicationDataBuffer::GetResLen() const + { + return ApplyOffset(reslen); + } + + void* ApplicationDataBuffer::GetData() + { + return ApplyOffset(buffer); + } + + SqlLen* ApplicationDataBuffer::GetResLen() + { + return ApplyOffset(reslen); + } + + template<typename T> + T ApplicationDataBuffer::GetNum() const + { + using namespace type_traits; + + T res = 0; + + switch (type) + { + case IGNITE_ODBC_C_TYPE_CHAR: + { + std::string str = GetString(static_cast<size_t>(buflen)); + + std::stringstream converter(str); + + // Workaround for char types which are recognised as + // symbolyc types and not numeric types. + if (sizeof(T) == 1) + { + short tmp; + + converter >> tmp; + + res = static_cast<T>(tmp); + } + else + converter >> res; + + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_TINYINT: + { + res = static_cast<T>(*reinterpret_cast<const signed char*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_BIT: + case IGNITE_ODBC_C_TYPE_UNSIGNED_TINYINT: + { + res = static_cast<T>(*reinterpret_cast<const unsigned char*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_SHORT: + { + res = static_cast<T>(*reinterpret_cast<const signed short*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_UNSIGNED_SHORT: + { + res = static_cast<T>(*reinterpret_cast<const unsigned short*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_LONG: + { + res = static_cast<T>(*reinterpret_cast<const signed long*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_UNSIGNED_LONG: + { + res = static_cast<T>(*reinterpret_cast<const unsigned long*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_BIGINT: + { + res = static_cast<T>(*reinterpret_cast<const int64_t*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT: + { + res = static_cast<T>(*reinterpret_cast<const uint64_t*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_FLOAT: + { + res = static_cast<T>(*reinterpret_cast<const float*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_DOUBLE: + { + res = static_cast<T>(*reinterpret_cast<const double*>(GetData())); + break; + } + + case IGNITE_ODBC_C_TYPE_NUMERIC: + { + const SQL_NUMERIC_STRUCT* numeric = + reinterpret_cast<const SQL_NUMERIC_STRUCT*>(GetData()); + + int64_t resInt; + + // TODO: implement propper conversation from numeric type. + memcpy(&resInt, numeric->val, std::min<int>(SQL_MAX_NUMERIC_LEN, sizeof(resInt))); + + if (numeric->sign) + resInt *= -1; + + double resDouble = static_cast<double>(resInt); + + for (SQLSCHAR scale = numeric->scale; scale > 0; --scale) + resDouble /= 10.0; + + res = static_cast<T>(resDouble); + + break; + } + + default: + break; + } + + return res; + } + + template<typename T> + T* ApplicationDataBuffer::ApplyOffset(T* ptr) const + { + if (!ptr || !offset || !*offset) + return ptr; + + return utility::GetPointerWithOffset(ptr, **offset); + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/src/app/parameter.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/app/parameter.cpp b/modules/platforms/cpp/odbc/src/app/parameter.cpp new file mode 100644 index 0000000..dbe33e1 --- /dev/null +++ b/modules/platforms/cpp/odbc/src/app/parameter.cpp @@ -0,0 +1,147 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <algorithm> +#include <string> +#include <sstream> + +#include "ignite/odbc/system/odbc_constants.h" +#include "ignite/odbc/app/parameter.h" +#include "ignite/odbc/utility.h" + +namespace ignite +{ + namespace odbc + { + namespace app + { + Parameter::Parameter() : + buffer(), + sqlType(), + columnSize(), + decDigits() + { + // No-op. + } + + Parameter::Parameter(const ApplicationDataBuffer& buffer, int16_t sqlType, + size_t columnSize, int16_t decDigits) : + buffer(buffer), + sqlType(sqlType), + columnSize(columnSize), + decDigits(decDigits) + { + // No-op. + } + + Parameter::Parameter(const Parameter & other) : + buffer(other.buffer), + sqlType(other.sqlType), + columnSize(other.columnSize), + decDigits(other.decDigits) + { + // No-op. + } + + Parameter::~Parameter() + { + // No-op. + } + + Parameter& Parameter::operator=(const Parameter &other) + { + buffer = other.buffer; + sqlType = other.sqlType; + columnSize = other.columnSize; + decDigits = other.decDigits; + + return *this; + } + + void Parameter::Write(ignite::impl::binary::BinaryWriterImpl& writer) const + { + switch (sqlType) + { + case SQL_CHAR: + case SQL_VARCHAR: + case SQL_LONGVARCHAR: + { + utility::WriteString(writer, buffer.GetString(columnSize)); + break; + } + + case SQL_SMALLINT: + { + writer.WriteInt16(buffer.GetInt16()); + break; + } + + case SQL_INTEGER: + { + writer.WriteInt32(buffer.GetInt32()); + break; + } + + case SQL_FLOAT: + { + writer.WriteFloat(buffer.GetFloat()); + break; + } + + case SQL_DOUBLE: + { + writer.WriteDouble(buffer.GetDouble()); + break; + } + + case SQL_TINYINT: + case SQL_BIT: + { + writer.WriteBool(buffer.GetInt8() != 0); + break; + } + + case SQL_BIGINT: + { + writer.WriteInt64(buffer.GetInt64()); + break; + } + + case SQL_BINARY: + case SQL_VARBINARY: + case SQL_LONGVARBINARY: + { + writer.WriteInt8Array(reinterpret_cast<const int8_t*>(buffer.GetData()), + static_cast<int32_t>(buffer.GetSize())); + break; + } + + case SQL_GUID: + default: + //TODO: Add GUID type support. + break; + } + } + + ApplicationDataBuffer & Parameter::GetBuffer() + { + return buffer; + } + } + } +} + http://git-wip-us.apache.org/repos/asf/ignite/blob/e8287063/modules/platforms/cpp/odbc/src/column.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/column.cpp b/modules/platforms/cpp/odbc/src/column.cpp new file mode 100644 index 0000000..7b2f1e9 --- /dev/null +++ b/modules/platforms/cpp/odbc/src/column.cpp @@ -0,0 +1,454 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <ignite/impl/interop/interop_stream_position_guard.h> + +#include "ignite/odbc/utility.h" +#include "ignite/odbc/column.h" + +namespace +{ + using namespace ignite::impl::interop; + using namespace ignite::impl::binary; + + bool GetObjectLength(InteropInputStream& stream, int32_t& len) + { + InteropStreamPositionGuard<InteropInputStream> guard(stream); + + int8_t hdr = stream.ReadInt8(); + + if (hdr != IGNITE_HDR_FULL) + return false; + + int8_t protoVer = stream.ReadInt8(); + + if (protoVer != IGNITE_PROTO_VER) + return false; + + // Skipping flags + stream.ReadInt16(); + + // Skipping typeId + stream.ReadInt32(); + + // Skipping hash code + stream.ReadInt32(); + + len = stream.ReadInt32(); + + return true; + } + + /** + * Read column header and restores position if the column is of + * complex type. + * @return Column type header. + */ + int8_t ReadColumnHeader(ignite::impl::interop::InteropInputStream& stream) + { + using namespace ignite::impl::binary; + + int32_t headerPos = stream.Position(); + + int8_t hdr = stream.ReadInt8(); + + // Check if we need to restore position - to read complex types + // stream should have unread header, but for primitive types it + // should not. + switch (hdr) + { + case IGNITE_TYPE_BYTE: + case IGNITE_TYPE_SHORT: + case IGNITE_TYPE_CHAR: + case IGNITE_TYPE_INT: + case IGNITE_TYPE_LONG: + case IGNITE_TYPE_FLOAT: + case IGNITE_TYPE_DOUBLE: + case IGNITE_TYPE_BOOL: + case IGNITE_HDR_NULL: + { + // No-op. + break; + } + + default: + { + // Restoring position. + stream.Position(headerPos); + break; + } + } + + return hdr; + } +} + +namespace ignite +{ + namespace odbc + { + Column::Column() : + type(0), startPos(-1), endPos(-1), offset(0), size(0) + { + // No-op. + } + + Column::Column(const Column& other) : + type(other.type), startPos(other.startPos), endPos(other.endPos), + offset(other.offset), size(other.size) + { + // No-op. + } + + Column& Column::operator=(const Column& other) + { + type = other.type; + startPos = other.startPos; + endPos = other.endPos; + offset = other.offset; + size = other.size; + + return *this; + } + + Column::~Column() + { + // No-op. + } + + Column::Column(ignite::impl::binary::BinaryReaderImpl& reader) : + type(0), startPos(-1), endPos(-1), offset(0), size(0) + { + ignite::impl::interop::InteropInputStream* stream = reader.GetStream(); + + if (!stream) + return; + + InteropStreamPositionGuard<InteropInputStream> guard(*stream); + + int32_t sizeTmp = 0; + + int8_t hdr = ReadColumnHeader(*stream); + + int32_t startPosTmp = stream->Position(); + + switch (hdr) + { + case IGNITE_HDR_NULL: + { + sizeTmp = 1; + + break; + } + + case IGNITE_TYPE_BYTE: + { + reader.ReadInt8(); + + sizeTmp = 1; + + break; + } + + case IGNITE_TYPE_BOOL: + { + reader.ReadBool(); + + sizeTmp = 1; + + break; + } + + case IGNITE_TYPE_SHORT: + case IGNITE_TYPE_CHAR: + { + reader.ReadInt16(); + + sizeTmp = 2; + + break; + } + + case IGNITE_TYPE_FLOAT: + { + reader.ReadFloat(); + + sizeTmp = 4; + + break; + } + + case IGNITE_TYPE_INT: + { + reader.ReadInt32(); + + sizeTmp = 4; + + break; + } + + case IGNITE_TYPE_DOUBLE: + { + reader.ReadDouble(); + + sizeTmp = 8; + + break; + } + + case IGNITE_TYPE_LONG: + { + reader.ReadInt64(); + + sizeTmp = 8; + + break; + } + + case IGNITE_TYPE_STRING: + { + std::string str; + utility::ReadString(reader, str); + + sizeTmp = static_cast<int32_t>(str.size()); + + break; + } + + case IGNITE_TYPE_UUID: + { + reader.ReadGuid(); + + sizeTmp = 16; + + break; + } + + case IGNITE_HDR_FULL: + { + int32_t len; + + if (!GetObjectLength(*stream, len)) + return; + + sizeTmp = len; + + stream->Position(stream->Position() + len); + + break; + } + + case IGNITE_TYPE_DECIMAL: + { + Decimal res; + + utility::ReadDecimal(reader, res); + + sizeTmp = res.GetLength() + 8; + + break; + } + + case IGNITE_TYPE_DATE: + default: + { + // This is a fail case. + return; + } + } + + type = hdr; + startPos = startPosTmp; + endPos = stream->Position(); + size = sizeTmp; + } + + SqlResult Column::ReadToBuffer(ignite::impl::binary::BinaryReaderImpl& reader, + app::ApplicationDataBuffer& dataBuf) + { + using namespace ignite::impl::binary; + using namespace ignite::impl::interop; + + if (!IsValid()) + return SQL_RESULT_ERROR; + + if (GetUnreadDataLength() == 0) + { + dataBuf.PutNull(); + + return SQL_RESULT_NO_DATA; + } + + ignite::impl::interop::InteropInputStream* stream = reader.GetStream(); + + if (!stream) + return SQL_RESULT_ERROR; + + InteropStreamPositionGuard<InteropInputStream> guard(*stream); + + stream->Position(startPos); + + switch (type) + { + case IGNITE_TYPE_BYTE: + { + dataBuf.PutInt8(reader.ReadInt8()); + + IncreaseOffset(size); + + break; + } + + case IGNITE_TYPE_SHORT: + case IGNITE_TYPE_CHAR: + { + dataBuf.PutInt16(reader.ReadInt16()); + + IncreaseOffset(size); + + break; + } + + case IGNITE_TYPE_INT: + { + dataBuf.PutInt32(reader.ReadInt32()); + + IncreaseOffset(size); + + break; + } + + case IGNITE_TYPE_LONG: + { + dataBuf.PutInt64(reader.ReadInt64()); + + IncreaseOffset(size); + + break; + } + + case IGNITE_TYPE_FLOAT: + { + dataBuf.PutFloat(reader.ReadFloat()); + + IncreaseOffset(size); + + break; + } + + case IGNITE_TYPE_DOUBLE: + { + dataBuf.PutDouble(reader.ReadDouble()); + + IncreaseOffset(size); + + break; + } + + case IGNITE_TYPE_BOOL: + { + dataBuf.PutInt8(reader.ReadBool() ? 1 : 0); + + IncreaseOffset(size); + + break; + } + + case IGNITE_TYPE_STRING: + { + std::string str; + utility::ReadString(reader, str); + + int32_t written = dataBuf.PutString(str.substr(offset)); + + IncreaseOffset(written); + + break; + } + + case IGNITE_TYPE_UUID: + { + Guid guid = reader.ReadGuid(); + + dataBuf.PutGuid(guid); + + IncreaseOffset(size); + + break; + } + + case IGNITE_HDR_NULL: + { + dataBuf.PutNull(); + + IncreaseOffset(size); + + break; + } + + case IGNITE_HDR_FULL: + { + int32_t len; + + if (!GetObjectLength(*stream, len)) + return SQL_RESULT_ERROR; + + std::vector<int8_t> data(len); + + stream->ReadInt8Array(&data[0], static_cast<int32_t>(data.size())); + + int32_t written = dataBuf.PutBinaryData(data.data() + offset, static_cast<size_t>(len - offset)); + + IncreaseOffset(written); + + break; + } + + case IGNITE_TYPE_DECIMAL: + { + Decimal res; + + utility::ReadDecimal(reader, res); + + dataBuf.PutDecimal(res); + + IncreaseOffset(size); + + break; + } + + case IGNITE_TYPE_DATE: + default: + { + // This is a fail case. Return false. + return SQL_RESULT_ERROR; + } + } + + return SQL_RESULT_SUCCESS; + } + + void Column::IncreaseOffset(int32_t value) + { + offset += value; + + if (offset > size) + offset = size; + } + } +} +
