column, placeholder and column_value generator progress

This commit is contained in:
Sascha Kühl
2025-11-10 16:12:53 +01:00
parent 4b51ad21da
commit b3bff2dd1b
15 changed files with 267 additions and 83 deletions
+4 -1
View File
@@ -3,10 +3,13 @@
#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/utils/types.hpp"
namespace matador::utils {
class foreign_attributes;
}
namespace matador::query::detail {
class fk_value_extractor
+190
View File
@@ -0,0 +1,190 @@
#ifndef MATADOR_GENERATOR_HPP
#define MATADOR_GENERATOR_HPP
#include <matador/utils/placeholder.hpp>
#include <matador/utils/primary_key_attribute.hpp>
#include <matador/utils/field_attributes.hpp>
#include <matador/utils/foreign_attributes.hpp>
#include "matador/query/fk_value_extractor.hpp"
#include "matador/query/internal/column_value_pair.hpp"
#include <vector>
namespace matador::query::generator {
class column_generator final {
public:
template < class V >
void on_primary_key(const char *id, V &, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
if (has_many_to_many_) {
return;
}
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) {
if (has_many_to_many_) {
return;
}
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 (has_many_to_many_) {
return;
}
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*/) {
if (!has_many_to_many_) {
return;
}
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*/) {}
};
class placeholder_generator final {
public:
template< class Type >
std::vector<utils::placeholder> generate() {
Type obj;
return generate(obj);
}
template< class Type >
std::vector<utils::placeholder> generate(const Type &obj) {
result_.clear();
access::process(*this, obj);
return result_;
}
template < class V >
void on_primary_key(const char * /*id*/, V &/*x*/, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
result_.emplace_back(utils::_);
}
void on_revision(const char *id, uint64_t &/*rev*/);
template<typename Type>
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {
result_.emplace_back(utils::_);
}
template<class Type, template < class ... > class Pointer>
void on_belongs_to(const char * /*id*/, Pointer<Type> &/*x*/, const utils::foreign_attributes &/*attr*/) {
result_.emplace_back(utils::_);
}
template<class Type, template < class ... > class Pointer>
void on_has_one(const char * /*id*/, Pointer<Type> &/*x*/, const utils::foreign_attributes &/*attr*/) {
result_.emplace_back(utils::_);
}
template<class ContainerType>
static void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
private:
std::vector<utils::placeholder> result_;
};
class column_value_generator final {
public:
template< class Type >
std::vector<internal::column_value_pair> generate() {
Type obj;
return generate(obj);
}
template< class Type >
std::vector<internal::column_value_pair> generate(const Type &obj) {
result_.clear();
access::process(*this, obj);
return result_;
}
template < class V >
void on_primary_key(const char *id, V &x, const utils::primary_key_attribute& /*attr*/ = utils::default_pk_attributes) {
result_.emplace_back(id, x);
}
void on_revision(const char *id, uint64_t &/*rev*/);
template<typename Type>
void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes) {
result_.emplace_back(id, x);
}
template<class Type, template < class ... > class Pointer>
void on_belongs_to(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/) {
result_.emplace_back(id, fk_value_extractor_.extract(*x));
}
template<class Type, template < class ... > class Pointer>
void on_has_one(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/) {
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*/) {}
private:
detail::fk_value_extractor fk_value_extractor_{};
std::vector<internal::column_value_pair> result_;
};
template<typename Type>
std::vector<utils::placeholder> placeholders() {
placeholder_generator generator;
return generator.generate<Type>();
}
template<typename Type>
std::vector<utils::placeholder> placeholders(const Type &obj) {
placeholder_generator generator;
return generator.generate(obj);
}
template<typename Type>
std::vector<internal::column_value_pair> column_value_pairs() {
column_value_generator generator;
return generator.generate<Type>();
}
template<typename Type>
std::vector<internal::column_value_pair> column_value_pairs(const Type &obj) {
column_value_generator generator;
return generator.generate(obj);
}
}
#endif //MATADOR_GENERATOR_HPP
@@ -7,7 +7,7 @@
#include "matador/query/key_value_generator.hpp"
#include "matador/query/internal/key_value_pair.hpp"
#include "matador/query/internal/column_value_pair.hpp"
namespace matador::query {
@@ -15,8 +15,8 @@ class query_update_intermediate : public query_intermediate {
public:
explicit query_update_intermediate(const sql::table& table);
query_set_intermediate set(std::initializer_list<internal::key_value_pair> columns);
query_set_intermediate set(std::vector<internal::key_value_pair> &&columns);
query_set_intermediate set(std::initializer_list<internal::column_value_pair> columns);
query_set_intermediate set(std::vector<internal::column_value_pair> &&columns);
template<class Type>
query_set_intermediate set() {
Type obj;
@@ -8,12 +8,12 @@
namespace matador::query::internal {
class key_value_pair {
class column_value_pair {
public:
key_value_pair(const sql::column &col, utils::database_type value);
key_value_pair(std::string name, utils::database_type value);
key_value_pair(const char *name, utils::database_type value);
key_value_pair(const char *name, utils::placeholder p);
column_value_pair(const sql::column &col, utils::database_type value);
column_value_pair(std::string name, utils::database_type value);
column_value_pair(const char *name, utils::database_type value);
column_value_pair(const char *name, utils::placeholder p);
[[nodiscard]] const std::string& name() const;
[[nodiscard]] const std::variant<utils::placeholder, utils::database_type>& value() const;
@@ -4,7 +4,7 @@
#include "matador/query/query_part_visitor.hpp"
#include "matador/query/criteria.hpp"
#include "matador/query/internal/key_value_pair.hpp"
#include "matador/query/internal/column_value_pair.hpp"
#include "matador/query/query_part.hpp"
#include "matador/sql/column.hpp"
@@ -318,15 +318,15 @@ private:
class query_set_part final : public query_part
{
public:
explicit query_set_part(const std::vector<internal::key_value_pair>& key_value_pairs);
explicit query_set_part(const std::vector<internal::column_value_pair>& key_value_pairs);
[[nodiscard]] const std::vector<internal::key_value_pair>& key_values() const;
[[nodiscard]] const std::vector<internal::column_value_pair>& key_values() const;
private:
void accept(query_part_visitor &visitor) override;
private:
std::vector<internal::key_value_pair> key_value_pairs_;
std::vector<internal::column_value_pair> key_value_pairs_;
};
class query_delete_part final : public query_part
@@ -2,7 +2,7 @@
#define QUERY_KEY_VALUE_GENERATOR_HPP
#include "matador/query/fk_value_extractor.hpp"
#include "matador/query/internal/key_value_pair.hpp"
#include "matador/query/internal/column_value_pair.hpp"
#include "matador/utils/foreign_attributes.hpp"
#include "matador/utils/primary_key_attribute.hpp"
@@ -15,12 +15,12 @@ class key_value_generator
{
private:
public:
explicit key_value_generator(std::vector<internal::key_value_pair> &result);
explicit key_value_generator(std::vector<internal::column_value_pair> &result);
public:
template < class Type >
static std::vector<internal::key_value_pair> generate(const Type &obj) {
std::vector<internal::key_value_pair> result;
static std::vector<internal::column_value_pair> generate(const Type &obj) {
std::vector<internal::column_value_pair> result;
key_value_generator generator(result);
access::process(generator, obj);
@@ -51,7 +51,7 @@ public:
private:
detail::fk_value_extractor fk_value_extractor_{};
std::vector<internal::key_value_pair> &result_;
std::vector<internal::column_value_pair> &result_;
};
}