attribute_definition and object_definition progress

This commit is contained in:
Sascha Kühl 2025-11-17 15:58:09 +01:00
parent 9ffcee1317
commit 7242dc2612
17 changed files with 161 additions and 205 deletions

View File

@ -240,9 +240,9 @@ utils::result<std::vector<object::attribute_definition>, utils::error> postgres_
// Todo: extract size // Todo: extract size
auto type = (string2type(reader.column(2))); auto type = (string2type(reader.column(2)));
end = nullptr; end = nullptr;
object::null_option null_opt{object::null_option::NULLABLE}; object::null_option_type null_opt{object::null_option_type::NULLABLE};
if (strtoul(reader.column(4), &end, 10) == 0) { if (strtoul(reader.column(4), &end, 10) == 0) {
null_opt = object::null_option::NOT_NULL; null_opt = object::null_option_type::NOT_NULL;
} }
// f.default_value(res->column(4)); // f.default_value(res->column(4));
prototype.emplace_back(name, type, utils::null_attributes, null_opt, index); prototype.emplace_back(name, type, utils::null_attributes, null_opt, index);

View File

@ -11,10 +11,18 @@
namespace matador::object { namespace matador::object {
enum class null_option : uint8_t { enum class null_option_type : uint8_t {
NULLABLE, NOT_NULL NULLABLE, NOT_NULL
}; };
class object_definition;
struct attribute_options {
utils::field_attributes attributes;
null_option_type null_option{null_option_type::NOT_NULL};
int index{-1};
};
class attribute_definition { class attribute_definition {
public: public:
explicit attribute_definition(const char *name); // NOLINT(*-explicit-constructor) explicit attribute_definition(const char *name); // NOLINT(*-explicit-constructor)
@ -26,12 +34,6 @@ public:
attribute_definition& operator=(attribute_definition&&) noexcept = default; attribute_definition& operator=(attribute_definition&&) noexcept = default;
attribute_definition() = default; attribute_definition() = default;
template<typename Type>
attribute_definition(std::string name, std::string table_name, const utils::field_attributes& attr)
: attribute_definition(std::move(name), std::move(table_name), utils::data_type_traits<Type>::type(attr.size()), attr)
{}
attribute_definition(std::string name, std::string table_name, utils::basic_type type, const utils::field_attributes& attr);
template<typename Type> template<typename Type>
attribute_definition(std::string name, const utils::field_attributes& attr) attribute_definition(std::string name, const utils::field_attributes& attr)
@ -39,30 +41,32 @@ public:
{} {}
template<typename Type> template<typename Type>
attribute_definition(std::string name, const Type &, const utils::field_attributes& attr, null_option null_opt) attribute_definition(std::string name, const Type &, const utils::field_attributes& attr, null_option_type null_opt)
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), attr, null_opt) : attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), attr, null_opt)
{} {}
template<size_t SIZE> template<size_t SIZE>
attribute_definition(std::string name, const char (&)[SIZE], const utils::field_attributes& attr, const null_option null_opt) attribute_definition(std::string name, const char (&)[SIZE], const utils::field_attributes& attr, const null_option_type null_opt)
: attribute_definition(std::move(name), utils::data_type_traits<const char*>::type(attr.size()), attr, null_opt) : attribute_definition(std::move(name), utils::data_type_traits<const char*>::type(attr.size()), attr, null_opt)
{} {}
attribute_definition(std::string name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, int index = 0); attribute_definition(std::string name, utils::basic_type type, const utils::field_attributes&, null_option_type null_opt, int index = 0);
attribute_definition(std::string name, std::string table_name, utils::basic_type type, const utils::field_attributes&, null_option null_opt, int index = 0);
template<typename Type> template<typename Type>
attribute_definition(std::string name, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt) attribute_definition(std::string name, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option_type null_opt)
: attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), ref_column, attr, null_opt) : attribute_definition(std::move(name), utils::data_type_traits<Type>::type(attr.size()), ref_column, attr, null_opt)
{} {}
attribute_definition(std::string name, utils::basic_type type, int index, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option null_opt); attribute_definition(std::string name, utils::basic_type type, int index, const std::shared_ptr<attribute_definition> &ref_column, const utils::field_attributes& attr, null_option_type null_opt);
attribute_definition(std::string name, utils::basic_type type, const std::shared_ptr<attribute_definition> &ref_column = {});
attribute_definition(std::string name, utils::basic_type type, const attribute_options& options, const std::shared_ptr<object_definition>& obj = {}, const std::shared_ptr<attribute_definition> &ref_column = {});
[[nodiscard]] const std::string& name() const; [[nodiscard]] const std::string& name() const;
void name(const std::string& n); void name(const std::string& n);
[[nodiscard]] std::string full_name() const; [[nodiscard]] std::string full_name() const;
[[nodiscard]] std::string table_name() const; [[nodiscard]] std::shared_ptr<object_definition> object() const;
void table_name(const std::string& tn); void object(const std::shared_ptr<object_definition> &obj);
[[nodiscard]] int index() const; [[nodiscard]] int index() const;
[[nodiscard]] const utils::field_attributes& attributes() const; [[nodiscard]] const utils::field_attributes& attributes() const;
[[nodiscard]] utils::field_attributes& attributes(); [[nodiscard]] utils::field_attributes& attributes();
@ -95,15 +99,14 @@ private:
using data_type_index = std::vector<utils::basic_type>; using data_type_index = std::vector<utils::basic_type>;
private: private:
friend class object_definition;
static const data_type_index data_type_index_; static const data_type_index data_type_index_;
std::string name_; std::string name_;
std::string table_; std::shared_ptr<object_definition> object_{};
int index_{-1}; attribute_options options_;
utils::field_attributes attributes_;
null_option null_option_{null_option::NOT_NULL};
utils::basic_type type_{utils::basic_type::type_null}; utils::basic_type type_{utils::basic_type::type_null};
size_t size_{0};
std::shared_ptr<attribute_definition> reference_column_; std::shared_ptr<attribute_definition> reference_column_;
}; };
@ -116,15 +119,15 @@ private:
* @param null_opt * @param null_opt
* @return A column object with a given name * @return A column object with a given name
*/ */
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL); attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr = utils::null_attributes, null_option_type null_opt = null_option_type::NOT_NULL);
template < typename Type > template < typename Type >
attribute_definition make_column(const std::string &name, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL) attribute_definition make_column(const std::string &name, utils::field_attributes attr = utils::null_attributes, null_option_type null_opt = null_option_type::NOT_NULL)
{ {
return make_column(name, utils::data_type_traits<Type>::type(0), attr, null_opt); return make_column(name, utils::data_type_traits<Type>::type(0), attr, null_opt);
} }
template <> template <>
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt); attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option_type null_opt);
template < typename Type > template < typename Type >
attribute_definition make_pk_column(const std::string &name, size_t size = 0) attribute_definition make_pk_column(const std::string &name, size_t size = 0)
@ -143,7 +146,7 @@ attribute_definition make_fk_column(const std::string &name, size_t size, const
template < typename Type > template < typename Type >
[[maybe_unused]] attribute_definition make_fk_column(const std::string &name, const std::shared_ptr<attribute_definition> &ref_column) [[maybe_unused]] attribute_definition make_fk_column(const std::string &name, const std::shared_ptr<attribute_definition> &ref_column)
{ {
return {name, utils::data_type_traits<Type>::type(0), 0, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL}; return {name, utils::data_type_traits<Type>::type(0), 0, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL};
} }
template <> template <>
@ -154,7 +157,7 @@ template < typename Type >
return { return {
name, utils::data_type_traits<Type>::type(size), 0, name, utils::data_type_traits<Type>::type(size), 0,
std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::data_type_traits<Type>::type(size), utils::constraints::FOREIGN_KEY), std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::data_type_traits<Type>::type(size), utils::constraints::FOREIGN_KEY),
{ 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL { 0, utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL
}; };
} }
@ -163,7 +166,7 @@ template < typename Type >
return { return {
name, utils::data_type_traits<Type>::type(0), 0, name, utils::data_type_traits<Type>::type(0), 0,
std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::data_type_traits<Type>::type(0), utils::constraints::FOREIGN_KEY), std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::data_type_traits<Type>::type(0), utils::constraints::FOREIGN_KEY),
{ 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL { 0, utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL
}; };
} }

View File

@ -26,7 +26,7 @@ public:
template<class Type> template<class Type>
attribute_definition generate(const char *id, Type &x, const std::shared_ptr<attribute_definition> &ref_column) { attribute_definition generate(const char *id, Type &x, const std::shared_ptr<attribute_definition> &ref_column) {
access::process(*this, x); access::process(*this, x);
return attribute_definition{id, type_, 0, ref_column, {utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL}; return attribute_definition{id, type_, 0, ref_column, {utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL};
} }
template<typename ValueType> template<typename ValueType>
@ -122,7 +122,7 @@ public:
private: private:
[[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> determine_foreign_ref(const std::type_index &ti) const; [[nodiscard]] utils::result<std::shared_ptr<attribute_definition>, utils::error> determine_foreign_ref(const std::type_index &ti) const;
void insert_missing_reference_column(const std::type_index &ti, std::shared_ptr<attribute_definition> ref_column) const; void insert_missing_reference_column(const std::type_index &ti, const std::shared_ptr<attribute_definition>& ref_column) const;
private: private:
size_t index_ = 0; size_t index_ = 0;
@ -140,13 +140,13 @@ void attribute_definition_generator::on_primary_key(const char *id, ValueType &x
template<typename Type> template<typename Type>
void attribute_definition_generator::on_attribute(const char *id, Type &x, const utils::field_attributes &attr) void attribute_definition_generator::on_attribute(const char *id, Type &x, const utils::field_attributes &attr)
{ {
columns_.emplace_back(id, x, attr, null_option::NOT_NULL); columns_.emplace_back(id, x, attr, null_option_type::NOT_NULL);
} }
template<typename Type> template<typename Type>
void attribute_definition_generator::on_attribute(const char *id, std::optional<Type> & /*x*/, const utils::field_attributes &attr) void attribute_definition_generator::on_attribute(const char *id, std::optional<Type> & /*x*/, const utils::field_attributes &attr)
{ {
columns_.emplace_back(id, utils::data_type_traits<Type>::type(attr.size()), attr, null_option::NULLABLE); columns_.emplace_back(id, utils::data_type_traits<Type>::type(attr.size()), attr, null_option_type::NULLABLE);
} }
} }

View File

@ -18,14 +18,17 @@ public:
using const_iterator = column_by_index::const_iterator; using const_iterator = column_by_index::const_iterator;
object_definition() = default; object_definition() = default;
object_definition(std::initializer_list<attribute_definition> columns); explicit object_definition(std::string name);
explicit object_definition(const std::vector<attribute_definition> &columns); object_definition(std::string name, std::initializer_list<attribute_definition> columns);
explicit object_definition(std::string name, const std::vector<attribute_definition> &columns);
object_definition(const object_definition &x); object_definition(const object_definition &x);
object_definition& operator=(const object_definition &x); object_definition& operator=(const object_definition &x);
object_definition(object_definition&&) noexcept = default; object_definition(object_definition&&) noexcept = default;
object_definition& operator=(object_definition&&) noexcept = default; object_definition& operator=(object_definition&&) noexcept = default;
~object_definition() = default; ~object_definition() = default;
[[nodiscard]] const std::string& name() const;
[[nodiscard]] bool has_primary_key() const; [[nodiscard]] bool has_primary_key() const;
[[nodiscard]] std::optional<attribute_definition> primary_key() const; [[nodiscard]] std::optional<attribute_definition> primary_key() const;
@ -33,7 +36,7 @@ public:
void append(const std::string &name, long size = -1) { void append(const std::string &name, long size = -1) {
append(make_column<Type>(name, size)); append(make_column<Type>(name, size));
} }
void append(attribute_definition col); void append(attribute_definition&& col);
[[nodiscard]] const std::vector<attribute_definition>& columns() const; [[nodiscard]] const std::vector<attribute_definition>& columns() const;
@ -60,6 +63,9 @@ private:
void add_to_map(attribute_definition &col, size_t index); void add_to_map(attribute_definition &col, size_t index);
private: private:
friend class repository_node;
std::string name_;
column_by_index columns_; column_by_index columns_;
column_by_name_map columns_by_name_; column_by_name_map columns_by_name_;

View File

@ -17,17 +17,22 @@ public:
using node_ptr = std::shared_ptr<repository_node>; using node_ptr = std::shared_ptr<repository_node>;
template < typename Type > template < typename Type >
static std::shared_ptr<repository_node> make_node(object::repository& tree, const std::string& name) { static std::shared_ptr<repository_node> make_node(repository& repo, const std::string& name) {
auto node = std::shared_ptr<repository_node>(new repository_node(tree, name, typeid(Type))); auto node = std::shared_ptr<repository_node>(new repository_node(repo, name, typeid(Type)));
primary_key_resolver resolver; primary_key_resolver resolver;
object_definition obj{name, {}};
auto pk_info = resolver.resolve<Type>(); auto pk_info = resolver.resolve<Type>();
auto ref_column = determine_reference_column(typeid(Type), name, pk_info, tree); auto ref_column = determine_reference_column(typeid(Type), name, pk_info, repo);
const auto attributes = attribute_definition_generator::generate<Type>(repo);
for (auto&& attr : attributes) {
obj.append(std::move(attr));
}
auto info = std::make_unique<object_info<Type>>( auto info = std::make_unique<object_info<Type>>(
node, node,
std::move(pk_info.pk), std::move(pk_info.pk),
ref_column, ref_column,
object_definition{attribute_definition_generator::generate<Type>(tree)}, std::move(obj),
[]{ return std::make_unique<Type>(); } []{ return std::make_unique<Type>(); }
); );
node->info_ = std::move(info); node->info_ = std::move(info);
@ -87,11 +92,11 @@ private:
void unlink(); void unlink();
static utils::result<node_ptr, utils::error> make_and_attach_node(object::repository& tree, const std::string& name, const std::type_index& ti); static utils::result<node_ptr, utils::error> make_and_attach_node(repository& repo, const std::string& name, const std::type_index& ti);
static std::shared_ptr<attribute_definition> determine_reference_column(const std::type_index& ti, static std::shared_ptr<attribute_definition> determine_reference_column(const std::type_index& ti,
const std::string& name, object_definition& obj,
const primary_key_info& pk_info, const primary_key_info& pk_info,
object::repository& tree); repository& repo);
private: private:
friend class repository; friend class repository;
@ -100,7 +105,7 @@ private:
friend class foreign_node_completer; friend class foreign_node_completer;
friend class const_repository_node_iterator; friend class const_repository_node_iterator;
object::repository &repo_; repository &repo_;
std::type_index type_index_; std::type_index type_index_;
std::unique_ptr<basic_object_info> info_; std::unique_ptr<basic_object_info> info_;

View File

@ -3,22 +3,13 @@
#include "matador/utils/value.hpp" #include "matador/utils/value.hpp"
#include "matador/utils/basic_types.hpp" #include "matador/utils/constraints.hpp"
#include <optional> #include <optional>
#include <string> #include <string>
namespace matador::utils {
enum class constraints : unsigned char;
}
namespace matador::sql { namespace matador::sql {
enum struct field_type {
Attribute,
PrimaryKey,
ForeignKey
};
/** /**
* *
*/ */
@ -26,12 +17,12 @@ class field {
public: public:
explicit field(std::string name); explicit field(std::string name);
template<typename Type> template<typename Type>
field(std::string name, Type value, const field_type type = field_type::Attribute, const size_t size = 0, const int index = -1) field(std::string name, Type value, const utils::constraints type = utils::constraints::NONE, const size_t size = 0, const int index = -1)
: name_(std::move(name)) : name_(std::move(name))
, type_(type) , type_(type)
, index_(index) , index_(index)
, value_(value, size) {} , value_(value, size) {}
field(std::string name, utils::basic_type dt, field_type type = field_type::Attribute, size_t size = 0, int index = -1); field(std::string name, utils::basic_type dt, utils::constraints type = utils::constraints::NONE, size_t size = 0, int index = -1);
field(const field &x) = default; field(const field &x) = default;
field& operator=(const field &x) = default; field& operator=(const field &x) = default;
field(field &&x) noexcept; field(field &&x) noexcept;
@ -45,7 +36,7 @@ public:
} }
[[nodiscard]] const std::string& name() const; [[nodiscard]] const std::string& name() const;
[[nodiscard]] field_type type() const; [[nodiscard]] utils::constraints type() const;
[[nodiscard]] size_t size() const; [[nodiscard]] size_t size() const;
[[nodiscard]] int index() const; [[nodiscard]] int index() const;
@ -71,18 +62,16 @@ public:
friend std::ostream& operator<<(std::ostream &out, const field &col); friend std::ostream& operator<<(std::ostream &out, const field &col);
private: private:
static utils::constraints determine_constraint(field_type type);
template<class Operator> template<class Operator>
void process(Operator &op) { void process(Operator &op) {
op.on_attribute(name_.c_str(), value_, { value_.size(), determine_constraint(type_) } ); op.on_attribute(name_.c_str(), value_, { value_.size(), type_ } );
} }
private: private:
friend class record; friend class record;
std::string name_; std::string name_;
field_type type_{field_type::Attribute}; utils::constraints type_{utils::constraints::NONE};
int index_{-1}; int index_{-1};
utils::value value_; utils::value value_;

View File

@ -1,64 +1,43 @@
#include "matador/object/attribute_definition.hpp" #include "matador/object/attribute_definition.hpp"
#include "matador/object/object_definition.hpp"
#include <ostream> #include <ostream>
#include <utility> #include <utility>
namespace matador::object { namespace matador::object {
attribute_definition::attribute_definition(const char *name) attribute_definition::attribute_definition(const char *name)
: name_(name) : attribute_definition(name, utils::basic_type::type_null, {utils::null_attributes}) {
, attributes_(utils::null_attributes) {
} }
attribute_definition::attribute_definition(std::string name) attribute_definition::attribute_definition(std::string name)
: name_(std::move(name)) : attribute_definition(std::move(name), utils::basic_type::type_null, {utils::null_attributes}) {
, attributes_(utils::null_attributes) {
}
attribute_definition::attribute_definition(std::string name,
std::string table_name,
const utils::basic_type type,
const utils::field_attributes& attr)
: name_(std::move(name))
, table_(std::move(table_name))
, index_(0)
, attributes_(attr)
, type_(type){
} }
attribute_definition::attribute_definition(std::string name, attribute_definition::attribute_definition(std::string name,
const utils::basic_type type, const utils::basic_type type,
const utils::field_attributes &attr, const utils::field_attributes &attr,
const null_option null_opt, const null_option_type null_opt,
const int index) const int index)
: name_(std::move(name)) : attribute_definition(std::move(name), type, {attr, null_opt, index}) {
, index_(index)
, attributes_(attr)
, null_option_(null_opt)
, type_(type) {
}
attribute_definition::attribute_definition(std::string name,
std::string table_name,
const utils::basic_type type,
const utils::field_attributes &attr, const null_option null_opt,
const int index)
: name_(std::move(name))
, table_(std::move(table_name))
, index_(index)
, attributes_(attr)
, null_option_(null_opt)
, type_(type) {
} }
attribute_definition::attribute_definition(std::string name, attribute_definition::attribute_definition(std::string name,
const utils::basic_type type, const utils::basic_type type,
const int index, const int index,
const std::shared_ptr<attribute_definition> &ref_column, const std::shared_ptr<attribute_definition> &ref_column,
const utils::field_attributes &attr, const null_option null_opt) const utils::field_attributes &attr,
const null_option_type null_opt)
: attribute_definition(std::move(name), type, {attr, null_opt, index}, {}, ref_column) {
}
attribute_definition::attribute_definition( std::string name, const utils::basic_type type, const std::shared_ptr<attribute_definition>& ref_column )
: attribute_definition(std::move(name), type, {}, {}, ref_column) {
}
attribute_definition::attribute_definition( std::string name, const utils::basic_type type, const attribute_options& options, const std::shared_ptr<object_definition>& obj, const std::shared_ptr<attribute_definition>& ref_column )
: name_( std::move( name ) ) : name_( std::move( name ) )
, index_(index) , options_( options )
, attributes_(attr)
, null_option_(null_opt)
, type_( type ) , type_( type )
, reference_column_( ref_column ) { , reference_column_( ref_column ) {
} }
@ -72,31 +51,31 @@ void attribute_definition::name( const std::string& n ) {
} }
std::string attribute_definition::full_name() const { std::string attribute_definition::full_name() const {
return table_ + "." + name_; return object_ ? object_->name() + "." + name_ : name_;
} }
std::string attribute_definition::table_name() const { std::shared_ptr<object_definition> attribute_definition::object() const {
return table_; return object_;
} }
void attribute_definition::table_name( const std::string& tn ) { void attribute_definition::object(const std::shared_ptr<object_definition>& obj) {
table_= tn; object_ = obj;
} }
int attribute_definition::index() const { int attribute_definition::index() const {
return index_; return options_.index;
} }
const utils::field_attributes &attribute_definition::attributes() const { const utils::field_attributes &attribute_definition::attributes() const {
return attributes_; return options_.attributes;
} }
utils::field_attributes& attribute_definition::attributes() { utils::field_attributes& attribute_definition::attributes() {
return attributes_; return options_.attributes;
} }
bool attribute_definition::is_nullable() const { bool attribute_definition::is_nullable() const {
return null_option_ == null_option::NULLABLE; return options_.null_option == null_option_type::NULLABLE;
} }
utils::basic_type attribute_definition::type() const { utils::basic_type attribute_definition::type() const {
@ -104,7 +83,7 @@ utils::basic_type attribute_definition::type() const {
} }
void attribute_definition::change_type(const utils::basic_type type, const utils::field_attributes& attr) { void attribute_definition::change_type(const utils::basic_type type, const utils::field_attributes& attr) {
attributes_ = attr; options_.attributes = attr;
type_ = type; type_ = type;
} }
@ -153,13 +132,13 @@ bool attribute_definition::is_null() const {
} }
attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr, attribute_definition make_column(const std::string &name, utils::basic_type type, utils::field_attributes attr,
null_option null_opt) { null_option_type null_opt) {
return {name, type, attr, null_opt}; return {name, type, attr, null_opt};
} }
template<> template<>
attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, attribute_definition make_column<std::string>(const std::string &name, utils::field_attributes attr,
null_option null_opt) { null_option_type null_opt) {
return make_column(name, utils::data_type_traits<std::string>::type(attr.size()), attr, null_opt); return make_column(name, utils::data_type_traits<std::string>::type(attr.size()), attr, null_opt);
} }
@ -172,7 +151,7 @@ template<>
attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::shared_ptr<attribute_definition> &ref_column) { attribute_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::shared_ptr<attribute_definition> &ref_column) {
return { return {
name, utils::data_type_traits<std::string>::type(size), 0, ref_column, name, utils::data_type_traits<std::string>::type(size), 0, ref_column,
{size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL {size, utils::constraints::FOREIGN_KEY}, null_option_type::NOT_NULL
}; };
} }
@ -180,8 +159,8 @@ template<>
attribute_definition make_fk_column<std::string>( const std::string& name, const std::string& ref_table_name, const std::string& ref_column_name ) { attribute_definition make_fk_column<std::string>( const std::string& name, const std::string& ref_table_name, const std::string& ref_column_name ) {
return { return {
name, utils::basic_type::type_varchar, 0, name, utils::basic_type::type_varchar, 0,
std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::basic_type::type_varchar, utils::constraints::FOREIGN_KEY), std::make_shared<attribute_definition>(ref_column_name, std::make_shared<object_definition>(ref_table_name), utils::basic_type::type_varchar, utils::constraints::FOREIGN_KEY),
{ 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL { 0, utils::constraints::FOREIGN_KEY }, null_option_type::NOT_NULL
}; };
} }
@ -190,7 +169,7 @@ attribute_definition make_fk_column<std::string>(const std::string &name, size_t
const auto ref_column = std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::basic_type::type_varchar, utils::constraints::FOREIGN_KEY); const auto ref_column = std::make_shared<attribute_definition>(ref_column_name, ref_table_name, utils::basic_type::type_varchar, utils::constraints::FOREIGN_KEY);
return { return {
name, utils::data_type_traits<std::string>::type(size), 0, ref_column, name, utils::data_type_traits<std::string>::type(size), 0, ref_column,
{size, utils::constraints::FOREIGN_KEY}, null_option::NOT_NULL {size, utils::constraints::FOREIGN_KEY}, null_option_type::NOT_NULL
}; };
} }
} }

View File

@ -3,13 +3,12 @@
namespace matador::object { namespace matador::object {
attribute_definition_generator::attribute_definition_generator(std::vector<object::attribute_definition> &columns, const repository &repo) attribute_definition_generator::attribute_definition_generator(std::vector<attribute_definition> &columns, const repository &repo)
: columns_(columns) : columns_(columns)
, repo_(repo) , repo_(repo)
{} {}
void attribute_definition_generator::on_revision(const char *id, uint64_t &rev) void attribute_definition_generator::on_revision(const char *id, uint64_t &rev) {
{
on_attribute(id, rev); on_attribute(id, rev);
} }
@ -17,7 +16,7 @@ utils::result<std::shared_ptr<attribute_definition>, utils::error> attribute_def
return repo_.reference_column(ti); return repo_.reference_column(ti);
} }
void attribute_definition_generator::insert_missing_reference_column(const std::type_index& ti, std::shared_ptr<attribute_definition> ref_column) const { void attribute_definition_generator::insert_missing_reference_column(const std::type_index& ti, const std::shared_ptr<attribute_definition>& ref_column) const {
const_cast<repository&>(repo_).missing_references_.insert({ti, ref_column}); const_cast<repository&>(repo_).missing_references_.insert({ti, ref_column});
} }

View File

@ -1,18 +1,24 @@
#include "matador/object/object_definition.hpp" #include "matador/object/object_definition.hpp"
namespace matador::object { namespace matador::object {
object_definition::object_definition(const std::initializer_list<attribute_definition> columns) object_definition::object_definition(std::string name)
: columns_(columns) { : name_(std::move(name)) {}
object_definition::object_definition(std::string name, const std::initializer_list<attribute_definition> columns)
: name_(std::move(name))
, columns_(columns) {
init(); init();
} }
object_definition::object_definition(const std::vector<attribute_definition> &columns) object_definition::object_definition(std::string name, const std::vector<attribute_definition> &columns)
: columns_(columns) { : name_(std::move(name))
, columns_(columns) {
init(); init();
} }
object_definition::object_definition(const object_definition &x) object_definition::object_definition(const object_definition &x)
: columns_(x.columns_) : name_(x.name_)
, columns_(x.columns_)
, pk_index_(x.pk_index_) { , pk_index_(x.pk_index_) {
for (auto& col : columns_) { for (auto& col : columns_) {
add_to_map(col, col.index()); add_to_map(col, col.index());
@ -25,6 +31,7 @@ object_definition &object_definition::operator=(const object_definition &x)
return *this; return *this;
} }
name_ = x.name_;
columns_ = x.columns_; columns_ = x.columns_;
columns_by_name_.clear(); columns_by_name_.clear();
pk_index_ = x.pk_index_; pk_index_ = x.pk_index_;
@ -34,8 +41,11 @@ object_definition &object_definition::operator=(const object_definition &x)
return *this; return *this;
} }
bool object_definition::has_primary_key() const const std::string& object_definition::name() const {
{ return name_;
}
bool object_definition::has_primary_key() const {
return pk_index_ > -1; return pk_index_ > -1;
} }
@ -48,14 +58,12 @@ std::optional<attribute_definition> object_definition::primary_key() const
return columns_[pk_index_]; return columns_[pk_index_];
} }
void object_definition::append(attribute_definition col) void object_definition::append(attribute_definition&& col) {
{
auto &ref = columns_.emplace_back(std::move(col)); auto &ref = columns_.emplace_back(std::move(col));
add_to_map(ref, columns_.size()-1); add_to_map(ref, columns_.size()-1);
} }
const std::vector<object::attribute_definition> &object_definition::columns() const const std::vector<object::attribute_definition> &object_definition::columns() const {
{
return columns_; return columns_;
} }
@ -71,12 +79,12 @@ const attribute_definition &object_definition::at( const size_t index) const
object_definition::iterator object_definition::find(const std::string &column_name) object_definition::iterator object_definition::find(const std::string &column_name)
{ {
auto it = columns_by_name_.find(column_name); const auto it = columns_by_name_.find(column_name);
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end(); return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
} }
object_definition::const_iterator object_definition::find(const std::string &column_name) const { object_definition::const_iterator object_definition::find(const std::string &column_name) const {
auto it = columns_by_name_.find(column_name); const auto it = columns_by_name_.find(column_name);
return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end(); return it != columns_by_name_.end() ? columns_.begin() + it->second.second : columns_.end();
} }

View File

@ -45,10 +45,12 @@ const basic_object_info &repository_node::info() const {
void repository_node::update_name(const std::string& name) { void repository_node::update_name(const std::string& name) {
name_ = name; name_ = name;
info_->reference_column()->table_name(name); if (info_->reference_column() && info_->reference_column()->object() != nullptr) {
info_->reference_column()->object()->name_ = name;
}
} }
const object::repository& repository_node::schema() const { const repository& repository_node::schema() const {
return repo_; return repo_;
} }
@ -96,27 +98,27 @@ void repository_node::unlink() {
previous_sibling_.reset(); previous_sibling_.reset();
} }
utils::result<repository_node::node_ptr, utils::error> repository_node::make_and_attach_node(object::repository& tree, const std::string& name, const std::type_index& ti) { utils::result<repository_node::node_ptr, utils::error> repository_node::make_and_attach_node(repository& repo, const std::string& name, const std::type_index& ti) {
const auto node = std::shared_ptr<repository_node>(new repository_node(tree, name, ti)); const auto node = std::shared_ptr<repository_node>(new repository_node(repo, name, ti));
return tree.attach_node(node, ""); return repo.attach_node(node, "");
} }
std::shared_ptr<attribute_definition> repository_node::determine_reference_column(const std::type_index& ti, const std::string& name, const primary_key_info& pk_info, object::repository& tree) { std::shared_ptr<attribute_definition> repository_node::determine_reference_column(const std::type_index& ti, object_definition& obj, const primary_key_info& pk_info, repository& repo) {
const auto it = tree.missing_references_.find(ti); const auto it = repo.missing_references_.find(ti);
if (it == tree.missing_references_.end()) { if (it == repo.missing_references_.end()) {
return std::make_shared<attribute_definition>(pk_info.pk_column_name, name, pk_info.type, utils::constraints::FOREIGN_KEY); return std::make_shared<attribute_definition>(pk_info.pk_column_name, pk_info.type, attribute_options{utils::constraints::FOREIGN_KEY});
} }
auto ref_column = it->second; auto ref_column = it->second;
tree.missing_references_.erase(it); repo.missing_references_.erase(it);
ref_column->name(pk_info.pk_column_name); ref_column->name(pk_info.pk_column_name);
ref_column->table_name(name); ref_column->object(obj);
ref_column->change_type(pk_info.type); ref_column->change_type(pk_info.type);
ref_column->attributes() = utils::constraints::FOREIGN_KEY; ref_column->attributes() = utils::constraints::FOREIGN_KEY;
if (name.empty()) { if (obj.name().empty()) {
tree.missing_references_.insert({ti, ref_column}); repo.missing_references_.insert({ti, ref_column});
} }
return ref_column; return ref_column;

View File

@ -7,23 +7,13 @@
namespace matador::query { namespace matador::query {
namespace detail { namespace detail {
sql::field_type determine_field_type(const utils::constraints c) {
if (is_constraint_set(c, utils::constraints::FOREIGN_KEY)) {
return sql::field_type::ForeignKey;
}
if (is_constraint_set(c, utils::constraints::PRIMARY_KEY)) {
return sql::field_type::PrimaryKey;
}
return sql::field_type::Attribute;
}
sql::record *create_prototype(const std::vector<object::attribute_definition> &prototype) { sql::record *create_prototype(const std::vector<object::attribute_definition> &prototype) {
auto result = std::make_unique<sql::record>(); auto result = std::make_unique<sql::record>();
for (const auto &col: prototype) { for (const auto &col: prototype) {
result->append({ result->append({
col.name(), col.name(),
col.type(), col.type(),
determine_field_type(col.attributes().options()), col.attributes().options(),
col.attributes().size(), col.attributes().size(),
col.index() col.index()
}); });

View File

@ -1,7 +1,5 @@
#include "matador/sql/field.hpp" #include "matador/sql/field.hpp"
#include "matador/utils/constraints.hpp"
#include <ostream> #include <ostream>
namespace matador::sql { namespace matador::sql {
@ -11,7 +9,7 @@ field::field(std::string name)
, value_(nullptr) , value_(nullptr)
{} {}
field::field(std::string name, const utils::basic_type dt, const field_type type, const size_t size, const int index) field::field(std::string name, const utils::basic_type dt, const utils::constraints type, const size_t size, const int index)
: name_(std::move(name)) : name_(std::move(name))
, type_(type) , type_(type)
, index_(index) , index_(index)
@ -42,7 +40,7 @@ const std::string &field::name() const
return name_; return name_;
} }
field_type field::type() const { utils::constraints field::type() const {
return type_; return type_;
} }
@ -62,19 +60,6 @@ std::ostream &operator<<(std::ostream &out, const field &col)
return out; return out;
} }
utils::constraints field::determine_constraint(const field_type type) {
switch (type) {
case field_type::PrimaryKey:
return utils::constraints::PRIMARY_KEY;
case field_type::ForeignKey:
return utils::constraints::FOREIGN_KEY;
case field_type::Attribute:
default:
return utils::constraints::NONE;
}
}
std::string field::str() const std::string field::str() const
{ {
return as<std::string>().value_or(""); return as<std::string>().value_or("");
@ -116,15 +101,15 @@ bool field::is_null() const
} }
bool field::is_primary_key() const { bool field::is_primary_key() const {
return type_ == field_type::PrimaryKey; return type_ == utils::constraints::PRIMARY_KEY;
} }
bool field::is_foreign_key() const { bool field::is_foreign_key() const {
return type_ == field_type::ForeignKey; return type_ == utils::constraints::FOREIGN_KEY;
} }
bool field::is_attribute() const { bool field::is_attribute() const {
return type_ == field_type::Attribute; return !is_primary_key() && !is_foreign_key();
} }

View File

@ -5,16 +5,6 @@
namespace matador::sql::detail { namespace matador::sql::detail {
field_type determine_field_type(const utils::constraints c) {
if (is_constraint_set(c, utils::constraints::FOREIGN_KEY)) {
return field_type::ForeignKey;
}
if (is_constraint_set(c, utils::constraints::PRIMARY_KEY)) {
return field_type::PrimaryKey;
}
return field_type::Attribute;
}
template<> template<>
record *create_prototype<record>(const std::vector<object::attribute_definition> &prototype) { record *create_prototype<record>(const std::vector<object::attribute_definition> &prototype) {
auto result = std::make_unique<record>(); auto result = std::make_unique<record>();
@ -22,7 +12,7 @@ record *create_prototype<record>(const std::vector<object::attribute_definition>
result->append({ result->append({
col.name(), col.name(),
col.type(), col.type(),
determine_field_type(col.attributes().options()), col.attributes().options(),
col.attributes().size(), col.attributes().size(),
col.index() col.index()
}); });

View File

@ -14,7 +14,7 @@ using namespace matador::test;
TEST_CASE_METHOD(SchemaFixture, "Test schema one-two-many", "[schema]") { TEST_CASE_METHOD(SchemaFixture, "Test schema one-two-many", "[schema]") {
using namespace matador::test; using namespace matador::test;
orm::schema repo(pool, "NoopSchema"); orm::schema repo(pool/*, "NoopSchema"*/);
auto result = repo.attach<department>("departments") auto result = repo.attach<department>("departments")
.and_then( [&repo] { return repo.attach<employee>("employees"); } ); .and_then( [&repo] { return repo.attach<employee>("employees"); } );

View File

@ -20,15 +20,15 @@ TEST_CASE("Generate column definitions from object", "[column][definition][gener
auto columns = attribute_definition_generator::generate<matador::test::product>(repo); auto columns = attribute_definition_generator::generate<matador::test::product>(repo);
const std::vector expected_columns = { const std::vector expected_columns = {
attribute_definition{"product_name", basic_type::type_varchar, constraints::PRIMARY_KEY, null_option::NOT_NULL }, attribute_definition{"product_name", basic_type::type_varchar, constraints::PRIMARY_KEY, null_option_type::NOT_NULL },
attribute_definition{"supplier_id", basic_type::type_uint32, constraints::FOREIGN_KEY, null_option::NOT_NULL }, attribute_definition{"supplier_id", basic_type::type_uint32, constraints::FOREIGN_KEY, null_option_type::NOT_NULL },
attribute_definition{"category_id", basic_type::type_uint32, constraints::FOREIGN_KEY, null_option::NOT_NULL }, attribute_definition{"category_id", basic_type::type_uint32, constraints::FOREIGN_KEY, null_option_type::NOT_NULL },
attribute_definition{"quantity_per_unit", basic_type::type_varchar, null_attributes, null_option::NOT_NULL }, attribute_definition{"quantity_per_unit", basic_type::type_varchar, null_attributes, null_option_type::NOT_NULL },
attribute_definition{"unit_price", basic_type::type_uint32, null_attributes, null_option::NOT_NULL }, attribute_definition{"unit_price", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
attribute_definition{"units_in_stock", basic_type::type_uint32, null_attributes, null_option::NOT_NULL }, attribute_definition{"units_in_stock", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
attribute_definition{"units_in_order", basic_type::type_uint32, null_attributes, null_option::NOT_NULL }, attribute_definition{"units_in_order", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
attribute_definition{"reorder_level", basic_type::type_uint32, null_attributes, null_option::NOT_NULL }, attribute_definition{"reorder_level", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL },
attribute_definition{"discontinued", basic_type::type_bool, null_attributes, null_option::NOT_NULL } attribute_definition{"discontinued", basic_type::type_bool, null_attributes, null_option_type::NOT_NULL }
}; };
REQUIRE(!columns.empty()); REQUIRE(!columns.empty());
REQUIRE(columns.size() == expected_columns.size()); REQUIRE(columns.size() == expected_columns.size());
@ -46,9 +46,9 @@ TEST_CASE("Generate columns from object with nullable columns", "[column generat
auto columns = attribute_definition_generator::generate<matador::test::optional>(repo); auto columns = attribute_definition_generator::generate<matador::test::optional>(repo);
const std::vector expected_columns = { const std::vector expected_columns = {
attribute_definition{"id", basic_type::type_uint32, constraints::PRIMARY_KEY, null_option::NOT_NULL }, attribute_definition{"id", basic_type::type_uint32, constraints::PRIMARY_KEY, null_option_type::NOT_NULL },
attribute_definition{"name", basic_type::type_varchar, null_attributes, null_option::NOT_NULL }, attribute_definition{"name", basic_type::type_varchar, null_attributes, null_option_type::NOT_NULL },
attribute_definition{"age", basic_type::type_uint32, null_attributes, null_option::NOT_NULL } attribute_definition{"age", basic_type::type_uint32, null_attributes, null_option_type::NOT_NULL }
}; };
REQUIRE(!columns.empty()); REQUIRE(!columns.empty());
REQUIRE(columns.size() == expected_columns.size()); REQUIRE(columns.size() == expected_columns.size());

View File

@ -48,7 +48,7 @@ TEST_CASE_METHOD(QueryFixture, "Test create table sql statement string", "[query
auto ctx = query::create() auto ctx = query::create()
.table("person", { .table("person", {
make_pk_column<uint32_t>("id"), make_pk_column<uint32_t>("id"),
make_column<std::string>("name", {255, constraints::UNIQUE}, null_option::NOT_NULL), make_column<std::string>("name", {255, constraints::UNIQUE}, null_option_type::NOT_NULL),
make_column<unsigned short>("age"), make_column<unsigned short>("age"),
make_fk_column<uint32_t>("address", "address", "id") make_fk_column<uint32_t>("address", "address", "id")
}).compile(*db); }).compile(*db);

View File

@ -27,7 +27,7 @@ TEST_CASE("Test copy and move column", "[column]") {
2, 2,
std::make_shared<attribute_definition>("author", "books", basic_type::type_uint32, constraints::FOREIGN_KEY), std::make_shared<attribute_definition>("author", "books", basic_type::type_uint32, constraints::FOREIGN_KEY),
{255, constraints::FOREIGN_KEY}, {255, constraints::FOREIGN_KEY},
null_option::NOT_NULL null_option_type::NOT_NULL
); );
REQUIRE(c.name() == "name"); REQUIRE(c.name() == "name");
REQUIRE(c.index() == 2); REQUIRE(c.index() == 2);