diff --git a/include/matador/sql/column_generator.hpp b/include/matador/sql/column_generator.hpp index 36f9e4f..f844660 100644 --- a/include/matador/sql/column_generator.hpp +++ b/include/matador/sql/column_generator.hpp @@ -27,7 +27,7 @@ public: ~column_generator() = default; template < class Type > - static std::vector generate(const object::schema &scm, bool force_lazy = false) + static std::vector generate(const object::schema &scm, const bool force_lazy = false) { const auto info = scm.info(); if (!info) { @@ -36,7 +36,7 @@ public: std::vector columns; column_generator gen(columns, scm, info.value().get().name(), force_lazy); Type obj; - matador::access::process(gen, obj); + access::process(gen, obj); return std::move(columns); } @@ -61,10 +61,14 @@ public: if (!info) { return; } - table_name_stack_.push(info.value().get().name()); - typename Pointer::value_type obj; - matador::access::process(*this, obj); - table_name_stack_.pop(); + if (seen_tables.count(info->get().name()) == 0) { + auto it = seen_tables.insert(info->get().name()).first; + table_name_stack_.push(info->get().name()); + typename Pointer::value_type obj; + access::process(*this, obj); + table_name_stack_.pop(); + seen_tables.erase(it); + } } } template @@ -77,10 +81,14 @@ public: if (!info) { return; } - table_name_stack_.push(info.value().get().name()); - typename Pointer::value_type obj; - matador::access::process(*this, obj); - table_name_stack_.pop(); + if (seen_tables.count(info->get().name()) == 0) { + auto it = seen_tables.insert(info->get().name()).first; + table_name_stack_.push(info.value().get().name()); + typename Pointer::value_type obj; + access::process(*this, obj); + table_name_stack_.pop(); + seen_tables.erase(it); + } } } template @@ -94,21 +102,21 @@ public: return; } - table_name_stack_.push(info.value().get().name()); - typename ContainerType::value_type::value_type obj; - matador::access::process(*this, obj); - table_name_stack_.pop(); + if (seen_tables.count(info->get().name()) == 0) { + auto it = seen_tables.insert(info->get().name()).first; + table_name_stack_.push(info.value().get().name()); + typename ContainerType::value_type::value_type obj; + access::process(*this, obj); + table_name_stack_.pop(); + seen_tables.erase(it); + } } template - void on_has_many_to_many(const char *id, ContainerType &c, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &attr) - { - } + static void on_has_many_to_many(const char *id, ContainerType &c, const char *join_column, const char *inverse_join_column, const utils::foreign_attributes &attr) {} template - void on_has_many_to_many(const char *id, ContainerType &c, const utils::foreign_attributes &attr) - { - } + static void on_has_many_to_many(const char *id, ContainerType &c, const utils::foreign_attributes &attr) {} private: void push(const std::string &column_name); @@ -116,6 +124,7 @@ private: private: std::stack table_name_stack_; std::vector &column_infos_; + std::unordered_set seen_tables; const object::schema &table_schema_; int column_index{0}; bool force_lazy_{false}; diff --git a/source/orm/sql/column_generator.cpp b/source/orm/sql/column_generator.cpp index 8abdb82..03d6468 100644 --- a/source/orm/sql/column_generator.cpp +++ b/source/orm/sql/column_generator.cpp @@ -13,6 +13,7 @@ column_generator::column_generator(std::vector &column_infos, , force_lazy_(force_lazy) { table_name_stack_.push(table_name); + seen_tables.insert(table_name); } void column_generator::on_primary_key(const char *id, std::string &, size_t) diff --git a/test/orm/sql/ColumnTest.cpp b/test/orm/sql/ColumnTest.cpp index 20b69eb..35fd492 100644 --- a/test/orm/sql/ColumnTest.cpp +++ b/test/orm/sql/ColumnTest.cpp @@ -11,8 +11,7 @@ TEST_CASE("Test create empty column", "[column]") { REQUIRE(c.name() == "name"); REQUIRE(c.index() == -1); REQUIRE(c.type() == basic_type::type_null); - REQUIRE(c.reference_column()->table_name().empty()); - REQUIRE(c.reference_column()->name().empty()); + REQUIRE(!c.reference_column()); c.set(std::string{"george"}, 255); REQUIRE(c.type() == basic_type::type_varchar); @@ -26,38 +25,47 @@ TEST_CASE("Test create empty column", "[column]") { } TEST_CASE("Test copy and move column", "[column]") { - attribute_definition c("name"); + attribute_definition c( + "name", + basic_type::type_varchar, + 2, + std::make_shared("author", "books", basic_type::type_uint32, constraints::FOREIGN_KEY), + constraints::FOREIGN_KEY, + null_option::NOT_NULL + ); c.set(std::string{"george"}, 255); REQUIRE(c.name() == "name"); - REQUIRE(c.index() == -1); - REQUIRE(c.reference_column()->table_name().empty()); - REQUIRE(c.reference_column()->name().empty()); + REQUIRE(c.index() == 2); + REQUIRE(c.reference_column()); + REQUIRE(c.reference_column()->name() == "author"); + REQUIRE(c.reference_column()->table_name() == "books"); REQUIRE(c.type() == basic_type::type_varchar); REQUIRE(c.as() == "george"); REQUIRE(c.attributes().size() == 255); auto c2 = c; REQUIRE(c2.name() == "name"); - REQUIRE(c2.index() == -1); - REQUIRE(c2.reference_column()->table_name().empty()); - REQUIRE(c2.reference_column()->name().empty()); + REQUIRE(c2.index() == 2); + REQUIRE(c2.reference_column()); + REQUIRE(c2.reference_column()->name() == "author"); + REQUIRE(c2.reference_column()->table_name() == "books"); REQUIRE(c2.type() == basic_type::type_varchar); REQUIRE(c2.as() == "george"); REQUIRE(c2.attributes().size() == 255); auto c3 = std::move(c2); REQUIRE(c3.name() == "name"); - REQUIRE(c3.index() == -1); - REQUIRE(c3.reference_column()->table_name().empty()); - REQUIRE(c3.reference_column()->name().empty()); + REQUIRE(c3.index() == 2); + REQUIRE(c3.reference_column()); + REQUIRE(c3.reference_column()->name() == "author"); + REQUIRE(c3.reference_column()->table_name() == "books"); REQUIRE(c3.type() == basic_type::type_varchar); REQUIRE(c3.as() == "george"); REQUIRE(c3.attributes().size() == 255); REQUIRE(c2.name().empty()); - REQUIRE(c2.index() == -1); - REQUIRE(c2.reference_column()->table_name().empty()); - REQUIRE(c2.reference_column()->name().empty()); + REQUIRE(c2.index() == 2); + REQUIRE(!c2.reference_column()); REQUIRE(c2.type() == basic_type::type_null); // REQUIRE(!c2.as().has_value()); REQUIRE(c2.attributes().size() == 255);