#include "Pgsql_Value.h" #include #include using namespace Pgsql; Value::Value(const char *val, Oid typ) : m_val(val) , m_typ(typ) {} QString Value::asQString() const { return QString::fromUtf8(m_val); } Value::operator QString() const { // if (isString()) return QString::fromUtf8(m_val); // else // throw std::logic_error("Column type doesn't match requested type"); } Value::operator QDateTime() const { return QDateTime::fromString(asQString(), Qt::ISODateWithMs); // return QDateTime::fromString(asQString(), // "yyyy-MM-dd hh:mm:ss"); } Value::operator QDate() const { return QDate::fromString(asQString(), Qt::ISODate); } Value::operator QTime() const { // as values are expected to be coming straight out of postgresql // we will not validate everything char* pos; int hours = std::strtol(m_val, &pos, 10); if (*pos == ':') ++pos; else throw std::runtime_error("Unpexted character after hour in input"); int minutes = std::strtol(pos, &pos, 10); if (*pos == ':') ++pos; else throw std::runtime_error("Unpexted character after minutes in input"); int seconds = std::strtol(pos, &pos, 10); int millis = 0; if (*pos == '.') { const char *start = ++pos; millis = std::strtol(pos, &pos, 10); int length = pos - start; switch (length) { case 0: break; // should be zero anyway so no reason to multiply by 1000 case 1: millis *= 100; break; case 2: millis *= 10; break; case 3: break; case 4: millis = (millis + 5) / 10; break; case 5: millis = (millis + 50) / 100; break; case 6: millis = (millis + 500) / 1000; break; default: throw std::runtime_error("Unpexted number of digits in microsecond field"); } } int tzhours = 0, tzminutes = 0; if (*pos == '+' || *pos == '-') { ++pos; tzhours = std::strtol(pos, &pos, 10); if (*pos == ':') { tzminutes = std::strtol(pos, &pos, 10); } // TODO QTime does not support timezones (and rightly so as they are meaningless without a date) // the postgresql documentation actually agrees with this but supports timezones to not break // compatability with older verions } return QTime(hours, minutes, seconds, millis); } Value::operator std::string() const { return m_val; } Value::operator int16_t() const { if (m_val == nullptr) return 0; int32_t r = operator int32_t(); if (r <= std::numeric_limits::max() && r >= std::numeric_limits::min()) return int16_t(r); throw std::runtime_error("Value conversion to int16_t failed (out of range)"); } Value::operator int32_t() const { if (m_val == nullptr) return 0; const size_t len = std::strlen(m_val); if (len > 0) { char *endptr = nullptr; long result = std::strtol(m_val, &endptr, 10); if (endptr == m_val + len) return result; } throw std::runtime_error("Value conversion to int32_t failed"); } Value::operator Oid() const { return operator int32_t(); } Value::operator int64_t() const { if (m_val == nullptr) return 0LL; const size_t len = std::strlen(m_val); if (len > 0) { char *endptr = nullptr; int64_t result = std::strtoll(m_val, &endptr, 10); if (endptr == m_val + len) return result; } throw std::runtime_error("Value conversion to int64_t failed"); } Value::operator bool() const { return std::strcmp(m_val, "t") == 0; } Value::operator float() const { return std::stof(m_val); } Value::operator double() const { return std::stod(m_val); } Value::operator char() const { return m_val[0]; } bool Value::isString() const { return m_typ == char_oid || m_typ == varchar_oid || m_typ == text_oid ; } //void operator<<(QString &s, const Value &v) //{ // s = v.asQString(); //} //void operator<<(QDateTime &l, const Value &v) //{ // l = QDateTime::fromString(asQString(), // "yyyy-MM-dd hh:mm:ss"); //} //void operator<<(std::string &l, const Value &v) //{ // l = v; //} //void operator<<(short &l, const Value &v) //{ // l = (short)std::atoi(v.c_str()); //} //void operator<<(int &l, const Value &v) //{ // l = std::atoi(v.c_str()); //} //void Pgsql::operator<<(Oid &l, const Value &v) //{ // l = std::atoi(v.c_str()); //} //void operator<<(__int64 &l, const Value &v) //{ // l = std::strtoull(v.c_str(), nullptr, 10); //} //void operator<<(bool &l, const Value &v) //{ // l = std::strcmp(v.c_str(), "t") == 0; //}