Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 7F693200C02 for ; Thu, 15 Dec 2016 10:21:11 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 7C78D160B30; Thu, 15 Dec 2016 09:21:11 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 4E64D160B39 for ; Thu, 15 Dec 2016 10:21:10 +0100 (CET) Received: (qmail 57967 invoked by uid 500); 15 Dec 2016 09:21:09 -0000 Mailing-List: contact commits-help@ignite.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ignite.apache.org Delivered-To: mailing list commits@ignite.apache.org Received: (qmail 57694 invoked by uid 99); 15 Dec 2016 09:21:08 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 15 Dec 2016 09:21:08 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id AA0ECF0BF2; Thu, 15 Dec 2016 09:21:08 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: sboikov@apache.org To: commits@ignite.apache.org Date: Thu, 15 Dec 2016 09:21:17 -0000 Message-Id: <7c532cb3c2b94d5fa251a153b0dedf4f@git.apache.org> In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [11/18] ignite git commit: IGNITE-4421: Added BinaryObject handling in ODBC archived-at: Thu, 15 Dec 2016 09:21:11 -0000 IGNITE-4421: Added BinaryObject handling in ODBC This closes #1342 Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/96160adf Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/96160adf Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/96160adf Branch: refs/heads/ignite-4371 Commit: 96160adf576753c600f3d42fae8ee761d349fad4 Parents: 3b6b02a Author: Igor Sapego Authored: Wed Dec 14 12:28:41 2016 +0300 Committer: Pavel Tupitsyn Committed: Wed Dec 14 12:28:41 2016 +0300 ---------------------------------------------------------------------- .../cpp/odbc-test/config/queries-test.xml | 37 ++++++ .../platforms/cpp/odbc-test/include/Makefile.am | 1 + .../cpp/odbc-test/include/complex_type.h | 122 +++++++++++++++++++ .../cpp/odbc-test/project/vs/odbc-test.vcxproj | 1 + .../project/vs/odbc-test.vcxproj.filters | 3 + .../cpp/odbc-test/src/queries_test.cpp | 101 ++++++++++++--- modules/platforms/cpp/odbc/src/column.cpp | 41 ++++--- modules/platforms/cpp/odbc/src/type_traits.cpp | 3 + 8 files changed, 277 insertions(+), 32 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/96160adf/modules/platforms/cpp/odbc-test/config/queries-test.xml ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/config/queries-test.xml b/modules/platforms/cpp/odbc-test/config/queries-test.xml index f511c7d..906fadf 100644 --- a/modules/platforms/cpp/odbc-test/config/queries-test.xml +++ b/modules/platforms/cpp/odbc-test/config/queries-test.xml @@ -85,6 +85,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://git-wip-us.apache.org/repos/asf/ignite/blob/96160adf/modules/platforms/cpp/odbc-test/include/Makefile.am ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/include/Makefile.am b/modules/platforms/cpp/odbc-test/include/Makefile.am index 832103c..d13e7b6 100644 --- a/modules/platforms/cpp/odbc-test/include/Makefile.am +++ b/modules/platforms/cpp/odbc-test/include/Makefile.am @@ -19,6 +19,7 @@ ACLOCAL_AMFLAGS =-I m4 noinst_HEADERS = \ teamcity/teamcity_messages.h \ + complex_type.h \ test_type.h \ test_utils.h \ sql_test_suite_fixture.h http://git-wip-us.apache.org/repos/asf/ignite/blob/96160adf/modules/platforms/cpp/odbc-test/include/complex_type.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/include/complex_type.h b/modules/platforms/cpp/odbc-test/include/complex_type.h new file mode 100644 index 0000000..a84b033 --- /dev/null +++ b/modules/platforms/cpp/odbc-test/include/complex_type.h @@ -0,0 +1,122 @@ +/* + * 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 _IGNITE_ODBC_TEST_COMPLEX_TYPE +#define _IGNITE_ODBC_TEST_COMPLEX_TYPE + +#include + +#include "ignite/ignite.h" +#include "ignite/ignition.h" + +namespace ignite +{ + struct TestObject + { + TestObject() : + f1(412), + f2("Lorem ipsum") + { + // No-op. + } + + int32_t f1; + std::string f2; + }; + + struct ComplexType + { + ComplexType() : + i32Field(0) + { + // No-op. + } + + int32_t i32Field; + TestObject objField; + std::string strField; + }; +} + +namespace ignite +{ + namespace binary + { + + IGNITE_BINARY_TYPE_START(ignite::TestObject) + + typedef ignite::TestObject TestObject; + + IGNITE_BINARY_GET_TYPE_ID_AS_HASH(TestObject) + IGNITE_BINARY_GET_TYPE_NAME_AS_IS(TestObject) + IGNITE_BINARY_GET_FIELD_ID_AS_HASH + IGNITE_BINARY_GET_HASH_CODE_ZERO(TestObject) + IGNITE_BINARY_IS_NULL_FALSE(TestObject) + IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(TestObject) + + void Write(BinaryWriter& writer, TestObject obj) + { + writer.WriteInt32("f1", obj.f1); + writer.WriteString("f2", obj.f2); + } + + TestObject Read(BinaryReader& reader) + { + TestObject obj; + + obj.f1 = reader.ReadInt32("f1"); + obj.f2 = reader.ReadString("f2"); + + return obj; + } + + IGNITE_BINARY_TYPE_END + + IGNITE_BINARY_TYPE_START(ignite::ComplexType) + + typedef ignite::ComplexType ComplexType; + + IGNITE_BINARY_GET_TYPE_ID_AS_HASH(ComplexType) + IGNITE_BINARY_GET_TYPE_NAME_AS_IS(ComplexType) + IGNITE_BINARY_GET_FIELD_ID_AS_HASH + IGNITE_BINARY_GET_HASH_CODE_ZERO(ComplexType) + IGNITE_BINARY_IS_NULL_FALSE(ComplexType) + IGNITE_BINARY_GET_NULL_DEFAULT_CTOR(ComplexType) + + void Write(BinaryWriter& writer, ComplexType obj) + { + writer.WriteInt32("i32Field", obj.i32Field); + writer.WriteObject("objField", obj.objField); + writer.WriteString("strField", obj.strField); + } + + ComplexType Read(BinaryReader& reader) + { + ComplexType obj; + + obj.i32Field = reader.ReadInt32("i32Field"); + obj.objField = reader.ReadObject("objField"); + obj.strField = reader.ReadString("strField"); + + return obj; + } + + IGNITE_BINARY_TYPE_END + } +}; + +#endif // _IGNITE_ODBC_TEST_COMPLEX_TYPE http://git-wip-us.apache.org/repos/asf/ignite/blob/96160adf/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj index 91603dc..753ae4c 100644 --- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj +++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj @@ -186,6 +186,7 @@ + http://git-wip-us.apache.org/repos/asf/ignite/blob/96160adf/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters index eef6abb..bedceaa 100644 --- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters +++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj.filters @@ -129,6 +129,9 @@ Code + + Code\CacheTypes + http://git-wip-us.apache.org/repos/asf/ignite/blob/96160adf/modules/platforms/cpp/odbc-test/src/queries_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/queries_test.cpp b/modules/platforms/cpp/odbc-test/src/queries_test.cpp index 554cee2..52b885d 100644 --- a/modules/platforms/cpp/odbc-test/src/queries_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/queries_test.cpp @@ -37,6 +37,7 @@ #include "ignite/impl/binary/binary_utils.h" #include "test_type.h" +#include "complex_type.h" #include "test_utils.h" using namespace ignite; @@ -150,11 +151,17 @@ struct QueriesTestSuiteFixture /** * Constructor. */ - QueriesTestSuiteFixture() : testCache(0), env(NULL), dbc(NULL), stmt(NULL) + QueriesTestSuiteFixture() : + cache1(0), + cache2(0), + env(NULL), + dbc(NULL), + stmt(NULL) { grid = StartNode("NodeMain", "queries-test.xml"); - testCache = grid.GetCache("cache"); + cache1 = grid.GetCache("cache"); + cache2 = grid.GetCache("cache2"); } /** @@ -180,8 +187,8 @@ struct QueriesTestSuiteFixture TestType in2(8, 7, 6, 5, "4", 3.0f, 2.0, false, Guid(1, 0), BinaryUtils::MakeDateGmt(1976, 1, 12), BinaryUtils::MakeTimestampGmt(1978, 8, 21, 23, 13, 45, 456)); - testCache.Put(1, in1); - testCache.Put(2, in2); + cache1.Put(1, in1); + cache1.Put(2, in2); const size_t columnsCnt = 11; @@ -362,8 +369,11 @@ struct QueriesTestSuiteFixture /** Node started during the test. */ Ignite grid; - /** Test cache instance. */ - Cache testCache; + /** Frist cache instance. */ + Cache cache1; + + /** Second cache instance. */ + Cache cache2; /** ODBC Environment. */ SQLHENV env; @@ -444,8 +454,8 @@ BOOST_AUTO_TEST_CASE(TestTwoRowsString) TestType in2(8, 7, 6, 5, "4", 3.0f, 2.0, false, Guid(1, 0), BinaryUtils::MakeDateGmt(1976, 1, 12), BinaryUtils::MakeTimestampGmt(1978, 8, 21, 23, 13, 45, 999999999)); - testCache.Put(1, in1); - testCache.Put(2, in2); + cache1.Put(1, in1); + cache1.Put(2, in2); const size_t columnsCnt = 11; @@ -541,7 +551,7 @@ BOOST_AUTO_TEST_CASE(TestOneRowString) TestType in(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9), BinaryUtils::MakeDateGmt(1987, 6, 5), BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456)); - testCache.Put(1, in); + cache1.Put(1, in); const size_t columnsCnt = 11; @@ -607,7 +617,7 @@ BOOST_AUTO_TEST_CASE(TestOneRowStringLen) TestType in(1, 2, 3, 4, "5", 6.0f, 7.0, true, Guid(8, 9), BinaryUtils::MakeDateGmt(1987, 6, 5), BinaryUtils::MakeTimestampGmt(1998, 12, 27, 1, 2, 3, 456)); - testCache.Put(1, in); + cache1.Put(1, in); const size_t columnsCnt = 11; @@ -649,6 +659,63 @@ BOOST_AUTO_TEST_CASE(TestOneRowStringLen) BOOST_CHECK(ret == SQL_NO_DATA); } +BOOST_AUTO_TEST_CASE(TestOneRowObject) +{ + Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache2"); + + SQLRETURN ret; + + ComplexType obj; + + obj.i32Field = 123; + obj.strField = "Some string"; + + obj.objField.f1 = 54321; + obj.objField.f2 = "Hello Ignite"; + + cache2.Put(1, obj); + + int64_t column1 = 0; + int8_t column2[ODBC_BUFFER_SIZE] = { 0 }; + char column3[ODBC_BUFFER_SIZE] = { 0 }; + + SQLLEN column1Len = sizeof(column1); + SQLLEN column2Len = sizeof(column2); + SQLLEN column3Len = sizeof(column3); + + // Binding columns. + ret = SQLBindCol(stmt, 1, SQL_C_SLONG, &column1, column1Len, &column1Len); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + ret = SQLBindCol(stmt, 2, SQL_C_BINARY, &column2, column2Len, &column2Len); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + ret = SQLBindCol(stmt, 3, SQL_C_CHAR, &column3, column3Len, &column3Len); + + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + SQLCHAR request[] = "SELECT i32Field, objField, strField FROM ComplexType"; + + ret = SQLExecDirect(stmt, request, SQL_NTS); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + ret = SQLFetch(stmt); + if (!SQL_SUCCEEDED(ret)) + BOOST_FAIL(GetOdbcErrorMessage(SQL_HANDLE_STMT, stmt)); + + BOOST_CHECK_EQUAL(column1, obj.i32Field); + BOOST_CHECK_EQUAL(column3, obj.strField); + + ret = SQLFetch(stmt); + BOOST_CHECK(ret == SQL_NO_DATA); +} + BOOST_AUTO_TEST_CASE(TestDataAtExecution) { Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache"); @@ -661,8 +728,8 @@ BOOST_AUTO_TEST_CASE(TestDataAtExecution) TestType in2(8, 7, 6, 5, "4", 3.0f, 2.0, false, Guid(1, 0), BinaryUtils::MakeDateGmt(1976, 1, 12), BinaryUtils::MakeTimestampGmt(1978, 8, 21, 23, 13, 45, 999999999)); - testCache.Put(1, in1); - testCache.Put(2, in2); + cache1.Put(1, in1); + cache1.Put(2, in2); const size_t columnsCnt = 11; @@ -785,9 +852,9 @@ BOOST_AUTO_TEST_CASE(TestNullFields) inNull.allNulls = true; - testCache.Put(1, in); - testCache.Put(2, inNull); - testCache.Put(3, in); + cache1.Put(1, in); + cache1.Put(2, inNull); + cache1.Put(3, in); const size_t columnsCnt = 10; @@ -900,7 +967,7 @@ BOOST_AUTO_TEST_CASE(TestDistributedJoins) entry.i32Field = i; entry.i64Field = entriesNum - i - 1; - testCache.Put(i, entry); + cache1.Put(i, entry); } Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache"); @@ -974,7 +1041,7 @@ BOOST_AUTO_TEST_CASE(TestDistributedJoinsWithOldVersion) entry.i32Field = i; entry.i64Field = entriesNum - i - 1; - testCache.Put(i, entry); + cache1.Put(i, entry); } Connect("DRIVER={Apache Ignite};ADDRESS=127.0.0.1:11110;CACHE=cache;DISTRIBUTED_JOINS=true;PROTOCOL_VERSION=1.6.0"); http://git-wip-us.apache.org/repos/asf/ignite/blob/96160adf/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 index b076a12..3e6bbca 100644 --- a/modules/platforms/cpp/odbc/src/column.cpp +++ b/modules/platforms/cpp/odbc/src/column.cpp @@ -31,24 +31,32 @@ namespace int8_t hdr = stream.ReadInt8(); - if (hdr != IGNITE_HDR_FULL) - return false; - - int8_t protoVer = stream.ReadInt8(); + switch (hdr) + { + case IGNITE_TYPE_BINARY: + { + // Header field + Length field + Object itself + Offset field + len = 1 + 4 + stream.ReadInt32() + 4; - if (protoVer != IGNITE_PROTO_VER) - return false; + break; + } + + case IGNITE_TYPE_OBJECT: + { + int8_t protoVer = stream.ReadInt8(); - // Skipping flags - stream.ReadInt16(); + if (protoVer != IGNITE_PROTO_VER) + return false; - // Skipping typeId - stream.ReadInt32(); + // Skipping flags, typeId and hash code + len = stream.ReadInt32(stream.Position() + 2 + 4 + 4); - // Skipping hash code - stream.ReadInt32(); + break; + } - len = stream.ReadInt32(); + default: + return false; + } return true; } @@ -238,7 +246,8 @@ namespace ignite break; } - case IGNITE_HDR_FULL: + case IGNITE_TYPE_BINARY: + case IGNITE_TYPE_OBJECT: { int32_t len; @@ -284,6 +293,7 @@ namespace ignite default: { // This is a fail case. + assert(false); return; } } @@ -413,7 +423,8 @@ namespace ignite break; } - case IGNITE_HDR_FULL: + case IGNITE_TYPE_BINARY: + case IGNITE_TYPE_OBJECT: { int32_t len; http://git-wip-us.apache.org/repos/asf/ignite/blob/96160adf/modules/platforms/cpp/odbc/src/type_traits.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/type_traits.cpp b/modules/platforms/cpp/odbc/src/type_traits.cpp index fced2e1..643e1b4 100644 --- a/modules/platforms/cpp/odbc/src/type_traits.cpp +++ b/modules/platforms/cpp/odbc/src/type_traits.cpp @@ -299,12 +299,14 @@ namespace ignite return IGNITE_ODBC_C_TYPE_WCHAR; case SQL_C_SSHORT: + case SQL_C_SHORT: return IGNITE_ODBC_C_TYPE_SIGNED_SHORT; case SQL_C_USHORT: return IGNITE_ODBC_C_TYPE_UNSIGNED_SHORT; case SQL_C_SLONG: + case SQL_C_LONG: return IGNITE_ODBC_C_TYPE_SIGNED_LONG; case SQL_C_ULONG: @@ -320,6 +322,7 @@ namespace ignite return IGNITE_ODBC_C_TYPE_BIT; case SQL_C_STINYINT: + case SQL_C_TINYINT: return IGNITE_ODBC_C_TYPE_SIGNED_TINYINT; case SQL_C_UTINYINT: