Repository: ignite Updated Branches: refs/heads/ignite-1232 3fd608e81 -> 45ce0fd7d
http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/core-test/src/dynamic_size_array_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/core-test/src/dynamic_size_array_test.cpp b/modules/platforms/cpp/core-test/src/dynamic_size_array_test.cpp new file mode 100644 index 0000000..fb9a468 --- /dev/null +++ b/modules/platforms/cpp/core-test/src/dynamic_size_array_test.cpp @@ -0,0 +1,360 @@ +/* + * 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/common/dynamic_size_array.h> + +using namespace ignite; +using namespace ignite::common; + + +struct TestStruct +{ + int32_t one; + int32_t two; + + TestStruct() : + one(1), + two(2) + { + // No-op. + } + + TestStruct(int32_t a, int32_t b) : + one(a), + two(b) + { + // No-op. + } + + void Clear() + { + one = two = 0; + } +}; + + +BOOST_AUTO_TEST_SUITE(DynamicSizeArrayTestSuite) + +BOOST_AUTO_TEST_CASE(BasicConstruction) +{ + DynamicSizeArray<int> test(16); + + BOOST_CHECK_EQUAL(test.GetSize(), 0); + BOOST_CHECK(test.GetCapasity() >= 16); +} + +BOOST_AUTO_TEST_CASE(ResizeInt) +{ + DynamicSizeArray<int> test; + + test.Resize(16); + + for (int i = 0; i < test.GetSize(); ++i) + BOOST_CHECK_EQUAL(test[i], 0); +} + +BOOST_AUTO_TEST_CASE(ResizeBool) +{ + DynamicSizeArray<bool> test; + + test.Resize(16); + + for (int i = 0; i < test.GetSize(); ++i) + BOOST_CHECK_EQUAL(test[i], false); +} + +BOOST_AUTO_TEST_CASE(ResizeStruct) +{ + DynamicSizeArray<TestStruct> test; + + test.Resize(16); + + for (int i = 0; i < test.GetSize(); ++i) + { + BOOST_CHECK_EQUAL(test[i].one, 1); + BOOST_CHECK_EQUAL(test[i].two, 2); + } +} + +BOOST_AUTO_TEST_CASE(PushBack) +{ + DynamicSizeArray<int> test; + + test.PushBack(1); + test.PushBack(2); + test.PushBack(42); + test.PushBack(88); + + BOOST_CHECK_EQUAL(test.GetSize(), 4); + BOOST_CHECK(test.GetCapasity() >= 4); + + BOOST_CHECK_EQUAL(test[0], 1); + BOOST_CHECK_EQUAL(test[1], 2); + BOOST_CHECK_EQUAL(test[2], 42); + BOOST_CHECK_EQUAL(test[3], 88); + + BOOST_CHECK_EQUAL(test.Back(), 88); + BOOST_CHECK_EQUAL(test.Front(), 1); +} + +BOOST_AUTO_TEST_CASE(ResizeGrowing) +{ + DynamicSizeArray<TestStruct> test; + + test.PushBack(TestStruct(3, 7)); + test.PushBack(TestStruct(5, 6)); + test.PushBack(TestStruct(42, 55)); + test.PushBack(TestStruct(47334, 3)); + + BOOST_CHECK_EQUAL(test.GetSize(), 4); + + test.Resize(8); + + BOOST_CHECK_EQUAL(test[0].one, 3); + BOOST_CHECK_EQUAL(test[1].one, 5); + BOOST_CHECK_EQUAL(test[2].one, 42); + BOOST_CHECK_EQUAL(test[3].one, 47334); + + BOOST_CHECK_EQUAL(test[0].two, 7); + BOOST_CHECK_EQUAL(test[1].two, 6); + BOOST_CHECK_EQUAL(test[2].two, 55); + BOOST_CHECK_EQUAL(test[3].two, 3); + + for (int i = 4; i < test.GetSize(); ++i) + { + BOOST_CHECK_EQUAL(test[i].one, 1); + BOOST_CHECK_EQUAL(test[i].two, 2); + + test[i] = TestStruct(i * 3, i * 32508 + i); + } +} + +BOOST_AUTO_TEST_CASE(ResizeShrinking) +{ + DynamicSizeArray<TestStruct> test; + + test.PushBack(TestStruct(3, 7)); + test.PushBack(TestStruct(5, 6)); + test.PushBack(TestStruct(42, 55)); + test.PushBack(TestStruct(47334, 3)); + + BOOST_CHECK_EQUAL(test.GetSize(), 4); + + test.Resize(2); + + BOOST_CHECK_EQUAL(test.GetSize(), 2); + + BOOST_CHECK_EQUAL(test[0].one, 3); + BOOST_CHECK_EQUAL(test[1].one, 5); + + BOOST_CHECK_EQUAL(test[0].two, 7); + BOOST_CHECK_EQUAL(test[1].two, 6); +} + +BOOST_AUTO_TEST_CASE(ResizeKeep) +{ + DynamicSizeArray<TestStruct> test; + + test.PushBack(TestStruct(3, 7)); + test.PushBack(TestStruct(5, 6)); + test.PushBack(TestStruct(42, 55)); + test.PushBack(TestStruct(47334, 3)); + + BOOST_CHECK_EQUAL(test.GetSize(), 4); + + test.Resize(4); + + BOOST_CHECK_EQUAL(test[0].one, 3); + BOOST_CHECK_EQUAL(test[1].one, 5); + BOOST_CHECK_EQUAL(test[2].one, 42); + BOOST_CHECK_EQUAL(test[3].one, 47334); + + BOOST_CHECK_EQUAL(test[0].two, 7); + BOOST_CHECK_EQUAL(test[1].two, 6); + BOOST_CHECK_EQUAL(test[2].two, 55); + BOOST_CHECK_EQUAL(test[3].two, 3); +} + +BOOST_AUTO_TEST_CASE(ReserveMore) +{ + DynamicSizeArray<TestStruct> test; + + test.PushBack(TestStruct(3, 7)); + test.PushBack(TestStruct(5, 6)); + test.PushBack(TestStruct(42, 55)); + test.PushBack(TestStruct(47334, 3)); + + BOOST_CHECK_EQUAL(test.GetSize(), 4); + + int32_t capasity = test.GetCapasity(); + + test.Reserve(capasity + 1); + + BOOST_CHECK(test.GetCapasity() > capasity); + BOOST_CHECK(test.GetCapasity() >= capasity + 1); + BOOST_CHECK_EQUAL(test.GetSize(), 4); + + BOOST_CHECK_EQUAL(test[0].one, 3); + BOOST_CHECK_EQUAL(test[1].one, 5); + BOOST_CHECK_EQUAL(test[2].one, 42); + BOOST_CHECK_EQUAL(test[3].one, 47334); + + BOOST_CHECK_EQUAL(test[0].two, 7); + BOOST_CHECK_EQUAL(test[1].two, 6); + BOOST_CHECK_EQUAL(test[2].two, 55); + BOOST_CHECK_EQUAL(test[3].two, 3); +} + +BOOST_AUTO_TEST_CASE(ReserveLess) +{ + DynamicSizeArray<TestStruct> test; + + test.PushBack(TestStruct(3, 7)); + test.PushBack(TestStruct(5, 6)); + test.PushBack(TestStruct(42, 55)); + test.PushBack(TestStruct(47334, 3)); + + BOOST_CHECK_EQUAL(test.GetSize(), 4); + + int32_t capasity = test.GetCapasity(); + + test.Reserve(capasity - 1); + + BOOST_CHECK(test.GetCapasity() == capasity); + BOOST_CHECK_EQUAL(test.GetSize(), 4); + + BOOST_CHECK_EQUAL(test[0].one, 3); + BOOST_CHECK_EQUAL(test[1].one, 5); + BOOST_CHECK_EQUAL(test[2].one, 42); + BOOST_CHECK_EQUAL(test[3].one, 47334); + + BOOST_CHECK_EQUAL(test[0].two, 7); + BOOST_CHECK_EQUAL(test[1].two, 6); + BOOST_CHECK_EQUAL(test[2].two, 55); + BOOST_CHECK_EQUAL(test[3].two, 3); +} + +BOOST_AUTO_TEST_CASE(Append) +{ + DynamicSizeArray<TestStruct> test1; + DynamicSizeArray<TestStruct> test2; + + test1.PushBack(TestStruct(3, 7)); + test1.PushBack(TestStruct(5, 6)); + + test2.PushBack(TestStruct(42, 55)); + test2.PushBack(TestStruct(47334, 3)); + + BOOST_CHECK_EQUAL(test1.GetSize(), 2); + BOOST_CHECK_EQUAL(test2.GetSize(), 2); + + test1.Append(test2.GetData(), test2.GetSize()); + + BOOST_CHECK_EQUAL(test1.GetSize(), 4); + BOOST_CHECK_EQUAL(test2.GetSize(), 2); + + BOOST_CHECK_EQUAL(test1[0].one, 3); + BOOST_CHECK_EQUAL(test1[1].one, 5); + BOOST_CHECK_EQUAL(test1[2].one, 42); + BOOST_CHECK_EQUAL(test1[3].one, 47334); + + BOOST_CHECK_EQUAL(test1[0].two, 7); + BOOST_CHECK_EQUAL(test1[1].two, 6); + BOOST_CHECK_EQUAL(test1[2].two, 55); + BOOST_CHECK_EQUAL(test1[3].two, 3); + + BOOST_CHECK_EQUAL(test2[0].one, 42); + BOOST_CHECK_EQUAL(test2[1].one, 47334); + + BOOST_CHECK_EQUAL(test2[0].two, 55); + BOOST_CHECK_EQUAL(test2[1].two, 3); +} + +BOOST_AUTO_TEST_CASE(ConstructionArray) +{ + int someVals[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + DynamicSizeArray<int> test(someVals, 10); + + for (int i = 0; i < test.GetSize(); ++i) + BOOST_CHECK_EQUAL(test[i], i); +} + +BOOST_AUTO_TEST_CASE(ConstructionCopy) +{ + DynamicSizeArray<int> test1(10); + + for (int i = 0; i < test1.GetSize(); ++i) + test1[i] = i * 5; + + DynamicSizeArray<int> test2(test1); + + for (int i = 0; i < test2.GetSize(); ++i) + BOOST_CHECK_EQUAL(test2[i], i * 5); +} + +BOOST_AUTO_TEST_CASE(IsEmpty) +{ + DynamicSizeArray<int> test; + + BOOST_CHECK(test.IsEmpty()); + + test.Resize(16); + + BOOST_CHECK(!test.IsEmpty()); + + test.Clear(); + + BOOST_CHECK(test.IsEmpty()); +} + +BOOST_AUTO_TEST_CASE(Swap) +{ + DynamicSizeArray<std::string> test1(3); + DynamicSizeArray<std::string> test2(2); + + test1.PushBack("Hello"); + test1.PushBack("World"); + test1.PushBack("!!!"); + + test2.PushBack("Hi"); + test2.PushBack("!"); + + BOOST_CHECK_EQUAL(test1[0], std::string("Hello")); + BOOST_CHECK_EQUAL(test1[1], std::string("World")); + BOOST_CHECK_EQUAL(test1[2], std::string("!!!")); + + BOOST_CHECK_EQUAL(test2[0], std::string("Hi")); + BOOST_CHECK_EQUAL(test2[1], std::string("!")); + + test1.Swap(test2); + + BOOST_CHECK_EQUAL(test2[0], std::string("Hello")); + BOOST_CHECK_EQUAL(test2[1], std::string("World")); + BOOST_CHECK_EQUAL(test2[2], std::string("!!!")); + + BOOST_CHECK_EQUAL(test1[0], std::string("Hi")); + BOOST_CHECK_EQUAL(test1[1], std::string("!")); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/core-test/src/fixed_size_array_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/core-test/src/fixed_size_array_test.cpp b/modules/platforms/cpp/core-test/src/fixed_size_array_test.cpp new file mode 100644 index 0000000..4574a98 --- /dev/null +++ b/modules/platforms/cpp/core-test/src/fixed_size_array_test.cpp @@ -0,0 +1,208 @@ +/* + * 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/common/fixed_size_array.h> + +using namespace ignite; +using namespace ignite::common; + + +struct TestStruct +{ + int32_t one; + int32_t two; + + TestStruct() : + one(1), + two(2) + { + // No-op. + } + + void Clear() + { + one = two = 0; + } +}; + + +BOOST_AUTO_TEST_SUITE(FixedSizeArrayTestSuite) + +BOOST_AUTO_TEST_CASE(ConstructionInt) +{ + FixedSizeArray<int> zeroed(16); + + for (int i = 0; i < zeroed.GetSize(); ++i) + BOOST_CHECK_EQUAL(zeroed[i], 0); +} + +BOOST_AUTO_TEST_CASE(ConstructionBool) +{ + FixedSizeArray<bool> fbool(16); + + for (int i = 0; i < fbool.GetSize(); ++i) + BOOST_CHECK_EQUAL(fbool[i], false); +} + +BOOST_AUTO_TEST_CASE(ConstructionStruct) +{ + FixedSizeArray<TestStruct> test(16); + + for (int i = 0; i < test.GetSize(); ++i) + { + BOOST_CHECK_EQUAL(test[i].one, 1); + BOOST_CHECK_EQUAL(test[i].two, 2); + } +} + +BOOST_AUTO_TEST_CASE(ConstructionArray) +{ + int someVals[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + + FixedSizeArray<int> test(someVals, 10); + + for (int i = 0; i < test.GetSize(); ++i) + BOOST_CHECK_EQUAL(test[i], i); +} + +BOOST_AUTO_TEST_CASE(ConstructionCopy) +{ + FixedSizeArray<int> test1(10); + + for (int i = 0; i < test1.GetSize(); ++i) + test1[i] = i * 5; + + FixedSizeArray<int> test2(test1); + + for (int i = 0; i < test2.GetSize(); ++i) + BOOST_CHECK_EQUAL(test2[i], i * 5); +} + +BOOST_AUTO_TEST_CASE(ResetInt) +{ + FixedSizeArray<int> test(16); + + for (int i = 0; i < test.GetSize(); ++i) + test[i] = 42; + + test.Reset(16); + + for (int i = 0; i < test.GetSize(); ++i) + BOOST_CHECK_EQUAL(test[i], 0); +} + +BOOST_AUTO_TEST_CASE(ResetBool) +{ + FixedSizeArray<bool> test(16); + + for (int i = 0; i < test.GetSize(); ++i) + test[i] = true; + + test.Reset(16); + + for (int i = 0; i < test.GetSize(); ++i) + BOOST_CHECK_EQUAL(test[i], false); +} + +BOOST_AUTO_TEST_CASE(ResetStruct) +{ + FixedSizeArray<TestStruct> test(16); + + for (int i = 0; i < test.GetSize(); ++i) + test[i].Clear(); + + test.Reset(16); + + for (int i = 0; i < test.GetSize(); ++i) + { + BOOST_CHECK_EQUAL(test[i].one, 1); + BOOST_CHECK_EQUAL(test[i].two, 2); + } +} + +BOOST_AUTO_TEST_CASE(ResetSizeChange) +{ + FixedSizeArray<int> test(4); + + BOOST_CHECK_EQUAL(test.GetSize(), 4); + + for (int i = 0; i < test.GetSize(); ++i) + test[i] = 42; + + test.Reset(16); + + BOOST_CHECK_EQUAL(test.GetSize(), 16); + + for (int i = 0; i < test.GetSize(); ++i) + { + BOOST_CHECK_EQUAL(test[i], 0); + + test[i] = 100500; + } +} + +BOOST_AUTO_TEST_CASE(IsEmpty) +{ + FixedSizeArray<int> test; + + BOOST_CHECK(test.IsEmpty()); + + test.Reset(16); + + BOOST_CHECK(!test.IsEmpty()); + + test.Reset(); + + BOOST_CHECK(test.IsEmpty()); +} + +BOOST_AUTO_TEST_CASE(Swap) +{ + FixedSizeArray<std::string> test1(3); + FixedSizeArray<std::string> test2(2); + + test1[0] = "Hello"; + test1[1] = "World"; + test1[2] = "!!!"; + + test2[0] = "Hi"; + test2[1] = "!"; + + BOOST_CHECK_EQUAL(test1[0], std::string("Hello")); + BOOST_CHECK_EQUAL(test1[1], std::string("World")); + BOOST_CHECK_EQUAL(test1[2], std::string("!!!")); + + BOOST_CHECK_EQUAL(test2[0], std::string("Hi")); + BOOST_CHECK_EQUAL(test2[1], std::string("!")); + + test1.Swap(test2); + + BOOST_CHECK_EQUAL(test2[0], std::string("Hello")); + BOOST_CHECK_EQUAL(test2[1], std::string("World")); + BOOST_CHECK_EQUAL(test2[2], std::string("!!!")); + + BOOST_CHECK_EQUAL(test1[0], std::string("Hi")); + BOOST_CHECK_EQUAL(test1[1], std::string("!")); +} + +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h b/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h index 9810600..c737940 100644 --- a/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h +++ b/modules/platforms/cpp/core/include/ignite/cache/cache_entry.h @@ -119,4 +119,4 @@ namespace ignite } } -#endif _IGNITE_CACHE_CACHE_ENTRY +#endif //_IGNITE_CACHE_CACHE_ENTRY http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc-test/Makefile.am ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/Makefile.am b/modules/platforms/cpp/odbc-test/Makefile.am index 45a824b..48b193a 100644 --- a/modules/platforms/cpp/odbc-test/Makefile.am +++ b/modules/platforms/cpp/odbc-test/Makefile.am @@ -67,7 +67,6 @@ ignite_odbc_tests_SOURCES = \ ../odbc/src/config/configuration.cpp \ ../odbc/src/row.cpp \ ../odbc/src/column.cpp \ - ../odbc/src/decimal.cpp \ ../odbc/src/utility.cpp \ ../odbc/src/result_page.cpp http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/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 d634cb3..fbc0929 100644 --- a/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj +++ b/modules/platforms/cpp/odbc-test/project/vs/odbc-test.vcxproj @@ -157,7 +157,6 @@ <ClCompile Include="..\..\..\odbc\src\config\configuration.cpp" /> <ClCompile Include="..\..\..\odbc\src\config\connection_info.cpp" /> <ClCompile Include="..\..\..\odbc\src\cursor.cpp" /> - <ClCompile Include="..\..\..\odbc\src\decimal.cpp" /> <ClCompile Include="..\..\..\odbc\src\result_page.cpp" /> <ClCompile Include="..\..\..\odbc\src\row.cpp" /> <ClCompile Include="..\..\..\odbc\src\utility.cpp" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/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 f47d990..2e38c24 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 @@ -58,9 +58,6 @@ <ClCompile Include="..\..\..\odbc\src\cursor.cpp"> <Filter>Externals</Filter> </ClCompile> - <ClCompile Include="..\..\..\odbc\src\decimal.cpp"> - <Filter>Externals</Filter> - </ClCompile> <ClCompile Include="..\..\..\odbc\src\result_page.cpp"> <Filter>Externals</Filter> </ClCompile> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc-test/src/application_data_buffer_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/application_data_buffer_test.cpp b/modules/platforms/cpp/odbc-test/src/application_data_buffer_test.cpp index d2ed033..1900e75 100644 --- a/modules/platforms/cpp/odbc-test/src/application_data_buffer_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/application_data_buffer_test.cpp @@ -24,7 +24,8 @@ #include <boost/test/unit_test.hpp> #include <ignite/guid.h> -#include <ignite/odbc/decimal.h> +#include <ignite/common/decimal.h> + #include <ignite/odbc/app/application_data_buffer.h> #include <ignite/odbc/utility.h> @@ -271,7 +272,7 @@ BOOST_AUTO_TEST_CASE(TestPutDecimalToDouble) ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_DOUBLE, &numBuf, sizeof(numBuf), &reslen, 0); - Decimal decimal; + common::Decimal decimal; BOOST_CHECK_CLOSE_FRACTION(static_cast<double>(decimal), 0.0, FLOAT_PRECISION); @@ -280,14 +281,14 @@ BOOST_AUTO_TEST_CASE(TestPutDecimalToDouble) int8_t mag1[] = { 1, 0 }; - decimal = Decimal(0, mag1, sizeof(mag1)); + decimal = common::Decimal(mag1, sizeof(mag1), 0, 1); appBuf.PutDecimal(decimal); BOOST_CHECK_CLOSE_FRACTION(numBuf, 256.0, FLOAT_PRECISION); int8_t mag2[] = { 2, 23 }; - decimal = Decimal(1 | 0x80000000, mag2, sizeof(mag2)); + decimal = common::Decimal(mag2, sizeof(mag2), 1, -1); appBuf.PutDecimal(decimal); BOOST_CHECK_CLOSE_FRACTION(numBuf, -53.5, FLOAT_PRECISION); @@ -300,21 +301,21 @@ BOOST_AUTO_TEST_CASE(TestPutDecimalToLong) ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_SIGNED_LONG, &numBuf, sizeof(numBuf), &reslen, 0); - Decimal decimal; + common::Decimal decimal; appBuf.PutDecimal(decimal); BOOST_CHECK(numBuf == 0); int8_t mag1[] = { 1, 0 }; - decimal = Decimal(0, mag1, sizeof(mag1)); + decimal = common::Decimal(mag1, sizeof(mag1), 0, 1); appBuf.PutDecimal(decimal); BOOST_CHECK(numBuf == 256); int8_t mag2[] = { 2, 23 }; - decimal = Decimal(1 | 0x80000000, mag2, sizeof(mag2)); + decimal = common::Decimal(mag2, sizeof(mag2), 1, -1); appBuf.PutDecimal(decimal); BOOST_CHECK(numBuf == -53); @@ -327,21 +328,21 @@ BOOST_AUTO_TEST_CASE(TestPutDecimalToString) ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_CHAR, &strBuf, sizeof(strBuf), &reslen, 0); - Decimal decimal; + common::Decimal decimal; appBuf.PutDecimal(decimal); BOOST_CHECK(std::string(strBuf, reslen) == "0"); int8_t mag1[] = { 1, 0 }; - decimal = Decimal(0, mag1, sizeof(mag1)); + decimal = common::Decimal(mag1, sizeof(mag1), 0, 1); appBuf.PutDecimal(decimal); BOOST_CHECK(std::string(strBuf, reslen) == "256"); int8_t mag2[] = { 2, 23 }; - decimal = Decimal(1 | 0x80000000, mag2, sizeof(mag2)); + decimal = common::Decimal(mag2, sizeof(mag2), 1, -1); appBuf.PutDecimal(decimal); BOOST_CHECK(std::string(strBuf, reslen) == "-53.5"); @@ -354,12 +355,12 @@ BOOST_AUTO_TEST_CASE(TestPutDecimalToNumeric) ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_NUMERIC, &buf, sizeof(buf), &reslen, 0); - Decimal decimal; + common::Decimal decimal; appBuf.PutDecimal(decimal); BOOST_CHECK_EQUAL(1, buf.sign); // Positive BOOST_CHECK_EQUAL(0, buf.scale); // Scale is 0 by default according to specification - BOOST_CHECK_EQUAL(20, buf.precision); // Precision is driver specific. We use 20. + BOOST_CHECK_EQUAL(1, buf.precision); // Precision is 1 for default constructed Decimal (0). for (int i = 0; i < SQL_MAX_NUMERIC_LEN; ++i) BOOST_CHECK_EQUAL(0, buf.val[i]); @@ -367,12 +368,12 @@ BOOST_AUTO_TEST_CASE(TestPutDecimalToNumeric) // Trying to store 123.45 => 12345 => 0x3039 => [0x30, 0x39]. uint8_t mag1[] = { 0x30, 0x39 }; - decimal = Decimal(2, reinterpret_cast<int8_t*>(mag1), sizeof(mag1)); + decimal = common::Decimal(reinterpret_cast<int8_t*>(mag1), sizeof(mag1), 2, 1); appBuf.PutDecimal(decimal); BOOST_CHECK_EQUAL(1, buf.sign); // Positive BOOST_CHECK_EQUAL(0, buf.scale); // Scale is 0 by default according to specification - BOOST_CHECK_EQUAL(20, buf.precision); // Precision is driver specific. We use 20. + BOOST_CHECK_EQUAL(3, buf.precision); // Precision is 3, as the scale is set to 0. // 123.45 => (scale=0) 123 => 0x7B => [0x7B]. BOOST_CHECK_EQUAL(buf.val[0], 0x7B); @@ -383,12 +384,12 @@ BOOST_AUTO_TEST_CASE(TestPutDecimalToNumeric) // Trying to store 12345.678 => 12345678 => 0xBC614E => [0xBC, 0x61, 0x4E]. uint8_t mag2[] = { 0xBC, 0x61, 0x4E }; - decimal = Decimal(3 | 0x80000000, reinterpret_cast<int8_t*>(mag2), sizeof(mag2)); + decimal = common::Decimal(reinterpret_cast<int8_t*>(mag2), sizeof(mag2), 3, -1); appBuf.PutDecimal(decimal); - BOOST_CHECK_EQUAL(2, buf.sign); // Negative + BOOST_CHECK_EQUAL(0, buf.sign); // Negative BOOST_CHECK_EQUAL(0, buf.scale); // Scale is 0 by default according to specification - BOOST_CHECK_EQUAL(20, buf.precision); // Precision is driver specific. We use 20. + BOOST_CHECK_EQUAL(5, buf.precision); // Precision is 5, as the scale is set to 0. // 12345.678 => (scale=0) 12345 => 0x3039 => [0x39, 0x30]. BOOST_CHECK_EQUAL(buf.val[0], 0x39); http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc-test/src/row_test.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc-test/src/row_test.cpp b/modules/platforms/cpp/odbc-test/src/row_test.cpp index bbf0e3d..1fcd43e 100644 --- a/modules/platforms/cpp/odbc-test/src/row_test.cpp +++ b/modules/platforms/cpp/odbc-test/src/row_test.cpp @@ -32,8 +32,9 @@ using namespace ignite::odbc; std::string GetStrColumnValue(size_t rowIdx) { - std::stringstream generator("Column 2 test string, row num: "); - generator << rowIdx << ". Some trailing bytes"; + std::stringstream generator; + generator << "Column 2 test string, row num: " + << rowIdx << ". Some trailing bytes"; return generator.str(); } http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/Makefile.am ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/Makefile.am b/modules/platforms/cpp/odbc/Makefile.am index cb9a2aa..29f0ef4 100644 --- a/modules/platforms/cpp/odbc/Makefile.am +++ b/modules/platforms/cpp/odbc/Makefile.am @@ -54,7 +54,6 @@ libignite_odbc_la_SOURCES = \ src/config/connection_info.cpp \ src/connection.cpp \ src/cursor.cpp \ - src/decimal.cpp \ src/diagnostic/diagnosable_adapter.cpp \ src/diagnostic/diagnostic_record.cpp \ src/diagnostic/diagnostic_record_storage.cpp \ http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/include/Makefile.am ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/Makefile.am b/modules/platforms/cpp/odbc/include/Makefile.am index db4ffe0..192021d 100644 --- a/modules/platforms/cpp/odbc/include/Makefile.am +++ b/modules/platforms/cpp/odbc/include/Makefile.am @@ -51,7 +51,6 @@ noinst_HEADERS = \ ignite/odbc/cursor.h \ ignite/odbc/common_types.h \ ignite/odbc/result_page.h \ - ignite/odbc/decimal.h \ ignite/odbc/type_traits.h uninstall-hook: http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/include/ignite/odbc/app/application_data_buffer.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/app/application_data_buffer.h b/modules/platforms/cpp/odbc/include/ignite/odbc/app/application_data_buffer.h index 4d7460b..ed24359 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/app/application_data_buffer.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/app/application_data_buffer.h @@ -25,8 +25,8 @@ #include <ignite/guid.h> #include <ignite/date.h> #include <ignite/timestamp.h> +#include <ignite/common/decimal.h> -#include "ignite/odbc/decimal.h" #include "ignite/odbc/common_types.h" #include "ignite/odbc/type_traits.h" @@ -164,7 +164,7 @@ namespace ignite * * @param value Value to put. */ - void PutDecimal(const Decimal& value); + void PutDecimal(const common::Decimal& value); /** * Put date to buffer. @@ -251,6 +251,13 @@ namespace ignite Timestamp GetTimestamp() const; /** + * Get value of type Decimal. + * + * @param val Result is placed here. + */ + void GetDecimal(common::Decimal& val) const; + + /** * Get raw data. * * @return Buffer data. http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/include/ignite/odbc/decimal.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/decimal.h b/modules/platforms/cpp/odbc/include/ignite/odbc/decimal.h deleted file mode 100644 index 8f7932a..0000000 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/decimal.h +++ /dev/null @@ -1,137 +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 _IGNITE_ODBC_DECIMAL -#define _IGNITE_ODBC_DECIMAL - -#include <stdint.h> - -namespace ignite -{ - - /** - * Big decimal number implementation. - * @todo Move to binary or common library. - */ - class Decimal - { - friend void swap(Decimal& first, Decimal& second); - public: - /** - * Default constructor. - */ - Decimal(); - - /** - * Constructor. - * - * @param scale Scale. - * @param mag Magnitude. Value is copied. - * @param len Magnitude length in bytes. - */ - Decimal(int32_t scale, const int8_t* mag, int32_t len); - - /** - * Copy constructor. - * - * @param other Other instance. - */ - Decimal(const Decimal& other); - - /** - * Destructor. - */ - ~Decimal(); - - /** - * Copy operator. - * - * @param other Other instance. - * @return This. - */ - Decimal& operator=(const Decimal& other); - - /** - * Convert to double. - */ - operator double() const; - - /** - * Get scale. - * - * @return Scale. - */ - int32_t GetScale() const; - - /** - * Get sign. - * - * @return Sign: -1 if negative and 1 if positive. - */ - int32_t GetSign() const; - - /** - * Check if the value is negative. - * - * @return True if negative and false otherwise. - */ - bool IsNegative() const; - - /** - * Get magnitude length in bytes. - * - * @return Magnitude length in bytes. - */ - int32_t GetLength() const; - - /** - * Get number of significant bits of the magnitude. - * - * @return Number of significant bits of the magnitude. - */ - int32_t BitLength() const; - - /** - * Get magnitude pointer. - * - * @return Magnitude pointer. - */ - const int8_t* GetMagnitude() const; - - private: - /** Scale. */ - int32_t scale; - - /** Magnitude lenght. */ - int32_t len; - - /** Magnitude. */ - int8_t* magnitude; - }; - - /** - * Swap function for the Decimal type. - * - * @param first First instance. - * @param second Second instance. - */ - void swap(Decimal& first, Decimal& second); -} - - - -#endif //_IGNITE_ODBC_DECIMAL \ No newline at end of file http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h b/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h index b2a1639..34627c1 100644 --- a/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h +++ b/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h @@ -29,11 +29,11 @@ #include <algorithm> #include <ignite/common/utils.h> +#include <ignite/common/decimal.h> #include "ignite/impl/binary/binary_reader_impl.h" #include "ignite/impl/binary/binary_writer_impl.h" -#include "ignite/odbc/decimal.h" #ifdef ODBC_DEBUG @@ -56,7 +56,7 @@ namespace ignite namespace utility { /** Using common version of the util. */ - using ignite::common::IntoLower; + using common::IntoLower; /** * Skip leading spaces. @@ -141,14 +141,14 @@ namespace ignite * @param reader Reader. * @param str String. */ - void ReadString(ignite::impl::binary::BinaryReaderImpl& reader, std::string& str); + void ReadString(impl::binary::BinaryReaderImpl& reader, std::string& str); /** * Write string using writer. * @param writer Writer. * @param str String. */ - void WriteString(ignite::impl::binary::BinaryWriterImpl& writer, const std::string& str); + void WriteString(impl::binary::BinaryWriterImpl& writer, const std::string& str); /** * Read decimal value using reader. @@ -156,7 +156,7 @@ namespace ignite * @param reader Reader. * @param decimal Decimal value. */ - void ReadDecimal(ignite::impl::binary::BinaryReaderImpl& reader, Decimal& decimal); + void ReadDecimal(impl::binary::BinaryReaderImpl& reader, common::Decimal& decimal); /** * Write decimal value using writer. @@ -164,7 +164,7 @@ namespace ignite * @param writer Writer. * @param decimal Decimal value. */ - void WriteDecimal(ignite::impl::binary::BinaryWriterImpl& writer, const Decimal& decimal); + void WriteDecimal(impl::binary::BinaryWriterImpl& writer, const common::Decimal& decimal); /** * Convert SQL string buffer to std::string. http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/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 index ca5587d..5820030 100644 --- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj +++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj @@ -162,7 +162,6 @@ <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" /> @@ -197,7 +196,6 @@ <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" /> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/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 index 804fc2d..6ca58e2 100644 --- a/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters +++ b/modules/platforms/cpp/odbc/project/vs/odbc.vcxproj.filters @@ -103,9 +103,6 @@ <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> @@ -215,9 +212,6 @@ <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> http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/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 index 600dc86..eab6750 100644 --- a/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp +++ b/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp @@ -19,6 +19,8 @@ #include <string> #include <sstream> +#include "ignite/common/bits.h" + #include "ignite/impl/binary/binary_utils.h" #include "ignite/odbc/system/odbc_constants.h" @@ -154,15 +156,15 @@ namespace ignite SQL_NUMERIC_STRUCT* out = reinterpret_cast<SQL_NUMERIC_STRUCT*>(GetData()); - out->precision = 20; // Max int64_t precision + uint64_t uval = static_cast<uint64_t>(value < 0 ? -value : value); + + out->precision = common::bits::DigitLength(uval); out->scale = 0; - out->sign = value < 0 ? 2 : 1; + out->sign = value < 0 ? 0 : 1; memset(out->val, 0, SQL_MAX_NUMERIC_LEN); - int64_t intVal = static_cast<int64_t>(std::abs(value)); - - memcpy(out->val, &intVal, std::min<int>(SQL_MAX_NUMERIC_LEN, sizeof(intVal))); + memcpy(out->val, &uval, std::min<int>(SQL_MAX_NUMERIC_LEN, sizeof(uval))); } break; } @@ -354,7 +356,11 @@ namespace ignite case IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT: case IGNITE_ODBC_C_TYPE_NUMERIC: { - std::stringstream converter(value); + std::stringstream converter; + + converter << value; + + converter << value; int64_t numValue; @@ -370,7 +376,11 @@ namespace ignite case IGNITE_ODBC_C_TYPE_FLOAT: case IGNITE_ODBC_C_TYPE_DOUBLE: { - std::stringstream converter(value); + std::stringstream converter; + + converter << value; + + converter << value; double numValue; @@ -532,7 +542,7 @@ namespace ignite *GetResLen() = SQL_NULL_DATA; } - void ApplicationDataBuffer::PutDecimal(const Decimal& value) + void ApplicationDataBuffer::PutDecimal(const common::Decimal& value) { using namespace type_traits; switch (type) @@ -546,28 +556,86 @@ namespace ignite case IGNITE_ODBC_C_TYPE_UNSIGNED_LONG: case IGNITE_ODBC_C_TYPE_SIGNED_BIGINT: case IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT: + { + PutNum<int64_t>(value.ToInt64()); + + converter << value; + + PutString(converter.str()); + + break; + } + case IGNITE_ODBC_C_TYPE_FLOAT: case IGNITE_ODBC_C_TYPE_DOUBLE: + { + PutNum<double>(value.ToDouble()); + + break; + } + case IGNITE_ODBC_C_TYPE_CHAR: case IGNITE_ODBC_C_TYPE_WCHAR: - case IGNITE_ODBC_C_TYPE_NUMERIC: { - PutNum<double>(static_cast<double>(value)); + std::stringstream converter; + + converter << value; + + PutString(converter.str()); + + common::FixedSizeArray<int8_t> bytesBuffer; + + const common::BigInteger& unscaled = zeroScaled.GetUnscaledValue(); + + unscaled.MagnitudeToBytes(bytesBuffer); + + for (int32_t i = 0; i < SQL_MAX_NUMERIC_LEN; ++i) + { + int32_t bufIdx = bytesBuffer.GetSize() - 1 - i; + if (bufIdx >= 0) + numeric->val[i] = bytesBuffer[bufIdx]; + else + numeric->val[i] = 0; + } + + numeric->scale = 0; + numeric->sign = unscaled.GetSign() < 0 ? 0 : 1; + numeric->precision = unscaled.GetPrecision(); break; } - case IGNITE_ODBC_C_TYPE_DEFAULT: + case IGNITE_ODBC_C_TYPE_NUMERIC: { - if (GetData()) - memcpy(GetData(), &value, std::min(static_cast<size_t>(buflen), sizeof(value))); + SQL_NUMERIC_STRUCT* numeric = + reinterpret_cast<SQL_NUMERIC_STRUCT*>(GetData()); - if (GetResLen()) - *GetResLen() = sizeof(value); + common::Decimal zeroScaled; + value.SetScale(0, zeroScaled); + + common::FixedSizeArray<int8_t> bytesBuffer; + + const common::BigInteger& unscaled = zeroScaled.GetUnscaledValue(); + + unscaled.MagnitudeToBytes(bytesBuffer); + + for (int32_t i = 0; i < SQL_MAX_NUMERIC_LEN; ++i) + { + int32_t bufIdx = bytesBuffer.GetSize() - 1 - i; + if (bufIdx >= 0) + numeric->val[i] = bytesBuffer[bufIdx]; + else + numeric->val[i] = 0; + } + + numeric->scale = 0; + numeric->sign = unscaled.GetSign() < 0 ? 0 : 1; + numeric->precision = unscaled.GetPrecision(); break; } + case IGNITE_ODBC_C_TYPE_DEFAULT: case IGNITE_ODBC_C_TYPE_BINARY: default: { @@ -659,11 +727,11 @@ namespace ignite case IGNITE_ODBC_C_TYPE_BINARY: case IGNITE_ODBC_C_TYPE_DEFAULT: { - if (GetData()) - memcpy(GetData(), &value, std::min(static_cast<size_t>(buflen), sizeof(value))); + SQL_NUMERIC_STRUCT* numeric = + reinterpret_cast<SQL_NUMERIC_STRUCT*>(GetData()); - if (GetResLen()) - *GetResLen() = sizeof(value); + common::Decimal zeroScaled; + value.SetScale(0, zeroScaled); break; } @@ -677,6 +745,12 @@ namespace ignite case IGNITE_ODBC_C_TYPE_UNSIGNED_LONG: case IGNITE_ODBC_C_TYPE_SIGNED_BIGINT: case IGNITE_ODBC_C_TYPE_UNSIGNED_BIGINT: + { + PutNum<int64_t>(value.ToInt64()); + + break; + } + case IGNITE_ODBC_C_TYPE_FLOAT: case IGNITE_ODBC_C_TYPE_DOUBLE: case IGNITE_ODBC_C_TYPE_NUMERIC: @@ -914,7 +988,11 @@ namespace ignite { std::string str(reinterpret_cast<const char*>(GetData()), static_cast<size_t>(buflen)); - std::stringstream converter(str); + std::stringstream converter; + + converter << str; + + converter << str; converter >> res; @@ -979,7 +1057,11 @@ namespace ignite { std::string str = GetString(static_cast<size_t>(buflen)); - std::stringstream converter(str); + std::stringstream converter; + + converter << str; + + converter << str; // Workaround for char types which are recognised as // symbolyc types and not numeric types. @@ -1063,20 +1145,10 @@ namespace ignite 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))); + common::Decimal dec(reinterpret_cast<const int8_t*>(numeric->val), + SQL_MAX_NUMERIC_LEN, numeric->scale, numeric->sign ? 1 : -1, false); - if (numeric->sign == 2) - resInt *= -1; - - double resDouble = static_cast<double>(resInt); - - for (SQLSCHAR scale = numeric->scale; scale > 0; --scale) - resDouble /= 10.0; - - res = static_cast<T>(resDouble); + res = static_cast<T>(dec.ToInt64()); break; } @@ -1202,6 +1274,76 @@ namespace ignite return BinaryUtils::CTmToTimestamp(tmTime, nanos); } + void ApplicationDataBuffer::GetDecimal(common::Decimal& val) const + { + using namespace type_traits; + + switch (type) + { + case IGNITE_ODBC_C_TYPE_CHAR: + { + std::string str = GetString(static_cast<size_t>(buflen)); + + std::stringstream converter; + + converter << str; + + converter >> val; + + break; + } + + case IGNITE_ODBC_C_TYPE_SIGNED_TINYINT: + case IGNITE_ODBC_C_TYPE_BIT: + case IGNITE_ODBC_C_TYPE_SIGNED_SHORT: + case IGNITE_ODBC_C_TYPE_SIGNED_LONG: + case IGNITE_ODBC_C_TYPE_SIGNED_BIGINT: + { + val.AssignInt64(GetNum<int64_t>()); + + break; + } + + 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: + { + val.AssignUint64(GetNum<uint64_t>()); + + break; + } + + case IGNITE_ODBC_C_TYPE_FLOAT: + case IGNITE_ODBC_C_TYPE_DOUBLE: + { + val.AssignDouble(GetNum<double>()); + + break; + } + + case IGNITE_ODBC_C_TYPE_NUMERIC: + { + const SQL_NUMERIC_STRUCT* numeric = + reinterpret_cast<const SQL_NUMERIC_STRUCT*>(GetData()); + + common::Decimal dec(reinterpret_cast<const int8_t*>(numeric->val), + SQL_MAX_NUMERIC_LEN, numeric->scale, numeric->sign ? 1 : -1, false); + + val.Swap(dec); + + break; + } + + default: + { + val.AssignInt64(0); + + break; + } + } + } + template<typename T> T* ApplicationDataBuffer::ApplyOffset(T* ptr) const { http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/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 index 3ced3e8..3e14642 100644 --- a/modules/platforms/cpp/odbc/src/app/parameter.cpp +++ b/modules/platforms/cpp/odbc/src/app/parameter.cpp @@ -156,7 +156,11 @@ namespace ignite case SQL_DECIMAL: { - //TODO: Add Decimal type support. + common::Decimal dec; + buffer.GetDecimal(dec); + + utility::WriteDecimal(writer, dec); + break; } http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/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 61a55ca..ec779ac 100644 --- a/modules/platforms/cpp/odbc/src/column.cpp +++ b/modules/platforms/cpp/odbc/src/column.cpp @@ -254,11 +254,11 @@ namespace ignite case IGNITE_TYPE_DECIMAL: { - Decimal res; + common::Decimal res; utility::ReadDecimal(reader, res); - sizeTmp = res.GetLength() + 8; + sizeTmp = res.GetMagnitudeLength() + 8; break; } @@ -437,7 +437,7 @@ namespace ignite case IGNITE_TYPE_DECIMAL: { - Decimal res; + common::Decimal res; utility::ReadDecimal(reader, res); http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/src/connection.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/connection.cpp b/modules/platforms/cpp/odbc/src/connection.cpp index 59a25f9..2441759 100644 --- a/modules/platforms/cpp/odbc/src/connection.cpp +++ b/modules/platforms/cpp/odbc/src/connection.cpp @@ -25,7 +25,6 @@ #include "ignite/odbc/message.h" #include "ignite/odbc/config/configuration.h" -// TODO: implement appropriate protocol with de-/serialisation. namespace { #pragma pack(push, 1) http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/src/decimal.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/decimal.cpp b/modules/platforms/cpp/odbc/src/decimal.cpp deleted file mode 100644 index c1b2c44..0000000 --- a/modules/platforms/cpp/odbc/src/decimal.cpp +++ /dev/null @@ -1,135 +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. - */ - -#include <cstring> -#include <utility> - -#include "ignite/common/utils.h" - -#include "ignite/odbc/decimal.h" - -namespace ignite -{ - Decimal::Decimal() : - scale(0), len(0), magnitude(0) - { - // No-op. - } - - Decimal::Decimal(int32_t scale, const int8_t* mag, int32_t len) : - scale(scale), len(len), magnitude(0) - { - magnitude = new int8_t[len]; - - memcpy(magnitude, mag, len); - } - - Decimal::Decimal(const Decimal& other) : - scale(other.scale), len(other.len), magnitude(0) - { - magnitude = new int8_t[len]; - - memcpy(magnitude, other.magnitude, len); - } - - Decimal::~Decimal() - { - if (magnitude) - delete[] magnitude; - } - - Decimal& Decimal::operator=(const Decimal& other) - { - Decimal tmp(other); - - swap(tmp, *this); - - return *this; - } - - Decimal::operator double() const - { - double res = 0; - - for (int32_t i = 0; i < len; ++i) - res = (res * 256) + static_cast<uint8_t>(magnitude[i]); - - for (int32_t i = 0; i < GetScale(); ++i) - res /= 10.0; - - return res * GetSign(); - } - - int32_t Decimal::GetScale() const - { - return scale & 0x7FFFFFFF; - } - - int32_t Decimal::GetSign() const - { - return IsNegative() ? -1 : 1; - } - - bool Decimal::IsNegative() const - { - return (scale & 0x80000000) != 0; - } - - int32_t Decimal::GetLength() const - { - return len; - } - - int32_t Decimal::BitLength() const - { - using namespace common; - - if (len == 0) - return 0; - - int32_t bitsLen = (len - 1) * 8 + - BitLengthForOctet(magnitude[len - 1]); - - if (IsNegative()) { - - // Check if magnitude is a power of two - bool pow2 = PowerOfTwo(magnitude[len - 1]); - for (int i = 0; i < len - 1 && pow2; ++i) - pow2 = (magnitude[i] == 0); - - if (pow2) - --bitsLen; - } - - return bitsLen; - } - - const int8_t* Decimal::GetMagnitude() const - { - return magnitude; - } - - void swap(Decimal& first, Decimal& second) - { - using std::swap; - - std::swap(first.scale, second.scale); - std::swap(first.len, second.len); - std::swap(first.magnitude, second.magnitude); - } -} - http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/src/odbc.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/odbc.cpp b/modules/platforms/cpp/odbc/src/odbc.cpp index 53717c7..3b31f1d 100644 --- a/modules/platforms/cpp/odbc/src/odbc.cpp +++ b/modules/platforms/cpp/odbc/src/odbc.cpp @@ -638,7 +638,6 @@ namespace ignite if (!statement) return SQL_INVALID_HANDLE; - //TODO: reset diagnostic here. return statement->DataAvailable() ? SQL_SUCCESS : SQL_NO_DATA; } @@ -887,7 +886,6 @@ namespace ignite if (!statement) return SQL_INVALID_HANDLE; - //TODO: move this logic into Statement. switch (attr) { case SQL_ATTR_APP_ROW_DESC: @@ -974,7 +972,6 @@ namespace ignite if (!statement) return SQL_INVALID_HANDLE; - //TODO: move this logic into Statement. switch (attr) { case SQL_ATTR_ROW_ARRAY_SIZE: http://git-wip-us.apache.org/repos/asf/ignite/blob/5cc1f074/modules/platforms/cpp/odbc/src/utility.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/src/utility.cpp b/modules/platforms/cpp/odbc/src/utility.cpp index 8cdfdb6..133f059 100644 --- a/modules/platforms/cpp/odbc/src/utility.cpp +++ b/modules/platforms/cpp/odbc/src/utility.cpp @@ -77,7 +77,7 @@ namespace ignite writer.WriteString(str.data(), static_cast<int32_t>(str.size())); } - void ReadDecimal(ignite::impl::binary::BinaryReaderImpl& reader, Decimal& decimal) + void ReadDecimal(ignite::impl::binary::BinaryReaderImpl& reader, common::Decimal& decimal) { int8_t hdr = reader.ReadInt8(); @@ -93,20 +93,31 @@ namespace ignite impl::binary::BinaryUtils::ReadInt8Array(reader.GetStream(), mag.data(), static_cast<int32_t>(mag.size())); - Decimal res(scale, mag.data(), static_cast<int32_t>(mag.size())); + int32_t sign = (scale & 0x80000000) ? -1 : 1; + scale = scale & 0x7FFFFFFF; - swap(decimal, res); + common::Decimal res(mag.data(), static_cast<int32_t>(mag.size()), scale, sign); + + decimal.Swap(res); } - void WriteDecimal(ignite::impl::binary::BinaryWriterImpl& writer, const Decimal& decimal) + void WriteDecimal(ignite::impl::binary::BinaryWriterImpl& writer, const common::Decimal& decimal) { writer.WriteInt8(ignite::impl::binary::IGNITE_TYPE_DECIMAL); - writer.WriteInt32(decimal.GetScale() | (decimal.IsNegative() ? 0x80000000 : 0)); + const common::BigInteger &unscaled = decimal.GetUnscaledValue(); + + int32_t signFlag = unscaled.GetSign() == -1 ? 0x80000000 : 0; + + writer.WriteInt32(decimal.GetScale() | signFlag); + + common::FixedSizeArray<int8_t> magnitude; + + unscaled.MagnitudeToBytes(magnitude); - writer.WriteInt32(decimal.GetLength()); + writer.WriteInt32(magnitude.GetSize()); - impl::binary::BinaryUtils::WriteInt8Array(writer.GetStream(), decimal.GetMagnitude(), decimal.GetLength()); + impl::binary::BinaryUtils::WriteInt8Array(writer.GetStream(), magnitude.GetData(), magnitude.GetSize()); } std::string SqlStringToString(const unsigned char* sqlStr, int32_t sqlStrLen)
