renamed column_generator to column_definition_generator and column_name_generator to column_generator

This commit is contained in:
Sascha Kühl
2024-03-27 15:15:45 +01:00
parent be9f66c427
commit 50a0eb580a
18 changed files with 429 additions and 352 deletions
+9 -18
View File
@@ -16,26 +16,17 @@ enum class sql_function_t {
struct column
{
column(const char *name) : name(name) {} // NOLINT(*-explicit-constructor)
column(std::string name) : name(std::move(name)) {} // NOLINT(*-explicit-constructor)
column(sql_function_t func, std::string name) : name(std::move(name)), function_(func) {} // NOLINT(*-explicit-constructor)
column(std::string table_name, std::string name, std::string as)
: table(std::move(table_name))
, name(std::move(name))
, alias(std::move(as)) {}
column(std::string table_name, const char* name, std::string as)
: table(std::move(table_name))
, name(name)
, alias(std::move(as)) {}
column(const char *name); // NOLINT(*-explicit-constructor)
column(std::string name); // NOLINT(*-explicit-constructor)
column(sql_function_t func, std::string name); // NOLINT(*-explicit-constructor)
column(std::string table_name, std::string name, std::string as);
column(std::string table_name, const char* name, std::string as);
column& as(std::string a) {
alias = std::move(a);
return *this;
}
bool equals(const column &x) const;
[[nodiscard]] bool is_function() const {
return function_ != sql_function_t::NONE;
}
column& as(std::string a);
[[nodiscard]] bool is_function() const;
std::string table;
std::string name;
@@ -0,0 +1,129 @@
#ifndef QUERY_COLUMN_DEFINITION_GENERATOR_HPP
#define QUERY_COLUMN_DEFINITION_GENERATOR_HPP
#include "matador/sql/column_definition.hpp"
#include "matador/sql/data_type_traits.hpp"
#include "matador/utils/access.hpp"
#include "matador/utils/field_attributes.hpp"
#include "matador/utils/foreign_attributes.hpp"
#include <typeindex>
#include <vector>
namespace matador::sql {
class schema;
class fk_column_generator
{
public:
fk_column_generator() = default;
template<class Type>
column_definition generate(const char *id, Type &x, const std::string &ref_table, const std::string &ref_column)
{
utils::access::process(*this, x);
return column_definition{id, type_, 0, ref_table, ref_column, {utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
}
template<typename ValueType>
void on_primary_key(const char *, ValueType &/*pk*/, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type* = 0)
{
type_ = data_type_traits<ValueType>::builtin_type(0);
}
void on_primary_key(const char * /*id*/, std::string &/*pk*/, size_t size);
void on_revision(const char * /*id*/, unsigned long long &/*rev*/) {}
template < class Type >
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
void on_attribute(const char * /*id*/, char * /*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<class Pointer>
void on_belongs_to(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
template<class Pointer>
void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
private:
data_type_t type_{};
};
class column_definition_generator
{
private:
column_definition_generator(std::vector<column_definition> &columns, const schema &repo);
public:
~column_definition_generator() = default;
template < class Type >
static std::vector<column_definition> generate(const schema &repo)
{
std::vector<column_definition> columns;
column_definition_generator gen(columns, repo);
Type obj;
matador::utils::access::process(gen, obj);
return std::move(columns);
}
template < class V >
void on_primary_key(const char *, V &x, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0);
void on_primary_key(const char *id, std::string &pk, size_t size);
void on_revision(const char *id, unsigned long long &rev);
template<typename Type>
void on_attribute(const char *id, Type &x, const utils::field_attributes &attr = utils::null_attributes);
template<typename Type>
void on_attribute(const char *id, std::optional<Type> &x, const utils::field_attributes &attr = utils::null_attributes);
template<class Pointer>
void on_belongs_to(const char *id, Pointer &x, const utils::foreign_attributes &/*attr*/)
{
const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
}
template<class Pointer>
void on_has_one(const char *id, Pointer &x, const utils::foreign_attributes &/*attr*/)
{
const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
private:
std::pair<std::string, std::string> determine_foreign_ref(const std::type_index &ti);
private:
size_t index_ = 0;
std::vector<column_definition> &columns_;
const schema &repo_;
fk_column_generator fk_column_generator_;
};
template<typename V>
void column_definition_generator::on_primary_key(const char *id, V &x, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type*)
{
on_attribute(id, x, { utils::constraints::PRIMARY_KEY });
}
template<typename Type>
void column_definition_generator::on_attribute(const char *id, Type &x, const utils::field_attributes &attr)
{
columns_.emplace_back(id, x, attr, null_option::NOT_NULL);
}
template<typename Type>
void column_definition_generator::on_attribute(const char *id, std::optional<Type> &x, const utils::field_attributes &attr)
{
columns_.emplace_back(id, data_type_traits<Type>::builtin_type(attr.size()), attr, null_option::NULLABLE);
}
}
#endif //QUERY_COLUMN_DEFINITION_GENERATOR_HPP
+73 -83
View File
@@ -1,129 +1,119 @@
#ifndef QUERY_COLUMN_GENERATOR_HPP
#define QUERY_COLUMN_GENERATOR_HPP
#include "matador/sql/column_definition.hpp"
#include "matador/sql/data_type_traits.hpp"
#include "matador/utils/access.hpp"
#include "matador/utils/field_attributes.hpp"
#include "matador/utils/foreign_attributes.hpp"
#include <typeindex>
#include "matador/sql/column.hpp"
#include "matador/sql/schema.hpp"
#include <string>
#include <vector>
#include <stack>
namespace matador::sql {
class schema;
class fk_column_generator
{
public:
fk_column_generator() = default;
template<class Type>
column_definition generate(const char *id, Type &x, const std::string &ref_table, const std::string &ref_column)
{
utils::access::process(*this, x);
return column_definition{id, type_, 0, ref_table, ref_column, {utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
}
template<typename ValueType>
void on_primary_key(const char *, ValueType &/*pk*/, typename std::enable_if<std::is_integral<ValueType>::value && !std::is_same<bool, ValueType>::value>::type* = 0)
{
type_ = data_type_traits<ValueType>::builtin_type(0);
}
void on_primary_key(const char * /*id*/, std::string &/*pk*/, size_t size);
void on_revision(const char * /*id*/, unsigned long long &/*rev*/) {}
template < class Type >
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
void on_attribute(const char * /*id*/, char * /*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
template<class Pointer>
void on_belongs_to(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
template<class Pointer>
void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
private:
data_type_t type_{};
};
class column_generator
{
private:
column_generator(std::vector<column_definition> &columns, const schema &repo);
column_generator(std::vector<column> &column_infos, const sql::schema &ts, const std::string &table_name);
public:
~column_generator() = default;
template < class Type >
static std::vector<column_definition> generate(const schema &repo)
static std::vector<column> generate(const sql::schema &ts)
{
std::vector<column_definition> columns;
column_generator gen(columns, repo);
const auto info = ts.info<Type>();
if (!info) {
return {};
}
std::vector<column> columns;
column_generator gen(columns, ts, info.value().name);
Type obj;
matador::utils::access::process(gen, obj);
return std::move(columns);
}
template < class V >
void on_primary_key(const char *, V &x, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0);
void on_primary_key(const char *id, std::string &pk, size_t size);
void on_revision(const char *id, unsigned long long &rev);
void on_primary_key(const char *id, V &, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
{
push(id);
}
void on_primary_key(const char *id, std::string &, size_t);
void on_revision(const char *id, unsigned long long &/*rev*/);
template<typename Type>
void on_attribute(const char *id, Type &x, const utils::field_attributes &attr = utils::null_attributes);
template<typename Type>
void on_attribute(const char *id, std::optional<Type> &x, const utils::field_attributes &attr = utils::null_attributes);
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*/)
void on_belongs_to(const char *id, Pointer &, const utils::foreign_attributes &attr)
{
const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
if (attr.fetch() == utils::fetch_type::LAZY) {
push(id);
} else {
const auto info = table_schema_.info<typename Pointer::value_type>();
if (!info) {
return;
}
table_name_stack_.push(info.value().name);
typename Pointer::value_type obj;
matador::utils::access::process(*this, obj);
table_name_stack_.pop();
}
}
template<class Pointer>
void on_has_one(const char *id, Pointer &x, const utils::foreign_attributes &/*attr*/)
void on_has_one(const char *id, Pointer &, const utils::foreign_attributes &attr)
{
const auto [ref_table, ref_column] = determine_foreign_ref(std::type_index(typeid(typename Pointer::value_type)));
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
if (attr.fetch() == utils::fetch_type::LAZY) {
push(id);
} else {
const auto info = table_schema_.info<typename Pointer::value_type>();
if (!info) {
return;
}
table_name_stack_.push(info.value().name);
typename Pointer::value_type obj;
matador::utils::access::process(*this, obj);
table_name_stack_.pop();
}
}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &attr)
{
if (attr.fetch() == utils::fetch_type::LAZY) {
return;
}
const auto info = table_schema_.info<typename ContainerType::value_type::value_type>();
if (!info) {
return;
}
table_name_stack_.push(info.value().name);
typename ContainerType::value_type::value_type obj;
matador::utils::access::process(*this, obj);
table_name_stack_.pop();
}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
void on_has_many(const char *id, ContainerType &c, const utils::foreign_attributes &attr)
{
on_has_many(id, c, "", "", attr);
}
private:
std::pair<std::string, std::string> determine_foreign_ref(const std::type_index &ti);
void push(const std::string &column_name);
private:
size_t index_ = 0;
std::vector<column_definition> &columns_;
const schema &repo_;
fk_column_generator fk_column_generator_;
std::stack<std::string> table_name_stack_;
std::vector<column> &column_infos_;
const sql::schema &table_schema_;
int column_index{0};
};
template<typename V>
void column_generator::on_primary_key(const char *id, V &x, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type*)
{
on_attribute(id, x, { utils::constraints::PRIMARY_KEY });
}
template<typename Type>
void column_generator::on_attribute(const char *id, Type &x, const utils::field_attributes &attr)
{
columns_.emplace_back(id, x, attr, null_option::NOT_NULL);
}
template<typename Type>
void column_generator::on_attribute(const char *id, std::optional<Type> &x, const utils::field_attributes &attr)
{
columns_.emplace_back(id, data_type_traits<Type>::builtin_type(attr.size()), attr, null_option::NULLABLE);
}
}
#endif //QUERY_COLUMN_GENERATOR_HPP
@@ -1,97 +0,0 @@
#ifndef QUERY_COLUMN_NAME_GENERATOR_HPP
#define QUERY_COLUMN_NAME_GENERATOR_HPP
#include "matador/utils/access.hpp"
#include "matador/utils/field_attributes.hpp"
#include "matador/utils/foreign_attributes.hpp"
#include "matador/sql/column.hpp"
#include "matador/sql/schema.hpp"
#include <string>
#include <vector>
#include <stack>
namespace matador::sql {
class column_name_generator
{
private:
column_name_generator(std::vector<column> &column_infos, const sql::schema &ts, const std::string &table_name);
public:
~column_name_generator() = default;
template < class Type >
static std::vector<column> generate(const sql::schema &ts)
{
const auto info = ts.info<Type>();
if (!info) {
return {};
}
std::vector<column> columns;
column_name_generator gen(columns, ts, info.value().name);
Type obj;
matador::utils::access::process(gen, obj);
return std::move(columns);
}
template < class V >
void on_primary_key(const char *id, V &, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
{
push(id);
}
void on_primary_key(const char *id, std::string &, size_t);
void on_revision(const char *id, unsigned long long &/*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 &, const utils::foreign_attributes &/*attr*/)
{
push(id);
}
template<class Pointer>
void on_has_one(const char *id, Pointer &, const utils::foreign_attributes &/*attr*/)
{
push(id);
}
template<class ContainerType>
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &attr)
{
if (attr.fetch() == utils::fetch_type::LAZY) {
return;
}
const auto info = table_schema_.info<typename ContainerType::value_type::value_type>();
if (!info) {
return;
}
table_name_stack_.push(info.value().name);
typename ContainerType::value_type::value_type obj;
matador::utils::access::process(*this, obj);
table_name_stack_.pop();
}
template<class ContainerType>
void on_has_many(const char *id, ContainerType &c, const utils::foreign_attributes &attr)
{
on_has_many(id, c, "", "", attr);
}
private:
void push(const std::string &column_name);
private:
std::stack<std::string> table_name_stack_;
std::vector<column> &column_infos_;
const sql::schema &table_schema_;
int column_index{0};
};
}
#endif //QUERY_COLUMN_NAME_GENERATOR_HPP
+2 -2
View File
@@ -34,13 +34,13 @@ private:
template<class Type>
query_select_intermediate query::select()
{
return select(column_name_generator::generate<Type>(schema_));
return select(column_generator::generate<Type>(schema_));
}
template<class Type>
query_select_intermediate query::select(std::initializer_list<column> columns)
{
auto cols = column_name_generator::generate<Type>(schema_);
auto cols = column_generator::generate<Type>(schema_);
cols.insert(cols.end(), columns);
return select(cols);
}
+3 -3
View File
@@ -2,8 +2,8 @@
#define QUERY_QUERY_INTERMEDIATES_HPP
#include "matador/sql/column_definition.hpp"
#include "matador/sql/column_definition_generator.hpp"
#include "matador/sql/column_generator.hpp"
#include "matador/sql/column_name_generator.hpp"
#include "matador/sql/key_value_generator.hpp"
#include "matador/sql/key_value_pair.hpp"
#include "matador/sql/placeholder_generator.hpp"
@@ -260,7 +260,7 @@ public:
// if (!schema_.exists<Type>()) {
// schema_.attach<Type>(table.name);
// }
return this->table(table, column_generator::generate<Type>(schema_));
return this->table(table, column_definition_generator::generate<Type>(schema_));
}
};
@@ -282,7 +282,7 @@ public:
template<class Type>
query_into_intermediate into(const sql::table &table)
{
return into(table, column_name_generator::generate<Type>(schema_));
return into(table, column_generator::generate<Type>(schema_));
}
};
+2 -2
View File
@@ -1,7 +1,7 @@
#ifndef QUERY_SCHEMA_HPP
#define QUERY_SCHEMA_HPP
#include "matador/sql/column_generator.hpp"
#include "matador/sql/column_definition_generator.hpp"
#include "matador/sql/table_definition.hpp"
#include <optional>
@@ -38,7 +38,7 @@ public:
template<typename Type>
const table_info& attach(const std::string &table_name)
{
return attach(std::type_index(typeid(Type)), table_info{table_name, table_definition{column_generator::generate<Type>(*this)}});
return attach(std::type_index(typeid(Type)), table_info{table_name, table_definition{column_definition_generator::generate<Type>(*this)}});
}
const table_info& attach(std::type_index ti, const table_info& table);