2017-02-18 12:05:48 +01:00
|
|
|
|
#include "Pgsql_Value.h"
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
|
|
|
|
using namespace Pgsql;
|
|
|
|
|
|
|
|
|
|
|
|
Value::Value(const char *val, Oid typ)
|
2017-12-09 10:45:13 +01:00
|
|
|
|
: m_val(val)
|
|
|
|
|
|
, m_typ(typ)
|
2017-02-18 12:05:48 +01:00
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
|
|
QString Value::asQString() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return QString::fromUtf8(m_val);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Value::operator QString() const
|
|
|
|
|
|
{
|
2017-12-09 10:45:13 +01:00
|
|
|
|
// if (isString())
|
|
|
|
|
|
return QString::fromUtf8(m_val);
|
|
|
|
|
|
// else
|
|
|
|
|
|
// throw std::logic_error("Column type doesn't match requested type");
|
2017-02-18 12:05:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Value::operator QDateTime() const
|
|
|
|
|
|
{
|
2017-12-09 10:45:13 +01:00
|
|
|
|
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
|
|
|
|
|
|
{
|
2022-02-06 14:15:16 +01:00
|
|
|
|
// 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);
|
2017-02-18 12:05:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-09 10:45:13 +01:00
|
|
|
|
|
2017-02-18 12:05:48 +01:00
|
|
|
|
Value::operator std::string() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_val;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-17 09:06:18 +01:00
|
|
|
|
Value::operator int16_t() const
|
2017-02-18 12:05:48 +01:00
|
|
|
|
{
|
2021-03-10 19:06:40 +01:00
|
|
|
|
if (m_val == nullptr)
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
int32_t r = operator int32_t();
|
2017-12-17 09:06:18 +01:00
|
|
|
|
if (r <= std::numeric_limits<int16_t>::max()
|
|
|
|
|
|
&& r >= std::numeric_limits<int16_t>::min())
|
|
|
|
|
|
return int16_t(r);
|
|
|
|
|
|
|
|
|
|
|
|
throw std::runtime_error("Value conversion to int16_t failed (out of range)");
|
2017-02-18 12:05:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-17 09:06:18 +01:00
|
|
|
|
Value::operator int32_t() const
|
2017-02-18 12:05:48 +01:00
|
|
|
|
{
|
2021-03-10 19:06:40 +01:00
|
|
|
|
if (m_val == nullptr)
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
|
|
const size_t len = std::strlen(m_val);
|
2017-12-17 09:06:18 +01:00
|
|
|
|
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");
|
2017-02-18 12:05:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Value::operator Oid() const
|
|
|
|
|
|
{
|
2017-12-17 09:06:18 +01:00
|
|
|
|
return operator int32_t();
|
2017-02-18 12:05:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-17 09:06:18 +01:00
|
|
|
|
Value::operator int64_t() const
|
2017-02-18 12:05:48 +01:00
|
|
|
|
{
|
2021-03-10 19:06:40 +01:00
|
|
|
|
if (m_val == nullptr)
|
|
|
|
|
|
return 0LL;
|
|
|
|
|
|
|
2025-02-23 16:52:39 +01:00
|
|
|
|
const size_t len = std::strlen(m_val);
|
2017-12-17 09:06:18 +01:00
|
|
|
|
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");
|
2017-02-18 12:05:48 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Value::operator bool() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return std::strcmp(m_val, "t") == 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-10 10:35:46 +01:00
|
|
|
|
Value::operator float() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return std::stof(m_val);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Value::operator double() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return std::stod(m_val);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-10-07 19:40:06 +02:00
|
|
|
|
Value::operator char() const
|
|
|
|
|
|
{
|
|
|
|
|
|
return m_val[0];
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-12-10 10:35:46 +01:00
|
|
|
|
|
2017-12-09 10:45:13 +01:00
|
|
|
|
bool Value::isString() const
|
|
|
|
|
|
{
|
2018-09-09 18:52:32 +02:00
|
|
|
|
return m_typ == char_oid
|
|
|
|
|
|
|| m_typ == varchar_oid
|
|
|
|
|
|
|| m_typ == text_oid
|
2017-12-09 10:45:13 +01:00
|
|
|
|
;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-08-22 12:45:45 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//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;
|
|
|
|
|
|
//}
|