Compare commits
No commits in common. "31e9c7e9ac18789ec8a65369976a782fb4a5af90" and "4cda0f26649c3e58cacdfecf7c41f1e3801a2a55" have entirely different histories.
31e9c7e9ac
...
4cda0f2664
|
|
@ -456,77 +456,43 @@ TEST_CASE_METHOD(QueryFixture, "Select statement with many to many relationship"
|
|||
}
|
||||
|
||||
auto result = db
|
||||
.query(schema)
|
||||
.select({"r.id", "r.name", "ri.ingredient_id"})
|
||||
.from({"recipes", "r"})
|
||||
.join_left({"recipe_ingredients", "ri"})
|
||||
.on("r.id"_col == "ri.recipe_id"_col)
|
||||
.fetch_all();
|
||||
.query(schema)
|
||||
.select({"r.id", "r.name", "ri.recipe_id"})
|
||||
.from({"recipes", "r"})
|
||||
.join_left({"recipe_ingredients", "ri"})
|
||||
.on("r.id"_col == "ri.recipe_id"_col)
|
||||
.fetch_all();
|
||||
|
||||
std::vector<std::tuple<unsigned long, std::string, unsigned long>> expected_result_one_join {
|
||||
{7, "Apple Crumble", 1},
|
||||
{7, "Apple Crumble", 4},
|
||||
{7, "Apple Crumble", 5},
|
||||
{8, "Beans Chili", 6},
|
||||
{8, "Beans Chili", 7},
|
||||
{9, "Fruit Salad", 1},
|
||||
{9, "Fruit Salad", 2},
|
||||
{9, "Fruit Salad", 3}
|
||||
};
|
||||
size_t index{0};
|
||||
for (const auto &r: result) {
|
||||
REQUIRE(r.size() == 3);
|
||||
REQUIRE(r.at(0).as<unsigned long>().value() == std::get<0>(expected_result_one_join[index]));
|
||||
REQUIRE(r.at(1).as<std::string>().value() == std::get<1>(expected_result_one_join[index]));
|
||||
REQUIRE(r.at(2).as<unsigned long>().value() == std::get<2>(expected_result_one_join[index]));
|
||||
++index;
|
||||
std::cout << "record r.id " << r.at(0).as<unsigned long>().value() << " r.name " << r.at(1).as<std::string>().value() << " ri.id " << r.at(2).as<unsigned long>().value() << "\n";
|
||||
}
|
||||
|
||||
result = db
|
||||
.query(schema)
|
||||
.select({"r.id", "r.name", "ri.ingredient_id", "i.name"})
|
||||
.select({"r.id", "r.name", "ri.recipe_id", "i.name"})
|
||||
.from({"recipes", "r"})
|
||||
.join_left({"recipe_ingredients", "ri"}).on("r.id"_col == "ri.recipe_id"_col)
|
||||
.join_left({"ingredients", "i"}).on("ri.ingredient_id"_col == "i.id"_col)
|
||||
.fetch_all();
|
||||
|
||||
std::vector<std::tuple<unsigned long, std::string, unsigned long, std::string>> expected_result_two_joins {
|
||||
{7, "Apple Crumble", 1, "Apple"},
|
||||
{7, "Apple Crumble", 4, "Sugar"},
|
||||
{7, "Apple Crumble", 5, "Flour"},
|
||||
{8, "Beans Chili", 6, "Butter"},
|
||||
{8, "Beans Chili", 7, "Beans"},
|
||||
{9, "Fruit Salad", 1, "Apple"},
|
||||
{9, "Fruit Salad", 2, "Strawberry"},
|
||||
{9, "Fruit Salad", 3, "Pineapple"}
|
||||
};
|
||||
index = 0;
|
||||
for (const auto &r: result) {
|
||||
REQUIRE(r.size() == 4);
|
||||
REQUIRE(r.at(0).as<unsigned long>().value() == std::get<0>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(1).as<std::string>().value() == std::get<1>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(2).as<unsigned long>().value() == std::get<2>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(3).as<std::string>().value() == std::get<3>(expected_result_two_joins[index]));
|
||||
++index;
|
||||
std::cout << "record r.id " << r.at(0).as<unsigned long>().value() << " r.name " << r.at(1).as<std::string>().value() << " ri.id " << r.at(2).as<unsigned long>().value() << " i.name " << r.at(3).as<std::string>().value() << "\n";
|
||||
}
|
||||
|
||||
result = db
|
||||
.query(schema)
|
||||
.select({"r.id", "r.name", "ri.ingredient_id", "i.name"})
|
||||
.select({"r.id", "r.name", "ri.recipe_id", "i.name"})
|
||||
.from({"recipes", "r"})
|
||||
.join_left({"recipe_ingredients", "ri"}).on("r.id"_col == "ri.recipe_id"_col)
|
||||
.join_left({"ingredients", "i"}).on("ri.ingredient_id"_col == "i.id"_col)
|
||||
.where("r.id"_col == 8)
|
||||
.fetch_all();
|
||||
|
||||
index = 3;
|
||||
for (const auto &r: result) {
|
||||
REQUIRE(r.size() == 4);
|
||||
REQUIRE(r.at(0).as<unsigned long>().value() == std::get<0>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(1).as<std::string>().value() == std::get<1>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(2).as<unsigned long>().value() == std::get<2>(expected_result_two_joins[index]));
|
||||
REQUIRE(r.at(3).as<std::string>().value() == std::get<3>(expected_result_two_joins[index]));
|
||||
++index;
|
||||
std::cout << "record r.id " << r.at(0).as<unsigned long>().value() << " r.name " << r.at(1).as<std::string>().value() << " ri.id " << r.at(2).as<unsigned long>().value() << " i.name " << r.at(3).as<std::string>().value() << "\n";
|
||||
}
|
||||
|
||||
db.query(schema).drop().table("recipe_ingredients").execute();
|
||||
|
|
|
|||
|
|
@ -23,9 +23,9 @@ struct column
|
|||
column(sql_function_t func, std::string name); // NOLINT(*-explicit-constructor)
|
||||
column(std::string table_name, std::string name, std::string as);
|
||||
column(std::string table_name, const char* name, std::string as);
|
||||
column(struct table &t, const char* name, std::string as);
|
||||
column(table &t, const char* name, std::string as);
|
||||
|
||||
[[nodiscard]] bool equals(const column &x) const;
|
||||
bool equals(const column &x) const;
|
||||
|
||||
column& as(std::string a);
|
||||
|
||||
|
|
|
|||
|
|
@ -53,15 +53,6 @@ public:
|
|||
[[nodiscard]] const std::string& ref_table() const;
|
||||
[[nodiscard]] const std::string& ref_column() const;
|
||||
|
||||
[[nodiscard]] bool is_integer() const;
|
||||
[[nodiscard]] bool is_floating_point() const;
|
||||
[[nodiscard]] bool is_bool() const;
|
||||
[[nodiscard]] bool is_string() const;
|
||||
[[nodiscard]] bool is_varchar() const;
|
||||
[[nodiscard]] bool is_blob() const;
|
||||
[[nodiscard]] bool is_null() const;
|
||||
[[nodiscard]] bool is_unknown() const;
|
||||
|
||||
void type(data_type_t type);
|
||||
|
||||
template< typename Type >
|
||||
|
|
|
|||
|
|
@ -63,46 +63,6 @@ const std::string &column_definition::ref_column() const
|
|||
return ref_column_;
|
||||
}
|
||||
|
||||
bool column_definition::is_integer() const
|
||||
{
|
||||
return type_ >= data_type_t::type_char && type_ <= data_type_t::type_unsigned_long_long;
|
||||
}
|
||||
|
||||
bool column_definition::is_floating_point() const
|
||||
{
|
||||
return type_ == data_type_t::type_float || type_ == data_type_t::type_double;
|
||||
}
|
||||
|
||||
bool column_definition::is_bool() const
|
||||
{
|
||||
return type_ == data_type_t::type_bool;
|
||||
}
|
||||
|
||||
bool column_definition::is_string() const
|
||||
{
|
||||
return type_ == data_type_t::type_text;
|
||||
}
|
||||
|
||||
bool column_definition::is_varchar() const
|
||||
{
|
||||
return type_ == data_type_t::type_varchar;
|
||||
}
|
||||
|
||||
bool column_definition::is_blob() const
|
||||
{
|
||||
return type_ == data_type_t::type_blob;
|
||||
}
|
||||
|
||||
bool column_definition::is_null() const
|
||||
{
|
||||
return type_ == data_type_t::type_null;
|
||||
}
|
||||
|
||||
bool column_definition::is_unknown() const
|
||||
{
|
||||
return type_ == data_type_t::type_unknown;
|
||||
}
|
||||
|
||||
void column_definition::type(data_type_t type)
|
||||
{
|
||||
type_ = type;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ struct author
|
|||
std::string date_of_birth;
|
||||
unsigned short year_of_birth{};
|
||||
bool distinguished{false};
|
||||
std::vector<matador::sql::entity<book>> books;
|
||||
|
||||
template<typename Operator>
|
||||
void process(Operator &op)
|
||||
|
|
@ -27,7 +26,6 @@ struct author
|
|||
field::attribute(op, "date_of_birth", date_of_birth, 31);
|
||||
field::attribute(op, "year_of_birth", year_of_birth);
|
||||
field::attribute(op, "distinguished", distinguished);
|
||||
field::has_many(op, "books", books, "author_id", "id", utils::fetch_type::LAZY);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ struct book
|
|||
namespace field = matador::utils::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::attribute(op, "title", title, 511);
|
||||
field::belongs_to(op, "author_id", book_author, utils::fetch_type::EAGER);
|
||||
field::has_one(op, "author_id", book_author, utils::fetch_type::EAGER);
|
||||
field::attribute(op, "published_in", published_in);
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,19 +11,16 @@
|
|||
|
||||
namespace matador::test {
|
||||
|
||||
struct recipe;
|
||||
struct ingredient
|
||||
{
|
||||
unsigned long id{};
|
||||
std::string name;
|
||||
std::vector<matador::sql::entity<recipe>> recipes;
|
||||
|
||||
template<class Operator>
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::utils::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::attribute(op, "name", name, 255);
|
||||
field::has_many(op, "recipes", recipes, "ingredient_id", "recipe_id", utils::fetch_type::EAGER);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -31,14 +28,12 @@ struct recipe
|
|||
{
|
||||
unsigned long id{};
|
||||
std::string name;
|
||||
std::vector<matador::sql::entity<ingredient>> ingredients;
|
||||
|
||||
template<class Operator>
|
||||
void process(Operator &op) {
|
||||
namespace field = matador::utils::access;
|
||||
field::primary_key(op, "id", id);
|
||||
field::attribute(op, "name", name, 255);
|
||||
field::has_many(op, "ingredients", ingredients, "recipe_id", "ingredient_id", utils::fetch_type::EAGER);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue