#include "postgres_result_reader.hpp" #include "matador/utils/convert.hpp" #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_)) {} postgres_result_reader::~postgres_result_reader() { if (result_) { PQclear(result_); } } size_t postgres_result_reader::column_count() const { return column_count_; } const char *postgres_result_reader::column( const size_t index) const { return PQgetvalue(result_, static_cast(row_index_), static_cast(index)); } utils::result postgres_result_reader::fetch() { return utils::ok(++row_index_ < row_count_); } size_t postgres_result_reader::start_column_index() const { return 0; } void postgres_result_reader::unshift() { if (row_index_ > 0) { --row_index_; } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, int8_t &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, int16_t &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, int32_t &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, int64_t &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, uint8_t &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, uint16_t &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, uint32_t &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, uint64_t &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, bool &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, float &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, double &value) { if (auto res = utils::to(column(index)); res.is_ok()) { value = res.value(); } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, time &/*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) { // value.set(val, matador::utils::date_format::ISO8601); // } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, char *value, size_t size) { auto val = column(index); if (const size_t len = strlen(val); len > size) { #ifdef _MSC_VER strncpy_s(value, size, val, len); #else strncpy(value, val, size); #endif value[size-1] = '\n'; } else { #ifdef _MSC_VER strcpy_s(value, size, val); #else strcpy(value, val); #endif } } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, std::string &value) { value.assign(column(index)); } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, std::string &value, size_t /*s*/) { 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(column(index)); // auto length = PQgetlength(result_, row_index_, static_cast(index)); size_t length; unsigned char* unescaped = PQunescapeBytea(data, &length); value.assign(unescaped, unescaped+length); } template void set_value(const char* str, utils::value& value) { if (const auto res = utils::to(str); res.is_ok()) { value = res.value(); } } template <> void set_value(const char* str, utils::value& value) { size_t length; unsigned char* unescaped = PQunescapeBytea(reinterpret_cast(str), &length); value = utils::blob(unescaped, unescaped+length); } void postgres_result_reader::read_value(const char * /*id*/, const size_t index, utils::value &val, size_t) { switch (val.type()) { case utils::basic_type::type_int8: set_value(column(index), val); break; case utils::basic_type::type_int16: set_value(column(index), val); break; case utils::basic_type::type_int32: set_value(column(index), val); break; case utils::basic_type::type_int64: set_value(column(index), val); break; case utils::basic_type::type_uint8: set_value(column(index), val); break; case utils::basic_type::type_uint16: set_value(column(index), val); break; case utils::basic_type::type_uint32: set_value(column(index), val); break; case utils::basic_type::type_uint64: set_value(column(index), val); break; case utils::basic_type::type_float: set_value(column(index), val); break; case utils::basic_type::type_double: set_value(column(index), val); break; case utils::basic_type::type_bool: set_value(column(index), val); break; case utils::basic_type::type_text: case utils::basic_type::type_varchar: { if (const auto *column_value = column(index); column_value == nullptr) { val = std::string{}; } else { val = std::string{column_value}; } break; } case utils::basic_type::type_time: case utils::basic_type::type_date: { val = std::string{column(index)}; break; } case utils::basic_type::type_null: { val = nullptr_t{}; break; } case utils::basic_type::type_blob: { set_value(column(index), val); break; } } } utils::attribute_reader &postgres_result_reader::result_binder() { return empty_binder_; } } // namespace matador::backends::postgres