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

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

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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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_;
};
}

View File

@ -22,8 +22,7 @@ private:
column_generator(std::vector<column> &column_infos,
const object::repository &ts,
const std::string &table_name,
bool force_lazy,
bool has_many_to_many = false);
bool force_lazy);
public:
template < class Type >
@ -56,18 +55,12 @@ 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);
}
@ -82,9 +75,6 @@ public:
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;
}
@ -105,9 +95,6 @@ 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*/) {
if (!has_many_to_many_) {
return;
}
push(join_column);
push(inverse_join_column);
}
@ -118,9 +105,6 @@ public:
private:
template<class Pointer>
void on_foreign_key(const char *id, Pointer &, const utils::foreign_attributes &attr) {
if (has_many_to_many_) {
return;
}
if (attr.fetch() == utils::fetch_type::LAZY || force_lazy_) {
push(id);
} else {
@ -148,7 +132,6 @@ private:
const object::repository &table_schema_;
int column_index{0};
bool force_lazy_{false};
bool has_many_to_many_{false};
};
}

View File

@ -44,7 +44,7 @@ add_library(matador-orm STATIC
../../include/matador/query/intermediates/query_update_intermediate.hpp
../../include/matador/query/intermediates/query_where_intermediate.hpp
../../include/matador/query/internal/basic_type_to_string_visitor.hpp
../../include/matador/query/internal/key_value_pair.hpp
../../include/matador/query/internal/column_value_pair.hpp
../../include/matador/query/internal/query_parts.hpp
../../include/matador/query/join_data.hpp
../../include/matador/query/key_value_generator.hpp
@ -123,7 +123,7 @@ add_library(matador-orm STATIC
query/intermediates/query_update_intermediate.cpp
query/intermediates/query_where_intermediate.cpp
query/internal/basic_type_to_string_visitor.cpp
query/internal/key_value_pair.cpp
query/internal/column_value_pair.cpp
query/internal/query_parts.cpp
query/internal/query_result_impl.cpp
query/key_value_generator.cpp
@ -154,6 +154,8 @@ add_library(matador-orm STATIC
sql/statement.cpp
sql/statement_cache.cpp
sql/table.cpp
../../include/matador/query/generator.hpp
query/generator.cpp
)
target_include_directories(matador-orm

View File

@ -0,0 +1,11 @@
#include "matador/query/generator.hpp"
namespace matador::query::generator {
void placeholder_generator::on_revision(const char* /*id*/, uint64_t&) {
result_.emplace_back(utils::_);
}
void column_value_generator::on_revision(const char* id, uint64_t& x) {
result_.emplace_back(id, x);
}
}

View File

@ -9,12 +9,12 @@ query_update_intermediate::query_update_intermediate(const sql::table& table)
context_->parts.push_back(std::make_unique<internal::query_update_part>(table));
}
query_set_intermediate query_update_intermediate::set(const std::initializer_list<internal::key_value_pair> columns)
query_set_intermediate query_update_intermediate::set(const std::initializer_list<internal::column_value_pair> columns)
{
return set(std::vector<internal::key_value_pair>{columns});
return set(std::vector<internal::column_value_pair>{columns});
}
query_set_intermediate query_update_intermediate::set(std::vector<internal::key_value_pair> &&columns)
query_set_intermediate query_update_intermediate::set(std::vector<internal::column_value_pair> &&columns)
{
context_->parts.push_back(std::make_unique<internal::query_set_part>(std::move(columns)));
return {context_};

View File

@ -0,0 +1,33 @@
#include "matador/query/internal/column_value_pair.hpp"
#include <utility>
namespace matador::query::internal {
column_value_pair::column_value_pair(std::string name, utils::database_type value)
: name_(std::move(name))
, value_(std::move(value)) {
}
column_value_pair::column_value_pair(const sql::column &col, utils::database_type value)
: name_(col.name)
, value_(std::move(value)) {
}
column_value_pair::column_value_pair(const char *name, utils::database_type value)
: name_(name)
, value_(std::move(value)) {
}
column_value_pair::column_value_pair( const char* name, utils::placeholder p )
: name_(name)
, value_(p) {}
const std::string &column_value_pair::name() const {
return name_;
}
const std::variant<utils::placeholder, utils::database_type>& column_value_pair::value() const {
return value_;
}
}

View File

@ -1,33 +0,0 @@
#include "matador/query/internal/key_value_pair.hpp"
#include <utility>
namespace matador::query::internal {
key_value_pair::key_value_pair(std::string name, utils::database_type value)
: name_(std::move(name))
, value_(std::move(value)) {
}
key_value_pair::key_value_pair(const sql::column &col, utils::database_type value)
: name_(col.name)
, value_(std::move(value)) {
}
key_value_pair::key_value_pair(const char *name, utils::database_type value)
: name_(name)
, value_(std::move(value)) {
}
key_value_pair::key_value_pair( const char* name, utils::placeholder p )
: name_(name)
, value_(p) {}
const std::string &key_value_pair::name() const {
return name_;
}
const std::variant<utils::placeholder, utils::database_type>& key_value_pair::value() const {
return value_;
}
}

View File

@ -300,11 +300,11 @@ void query_update_part::accept(query_part_visitor &visitor)
visitor.visit(*this);
}
query_set_part::query_set_part(const std::vector<key_value_pair>& key_value_pairs)
query_set_part::query_set_part(const std::vector<column_value_pair>& key_value_pairs)
: query_part(sql::dialect_token::Set)
, key_value_pairs_(key_value_pairs) {}
const std::vector<key_value_pair> &query_set_part::key_values() const
const std::vector<column_value_pair> &query_set_part::key_values() const
{
return key_value_pairs_;
}

View File

@ -3,7 +3,7 @@
#include "matador/query/value_extractor.hpp"
namespace matador::query {
key_value_generator::key_value_generator(std::vector<internal::key_value_pair> &result)
key_value_generator::key_value_generator(std::vector<internal::column_value_pair> &result)
: result_(result) {}
void key_value_generator::on_revision(const char *id, uint64_t &x) {

View File

@ -7,12 +7,10 @@ namespace matador::sql {
column_generator::column_generator(std::vector<column> &column_infos,
const object::repository &scm,
const std::string &table_name,
const bool force_lazy,
const bool has_many_to_many)
const bool force_lazy)
: column_infos_(column_infos)
, table_schema_(scm)
, force_lazy_(force_lazy)
, has_many_to_many_(has_many_to_many)
{
table_name_stack_.push(table_name);
seen_tables.insert(table_name);
@ -33,9 +31,6 @@ std::vector<column> column_generator::generate( const object::repository& scm, c
void column_generator::on_revision(const char *id, uint64_t &)
{
if (has_many_to_many_) {
return;
}
push(id);
}