added test for date and time, sql read and write functionality

This commit is contained in:
Sascha Kühl 2026-01-06 22:23:50 +01:00
parent 0c6b5a0a93
commit c48bd4f9d6
17 changed files with 516 additions and 360 deletions

View File

@ -9,8 +9,7 @@ namespace matador::backends::postgres {
namespace detail {
class empty_binder final : public utils::attribute_reader
{
class empty_binder final : public utils::attribute_reader {
public:
void read_value(const char *, size_t, int8_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, float &) 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, date &) override {}
void read_value(const char *, size_t, utils::date_type_t &) 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, std::string &) 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:
explicit postgres_result_reader(PGresult *result);
~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, float &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, matador::date &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, 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, std::string &value) override;
void read_value(const char *id, size_t index, std::string &value, size_t size) override;

View File

@ -178,8 +178,10 @@ utils::basic_type oid2type(const Oid oid) {
return utils::basic_type::Double;
case 1082:
return utils::basic_type::Date;
case 1114:
case 1083:
return utils::basic_type::Time;
case 1114:
return utils::basic_type::DateTime;
default:
return utils::basic_type::Null;
}
@ -201,9 +203,12 @@ utils::basic_type string2type(const char *type) {
if (strcmp(type, "date") == 0) {
return utils::basic_type::Date;
}
if (strcmp(type, "timestamp") == 0) {
if (strcmp(type, "time") == 0) {
return utils::basic_type::Time;
}
if (strcmp(type, "timestamp") == 0) {
return utils::basic_type::DateTime;
}
if (strcmp(type, "float4") == 0) {
return utils::basic_type::Float;
}

View File

@ -20,7 +20,8 @@
{matador::utils::basic_type::UInt8, "SMALLINT"},
{matador::utils::basic_type::Float, "REAL"},
{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"}
})
.with_bool_strings("TRUE", "FALSE")

View File

@ -123,15 +123,23 @@ void postgres_parameter_binder::write_value(const size_t pos, const std::string
write_value(pos, 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);
void postgres_parameter_binder::write_value(const size_t pos, const utils::date_type_t &x) {
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_.lengths[pos] = static_cast<int>(bind_data_.strings[pos].size());
bind_data_.formats[pos] = 0;
}
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");
void postgres_parameter_binder::write_value(const size_t pos, const utils::time_type_t &x) {
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_.lengths[pos] = static_cast<int>(bind_data_.strings[pos].size());
bind_data_.formats[pos] = 0;

View File

@ -4,27 +4,23 @@
#include "matador/utils/value.hpp"
namespace matador::backends::postgres {
postgres_result_reader::postgres_result_reader(PGresult *result)
: result_(result)
, row_count_(PQntuples(result_))
, column_count_(PQnfields(result_))
{}
, row_count_(PQntuples(result_))
, column_count_(PQnfields(result_)) {
}
postgres_result_reader::~postgres_result_reader()
{
postgres_result_reader::~postgres_result_reader() {
if (result_) {
PQclear(result_);
}
}
size_t postgres_result_reader::column_count() const
{
size_t postgres_result_reader::column_count() const {
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));
}
@ -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*/) {
// if (const auto val = column(index); strlen(val) > 0) {
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) {
// value = time::parse(val, "%Y-%m-%d %T.%f");
// }
}
}
void postgres_result_reader::read_value(const char * /*id*/, const size_t /*index*/, date &/*value*/) {
// if (const auto val = column(index); strlen(val) > 0) {
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) {
// 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) {
@ -126,7 +127,7 @@ void postgres_result_reader::read_value(const char * /*id*/, const size_t index,
#else
strncpy(value, val, size);
#endif
value[size-1] = '\n';
value[size - 1] = '\n';
} else {
#ifdef _MSC_VER
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));
}
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));
// auto length = PQgetlength(result_, row_index_, static_cast<int>(index));
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));
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);
}
template <typename Type>
void set_value(const char* str, utils::value& value) {
template<typename Type>
void set_value(const char *str, utils::value &value) {
if (const auto res = utils::to<Type>(str); res.is_ok()) {
value = res.value();
}
}
template <>
void set_value<utils::blob>(const char* str, utils::value& value) {
template<>
void set_value<utils::blob>(const char *str, utils::value &value) {
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);
}
@ -219,8 +218,13 @@ void postgres_result_reader::read_value(const char * /*id*/, const size_t index,
break;
}
case utils::basic_type::Time:
case utils::basic_type::Date: {
val = std::string{column(index)};
set_value<utils::time_type_t>(column(index), val);
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;
}
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);
break;
}
case utils::basic_type::Unknown:
break;
}
}
utils::attribute_reader &postgres_result_reader::result_binder() {
return empty_binder_;
}
} // namespace matador::backends::postgres

View File

@ -69,7 +69,7 @@ public:
[[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
*/
@ -259,7 +259,8 @@ private:
{utils::basic_type::Varchar, "VARCHAR"},
{utils::basic_type::Text, "TEXT"},
{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::Null, "NULL"}
};

View File

@ -5,10 +5,6 @@
#include <string>
namespace matador {
class date;
class time;
}
namespace matador::utils {
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, 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, time &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, time_type_t &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, std::string &value) = 0;
virtual void read_value(const char *id, size_t index, std::string &value, size_t size) = 0;

View File

@ -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) {
std::tm result{};
std::istringstream iss(source);
iss >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
return ok(result);
iss >> std::get_time(&result, "%Y-%m-%d");
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 >
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::istringstream iss(source);
iss >> std::get_time(&result, "%Y-%m-%d %H:%M:%S");
return ok(result);
iss >> std::get_time(&result, "%H:%M:%S");
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 >
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, timestamp>>* = nullptr) {
std::tm result{};
std::istringstream iss(source);
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 >
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);
@ -351,6 +382,104 @@ result<DestType, conversion_error> to(const SourceType &/*source*/, std::enable_
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

View File

@ -8,159 +8,162 @@
#include <string>
namespace matador::utils {
/// @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 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*/,
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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 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);
};
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; }
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) {
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) {
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 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);
};
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 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);
};
//template <> struct data_type_traits<matador::date, void>
//{
// static basic_type type(std::size_t /*size*/) { return basic_type::type_date; }
// static void read_value(attribute_reader &reader, const char *id, size_t index, matador::date &value);
// static void bind_value(attribute_writer &binder, size_t index, matador::date &value);
//};
//
//template <> struct data_type_traits<matador::time, void>
//{
// static basic_type type(std::size_t /*size*/) { return basic_type::type_time; }
// static void read_value(attribute_reader &reader, const char *id, size_t index, matador::time &value);
// static void bind_value(attribute_writer &binder, size_t index, matador::time &value);
//};
template<>
struct data_type_traits<date_type_t, void> {
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, date_type_t &value);
static void bind_value(attribute_writer &binder, size_t index, date_type_t &value);
};
template < typename EnumType >
struct data_type_traits<EnumType, std::enable_if_t<std::is_enum_v<EnumType>>>
{
template<>
struct data_type_traits<time_type_t, void> {
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, time_type_t &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; }
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) {
data_type_traits<int>::bind_value(binder, index, static_cast<int &>(value), size);
}
};
/// @endcond
/// @endcond
}
#endif //MATADOR_DEFAULT_TYPE_TRAITS_HPP

View File

@ -19,6 +19,8 @@ namespace matador::utils {
* @return Binary data as string
*/
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

View File

@ -127,28 +127,24 @@ void data_type_traits<blob>::read_value(attribute_reader &reader, const char *id
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);
}
// void data_type_traits<matador::date>::read_value(attribute_reader &reader, const char *id, size_t index, date &value)
// {
// reader.read_value(id, index, value);
// }
//
// void data_type_traits<matador::date>::bind_value(attribute_writer &binder, size_t index, date &value)
// {
// binder.write_value(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<matador::time>::bind_value(attribute_writer &binder, size_t index, time &value)
// {
// binder.write_value(index, 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);
}
void data_type_traits<date_type_t>::bind_value(attribute_writer &binder, const size_t index, date_type_t &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<time_type_t>::bind_value(attribute_writer &binder, const size_t index, time_type_t &value) {
binder.write_value(index, value);
}
}

View File

@ -18,6 +18,24 @@ std::string to_string(const blob& data) {
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)
{
std::stringstream ss(str);

View File

@ -9,104 +9,108 @@
#include "matador/utils/string.hpp"
namespace matador::query {
attribute_string_writer::attribute_string_writer(const sql::dialect &d, const std::optional<std::reference_wrapper<const sql::connection_impl>> conn)
attribute_string_writer::attribute_string_writer(const sql::dialect &d,
const std::optional<std::reference_wrapper<const
sql::connection_impl> > conn)
: dialect_(d)
, conn_(conn) {}
, conn_(conn) {
}
const sql::dialect& attribute_string_writer::dialect() const {
const sql::dialect &attribute_string_writer::dialect() const {
return dialect_;
}
void attribute_string_writer::write_value(size_t /*pos*/, const int8_t& x ) {
result_ = std::to_string(x) ;
void attribute_string_writer::write_value(size_t /*pos*/, const int8_t &x) {
result_ = std::to_string(x);
}
void attribute_string_writer::write_value(size_t /*pos*/, const int16_t& x ) {
result_ = std::to_string(x) ;
void attribute_string_writer::write_value(size_t /*pos*/, const int16_t &x) {
result_ = std::to_string(x);
}
void attribute_string_writer::write_value(size_t /*pos*/, const int32_t& x ) {
result_ = std::to_string(x) ;
void attribute_string_writer::write_value(size_t /*pos*/, const int32_t &x) {
result_ = std::to_string(x);
}
void attribute_string_writer::write_value(size_t /*pos*/, const int64_t& x ) {
result_ = std::to_string(x) ;
void attribute_string_writer::write_value(size_t /*pos*/, const int64_t &x) {
result_ = std::to_string(x);
}
void attribute_string_writer::write_value(size_t /*pos*/, const uint8_t& x ) {
result_ = std::to_string(x) ;
void attribute_string_writer::write_value(size_t /*pos*/, const uint8_t &x) {
result_ = std::to_string(x);
}
void attribute_string_writer::write_value(size_t /*pos*/, const uint16_t& x ) {
result_ = std::to_string(x) ;
void attribute_string_writer::write_value(size_t /*pos*/, const uint16_t &x) {
result_ = std::to_string(x);
}
void attribute_string_writer::write_value(size_t /*pos*/, const uint32_t& x ) {
result_ = std::to_string(x) ;
void attribute_string_writer::write_value(size_t /*pos*/, const uint32_t &x) {
result_ = std::to_string(x);
}
void attribute_string_writer::write_value(size_t /*pos*/, const uint64_t& x ) {
result_ = std::to_string(x) ;
void attribute_string_writer::write_value(size_t /*pos*/, const uint64_t &x) {
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") + "'";
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);
}
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()) {
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()) {
result_ = *res;
}
}
void attribute_string_writer::write_value(size_t /*pos*/, const utils::date_type_t& /*x*/ ) {
// result_ = "'" + dialect_.prepare_literal(utils::to_string(x)) + "'";
void attribute_string_writer::write_value(size_t /*pos*/, const utils::date_type_t &x) {
result_ = "'" + dialect_.prepare_literal(utils::to_string(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")) + "'";
void attribute_string_writer::write_value(size_t /*pos*/, const utils::time_type_t &x) {
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 char* x ) {
write_value(pos, std::string(x) );
void attribute_string_writer::write_value(size_t pos, const char *x) {
write_value(pos, std::string(x));
}
void attribute_string_writer::write_value(size_t pos, const char* x, size_t /*size*/) {
write_value(pos, std::string(x) );
void attribute_string_writer::write_value(size_t pos, const char *x, size_t /*size*/) {
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) + "'";
}
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) + "'";
}
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:
// MySQL: X'5468697320697320612062616E617279204461746120737472696E67'
// Postgres: '\\x5468697320697320612062616E617279204461746120737472696E67'
// MSSQL: 0x5468697320697320612062616E617279204461746120737472696E67
// Sqlite: X'5468697320697320612062616E617279204461746120737472696E67'
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 {
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*/) {
}
}

View File

@ -3,49 +3,47 @@
#include "matador/sql/interface/query_result_reader.hpp"
namespace matador::sql {
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)
, prototype_(std::move(prototype))
, reader_(std::move(reader))
, pk_reader_(*reader_)
{}
, prototype_(std::move(prototype))
, reader_(std::move(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)
, prototype_(prototype)
, reader_(std::move(reader))
, pk_reader_(*reader_)
{}
, prototype_(prototype)
, reader_(std::move(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);
reader_->read_value(id, column_index_++, rev);
}
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());
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());
}
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());
}
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());
}
const std::vector<object::attribute>& query_result_impl::prototype() const
{
const std::vector<object::attribute> &query_result_impl::prototype() const {
return prototype_;
}
}

View File

@ -61,15 +61,16 @@ void value_extractor::write_value(size_t /*pos*/, const double &x) {
values_.emplace_back(x);
}
void value_extractor::write_value(size_t /*pos*/, const utils::date_type_t &/*x*/) {
// values_.emplace_back(x);
void value_extractor::write_value(size_t /*pos*/, const utils::date_type_t &x) {
values_.emplace_back(x);
}
void value_extractor::write_value(size_t /*pos*/, const utils::time_type_t &/*x*/) {
// values_.emplace_back(x);
void value_extractor::write_value(size_t /*pos*/, const utils::time_type_t &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) {

View File

@ -6,8 +6,7 @@
#include "matador/utils/value.hpp"
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);
}
@ -15,22 +14,21 @@ const std::string &dialect::data_type_at(const utils::basic_type type) const {
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);
}
std::string dialect::table_name( const std::string& table, const std::string& schema_name ) const {
if ( schema_name.empty() && default_schema_name_.empty()) {
return prepare_identifier_string( table );
std::string dialect::table_name(const std::string &table, const std::string &schema_name) const {
if (schema_name.empty() && default_schema_name_.empty()) {
return prepare_identifier_string(table);
}
if ( schema_name.empty() ) {
return prepare_identifier_string( default_schema_name_ ) + "." + prepare_identifier_string( table );
if (schema_name.empty()) {
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)];
}
@ -45,38 +43,33 @@ std::string dialect::to_sql_string(const utils::value &val) const {
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_[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, '.');
for (auto &part : parts) {
for (auto &part: parts) {
escape_quotes_in_identifier(part);
quote_identifier(part);
}
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);
escape_quotes_in_literals(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 += 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 close_char(token_at(dialect_token::EndQuote));
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 double_quote(token_at(dialect_token::StringQuote) + token_at(dialect_token::StringQuote));
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;
}
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());
}
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) {
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);
}
std::string dialect::default_schema_name() const
{
std::string dialect::default_schema_name() const {
return default_schema_name_;
}
const std::string& dialect::add_constraint() const {
const std::string &dialect::add_constraint() const {
return token_at(dialect_token::AddConstraint);
}
const std::string& dialect::alter() const {
const std::string &dialect::alter() const {
return token_at(dialect_token::Alter);
}
const std::string& dialect::and_() const {
const std::string &dialect::and_() const {
return token_at(dialect_token::And);
}
const std::string& dialect::as() const {
const std::string &dialect::as() const {
return token_at(dialect_token::As);
}
const std::string& dialect::asc() const {
const std::string &dialect::asc() const {
return token_at(dialect_token::Asc);
}
const std::string& dialect::begin() const {
const std::string &dialect::begin() const {
return token_at(dialect_token::Begin);
}
const std::string& dialect::asterisk() const {
const std::string &dialect::asterisk() const {
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);
}
const std::string& dialect::begin_string_data() const {
const std::string &dialect::begin_string_data() const {
return token_at(dialect_token::BeginStringData);
}
const std::string& dialect::between() const {
const std::string &dialect::between() const {
return token_at(dialect_token::Between);
}
const std::string& dialect::column() const {
const std::string &dialect::column() const {
return token_at(dialect_token::Column);
}
const std::string& dialect::columns() const {
const std::string &dialect::columns() const {
return token_at(dialect_token::Columns);
}
const std::string& dialect::commit() const {
const std::string &dialect::commit() const {
return token_at(dialect_token::Commit);
}
const std::string& dialect::constraint() const {
const std::string &dialect::constraint() const {
return token_at(dialect_token::Constraint);
}
const std::string& dialect::create() const {
const std::string &dialect::create() const {
return token_at(dialect_token::Create);
}
const std::string& dialect::drop() const {
const std::string &dialect::drop() const {
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);
}
const std::string& dialect::end_string_data() const {
const std::string &dialect::end_string_data() const {
return token_at(dialect_token::EndStringData);
}
const std::string& dialect::from() const {
const std::string &dialect::from() const {
return token_at(dialect_token::From);
}
const std::string& dialect::in() const {
const std::string &dialect::in() const {
return token_at(dialect_token::In);
}
const std::string& dialect::desc() const {
const std::string &dialect::desc() const {
return token_at(dialect_token::Desc);
}
const std::string& dialect::distinct() const {
const std::string &dialect::distinct() const {
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);
}
const std::string& dialect::end_quote() const {
const std::string &dialect::end_quote() const {
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);
}
const std::string& dialect::group_by() const {
const std::string &dialect::group_by() const {
return token_at(dialect_token::GroupBy);
}
const std::string& dialect::insert() const {
const std::string &dialect::insert() const {
return token_at(dialect_token::Insert);
}
const std::string& dialect::into() const {
const std::string &dialect::into() const {
return token_at(dialect_token::Into);
}
const std::string& dialect::join() const {
const std::string &dialect::join() const {
return token_at(dialect_token::Join);
}
const std::string& dialect::like() const {
const std::string &dialect::like() const {
return token_at(dialect_token::Like);
}
const std::string& dialect::limit() const {
const std::string &dialect::limit() const {
return token_at(dialect_token::Limit);
}
const std::string& dialect::not_() const {
const std::string &dialect::not_() const {
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);
}
const std::string& dialect::offset() const {
const std::string &dialect::offset() const {
return token_at(dialect_token::Offset);
}
const std::string& dialect::on() const {
const std::string &dialect::on() const {
return token_at(dialect_token::On);
}
const std::string& dialect::or_() const {
const std::string &dialect::or_() const {
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);
}
const std::string& dialect::primary_key() const {
const std::string &dialect::primary_key() const {
return token_at(dialect_token::PrimaryKey);
}
const std::string& dialect::references() const {
const std::string &dialect::references() const {
return token_at(dialect_token::References);
}
const std::string& dialect::remove() const {
const std::string &dialect::remove() const {
return token_at(dialect_token::Remove);
}
const std::string& dialect::rollback() const {
const std::string &dialect::rollback() const {
return token_at(dialect_token::Rollback);
}
const std::string& dialect::schema() const {
const std::string &dialect::schema() const {
return token_at(dialect_token::Schema);
}
const std::string& dialect::select() const {
const std::string &dialect::select() const {
return token_at(dialect_token::Select);
}
const std::string& dialect::set() const {
const std::string &dialect::set() const {
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);
}
const std::string& dialect::string_quote() const {
const std::string &dialect::string_quote() const {
return token_at(dialect_token::StringQuote);
}
const std::string& dialect::table() const {
const std::string &dialect::table() const {
return token_at(dialect_token::Table);
}
const std::string & dialect::unique() const {
const std::string &dialect::unique() const {
return token_at(dialect_token::Unique);
}
const std::string& dialect::update() const {
const std::string &dialect::update() const {
return token_at(dialect_token::Update);
}
const std::string& dialect::values() const {
const std::string &dialect::values() const {
return token_at(dialect_token::Values);
}
const std::string& dialect::where() const {
const std::string &dialect::where() const {
return token_at(dialect_token::Where);
}
}

View File

@ -26,9 +26,6 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record
const table tab("types");
// auto r = query::create().table(tab).columns({
// column("id", basic_type::UInt32)
// });
auto res = query::create()
.table(tab)
.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_string", basic_type::Text),
column("val_varchar", basic_type::Varchar, 63),
// column("val_date", basic_type::type_date),
// column("val_time", basic_type::type_time),
column("val_date", basic_type::Date),
column("val_time", basic_type::Time),
column("val_blob", basic_type::Blob),
})
.constraints({
@ -66,7 +63,7 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record
"val_bool",
"val_float", "val_double",
"val_string", "val_varchar",
// "val_date", "val_time",
"val_date", "val_time",
"val_blob"};
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};
std::string str{"long text"};
std::string varchar{"good day"};
// auto md{matador::date()};
// auto mt{matador::time::now()};
date_type_t md{2025, 11, 27};
time_type_t mt{12, 34, 56};
blob bin{0x01,0x02,0x03,0x04};
res = query::insert()
.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);
REQUIRE(res.is_ok());
REQUIRE(res.value() == 1);
auto row = query::select(cols)
auto result = query::select(cols)
.from("types")
.fetch_one(db);
REQUIRE(row.is_ok());
REQUIRE(row.value().has_value());
REQUIRE(result.is_ok());
REQUIRE(result.value().has_value());
REQUIRE(id == (*row)->at<uint32_t>("id"));
REQUIRE(c == (*row)->at<int8_t>("val_char"));
REQUIRE(s == (*row)->at<int16_t>("val_short"));
REQUIRE(i == (*row)->at<int32_t>("val_int"));
REQUIRE(ll == (*row)->at<int64_t>("val_long_long"));
REQUIRE(uc == (*row)->at<uint8_t>("val_uchar"));
REQUIRE(us == (*row)->at<unsigned short>("val_ushort"));
REQUIRE(ui == (*row)->at<unsigned int>("val_uint"));
REQUIRE(ull == (*row)->at<uint64_t>("val_ulong_long"));
REQUIRE((*row)->at<bool>("val_bool"));
REQUIRE(f == (*row)->at<float>("val_float"));
REQUIRE(d == (*row)->at<double>("val_double"));
REQUIRE(str == (*row)->at<std::string>("val_string"));
REQUIRE(varchar == (*row)->at<std::string>("val_varchar"));
// REQUIRE(md == (*row)->at<matador::date>("val_date"));
// REQUIRE(mt == (*row)->at<matador::time>("val_time"));
REQUIRE(bin == (*row)->at<blob>("val_blob"));
const auto &row = result.value().value();
REQUIRE(id == row.at<uint32_t>("id"));
REQUIRE(c == row.at<int8_t>("val_char"));
REQUIRE(s == row.at<int16_t>("val_short"));
REQUIRE(i == row.at<int32_t>("val_int"));
REQUIRE(ll == row.at<int64_t>("val_long_long"));
REQUIRE(uc == row.at<uint8_t>("val_uchar"));
REQUIRE(us == row.at<unsigned short>("val_ushort"));
REQUIRE(ui == row.at<unsigned int>("val_uint"));
REQUIRE(ull == row.at<uint64_t>("val_ulong_long"));
REQUIRE(row.at<bool>("val_bool"));
REQUIRE(f == row.at<float>("val_float"));
REQUIRE(d == row.at<double>("val_double"));
REQUIRE(str == row.at<std::string>("val_string"));
REQUIRE(varchar == row.at<std::string>("val_varchar"));
REQUIRE(md == row.at<date_type_t>("val_date"));
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]")