fixed object generation on nested objects

This commit is contained in:
Sascha Kühl
2025-12-11 15:41:45 +01:00
parent 571cfd52ae
commit 79c46bbd38
8 changed files with 97 additions and 34 deletions
+48 -4
View File
@@ -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