From e267def4f9f2e47402d72b56a45924f0bd2c0a18 Mon Sep 17 00:00:00 2001 From: randomdan Date: Mon, 3 Mar 2014 20:57:27 +0000 Subject: Adds native support for time_duration as a variable type Pass/retrieve boost::posix_time ptime and time_duration into/out of the db tier --- libodbcpp/bind.h | 3 --- libodbcpp/column.cpp | 37 +++++++++++++++---------------------- libodbcpp/column.h | 15 +++++++++++++-- libodbcpp/command.h | 5 ++--- libodbcpp/param.cpp | 29 ++++++++++++++++++++++------- libodbcpp/param.h | 20 ++++++++++++++++---- libodbcpp/selectcommand.cpp | 17 ++++++++++++++++- 7 files changed, 84 insertions(+), 42 deletions(-) (limited to 'libodbcpp') diff --git a/libodbcpp/bind.h b/libodbcpp/bind.h index c256b2b..356723b 100644 --- a/libodbcpp/bind.h +++ b/libodbcpp/bind.h @@ -17,8 +17,5 @@ namespace ODBC { }; } -void operator << (SQL_TIMESTAMP_STRUCT & target, const struct tm &); -void operator << (struct tm &, const SQL_TIMESTAMP_STRUCT & target); - #endif diff --git a/libodbcpp/column.cpp b/libodbcpp/column.cpp index 9ff6d8d..da31ed0 100644 --- a/libodbcpp/column.cpp +++ b/libodbcpp/column.cpp @@ -61,32 +61,19 @@ ODBC::Column::bind() } } -ODBC::TimeStampColumn::operator struct tm() const +ODBC::TimeStampColumn::operator boost::posix_time::ptime() const { - struct tm t; - t << data; - return t; + return boost::posix_time::ptime( + boost::gregorian::date(data.year, data.month, data.day), + boost::posix_time::time_duration(data.hour, data.minute, data.second, data.fraction)); } -void operator << (SQL_TIMESTAMP_STRUCT & target, const struct tm & src) +ODBC::IntervalColumn::operator boost::posix_time::time_duration() const { - target.year = src.tm_year + 1900; - target.month = src.tm_mon + 1; - target.day = src.tm_mday; - target.hour = src.tm_hour; - target.minute = src.tm_min; - target.second = src.tm_sec; - target.fraction = 0; + auto dur = boost::posix_time::time_duration( + (24 * data.intval.day_second.day) + data.intval.day_second.hour, + data.intval.day_second.minute, data.intval.day_second.second, data.intval.day_second.fraction); + return (data.interval_sign ? -dur : dur); } -void operator << (struct tm & target, const SQL_TIMESTAMP_STRUCT & src) -{ - target.tm_year = src.year - 1900; - target.tm_mon = src.month - 1; - target.tm_mday = src.day; - target.tm_hour = src.hour; - target.tm_min = src.minute; - target.tm_sec = src.second; -} - void ODBC::SignedIntegerColumn::apply(DB::HandleField & h) const { @@ -111,3 +98,9 @@ ODBC::TimeStampColumn::apply(DB::HandleField & h) const if (isNull()) return h.null(); h.timestamp(*this); } +void +ODBC::IntervalColumn::apply(DB::HandleField & h) const +{ + if (isNull()) return h.null(); + h.interval(*this); +} diff --git a/libodbcpp/column.h b/libodbcpp/column.h index e981a14..f973577 100644 --- a/libodbcpp/column.h +++ b/libodbcpp/column.h @@ -101,6 +101,18 @@ namespace ODBC { virtual const Param * meAsAParam() const { return this; } virtual void apply(DB::HandleField &) const; }; + class IntervalColumn : public Column, public IntervalParam { + public: + IntervalColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : + DB::Column(n, i), + Column(sc, n, i) { } + virtual SQLSMALLINT ctype() const { return IntervalParam::ctype(); } + virtual SQLULEN size() const { return IntervalParam::size(); } + virtual void * rwDataAddress() { return &data; } + virtual operator boost::posix_time::time_duration () const; + virtual const Param * meAsAParam() const { return this; } + virtual void apply(DB::HandleField &) const; + }; class TimeStampColumn : public Column, public TimeStampParam { public: TimeStampColumn(SelectCommand * sc, const Glib::ustring & n, unsigned int i) : @@ -109,8 +121,7 @@ namespace ODBC { virtual SQLSMALLINT ctype() const { return TimeStampParam::ctype(); } virtual SQLULEN size() const { return TimeStampParam::size(); } virtual void * rwDataAddress() { return &data; } - virtual operator struct tm () const; - virtual operator SQL_TIMESTAMP_STRUCT () const { return data; } + virtual operator boost::posix_time::ptime () const; virtual const Param * meAsAParam() const { return this; } virtual void apply(DB::HandleField &) const; }; diff --git a/libodbcpp/command.h b/libodbcpp/command.h index fdabe4a..02347cf 100644 --- a/libodbcpp/command.h +++ b/libodbcpp/command.h @@ -26,9 +26,8 @@ namespace ODBC { void bindParamS(unsigned int i, const Glib::ustring &); - void bindParamT(unsigned int i, const struct tm *); - void bindParamT(unsigned int i, const SQL_TIMESTAMP_STRUCT &); - void bindParamT(unsigned int i, time_t); + void bindParamT(unsigned int i, const boost::posix_time::time_duration &); + void bindParamT(unsigned int i, const boost::posix_time::ptime &); void bindNull(unsigned int i); diff --git a/libodbcpp/param.cpp b/libodbcpp/param.cpp index 466892c..8e30f14 100644 --- a/libodbcpp/param.cpp +++ b/libodbcpp/param.cpp @@ -74,9 +74,8 @@ SIMPLEBINDER(float, FloatingPointParam, F); SIMPLEBINDER(const Glib::ustring &, GlibUstringParam, S); -SIMPLEBINDER(const struct tm *, TimeStampParam, T); -SIMPLEBINDER(const SQL_TIMESTAMP_STRUCT &, TimeStampParam, T); -SIMPLEBINDER(time_t, TimeStampParam, T); +SIMPLEBINDER(const boost::posix_time::ptime &, TimeStampParam, T); +SIMPLEBINDER(const boost::posix_time::time_duration &, IntervalParam, T); void ODBC::Command::bindNull(unsigned int i) @@ -98,10 +97,26 @@ ODBC::GlibUstringParam::operator=(Glib::ustring const & d) } void -ODBC::TimeStampParam::operator=(time_t const & d) +ODBC::TimeStampParam::operator=(const boost::posix_time::ptime & d) { - struct tm t; - gmtime_r(&d, &t); - data << t; + data.year = d.date().year(); + data.month = d.date().month(); + data.day = d.date().day(); + data.hour = d.time_of_day().hours(); + data.minute = d.time_of_day().minutes(); + data.second = d.time_of_day().seconds(); + data.fraction = d.time_of_day().fractional_seconds(); +} + +void +ODBC::IntervalParam::operator=(const boost::posix_time::time_duration & d) +{ + data.interval_type = SQL_IS_DAY_TO_SECOND; + data.interval_sign = d.is_negative(); + data.intval.day_second.day = d.hours() / 24; + data.intval.day_second.hour = d.hours() % 24; + data.intval.day_second.minute = d.minutes(); + data.intval.day_second.second = d.seconds(); + data.intval.day_second.fraction = d.fractional_seconds(); } diff --git a/libodbcpp/param.h b/libodbcpp/param.h index 661d9b3..37f8d5a 100644 --- a/libodbcpp/param.h +++ b/libodbcpp/param.h @@ -5,6 +5,7 @@ #include #include #include "bind.h" +#include namespace ODBC { class Command; @@ -79,6 +80,19 @@ namespace ODBC { protected: Glib::ustring data; }; + class IntervalParam : public Param { + public: + IntervalParam() : Param() { } + IntervalParam(Command * c, unsigned int i) : Param(c, i) { bindLen = size(); } + virtual SQLSMALLINT ctype() const { return SQL_C_INTERVAL_DAY_TO_SECOND; } + virtual SQLSMALLINT stype() const { return SQL_INTERVAL; } + virtual SQLULEN size() const { return sizeof(SQL_INTERVAL); } + virtual SQLINTEGER dp() const { return boost::posix_time::time_res_traits::num_fractional_digits(); } + virtual const void * dataAddress() const { return &data; } + void operator=(const boost::posix_time::time_duration & d); + protected: + SQL_INTERVAL_STRUCT data; + }; class TimeStampParam : public Param { public: TimeStampParam() : Param() { } @@ -86,11 +100,9 @@ namespace ODBC { virtual SQLSMALLINT ctype() const { return SQL_C_TYPE_TIMESTAMP; } virtual SQLSMALLINT stype() const { return SQL_TYPE_TIMESTAMP; } virtual SQLULEN size() const { return sizeof(SQL_TIMESTAMP_STRUCT); } - virtual SQLINTEGER dp() const { return 0; } + virtual SQLINTEGER dp() const { return boost::posix_time::time_res_traits::num_fractional_digits(); } virtual const void * dataAddress() const { return &data; } - void operator=(const time_t & d); - void operator=(const struct tm * d) { data << *d; } - void operator=(const SQL_TIMESTAMP_STRUCT & d) { data = d; } + void operator=(const boost::posix_time::ptime & d); protected: SQL_TIMESTAMP_STRUCT data; }; diff --git a/libodbcpp/selectcommand.cpp b/libodbcpp/selectcommand.cpp index 5f87a5a..d53a487 100644 --- a/libodbcpp/selectcommand.cpp +++ b/libodbcpp/selectcommand.cpp @@ -113,9 +113,24 @@ ODBC::SelectCommand::execute() case SQL_BIGINT: columns[col] = new SignedIntegerColumn(this, colName, col); break; + case SQL_TYPE_TIME: + case SQL_INTERVAL_YEAR: + case SQL_INTERVAL_MONTH: + case SQL_INTERVAL_DAY: + case SQL_INTERVAL_HOUR: + case SQL_INTERVAL_MINUTE: + case SQL_INTERVAL_SECOND: + case SQL_INTERVAL_YEAR_TO_MONTH: + case SQL_INTERVAL_DAY_TO_HOUR: + case SQL_INTERVAL_DAY_TO_MINUTE: + case SQL_INTERVAL_DAY_TO_SECOND: + case SQL_INTERVAL_HOUR_TO_MINUTE: + case SQL_INTERVAL_HOUR_TO_SECOND: + case SQL_INTERVAL_MINUTE_TO_SECOND: + columns[col] = new IntervalColumn(this, colName, col); + break; case SQL_TIMESTAMP: case SQL_DATETIME: - case SQL_TYPE_TIME: case SQL_TYPE_DATE: case SQL_TYPE_TIMESTAMP: columns[col] = new TimeStampColumn(this, colName, col); -- cgit v1.2.3