118 lines
4.1 KiB
C++
118 lines
4.1 KiB
C++
#include "matador/query/session.hpp"
|
|
|
|
#include "matador/sql/backend_provider.hpp"
|
|
#include "matador/sql/dialect.hpp"
|
|
|
|
#include "matador/query/query.hpp"
|
|
#include "matador/query/generator.hpp"
|
|
#include "matador/query/basic_schema.hpp"
|
|
|
|
#include <stdexcept>
|
|
|
|
namespace matador::query {
|
|
utils::error make_error(const error_code ec, const std::string &msg) {
|
|
return utils::error(ec, msg);
|
|
}
|
|
|
|
session::session(session_context&& ctx, const basic_schema &scm)
|
|
: pool_(ctx.dns, ctx.connection_count, [ctx](const sql::connection_info& info) { return sql::connection(info, ctx.resolver_service); })
|
|
, cache_(ctx.bus, pool_, ctx.cache_size)
|
|
, dialect_(sql::backend_provider::instance().connection_dialect(pool_.info().type))
|
|
, schema_(scm)
|
|
, resolver_service_(ctx.resolver_service) {
|
|
using namespace matador::utils;
|
|
for (const auto &[type, node] : schema_) {
|
|
query_contexts queries;
|
|
|
|
// SELECT all
|
|
queries.select_all = select(node.table())
|
|
.from(node.name())
|
|
.compile(dialect_);
|
|
if (node.table().has_primary_key()) {
|
|
// SELECT one
|
|
queries.select_one = select(node.table())
|
|
.from(node.name())
|
|
.where(*node.table().primary_key_column() == _)
|
|
.compile(dialect_);
|
|
// UPDATE one
|
|
auto update_set = query::update(node.table());
|
|
for (const auto &col: node.table().columns()) {
|
|
update_set.set(col, _);
|
|
}
|
|
queries.update_one = update_set.where(*node.table().primary_key_column() == _)
|
|
.compile(dialect_);
|
|
// DELETE one
|
|
queries.delete_one = query::remove()
|
|
.from(node.name())
|
|
.where(*node.table().primary_key_column() == _)
|
|
.compile(dialect_);
|
|
}
|
|
// INSERT one
|
|
std::vector<table_column> columns;
|
|
for (const auto &col: node.table().columns()) {
|
|
if (col.is_primary_key() && utils::is_constraint_set(col.attributes().options(), constraints::Identity)) {
|
|
continue;
|
|
}
|
|
columns.push_back(col);
|
|
}
|
|
if (node.pk_generator().type() == utils::generator_type::Identity) {
|
|
queries.insert = query::insert()
|
|
.into(node.name(), columns)
|
|
.values(generator::placeholders(columns.size()))
|
|
.returning(node.table().primary_key_column()->as(node.table().primary_key_column()->column_name()))
|
|
.compile(dialect_);
|
|
} else {
|
|
queries.insert = query::insert()
|
|
.into(node.name(), columns)
|
|
.values(generator::placeholders(columns.size()))
|
|
.compile(dialect_);
|
|
}
|
|
|
|
queries.insert.resolver = resolver_service_;
|
|
queries.update_one.resolver = resolver_service_;
|
|
queries.delete_one.resolver = resolver_service_;
|
|
queries.select_one.resolver = resolver_service_;
|
|
queries.select_all.resolver = resolver_service_;
|
|
contexts_by_type_[node.node().type_index()] = queries;
|
|
}
|
|
|
|
for (const auto &pair : schema_.resolver_producers()) {
|
|
auto res = pair.second->build_query(dialect_).and_then([this](sql::query_context&& query_ctx) -> result<sql::statement, error> {
|
|
query_ctx.resolver = resolver_service_;
|
|
return cache_.acquire(query_ctx);
|
|
}).and_then([&pair, this](sql::statement&& stmt) -> result<void, error> {
|
|
resolver_service_->register_object_resolver(pair.second->produce(std::move(stmt)));
|
|
|
|
return ok<void>();
|
|
}).or_else([](const auto &err) {
|
|
return failure(err);
|
|
});
|
|
|
|
if (!res) {
|
|
throw std::runtime_error(res.err().message());
|
|
}
|
|
}
|
|
|
|
for (const auto &pair : schema_.collection_resolver_producers()) {
|
|
auto res = pair.second->build_query(dialect_).and_then([this](sql::query_context&& query_ctx) -> result<sql::statement, error> {
|
|
query_ctx.resolver = resolver_service_;
|
|
return cache_.acquire(query_ctx);
|
|
}).and_then([&pair, this](sql::statement&& stmt) -> result<void, error> {
|
|
resolver_service_->register_collection_resolver(pair.second->produce(std::move(stmt), *resolver_service_));
|
|
|
|
return ok<void>();
|
|
}).or_else([](const auto &err) {
|
|
return failure(err);
|
|
});
|
|
|
|
if (!res) {
|
|
throw std::runtime_error(res.err().message());
|
|
}
|
|
}
|
|
}
|
|
|
|
const basic_schema & session::schema() const {
|
|
return schema_;
|
|
}
|
|
}
|