IGNITE-2223: Basic decimal type cast implemented.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/d4547246 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/d4547246 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/d4547246 Branch: refs/heads/ignite-1786 Commit: d4547246a5d74588a76677ab3af31563d6e87cdc Parents: 9c904bf Author: isapego <[email protected]> Authored: Tue Jan 12 15:36:31 2016 +0300 Committer: isapego <[email protected]> Committed: Tue Jan 12 15:36:31 2016 +0300 ---------------------------------------------------------------------- .../ignite/odbc/app/application_data_buffer.h | 8 +++ .../odbc-driver/include/ignite/odbc/decimal.h | 19 ++++++ .../src/app/application_data_buffer.cpp | 68 ++++++++++++++++++-- .../cpp/odbc/odbc-driver/src/decimal.cpp | 36 ++++++++++- .../platforms/cpp/odbc/odbc-driver/src/row.cpp | 25 ++++++- 5 files changed, 147 insertions(+), 9 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/d4547246/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/app/application_data_buffer.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/app/application_data_buffer.h b/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/app/application_data_buffer.h index 5b7d539..c2d4d1b 100644 --- a/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/app/application_data_buffer.h +++ b/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/app/application_data_buffer.h @@ -24,6 +24,7 @@ #include <ignite/guid.h> +#include "ignite/odbc/decimal.h" #include "ignite/odbc/type_traits.h" namespace ignite @@ -154,6 +155,13 @@ namespace ignite void PutNull(); /** + * Put decimal value to buffer. + * + * @param value Value to put. + */ + void PutDecimal(const Decimal& value); + + /** * Get string. * * @return String value of buffer. http://git-wip-us.apache.org/repos/asf/ignite/blob/d4547246/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/decimal.h ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/decimal.h b/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/decimal.h index 7b5188b..abf7f34 100644 --- a/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/decimal.h +++ b/modules/platforms/cpp/odbc/odbc-driver/include/ignite/odbc/decimal.h @@ -62,6 +62,11 @@ namespace ignite Decimal& operator=(const Decimal& other); /** + * Convert to double. + */ + operator double() const; + + /** * Get scale. * * @return Scale. @@ -69,6 +74,20 @@ namespace ignite 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. * * @return Magnitude length. http://git-wip-us.apache.org/repos/asf/ignite/blob/d4547246/modules/platforms/cpp/odbc/odbc-driver/src/app/application_data_buffer.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/odbc-driver/src/app/application_data_buffer.cpp b/modules/platforms/cpp/odbc/odbc-driver/src/app/application_data_buffer.cpp index e3e4400..3a3d061 100644 --- a/modules/platforms/cpp/odbc/odbc-driver/src/app/application_data_buffer.cpp +++ b/modules/platforms/cpp/odbc/odbc-driver/src/app/application_data_buffer.cpp @@ -446,9 +446,9 @@ namespace ignite for (size_t i = 0; i < len; ++i) { converter << std::hex - << std::setfill('0') - << std::setw(2) - << (unsigned)dataBytes[i]; + << std::setfill('0') + << std::setw(2) + << static_cast<unsigned>(dataBytes[i]); } PutStrToStrBuffer<char>(converter.str()); @@ -467,7 +467,7 @@ namespace ignite converter << std::hex << std::setfill<wchar_t>('0') << std::setw(2) - << (unsigned)dataBytes[i]; + << static_cast<unsigned>(dataBytes[i]); } PutStrToStrBuffer<wchar_t>(converter.str()); @@ -489,6 +489,66 @@ namespace ignite *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<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; http://git-wip-us.apache.org/repos/asf/ignite/blob/d4547246/modules/platforms/cpp/odbc/odbc-driver/src/decimal.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/odbc-driver/src/decimal.cpp b/modules/platforms/cpp/odbc/odbc-driver/src/decimal.cpp index af16747..128fb97 100644 --- a/modules/platforms/cpp/odbc/odbc-driver/src/decimal.cpp +++ b/modules/platforms/cpp/odbc/odbc-driver/src/decimal.cpp @@ -22,10 +22,10 @@ namespace ignite { - Decimal::Decimal() : scale(0), len(0), magnitude(0) { + // No-op. } Decimal::Decimal(int32_t scale, const int8_t* mag, int32_t len) : @@ -59,9 +59,40 @@ namespace ignite return *this; } + Decimal::operator double() const + { + double res = 1; + + int32_t localScale = GetScale(); + + for (size_t i = 0; i < len; ++i) + { + res = (res * 256) + magnitude[i]; + + while (localScale && res > 10.0) + { + res /= 10.0; + + --localScale; + } + } + + return res * GetSign(); + } + int32_t Decimal::GetScale() const { - return scale; + 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 @@ -83,3 +114,4 @@ namespace ignite std::swap(first.magnitude, second.magnitude); } } + http://git-wip-us.apache.org/repos/asf/ignite/blob/d4547246/modules/platforms/cpp/odbc/odbc-driver/src/row.cpp ---------------------------------------------------------------------- diff --git a/modules/platforms/cpp/odbc/odbc-driver/src/row.cpp b/modules/platforms/cpp/odbc/odbc-driver/src/row.cpp index 3a81b0a..c1ddcb1 100644 --- a/modules/platforms/cpp/odbc/odbc-driver/src/row.cpp +++ b/modules/platforms/cpp/odbc/odbc-driver/src/row.cpp @@ -186,7 +186,8 @@ namespace ignite case IGNITE_HDR_NULL: { - // TODO: clear buffer here. + dataBuf.PutNull(); + break; } @@ -207,10 +208,20 @@ namespace ignite } case IGNITE_TYPE_DECIMAL: + { + Decimal res; + + utility::ReadDecimal(reader, res); + + //dataBuf.putDecimal(res); + + break; + } + case IGNITE_TYPE_DATE: default: { - // TODO: This is a fail case. Process it somehow. + // This is a fail case. Return false. return false; } } @@ -307,10 +318,18 @@ namespace ignite } case IGNITE_TYPE_DECIMAL: + { + Decimal res; + + utility::ReadDecimal(reader, res); + + break; + } + case IGNITE_TYPE_DATE: default: { - // TODO: This is a fail case. Process it somehow. + // This is a fail case. Return false. return false; } }
