You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by vo...@apache.org on 2016/02/20 10:20:10 UTC
ignite git commit: IGNITE-2601: ODBC: Date and Timestamp support.
Repository: ignite
Updated Branches:
refs/heads/ignite-1786 5dd271ae3 -> 3c52e63b1
IGNITE-2601: ODBC: Date and Timestamp support.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/3c52e63b
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/3c52e63b
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/3c52e63b
Branch: refs/heads/ignite-1786
Commit: 3c52e63b17d86d095eda53eed361140a134c4d20
Parents: 5dd271a
Author: isapego <is...@gridgain.com>
Authored: Sat Feb 20 12:20:03 2016 +0300
Committer: vozerov-gridgain <vo...@gridgain.com>
Committed: Sat Feb 20 12:20:03 2016 +0300
----------------------------------------------------------------------
.../cpp/core-test/src/cache_query_test.cpp | 2 +-
.../src/application_data_buffer_test.cpp | 358 +++++++++++++++++++
.../platforms/cpp/odbc-test/src/parser_test.cpp | 13 +-
.../ignite/odbc/app/application_data_buffer.h | 32 +-
.../cpp/odbc/include/ignite/odbc/type_traits.h | 3 +
.../cpp/odbc/include/ignite/odbc/utility.h | 21 +-
.../odbc/src/app/application_data_buffer.cpp | 354 ++++++++++++++++++
.../platforms/cpp/odbc/src/app/parameter.cpp | 12 +
modules/platforms/cpp/odbc/src/column.cpp | 34 ++
modules/platforms/cpp/odbc/src/type_traits.cpp | 16 +-
modules/platforms/cpp/odbc/src/utility.cpp | 10 +
11 files changed, 838 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/core-test/src/cache_query_test.cpp b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
index 375b8b2..1630704 100644
--- a/modules/platforms/cpp/core-test/src/cache_query_test.cpp
+++ b/modules/platforms/cpp/core-test/src/cache_query_test.cpp
@@ -823,7 +823,7 @@ BOOST_AUTO_TEST_CASE(TestFieldsQueryExceptions)
CheckEmpty(cursor);
// Test simple query.
- cache.Put(1, QueryPerson("A1", 10));
+ cache.Put(1, QueryPerson("A1", 10, MakeDate(1990, 03, 18), MakeTimestamp(2016, 02, 10, 17, 39, 34, 579304685)));
cursor = cache.Query(qry);
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/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 632f05f..5a840ca 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
@@ -19,11 +19,14 @@
# define BOOST_TEST_DYN_LINK
#endif
+#include <ignite/odbc/system/odbc_constants.h>
+
#include <boost/test/unit_test.hpp>
#include <ignite/guid.h>
#include <ignite/odbc/decimal.h>
#include <ignite/odbc/app/application_data_buffer.h>
+#include <ignite/odbc/utility.h>
#define FLOAT_PRECISION 0.0000001f
@@ -32,6 +35,63 @@ using namespace ignite::odbc;
using namespace ignite::odbc::app;
using namespace ignite::odbc::type_traits;
+/**
+ * Make Date in human understandable way.
+ *
+ * @param year Year.
+ * @param month Month.
+ * @param day Day.
+ * @param hour Hour.
+ * @param min Min.
+ * @param sec Sec.
+ * @return Date.
+ */
+Date MakeDate(int year = 1900, int month = 1, int day = 1, int hour = 0,
+ int min = 0, int sec = 0)
+{
+ tm date;
+
+ date.tm_year = year - 1900;
+ date.tm_mon = month - 1;
+ date.tm_mday = day;
+ date.tm_hour = hour;
+ date.tm_min = min;
+ date.tm_sec = sec;
+
+ time_t ct = mktime(&date) - timezone;
+
+ return Date(ct * 1000);
+}
+
+/**
+ * Make Date in human understandable way.
+ *
+ * @param year Year.
+ * @param month Month.
+ * @param day Day.
+ * @param hour Hour.
+ * @param min Minute.
+ * @param sec Second.
+ * @param ns Nanosecond.
+ * @return Timestamp.
+ */
+Timestamp MakeTimestamp(int year = 1900, int month = 1, int day = 1,
+ int hour = 0, int min = 0, int sec = 0, long ns = 0)
+{
+ tm date;
+
+ date.tm_year = year - 1900;
+ date.tm_mon = month - 1;
+ date.tm_mday = day;
+ date.tm_hour = hour;
+ date.tm_min = min;
+ date.tm_sec = sec;
+
+ time_t ct = mktime(&date) - timezone;
+
+ return Timestamp(ct, ns);
+}
+
BOOST_AUTO_TEST_SUITE(ApplicationDataBufferTestSuite)
BOOST_AUTO_TEST_CASE(TestPutIntToString)
@@ -330,6 +390,119 @@ BOOST_AUTO_TEST_CASE(TestPutDecimalToString)
BOOST_REQUIRE(std::string(strBuf, reslen) == "-53.5");
}
+BOOST_AUTO_TEST_CASE(TestPutDateToString)
+{
+ char strBuf[64] = { 0 };
+ SqlLen reslen = 0;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_CHAR, &strBuf, sizeof(strBuf), &reslen, 0);
+
+ Date date = MakeDate(1999, 2, 22);
+
+ appBuf.PutDate(date);
+
+ BOOST_CHECK_EQUAL(std::string(strBuf, reslen), std::string("1999-02-22"));
+}
+
+BOOST_AUTO_TEST_CASE(TestPutTimestampToString)
+{
+ char strBuf[64] = { 0 };
+ SqlLen reslen = 0;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_CHAR, &strBuf, sizeof(strBuf), &reslen, 0);
+
+ Timestamp date = MakeTimestamp(2018, 11, 1, 17, 45, 59);
+
+ appBuf.PutTimestamp(date);
+
+ BOOST_CHECK_EQUAL(std::string(strBuf, reslen), std::string("2018-11-01 17:45:59"));
+}
+
+BOOST_AUTO_TEST_CASE(TestPutDateToDate)
+{
+ SQL_DATE_STRUCT buf = { 0 };
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_TDATE, &buf, sizeof(buf), &reslen, &offsetPtr);
+
+ Date date = MakeDate(1984, 5, 27);
+
+ appBuf.PutDate(date);
+
+ BOOST_CHECK_EQUAL(1984, buf.year);
+ BOOST_CHECK_EQUAL(5, buf.month);
+ BOOST_CHECK_EQUAL(27, buf.day);
+}
+
+BOOST_AUTO_TEST_CASE(TestPutTimestampToDate)
+{
+ SQL_DATE_STRUCT buf = { 0 };
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_TDATE, &buf, sizeof(buf), &reslen, &offsetPtr);
+
+ Timestamp ts = MakeTimestamp(2004, 8, 14, 6, 34, 51, 573948623);
+
+ appBuf.PutTimestamp(ts);
+
+ BOOST_CHECK_EQUAL(2004, buf.year);
+ BOOST_CHECK_EQUAL(8, buf.month);
+ BOOST_CHECK_EQUAL(14, buf.day);
+}
+
+BOOST_AUTO_TEST_CASE(TestPutTimestampToTimestamp)
+{
+ SQL_TIMESTAMP_STRUCT buf = { 0 };
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_TTIMESTAMP, &buf, sizeof(buf), &reslen, &offsetPtr);
+
+ Timestamp ts = MakeTimestamp(2004, 8, 14, 6, 34, 51, 573948623);
+
+ appBuf.PutTimestamp(ts);
+
+ BOOST_CHECK_EQUAL(2004, buf.year);
+ BOOST_CHECK_EQUAL(8, buf.month);
+ BOOST_CHECK_EQUAL(14, buf.day);
+ BOOST_CHECK_EQUAL(6, buf.hour);
+ BOOST_CHECK_EQUAL(34, buf.minute);
+ BOOST_CHECK_EQUAL(51, buf.second);
+ BOOST_CHECK_EQUAL(573948623, buf.fraction);
+}
+
+BOOST_AUTO_TEST_CASE(TestPutDateToTimestamp)
+{
+ SQL_TIMESTAMP_STRUCT buf = { 0 };
+
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_TTIMESTAMP, &buf, sizeof(buf), &reslen, &offsetPtr);
+
+ Date date = MakeDate(1984, 5, 27);
+
+ appBuf.PutDate(date);
+
+ BOOST_CHECK_EQUAL(1984, buf.year);
+ BOOST_CHECK_EQUAL(5, buf.month);
+ BOOST_CHECK_EQUAL(27, buf.day);
+ BOOST_CHECK_EQUAL(0, buf.hour);
+ BOOST_CHECK_EQUAL(0, buf.minute);
+ BOOST_CHECK_EQUAL(0, buf.second);
+ BOOST_CHECK_EQUAL(0, buf.fraction);
+}
+
BOOST_AUTO_TEST_CASE(TestGetStringFromLong)
{
long numBuf = 42;
@@ -627,4 +800,189 @@ BOOST_AUTO_TEST_CASE(TestSetStringWithOffset)
BOOST_REQUIRE(buf[1].reslen == strlen("Hello with offset!"));
}
+BOOST_AUTO_TEST_CASE(TestGetDateFromString)
+{
+ char buf[] = "1999-02-22";
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_CHAR, &buf[0], sizeof(buf), &reslen, &offsetPtr);
+
+ Date date = appBuf.GetDate();
+
+ time_t cTime = utility::DateToCTime(date);
+
+ tm *tmDate = gmtime(&cTime);
+
+ BOOST_REQUIRE(tmDate != 0);
+
+ BOOST_CHECK_EQUAL(1999, tmDate->tm_year + 1900);
+ BOOST_CHECK_EQUAL(2, tmDate->tm_mon + 1);
+ BOOST_CHECK_EQUAL(22, tmDate->tm_mday);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_hour);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_min);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_sec);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetTimestampFromString)
+{
+ char buf[] = "2018-11-01 17:45:59";
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_CHAR, &buf[0], sizeof(buf), &reslen, &offsetPtr);
+
+ Timestamp date = appBuf.GetTimestamp();
+
+ time_t cTime = utility::TimestampToCTime(date);
+
+ tm *tmDate = gmtime(&cTime);
+
+ BOOST_REQUIRE(tmDate != 0);
+
+ BOOST_CHECK_EQUAL(2018, tmDate->tm_year + 1900);
+ BOOST_CHECK_EQUAL(11, tmDate->tm_mon + 1);
+ BOOST_CHECK_EQUAL(1, tmDate->tm_mday);
+ BOOST_CHECK_EQUAL(17, tmDate->tm_hour);
+ BOOST_CHECK_EQUAL(45, tmDate->tm_min);
+ BOOST_CHECK_EQUAL(59, tmDate->tm_sec);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDateFromDate)
+{
+ SQL_DATE_STRUCT buf = { 0 };
+
+ buf.year = 1984;
+ buf.month = 5;
+ buf.day = 27;
+
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_TDATE, &buf, sizeof(buf), &reslen, &offsetPtr);
+
+ Date date = appBuf.GetDate();
+
+ time_t cTime = utility::DateToCTime(date);
+
+ tm *tmDate = gmtime(&cTime);
+
+ BOOST_REQUIRE(tmDate != 0);
+
+ BOOST_CHECK_EQUAL(1984, tmDate->tm_year + 1900);
+ BOOST_CHECK_EQUAL(5, tmDate->tm_mon + 1);
+ BOOST_CHECK_EQUAL(27, tmDate->tm_mday);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_hour);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_min);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_sec);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetTimestampFromDate)
+{
+ SQL_DATE_STRUCT buf = { 0 };
+
+ buf.year = 1984;
+ buf.month = 5;
+ buf.day = 27;
+
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_TDATE, &buf, sizeof(buf), &reslen, &offsetPtr);
+
+ Timestamp ts = appBuf.GetTimestamp();
+
+ time_t cTime = utility::TimestampToCTime(ts);
+
+ tm *tmDate = gmtime(&cTime);
+
+ BOOST_REQUIRE(tmDate != 0);
+
+ BOOST_CHECK_EQUAL(1984, tmDate->tm_year + 1900);
+ BOOST_CHECK_EQUAL(5, tmDate->tm_mon + 1);
+ BOOST_CHECK_EQUAL(27, tmDate->tm_mday);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_hour);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_min);
+ BOOST_CHECK_EQUAL(0, tmDate->tm_sec);
+}
+
+BOOST_AUTO_TEST_CASE(TestGetTimestampFromTimestamp)
+{
+ SQL_TIMESTAMP_STRUCT buf = { 0 };
+
+ buf.year = 2004;
+ buf.month = 8;
+ buf.day = 14;
+ buf.hour = 6;
+ buf.minute = 34;
+ buf.second = 51;
+ buf.fraction = 573948623;
+
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_TTIMESTAMP, &buf, sizeof(buf), &reslen, &offsetPtr);
+
+ Timestamp ts = appBuf.GetTimestamp();
+
+ time_t cTime = utility::TimestampToCTime(ts);
+
+ tm *tmDate = gmtime(&cTime);
+
+ BOOST_REQUIRE(tmDate != 0);
+
+ BOOST_CHECK_EQUAL(2004, tmDate->tm_year + 1900);
+ BOOST_CHECK_EQUAL(8, tmDate->tm_mon + 1);
+ BOOST_CHECK_EQUAL(14, tmDate->tm_mday);
+ BOOST_CHECK_EQUAL(6, tmDate->tm_hour);
+ BOOST_CHECK_EQUAL(34, tmDate->tm_min);
+ BOOST_CHECK_EQUAL(51, tmDate->tm_sec);
+ BOOST_CHECK_EQUAL(573948623, ts.GetSecondFraction());
+}
+
+BOOST_AUTO_TEST_CASE(TestGetDateFromTimestamp)
+{
+ SQL_TIMESTAMP_STRUCT buf = { 0 };
+
+ buf.year = 2004;
+ buf.month = 8;
+ buf.day = 14;
+ buf.hour = 6;
+ buf.minute = 34;
+ buf.second = 51;
+ buf.fraction = 573948623;
+
+ SqlLen reslen = sizeof(buf);
+
+ size_t offset = 0;
+ size_t* offsetPtr = &offset;
+
+ ApplicationDataBuffer appBuf(IGNITE_ODBC_C_TYPE_TTIMESTAMP, &buf, sizeof(buf), &reslen, &offsetPtr);
+
+ Date date = appBuf.GetDate();
+
+ time_t cTime = utility::DateToCTime(date);
+
+ tm *tmDate = gmtime(&cTime);
+
+ BOOST_REQUIRE(tmDate != 0);
+
+ BOOST_CHECK_EQUAL(2004, tmDate->tm_year + 1900);
+ BOOST_CHECK_EQUAL(8, tmDate->tm_mon + 1);
+ BOOST_CHECK_EQUAL(14, tmDate->tm_mday);
+ BOOST_CHECK_EQUAL(6, tmDate->tm_hour);
+ BOOST_CHECK_EQUAL(34, tmDate->tm_min);
+ BOOST_CHECK_EQUAL(51, tmDate->tm_sec);
+}
+
BOOST_AUTO_TEST_SUITE_END()
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/modules/platforms/cpp/odbc-test/src/parser_test.cpp
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc-test/src/parser_test.cpp b/modules/platforms/cpp/odbc-test/src/parser_test.cpp
index ad8a5b4..7c8a73d 100644
--- a/modules/platforms/cpp/odbc-test/src/parser_test.cpp
+++ b/modules/platforms/cpp/odbc-test/src/parser_test.cpp
@@ -72,21 +72,14 @@ BOOST_AUTO_TEST_CASE(TestParserEncodeDecode)
{
Parser parser;
- std::vector<int8_t> outBuffer;
- std::vector<int8_t> inBuffer;
+ std::vector<int8_t> buffer;
TestMessage outMsg(42, "Test message");
TestMessage inMsg;
- parser.Encode(outMsg, outBuffer);
+ parser.Encode(outMsg, buffer);
- inBuffer.reserve(outBuffer.size());
-
- // First 4 bytes contain message size after encoding but are not expected
- // during decoding.
- std::copy(outBuffer.begin() + 4, outBuffer.end(), std::back_inserter(inBuffer));
-
- parser.Decode(inMsg, inBuffer);
+ parser.Decode(inMsg, buffer);
BOOST_REQUIRE(outMsg == inMsg);
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/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 051f459..8a4e70d 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
@@ -23,6 +23,8 @@
#include <map>
#include <ignite/guid.h>
+#include <ignite/date.h>
+#include <ignite/timestamp.h>
#include "ignite/odbc/decimal.h"
#include "ignite/odbc/common_types.h"
@@ -165,6 +167,20 @@ namespace ignite
void PutDecimal(const Decimal& value);
/**
+ * Put date to buffer.
+ *
+ * @param value Value to put.
+ */
+ void PutDate(const Date& value);
+
+ /**
+ * Put timestamp to buffer.
+ *
+ * @param value Value to put.
+ */
+ void PutTimestamp(const Timestamp& value);
+
+ /**
* Get string.
*
* @return String value of buffer.
@@ -209,11 +225,25 @@ namespace ignite
/**
* Get value of type double.
*
- * @return Integer value of type double.
+ * @return Value of type double.
*/
double GetDouble() const;
/**
+ * Get value of type Date.
+ *
+ * @return Value of type Date.
+ */
+ Date GetDate() const;
+
+ /**
+ * Get value of type Timestamp.
+ *
+ * @return Value of type Timestamp.
+ */
+ Timestamp GetTimestamp() const;
+
+ /**
* Get raw data.
*
* @return Buffer data.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h
----------------------------------------------------------------------
diff --git a/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h b/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h
index 230a4ec..9d93018 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/type_traits.h
@@ -148,6 +148,9 @@ namespace ignite
/** DATE SQL type name constant. */
static const std::string DATE;
+ /** TIMESTAMP SQL type name constant. */
+ static const std::string TIMESTAMP;
+
/** GUID SQL type name constant. */
static const std::string GUID;
};
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/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 4a2e928..9efaba5 100644
--- a/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h
+++ b/modules/platforms/cpp/odbc/include/ignite/odbc/utility.h
@@ -18,13 +18,14 @@
#ifndef _IGNITE_ODBC_DRIVER_UTILITY
#define _IGNITE_ODBC_DRIVER_UTILITY
-#include <string>
-#include <stdint.h>
-
#ifdef min
# undef min
#endif //min
+#include <stdint.h>
+#include <ctime>
+
+#include <string>
#include <algorithm>
#include <ignite/common/utils.h>
@@ -165,6 +166,20 @@ namespace ignite
* @return Standard string containing the same data.
*/
std::string SqlStringToString(const unsigned char* sqlStr, int32_t sqlStrLen);
+
+ /**
+ * Convert Date type to standard C type time_t.
+ *
+ * @return Corresponding value of time_t.
+ */
+ time_t DateToCTime(const Date& date);
+
+ /**
+ * Convert Timestamp type to standard C type time_t.
+ *
+ * @return Corresponding value of time_t.
+ */
+ time_t TimestampToCTime(const Timestamp& ts);
}
}
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/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 e10011b..66c8831 100644
--- a/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp
+++ b/modules/platforms/cpp/odbc/src/app/application_data_buffer.cpp
@@ -191,6 +191,20 @@ namespace ignite
break;
}
+ case IGNITE_ODBC_C_TYPE_TDATE:
+ {
+ PutDate(Date(static_cast<int64_t>(value)));
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_TTIMESTAMP:
+ {
+ PutTimestamp(Timestamp(static_cast<int64_t>(value)));
+
+ break;
+ }
+
default:
{
if (GetResLen())
@@ -575,6 +589,228 @@ namespace ignite
}
}
+ void ApplicationDataBuffer::PutDate(const Date& value)
+ {
+ using namespace type_traits;
+
+ time_t time = utility::DateToCTime(value);
+
+ tm* tmTime = std::gmtime(&time);
+
+ switch (type)
+ {
+ case IGNITE_ODBC_C_TYPE_CHAR:
+ {
+ char* buffer = reinterpret_cast<char*>(GetData());
+
+ if (buffer)
+ {
+ strftime(buffer, GetSize(), "%Y-%m-%d", tmTime);
+
+ if (GetResLen())
+ *GetResLen() = strlen(buffer);
+ }
+ else if (GetResLen())
+ *GetResLen() = sizeof("HHHH-MM-DD");
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_WCHAR:
+ {
+ SQLWCHAR* buffer = reinterpret_cast<SQLWCHAR*>(GetData());
+
+ if (buffer)
+ {
+ std::string tmp(GetSize(), 0);
+
+ strftime(&tmp[0], GetSize(), "%Y-%m-%d", tmTime);
+
+ SqlLen toCopy = std::min(static_cast<SqlLen>(strlen(tmp.c_str()) + 1), GetSize());
+
+ for (SqlLen i = 0; i < toCopy; ++i)
+ buffer[i] = tmp[i];
+
+ buffer[toCopy] = 0;
+
+ if (GetResLen())
+ *GetResLen() = toCopy;
+ }
+ else if (GetResLen())
+ *GetResLen() = sizeof("HHHH-MM-DD");
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_TDATE:
+ {
+ SQL_DATE_STRUCT* buffer = reinterpret_cast<SQL_DATE_STRUCT*>(GetData());
+
+ buffer->year = tmTime->tm_year + 1900;
+ buffer->month = tmTime->tm_mon + 1;
+ buffer->day = tmTime->tm_mday;
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_TTIMESTAMP:
+ {
+ SQL_TIMESTAMP_STRUCT* buffer = reinterpret_cast<SQL_TIMESTAMP_STRUCT*>(GetData());
+
+ buffer->year = tmTime->tm_year + 1900;
+ buffer->month = tmTime->tm_mon + 1;
+ buffer->day = tmTime->tm_mday;
+ buffer->hour = tmTime->tm_hour;
+ buffer->minute = tmTime->tm_min;
+ buffer->second = tmTime->tm_sec;
+ buffer->fraction = 0;
+
+ break;
+ }
+
+ 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)));
+
+ if (GetResLen())
+ *GetResLen() = sizeof(value);
+
+ break;
+ }
+
+ 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_NUMERIC:
+ default:
+ {
+ if (GetResLen())
+ *GetResLen() = SQL_NO_TOTAL;
+ }
+ }
+ }
+
+ void ApplicationDataBuffer::PutTimestamp(const Timestamp& value)
+ {
+ using namespace type_traits;
+
+ time_t time = utility::TimestampToCTime(value);
+
+ tm* tmTime = std::gmtime(&time);
+
+ switch (type)
+ {
+ case IGNITE_ODBC_C_TYPE_CHAR:
+ {
+ char* buffer = reinterpret_cast<char*>(GetData());
+
+ if (buffer)
+ {
+ strftime(buffer, GetSize(), "%Y-%m-%d %H:%M:%S", tmTime);
+
+ if (GetResLen())
+ *GetResLen() = strlen(buffer);
+ }
+ else if (GetResLen())
+ *GetResLen() = sizeof("HHHH-MM-DD HH:MM:SS");
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_WCHAR:
+ {
+ SQLWCHAR* buffer = reinterpret_cast<SQLWCHAR*>(GetData());
+
+ if (buffer)
+ {
+ std::string tmp(GetSize(), 0);
+
+ strftime(&tmp[0], GetSize(), "%Y-%m-%d %H:%M:%S", tmTime);
+
+ SqlLen toCopy = std::min(static_cast<SqlLen>(strlen(tmp.c_str()) + 1), GetSize());
+
+ for (SqlLen i = 0; i < toCopy; ++i)
+ buffer[i] = tmp[i];
+
+ buffer[toCopy] = 0;
+
+ if (GetResLen())
+ *GetResLen() = toCopy;
+ }
+ else if (GetResLen())
+ *GetResLen() = sizeof("HHHH-MM-DD HH:MM:SS");
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_TDATE:
+ {
+ SQL_DATE_STRUCT* buffer = reinterpret_cast<SQL_DATE_STRUCT*>(GetData());
+
+ buffer->year = tmTime->tm_year + 1900;
+ buffer->month = tmTime->tm_mon + 1;
+ buffer->day = tmTime->tm_mday;
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_TTIMESTAMP:
+ {
+ SQL_TIMESTAMP_STRUCT* buffer = reinterpret_cast<SQL_TIMESTAMP_STRUCT*>(GetData());
+
+ buffer->year = tmTime->tm_year + 1900;
+ buffer->month = tmTime->tm_mon + 1;
+ buffer->day = tmTime->tm_mday;
+ buffer->hour = tmTime->tm_hour;
+ buffer->minute = tmTime->tm_min;
+ buffer->second = tmTime->tm_sec;
+ buffer->fraction = value.GetSecondFraction();
+
+ break;
+ }
+
+ 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)));
+
+ if (GetResLen())
+ *GetResLen() = sizeof(value);
+
+ break;
+ }
+
+ 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_NUMERIC:
+ default:
+ {
+ if (GetResLen())
+ *GetResLen() = SQL_NO_TOTAL;
+ }
+ }
+ }
+
std::string ApplicationDataBuffer::GetString(size_t maxLen) const
{
using namespace type_traits;
@@ -820,6 +1056,124 @@ namespace ignite
return res;
}
+ Date ApplicationDataBuffer::GetDate() const
+ {
+ using namespace type_traits;
+
+ tm tmTime = { 0 };
+
+ switch (type)
+ {
+ case IGNITE_ODBC_C_TYPE_TDATE:
+ {
+ const SQL_DATE_STRUCT* buffer = reinterpret_cast<const SQL_DATE_STRUCT*>(GetData());
+
+ tmTime.tm_year = buffer->year - 1900;
+ tmTime.tm_mon = buffer->month - 1;
+ tmTime.tm_mday = buffer->day;
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_TTIMESTAMP:
+ {
+ const SQL_TIMESTAMP_STRUCT* buffer = reinterpret_cast<const SQL_TIMESTAMP_STRUCT*>(GetData());
+
+ tmTime.tm_year = buffer->year - 1900;
+ tmTime.tm_mon = buffer->month - 1;
+ tmTime.tm_mday = buffer->day;
+ tmTime.tm_hour = buffer->hour;
+ tmTime.tm_min = buffer->minute;
+ tmTime.tm_sec = buffer->second;
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_CHAR:
+ {
+ std::string str = utility::SqlStringToString(
+ reinterpret_cast<const unsigned char*>(GetData()),
+ static_cast<int32_t>(GetSize()));
+
+ sscanf(str.c_str(), "%d-%d-%d %d:%d:%d", &tmTime.tm_year, &tmTime.tm_mon,
+ &tmTime.tm_mday, &tmTime.tm_hour, &tmTime.tm_min, &tmTime.tm_sec);
+
+ tmTime.tm_year = tmTime.tm_year - 1900;
+ tmTime.tm_mon = tmTime.tm_mon - 1;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ time_t cTime = mktime(&tmTime) - timezone;
+
+ return Date(cTime * 1000);
+ }
+
+ Timestamp ApplicationDataBuffer::GetTimestamp() const
+ {
+ using namespace type_traits;
+
+ tm tmTime = { 0 };
+
+ int32_t nanos = 0;
+
+ switch (type)
+ {
+ case IGNITE_ODBC_C_TYPE_TDATE:
+ {
+ const SQL_DATE_STRUCT* buffer = reinterpret_cast<const SQL_DATE_STRUCT*>(GetData());
+
+ tmTime.tm_year = buffer->year - 1900;
+ tmTime.tm_mon = buffer->month - 1;
+ tmTime.tm_mday = buffer->day;
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_TTIMESTAMP:
+ {
+ const SQL_TIMESTAMP_STRUCT* buffer = reinterpret_cast<const SQL_TIMESTAMP_STRUCT*>(GetData());
+
+ tmTime.tm_year = buffer->year - 1900;
+ tmTime.tm_mon = buffer->month - 1;
+ tmTime.tm_mday = buffer->day;
+ tmTime.tm_hour = buffer->hour;
+ tmTime.tm_min = buffer->minute;
+ tmTime.tm_sec = buffer->second;
+
+ nanos = buffer->fraction;
+
+ break;
+ }
+
+ case IGNITE_ODBC_C_TYPE_CHAR:
+ {
+ std::string str = utility::SqlStringToString(
+ reinterpret_cast<const unsigned char*>(GetData()),
+ static_cast<int32_t>(GetSize()));
+
+ sscanf(str.c_str(), "%d-%d-%d %d:%d:%d", &tmTime.tm_year, &tmTime.tm_mon,
+ &tmTime.tm_mday, &tmTime.tm_hour, &tmTime.tm_min, &tmTime.tm_sec);
+
+ tmTime.tm_year = tmTime.tm_year - 1900;
+ tmTime.tm_mon = tmTime.tm_mon - 1;
+
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ time_t cTime = mktime(&tmTime) - timezone;
+
+ return Timestamp(cTime, nanos);
+ }
+
template<typename T>
T* ApplicationDataBuffer::ApplyOffset(T* ptr) const
{
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/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 dbe33e1..26570c4 100644
--- a/modules/platforms/cpp/odbc/src/app/parameter.cpp
+++ b/modules/platforms/cpp/odbc/src/app/parameter.cpp
@@ -121,6 +121,18 @@ namespace ignite
break;
}
+ case SQL_DATE:
+ {
+ writer.WriteDate(buffer.GetDate());
+ break;
+ }
+
+ case SQL_TIMESTAMP:
+ {
+ writer.WriteTimestamp(buffer.GetTimestamp());
+ break;
+ }
+
case SQL_BINARY:
case SQL_VARBINARY:
case SQL_LONGVARBINARY:
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/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 7b2f1e9..61a55ca 100644
--- a/modules/platforms/cpp/odbc/src/column.cpp
+++ b/modules/platforms/cpp/odbc/src/column.cpp
@@ -264,6 +264,23 @@ namespace ignite
}
case IGNITE_TYPE_DATE:
+ {
+ reader.ReadDate();
+
+ sizeTmp = 8;
+
+ break;
+ }
+
+ case IGNITE_TYPE_TIMESTAMP:
+ {
+ reader.ReadTimestamp();
+
+ sizeTmp = 12;
+
+ break;
+ }
+
default:
{
// This is a fail case.
@@ -432,6 +449,23 @@ namespace ignite
}
case IGNITE_TYPE_DATE:
+ {
+ Date date = reader.ReadDate();
+
+ dataBuf.PutDate(date);
+
+ break;
+ }
+
+ case IGNITE_TYPE_TIMESTAMP:
+ {
+ Timestamp ts = reader.ReadTimestamp();
+
+ dataBuf.PutTimestamp(ts);
+
+ break;
+ }
+
default:
{
// This is a fail case. Return false.
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/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 03e525f..fced2e1 100644
--- a/modules/platforms/cpp/odbc/src/type_traits.cpp
+++ b/modules/platforms/cpp/odbc/src/type_traits.cpp
@@ -57,6 +57,8 @@ namespace ignite
const std::string SqlTypeName::DATE("DATE");
+ const std::string SqlTypeName::TIMESTAMP("TIMESTAMP");
+
const std::string SqlTypeName::GUID("GUID");
#ifdef ODBC_DEBUG
@@ -149,6 +151,9 @@ namespace ignite
case IGNITE_TYPE_DATE:
return SqlTypeName::DATE;
+ case IGNITE_TYPE_TIMESTAMP:
+ return SqlTypeName::TIMESTAMP;
+
case IGNITE_TYPE_OBJECT:
case IGNITE_TYPE_ARRAY_BYTE:
case IGNITE_TYPE_ARRAY_SHORT:
@@ -162,6 +167,7 @@ namespace ignite
case IGNITE_TYPE_ARRAY_STRING:
case IGNITE_TYPE_ARRAY_UUID:
case IGNITE_TYPE_ARRAY_DATE:
+ case IGNITE_TYPE_ARRAY_TIMESTAMP:
case IGNITE_TYPE_ARRAY:
case IGNITE_TYPE_COLLECTION:
case IGNITE_TYPE_MAP:
@@ -198,6 +204,8 @@ namespace ignite
case SQL_LONGVARBINARY:
case SQL_GUID:
case SQL_DECIMAL:
+ case SQL_TYPE_DATE:
+ case SQL_TYPE_TIMESTAMP:
return true;
case SQL_WCHAR:
@@ -205,9 +213,7 @@ namespace ignite
case SQL_WLONGVARCHAR:
case SQL_REAL:
case SQL_NUMERIC:
- case SQL_TYPE_DATE:
case SQL_TYPE_TIME:
- case SQL_TYPE_TIMESTAMP:
case SQL_INTERVAL_MONTH:
case SQL_INTERVAL_YEAR:
case SQL_INTERVAL_YEAR_TO_MONTH:
@@ -272,6 +278,9 @@ namespace ignite
case SQL_TYPE_DATE:
return IGNITE_TYPE_DATE;
+ case SQL_TYPE_TIMESTAMP:
+ return IGNITE_TYPE_TIMESTAMP;
+
default:
break;
}
@@ -387,6 +396,9 @@ namespace ignite
case IGNITE_TYPE_DATE:
return SQL_TYPE_DATE;
+ case IGNITE_TYPE_TIMESTAMP:
+ return SQL_TYPE_TIMESTAMP;
+
case IGNITE_TYPE_ARRAY_BYTE:
case IGNITE_TYPE_ARRAY_SHORT:
case IGNITE_TYPE_ARRAY_INT:
http://git-wip-us.apache.org/repos/asf/ignite/blob/3c52e63b/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 6f4ac22..1c88e7a 100644
--- a/modules/platforms/cpp/odbc/src/utility.cpp
+++ b/modules/platforms/cpp/odbc/src/utility.cpp
@@ -100,6 +100,16 @@ namespace ignite
return res;
}
+
+ time_t DateToCTime(const Date& date)
+ {
+ return static_cast<time_t>(date.GetSeconds());
+ }
+
+ time_t TimestampToCTime(const Timestamp& ts)
+ {
+ return static_cast<time_t>(ts.GetSeconds());
+ }
}
}