fixed object generation on nested objects
This commit is contained in:
@@ -29,8 +29,7 @@ private:
|
||||
public:
|
||||
template<class Type>
|
||||
static void complete(const std::shared_ptr<repository_node> &node) {
|
||||
internal::shadow_repository shadow(node->repo_);
|
||||
foreign_node_completer<Type> completer(shadow);
|
||||
foreign_node_completer<Type> completer(internal::shadow_repository(node->repo_));
|
||||
|
||||
completer.complete_node(node);
|
||||
}
|
||||
@@ -83,7 +82,7 @@ private:
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void attach_node(const std::string &name = "") {
|
||||
void attach_node(const std::string &name) {
|
||||
if (repo_.contains(typeid(Type))) {
|
||||
return;
|
||||
}
|
||||
@@ -93,6 +92,18 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void attach_node() {
|
||||
if (repo_.contains(typeid(Type))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto node = repository_node::make_node<Type>(repo_.repo(), "");
|
||||
if (auto result = repo_.attach_node(node)) {
|
||||
complete<Type>(result.value());
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void attach_relation_node(const std::string &name, const std::string &join_column, const std::string &inverse_join_column) {
|
||||
using relation_value_type = many_to_many_relation<Type, NodeType>;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef SHADOW_SCHEMA_HPP
|
||||
#define SHADOW_SCHEMA_HPP
|
||||
|
||||
#include "matador/object/basic_object_info.hpp"
|
||||
|
||||
#include "matador/utils/result.hpp"
|
||||
#include "matador/utils/error.hpp"
|
||||
|
||||
@@ -10,6 +12,7 @@
|
||||
namespace matador::object {
|
||||
class repository;
|
||||
class repository_node;
|
||||
class object;
|
||||
}
|
||||
|
||||
namespace matador::object::internal {
|
||||
@@ -22,6 +25,7 @@ public:
|
||||
|
||||
[[nodiscard]] repository& repo() const;
|
||||
[[nodiscard]] bool contains(const std::type_index& ti) const;
|
||||
[[nodiscard]] utils::result<basic_object_info_ref, utils::error> basic_info(const std::type_index& ti) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> find_node(const std::type_index &type_index) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> find_node(const std::string &name) const;
|
||||
[[nodiscard]] utils::result<node_ptr, utils::error> attach_node(const std::shared_ptr<repository_node> &node) const;
|
||||
@@ -31,6 +35,11 @@ public:
|
||||
void expect_relation_node(const std::string &name, const std::type_index &ti) const;
|
||||
void remove_expected_relation_node(const std::string &name) const;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<object> provide_object_in_advance(const std::type_index &ti, const std::shared_ptr<object>& obj) const;
|
||||
[[nodiscard]] bool has_object_for_type(const std::type_index &ti) const;
|
||||
[[nodiscard]] std::shared_ptr<object> object_for_type(const std::type_index &ti) const;
|
||||
void remove_object_for_type(const std::type_index &ti) const;
|
||||
|
||||
private:
|
||||
repository& repo_;
|
||||
};
|
||||
|
||||
@@ -23,6 +23,7 @@ public:
|
||||
[[nodiscard]] const utils::identifier& primary_key() const;
|
||||
[[nodiscard]] bool has_primary_key() const;
|
||||
|
||||
[[nodiscard]] bool empty() const;
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
|
||||
void update_name(const std::string& name);
|
||||
@@ -33,7 +34,7 @@ public:
|
||||
|
||||
[[nodiscard]] bool has_constraints() const;
|
||||
[[nodiscard]] size_t constraint_count() const;
|
||||
[[nodiscard]] const std::list<class restriction>& constraints() const;
|
||||
[[nodiscard]] const std::list<restriction>& constraints() const;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, const object& obj);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef MATADOR_OBJECT_GENERATOR_HPP
|
||||
#define MATADOR_OBJECT_GENERATOR_HPP
|
||||
|
||||
#include "matador/object/internal/shadow_repository.hpp"
|
||||
#include "matador/object/object.hpp"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
@@ -60,7 +61,16 @@ public:
|
||||
|
||||
template < class Type >
|
||||
static std::shared_ptr<object> generate(std::unique_ptr<Type>&& t, repository &repo, const std::string &name) {
|
||||
auto obj = acquire_object(repo, typeid(Type), name);
|
||||
const internal::shadow_repository shadow_repo(repo);
|
||||
const std::type_index ti(typeid(Type));
|
||||
if (shadow_repo.has_object_for_type(ti)) {
|
||||
auto obj = shadow_repo.object_for_type(ti);
|
||||
shadow_repo.remove_object_for_type(ti);
|
||||
obj->update_name(name);
|
||||
return obj;
|
||||
}
|
||||
|
||||
auto obj = shadow_repo.provide_object_in_advance(ti, std::make_shared<object>(name));
|
||||
object_generator gen(repo, obj);
|
||||
access::process(gen, *t);
|
||||
return obj;
|
||||
@@ -79,7 +89,7 @@ public:
|
||||
template<class Pointer>
|
||||
void on_belongs_to(const char *id, Pointer &x, const utils::foreign_attributes &/*attr*/) {
|
||||
on_foreign_key(id, x);
|
||||
create_fk_constraint( typeid(typename Pointer::value_type), id);
|
||||
create_fk_constraint<typename Pointer::value_type>(id);
|
||||
}
|
||||
template<class Pointer>
|
||||
static void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
|
||||
@@ -106,14 +116,16 @@ private:
|
||||
}
|
||||
|
||||
void create_pk_constraint(const std::string& name) const;
|
||||
void create_fk_constraint(const std::type_index& ti, const std::string& name) const;
|
||||
template<typename Type>
|
||||
void create_fk_constraint(const std::string& name) const;
|
||||
void create_unique_constraint(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;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<class object> fk_object(const std::type_index& ti) const;
|
||||
template<typename Type>
|
||||
[[nodiscard]] std::shared_ptr<object> fk_object() const;
|
||||
|
||||
static std::shared_ptr<object> acquire_object(repository &repo, const std::type_index &ti, const std::string& name);
|
||||
private:
|
||||
@@ -138,5 +150,37 @@ void object_generator::on_attribute(const char *id, std::optional<Type> & /*x*/,
|
||||
std::ignore = emplace_attribute<Type>(id, attr, null_option_type::Nullable);
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
void object_generator::create_fk_constraint(const std::string& name) const {
|
||||
const auto pk_attr = find_attribute_by_name(name);
|
||||
if (pk_attr == std::end(object_->attributes_)) {
|
||||
return;
|
||||
}
|
||||
const auto obj = fk_object<Type>();
|
||||
restriction pk_constraint(*pk_attr);
|
||||
pk_constraint.options_ |= utils::constraints::ForeignKey;
|
||||
pk_constraint.owner_ = object_;
|
||||
pk_constraint.reference_ = obj;
|
||||
object_->constraints_.emplace_back(std::move(pk_constraint));
|
||||
}
|
||||
|
||||
template<typename Type>
|
||||
std::shared_ptr<object> object_generator::fk_object() const {
|
||||
const auto ti = std::type_index(typeid(Type));
|
||||
const internal::shadow_repository shadow_repo(repo_);
|
||||
if (const auto result = shadow_repo.basic_info(ti)) {
|
||||
return result->get().object();
|
||||
}
|
||||
|
||||
if (shadow_repo.has_object_for_type(ti)) {
|
||||
return shadow_repo.object_for_type(ti);
|
||||
}
|
||||
const auto obj = shadow_repo.provide_object_in_advance(ti, std::make_shared<object>(""));
|
||||
object_generator gen(repo_, obj);
|
||||
Type t;
|
||||
access::process(gen, t);
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
#endif //MATADOR_OBJECT_GENERATOR_HPP
|
||||
Reference in New Issue
Block a user