introduced a processed table set

This commit is contained in:
Sascha Kühl 2025-02-07 11:49:32 +01:00
parent 23646ab4ee
commit 9e60b5e485
1 changed files with 26 additions and 13 deletions

View File

@ -2,11 +2,9 @@
#define QUERY_ENTITY_QUERY_BUILDER_HPP #define QUERY_ENTITY_QUERY_BUILDER_HPP
#include "matador/query/condition.hpp" #include "matador/query/condition.hpp"
#include "matador/query/query.hpp"
#include "matador/query/query_intermediates.hpp" #include "matador/query/query_intermediates.hpp"
#include "matador/sql/connection.hpp" #include "matador/sql/connection.hpp"
#include "matador/sql/query_context.hpp"
#include "matador/object/schema.hpp" #include "matador/object/schema.hpp"
@ -14,6 +12,7 @@
#include "matador/utils/value.hpp" #include "matador/utils/value.hpp"
#include <stack> #include <stack>
#include <unordered_set>
namespace matador::orm { namespace matador::orm {
@ -101,6 +100,7 @@ public:
} }
pk_ = pk; pk_ = pk;
table_info_stack_.push(info.value()); table_info_stack_.push(info.value());
processed_tables_.insert(info->get().name());
entity_query_data_ = { info.value().get().name() }; entity_query_data_ = { info.value().get().name() };
try { try {
access::process(*this, info.value().get().prototype()); access::process(*this, info.value().get().prototype());
@ -175,24 +175,30 @@ public:
} }
template<class ContainerType> template<class ContainerType>
void on_has_many(ContainerType &, const char *join_column, const utils::foreign_attributes &attr) void on_has_many(const char * id, ContainerType &, const char *join_column, const utils::foreign_attributes &attr) {
{
if (attr.fetch() == utils::fetch_type::EAGER) { if (attr.fetch() == utils::fetch_type::EAGER) {
const auto info = schema_.info<typename ContainerType::value_type::value_type>(); const auto info = schema_.info<typename ContainerType::value_type::value_type>();
if (!info) { if (!info) {
throw query_builder_exception{query_build_error::UnknownType}; throw query_builder_exception{query_build_error::UnknownType};
} }
auto curr = table_info_stack_.top().get().name();
auto next = info.value().get().name();
if (processed_tables_.count(next) > 0) {
return;
}
table_info_stack_.push(info.value()); table_info_stack_.push(info.value());
processed_tables_.insert(next);
typename ContainerType::value_type::value_type obj; typename ContainerType::value_type::value_type obj;
matador::access::process(*this , obj); access::process(*this , obj);
table_info_stack_.pop(); table_info_stack_.pop();
auto pk = info->prototype.primary_key(); auto pk = info->get().definition().primary_key();
if (!pk) { if (!pk) {
throw query_builder_exception{query_build_error::MissingPrimaryKey}; throw query_builder_exception{query_build_error::MissingPrimaryKey};
} }
append_join({table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, {info->name, join_column}); append_join(sql::column{table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, sql::column{info->get().name(), join_column});
} }
} }
@ -211,13 +217,13 @@ public:
matador::access::process(*this , obj); matador::access::process(*this , obj);
table_info_stack_.pop(); table_info_stack_.pop();
auto pk = info->prototype.primary_key(); auto pk = info->get().definition().primary_key();
if (!pk) { if (!pk) {
throw query_builder_exception{query_build_error::MissingPrimaryKey}; throw query_builder_exception{query_build_error::MissingPrimaryKey};
} }
append_join(sql::column{table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, {id, join_column}); append_join(sql::column{table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, {id, join_column});
append_join({id, inverse_join_column}, {info->name, pk->name()}); append_join(sql::column{id, inverse_join_column}, sql::column{info->get().name(), pk->name()});
} }
template<class ContainerType> template<class ContainerType>
@ -235,15 +241,15 @@ public:
matador::access::process(*this , obj); matador::access::process(*this , obj);
table_info_stack_.pop(); table_info_stack_.pop();
auto pk = info->prototype.primary_key(); auto pk = info->get().definition().primary_key();
if (!pk) { if (!pk) {
throw query_builder_exception{query_build_error::MissingPrimaryKey}; throw query_builder_exception{query_build_error::MissingPrimaryKey};
} }
const auto join_columns = join_column_collector_.collect<typename ContainerType::value_type::value_type>(); const auto join_columns = join_column_collector_.collect<typename ContainerType::value_type::value_type>();
append_join({table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, {id, join_columns.inverse_join_column}); append_join(sql::column{table_info_stack_.top().get().name(), table_info_stack_.top().get().definition().primary_key()->name()}, sql::column{id, join_columns.inverse_join_column});
append_join({id, join_columns.join_column}, {info->name, pk->name()}); append_join(sql::column{id, join_columns.join_column}, sql::column{info->get().name(), pk->name()});
} }
private: private:
@ -256,6 +262,7 @@ private:
private: private:
utils::value pk_; utils::value pk_;
std::stack<std::reference_wrapper<const object::basic_object_info>> table_info_stack_; std::stack<std::reference_wrapper<const object::basic_object_info>> table_info_stack_;
std::unordered_set<std::string> processed_tables_;
const object::schema &schema_; const object::schema &schema_;
entity_query_data entity_query_data_; entity_query_data entity_query_data_;
int column_index{0}; int column_index{0};
@ -270,9 +277,15 @@ void session_query_builder::on_foreign_object(const char *id, Pointer &, const u
if (!info) { if (!info) {
throw query_builder_exception{query_build_error::UnknownType}; throw query_builder_exception{query_build_error::UnknownType};
} }
auto curr = table_info_stack_.top().get().name();
auto next = info.value().get().name();
if (processed_tables_.count(next) > 0) {
return;
}
processed_tables_.insert(next);
table_info_stack_.push(info.value()); table_info_stack_.push(info.value());
typename Pointer::value_type obj; typename Pointer::value_type obj;
matador::access::process(*this, obj); access::process(*this, obj);
table_info_stack_.pop(); table_info_stack_.pop();
auto pk = info->get().definition().primary_key(); auto pk = info->get().definition().primary_key();