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

80 lines
2.4 KiB
C++

#include "matador/query/intermediates/fetchable_query.hpp"
#include "matador/query/query_builder.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_builder compiler;
auto ctx = compiler.build(*context_, exec.dialect(), std::nullopt);
ctx.resolver = exec.resolver();
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));
});
}
utils::result<std::optional<sql::record>, utils::error> fetchable_query::fetch_one(const sql::executor &exec) const {
query_builder compiler;
auto ctx = compiler.build(*context_, exec.dialect(), std::nullopt);
ctx.resolver = exec.resolver();
auto result = exec.fetch(ctx);
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);
auto first = records.begin();
if (first == records.end()) {
return utils::ok(std::optional<sql::record>{std::nullopt});
}
return utils::ok(std::optional{first.release()});
}
std::string fetchable_query::str(const sql::dialect &d) const {
return compile(d).sql;
}
sql::query_context fetchable_query::compile(const sql::dialect &d) const {
query_builder compiler;
return compiler.build(*context_, d, std::nullopt);
}
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetchable_query::fetch(const sql::executor &exec, const std::type_index& index) const {
auto ctx = compile(exec.dialect());
ctx.resolver = exec.resolver();
ctx.result_type = index;
return exec.fetch(ctx);
}
utils::result<sql::statement, utils::error> fetchable_query::prepare(sql::executor &exec) const {
auto ctx = compile(exec.dialect());
ctx.resolver = exec.resolver();
return exec.prepare(ctx);
}
}