From 1b6aaca3c5eb7e58ebc54242cb76ebe712e2821a 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 --- libpqpp/column.cpp | 31 +++++++++++++++++++------------ libpqpp/command.cpp | 19 +++++++++++-------- libpqpp/command.h | 4 ++-- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/libpqpp/column.cpp b/libpqpp/column.cpp index 90858c8..1f7b932 100644 --- a/libpqpp/column.cpp +++ b/libpqpp/column.cpp @@ -2,6 +2,7 @@ #include "selectcommand.h" #include "error.h" #include +#include PQ::Column::Column(const SelectCommand * s, unsigned int i) : DB::Column(PQfname(s->execRes, i), i), @@ -23,7 +24,6 @@ PQ::Column::apply(DB::HandleField & h) const h.null(); return; } - struct tm tm; switch (oid) { case 18: //CHAROID: case 1043: //VARCHAROID: @@ -44,21 +44,28 @@ PQ::Column::apply(DB::HandleField & h) const case 701: //FLOAT8OID: h.floatingpoint(atof(PQgetvalue(sc->execRes, sc->tuple, colNo))); break; + case 704: //TINTERVALOID case 1083: //TIMEOID: - memset(&tm, 0, sizeof(tm)); - strptime(PQgetvalue(sc->execRes, sc->tuple, colNo), "%T", &tm); - h.timestamp(tm); - break; - case 1082: //DATEOID: - memset(&tm, 0, sizeof(tm)); - strptime(PQgetvalue(sc->execRes, sc->tuple, colNo), "%F", &tm); - h.timestamp(tm); - break; + case 1186: //INTERVALOID + { + int days = 0, hours = 0, minutes = 0, seconds = 0, fractions = 0, flen1 = 0, flen2 = 0; + const char * val = PQgetvalue(sc->execRes, sc->tuple, colNo); + if (sscanf(val, "%d days %d:%d:%d.%n%d%n", &days, &hours, &minutes, &seconds, &flen1, &fractions, &flen2) >= 4) { + h.interval(boost::posix_time::time_duration((24 * days) + hours, minutes, seconds, fractions * pow(10, boost::posix_time::time_res_traits::num_fractional_digits() + flen1 - flen2))); + } + else if (sscanf(val, "%d day %d:%d:%d.%n%d%n", &days, &hours, &minutes, &seconds, &flen1, &fractions, &flen2) >= 4) { + h.interval(boost::posix_time::time_duration((24 * days) + hours, minutes, seconds, fractions * pow(10, boost::posix_time::time_res_traits::num_fractional_digits() + flen1 - flen2))); + } + else { + h.interval(boost::posix_time::duration_from_string(PQgetvalue(sc->execRes, sc->tuple, colNo))); + } + break; + } case 702: //ABSTIMEOID: + case 1082: //DATEOID: case 1114: //TIMESTAMPOID: case 1184: //TIMESTAMPTZOID: - strptime(PQgetvalue(sc->execRes, sc->tuple, colNo), "%F %T", &tm); - h.timestamp(tm); + h.timestamp(boost::posix_time::time_from_string(PQgetvalue(sc->execRes, sc->tuple, colNo))); break; default: h.string(PQgetvalue(sc->execRes, sc->tuple, colNo), PQgetlength(sc->execRes, sc->tuple, colNo)); diff --git a/libpqpp/command.cpp b/libpqpp/command.cpp index b901310..abd37e6 100644 --- a/libpqpp/command.cpp +++ b/libpqpp/command.cpp @@ -2,6 +2,7 @@ #include "connection.h" #include #include +#include static std::string addrStr(void * p, unsigned int no) { std::string r(50, ' '); @@ -102,20 +103,22 @@ PQ::Command::bindParamS(unsigned int n, const Glib::ustring & s) lengths[n] = s.bytes(); } void -PQ::Command::bindParamT(unsigned int n, const tm * v) +PQ::Command::bindParamT(unsigned int n, const boost::posix_time::time_duration & v) { paramsAtLeast(n); - values[n] = static_cast(malloc(20)); + auto buf = boost::posix_time::to_simple_string(v); + values[n] = strdup(buf.c_str()); formats[n] = 0; - strftime(values[n], 20, "%F %T", v); - lengths[n] = 19; + lengths[n] = buf.length(); } void -PQ::Command::bindParamT(unsigned int n, time_t v) +PQ::Command::bindParamT(unsigned int n, const boost::posix_time::ptime & v) { - struct tm t; - gmtime_r(&v, &t); - bindParamT(n, &t); + paramsAtLeast(n); + auto buf = boost::posix_time::to_iso_extended_string(v); + values[n] = strdup(buf.c_str()); + formats[n] = 0; + lengths[n] = buf.length(); } void PQ::Command::bindNull(unsigned int n) diff --git a/libpqpp/command.h b/libpqpp/command.h index 3fb6e24..e78722b 100644 --- a/libpqpp/command.h +++ b/libpqpp/command.h @@ -24,8 +24,8 @@ namespace PQ { void bindParamS(unsigned int, const Glib::ustring&); - void bindParamT(unsigned int, const tm*); - void bindParamT(unsigned int, time_t); + void bindParamT(unsigned int, const boost::posix_time::time_duration &); + void bindParamT(unsigned int, const boost::posix_time::ptime &); void bindNull(unsigned int); protected: -- cgit v1.2.3