column, placeholder and column_value generator progress

This commit is contained in:
Sascha Kühl
2025-11-12 15:53:03 +01:00
parent 9e76203bc9
commit 1c5b2b21b0
16 changed files with 93 additions and 236 deletions
+4 -4
View File
@@ -6,8 +6,8 @@
#include "matador/query/criteria.hpp"
#include "matador/query/query.hpp"
#include "matador/query/generator.hpp"
#include "matador/sql/column_generator.hpp"
#include "matador/sql/connection.hpp"
#include "matador/sql/connection_pool.hpp"
#include "matador/sql/executor.hpp"
@@ -172,8 +172,8 @@ utils::result<object::object_ptr<Type>, utils::error> session::insert(Type *obj)
}
auto res = query::query::insert()
.into(info->get().name(), sql::column_generator::generate<Type>(*schema_, true))
.values(*obj)
.into(info->get().name(), query::generator::columns<Type>(*schema_))
.values(query::generator::placeholders<Type>())
.prepare(*this);
if (!res) {
return utils::failure(res.err());
@@ -248,7 +248,7 @@ utils::result<object::object_ptr<Type>, utils::error> session::update( const obj
const auto col = sql::column(info.value().get().definition().primary_key()->name());
auto res = matador::query::query::update(info->get().name())
.set(*obj)
.set(generator::placeholders<Type>())
.where(col == _)
.prepare(*this);
if (!res) {
@@ -280,7 +280,7 @@ void session_query_builder::on_foreign_object(const char *id, Pointer &, const u
using namespace matador::utils;
using namespace matador::query;
// create select query
auto result = matador::query::query::select(sql::column_generator::generate<typename Pointer::value_type>(schema_, true))
auto result = matador::query::query::select(generator::columns<typename Pointer::value_type>(schema_, generator::column_generator_options::ForceLazy))
.from(*foreign_table)
.where(sql::column(foreign_table, pk->name(), "") == _)
.prepare(executor_);
+32 -10
View File
@@ -39,11 +39,11 @@ inline bool is_column_generator_option_set(const column_generator_options source
constexpr auto default_column_generator_options = column_generator_options::ForceLazy;
class column_generator2 {
class column_generator {
public:
explicit column_generator2(const std::string &table_name = "",
explicit column_generator(const std::string &table_name = "",
column_generator_options options = default_column_generator_options);
explicit column_generator2(const object::repository &repo,
explicit column_generator(const object::repository &repo,
const std::string &table_name = "",
column_generator_options options = default_column_generator_options);
@@ -105,7 +105,10 @@ public:
}
template<class ContainerType>
void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {
void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &attr) {
if (attr.fetch() == utils::fetch_type::LAZY || is_column_generator_option_set(options_, column_generator_options::ForceLazy)) {
return;
}
push(join_column);
push(inverse_join_column);
}
@@ -184,7 +187,11 @@ public:
result_.emplace_back(utils::_);
}
template<class ContainerType>
static void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
private:
std::vector<utils::placeholder> result_;
@@ -226,7 +233,11 @@ public:
result_.emplace_back(id, fk_value_extractor_.extract(*x));
}
template<class ContainerType>
static void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
static void on_has_many_to_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
private:
detail::fk_value_extractor fk_value_extractor_{};
@@ -256,7 +267,18 @@ template<typename Type>
std::vector<sql::column> columns(const object::repository &repo,
const std::string &table_name = "",
const column_generator_options options = default_column_generator_options) {
column_generator2 generator(repo, table_name, options);
column_generator generator(repo, table_name, options);
return generator.generate<Type>();
}
template<typename Type>
std::vector<sql::column> columns(const object::repository &repo,
const column_generator_options options) {
std::string table_name;
if (const auto result = repo.info<Type>()) {
table_name = result.value().get().name();
}
column_generator generator(repo, table_name, options);
return generator.generate<Type>();
}
@@ -265,14 +287,14 @@ std::vector<sql::column> columns(const Type &obj,
const object::repository &repo,
const std::string &table_name = "",
const column_generator_options options = default_column_generator_options) {
column_generator2 generator(repo, table_name, options);
column_generator generator(repo, table_name, options);
return generator.generate(obj);
}
template<typename Type>
std::vector<sql::column> columns(const std::string &table_name = "",
const column_generator_options options = default_column_generator_options) {
column_generator2 generator(table_name, options);
column_generator generator(table_name, options);
return generator.generate<Type>();
}
@@ -280,7 +302,7 @@ template<typename Type>
std::vector<sql::column> columns(const Type &obj,
const std::string &table_name = "",
const column_generator_options options = default_column_generator_options) {
column_generator2 generator(table_name, options);
column_generator generator(table_name, options);
return generator.generate(obj);
}
@@ -4,7 +4,7 @@
#include "matador/query/intermediates/query_intermediate.hpp"
#include "matador/query/intermediates/query_into_intermediate.hpp"
#include "matador/sql/column_generator.hpp"
#include "matador/query/generator.hpp"
namespace matador::query {
@@ -15,7 +15,7 @@ public:
template<class Type>
query_into_intermediate into(const sql::table &table, const object::repository &schema) {
return into(table, sql::column_generator::generate<Type>(schema));
return into(table, generator::columns<Type>(schema));
}
query_into_intermediate into(const sql::table &table, std::initializer_list<sql::column> columns);
query_into_intermediate into(const sql::table &table, std::vector<sql::column> &&columns);
@@ -16,6 +16,7 @@ public:
executable_query values(std::initializer_list<std::variant<utils::placeholder, utils::database_type>> values);
executable_query values(std::vector<std::variant<utils::placeholder, utils::database_type>> &&values);
executable_query values(std::vector<utils::placeholder> &&values);
executable_query values(std::vector<utils::database_type> &&values);
template<class Type>
executable_query values() {
+2 -2
View File
@@ -3,7 +3,7 @@
#include "matador/query/query_intermediates.hpp"
#include "matador/sql/column_generator.hpp"
#include "matador/query/generator.hpp"
namespace matador::sql {
class connection;
@@ -27,7 +27,7 @@ public:
[[nodiscard]] static query_select_intermediate select(std::vector<sql::column> columns, std::initializer_list<sql::column> additional_columns);
template<class Type>
[[nodiscard]] static query_select_intermediate select(const object::repository &schema) {
return select(sql::column_generator::generate<Type>(schema));
return select(generator::columns<Type>(schema));
}
[[nodiscard]] static query_insert_intermediate insert();
[[nodiscard]] static query_update_intermediate update(const sql::table &table);
-126
View File
@@ -1,126 +0,0 @@
#ifndef QUERY_COLUMN_GENERATOR_HPP
#define QUERY_COLUMN_GENERATOR_HPP
#include "matador/utils/access.hpp"
#include "matador/utils/field_attributes.hpp"
#include "matador/utils/foreign_attributes.hpp"
#include "matador/utils/primary_key_attribute.hpp"
#include "matador/sql/column.hpp"
#include "matador/object/repository.hpp"
#include <string>
#include <vector>
#include <stack>
namespace matador::sql {
class column_generator
{
private:
column_generator(std::vector<column> &column_infos,
const object::repository &ts,
const std::string &table_name,
bool force_lazy);
public:
template < class Type >
static std::vector<column> generate(const object::repository &scm, const bool force_lazy = false) {
const auto info = scm.info<Type>();
if (!info) {
return {};
}
std::vector<column> columns;
column_generator gen(columns, scm, info.value().get().name(), force_lazy);
Type obj;
access::process(gen, obj);
return columns;
}
static std::vector<column> generate(const object::repository &scm, const std::string &name, bool force_lazy = false);
template < class V >
void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
push(id);
}
void on_revision(const char *id, uint64_t &/*rev*/);
template<typename Type>
void on_attribute(const char *id, Type &, const utils::field_attributes &/*attr*/ = utils::null_attributes) {
push(id);
}
template<class Pointer>
void on_belongs_to(const char *id, Pointer &x, const utils::foreign_attributes &attr) {
on_foreign_key(id, x, attr);
}
template<class Pointer>
void on_has_one(const char *id, Pointer &x, const utils::foreign_attributes &attr) {
on_foreign_key(id, x, attr);
}
template<class ContainerType>
void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &attr) {
if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) {
return;
}
const auto info = table_schema_.info<typename ContainerType::value_type::value_type>();
if (!info) {
return;
}
if (seen_tables.count(info->get().name()) == 0) {
auto it = seen_tables.insert(info->get().name()).first;
table_name_stack_.push(info.value().get().name());
typename ContainerType::value_type::value_type obj;
access::process(*this, obj);
table_name_stack_.pop();
seen_tables.erase(it);
}
}
template<class ContainerType>
void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &/*attr*/) {
push(join_column);
push(inverse_join_column);
}
template<class ContainerType>
static void on_has_many_to_many(const char * /*id*/, ContainerType & /*cont*/, const utils::foreign_attributes &/*attr*/) {}
private:
template<class Pointer>
void on_foreign_key(const char *id, Pointer &, const utils::foreign_attributes &attr) {
if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) {
push(id);
} else {
const auto info = table_schema_.info<typename Pointer::value_type>();
if (!info) {
return;
}
if (seen_tables.count(info->get().name()) == 0) {
auto it = seen_tables.insert(info->get().name()).first;
table_name_stack_.push(info.value().get().name());
typename Pointer::value_type obj;
access::process(*this, obj);
table_name_stack_.pop();
seen_tables.erase(it);
}
}
}
void push(const std::string &column_name);
private:
std::stack<std::string> table_name_stack_;
std::vector<column> &column_infos_;
std::unordered_set<std::string> seen_tables;
const object::repository &table_schema_;
int column_index{0};
bool force_lazy_{false};
};
}
#endif //QUERY_COLUMN_GENERATOR_HPP