query/source/orm/query/intermediates/fetchable_query.cpp

74 lines
2.3 KiB
C++

#include "matador/query/intermediates/fetchable_query.hpp"
#include "matador/sql/executor.hpp"
#include "matador/sql/field.hpp"
#include "matador/sql/statement.hpp"
namespace matador::query {
namespace detail {
sql::record *create_prototype(const std::vector<object::attribute> &prototype) {
auto result = std::make_unique<sql::record>();
int index{0};
for (const auto &col: prototype) {
result->append({
col.name(),
col.type(),
col.attributes().options(),
col.attributes().size(),
index++
});
}
return result.release();
}
}
utils::result<sql::query_result<sql::record>, utils::error> fetchable_query::fetch_all(const sql::executor &exec) const {
query_compiler compiler;
const auto ctx = compiler.compile(*context_, exec.dialect(), std::nullopt);
return exec.fetch(ctx)
.and_then([](auto &&res) {
const auto prototype = res->prototype();
return utils::ok(sql::query_result<sql::record>(std::forward<decltype(res)>(res), [prototype] {
return detail::create_prototype(prototype);
}));
});
}
utils::result<std::optional<sql::record>, utils::error> fetchable_query::fetch_one(const sql::executor &exec) const {
query_compiler compiler;
auto result = exec.fetch(compiler.compile(*context_, exec.dialect(), std::nullopt));
if (!result.is_ok()) {
return utils::failure(result.err());
}
const auto prototype = result.value()->prototype();
sql::query_result<sql::record> records(std::move(*result), [prototype] {
return detail::create_prototype(prototype);
});
auto first = records.begin();
if (first == records.end()) {
return utils::ok(std::optional<sql::record>{std::nullopt});
}
return utils::ok(std::optional{*first.get()});
}
std::string fetchable_query::str(const sql::executor &exec) const {
return exec.str(compile(exec.dialect()));
}
sql::query_context fetchable_query::compile(const sql::dialect &d) const {
query_compiler compiler;
return compiler.compile(*context_, d, std::nullopt);
}
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetchable_query::fetch(const sql::executor &exec) const {
return exec.fetch(compile(exec.dialect()));
}
utils::result<sql::statement, utils::error> fetchable_query::prepare(sql::executor &exec) const {
return exec.prepare(compile(exec.dialect()));
}
}