moved session to namespace query and move basic_schema::initialize to session constructor

This commit is contained in:
2026-04-23 16:01:44 +02:00
parent a34a3dc266
commit 3a82f4891a
30 changed files with 337 additions and 367 deletions
+2 -4
View File
@@ -1,6 +1,5 @@
add_library(matador-orm STATIC
../../include/matador/orm/error_code.hpp
../../include/matador/orm/session.hpp
../../include/matador/query/session.hpp
../../include/matador/query/abstract_pk_generator.hpp
../../include/matador/query/attribute_string_writer.hpp
../../include/matador/query/basic_schema.hpp
@@ -120,8 +119,7 @@ add_library(matador-orm STATIC
../../include/matador/sql/sql_functions.hpp
../../include/matador/sql/statement.hpp
../../include/matador/sql/statement_cache.hpp
orm/error_code.cpp
orm/session.cpp
query/session.cpp
query/abstract_pk_generator.cpp
query/attribute_string_writer.cpp
query/basic_schema.cpp
-45
View File
@@ -1,45 +0,0 @@
#include "matador/orm/error_code.hpp"
namespace matador::orm {
const char * orm_category_impl::name() const noexcept {
return "orm";
}
std::string orm_category_impl::message(const int ev) const {
switch (static_cast<error_code>(ev)) {
case error_code::Ok:
return "OK";
case error_code::NoConnectionAvailable:
return "No connection available";
case error_code::UnknownType:
return "Unknown type";
case error_code::NoPrimaryKey:
return "No primary key";
case error_code::FailedToBuildQuery:
return "Failed to build query";
case error_code::FailedToFindObject:
return "Failed to find object";
case error_code::FailedToInsertObject:
return "Failed to insert object";
case error_code::Failed:
return "Failed";
default:
return "Unknown error";
}
}
const std::error_category & orm_category() {
static orm_category_impl instance;
return instance;
}
std::error_code make_error_code(error_code e) {
return {static_cast<int>(e), orm_category()};
}
std::error_condition make_error_condition(error_code e) {
return {static_cast<int>(e), orm_category()};
}
}
-98
View File
@@ -1,98 +0,0 @@
#include "matador/orm/session.hpp"
#include "matador/sql/backend_provider.hpp"
#include "matador/sql/dialect.hpp"
#include "matador/query/query.hpp"
#include "matador/query/generator.hpp"
#include <stdexcept>
namespace matador::orm {
utils::error make_error(const error_code ec, const std::string &msg) {
return utils::error(ec, msg);
}
session::session(session_context&& ctx, const query::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::query_contexts queries;
// SELECT all
queries.select_all = query::select(node.table())
.from(node.name())
.compile(dialect_);
if (node.table().has_primary_key()) {
// SELECT one
queries.select_one = query::select(node.table())
.from(node.name())
.where(*node.table().primary_key_column().value() == _)
.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().value() == _)
.compile(dialect_);
// DELETE one
queries.delete_one = query::remove()
.from(node.name())
.where(*node.table().primary_key_column().value() == _)
.compile(dialect_);
}
// INSERT one
queries.insert = query::insert()
.into(node.name(), node.table())
.values(query::generator::placeholders(node.table().columns().size()))
.compile(dialect_);
contexts_by_type_[node.node().type_index()] = queries;
}
}
const class sql::dialect &session::dialect() const {
return dialect_;
}
std::shared_ptr<sql::resolver_service> session::resolver() const {
return resolver_service_;
}
const query::basic_schema & session::schema() const {
return schema_;
}
utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> session::fetch(const sql::query_context& ctx) const {
if (const auto result = cache_.acquire(ctx); !result) {
return utils::failure(result.err());
} else if (auto fetch_result = result->fetch_internal(); !fetch_result) {
return utils::failure(fetch_result.err());
} else {
return fetch_result;
}
}
utils::result<sql::execute_result, utils::error> session::execute(const sql::query_context& ctx) const {
if (const auto result = cache_.acquire(ctx); !result) {
return utils::failure(result.err());
} else if (auto exec_result = result->execute(); !exec_result) {
return utils::failure(exec_result.err());
} else {
return exec_result;
}
}
utils::result<sql::statement, utils::error> session::prepare(const sql::query_context& ctx) {
return cache_.acquire(ctx);
}
std::string session::str(const sql::query_context& ctx) const {
return ctx.sql;
}
}
-15
View File
@@ -85,19 +85,4 @@ basic_schema::const_iterator basic_schema::find(const std::string &name) const {
bool basic_schema::contains(const std::type_index &index) const {
return schema_nodes_.count(index) == 1;
}
void basic_schema::initialize(sql::executor &exec) const {
auto factory = std::make_shared<sql::producer_resolver_factory>();
for (const auto &[key, producer] : resolver_producers_) {
auto resolver = producer->produce(exec);
exec.resolver()->register_object_resolver(std::move(resolver));
}
auto collection_factory = std::make_shared<sql::producer_collection_resolver_factory>();
for (const auto &[key, producer] : collection_resolver_producers_) {
auto resolver = producer->produce(exec);
exec.resolver()->register_collection_resolver(std::move(resolver));
}
}
}
+21 -1
View File
@@ -7,7 +7,7 @@ const char* query_category_impl::name() const noexcept {
std::string query_category_impl::message(int ev) const {
switch (static_cast<error_code>(ev)) {
case error_code::Success:
case error_code::Ok:
return "Success";
case error_code::Failure:
return "Failure";
@@ -25,6 +25,26 @@ std::string query_category_impl::message(int ev) const {
return "Invalid data type";
case error_code::InvalidValue:
return "Invalid value";
case error_code::InvalidRelationType:
return "Invalid relation type";
case error_code::MissingPrimaryKey:
return "Missing primary key";
case error_code::UnknownType:
return "Unknown type";
case error_code::FailedToAcquireConnection:
return "Failed to acquire connection";
case error_code::FailedToFindPrimaryKey:
return "Failed to find primary key";
case error_code::FailedToBuildQuery:
return "Failed to build query";
case error_code::FailedToFindObject:
return "Failed to find object";
case error_code::FailedToInsertObject:
return "Failed to insert object";
case error_code::FailedToAcquirePool:
return "Failed to acquire pool";
case error_code::UnexpectedError:
return "Unexpected error";
default:
return "Unknown error";
}
-1
View File
@@ -269,7 +269,6 @@ void query_builder::visit(internal::query_values_part& part) {
}
void query_builder::visit(internal::query_returning_part& part) {
query_.mode = sql::return_mode::Rows;
query_.sql += " " + dialect_->returning() + " ";
build_fetchable_columns(query_, part.columns(), *dialect_);
+3 -7
View File
@@ -2,13 +2,9 @@
namespace matador::query {
query_builder_exception::query_builder_exception(const query_build_error error, utils::error&& err)
: error_type_(error)
, error_( std::move(err) ) {}
query_build_error query_builder_exception::error_type() const {
return error_type_;
}
query_builder_exception::query_builder_exception(const error_code error, std::string&& msg)
: error_(error, msg)
{}
const utils::error& query_builder_exception::error() const {
return error_;
+1 -1
View File
@@ -59,7 +59,7 @@ void select_query_builder::on_revision(const char *id, uint64_t &/*rev*/) {
void select_query_builder::push(const std::string &column_name) {
const auto it = processed_tables_.find(table_info_stack_.top().info.name());
if (it == processed_tables_.end()) {
throw query_builder_exception{query_build_error::UnexpectedError};
throw query_builder_exception{error_code::UnexpectedError, "Unexpected error during column processing"};
}
entity_query_data_.columns.emplace_back(&it->second, column_name, build_alias('c', ++column_index));
}
+145
View File
@@ -0,0 +1,145 @@
#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 {
class producer_accessor {
public:
static const std::unordered_map<std::type_index, std::unique_ptr<sql::object_resolver_producer>>& resolver_producers(const basic_schema& scm) {
return scm.resolver_producers_;
}
static const std::unordered_map<object::collection_composite_key, std::unique_ptr<sql::collection_resolver_producer>, object::collection_composite_key_hash>& collection_resolver_producers(const basic_schema& scm) {
return scm.collection_resolver_producers_;
}
};
utils::error make_error(const error_code ec, const std::string &msg) {
return utils::error(ec, msg);
}
session::session(session_context&& ctx, const query::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::query_contexts queries;
// SELECT all
queries.select_all = query::select(node.table())
.from(node.name())
.compile(dialect_);
if (node.table().has_primary_key()) {
// SELECT one
queries.select_one = query::select(node.table())
.from(node.name())
.where(*node.table().primary_key_column().value() == _)
.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().value() == _)
.compile(dialect_);
// DELETE one
queries.delete_one = query::remove()
.from(node.name())
.where(*node.table().primary_key_column().value() == _)
.compile(dialect_);
}
// INSERT one
queries.insert = query::insert()
.into(node.name(), node.table())
.values(query::generator::placeholders(node.table().columns().size()))
.compile(dialect_);
contexts_by_type_[node.node().type_index()] = queries;
}
auto factory = std::make_shared<sql::producer_resolver_factory>();
for (const auto &pair : producer_accessor::resolver_producers(schema_)) {
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());
}
}
auto collection_factory = std::make_shared<sql::producer_collection_resolver_factory>();
for (const auto &pair : producer_accessor::collection_resolver_producers(schema_)) {
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 class sql::dialect &session::dialect() const {
// return dialect_;
// }
//
// std::shared_ptr<sql::resolver_service> session::resolver() const {
// return resolver_service_;
// }
const query::basic_schema & session::schema() const {
return schema_;
}
// utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> session::fetch(const sql::query_context& ctx) const {
// if (const auto result = cache_.acquire(ctx); !result) {
// return utils::failure(result.err());
// } else if (auto fetch_result = result->fetch_internal(); !fetch_result) {
// return utils::failure(fetch_result.err());
// } else {
// return fetch_result;
// }
// }
//
// utils::result<sql::execute_result, utils::error> session::execute(const sql::query_context& ctx) const {
// if (const auto result = cache_.acquire(ctx); !result) {
// return utils::failure(result.err());
// } else if (auto exec_result = result->execute(); !exec_result) {
// return utils::failure(exec_result.err());
// } else {
// return exec_result;
// }
// }
//
// utils::result<sql::statement, utils::error> session::prepare(const sql::query_context& ctx) {
// return cache_.acquire(ctx);
// }
//
// std::string session::str(const sql::query_context& ctx) const {
// return ctx.sql;
// }
}