fixed backend tests (progress)

This commit is contained in:
Sascha Kühl 2025-02-14 16:01:22 +01:00
parent d070a5a0ac
commit 6e64ba99de
6 changed files with 89 additions and 22 deletions

View File

@ -10,6 +10,7 @@
#include "matador/sql/internal/query_result_impl.hpp"
#include <algorithm>
#include <sstream>
namespace matador::backends::postgres {
@ -79,6 +80,8 @@ utils::result<utils::version, utils::error> postgres_connection::server_version(
});
}
utils::basic_type oid2type(Oid oid);
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_connection::fetch(const sql::query_context &context) {
PGresult *res = PQexec(conn_, context.sql.c_str());
@ -86,16 +89,28 @@ utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> postgres_co
return utils::failure(make_error(sql::error_code::FETCH_FAILED, res, conn_, "Failed to fetch", context.sql));
}
// std::vector<object::column_definition> prototype;
// const auto num_col = PQnfields(res);
// for (int i = 0; i < num_col; ++i) {
// const char *col_name = PQfname(res, i);
// auto type = PQftype(res, i);
// auto size = PQfmod(res, i);
// prototype.emplace_back(col_name);
// const auto is_unknown = std::all_of( context.prototype.begin(), context.prototype.end(), [](const object::attribute_definition &a) {return a.is_null();} );
// if (!is_unknown) {
// return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), context.prototype));
// }
return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), context.prototype));
std::vector<object::attribute_definition> prototype = context.prototype;
const auto num_col = PQnfields(res);
if (prototype.size() != num_col) {
return utils::failure(make_error(sql::error_code::FETCH_FAILED, res, conn_, "Number of received columns doesn't match expected columns.", context.sql));
}
for (int i = 0; i < num_col; ++i) {
if (!prototype.at(i).is_null()) {
continue;
}
const auto type = oid2type(PQftype(res, i));
// const char *col_name = PQfname(res, i);
// const auto size = PQfmod(res, i);
prototype.at(i).type(type);
}
return utils::ok(std::make_unique<sql::query_result_impl>(std::make_unique<postgres_result_reader>(res), prototype));
}
std::string postgres_connection::generate_statement_name(const sql::query_context &query) {
@ -141,6 +156,37 @@ utils::result<size_t, utils::error> postgres_connection::execute(const std::stri
return utils::ok(static_cast<size_t>(affected_rows));
}
utils::basic_type oid2type(const Oid oid) {
switch (oid) {
case 16:
return utils::basic_type::type_bool;
case 17:
return utils::basic_type::type_blob;
case 18:
return utils::basic_type::type_int8;
case 21:
return utils::basic_type::type_int16;
case 23:
return utils::basic_type::type_int32;
case 20:
return utils::basic_type::type_int64;
case 24:
return utils::basic_type::type_text;
case 1043:
return utils::basic_type::type_varchar;
case 700:
return utils::basic_type::type_float;
case 701:
return utils::basic_type::type_double;
case 1082:
return utils::basic_type::type_date;
case 1114:
return utils::basic_type::type_time;
default:
return utils::basic_type::type_null;
}
}
utils::basic_type string2type(const char *type) {
if (strcmp(type, "int2") == 0) {
return utils::basic_type::type_int16;

View File

@ -13,7 +13,7 @@
return "$" + std::to_string(index);
})
.with_token_replace_map({
{dialect_token::BEGIN_BINARY_DATA, "'"}
{dialect_token::BEGIN_BINARY_DATA, "'\\x"}
})
.with_data_type_replace_map({
{matador::utils::basic_type::type_int8, "SMALLINT"},

View File

@ -131,7 +131,7 @@ result<DestType, conversion_error> to(const std::string &source, std::enable_if_
}
template < typename DestType >
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_integral_v<DestType> && std::is_unsigned_v<DestType>>* = nullptr)
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_integral_v<DestType> && std::is_unsigned_v<DestType> && !std::is_same_v<DestType, bool>>* = nullptr)
{
if (source.empty()) {
return failure(conversion_error::MissingData/*, "failed to convert empty string"}*/);
@ -167,17 +167,27 @@ result<DestType, conversion_error> to(const blob &source, std::enable_if_t<std::
return ok(source);
}
// template < typename DestType >
// result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, blob>>* = nullptr) {
// if (source.empty()) {
// return failure(conversion_error::MissingData/*, "failed to convert empty string"}*/);
// }
//
// }
//
static std::unordered_map<std::string, bool> string_to_bool_map = {
{"true", true},
{"t", true},
{"on", true},
{"1", true},
{"false", false},
{"f", false},
{"off", false},
{"0", false}
};
template < typename DestType, typename SourceType >
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_same_v<SourceType, std::string> &&std::is_same_v<DestType, bool>>* = nullptr) {
template < typename DestType >
result<DestType, conversion_error> to(const std::string &source, std::enable_if_t<std::is_same_v<DestType, bool>>* = nullptr) {
if (source.empty()) {
return failure(conversion_error::MissingData);
}
@ -188,6 +198,18 @@ result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t
return ok(it->second);
}
template < typename DestType >
result<DestType, conversion_error> to(const char *source, std::enable_if_t<std::is_same_v<DestType, bool>>* = nullptr) {
if (strlen(source) == 0) {
return failure(conversion_error::MissingData);
}
const auto it = string_to_bool_map.find(source);
if (it == string_to_bool_map.end()) {
return failure(conversion_error::NotConvertable);
}
return ok(it->second);
}
template < typename DestType, typename SourceType >
result<DestType, conversion_error> to(const SourceType &source, std::enable_if_t<std::is_same_v<SourceType, bool> &&std::is_same_v<DestType, std::string>>* = nullptr) {
return ok(std::string(source ? "true" : "false"));

View File

@ -1,6 +1,6 @@
#include "matador/query/attribute_string_writer.hpp"
// #include "matador/sql/connection_impl.hpp"
#include "matador/sql/interface/connection_impl.hpp"
#include <matador/utils/convert.hpp>
@ -56,13 +56,13 @@ void attribute_string_writer::write_value(size_t /*pos*/, const bool& 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;
}
}
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;
}
}
@ -98,7 +98,7 @@ void attribute_string_writer::write_value(size_t /*pos*/, const utils::blob& x )
// MSSQL: 0x5468697320697320612062616E617279204461746120737472696E67
// Sqlite: X'5468697320697320612062616E617279204461746120737472696E67'
if (conn_.has_value()) {
// result_ = dialect_.token_at(sql::dialect_token::BEGIN_BINARY_DATA) + conn_.value().get().to_escaped_string(x) + dialect_.token_at(sql::dialect_token::END_BINARY_DATA);
result_ = dialect_.token_at(sql::dialect_token::BEGIN_BINARY_DATA) + conn_.value().get().to_escaped_string(x) + dialect_.token_at(sql::dialect_token::END_BINARY_DATA);
} else {
result_ = dialect_.token_at(sql::dialect_token::BEGIN_BINARY_DATA) + dialect_.to_escaped_string(x) + dialect_.token_at(sql::dialect_token::END_BINARY_DATA);
}

View File

@ -74,7 +74,7 @@ TEST_CASE_METHOD( QueryFixture, "Insert and select basic datatypes", "[query][da
};
res = query::insert()
.into("types", matador::sql::column_generator::generate<types>(schema, true))
.into("types", column_generator::generate<types>(schema, true))
.values(t)
.execute(db);
REQUIRE(res.is_ok());

View File

@ -50,8 +50,8 @@ TEST_CASE_METHOD(QueryFixture, "Test all data types for record", "[query][record
tables_to_drop.emplace("types");
auto cols = std::vector<std::string>{"id",
"val_char", "val_short", "val_int", "val_long", "val_long_long",
"val_uchar", "val_ushort", "val_uint", "val_ulong", "val_ulong_long",
"val_char", "val_short", "val_int", "val_long_long",
"val_uchar", "val_ushort", "val_uint", "val_ulong_long",
"val_bool",
"val_float", "val_double",
"val_string", "val_varchar",
@ -426,8 +426,7 @@ TEST_CASE_METHOD(QueryFixture, "Execute select statement with order by", "[query
REQUIRE(expected_names.empty());
}
TEST_CASE_METHOD(QueryFixture, "Execute select statement with group by and order by", "[query][record]")
{
TEST_CASE_METHOD(QueryFixture, "Execute select statement with group by and order by", "[query][record]") {
auto res = query::create()
.table("person", {
make_pk_column<uint32_t>("id"),