added test for date and time, sql read and write functionality
This commit is contained in:
parent
0c6b5a0a93
commit
c48bd4f9d6
|
|
@ -9,8 +9,7 @@ namespace matador::backends::postgres {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
class empty_binder final : public utils::attribute_reader
|
class empty_binder final : public utils::attribute_reader {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
void read_value(const char *, size_t, int8_t &) override {}
|
void read_value(const char *, size_t, int8_t &) override {}
|
||||||
void read_value(const char *, size_t, int16_t &) override {}
|
void read_value(const char *, size_t, int16_t &) override {}
|
||||||
|
|
@ -23,8 +22,9 @@ public:
|
||||||
void read_value(const char *, size_t, bool &) override {}
|
void read_value(const char *, size_t, bool &) override {}
|
||||||
void read_value(const char *, size_t, float &) override {}
|
void read_value(const char *, size_t, float &) override {}
|
||||||
void read_value(const char *, size_t, double &) override {}
|
void read_value(const char *, size_t, double &) override {}
|
||||||
void read_value(const char *, size_t, time &) override {}
|
void read_value(const char *, size_t, utils::date_type_t &) override {}
|
||||||
void read_value(const char *, size_t, date &) override {}
|
void read_value(const char *, size_t, utils::time_type_t &) override {}
|
||||||
|
void read_value(const char *, size_t, utils::timestamp &) override {}
|
||||||
void read_value(const char *, size_t, char *, size_t) override {}
|
void read_value(const char *, size_t, char *, size_t) override {}
|
||||||
void read_value(const char *, size_t, std::string &) override {}
|
void read_value(const char *, size_t, std::string &) override {}
|
||||||
void read_value(const char *, size_t, std::string &, size_t) override {}
|
void read_value(const char *, size_t, std::string &, size_t) override {}
|
||||||
|
|
@ -34,8 +34,7 @@ public:
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class postgres_result_reader final : public sql::query_result_reader
|
class postgres_result_reader final : public sql::query_result_reader {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit postgres_result_reader(PGresult *result);
|
explicit postgres_result_reader(PGresult *result);
|
||||||
~postgres_result_reader() override;
|
~postgres_result_reader() override;
|
||||||
|
|
@ -57,8 +56,9 @@ public:
|
||||||
void read_value(const char *id, size_t index, bool &value) override;
|
void read_value(const char *id, size_t index, bool &value) override;
|
||||||
void read_value(const char *id, size_t index, float &value) override;
|
void read_value(const char *id, size_t index, float &value) override;
|
||||||
void read_value(const char *id, size_t index, double &value) override;
|
void read_value(const char *id, size_t index, double &value) override;
|
||||||
void read_value(const char *id, size_t index, matador::time &value) override;
|
void read_value(const char *id, size_t index, utils::date_type_t &) override;
|
||||||
void read_value(const char *id, size_t index, matador::date &value) override;
|
void read_value(const char *id, size_t index, utils::time_type_t &) override;
|
||||||
|
void read_value(const char *id, size_t index, utils::timestamp &) override;
|
||||||
void read_value(const char *id, size_t index, char *value, size_t size) override;
|
void read_value(const char *id, size_t index, char *value, size_t size) override;
|
||||||
void read_value(const char *id, size_t index, std::string &value) override;
|
void read_value(const char *id, size_t index, std::string &value) override;
|
||||||
void read_value(const char *id, size_t index, std::string &value, size_t size) override;
|
void read_value(const char *id, size_t index, std::string &value, size_t size) override;
|
||||||
|
|
|
||||||
|
|
@ -178,8 +178,10 @@ utils::basic_type oid2type(const Oid oid) {
|
||||||
return utils::basic_type::Double;
|
return utils::basic_type::Double;
|
||||||
case 1082:
|
case 1082:
|
||||||
return utils::basic_type::Date;
|
return utils::basic_type::Date;
|
||||||
case 1114:
|
case 1083:
|
||||||
return utils::basic_type::Time;
|
return utils::basic_type::Time;
|
||||||
|
case 1114:
|
||||||
|
return utils::basic_type::DateTime;
|
||||||
default:
|
default:
|
||||||
return utils::basic_type::Null;
|
return utils::basic_type::Null;
|
||||||
}
|
}
|
||||||
|
|
@ -201,9 +203,12 @@ utils::basic_type string2type(const char *type) {
|
||||||
if (strcmp(type, "date") == 0) {
|
if (strcmp(type, "date") == 0) {
|
||||||
return utils::basic_type::Date;
|
return utils::basic_type::Date;
|
||||||
}
|
}
|
||||||
if (strcmp(type, "timestamp") == 0) {
|
if (strcmp(type, "time") == 0) {
|
||||||
return utils::basic_type::Time;
|
return utils::basic_type::Time;
|
||||||
}
|
}
|
||||||
|
if (strcmp(type, "timestamp") == 0) {
|
||||||
|
return utils::basic_type::DateTime;
|
||||||
|
}
|
||||||
if (strcmp(type, "float4") == 0) {
|
if (strcmp(type, "float4") == 0) {
|
||||||
return utils::basic_type::Float;
|
return utils::basic_type::Float;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,8 @@
|
||||||
{matador::utils::basic_type::UInt8, "SMALLINT"},
|
{matador::utils::basic_type::UInt8, "SMALLINT"},
|
||||||
{matador::utils::basic_type::Float, "REAL"},
|
{matador::utils::basic_type::Float, "REAL"},
|
||||||
{matador::utils::basic_type::Double, "DOUBLE PRECISION"},
|
{matador::utils::basic_type::Double, "DOUBLE PRECISION"},
|
||||||
{matador::utils::basic_type::Time, "TIMESTAMP"},
|
{matador::utils::basic_type::Time, "TIME(6)"},
|
||||||
|
{matador::utils::basic_type::DateTime, "TIMESTAMPTZ(6)"},
|
||||||
{matador::utils::basic_type::Blob, "BYTEA"}
|
{matador::utils::basic_type::Blob, "BYTEA"}
|
||||||
})
|
})
|
||||||
.with_bool_strings("TRUE", "FALSE")
|
.with_bool_strings("TRUE", "FALSE")
|
||||||
|
|
|
||||||
|
|
@ -123,15 +123,23 @@ void postgres_parameter_binder::write_value(const size_t pos, const std::string
|
||||||
write_value(pos, x);
|
write_value(pos, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void postgres_parameter_binder::write_value(const size_t pos, const utils::date_type_t &/*x*/) {
|
void postgres_parameter_binder::write_value(const size_t pos, const utils::date_type_t &x) {
|
||||||
// bind_data_.strings[pos] = utils::to_string(x, utils::date_format::ISO8601);
|
char buf[11]; // "YYYY-MM-DD" + '\0'
|
||||||
|
|
||||||
|
std::snprintf(buf, sizeof(buf), "%04d-%02u-%02u", x.year, static_cast<unsigned>(x.month), static_cast<unsigned>(x.day));
|
||||||
|
bind_data_.strings[pos] = std::string{buf};
|
||||||
bind_data_.values[pos] = bind_data_.strings[pos].data();
|
bind_data_.values[pos] = bind_data_.strings[pos].data();
|
||||||
bind_data_.lengths[pos] = static_cast<int>(bind_data_.strings[pos].size());
|
bind_data_.lengths[pos] = static_cast<int>(bind_data_.strings[pos].size());
|
||||||
bind_data_.formats[pos] = 0;
|
bind_data_.formats[pos] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void postgres_parameter_binder::write_value(const size_t pos, const utils::time_type_t &/*x*/) {
|
void postgres_parameter_binder::write_value(const size_t pos, const utils::time_type_t &x) {
|
||||||
// bind_data_.strings[pos] = utils::to_string(x, "%Y-%m-%d %T.%f");
|
char buf[16]; // "HH:MM:SS.ffffff" + '\0'
|
||||||
|
|
||||||
|
std::snprintf(buf, sizeof(buf), "%02u:%02u:%02u.%06u",
|
||||||
|
static_cast<unsigned>(x.hour), static_cast<unsigned>(x.minute), static_cast<unsigned>(x.second), x.microsecond);
|
||||||
|
|
||||||
|
bind_data_.strings[pos] = std::string{buf};
|
||||||
bind_data_.values[pos] = bind_data_.strings[pos].data();
|
bind_data_.values[pos] = bind_data_.strings[pos].data();
|
||||||
bind_data_.lengths[pos] = static_cast<int>(bind_data_.strings[pos].size());
|
bind_data_.lengths[pos] = static_cast<int>(bind_data_.strings[pos].size());
|
||||||
bind_data_.formats[pos] = 0;
|
bind_data_.formats[pos] = 0;
|
||||||
|
|
|
||||||
|
|
@ -4,27 +4,23 @@
|
||||||
#include "matador/utils/value.hpp"
|
#include "matador/utils/value.hpp"
|
||||||
|
|
||||||
namespace matador::backends::postgres {
|
namespace matador::backends::postgres {
|
||||||
|
|
||||||
postgres_result_reader::postgres_result_reader(PGresult *result)
|
postgres_result_reader::postgres_result_reader(PGresult *result)
|
||||||
: result_(result)
|
: result_(result)
|
||||||
, row_count_(PQntuples(result_))
|
, row_count_(PQntuples(result_))
|
||||||
, column_count_(PQnfields(result_))
|
, column_count_(PQnfields(result_)) {
|
||||||
{}
|
}
|
||||||
|
|
||||||
postgres_result_reader::~postgres_result_reader()
|
postgres_result_reader::~postgres_result_reader() {
|
||||||
{
|
|
||||||
if (result_) {
|
if (result_) {
|
||||||
PQclear(result_);
|
PQclear(result_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t postgres_result_reader::column_count() const
|
size_t postgres_result_reader::column_count() const {
|
||||||
{
|
|
||||||
return column_count_;
|
return column_count_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *postgres_result_reader::column( const size_t index) const
|
const char *postgres_result_reader::column(const size_t index) const {
|
||||||
{
|
|
||||||
return PQgetvalue(result_, static_cast<int>(row_index_), static_cast<int>(index));
|
return PQgetvalue(result_, static_cast<int>(row_index_), static_cast<int>(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,16 +102,21 @@ void postgres_result_reader::read_value(const char * /*id*/, const size_t index,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void postgres_result_reader::read_value(const char * /*id*/, const size_t /*index*/, time &/*value*/) {
|
void postgres_result_reader::read_value(const char * /*id*/, const size_t index, utils::date_type_t &value) {
|
||||||
// if (const auto val = column(index); strlen(val) > 0) {
|
if (const auto val = column(index); strlen(val) > 0) {
|
||||||
// value = time::parse(val, "%Y-%m-%d %T.%f");
|
// value = time::parse(val, "%Y-%m-%d %T.%f");
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void postgres_result_reader::read_value(const char * /*id*/, const size_t /*index*/, date &/*value*/) {
|
void postgres_result_reader::read_value(const char * /*id*/, const size_t index, utils::time_type_t &value) {
|
||||||
// if (const auto val = column(index); strlen(val) > 0) {
|
if (const auto val = column(index); strlen(val) > 0) {
|
||||||
// value.set(val, matador::utils::date_format::ISO8601);
|
// value.set(val, matador::utils::date_format::ISO8601);
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void postgres_result_reader::read_value(const char * /*id*/, size_t index, utils::timestamp &value) {
|
||||||
|
if (const auto val = column(index); strlen(val) > 0) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void postgres_result_reader::read_value(const char * /*id*/, const size_t index, char *value, size_t size) {
|
void postgres_result_reader::read_value(const char * /*id*/, const size_t index, char *value, size_t size) {
|
||||||
|
|
@ -126,7 +127,7 @@ void postgres_result_reader::read_value(const char * /*id*/, const size_t index,
|
||||||
#else
|
#else
|
||||||
strncpy(value, val, size);
|
strncpy(value, val, size);
|
||||||
#endif
|
#endif
|
||||||
value[size-1] = '\n';
|
value[size - 1] = '\n';
|
||||||
} else {
|
} else {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
strcpy_s(value, size, val);
|
strcpy_s(value, size, val);
|
||||||
|
|
@ -144,32 +145,30 @@ void postgres_result_reader::read_value(const char * /*id*/, const size_t index,
|
||||||
value.assign(column(index));
|
value.assign(column(index));
|
||||||
}
|
}
|
||||||
|
|
||||||
void postgres_result_reader::read_value( const char* /*id*/, const size_t index, utils::blob& value )
|
void postgres_result_reader::read_value(const char * /*id*/, const size_t index, utils::blob &value) {
|
||||||
{
|
const auto *data = reinterpret_cast<const unsigned char *>(column(index));
|
||||||
const auto *data = reinterpret_cast<const unsigned char*>(column(index));
|
|
||||||
// auto length = PQgetlength(result_, row_index_, static_cast<int>(index));
|
|
||||||
|
|
||||||
size_t length;
|
size_t length;
|
||||||
unsigned char* unescaped = PQunescapeBytea(data, &length);
|
unsigned char *unescaped = PQunescapeBytea(data, &length);
|
||||||
|
|
||||||
value.assign(unescaped, unescaped+length);
|
value.assign(unescaped, unescaped + length);
|
||||||
|
|
||||||
PQfreemem(unescaped);
|
PQfreemem(unescaped);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Type>
|
template<typename Type>
|
||||||
void set_value(const char* str, utils::value& value) {
|
void set_value(const char *str, utils::value &value) {
|
||||||
if (const auto res = utils::to<Type>(str); res.is_ok()) {
|
if (const auto res = utils::to<Type>(str); res.is_ok()) {
|
||||||
value = res.value();
|
value = res.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template<>
|
||||||
void set_value<utils::blob>(const char* str, utils::value& value) {
|
void set_value<utils::blob>(const char *str, utils::value &value) {
|
||||||
size_t length;
|
size_t length;
|
||||||
unsigned char* unescaped = PQunescapeBytea(reinterpret_cast<const unsigned char*>(str), &length);
|
unsigned char *unescaped = PQunescapeBytea(reinterpret_cast<const unsigned char *>(str), &length);
|
||||||
|
|
||||||
value = utils::blob(unescaped, unescaped+length);
|
value = utils::blob(unescaped, unescaped + length);
|
||||||
|
|
||||||
PQfreemem(unescaped);
|
PQfreemem(unescaped);
|
||||||
}
|
}
|
||||||
|
|
@ -219,8 +218,13 @@ void postgres_result_reader::read_value(const char * /*id*/, const size_t index,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case utils::basic_type::Time:
|
case utils::basic_type::Time:
|
||||||
case utils::basic_type::Date: {
|
set_value<utils::time_type_t>(column(index), val);
|
||||||
val = std::string{column(index)};
|
break;
|
||||||
|
case utils::basic_type::Date:
|
||||||
|
set_value<utils::date_type_t>(column(index), val);
|
||||||
|
break;
|
||||||
|
case utils::basic_type::DateTime: {
|
||||||
|
set_value<utils::timestamp>(column(index), val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case utils::basic_type::Null: {
|
case utils::basic_type::Null: {
|
||||||
|
|
@ -231,11 +235,12 @@ void postgres_result_reader::read_value(const char * /*id*/, const size_t index,
|
||||||
set_value<utils::blob>(column(index), val);
|
set_value<utils::blob>(column(index), val);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case utils::basic_type::Unknown:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
utils::attribute_reader &postgres_result_reader::result_binder() {
|
utils::attribute_reader &postgres_result_reader::result_binder() {
|
||||||
return empty_binder_;
|
return empty_binder_;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace matador::backends::postgres
|
} // namespace matador::backends::postgres
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ public:
|
||||||
[[nodiscard]] std::string prepare_literal(const std::string &str) const;
|
[[nodiscard]] std::string prepare_literal(const std::string &str) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wrap identifier quotes around a sql identifier keyword
|
* Wrap identifier quotes around a SQL identifier keyword
|
||||||
*
|
*
|
||||||
* @param str Identifier to put quotes around
|
* @param str Identifier to put quotes around
|
||||||
*/
|
*/
|
||||||
|
|
@ -259,7 +259,8 @@ private:
|
||||||
{utils::basic_type::Varchar, "VARCHAR"},
|
{utils::basic_type::Varchar, "VARCHAR"},
|
||||||
{utils::basic_type::Text, "TEXT"},
|
{utils::basic_type::Text, "TEXT"},
|
||||||
{utils::basic_type::Date, "DATE"},
|
{utils::basic_type::Date, "DATE"},
|
||||||
{utils::basic_type::Time, "DATETIME"},
|
{utils::basic_type::Time, "TIME"},
|
||||||
|
{utils::basic_type::DateTime, "DATETIME"},
|
||||||
{utils::basic_type::Blob, "BLOB"},
|
{utils::basic_type::Blob, "BLOB"},
|
||||||
{utils::basic_type::Null, "NULL"}
|
{utils::basic_type::Null, "NULL"}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,6 @@
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace matador {
|
|
||||||
class date;
|
|
||||||
class time;
|
|
||||||
}
|
|
||||||
namespace matador::utils {
|
namespace matador::utils {
|
||||||
|
|
||||||
class value;
|
class value;
|
||||||
|
|
@ -29,8 +25,9 @@ public:
|
||||||
virtual void read_value(const char *id, size_t index, bool &value) = 0;
|
virtual void read_value(const char *id, size_t index, bool &value) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, float &value) = 0;
|
virtual void read_value(const char *id, size_t index, float &value) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, double &value) = 0;
|
virtual void read_value(const char *id, size_t index, double &value) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, time &value) = 0;
|
virtual void read_value(const char *id, size_t index, time_type_t &value) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, date &value) = 0;
|
virtual void read_value(const char *id, size_t index, date_type_t &value) = 0;
|
||||||
|
virtual void read_value(const char *id, size_t index, timestamp &value) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, char *value, size_t size) = 0;
|
virtual void read_value(const char *id, size_t index, char *value, size_t size) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, std::string &value) = 0;
|
virtual void read_value(const char *id, size_t index, std::string &value) = 0;
|
||||||
virtual void read_value(const char *id, size_t index, std::string &value, size_t size) = 0;
|
virtual void read_value(const char *id, size_t index, std::string &value, size_t size) = 0;
|
||||||
|
|
|
||||||
|
|
@ -256,26 +256,57 @@ template < typename DestType >
|
||||||
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, date_type_t>>* = nullptr) {
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, date_type_t>>* = nullptr) {
|
||||||
std::tm result{};
|
std::tm result{};
|
||||||
std::istringstream iss(source);
|
std::istringstream iss(source);
|
||||||
iss >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
|
iss >> std::get_time(&result, "%Y-%m-%d");
|
||||||
return ok(result);
|
if (iss.fail()) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
return ok(date_type_t{result.tm_year + 1900, static_cast<uint8_t>(result.tm_mon + 1), static_cast<uint8_t>(result.tm_mday)});
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType >
|
||||||
|
result<DestType, conversion_error> to(const char *source, std::enable_if_t<std::is_same_v<DestType, date_type_t>>* = nullptr) {
|
||||||
|
return to<DestType>(std::string{source});
|
||||||
}
|
}
|
||||||
|
|
||||||
template < typename DestType >
|
template < typename DestType >
|
||||||
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, time_type_t>>* = nullptr) {
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, time_type_t>>* = nullptr) {
|
||||||
std::tm result{};
|
std::tm result{};
|
||||||
std::istringstream iss(source);
|
std::istringstream iss(source);
|
||||||
iss >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
|
iss >> std::get_time(&result, "%H:%M:%S");
|
||||||
return ok(result);
|
if (iss.fail()) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
return ok(time_type_t{static_cast<uint8_t>(result.tm_hour), static_cast<uint8_t>(result.tm_min), static_cast<uint8_t>(result.tm_sec)});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename DestType >
|
||||||
|
result<DestType, conversion_error> to(const char *source, std::enable_if_t<std::is_same_v<DestType, time_type_t>>* = nullptr) {
|
||||||
|
return to<DestType>(std::string{source});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template < typename DestType >
|
template < typename DestType >
|
||||||
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, timestamp>>* = nullptr) {
|
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, timestamp>>* = nullptr) {
|
||||||
std::tm result{};
|
std::tm result{};
|
||||||
std::istringstream iss(source);
|
std::istringstream iss(source);
|
||||||
iss >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
|
iss >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
|
||||||
return ok(result);
|
if (iss.fail()) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::time_t tt = std::mktime(&result);
|
||||||
|
if (tt == -1) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
return ok(std::chrono::system_clock::from_time_t(tt));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename DestType >
|
||||||
|
result<DestType, conversion_error> to(const char *source, std::enable_if_t<std::is_same_v<DestType, timestamp>>* = nullptr) {
|
||||||
|
return to<DestType>(std::string{source});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template < typename DestType, typename SourceType >
|
template < typename DestType, typename SourceType >
|
||||||
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<DestType> && !std::is_same_v<bool, DestType> && std::is_same_v<date_type_t, SourceType>>* = nullptr) {
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<DestType> && !std::is_same_v<bool, DestType> && std::is_same_v<date_type_t, SourceType>>* = nullptr) {
|
||||||
return failure(conversion_error::NotConvertable);
|
return failure(conversion_error::NotConvertable);
|
||||||
|
|
@ -351,6 +382,104 @@ result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_
|
||||||
return failure(conversion_error::NotConvertable);
|
return failure(conversion_error::NotConvertable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template < typename DestType, typename SourceType >
|
||||||
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<SourceType> && !std::is_same_v<bool, SourceType> && std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType, typename SourceType >
|
||||||
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<SourceType> && !std::is_same_v<bool, SourceType> && std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType, typename SourceType >
|
||||||
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_integral_v<SourceType> && !std::is_same_v<bool, SourceType> && std::is_same_v<timestamp, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType, typename SourceType >
|
||||||
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<SourceType> && std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType, typename SourceType >
|
||||||
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<SourceType> && std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType, typename SourceType >
|
||||||
|
result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_if_t<std::is_floating_point_v<SourceType> && std::is_same_v<timestamp, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const blob &/*source*/, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const blob &/*source*/, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const blob &/*source*/, std::enable_if_t<std::is_same_v<timestamp, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const bool &/*source*/, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const bool &/*source*/, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const bool &/*source*/, std::enable_if_t<std::is_same_v<timestamp, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const time_type_t &/*source*/, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const time_type_t &source, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
||||||
|
return ok(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const date_type_t &/*source*/, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
||||||
|
return failure(conversion_error::NotConvertable);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const date_type_t &source, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
||||||
|
return ok(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const timestamp &source, std::enable_if_t<std::is_same_v<time_type_t, DestType>>* = nullptr) {
|
||||||
|
const std::time_t tt = std::chrono::system_clock::to_time_t(source);
|
||||||
|
|
||||||
|
const std::tm* result = std::localtime(&tt);
|
||||||
|
|
||||||
|
return ok(time_type_t{static_cast<uint8_t>(result->tm_hour), static_cast<uint8_t>(result->tm_min), static_cast<uint8_t>(result->tm_sec)});
|
||||||
|
}
|
||||||
|
|
||||||
|
template < typename DestType>
|
||||||
|
result<DestType, conversion_error> to(const timestamp &source, std::enable_if_t<std::is_same_v<date_type_t, DestType>>* = nullptr) {
|
||||||
|
const std::time_t tt = std::chrono::system_clock::to_time_t(source);
|
||||||
|
|
||||||
|
const std::tm* result = std::localtime(&tt);
|
||||||
|
|
||||||
|
return ok(date_type_t{result->tm_year + 1900, static_cast<uint8_t>(result->tm_mon + 1), static_cast<uint8_t>(result->tm_mday)});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //MATADOR_CONVERT_HPP
|
#endif //MATADOR_CONVERT_HPP
|
||||||
|
|
|
||||||
|
|
@ -8,159 +8,162 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace matador::utils {
|
namespace matador::utils {
|
||||||
|
|
||||||
/// @cond MATADOR_DEV
|
/// @cond MATADOR_DEV
|
||||||
template <> struct data_type_traits<nullptr_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<nullptr_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/) { return basic_type::Null; }
|
static basic_type type(std::size_t /*size*/) { return basic_type::Null; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, nullptr_t &/*value*/, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, nullptr_t &/*value*/,
|
||||||
static void bind_value(attribute_writer &binder, size_t index, nullptr_t &/*value*/, size_t /*size*/ = 0);
|
size_t /*size*/ = 0);
|
||||||
|
static void bind_value(attribute_writer &binder, size_t index, nullptr_t &/*value*/, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<int8_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<int8_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int8; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int8; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, int8_t &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, int8_t &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const int8_t &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const int8_t &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<int16_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<int16_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int16; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int16; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, int16_t &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, int16_t &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const int16_t &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const int16_t &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<int32_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<int32_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int32; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int32; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, int32_t &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, int32_t &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const int32_t &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const int32_t &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<int64_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<int64_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int64; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int64; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, int64_t &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, int64_t &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const int64_t &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const int64_t &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<uint8_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<uint8_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::UInt8; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::UInt8; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, uint8_t &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, uint8_t &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const uint8_t &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const uint8_t &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<uint16_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<uint16_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::UInt16; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::UInt16; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, uint16_t &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, uint16_t &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const uint16_t &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const uint16_t &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<uint32_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<uint32_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::UInt32; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::UInt32; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, uint32_t &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, uint32_t &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const uint32_t &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const uint32_t &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<uint64_t, void>
|
template<>
|
||||||
{
|
struct data_type_traits<uint64_t, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::UInt64; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::UInt64; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, uint64_t &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, uint64_t &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const uint64_t &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const uint64_t &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<bool, void>
|
template<>
|
||||||
{
|
struct data_type_traits<bool, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Boolean; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Boolean; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, bool &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, bool &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const bool &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const bool &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<float, void>
|
template<>
|
||||||
{
|
struct data_type_traits<float, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Float; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Float; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, float &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, float &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const float &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const float &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<double, void>
|
template<>
|
||||||
{
|
struct data_type_traits<double, void> {
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Double; }
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Double; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, double &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, double &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const double &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const double &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<const char*, void>
|
template<>
|
||||||
{
|
struct data_type_traits<const char *, void> {
|
||||||
static basic_type type(const std::size_t size) { return size == 0 ? basic_type::Text : basic_type::Varchar; }
|
static basic_type type(const std::size_t size) { return size == 0 ? basic_type::Text : basic_type::Varchar; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, const char* value, size_t size);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, const char *value, size_t size);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const char *value, size_t size = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const char *value, size_t size = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<char*, void>
|
template<>
|
||||||
{
|
struct data_type_traits<char *, void> {
|
||||||
static basic_type type(const std::size_t size) { return size == 0 ? basic_type::Text : basic_type::Varchar; }
|
static basic_type type(const std::size_t size) { return size == 0 ? basic_type::Text : basic_type::Varchar; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, char *value, size_t size);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, char *value, size_t size);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, const char *value, size_t size = 0);
|
static void bind_value(attribute_writer &binder, size_t index, const char *value, size_t size = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<char[], void>
|
template<>
|
||||||
{
|
struct data_type_traits<char[], void> {
|
||||||
static basic_type type(const std::size_t size) { return size == 0 ? basic_type::Text : basic_type::Varchar; }
|
static basic_type type(const std::size_t size) { return size == 0 ? basic_type::Text : basic_type::Varchar; }
|
||||||
template < int N >
|
|
||||||
|
template<int N>
|
||||||
static void read_value(attribute_reader &reader, const char *id, const size_t index, char (&value)[N], const size_t size) {
|
static void read_value(attribute_reader &reader, const char *id, const size_t index, char (&value)[N], const size_t size) {
|
||||||
data_type_traits<const char*>::read_value(reader, id, index, value, size);
|
data_type_traits<const char *>::read_value(reader, id, index, value, size);
|
||||||
}
|
}
|
||||||
template < int N >
|
|
||||||
|
template<int N>
|
||||||
static void bind_value(attribute_writer &binder, const size_t index, char *value, const size_t size = 0) {
|
static void bind_value(attribute_writer &binder, const size_t index, char *value, const size_t size = 0) {
|
||||||
data_type_traits<const char*>::bind_value(binder, index, value, size);
|
data_type_traits<const char *>::bind_value(binder, index, value, size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<std::string, void>
|
template<>
|
||||||
{
|
struct data_type_traits<std::string, void> {
|
||||||
static basic_type type(const std::size_t size) { return size == 0 ? basic_type::Text : basic_type::Varchar; }
|
static basic_type type(const std::size_t size) { return size == 0 ? basic_type::Text : basic_type::Varchar; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, std::string &value, size_t size);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, std::string &value, size_t size);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, std::string &value, size_t size = 0);
|
static void bind_value(attribute_writer &binder, size_t index, std::string &value, size_t size = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> struct data_type_traits<utils::blob, void>
|
template<>
|
||||||
{
|
struct data_type_traits<utils::blob, void> {
|
||||||
static basic_type type(std::size_t /*size*/) { return basic_type::Blob; }
|
static basic_type type(std::size_t /*size*/) { return basic_type::Blob; }
|
||||||
static void read_value(attribute_reader &reader, const char *id, size_t index, utils::blob &value, size_t /*size*/ = 0);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, utils::blob &value, size_t /*size*/ = 0);
|
||||||
static void bind_value(attribute_writer &binder, size_t index, utils::blob &value, size_t /*size*/ = 0);
|
static void bind_value(attribute_writer &binder, size_t index, utils::blob &value, size_t /*size*/ = 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
//template <> struct data_type_traits<matador::date, void>
|
template<>
|
||||||
//{
|
struct data_type_traits<date_type_t, void> {
|
||||||
// static basic_type type(std::size_t /*size*/) { return basic_type::type_date; }
|
static basic_type type(std::size_t /*size*/) { return basic_type::Date; }
|
||||||
// static void read_value(attribute_reader &reader, const char *id, size_t index, matador::date &value);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, date_type_t &value);
|
||||||
// static void bind_value(attribute_writer &binder, size_t index, matador::date &value);
|
static void bind_value(attribute_writer &binder, size_t index, date_type_t &value);
|
||||||
//};
|
};
|
||||||
//
|
|
||||||
//template <> struct data_type_traits<matador::time, void>
|
template<>
|
||||||
//{
|
struct data_type_traits<time_type_t, void> {
|
||||||
// static basic_type type(std::size_t /*size*/) { return basic_type::type_time; }
|
static basic_type type(std::size_t /*size*/) { return basic_type::Time; }
|
||||||
// static void read_value(attribute_reader &reader, const char *id, size_t index, matador::time &value);
|
static void read_value(attribute_reader &reader, const char *id, size_t index, time_type_t &value);
|
||||||
// static void bind_value(attribute_writer &binder, size_t index, matador::time &value);
|
static void bind_value(attribute_writer &binder, size_t index, time_type_t &value);
|
||||||
//};
|
};
|
||||||
|
|
||||||
|
template<typename EnumType>
|
||||||
|
struct data_type_traits<EnumType, std::enable_if_t<std::is_enum_v<EnumType> > > {
|
||||||
|
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int32; }
|
||||||
|
|
||||||
template < typename EnumType >
|
|
||||||
struct data_type_traits<EnumType, std::enable_if_t<std::is_enum_v<EnumType>>>
|
|
||||||
{
|
|
||||||
static basic_type type(std::size_t /*size*/ = 0) { return basic_type::Int32; }
|
|
||||||
static void read_value(attribute_reader &reader, const char *id, const size_t index, EnumType &value, const size_t size = 0) {
|
static void read_value(attribute_reader &reader, const char *id, const size_t index, EnumType &value, const size_t size = 0) {
|
||||||
data_type_traits<int>::read_value(reader, id, index, reinterpret_cast<int&>(value), size);
|
data_type_traits<int>::read_value(reader, id, index, reinterpret_cast<int &>(value), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bind_value(attribute_writer &binder, const size_t index, EnumType &value, const size_t size = 0) {
|
static void bind_value(attribute_writer &binder, const size_t index, EnumType &value, const size_t size = 0) {
|
||||||
data_type_traits<int>::bind_value(binder, index, static_cast<int &>(value), size);
|
data_type_traits<int>::bind_value(binder, index, static_cast<int &>(value), size);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
/// @endcond
|
|
||||||
|
|
||||||
|
/// @endcond
|
||||||
}
|
}
|
||||||
#endif //MATADOR_DEFAULT_TYPE_TRAITS_HPP
|
#endif //MATADOR_DEFAULT_TYPE_TRAITS_HPP
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ namespace matador::utils {
|
||||||
* @return Binary data as string
|
* @return Binary data as string
|
||||||
*/
|
*/
|
||||||
MATADOR_UTILS_API std::string to_string(const blob &data);
|
MATADOR_UTILS_API std::string to_string(const blob &data);
|
||||||
|
MATADOR_UTILS_API std::string to_string(const date_type_t &data);
|
||||||
|
MATADOR_UTILS_API std::string to_string(const time_type_t &data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Splits a string by a delimiter and
|
* Splits a string by a delimiter and
|
||||||
|
|
|
||||||
|
|
@ -127,28 +127,24 @@ void data_type_traits<blob>::read_value(attribute_reader &reader, const char *id
|
||||||
reader.read_value(id, index, value);
|
reader.read_value(id, index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void data_type_traits<blob>::bind_value(attribute_writer &binder, const size_t index, utils::blob &value, const size_t /*size*/) {
|
void data_type_traits<blob>::bind_value(attribute_writer &binder, const size_t index, blob &value, const size_t /*size*/) {
|
||||||
binder.write_value(index, value);
|
binder.write_value(index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// void data_type_traits<matador::date>::read_value(attribute_reader &reader, const char *id, size_t index, date &value)
|
void data_type_traits<date_type_t>::read_value(attribute_reader &reader, const char *id, size_t index, date_type_t &value) {
|
||||||
// {
|
reader.read_value(id, index, value);
|
||||||
// reader.read_value(id, index, value);
|
}
|
||||||
// }
|
|
||||||
//
|
void data_type_traits<date_type_t>::bind_value(attribute_writer &binder, const size_t index, date_type_t &value) {
|
||||||
// void data_type_traits<matador::date>::bind_value(attribute_writer &binder, size_t index, date &value)
|
binder.write_value(index, value);
|
||||||
// {
|
}
|
||||||
// binder.write_value(index, value);
|
|
||||||
// }
|
void data_type_traits<time_type_t>::read_value(attribute_reader &reader, const char *id, size_t index, time_type_t &value) {
|
||||||
//
|
reader.read_value(id, index, value);
|
||||||
// void data_type_traits<matador::time>::read_value(attribute_reader &reader, const char *id, size_t index, time &value)
|
}
|
||||||
// {
|
|
||||||
// reader.read_value(id, index, value);
|
void data_type_traits<time_type_t>::bind_value(attribute_writer &binder, const size_t index, time_type_t &value) {
|
||||||
// }
|
binder.write_value(index, value);
|
||||||
//
|
}
|
||||||
// void data_type_traits<matador::time>::bind_value(attribute_writer &binder, size_t index, time &value)
|
|
||||||
// {
|
|
||||||
// binder.write_value(index, value);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -18,6 +18,24 @@ std::string to_string(const blob& data) {
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string to_string(const date_type_t &data) {
|
||||||
|
char buf[11]; // "YYYY-MM-DD" + '\0'
|
||||||
|
|
||||||
|
std::snprintf(buf, sizeof(buf), "%04d-%02u-%02u",
|
||||||
|
data.year, static_cast<unsigned>(data.month), static_cast<unsigned>(data.day));
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_string(const time_type_t &data) {
|
||||||
|
char buf[16]; // "HH:MM:SS.ffffff" + '\0'
|
||||||
|
|
||||||
|
std::snprintf(buf, sizeof(buf), "%02u:%02u:%02u.%06u",
|
||||||
|
static_cast<unsigned>(data.hour), static_cast<unsigned>(data.minute), static_cast<unsigned>(data.second), data.microsecond);
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
size_t split(const std::string &str, char delim, std::vector<std::string> &values)
|
size_t split(const std::string &str, char delim, std::vector<std::string> &values)
|
||||||
{
|
{
|
||||||
std::stringstream ss(str);
|
std::stringstream ss(str);
|
||||||
|
|
|
||||||
|
|
@ -9,104 +9,108 @@
|
||||||
#include "matador/utils/string.hpp"
|
#include "matador/utils/string.hpp"
|
||||||
|
|
||||||
namespace matador::query {
|
namespace matador::query {
|
||||||
|
attribute_string_writer::attribute_string_writer(const sql::dialect &d,
|
||||||
attribute_string_writer::attribute_string_writer(const sql::dialect &d, const std::optional<std::reference_wrapper<const sql::connection_impl>> conn)
|
const std::optional<std::reference_wrapper<const
|
||||||
|
sql::connection_impl> > conn)
|
||||||
: dialect_(d)
|
: dialect_(d)
|
||||||
, conn_(conn) {}
|
, conn_(conn) {
|
||||||
|
|
||||||
const sql::dialect& attribute_string_writer::dialect() const {
|
|
||||||
return dialect_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const int8_t& x ) {
|
const sql::dialect &attribute_string_writer::dialect() const {
|
||||||
result_ = std::to_string(x) ;
|
return dialect_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const int16_t& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const int8_t &x) {
|
||||||
result_ = std::to_string(x) ;
|
result_ = std::to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const int32_t& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const int16_t &x) {
|
||||||
result_ = std::to_string(x) ;
|
result_ = std::to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const int64_t& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const int32_t &x) {
|
||||||
result_ = std::to_string(x) ;
|
result_ = std::to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const uint8_t& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const int64_t &x) {
|
||||||
result_ = std::to_string(x) ;
|
result_ = std::to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const uint16_t& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const uint8_t &x) {
|
||||||
result_ = std::to_string(x) ;
|
result_ = std::to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const uint32_t& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const uint16_t &x) {
|
||||||
result_ = std::to_string(x) ;
|
result_ = std::to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const uint64_t& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const uint32_t &x) {
|
||||||
result_ = std::to_string(x) ;
|
result_ = std::to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const bool& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const uint64_t &x) {
|
||||||
// result_ = "'" + conn_->dialect().prepare_literal(x ? "true" : "false") + "'";
|
result_ = std::to_string(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
void attribute_string_writer::write_value(size_t /*pos*/, const bool &x) {
|
||||||
|
// result_ = "'" + conn_->dialect().prepare_literal(x ? "true" : "false") + "'";
|
||||||
result_ = dialect_.to_string(x);
|
result_ = dialect_.to_string(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const float& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const float &x) {
|
||||||
if (const auto res = utils::to<std::string>(x); !res.is_error()) {
|
if (const auto res = utils::to<std::string>(x); !res.is_error()) {
|
||||||
result_ = *res;
|
result_ = *res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const double& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const double &x) {
|
||||||
if (const auto res = utils::to<std::string>(x); !res.is_error()) {
|
if (const auto res = utils::to<std::string>(x); !res.is_error()) {
|
||||||
result_ = *res;
|
result_ = *res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const utils::date_type_t& /*x*/ ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const utils::date_type_t &x) {
|
||||||
// result_ = "'" + dialect_.prepare_literal(utils::to_string(x)) + "'";
|
result_ = "'" + dialect_.prepare_literal(utils::to_string(x)) + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const utils::time_type_t& /*x*/ ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const utils::time_type_t &x) {
|
||||||
// result_ = "'" + dialect_.prepare_literal(utils::to_string(x, "%F %T.%f")) + "'";
|
result_ = "'" + dialect_.prepare_literal(utils::to_string(x)) + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const utils::timestamp &/*x*/) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const utils::timestamp &/*x*/) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t pos, const char* x ) {
|
void attribute_string_writer::write_value(size_t pos, const char *x) {
|
||||||
write_value(pos, std::string(x) );
|
write_value(pos, std::string(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t pos, const char* x, size_t /*size*/) {
|
void attribute_string_writer::write_value(size_t pos, const char *x, size_t /*size*/) {
|
||||||
write_value(pos, std::string(x) );
|
write_value(pos, std::string(x));
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const std::string& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const std::string &x) {
|
||||||
result_ = "'" + dialect_.prepare_literal(x) + "'";
|
result_ = "'" + dialect_.prepare_literal(x) + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const std::string& x, size_t /*size*/) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const std::string &x, size_t /*size*/) {
|
||||||
result_ = "'" + dialect_.prepare_literal(x) + "'";
|
result_ = "'" + dialect_.prepare_literal(x) + "'";
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const utils::blob& x ) {
|
void attribute_string_writer::write_value(size_t /*pos*/, const utils::blob &x) {
|
||||||
// "This is a binary Data string" as binary data:
|
// "This is a binary Data string" as binary data:
|
||||||
// MySQL: X'5468697320697320612062616E617279204461746120737472696E67'
|
// MySQL: X'5468697320697320612062616E617279204461746120737472696E67'
|
||||||
// Postgres: '\\x5468697320697320612062616E617279204461746120737472696E67'
|
// Postgres: '\\x5468697320697320612062616E617279204461746120737472696E67'
|
||||||
// MSSQL: 0x5468697320697320612062616E617279204461746120737472696E67
|
// MSSQL: 0x5468697320697320612062616E617279204461746120737472696E67
|
||||||
// Sqlite: X'5468697320697320612062616E617279204461746120737472696E67'
|
// Sqlite: X'5468697320697320612062616E617279204461746120737472696E67'
|
||||||
if (conn_.has_value()) {
|
if (conn_.has_value()) {
|
||||||
result_ = dialect_.token_at(sql::dialect_token::BeginBinaryData) + conn_.value().get().to_escaped_string(x) + dialect_.token_at(sql::dialect_token::EndBinaryData);
|
result_ = dialect_.token_at(sql::dialect_token::BeginBinaryData) + conn_.value().get().to_escaped_string(x) +
|
||||||
|
dialect_.token_at(sql::dialect_token::EndBinaryData);
|
||||||
} else {
|
} else {
|
||||||
result_ = dialect_.token_at(sql::dialect_token::BeginBinaryData) + dialect_.to_escaped_string(x) + dialect_.token_at(sql::dialect_token::EndBinaryData);
|
result_ = dialect_.token_at(sql::dialect_token::BeginBinaryData) + dialect_.to_escaped_string(x) + dialect_.
|
||||||
|
token_at(sql::dialect_token::EndBinaryData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void attribute_string_writer::write_value(size_t /*pos*/, const utils::value &/*x*/, size_t /*size*/) {}
|
void attribute_string_writer::write_value(size_t /*pos*/, const utils::value &/*x*/, size_t /*size*/) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,49 +3,47 @@
|
||||||
#include "matador/sql/interface/query_result_reader.hpp"
|
#include "matador/sql/interface/query_result_reader.hpp"
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
detail::pk_reader::pk_reader(query_result_reader &reader)
|
detail::pk_reader::pk_reader(query_result_reader &reader)
|
||||||
: reader_(reader) {}
|
: reader_(reader) {
|
||||||
|
}
|
||||||
|
|
||||||
query_result_impl::query_result_impl(std::unique_ptr<query_result_reader> &&reader, std::vector<object::attribute> &&prototype, const size_t column_index)
|
query_result_impl::query_result_impl(std::unique_ptr<query_result_reader> &&reader,
|
||||||
|
std::vector<object::attribute> &&prototype,
|
||||||
|
const size_t column_index)
|
||||||
: column_index_(column_index)
|
: column_index_(column_index)
|
||||||
, prototype_(std::move(prototype))
|
, prototype_(std::move(prototype))
|
||||||
, reader_(std::move(reader))
|
, reader_(std::move(reader))
|
||||||
, pk_reader_(*reader_)
|
, pk_reader_(*reader_) {
|
||||||
{}
|
}
|
||||||
|
|
||||||
query_result_impl::query_result_impl(std::unique_ptr<query_result_reader> &&reader, const std::vector<object::attribute> &prototype, const size_t column_index)
|
query_result_impl::query_result_impl(std::unique_ptr<query_result_reader> &&reader,
|
||||||
|
const std::vector<object::attribute> &prototype,
|
||||||
|
const size_t column_index)
|
||||||
: column_index_(column_index)
|
: column_index_(column_index)
|
||||||
, prototype_(prototype)
|
, prototype_(prototype)
|
||||||
, reader_(std::move(reader))
|
, reader_(std::move(reader))
|
||||||
, pk_reader_(*reader_)
|
, pk_reader_(*reader_) {
|
||||||
{}
|
}
|
||||||
|
|
||||||
void query_result_impl::on_revision(const char *id, uint64_t &rev)
|
void query_result_impl::on_revision(const char *id, uint64_t &rev) {
|
||||||
{
|
|
||||||
utils::data_type_traits<uint64_t>::read_value(*reader_, id, column_index_++, rev);
|
utils::data_type_traits<uint64_t>::read_value(*reader_, id, column_index_++, rev);
|
||||||
reader_->read_value(id, column_index_++, rev);
|
reader_->read_value(id, column_index_++, rev);
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_result_impl::on_attribute(const char *id, char *value, const utils::field_attributes &attr)
|
void query_result_impl::on_attribute(const char *id, char *value, const utils::field_attributes &attr) {
|
||||||
{
|
utils::data_type_traits<char *>::read_value(*reader_, id, column_index_++, value, attr.size());
|
||||||
utils::data_type_traits<char*>::read_value(*reader_, id, column_index_++, value, attr.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void query_result_impl::on_attribute(const char *id, std::string &value, const utils::field_attributes &attr)
|
void query_result_impl::on_attribute(const char *id, std::string &value, const utils::field_attributes &attr) {
|
||||||
{
|
|
||||||
utils::data_type_traits<std::string>::read_value(*reader_, id, column_index_++, value, attr.size());
|
utils::data_type_traits<std::string>::read_value(*reader_, id, column_index_++, value, attr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
query_result_impl::on_attribute(const char *id, utils::value &val, const utils::field_attributes &attr)
|
query_result_impl::on_attribute(const char *id, utils::value &val, const utils::field_attributes &attr) {
|
||||||
{
|
|
||||||
reader_->read_value(id, column_index_++, val, attr.size());
|
reader_->read_value(id, column_index_++, val, attr.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<object::attribute>& query_result_impl::prototype() const
|
const std::vector<object::attribute> &query_result_impl::prototype() const {
|
||||||
{
|
|
||||||
return prototype_;
|
return prototype_;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -61,15 +61,16 @@ void value_extractor::write_value(size_t /*pos*/, const double &x) {
|
||||||
values_.emplace_back(x);
|
values_.emplace_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_extractor::write_value(size_t /*pos*/, const utils::date_type_t &/*x*/) {
|
void value_extractor::write_value(size_t /*pos*/, const utils::date_type_t &x) {
|
||||||
// values_.emplace_back(x);
|
values_.emplace_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_extractor::write_value(size_t /*pos*/, const utils::time_type_t &/*x*/) {
|
void value_extractor::write_value(size_t /*pos*/, const utils::time_type_t &x) {
|
||||||
// values_.emplace_back(x);
|
values_.emplace_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_extractor::write_value(size_t /*pos*/, const utils::timestamp &/*x*/) {
|
void value_extractor::write_value(size_t /*pos*/, const utils::timestamp &x) {
|
||||||
|
values_.emplace_back(x);
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_extractor::write_value(size_t /*pos*/, const char *x) {
|
void value_extractor::write_value(size_t /*pos*/, const char *x) {
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,7 @@
|
||||||
#include "matador/utils/value.hpp"
|
#include "matador/utils/value.hpp"
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
const std::string &dialect::token_at(const dialect_token token) const {
|
||||||
const std::string& dialect::token_at(const dialect_token token) const {
|
|
||||||
return tokens_.at(token);
|
return tokens_.at(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -15,22 +14,21 @@ const std::string &dialect::data_type_at(const utils::basic_type type) const {
|
||||||
return data_types_.at(type);
|
return data_types_.at(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::sql_function_at(const sql_function_t func) const {
|
const std::string &dialect::sql_function_at(const sql_function_t func) const {
|
||||||
return sql_func_map_.at(func);
|
return sql_func_map_.at(func);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dialect::table_name( const std::string& table, const std::string& schema_name ) const {
|
std::string dialect::table_name(const std::string &table, const std::string &schema_name) const {
|
||||||
if ( schema_name.empty() && default_schema_name_.empty()) {
|
if (schema_name.empty() && default_schema_name_.empty()) {
|
||||||
return prepare_identifier_string( table );
|
return prepare_identifier_string(table);
|
||||||
}
|
}
|
||||||
if ( schema_name.empty() ) {
|
if (schema_name.empty()) {
|
||||||
return prepare_identifier_string( default_schema_name_ ) + "." + prepare_identifier_string( table );
|
return prepare_identifier_string(default_schema_name_) + "." + prepare_identifier_string(table);
|
||||||
}
|
}
|
||||||
return prepare_identifier_string( schema_name ) + "." + prepare_identifier_string( table );
|
return prepare_identifier_string(schema_name) + "." + prepare_identifier_string(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::to_string(const bool val) const
|
const std::string &dialect::to_string(const bool val) const {
|
||||||
{
|
|
||||||
return bool_strings_[static_cast<int>(val)];
|
return bool_strings_[static_cast<int>(val)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -45,38 +43,33 @@ std::string dialect::to_sql_string(const utils::value &val) const {
|
||||||
return val.str();
|
return val.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void dialect::bool_strings(const std::string &true_string, const std::string &false_string)
|
void dialect::bool_strings(const std::string &true_string, const std::string &false_string) {
|
||||||
{
|
|
||||||
bool_strings_[0] = false_string;
|
bool_strings_[0] = false_string;
|
||||||
bool_strings_[1] = true_string;
|
bool_strings_[1] = true_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dialect::prepare_identifier_string(const std::string &col) const
|
std::string dialect::prepare_identifier_string(const std::string &col) const {
|
||||||
{
|
|
||||||
auto parts = utils::split(col, '.');
|
auto parts = utils::split(col, '.');
|
||||||
|
|
||||||
for (auto &part : parts) {
|
for (auto &part: parts) {
|
||||||
escape_quotes_in_identifier(part);
|
escape_quotes_in_identifier(part);
|
||||||
quote_identifier(part);
|
quote_identifier(part);
|
||||||
}
|
}
|
||||||
return utils::join(parts, ".");
|
return utils::join(parts, ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dialect::prepare_literal(const std::string &str) const
|
std::string dialect::prepare_literal(const std::string &str) const {
|
||||||
{
|
|
||||||
std::string result(str);
|
std::string result(str);
|
||||||
escape_quotes_in_literals(result);
|
escape_quotes_in_literals(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dialect::quote_identifier(std::string &str) const
|
void dialect::quote_identifier(std::string &str) const {
|
||||||
{
|
|
||||||
str.insert(0, token_at(dialect_token::StartQuote));
|
str.insert(0, token_at(dialect_token::StartQuote));
|
||||||
str += token_at(dialect_token::EndQuote);
|
str += token_at(dialect_token::EndQuote);
|
||||||
}
|
}
|
||||||
|
|
||||||
void dialect::escape_quotes_in_identifier(std::string &str) const
|
void dialect::escape_quotes_in_identifier(std::string &str) const {
|
||||||
{
|
|
||||||
const std::string open_char(token_at(dialect_token::StartQuote));
|
const std::string open_char(token_at(dialect_token::StartQuote));
|
||||||
const std::string close_char(token_at(dialect_token::EndQuote));
|
const std::string close_char(token_at(dialect_token::EndQuote));
|
||||||
if (identifier_escape_type() == escape_identifier_t::ESCAPE_CLOSING_BRACKET) {
|
if (identifier_escape_type() == escape_identifier_t::ESCAPE_CLOSING_BRACKET) {
|
||||||
|
|
@ -86,8 +79,7 @@ void dialect::escape_quotes_in_identifier(std::string &str) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void dialect::escape_quotes_in_literals(std::string &str) const
|
void dialect::escape_quotes_in_literals(std::string &str) const {
|
||||||
{
|
|
||||||
const std::string single_quote(token_at(dialect_token::StringQuote));
|
const std::string single_quote(token_at(dialect_token::StringQuote));
|
||||||
const std::string double_quote(token_at(dialect_token::StringQuote) + token_at(dialect_token::StringQuote));
|
const std::string double_quote(token_at(dialect_token::StringQuote) + token_at(dialect_token::StringQuote));
|
||||||
utils::replace_all(str, single_quote, double_quote);
|
utils::replace_all(str, single_quote, double_quote);
|
||||||
|
|
@ -101,13 +93,11 @@ void dialect::identifier_escape_type(escape_identifier_t escape_identifier) {
|
||||||
identifier_escape_type_ = escape_identifier;
|
identifier_escape_type_ = escape_identifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dialect::next_placeholder(const std::vector<std::string> &bind_vars) const
|
std::string dialect::next_placeholder(const std::vector<std::string> &bind_vars) const {
|
||||||
{
|
|
||||||
return placeholder_func_(bind_vars.size());
|
return placeholder_func_(bind_vars.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dialect::to_escaped_string(const utils::blob &value, const connection_impl *conn) const
|
std::string dialect::to_escaped_string(const utils::blob &value, const connection_impl *conn) const {
|
||||||
{
|
|
||||||
if (conn != nullptr) {
|
if (conn != nullptr) {
|
||||||
return conn->to_escaped_string(value);
|
return conn->to_escaped_string(value);
|
||||||
}
|
}
|
||||||
|
|
@ -115,212 +105,211 @@ std::string dialect::to_escaped_string(const utils::blob &value, const connectio
|
||||||
return to_escaped_string_func_(value);
|
return to_escaped_string_func_(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string dialect::default_schema_name() const
|
std::string dialect::default_schema_name() const {
|
||||||
{
|
|
||||||
return default_schema_name_;
|
return default_schema_name_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::add_constraint() const {
|
const std::string &dialect::add_constraint() const {
|
||||||
return token_at(dialect_token::AddConstraint);
|
return token_at(dialect_token::AddConstraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::alter() const {
|
const std::string &dialect::alter() const {
|
||||||
return token_at(dialect_token::Alter);
|
return token_at(dialect_token::Alter);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::and_() const {
|
const std::string &dialect::and_() const {
|
||||||
return token_at(dialect_token::And);
|
return token_at(dialect_token::And);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::as() const {
|
const std::string &dialect::as() const {
|
||||||
return token_at(dialect_token::As);
|
return token_at(dialect_token::As);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::asc() const {
|
const std::string &dialect::asc() const {
|
||||||
return token_at(dialect_token::Asc);
|
return token_at(dialect_token::Asc);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::begin() const {
|
const std::string &dialect::begin() const {
|
||||||
return token_at(dialect_token::Begin);
|
return token_at(dialect_token::Begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::asterisk() const {
|
const std::string &dialect::asterisk() const {
|
||||||
return token_at(dialect_token::Asterisk);
|
return token_at(dialect_token::Asterisk);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::begin_binary_data() const {
|
const std::string &dialect::begin_binary_data() const {
|
||||||
return token_at(dialect_token::BeginBinaryData);
|
return token_at(dialect_token::BeginBinaryData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::begin_string_data() const {
|
const std::string &dialect::begin_string_data() const {
|
||||||
return token_at(dialect_token::BeginStringData);
|
return token_at(dialect_token::BeginStringData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::between() const {
|
const std::string &dialect::between() const {
|
||||||
return token_at(dialect_token::Between);
|
return token_at(dialect_token::Between);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::column() const {
|
const std::string &dialect::column() const {
|
||||||
return token_at(dialect_token::Column);
|
return token_at(dialect_token::Column);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::columns() const {
|
const std::string &dialect::columns() const {
|
||||||
return token_at(dialect_token::Columns);
|
return token_at(dialect_token::Columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::commit() const {
|
const std::string &dialect::commit() const {
|
||||||
return token_at(dialect_token::Commit);
|
return token_at(dialect_token::Commit);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::constraint() const {
|
const std::string &dialect::constraint() const {
|
||||||
return token_at(dialect_token::Constraint);
|
return token_at(dialect_token::Constraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::create() const {
|
const std::string &dialect::create() const {
|
||||||
return token_at(dialect_token::Create);
|
return token_at(dialect_token::Create);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::drop() const {
|
const std::string &dialect::drop() const {
|
||||||
return token_at(dialect_token::Drop);
|
return token_at(dialect_token::Drop);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::end_binary_data() const {
|
const std::string &dialect::end_binary_data() const {
|
||||||
return token_at(dialect_token::EndBinaryData);
|
return token_at(dialect_token::EndBinaryData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::end_string_data() const {
|
const std::string &dialect::end_string_data() const {
|
||||||
return token_at(dialect_token::EndStringData);
|
return token_at(dialect_token::EndStringData);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::from() const {
|
const std::string &dialect::from() const {
|
||||||
return token_at(dialect_token::From);
|
return token_at(dialect_token::From);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::in() const {
|
const std::string &dialect::in() const {
|
||||||
return token_at(dialect_token::In);
|
return token_at(dialect_token::In);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::desc() const {
|
const std::string &dialect::desc() const {
|
||||||
return token_at(dialect_token::Desc);
|
return token_at(dialect_token::Desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::distinct() const {
|
const std::string &dialect::distinct() const {
|
||||||
return token_at(dialect_token::Distinct);
|
return token_at(dialect_token::Distinct);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::drop_constraint() const {
|
const std::string &dialect::drop_constraint() const {
|
||||||
return token_at(dialect_token::DropConstraint);
|
return token_at(dialect_token::DropConstraint);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::end_quote() const {
|
const std::string &dialect::end_quote() const {
|
||||||
return token_at(dialect_token::EndQuote);
|
return token_at(dialect_token::EndQuote);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::foreign_key() const {
|
const std::string &dialect::foreign_key() const {
|
||||||
return token_at(dialect_token::ForeignKey);
|
return token_at(dialect_token::ForeignKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::group_by() const {
|
const std::string &dialect::group_by() const {
|
||||||
return token_at(dialect_token::GroupBy);
|
return token_at(dialect_token::GroupBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::insert() const {
|
const std::string &dialect::insert() const {
|
||||||
return token_at(dialect_token::Insert);
|
return token_at(dialect_token::Insert);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::into() const {
|
const std::string &dialect::into() const {
|
||||||
return token_at(dialect_token::Into);
|
return token_at(dialect_token::Into);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::join() const {
|
const std::string &dialect::join() const {
|
||||||
return token_at(dialect_token::Join);
|
return token_at(dialect_token::Join);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::like() const {
|
const std::string &dialect::like() const {
|
||||||
return token_at(dialect_token::Like);
|
return token_at(dialect_token::Like);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::limit() const {
|
const std::string &dialect::limit() const {
|
||||||
return token_at(dialect_token::Limit);
|
return token_at(dialect_token::Limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::not_() const {
|
const std::string &dialect::not_() const {
|
||||||
return token_at(dialect_token::Not);
|
return token_at(dialect_token::Not);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::not_null() const {
|
const std::string &dialect::not_null() const {
|
||||||
return token_at(dialect_token::NotNull);
|
return token_at(dialect_token::NotNull);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::offset() const {
|
const std::string &dialect::offset() const {
|
||||||
return token_at(dialect_token::Offset);
|
return token_at(dialect_token::Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::on() const {
|
const std::string &dialect::on() const {
|
||||||
return token_at(dialect_token::On);
|
return token_at(dialect_token::On);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::or_() const {
|
const std::string &dialect::or_() const {
|
||||||
return token_at(dialect_token::Or);
|
return token_at(dialect_token::Or);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::order_by() const {
|
const std::string &dialect::order_by() const {
|
||||||
return token_at(dialect_token::OrderBy);
|
return token_at(dialect_token::OrderBy);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::primary_key() const {
|
const std::string &dialect::primary_key() const {
|
||||||
return token_at(dialect_token::PrimaryKey);
|
return token_at(dialect_token::PrimaryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::references() const {
|
const std::string &dialect::references() const {
|
||||||
return token_at(dialect_token::References);
|
return token_at(dialect_token::References);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::remove() const {
|
const std::string &dialect::remove() const {
|
||||||
return token_at(dialect_token::Remove);
|
return token_at(dialect_token::Remove);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::rollback() const {
|
const std::string &dialect::rollback() const {
|
||||||
return token_at(dialect_token::Rollback);
|
return token_at(dialect_token::Rollback);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::schema() const {
|
const std::string &dialect::schema() const {
|
||||||
return token_at(dialect_token::Schema);
|
return token_at(dialect_token::Schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::select() const {
|
const std::string &dialect::select() const {
|
||||||
return token_at(dialect_token::Select);
|
return token_at(dialect_token::Select);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::set() const {
|
const std::string &dialect::set() const {
|
||||||
return token_at(dialect_token::Set);
|
return token_at(dialect_token::Set);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::start_quote() const {
|
const std::string &dialect::start_quote() const {
|
||||||
return token_at(dialect_token::StartQuote);
|
return token_at(dialect_token::StartQuote);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::string_quote() const {
|
const std::string &dialect::string_quote() const {
|
||||||
return token_at(dialect_token::StringQuote);
|
return token_at(dialect_token::StringQuote);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::table() const {
|
const std::string &dialect::table() const {
|
||||||
return token_at(dialect_token::Table);
|
return token_at(dialect_token::Table);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string & dialect::unique() const {
|
const std::string &dialect::unique() const {
|
||||||
return token_at(dialect_token::Unique);
|
return token_at(dialect_token::Unique);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::update() const {
|
const std::string &dialect::update() const {
|
||||||
return token_at(dialect_token::Update);
|
return token_at(dialect_token::Update);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::values() const {
|
const std::string &dialect::values() const {
|
||||||
return token_at(dialect_token::Values);
|
return token_at(dialect_token::Values);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string& dialect::where() const {
|
const std::string &dialect::where() const {
|
||||||
return token_at(dialect_token::Where);
|
return token_at(dialect_token::Where);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,6 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record
|
||||||
|
|
||||||
const table tab("types");
|
const table tab("types");
|
||||||
|
|
||||||
// auto r = query::create().table(tab).columns({
|
|
||||||
// column("id", basic_type::UInt32)
|
|
||||||
// });
|
|
||||||
auto res = query::create()
|
auto res = query::create()
|
||||||
.table(tab)
|
.table(tab)
|
||||||
.columns({
|
.columns({
|
||||||
|
|
@ -46,8 +43,8 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record
|
||||||
column("val_double", basic_type::Double),
|
column("val_double", basic_type::Double),
|
||||||
column("val_string", basic_type::Text),
|
column("val_string", basic_type::Text),
|
||||||
column("val_varchar", basic_type::Varchar, 63),
|
column("val_varchar", basic_type::Varchar, 63),
|
||||||
// column("val_date", basic_type::type_date),
|
column("val_date", basic_type::Date),
|
||||||
// column("val_time", basic_type::type_time),
|
column("val_time", basic_type::Time),
|
||||||
column("val_blob", basic_type::Blob),
|
column("val_blob", basic_type::Blob),
|
||||||
})
|
})
|
||||||
.constraints({
|
.constraints({
|
||||||
|
|
@ -66,7 +63,7 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record
|
||||||
"val_bool",
|
"val_bool",
|
||||||
"val_float", "val_double",
|
"val_float", "val_double",
|
||||||
"val_string", "val_varchar",
|
"val_string", "val_varchar",
|
||||||
// "val_date", "val_time",
|
"val_date", "val_time",
|
||||||
"val_blob"};
|
"val_blob"};
|
||||||
|
|
||||||
const auto fields = db.describe("types");
|
const auto fields = db.describe("types");
|
||||||
|
|
@ -89,41 +86,43 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record
|
||||||
double d{2.71828};
|
double d{2.71828};
|
||||||
std::string str{"long text"};
|
std::string str{"long text"};
|
||||||
std::string varchar{"good day"};
|
std::string varchar{"good day"};
|
||||||
// auto md{matador::date()};
|
date_type_t md{2025, 11, 27};
|
||||||
// auto mt{matador::time::now()};
|
time_type_t mt{12, 34, 56};
|
||||||
blob bin{0x01,0x02,0x03,0x04};
|
blob bin{0x01,0x02,0x03,0x04};
|
||||||
|
|
||||||
res = query::insert()
|
res = query::insert()
|
||||||
.into("types", cols)
|
.into("types", cols)
|
||||||
.values({id, c, s, i, ll, uc, us, ui, ull, b, f, d, str, varchar, /*md, mt, */bin})
|
.values({id, c, s, i, ll, uc, us, ui, ull, b, f, d, str, varchar, md, mt, bin})
|
||||||
.execute(db);
|
.execute(db);
|
||||||
REQUIRE(res.is_ok());
|
REQUIRE(res.is_ok());
|
||||||
REQUIRE(res.value() == 1);
|
REQUIRE(res.value() == 1);
|
||||||
|
|
||||||
auto row = query::select(cols)
|
auto result = query::select(cols)
|
||||||
.from("types")
|
.from("types")
|
||||||
.fetch_one(db);
|
.fetch_one(db);
|
||||||
|
|
||||||
REQUIRE(row.is_ok());
|
REQUIRE(result.is_ok());
|
||||||
REQUIRE(row.value().has_value());
|
REQUIRE(result.value().has_value());
|
||||||
|
|
||||||
REQUIRE(id == (*row)->at<uint32_t>("id"));
|
const auto &row = result.value().value();
|
||||||
REQUIRE(c == (*row)->at<int8_t>("val_char"));
|
REQUIRE(id == row.at<uint32_t>("id"));
|
||||||
REQUIRE(s == (*row)->at<int16_t>("val_short"));
|
REQUIRE(c == row.at<int8_t>("val_char"));
|
||||||
REQUIRE(i == (*row)->at<int32_t>("val_int"));
|
REQUIRE(s == row.at<int16_t>("val_short"));
|
||||||
REQUIRE(ll == (*row)->at<int64_t>("val_long_long"));
|
REQUIRE(i == row.at<int32_t>("val_int"));
|
||||||
REQUIRE(uc == (*row)->at<uint8_t>("val_uchar"));
|
REQUIRE(ll == row.at<int64_t>("val_long_long"));
|
||||||
REQUIRE(us == (*row)->at<unsigned short>("val_ushort"));
|
REQUIRE(uc == row.at<uint8_t>("val_uchar"));
|
||||||
REQUIRE(ui == (*row)->at<unsigned int>("val_uint"));
|
REQUIRE(us == row.at<unsigned short>("val_ushort"));
|
||||||
REQUIRE(ull == (*row)->at<uint64_t>("val_ulong_long"));
|
REQUIRE(ui == row.at<unsigned int>("val_uint"));
|
||||||
REQUIRE((*row)->at<bool>("val_bool"));
|
REQUIRE(ull == row.at<uint64_t>("val_ulong_long"));
|
||||||
REQUIRE(f == (*row)->at<float>("val_float"));
|
REQUIRE(row.at<bool>("val_bool"));
|
||||||
REQUIRE(d == (*row)->at<double>("val_double"));
|
REQUIRE(f == row.at<float>("val_float"));
|
||||||
REQUIRE(str == (*row)->at<std::string>("val_string"));
|
REQUIRE(d == row.at<double>("val_double"));
|
||||||
REQUIRE(varchar == (*row)->at<std::string>("val_varchar"));
|
REQUIRE(str == row.at<std::string>("val_string"));
|
||||||
// REQUIRE(md == (*row)->at<matador::date>("val_date"));
|
REQUIRE(varchar == row.at<std::string>("val_varchar"));
|
||||||
// REQUIRE(mt == (*row)->at<matador::time>("val_time"));
|
REQUIRE(md == row.at<date_type_t>("val_date"));
|
||||||
REQUIRE(bin == (*row)->at<blob>("val_blob"));
|
const auto mtres = row.at<time_type_t>("val_time");
|
||||||
|
REQUIRE(mt == row.at<time_type_t>("val_time"));
|
||||||
|
REQUIRE(bin == row.at<blob>("val_blob"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE_METHOD(QueryFixture, "Create and drop table statement", "[query][record]")
|
TEST_CASE_METHOD(QueryFixture, "Create and drop table statement", "[query][record]")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue