renamed column_generator to column_definition_generator and column_name_generator to column_generator
This commit is contained in:
parent
be9f66c427
commit
50a0eb580a
|
|
@ -16,26 +16,17 @@ enum class sql_function_t {
|
||||||
|
|
||||||
struct column
|
struct column
|
||||||
{
|
{
|
||||||
column(const char *name) : name(name) {} // NOLINT(*-explicit-constructor)
|
column(const char *name); // NOLINT(*-explicit-constructor)
|
||||||
column(std::string name) : name(std::move(name)) {} // NOLINT(*-explicit-constructor)
|
column(std::string name); // NOLINT(*-explicit-constructor)
|
||||||
column(sql_function_t func, std::string name) : name(std::move(name)), function_(func) {} // 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, std::string name, std::string as);
|
||||||
: table(std::move(table_name))
|
column(std::string table_name, const char* name, std::string as);
|
||||||
, 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& as(std::string a) {
|
bool equals(const column &x) const;
|
||||||
alias = std::move(a);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] bool is_function() const {
|
column& as(std::string a);
|
||||||
return function_ != sql_function_t::NONE;
|
|
||||||
}
|
[[nodiscard]] bool is_function() const;
|
||||||
|
|
||||||
std::string table;
|
std::string table;
|
||||||
std::string name;
|
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
|
||||||
|
|
@ -1,129 +1,119 @@
|
||||||
#ifndef QUERY_COLUMN_GENERATOR_HPP
|
#ifndef QUERY_COLUMN_GENERATOR_HPP
|
||||||
#define 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/access.hpp"
|
||||||
#include "matador/utils/field_attributes.hpp"
|
#include "matador/utils/field_attributes.hpp"
|
||||||
#include "matador/utils/foreign_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 <vector>
|
||||||
|
#include <stack>
|
||||||
|
|
||||||
namespace matador::sql {
|
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
|
class column_generator
|
||||||
{
|
{
|
||||||
private:
|
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:
|
public:
|
||||||
~column_generator() = default;
|
~column_generator() = default;
|
||||||
|
|
||||||
template < class Type >
|
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;
|
const auto info = ts.info<Type>();
|
||||||
column_generator gen(columns, repo);
|
if (!info) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
std::vector<column> columns;
|
||||||
|
column_generator gen(columns, ts, info.value().name);
|
||||||
Type obj;
|
Type obj;
|
||||||
matador::utils::access::process(gen, obj);
|
matador::utils::access::process(gen, obj);
|
||||||
return std::move(columns);
|
return std::move(columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
template < class V >
|
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, V &, 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);
|
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>
|
template<typename Type>
|
||||||
void on_attribute(const char *id, 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)
|
||||||
|
{
|
||||||
template<typename Type>
|
push(id);
|
||||||
void on_attribute(const char *id, std::optional<Type> &x, const utils::field_attributes &attr = utils::null_attributes);
|
}
|
||||||
|
|
||||||
template<class Pointer>
|
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)));
|
if (attr.fetch() == utils::fetch_type::LAZY) {
|
||||||
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
|
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>
|
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)));
|
if (attr.fetch() == utils::fetch_type::LAZY) {
|
||||||
columns_.push_back(fk_column_generator_.generate(id, *x, ref_table, ref_column));
|
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>
|
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>
|
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:
|
private:
|
||||||
std::pair<std::string, std::string> determine_foreign_ref(const std::type_index &ti);
|
void push(const std::string &column_name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t index_ = 0;
|
std::stack<std::string> table_name_stack_;
|
||||||
std::vector<column_definition> &columns_;
|
std::vector<column> &column_infos_;
|
||||||
const schema &repo_;
|
const sql::schema &table_schema_;
|
||||||
|
int column_index{0};
|
||||||
fk_column_generator fk_column_generator_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
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
|
#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
|
|
||||||
|
|
@ -34,13 +34,13 @@ private:
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_select_intermediate query::select()
|
query_select_intermediate query::select()
|
||||||
{
|
{
|
||||||
return select(column_name_generator::generate<Type>(schema_));
|
return select(column_generator::generate<Type>(schema_));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
query_select_intermediate query::select(std::initializer_list<column> columns)
|
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);
|
cols.insert(cols.end(), columns);
|
||||||
return select(cols);
|
return select(cols);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
#define QUERY_QUERY_INTERMEDIATES_HPP
|
#define QUERY_QUERY_INTERMEDIATES_HPP
|
||||||
|
|
||||||
#include "matador/sql/column_definition.hpp"
|
#include "matador/sql/column_definition.hpp"
|
||||||
|
#include "matador/sql/column_definition_generator.hpp"
|
||||||
#include "matador/sql/column_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_generator.hpp"
|
||||||
#include "matador/sql/key_value_pair.hpp"
|
#include "matador/sql/key_value_pair.hpp"
|
||||||
#include "matador/sql/placeholder_generator.hpp"
|
#include "matador/sql/placeholder_generator.hpp"
|
||||||
|
|
@ -260,7 +260,7 @@ public:
|
||||||
// if (!schema_.exists<Type>()) {
|
// if (!schema_.exists<Type>()) {
|
||||||
// schema_.attach<Type>(table.name);
|
// 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>
|
template<class Type>
|
||||||
query_into_intermediate into(const sql::table &table)
|
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_));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#ifndef QUERY_SCHEMA_HPP
|
#ifndef QUERY_SCHEMA_HPP
|
||||||
#define 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 "matador/sql/table_definition.hpp"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
@ -38,7 +38,7 @@ public:
|
||||||
template<typename Type>
|
template<typename Type>
|
||||||
const table_info& attach(const std::string &table_name)
|
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);
|
const table_info& attach(std::type_index ti, const table_info& table);
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ set(SQL_SOURCES
|
||||||
sql/session.cpp
|
sql/session.cpp
|
||||||
sql/backend_provider.cpp
|
sql/backend_provider.cpp
|
||||||
sql/query_result_impl.cpp
|
sql/query_result_impl.cpp
|
||||||
|
sql/column_definition_generator.cpp
|
||||||
sql/column_generator.cpp
|
sql/column_generator.cpp
|
||||||
sql/column_name_generator.cpp
|
|
||||||
sql/key_value_generator.cpp
|
sql/key_value_generator.cpp
|
||||||
sql/fk_value_extractor.cpp
|
sql/fk_value_extractor.cpp
|
||||||
sql/schema.cpp
|
sql/schema.cpp
|
||||||
|
|
@ -57,8 +57,8 @@ set(SQL_HEADER
|
||||||
../include/matador/sql/session.hpp
|
../include/matador/sql/session.hpp
|
||||||
../include/matador/sql/backend_provider.hpp
|
../include/matador/sql/backend_provider.hpp
|
||||||
../include/matador/sql/query_result_impl.hpp
|
../include/matador/sql/query_result_impl.hpp
|
||||||
|
../include/matador/sql/column_definition_generator.hpp
|
||||||
../include/matador/sql/column_generator.hpp
|
../include/matador/sql/column_generator.hpp
|
||||||
../include/matador/sql/column_name_generator.hpp
|
|
||||||
../include/matador/sql/value_extractor.hpp
|
../include/matador/sql/value_extractor.hpp
|
||||||
../include/matador/sql/any_type.hpp
|
../include/matador/sql/any_type.hpp
|
||||||
../include/matador/sql/key_value_generator.hpp
|
../include/matador/sql/key_value_generator.hpp
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,38 @@ column operator ""_col(const char *name, size_t len)
|
||||||
return {{name, len}};
|
return {{name, len}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
column::column(const char *name) : name(name) {}
|
||||||
|
|
||||||
|
column::column(std::string name) : name(std::move(name)) {}
|
||||||
|
|
||||||
|
column::column(sql_function_t func, std::string name) : name(std::move(name)), function_(func) {}
|
||||||
|
|
||||||
|
column::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::column(std::string table_name, const char *name, std::string as)
|
||||||
|
: table(std::move(table_name))
|
||||||
|
, name(name)
|
||||||
|
, alias(std::move(as)) {}
|
||||||
|
|
||||||
|
bool column::equals(const column &x) const
|
||||||
|
{
|
||||||
|
return table == x.table &&
|
||||||
|
name == x.name &&
|
||||||
|
alias == x.alias &&
|
||||||
|
function_ == x.function_;
|
||||||
|
}
|
||||||
|
|
||||||
|
column &column::as(std::string a)
|
||||||
|
{
|
||||||
|
alias = std::move(a);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool column::is_function() const
|
||||||
|
{
|
||||||
|
return function_ != sql_function_t::NONE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
#include "matador/sql/column_definition_generator.hpp"
|
||||||
|
#include "matador/sql/schema.hpp"
|
||||||
|
|
||||||
|
namespace matador::sql {
|
||||||
|
|
||||||
|
column_definition_generator::column_definition_generator(std::vector<column_definition> &columns, const schema &repo)
|
||||||
|
: columns_(columns)
|
||||||
|
, repo_(repo)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void column_definition_generator::on_primary_key(const char *id, std::string &pk, size_t size)
|
||||||
|
{
|
||||||
|
on_attribute(id, pk, { size, utils::constraints::PRIMARY_KEY });
|
||||||
|
}
|
||||||
|
|
||||||
|
void column_definition_generator::on_revision(const char *id, unsigned long long int &x)
|
||||||
|
{
|
||||||
|
on_attribute(id, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<std::string, std::string> column_definition_generator::determine_foreign_ref(const std::type_index &ti)
|
||||||
|
{
|
||||||
|
return repo_.reference(ti);
|
||||||
|
}
|
||||||
|
|
||||||
|
void fk_column_generator::on_primary_key(const char *, std::string &, size_t size)
|
||||||
|
{
|
||||||
|
type_ = data_type_traits<std::string>::builtin_type(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,31 +1,31 @@
|
||||||
#include "matador/sql/column_generator.hpp"
|
#include "matador/sql/column_generator.hpp"
|
||||||
#include "matador/sql/schema.hpp"
|
|
||||||
|
|
||||||
namespace matador::sql {
|
namespace matador::sql {
|
||||||
|
|
||||||
column_generator::column_generator(std::vector<column_definition> &columns, const schema &repo)
|
column_generator::column_generator(std::vector<column> &column_infos,
|
||||||
: columns_(columns)
|
const sql::schema &ts,
|
||||||
, repo_(repo)
|
const std::string &table_name)
|
||||||
{}
|
: column_infos_(column_infos)
|
||||||
|
, table_schema_(ts)
|
||||||
void column_generator::on_primary_key(const char *id, std::string &pk, size_t size)
|
|
||||||
{
|
{
|
||||||
on_attribute(id, pk, { size, utils::constraints::PRIMARY_KEY });
|
table_name_stack_.push(table_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void column_generator::on_revision(const char *id, unsigned long long int &x)
|
void column_generator::on_primary_key(const char *id, std::string &, size_t)
|
||||||
{
|
{
|
||||||
on_attribute(id, x);
|
push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::string, std::string> column_generator::determine_foreign_ref(const std::type_index &ti)
|
void column_generator::on_revision(const char *id, unsigned long long int &)
|
||||||
{
|
{
|
||||||
return repo_.reference(ti);
|
push(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fk_column_generator::on_primary_key(const char *, std::string &, size_t size)
|
void column_generator::push(const std::string &column_name)
|
||||||
{
|
{
|
||||||
type_ = data_type_traits<std::string>::builtin_type(size);
|
char str[4];
|
||||||
|
snprintf(str, 4, "c%02d", ++column_index);
|
||||||
|
column_infos_.emplace_back(table_name_stack_.top(), column_name, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
#include "matador/sql/column_name_generator.hpp"
|
|
||||||
|
|
||||||
namespace matador::sql {
|
|
||||||
|
|
||||||
column_name_generator::column_name_generator(std::vector<column> &column_infos,
|
|
||||||
const sql::schema &ts,
|
|
||||||
const std::string &table_name)
|
|
||||||
: column_infos_(column_infos)
|
|
||||||
, table_schema_(ts)
|
|
||||||
{
|
|
||||||
table_name_stack_.push(table_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
void column_name_generator::on_primary_key(const char *id, std::string &, size_t)
|
|
||||||
{
|
|
||||||
push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void column_name_generator::on_revision(const char *id, unsigned long long int &)
|
|
||||||
{
|
|
||||||
push(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
void column_name_generator::push(const std::string &column_name)
|
|
||||||
{
|
|
||||||
char str[4];
|
|
||||||
snprintf(str, 4, "c%02d", ++column_index);
|
|
||||||
column_infos_.emplace_back(table_name_stack_.top(), column_name, str);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
#include "matador/sql/query_builder.hpp"
|
#include "matador/sql/query_builder.hpp"
|
||||||
#include "matador/sql/column_name_generator.hpp"
|
#include "matador/sql/column_generator.hpp"
|
||||||
#include "matador/sql/column.hpp"
|
#include "matador/sql/column.hpp"
|
||||||
#include "matador/sql/dialect.hpp"
|
#include "matador/sql/dialect.hpp"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@ add_executable(tests
|
||||||
models/product.hpp
|
models/product.hpp
|
||||||
models/order.hpp
|
models/order.hpp
|
||||||
models/order_details.h
|
models/order_details.h
|
||||||
|
ColumnDefinitionGeneratorTest.cpp
|
||||||
ColumnGeneratorTest.cpp
|
ColumnGeneratorTest.cpp
|
||||||
ColumnNameGeneratorTest.cpp
|
|
||||||
ValueGeneratorTest.cpp
|
ValueGeneratorTest.cpp
|
||||||
models/category.hpp
|
models/category.hpp
|
||||||
models/supplier.hpp
|
models/supplier.hpp
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
|
||||||
|
#include "matador/sql/column_definition_generator.hpp"
|
||||||
|
#include "matador/sql/schema.hpp"
|
||||||
|
|
||||||
|
#include "models/product.hpp"
|
||||||
|
#include "models/optional.hpp"
|
||||||
|
|
||||||
|
using namespace matador::sql;
|
||||||
|
using namespace matador::utils;
|
||||||
|
|
||||||
|
TEST_CASE("Generate columns from object", "[column generator]") {
|
||||||
|
schema repo("main");
|
||||||
|
|
||||||
|
auto columns = column_definition_generator::generate<matador::test::product>(repo);
|
||||||
|
|
||||||
|
const std::vector<column_definition> expected_columns = {
|
||||||
|
column_definition{"product_name", data_type_t::type_varchar, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
||||||
|
column_definition{"supplier_id", data_type_t::type_unsigned_long, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
||||||
|
column_definition{"category_id", data_type_t::type_unsigned_long, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
||||||
|
column_definition{"quantity_per_unit", data_type_t::type_varchar, null_attributes, null_option::NOT_NULL },
|
||||||
|
column_definition{"unit_price", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||||
|
column_definition{"units_in_stock", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||||
|
column_definition{"units_in_order", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||||
|
column_definition{"reorder_level", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
||||||
|
column_definition{"discontinued", data_type_t::type_bool, null_attributes, null_option::NOT_NULL }
|
||||||
|
};
|
||||||
|
REQUIRE(!columns.empty());
|
||||||
|
REQUIRE(columns.size() == expected_columns.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
||||||
|
REQUIRE(expected_columns[i].name() == columns[i].name());
|
||||||
|
REQUIRE(expected_columns[i].attributes().options() == columns[i].attributes().options() );
|
||||||
|
REQUIRE(expected_columns[i].type() == columns[i].type() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Generate columns from object with nullable columns", "[column generator]") {
|
||||||
|
schema repo("main");
|
||||||
|
|
||||||
|
auto columns = column_definition_generator::generate<matador::test::optional>(repo);
|
||||||
|
|
||||||
|
const std::vector<column_definition> expected_columns = {
|
||||||
|
column_definition{"id", data_type_t::type_unsigned_long, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
||||||
|
column_definition{"name", data_type_t::type_varchar, null_attributes, null_option::NOT_NULL },
|
||||||
|
column_definition{"age", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL }
|
||||||
|
};
|
||||||
|
REQUIRE(!columns.empty());
|
||||||
|
REQUIRE(columns.size() == expected_columns.size());
|
||||||
|
|
||||||
|
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
||||||
|
REQUIRE(expected_columns[i].name() == columns[i].name());
|
||||||
|
REQUIRE(expected_columns[i].attributes().options() == columns[i].attributes().options() );
|
||||||
|
REQUIRE(expected_columns[i].type() == columns[i].type() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,54 +3,96 @@
|
||||||
#include "matador/sql/column_generator.hpp"
|
#include "matador/sql/column_generator.hpp"
|
||||||
#include "matador/sql/schema.hpp"
|
#include "matador/sql/schema.hpp"
|
||||||
|
|
||||||
|
#include "models/order.hpp"
|
||||||
#include "models/product.hpp"
|
#include "models/product.hpp"
|
||||||
#include "models/optional.hpp"
|
#include "models/book.hpp"
|
||||||
|
#include "models/author.hpp"
|
||||||
|
|
||||||
using namespace matador::sql;
|
using namespace matador::sql;
|
||||||
using namespace matador::utils;
|
|
||||||
|
|
||||||
TEST_CASE("Generate columns from object", "[column generator]") {
|
TEST_CASE("Generate columns from object", "[column][generator]") {
|
||||||
schema repo("main");
|
using namespace matador::test;
|
||||||
|
schema s("main");
|
||||||
|
s.attach<product>("product");
|
||||||
|
|
||||||
auto columns = column_generator::generate<matador::test::product>(repo);
|
auto columns = column_generator::generate<product>(s);
|
||||||
|
|
||||||
const std::vector<column_definition> expected_columns = {
|
const std::vector<std::string> expected_columns = {
|
||||||
column_definition{"product_name", data_type_t::type_varchar, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
"product_name",
|
||||||
column_definition{"supplier_id", data_type_t::type_unsigned_long, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
"supplier_id",
|
||||||
column_definition{"category_id", data_type_t::type_unsigned_long, constraints::FOREIGN_KEY, null_option::NOT_NULL },
|
"category_id",
|
||||||
column_definition{"quantity_per_unit", data_type_t::type_varchar, null_attributes, null_option::NOT_NULL },
|
"quantity_per_unit",
|
||||||
column_definition{"unit_price", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
"unit_price",
|
||||||
column_definition{"units_in_stock", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
"units_in_stock",
|
||||||
column_definition{"units_in_order", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
"units_in_order",
|
||||||
column_definition{"reorder_level", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL },
|
"reorder_level",
|
||||||
column_definition{"discontinued", data_type_t::type_bool, null_attributes, null_option::NOT_NULL }
|
"discontinued"
|
||||||
};
|
};
|
||||||
REQUIRE(!columns.empty());
|
REQUIRE(!columns.empty());
|
||||||
REQUIRE(columns.size() == expected_columns.size());
|
REQUIRE(columns.size() == expected_columns.size());
|
||||||
|
|
||||||
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
||||||
REQUIRE(expected_columns[i].name() == columns[i].name());
|
REQUIRE(expected_columns[i] == columns[i].name);
|
||||||
REQUIRE(expected_columns[i].attributes().options() == columns[i].attributes().options() );
|
|
||||||
REQUIRE(expected_columns[i].type() == columns[i].type() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("Generate columns from object with nullable columns", "[column generator]") {
|
TEST_CASE("Generate columns for object with has many relation", "[column][generator][relation]") {
|
||||||
schema repo("main");
|
using namespace matador::test;
|
||||||
|
schema s("main");
|
||||||
|
s.attach<product>("product");
|
||||||
|
s.attach<order_details>("order_details");
|
||||||
|
s.attach<order>("order");
|
||||||
|
|
||||||
auto columns = column_generator::generate<matador::test::optional>(repo);
|
auto columns = column_generator::generate<order>(s);
|
||||||
|
|
||||||
const std::vector<column_definition> expected_columns = {
|
const std::vector<column> expected_columns = {
|
||||||
column_definition{"id", data_type_t::type_unsigned_long, constraints::PRIMARY_KEY, null_option::NOT_NULL },
|
{ "order", "order_id", "c01" },
|
||||||
column_definition{"name", data_type_t::type_varchar, null_attributes, null_option::NOT_NULL },
|
{ "order", "order_date", "c02" },
|
||||||
column_definition{"age", data_type_t::type_unsigned_int, null_attributes, null_option::NOT_NULL }
|
{ "order", "required_date", "c03" },
|
||||||
|
{ "order", "shipped_date", "c04" },
|
||||||
|
{ "order", "ship_via", "c05" },
|
||||||
|
{ "order", "freight", "c06" },
|
||||||
|
{ "order", "ship_name", "c07" },
|
||||||
|
{ "order", "ship_address", "c08" },
|
||||||
|
{ "order", "ship_city", "c09" },
|
||||||
|
{ "order", "ship_region", "c10" },
|
||||||
|
{ "order", "ship_postal_code", "c11" },
|
||||||
|
{ "order", "ship_country", "c12" },
|
||||||
|
{ "order_details", "order_details_id", "c13" },
|
||||||
|
{ "order_details", "order_id", "c14" },
|
||||||
|
{ "order_details", "product_id", "c15" }
|
||||||
};
|
};
|
||||||
REQUIRE(!columns.empty());
|
REQUIRE(!columns.empty());
|
||||||
REQUIRE(columns.size() == expected_columns.size());
|
REQUIRE(columns.size() == expected_columns.size());
|
||||||
|
|
||||||
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
||||||
REQUIRE(expected_columns[i].name() == columns[i].name());
|
REQUIRE(expected_columns[i].equals(columns[i]));
|
||||||
REQUIRE(expected_columns[i].attributes().options() == columns[i].attributes().options() );
|
|
||||||
REQUIRE(expected_columns[i].type() == columns[i].type() );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Generate columns for object with eager foreign key relation", "[column][generator][eager]") {
|
||||||
|
using namespace matador::test;
|
||||||
|
schema s("main");
|
||||||
|
s.attach<book>("books");
|
||||||
|
s.attach<author>("authors");
|
||||||
|
|
||||||
|
const std::vector<column> expected_columns {
|
||||||
|
{ "books", "id", "c01" },
|
||||||
|
{ "books", "title", "c02" },
|
||||||
|
{ "authors", "id", "c03" },
|
||||||
|
{ "authors", "first_name", "c04" },
|
||||||
|
{ "authors", "last_name", "c05" },
|
||||||
|
{ "authors", "date_of_birth", "c06" },
|
||||||
|
{ "authors", "year_of_birth", "c07" },
|
||||||
|
{ "authors", "distinguished", "c08" },
|
||||||
|
{ "books", "published_in", "c09" }
|
||||||
|
};
|
||||||
|
auto columns = column_generator::generate<book>(s);
|
||||||
|
|
||||||
|
REQUIRE(!columns.empty());
|
||||||
|
REQUIRE(columns.size() == expected_columns.size());
|
||||||
|
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
||||||
|
REQUIRE(expected_columns[i].equals(columns[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
||||||
#include <catch2/catch_test_macros.hpp>
|
|
||||||
|
|
||||||
#include "matador/sql/column_name_generator.hpp"
|
|
||||||
#include "matador/sql/schema.hpp"
|
|
||||||
|
|
||||||
#include "models/order.hpp"
|
|
||||||
#include "models/product.hpp"
|
|
||||||
|
|
||||||
using namespace matador::sql;
|
|
||||||
|
|
||||||
TEST_CASE("Generate column names from object", "[column name generator]") {
|
|
||||||
schema s("main");
|
|
||||||
s.attach<matador::test::product>("product");
|
|
||||||
|
|
||||||
auto columns = column_name_generator::generate<matador::test::product>(s);
|
|
||||||
|
|
||||||
const std::vector<std::string> expected_columns = {
|
|
||||||
"product_name",
|
|
||||||
"supplier_id",
|
|
||||||
"category_id",
|
|
||||||
"quantity_per_unit",
|
|
||||||
"unit_price",
|
|
||||||
"units_in_stock",
|
|
||||||
"units_in_order",
|
|
||||||
"reorder_level",
|
|
||||||
"discontinued"
|
|
||||||
};
|
|
||||||
REQUIRE(!columns.empty());
|
|
||||||
REQUIRE(columns.size() == expected_columns.size());
|
|
||||||
|
|
||||||
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
|
||||||
REQUIRE(expected_columns[i] == columns[i].name);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_CASE("Generate column names for object with has many relation", "[column][relation]") {
|
|
||||||
schema s("main");
|
|
||||||
s.attach<matador::test::product>("product");
|
|
||||||
s.attach<matador::test::order_details>("order_details");
|
|
||||||
s.attach<matador::test::order>("order");
|
|
||||||
|
|
||||||
auto columns = column_name_generator::generate<matador::test::order>(s);
|
|
||||||
|
|
||||||
const std::vector<std::string> expected_columns = {
|
|
||||||
"order_id",
|
|
||||||
"order_date",
|
|
||||||
"required_date",
|
|
||||||
"shipped_date",
|
|
||||||
"ship_via",
|
|
||||||
"freight",
|
|
||||||
"ship_name",
|
|
||||||
"ship_address",
|
|
||||||
"ship_city",
|
|
||||||
"ship_region",
|
|
||||||
"ship_postal_code",
|
|
||||||
"ship_country",
|
|
||||||
"order_details_id",
|
|
||||||
"order_id",
|
|
||||||
"product_id",
|
|
||||||
};
|
|
||||||
REQUIRE(!columns.empty());
|
|
||||||
REQUIRE(columns.size() == expected_columns.size());
|
|
||||||
|
|
||||||
for (size_t i = 0; i != expected_columns.size(); ++i) {
|
|
||||||
REQUIRE(expected_columns[i] == columns[i].name);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -25,7 +25,7 @@ struct book
|
||||||
namespace field = matador::utils::access;
|
namespace field = matador::utils::access;
|
||||||
field::primary_key(op, "id", id);
|
field::primary_key(op, "id", id);
|
||||||
field::attribute(op, "title", title, 511);
|
field::attribute(op, "title", title, 511);
|
||||||
field::has_one(op, "author_id", book_author, matador::utils::default_foreign_attributes);
|
field::has_one(op, "author_id", book_author, utils::fetch_type::EAGER);
|
||||||
field::attribute(op, "published_in", published_in);
|
field::attribute(op, "published_in", published_in);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue