diff --git a/backends/tests/QueryTest.cpp b/backends/tests/QueryTest.cpp index b4fdf5d..3ac9cbd 100644 --- a/backends/tests/QueryTest.cpp +++ b/backends/tests/QueryTest.cpp @@ -232,8 +232,8 @@ TEST_CASE_METHOD(QueryFixture, " Select statement with foreign key and join_left REQUIRE(f.airplane->id == 1); auto result = db.query().select({"f.id", "ap.brand", "ap.model", "f.pilot_name"}) - .from("flight", "f") - .join_left("airplane", "ap") + .from({"flight", "f"}) + .join_left({"airplane", "ap"}) .on("f.airplane_id"_col == "ap.id"_col) .order_by("f.id").asc() .fetch_all(); diff --git a/backends/tests/StatementTest.cpp b/backends/tests/StatementTest.cpp index 9f61c28..aeef342 100644 --- a/backends/tests/StatementTest.cpp +++ b/backends/tests/StatementTest.cpp @@ -46,6 +46,7 @@ private: TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement]") { + table ap{"airplane"}; SECTION("Insert with prepared statement and placeholder") { auto stmt = db.query().insert() .into("airplane") @@ -57,7 +58,7 @@ TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement stmt.reset(); } - auto result = db.query().select().from("airplane").fetch_all(); + auto result = db.query().select().from(ap).fetch_all(); size_t index{0}; for (const auto &i: result) { @@ -73,7 +74,7 @@ TEST_CASE_METHOD(StatementTestFixture, " Create prepared statement", "[statement REQUIRE(res == 1); } - auto stmt = db.query().select().from("airplane").where("brand"_col == _).prepare(); + auto stmt = db.query().select().from(ap).where("brand"_col == _).prepare(); stmt.bind(0, "Airbus"); diff --git a/demo/main.cpp b/demo/main.cpp index cb93c28..4ee6a42 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -49,8 +49,8 @@ struct book } }; -QUERY_HELPER(author, id, first_name, last_name, date_of_birth, year_of_birth, distinguished) -QUERY_HELPER(book, id, book_author, title, published_in) +QUERY_HELPER(authors, id, first_name, last_name, date_of_birth, year_of_birth, distinguished) +QUERY_HELPER(books, id, book_author, title, published_in) int main() { @@ -67,7 +67,7 @@ int main() connection c(dns, s); auto books = c.query() - .select({qh::book.id.name}) + .select({matador::qh::books.id.name}) .from({"book"}) .join_left({"authors"}) .on("book.author_id"_col == "author.id"_col) diff --git a/demo/query_helper.hpp b/demo/query_helper.hpp index 73eeaa7..ca9e201 100644 --- a/demo/query_helper.hpp +++ b/demo/query_helper.hpp @@ -41,7 +41,7 @@ table::table(const basic_query&) #define FIELD(x) const field x{#x}; #define QUERY_HELPER(C, ...) \ -namespace qh { \ +namespace matador::qh { \ namespace internal { \ struct C##_query { \ MAP(FIELD, __VA_ARGS__) \ diff --git a/include/matador/sql/query_intermediates.hpp b/include/matador/sql/query_intermediates.hpp index 57d67e1..728e52f 100644 --- a/include/matador/sql/query_intermediates.hpp +++ b/include/matador/sql/query_intermediates.hpp @@ -138,7 +138,12 @@ public: using query_select_finish::query_select_finish; query_join_intermediate join(const std::string &join_table_name, const std::string &as); - query_where_intermediate where(const basic_condition &cond); + template + query_where_intermediate where(const Condition &cond) + { + data_.parts.push_back(std::make_unique(cond)); + return {connection_, data_}; + } query_group_by_intermediate group_by(const std::string &name); query_order_by_intermediate order_by(const std::string &name); }; diff --git a/include/matador/sql/query_parts.hpp b/include/matador/sql/query_parts.hpp index 3464766..23e8ed8 100644 --- a/include/matador/sql/query_parts.hpp +++ b/include/matador/sql/query_parts.hpp @@ -81,6 +81,8 @@ public: : query_part(dialect::token_t::ON) , condition_(new Condition(cond)) {} + const basic_condition& condition() const; + private: void accept(query_part_visitor &visitor) override; @@ -96,6 +98,8 @@ public: : query_part(dialect::token_t::WHERE) , condition_(new Condition(cond)) {} + const basic_condition& condition() const; + private: void accept(query_part_visitor &visitor) override; diff --git a/include/matador/sql/table.hpp b/include/matador/sql/table.hpp index 7a57ee3..f0c8742 100644 --- a/include/matador/sql/table.hpp +++ b/include/matador/sql/table.hpp @@ -12,6 +12,8 @@ struct table std::string name; std::string alias; + table(const char *name, std::string as = "") // NOLINT(*-explicit-constructor) + : name(name), alias(std::move(as)) {} table(std::string name, std::string as = "") // NOLINT(*-explicit-constructor) : name(std::move(name)), alias(std::move(as)) {} diff --git a/src/sql/query_compiler.cpp b/src/sql/query_compiler.cpp index 3c32ad1..f358b26 100644 --- a/src/sql/query_compiler.cpp +++ b/src/sql/query_compiler.cpp @@ -6,7 +6,7 @@ namespace matador::sql { query_compiler::query_compiler(const sql::dialect &d) -: dialect_(d) + : dialect_(d) {} query_context query_compiler::compile(const query_data *data) @@ -53,28 +53,34 @@ void query_compiler::visit(query_from_part &from_part) if (dialect_.default_schema_name().empty()) { query_.sql += " " + dialect_.token_at(dialect::token_t::FROM) + " " + dialect_.prepare_identifier(from_part.table().name) + - (from_part.table().alias.empty() ? "" : " AS " + dialect_.prepare_identifier(from_part.table().alias)); + (from_part.table().alias.empty() ? "" : " AS " + + dialect_.prepare_identifier(from_part.table().alias)); } else { query_.sql += " " + dialect_.token_at(dialect::token_t::FROM) + " " + dialect_.prepare_identifier(dialect_.default_schema_name()) + "." + dialect_.prepare_identifier(from_part.table().name) + - (from_part.table().alias.empty() ? "" : " AS " + dialect_.prepare_identifier(from_part.table().alias)); + (from_part.table().alias.empty() ? "" : " AS " + + dialect_.prepare_identifier(from_part.table().alias)); } } void query_compiler::visit(query_join_part &join_part) { - + query_.sql += " " + dialect_.token_at(dialect::token_t::JOIN) + + " " + dialect_.prepare_identifier(join_part.table().name) + + (join_part.table().alias.empty() ? "" : " AS " + dialect_.prepare_identifier(join_part.table().alias)); } void query_compiler::visit(query_on_part &on_part) { - + query_.sql += " " + dialect_.token_at(dialect::token_t::ON) + + " " + on_part.condition().evaluate(const_cast(dialect_), query_); } void query_compiler::visit(query_where_part &where_part) { - + query_.sql += " " + dialect_.token_at(dialect::token_t::WHERE) + + " " + where_part.condition().evaluate(const_cast(dialect_), query_); } void query_compiler::visit(query_group_by_part &group_by_part) diff --git a/src/sql/query_intermediates.cpp b/src/sql/query_intermediates.cpp index 68f4108..175572b 100644 --- a/src/sql/query_intermediates.cpp +++ b/src/sql/query_intermediates.cpp @@ -108,12 +108,6 @@ query_join_intermediate query_on_intermediate::join(const std::string &join_tabl // return {connection_, builder_.join(join_table_name, join_type_t::INNER, as)}; } -query_where_intermediate query_on_intermediate::where(const basic_condition &cond) -{ - return {connection_, data_}; -// return {connection_, builder_.where(cond)}; -} - query_group_by_intermediate query_on_intermediate::group_by(const std::string &name) { return {connection_, data_}; diff --git a/src/sql/query_parts.cpp b/src/sql/query_parts.cpp index 8ba7fc6..6104d28 100644 --- a/src/sql/query_parts.cpp +++ b/src/sql/query_parts.cpp @@ -48,6 +48,11 @@ void query_join_part::accept(query_part_visitor &visitor) visitor.visit(*this); } +const basic_condition &query_on_part::condition() const +{ + return *condition_; +} + void query_on_part::accept(query_part_visitor &visitor) { visitor.visit(*this); @@ -58,6 +63,11 @@ void query_where_part::accept(query_part_visitor &visitor) visitor.visit(*this); } +const basic_condition &query_where_part::condition() const +{ + return *condition_; +} + query_table_name_part::query_table_name_part(sql::dialect::token_t token, std::string table_name) : query_part(token) , table_name_(std::move(table_name)) {}