object generation progress
This commit is contained in:
parent
422df82b7c
commit
c156ab5e74
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "matador/utils/identifier.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <typeindex>
|
||||
|
||||
|
|
@ -24,8 +25,7 @@ public:
|
|||
|
||||
[[nodiscard]] std::type_index type_index() const;
|
||||
[[nodiscard]] std::string name() const;
|
||||
[[nodiscard]] const std::vector<attribute>& attributes() const;
|
||||
// [[nodiscard]] std::shared_ptr<attribute> reference_column() const;
|
||||
[[nodiscard]] const std::list<attribute>& attributes() const;
|
||||
|
||||
[[nodiscard]] bool has_primary_key() const;
|
||||
[[nodiscard]] const utils::identifier& primary_key() const;
|
||||
|
|
@ -50,8 +50,6 @@ public:
|
|||
[[nodiscard]] bool endpoints_empty() const;
|
||||
|
||||
protected:
|
||||
// basic_object_info(std::shared_ptr<repository_node> node, const std::vector<attribute> &attributes, utils::identifier &&pk, const std::shared_ptr<attribute> &pk_as_fk_column);
|
||||
// basic_object_info(std::shared_ptr<repository_node> node, const std::vector<attribute> &attributes);
|
||||
basic_object_info(std::shared_ptr<repository_node> node, std::unique_ptr<object> &&obj);
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#include "matador/utils/field_attributes.hpp"
|
||||
#include "matador/utils/primary_key_attribute.hpp"
|
||||
|
||||
#include <list>
|
||||
#include <typeindex>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::object {
|
||||
class object;
|
||||
|
|
@ -17,20 +17,20 @@ class repository;
|
|||
|
||||
class constraints_generator final {
|
||||
private:
|
||||
constraints_generator(std::vector<class constraint> &constraints, const repository &repo, object &obj);
|
||||
constraints_generator(std::list<class constraint> &constraints, const repository &repo, object &obj);
|
||||
|
||||
public:
|
||||
constraints_generator() = delete;
|
||||
|
||||
template < typename Type >
|
||||
static std::vector<class constraint> generate(const repository &repo, object &obj) {
|
||||
static std::list<class constraint> generate(const repository &repo, object &obj) {
|
||||
Type t;
|
||||
return generate(t, repo, obj);
|
||||
}
|
||||
|
||||
template < typename Type >
|
||||
static std::vector<class constraint> generate(const Type& t, const repository &repo, object &obj) {
|
||||
std::vector<class constraint> constraints;
|
||||
static std::list<class constraint> generate(const Type& t, const repository &repo, object &obj) {
|
||||
std::list<class constraint> constraints;
|
||||
constraints_generator gen(constraints, repo, obj);
|
||||
access::process(gen, t);
|
||||
return constraints;
|
||||
|
|
@ -66,10 +66,10 @@ private:
|
|||
void create_fk_constraint(const std::type_index& ti, const std::string& name) const;
|
||||
void create_unique_constraint(const std::string& name) const;
|
||||
|
||||
[[nodiscard]] std::vector<attribute>::iterator find_attribute_by_name(const std::string &name) const;
|
||||
[[nodiscard]] std::list<attribute>::iterator find_attribute_by_name(const std::string &name) const;
|
||||
|
||||
private:
|
||||
std::vector<class constraint> &constraints_;
|
||||
std::list<class constraint> &constraints_;
|
||||
const repository &repo_;
|
||||
object &obj_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include "matador/utils/identifier.hpp"
|
||||
|
||||
#include <list>
|
||||
|
||||
namespace matador::object {
|
||||
|
||||
class repository;
|
||||
|
|
@ -16,22 +18,6 @@ class object {
|
|||
public:
|
||||
explicit object(std::string name, std::string alias = "");
|
||||
|
||||
// template<typename Type>
|
||||
// static std::unique_ptr<object> generate(const repository& repo, std::string name, std::string alias = "") {
|
||||
// auto obj = std::make_unique<object>(std::move(name), std::move(alias));
|
||||
// obj->attributes_ = std::move(attribute_generator::generate<Type>(repo, *obj));
|
||||
// obj->constraints_ = std::move(constraints_generator::generate<Type>(repo, *obj));
|
||||
// return obj;
|
||||
// }
|
||||
//
|
||||
// template<typename Type>
|
||||
// static std::unique_ptr<object> generate(const std::unique_ptr<Type>& ptr, const repository& repo, std::string name, std::string alias = "") {
|
||||
// auto obj = std::make_unique<object>(std::move(name), std::move(alias));
|
||||
// obj->attributes_ = std::move(attribute_generator::generate(*ptr, repo, *obj));
|
||||
// obj->constraints_ = std::move(constraints_generator::generate(*ptr, repo, *obj));
|
||||
// return obj;
|
||||
// }
|
||||
|
||||
static const attribute& create_attribute(std::string name, object& obj);
|
||||
|
||||
void add_attribute(attribute attr);
|
||||
|
|
@ -48,11 +34,11 @@ public:
|
|||
|
||||
[[nodiscard]] bool has_attributes() const;
|
||||
[[nodiscard]] size_t attribute_count() const;
|
||||
[[nodiscard]] const std::vector<attribute>& attributes() const;
|
||||
[[nodiscard]] const std::list<attribute>& attributes() const;
|
||||
|
||||
[[nodiscard]] bool has_constraints() const;
|
||||
[[nodiscard]] size_t constraint_count() const;
|
||||
[[nodiscard]] const std::vector<class constraint>& constraints() const;
|
||||
[[nodiscard]] const std::list<class constraint>& constraints() const;
|
||||
|
||||
private:
|
||||
friend class constraints_generator;
|
||||
|
|
@ -64,8 +50,8 @@ private:
|
|||
|
||||
attribute* pk_attribute_{nullptr};
|
||||
utils::identifier pk_identifier_;
|
||||
std::vector<attribute> attributes_;
|
||||
std::vector<class constraint> constraints_;
|
||||
std::list<attribute> attributes_;
|
||||
std::list<class constraint> constraints_;
|
||||
};
|
||||
}
|
||||
#endif //MATADOR_OBJECT_HPP
|
||||
|
|
@ -86,12 +86,10 @@ public:
|
|||
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
|
||||
|
||||
template <class Pointer>
|
||||
void on_foreign_key(const char *id, Pointer &x) {
|
||||
void on_foreign_key(const char *id, Pointer &/*x*/) {
|
||||
const auto type = pk_type_determinator::determine<typename Pointer::value_type>();
|
||||
auto &ref = object_->attributes_.emplace_back(id, type, utils::constraints::ForeignKey, null_option_type::NOT_NULL);
|
||||
ref.owner_ = object_.get();
|
||||
|
||||
create_fk_constraint(typeid(typename Pointer::value_type), id);
|
||||
}
|
||||
template<class ContainerType>
|
||||
static void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
|
||||
|
|
@ -112,7 +110,7 @@ private:
|
|||
void create_fk_constraint(const std::type_index& ti, const std::string& name) const;
|
||||
void create_unique_constraint(const std::string& name) const;
|
||||
|
||||
[[nodiscard]] std::vector<attribute>::iterator find_attribute_by_name(const std::string &name) const;
|
||||
[[nodiscard]] std::list<attribute>::iterator find_attribute_by_name(const std::string &name) const;
|
||||
|
||||
void prepare_primary_key(attribute &ref, utils::identifier &&pk) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -114,27 +114,28 @@ public:
|
|||
template<class ContainerType>
|
||||
void on_has_many(const char * /*id*/, ContainerType &, const char *join_column, const utils::foreign_attributes &attr) {
|
||||
if (attr.fetch() == utils::fetch_type::EAGER) {
|
||||
const auto info = schema_.info<typename ContainerType::value_type::value_type>();
|
||||
if (!info) {
|
||||
const auto result = schema_.basic_info(typeid(typename ContainerType::value_type::value_type));
|
||||
if (!result) {
|
||||
throw query_builder_exception{query_build_error::UnknownType};
|
||||
}
|
||||
|
||||
auto next = processed_tables_.find(info->get().name());
|
||||
const auto &info = result.value().get();
|
||||
auto next = processed_tables_.find(info.name());
|
||||
if (next != processed_tables_.end()) {
|
||||
return;
|
||||
}
|
||||
table_info_stack_.push({info.value(), std::make_shared<query::table>(info->get().name(), build_alias('t', ++table_index))});
|
||||
next = processed_tables_.insert({info->get().name(), table_info_stack_.top().table}).first;
|
||||
table_info_stack_.push({*result, std::make_shared<query::table>(info.name(), build_alias('t', ++table_index))});
|
||||
next = processed_tables_.insert({info.name(), table_info_stack_.top().table}).first;
|
||||
typename ContainerType::value_type::value_type obj;
|
||||
access::process(*this , obj);
|
||||
table_info_stack_.pop();
|
||||
|
||||
if (!info->get().has_primary_key()) {
|
||||
if (!info.has_primary_key()) {
|
||||
throw query_builder_exception{query_build_error::MissingPrimaryKey};
|
||||
}
|
||||
|
||||
append_join(
|
||||
query::column{table_info_stack_.top().table, table_info_stack_.top().info.get().reference_column()->name()},
|
||||
query::column{table_info_stack_.top().table, table_info_stack_.top().info.get().primary_key_attribute()->name()},
|
||||
query::column{next->second, join_column}
|
||||
);
|
||||
}
|
||||
|
|
@ -145,12 +146,13 @@ public:
|
|||
if (attr.fetch() != utils::fetch_type::EAGER) {
|
||||
return;
|
||||
}
|
||||
const auto info = schema_.info<typename ContainerType::value_type::value_type>();
|
||||
if (!info) {
|
||||
const auto result = schema_.basic_info(typeid(typename ContainerType::value_type::value_type));
|
||||
if (!result) {
|
||||
throw query_builder_exception{query_build_error::UnknownType};
|
||||
}
|
||||
|
||||
auto next = processed_tables_.find(info->get().name());
|
||||
const auto &info = result.value().get();
|
||||
auto next = processed_tables_.find(info.name());
|
||||
if (next != processed_tables_.end()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -159,23 +161,23 @@ public:
|
|||
relation = processed_tables_.insert({id, std::make_shared<query::table>(id, build_alias('t', ++table_index))}).first;
|
||||
}
|
||||
|
||||
table_info_stack_.push({info.value(), std::make_shared<query::table>(info->get().name(), build_alias('t', ++table_index))});
|
||||
next = processed_tables_.insert({info->get().name(), table_info_stack_.top().table}).first;
|
||||
table_info_stack_.push({*result, std::make_shared<query::table>(info.name(), build_alias('t', ++table_index))});
|
||||
next = processed_tables_.insert({info.name(), table_info_stack_.top().table}).first;
|
||||
typename ContainerType::value_type::value_type obj;
|
||||
access::process(*this , obj);
|
||||
table_info_stack_.pop();
|
||||
|
||||
if (!info->get().has_primary_key()) {
|
||||
if (!info.has_primary_key()) {
|
||||
throw query_builder_exception{query_build_error::MissingPrimaryKey};
|
||||
}
|
||||
|
||||
append_join(
|
||||
query::column{table_info_stack_.top().table, table_info_stack_.top().info.get().reference_column()->name()},
|
||||
query::column{table_info_stack_.top().table, table_info_stack_.top().info.get().primary_key_attribute()->name()},
|
||||
query::column{relation->second, join_column}
|
||||
);
|
||||
append_join(
|
||||
query::column{relation->second, inverse_join_column},
|
||||
query::column{next->second, info->get().reference_column()->name()}
|
||||
query::column{next->second, info.primary_key_attribute()->name()}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -184,12 +186,13 @@ public:
|
|||
if (attr.fetch() != utils::fetch_type::EAGER) {
|
||||
return;
|
||||
}
|
||||
const auto info = schema_.info<typename ContainerType::value_type::value_type>();
|
||||
if (!info) {
|
||||
const auto result = schema_.basic_info(typeid(typename ContainerType::value_type::value_type));
|
||||
if (!result) {
|
||||
throw query_builder_exception{query_build_error::UnknownType};
|
||||
}
|
||||
|
||||
auto next = processed_tables_.find(info->get().name());
|
||||
const auto &info = result.value().get();
|
||||
auto next = processed_tables_.find(info.name());
|
||||
if (next != processed_tables_.end()) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -198,25 +201,25 @@ public:
|
|||
if (relation == processed_tables_.end()) {
|
||||
relation = processed_tables_.insert({id, std::make_shared<query::table>(id, build_alias('t', ++table_index))}).first;
|
||||
}
|
||||
table_info_stack_.push({info.value(), std::make_shared<query::table>(info->get().name(), build_alias('t', ++table_index))});
|
||||
next = processed_tables_.insert({info->get().name(), table_info_stack_.top().table}).first;
|
||||
table_info_stack_.push({*result, std::make_shared<query::table>(info.name(), build_alias('t', ++table_index))});
|
||||
next = processed_tables_.insert({info.name(), table_info_stack_.top().table}).first;
|
||||
typename ContainerType::value_type::value_type obj;
|
||||
access::process(*this , obj);
|
||||
table_info_stack_.pop();
|
||||
|
||||
if (!info->get().has_primary_key()) {
|
||||
if (!info.has_primary_key()) {
|
||||
throw query_builder_exception{query_build_error::MissingPrimaryKey};
|
||||
}
|
||||
|
||||
const auto join_columns = join_columns_collector_.collect<typename ContainerType::value_type::value_type>();
|
||||
|
||||
append_join(
|
||||
query::column{table_info_stack_.top().table, table_info_stack_.top().info.get().reference_column()->name()},
|
||||
query::column{table_info_stack_.top().table, table_info_stack_.top().info.get().primary_key_attribute()->name()},
|
||||
query::column{relation->second, join_columns.inverse_join_column}
|
||||
);
|
||||
append_join(
|
||||
query::column{relation->second, join_columns.join_column},
|
||||
query::column{next->second, info->get().reference_column()->name()}
|
||||
query::column{next->second, info.primary_key_attribute()->name()}
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,14 +32,10 @@ std::string basic_object_info::name() const {
|
|||
return node_->name();
|
||||
}
|
||||
|
||||
const std::vector<attribute>& basic_object_info::attributes() const {
|
||||
const std::list<attribute>& basic_object_info::attributes() const {
|
||||
return object_->attributes();
|
||||
}
|
||||
|
||||
// std::shared_ptr<attribute> basic_object_info::reference_column() const {
|
||||
// return pk_as_fk_column_;
|
||||
// }
|
||||
|
||||
bool basic_object_info::has_primary_key() const {
|
||||
return object_->has_primary_key();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
#include <algorithm>
|
||||
|
||||
namespace matador::object {
|
||||
constraints_generator::constraints_generator(std::vector<class constraint> &constraints, const repository& repo, object &obj)
|
||||
constraints_generator::constraints_generator(std::list<class constraint> &constraints, const repository& repo, object &obj)
|
||||
: constraints_(constraints)
|
||||
, repo_(repo)
|
||||
, obj_(obj) {}
|
||||
|
|
@ -46,7 +46,7 @@ void constraints_generator::create_unique_constraint(const std::string& name) co
|
|||
pk_constraint.owner_ = &obj_;
|
||||
}
|
||||
|
||||
std::vector<attribute>::iterator constraints_generator::find_attribute_by_name(const std::string& name) const {
|
||||
std::list<attribute>::iterator constraints_generator::find_attribute_by_name(const std::string& name) const {
|
||||
return std::find_if(std::begin(obj_.attributes_), std::end(obj_.attributes_), [&name](const attribute& elem) {
|
||||
return elem.name() == name;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ size_t object::attribute_count() const {
|
|||
return attributes_.size();
|
||||
}
|
||||
|
||||
const std::vector<attribute>& object::attributes() const {
|
||||
const std::list<attribute>& object::attributes() const {
|
||||
return attributes_;
|
||||
}
|
||||
|
||||
|
|
@ -65,7 +65,7 @@ size_t object::constraint_count() const {
|
|||
return constraints_.size();
|
||||
}
|
||||
|
||||
const std::vector<class constraint>& object::constraints() const {
|
||||
const std::list<class constraint>& object::constraints() const {
|
||||
return constraints_;
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
#include "matador/object/repository.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace matador::object {
|
||||
object_generator::object_generator( const repository& repo, std::unique_ptr<object>&& object )
|
||||
: repo_(repo)
|
||||
|
|
@ -47,7 +49,7 @@ void object_generator::create_unique_constraint(const std::string& name) const {
|
|||
pk_constraint.owner_ = object_.get();
|
||||
}
|
||||
|
||||
std::vector<attribute>::iterator object_generator::find_attribute_by_name(const std::string& name) const {
|
||||
std::list<attribute>::iterator object_generator::find_attribute_by_name(const std::string& name) const {
|
||||
return std::find_if(std::begin(object_->attributes_), std::end(object_->attributes_), [&name](const attribute& elem) {
|
||||
return elem.name() == name;
|
||||
});
|
||||
|
|
|
|||
|
|
@ -18,11 +18,13 @@ struct student final : person {};
|
|||
struct teacher final : person {};
|
||||
|
||||
struct names {
|
||||
unsigned int id{};
|
||||
std::vector<std::string> names_list;
|
||||
|
||||
template<typename Operator>
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::has_many(op, "name_list", names_list, "names_id", utils::fetch_type::EAGER);
|
||||
}
|
||||
};
|
||||
|
|
@ -75,10 +77,10 @@ TEST_CASE("Test automatic creating of a relation table with foreign key", "[sche
|
|||
}
|
||||
|
||||
TEST_CASE("Test automatic creating of a relation table with values", "[schema][relation_table][values]") {
|
||||
object::repository tree;
|
||||
object::repository repo;
|
||||
|
||||
REQUIRE( tree.empty() );
|
||||
REQUIRE( repo.empty() );
|
||||
|
||||
auto res = tree.attach<names>("names");
|
||||
auto res = repo.attach<names>("names");
|
||||
REQUIRE( res.is_ok() );
|
||||
}
|
||||
Loading…
Reference in New Issue