diff --git a/CMakeLists.txt b/CMakeLists.txt index c17fff8..8c2b6b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,10 @@ find_package(SQLite3 REQUIRED) find_package(PostgreSQL REQUIRED) find_package(MySQL REQUIRED) +message(STATUS "Found ODBC config ${ODBC_CONFIG}") +message(STATUS "Adding ODBC include directory: ${ODBC_INCLUDE_DIRS}") +message(STATUS "Adding ODBC libs: ${ODBC_LIBRARIES}") + message(STATUS "Found SQLite3 ${SQLite3_VERSION}") message(STATUS "Adding SQLite3 include directory: ${SQLite3_INCLUDE_DIRS}") message(STATUS "Adding SQLite3 libs: ${SQLite3_LIBRARIES}") diff --git a/backends/tests/TypeTraitsTest.cpp b/backends/tests/TypeTraitsTest.cpp index bc99de8..cd4ae89 100644 --- a/backends/tests/TypeTraitsTest.cpp +++ b/backends/tests/TypeTraitsTest.cpp @@ -52,38 +52,32 @@ static const matador::utils::enum_mapper color_enum({ {Color::Brown, "brown"} }); -namespace matador::sql { - template<> -struct data_type_traits +struct matador::sql::data_type_traits { - inline static data_type_t builtin_type(std::size_t size) - { return data_type_traits::builtin_type(size); } + inline static data_type_t builtin_type(std::size_t size) + { return data_type_traits::builtin_type(size); } - static void read_value(query_result_reader &reader, const char *id, size_t index, Color &value) - { - std::string enum_string; - reader.read_value(id, index, enum_string, 64); - auto enum_opt = color_enum.to_enum(enum_string); - if (enum_opt) { - value = enum_opt.value(); + static void read_value(query_result_reader &reader, const char *id, size_t index, Color &value) + { + std::string enum_string; + reader.read_value(id, index, enum_string, 64); + if (const auto enum_opt = color_enum.to_enum(enum_string)) { + value = enum_opt.value(); + } } - } - static any_type create_value(Color &value) - { - return color_enum.to_string(value); - } + static any_type create_value(const Color &value) + { + return color_enum.to_string(value); + } - static void bind_value(parameter_binder &binder, size_t index, Color &value) - { - binder.bind(index, color_enum.to_string(value)); - } + static void bind_value(parameter_binder &binder, size_t index, Color &value) + { + binder.bind(index, color_enum.to_string(value)); + } }; -} - - TEST_CASE_METHOD(TypeTraitsTestFixture, "Special handling of attributes with type traits", "[typetraits]") { schema.attach("location"); diff --git a/demo/main.cpp b/demo/main.cpp index 0987a54..7751a7d 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -11,160 +11,219 @@ #include #include -struct author -{ - unsigned long id{}; - std::string first_name; - std::string last_name; - std::string date_of_birth; - unsigned short year_of_birth{}; - bool distinguished{false}; +struct author { + unsigned long id{}; + std::string first_name; + std::string last_name; + std::string date_of_birth; + unsigned short year_of_birth{}; + bool distinguished{false}; - template - void process(Operator &op) - { - namespace field = matador::utils::access; - field::primary_key(op, "id", id); - field::attribute(op, "first_name", first_name, 63); - field::attribute(op, "last_name", last_name, 63); - field::attribute(op, "date_of_birth", date_of_birth, 31); - field::attribute(op, "year_of_birth", year_of_birth); - field::attribute(op, "distinguished", distinguished); - } + template + void process( Operator& op ) { + namespace field = matador::utils::access; + field::primary_key( op, "id", id ); + field::attribute( op, "first_name", first_name, 63 ); + field::attribute( op, "last_name", last_name, 63 ); + field::attribute( op, "date_of_birth", date_of_birth, 31 ); + field::attribute( op, "year_of_birth", year_of_birth ); + field::attribute( op, "distinguished", distinguished ); + } }; -struct book -{ - unsigned long id{}; - matador::sql::entity book_author; - std::string title; - unsigned short published_in{}; +struct book { + unsigned long id{}; + matador::sql::entity book_author; + std::string title; + unsigned short published_in{}; - template - void process(Operator &op) - { - namespace field = matador::utils::access; - field::primary_key(op, "id", id); - field::attribute(op, "title", title, 511); - field::has_one(op, "author_id", book_author, matador::utils::default_foreign_attributes); - field::attribute(op, "published_in", published_in); - } + template + void process( Operator& op ) { + namespace field = matador::utils::access; + field::primary_key( op, "id", id ); + field::attribute( op, "title", title, 511 ); + field::has_one( op, "author_id", book_author, matador::utils::default_foreign_attributes ); + field::attribute( op, "published_in", published_in ); + } }; -QUERY_HELPER(authors, id, first_name, last_name, date_of_birth, year_of_birth, distinguished) -QUERY_HELPER(books, id, author_id, title, published_in) +struct payload { + unsigned long id{}; -int main() -{ - using namespace matador::sql; - using namespace matador; + template + void process( Operator& op ) { + namespace field = matador::utils::access; + field::primary_key( op, "id", id ); + } +}; - const std::string env_var{"MATADOR_BACKENDS_PATH"}; +struct job { + enum class job_state { + Pending, + Running, + Succeeded, + Failed, + Canceled + }; - std::string dns{"sqlite://demo.db"}; - schema s("main"); - s.attach("authors"); - s.attach("books"); + enum class job_mode { + Foreground, + Background + }; - connection c(dns); - c.open(); + unsigned long id{}; + matador::sql::entity payload; + std::string type; + std::string description; + job_state state; + job_mode mode; - auto create_authors_sql = c.query(s) - .create() - .table(qh::authors) - .execute(); + template + void process( Operator& op ) { + namespace field = matador::utils::access; + field::primary_key( op, "id", id ); + field::belongs_to( op, "payload", payload, matador::utils::default_foreign_attributes ); + field::attribute( op, "type", type, 511 ); + field::attribute( op, "description", description, 511 ); + field::attribute( op, "state", state ); + field::attribute( op, "mode", mode ); + } +}; - c.query(s) - .create() - .table(qh::books) - .execute(); +QUERY_HELPER( authors, id, first_name, last_name, date_of_birth, year_of_birth, distinguished ) - std::cout << "SQL: " << create_authors_sql << "\n"; +QUERY_HELPER( books, id, author_id, title, published_in ) - author mc; - mc.id = 1; - mc.first_name = "Michael"; - mc.last_name = "Crichton"; - mc.date_of_birth = "19.8.1954"; - mc.year_of_birth = 1954; - mc.distinguished = true; - auto insert_authors_sql = c.query(s) - .insert() - .into(qh::authors) - .values(mc) - .execute(); +QUERY_HELPER( job, id, payload, type, description, state, mode ) - std::cout << "SQL: " << insert_authors_sql << "\n"; +QUERY_HELPER( payload, id ) - auto result = c.query(s) - .select(qh::authors.columns) - .from(qh::authors) - .fetch_all(); +QUERY_HELPER( temporary_table, id ); - for (const auto &row: result) { - std::cout << "Author " << row.at(qh::authors.first_name) << "\n"; - } +int main() { + using namespace matador::sql; + using namespace matador; - auto update_authors_sql = c.query(s) - .update(qh::authors) - .set({{qh::authors.first_name, "Stephen"}, - {qh::authors.last_name, "King"}}) - .where(qh::authors.last_name == "Crichton") - .execute(); + const std::string env_var{"MATADOR_BACKENDS_PATH"}; - std::cout << "SQL: " << update_authors_sql << "\n"; + std::string dns{"sqlite://demo.db"}; + schema s( "main" ); + s.attach( "authors" ); + s.attach( "books" ); - auto authors = c.query(s) - .select(qh::authors.columns) - .from(qh::authors) - .fetch_all(); + connection c( dns ); + c.open(); + s.create( c ); - for (const auto &a: authors) { - std::cout << "Author " << a.first_name << "\n"; - } + auto create_authors_sql = c.query( s ) + .create() + .table( qh::authors ) + .execute(); - c.query(s) - .insert() - .into(qh::books) - .values({2, "It", mc.id, 1980}) - .execute(); + c.query( s ) + .create() + .table( qh::books ) + .execute(); - c.query(s) - .insert() - .into(qh::books) - .values({3, "Misery", mc.id, 1984}) - .execute(); + std::cout << "SQL: " << create_authors_sql << "\n"; - auto select_books_sql = c.query(s) - .select(qh::books.columns, {qh::authors.last_name}) - .from(qh::books) - .join_left(qh::authors) - .on(qh::books.author_id == qh::authors.id) - .where(qh::books.published_in < 2008 && qh::authors.last_name == "King") - .group_by(qh::books.published_in) - .order_by(qh::books.title).asc() - .limit(5) - .offset(2) - .fetch_all(); + author mc; + mc.id = 1; + mc.first_name = "Michael"; + mc.last_name = "Crichton"; + mc.date_of_birth = "19.8.1954"; + mc.year_of_birth = 1954; + mc.distinguished = true; + auto insert_authors_sql = c.query( s ) + .insert() + .into( qh::authors ) + .values( mc ) + .execute(); - for (const auto &r: select_books_sql) { - std::cout << "R: " << r.at(qh::books.title) << ", " << r.at(qh::authors.last_name) << "\n"; - } - // SELECT book.title, book.id, book.author_id, book.published_in, author.name - // FROM book - // INNER JOIN author ON book.author_id = author.id - // WHERE book.published_in < 2008 AND author.name = "Michael Crichton" - // ORDER BY "book.title" ASC - // OFFSET 2 LIMIT 5 + std::cout << "SQL: " << insert_authors_sql << "\n"; - c.query(s).drop().table(qh::books).execute(); + auto result = c.query( s ) + .select( qh::authors.columns ) + .from( qh::authors ) + .fetch_all(); - auto drop_authors_sql = c.query(s) - .drop() - .table(qh::authors) - .execute(); + for (const auto& row: result) { std::cout << "Author " << row.at( qh::authors.first_name ) << "\n"; } - std::cout << "SQL: " << drop_authors_sql << "\n"; + auto update_authors_sql = c.query( s ) + .update( qh::authors ) + .set( {{qh::authors.first_name, "Stephen"}, + {qh::authors.last_name, "King"}} ) + .where( qh::authors.last_name == "Crichton" ) + .execute(); - return 0; -} + std::cout << "SQL: " << update_authors_sql << "\n"; + + auto authors = c.query( s ) + .select( qh::authors.columns ) + .from( qh::authors ) + .fetch_all(); + + for (const auto& a: authors) { std::cout << "Author " << a.first_name << "\n"; } + + c.query( s ) + .insert() + .into( qh::books ) + .values( {2, "It", mc.id, 1980} ) + .execute(); + + c.query( s ) + .insert() + .into( qh::books ) + .values( {3, "Misery", mc.id, 1984} ) + .execute(); + + auto select_books_sql = c.query( s ) + .select( qh::books.columns, {qh::authors.last_name} ) + .from( qh::books ) + .join_left( qh::authors ) + .on( qh::books.author_id == qh::authors.id ) + .where( qh::books.published_in < 2008 && qh::authors.last_name == "King" ) + .group_by( qh::books.published_in ) + .order_by( qh::books.title ).asc() + .limit( 5 ) + .offset( 2 ) + .fetch_all(); + + for (const auto& r: select_books_sql) { std::cout << "R: " << r.at( qh::books.title ) << ", " << r.at( qh::authors.last_name ) << "\n"; } + // SELECT book.title, book.id, book.author_id, book.published_in, author.name + // FROM book + // INNER JOIN author ON book.author_id = author.id + // WHERE book.published_in < 2008 AND author.name = "Michael Crichton" + // ORDER BY "book.title" ASC + // OFFSET 2 LIMIT 5 + + c.query( s ).drop().table( qh::books ).execute(); + + auto drop_authors_sql = c.query( s ) + .drop() + .table( qh::authors ) + .execute(); + + std::cout << "SQL: " << drop_authors_sql << "\n"; + + auto res = c.query( s ) + .select( {qh::payload.id} ) + .from( qh::payload ) + .join_left( qh::job ) + .on( qh::job.payload == qh::payload.id ) + .where( + in( qh::payload.id, c.query( s ) + .select( {qh::job.state} ) + .from( qh::job ) + .where( qh::job.state == job::job_state::Running ) + ) && + in( qh::payload.id, c.query( s ) + .select( {qh::temporary_table.id} ) + .from( qh::temporary_table ) ) + ) + .build(); + // .fetch_value(); + std::cout << "SQL: " << res.sql << "\n"; + + return 0; +} \ No newline at end of file diff --git a/include/matador/sql/condition.hpp b/include/matador/sql/condition.hpp index e390c3f..fcd5b9c 100644 --- a/include/matador/sql/condition.hpp +++ b/include/matador/sql/condition.hpp @@ -1,6 +1,8 @@ #ifndef QUERY_CONDITION_HPP #define QUERY_CONDITION_HPP +#include "matador/sql/any_type_to_string_visitor.hpp" +#include "matador/sql/query_result.hpp" #include "matador/sql/basic_condition.hpp" #include "matador/sql/dialect.hpp" #include "matador/sql/placeholder.hpp" @@ -26,6 +28,8 @@ namespace matador::sql { /// @cond MATADOR_DEV +class query_select; + template class condition; @@ -43,6 +47,7 @@ public: template class condition::value && + !std::is_enum::value && !std::is_same::value && !std::is_same::value>::type> : public basic_column_condition { @@ -82,10 +87,32 @@ public: }; template -class condition::value && - !std::is_same::value && - !std::is_same::value>::type> : public basic_column_condition +class condition>> final : public basic_column_condition +{ +public: + condition(const column &fld, basic_condition::operand_t op, T val) + : basic_column_condition(fld, op) + , value(val) + { } + + T value; + + std::string evaluate(const dialect &d, query_context &query) const override + { + auto at = data_type_traits::create_value(value); + any_type_to_string_visitor value_to_string(d, query); + std::visit(value_to_string, at); + return "'" + value_to_string.result + "' " + operand + " " + d.prepare_identifier(field_); + } + +}; + + +template +class condition && + !std::is_same_v && + !std::is_same_v>> final : public basic_column_condition { public: condition(T val, basic_condition::operand_t op, const column &fld) @@ -215,7 +242,7 @@ public: * @param op Operand of the condition * @param q The query to be evaluated to the IN arguments */ - condition(column col, basic_condition::operand_t op, query_context &q); + condition(column col, basic_condition::operand_t op, const query_context &q); /** * @brief Evaluates the condition @@ -229,7 +256,7 @@ public: std::string evaluate(const dialect &d, query_context &query) const override; private: - query_context &query_; + query_context query_; }; /** @@ -415,7 +442,8 @@ condition> in(const column &col, std::initializ * @param q The query to be executes as sub select * @return The condition object */ -condition in(const column &col, query_context &&q); +condition in(const column &col, const query_context &q); +condition in(const column &col, const query_select &q); /** * @brief Creates a between condition. diff --git a/include/matador/sql/data_type_traits.hpp b/include/matador/sql/data_type_traits.hpp index ef23b14..6b5a2f1 100644 --- a/include/matador/sql/data_type_traits.hpp +++ b/include/matador/sql/data_type_traits.hpp @@ -59,7 +59,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, nullptr_t &/*value*/); static void bind_value(parameter_binder &binder, size_t index, nullptr_t &/*value*/); static void bind_result_value(result_parameter_binder &binder, size_t index, nullptr_t &/*value*/); - inline static any_type create_value(char &value) { return value; } + inline static any_type create_value(const char &value) { return value; } }; template <> struct data_type_traits @@ -68,7 +68,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, char &value); static void bind_value(parameter_binder &binder, size_t index, char &value); static void bind_result_value(result_parameter_binder &binder, size_t index, char &value); - inline static any_type create_value(char &value) { return value; } + inline static any_type create_value(const char &value) { return value; } }; template <> struct data_type_traits @@ -77,7 +77,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, short &value); static void bind_value(parameter_binder &binder, size_t index, short &value); static void bind_result_value(result_parameter_binder &binder, size_t index, short &value); - inline static any_type create_value(short &value) { return value; } + inline static any_type create_value(const short &value) { return value; } }; template <> struct data_type_traits @@ -86,7 +86,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, int &value); static void bind_value(parameter_binder &binder, size_t index, int &value); static void bind_result_value(result_parameter_binder &binder, size_t index, int &value); - inline static any_type create_value(int &value) { return value; } + inline static any_type create_value(const int &value) { return value; } }; template <> struct data_type_traits @@ -95,7 +95,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, long &value); static void bind_value(parameter_binder &binder, size_t index, long &value); static void bind_result_value(result_parameter_binder &binder, size_t index, long &value); - inline static any_type create_value(long &value) { return value; } + inline static any_type create_value(const long &value) { return value; } }; template <> struct data_type_traits @@ -104,7 +104,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, long long &value); static void bind_value(parameter_binder &binder, size_t index, long long &value); static void bind_result_value(result_parameter_binder &binder, size_t index, long long &value); - inline static any_type create_value(long long &value) { return value; } + inline static any_type create_value(const long long &value) { return value; } }; template <> struct data_type_traits @@ -113,7 +113,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned char &value); static void bind_value(parameter_binder &binder, size_t index, unsigned char &value); static void bind_result_value(result_parameter_binder &binder, size_t index, unsigned char &value); - inline static any_type create_value(unsigned char &value) { return value; } + inline static any_type create_value(const unsigned char &value) { return value; } }; template <> struct data_type_traits @@ -122,7 +122,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned short &value); static void bind_value(parameter_binder &binder, size_t index, unsigned short &value); static void bind_result_value(result_parameter_binder &binder, size_t index, unsigned short &value); - inline static any_type create_value(unsigned short &value) { return value; } + inline static any_type create_value(const unsigned short &value) { return value; } }; template <> struct data_type_traits @@ -131,7 +131,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned int &value); static void bind_value(parameter_binder &binder, size_t index, unsigned int &value); static void bind_result_value(result_parameter_binder &binder, size_t index, unsigned int &value); - inline static any_type create_value(unsigned int &value) { return value; } + inline static any_type create_value(const unsigned int &value) { return value; } }; template <> struct data_type_traits @@ -140,7 +140,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned long &value); static void bind_value(parameter_binder &binder, size_t index, unsigned long &value); static void bind_result_value(result_parameter_binder &binder, size_t index, unsigned long &value); - inline static any_type create_value(unsigned long &value) { return value; } + inline static any_type create_value(const unsigned long &value) { return value; } }; template <> struct data_type_traits @@ -149,7 +149,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, unsigned long long &value); static void bind_value(parameter_binder &binder, size_t index, unsigned long long &value); static void bind_result_value(result_parameter_binder &binder, size_t index, unsigned long long &value); - inline static any_type create_value(unsigned long long &value) { return value; } + inline static any_type create_value(const unsigned long long &value) { return value; } }; template <> struct data_type_traits @@ -158,7 +158,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, bool &value); static void bind_value(parameter_binder &binder, size_t index, bool &value); static void bind_result_value(result_parameter_binder &binder, size_t index, bool &value); - inline static any_type create_value(bool &value) { return value; } + inline static any_type create_value(const bool &value) { return value; } }; template <> struct data_type_traits @@ -167,7 +167,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, float &value); static void bind_result_value(result_parameter_binder &binder, size_t index, float &value); static void bind_value(parameter_binder &binder, size_t index, float &value); - inline static any_type create_value(float &value) { return value; } + inline static any_type create_value(const float &value) { return value; } }; template <> struct data_type_traits @@ -176,7 +176,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, double &value); static void bind_result_value(result_parameter_binder &binder, size_t index, double &value); static void bind_value(parameter_binder &binder, size_t index, double &value); - inline static any_type create_value(double &value) { return value; } + inline static any_type create_value(const double &value) { return value; } }; template <> struct data_type_traits @@ -203,7 +203,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, std::string &value, size_t size); static void bind_value(parameter_binder &binder, size_t index, std::string &value, size_t size = 0); static void bind_result_value(result_parameter_binder &binder, size_t index, std::string &value, size_t size = 0); - inline static any_type create_value(std::string &value) { return value; } + inline static any_type create_value(const std::string &value) { return value; } }; template <> struct data_type_traits @@ -212,7 +212,7 @@ template <> struct data_type_traits static void read_value(query_result_reader &reader, const char *id, size_t index, utils::blob &value); static void bind_value(parameter_binder &binder, size_t index, utils::blob &value); static void bind_result_value(result_parameter_binder &binder, size_t index, utils::blob &value); - inline static any_type create_value(utils::blob &value) { return value; } + inline static any_type create_value(const utils::blob &value) { return value; } }; //template <> struct data_type_traits @@ -232,7 +232,7 @@ template <> struct data_type_traits //}; template < typename EnumType > -struct data_type_traits::value>::type> +struct data_type_traits>> { inline static data_type_t builtin_type(std::size_t /*size*/) { return data_type_t::type_int; } static void read_value(query_result_reader &reader, const char *id, size_t index, EnumType &value) @@ -241,13 +241,15 @@ struct data_type_traits } static void bind_value(parameter_binder &binder, size_t index, EnumType &value) { - data_type_traits::bind_value(binder, index, (int&)value); + data_type_traits::bind_value(binder, index, static_cast(value)); } static void bind_result_value(result_parameter_binder &binder, size_t index, EnumType &value) { - data_type_traits::bind_result_value(binder, index, (int&)value); + data_type_traits::bind_result_value(binder, index, static_cast(value)); + } + static any_type create_value(const EnumType &value) { + return static_cast(value); } - inline static any_type create_value(EnumType &value) { return (int)value; } }; /// @endcond diff --git a/include/matador/sql/entity_query_builder.hpp b/include/matador/sql/entity_query_builder.hpp index 5b1d4ab..9c7c42c 100644 --- a/include/matador/sql/entity_query_builder.hpp +++ b/include/matador/sql/entity_query_builder.hpp @@ -136,7 +136,12 @@ public: void on_primary_key(const char *id, V &, typename std::enable_if::value && !std::is_same::value>::type* = 0) { push(id); - if (is_root_entity() && pk_.is_integer()) { + if (!is_root_entity()) { + return; + } + if (pk_.is_null()) { + entity_query_data_.pk_column_ = id; + } else if (pk_.is_integer()) { entity_query_data_.where_clause = make_condition(column{table_info_stack_.top().name, id, ""} == *pk_.as()); entity_query_data_.pk_column_ = id; } diff --git a/include/matador/sql/schema.hpp b/include/matador/sql/schema.hpp index 6cde249..1c85c55 100644 --- a/include/matador/sql/schema.hpp +++ b/include/matador/sql/schema.hpp @@ -36,6 +36,8 @@ public: [[nodiscard]] std::string name() const; + void create(connection &c); + template const table_info& attach(const std::string &table_name) { diff --git a/src/sql/condition.cpp b/src/sql/condition.cpp index 532dd7e..92b19d0 100644 --- a/src/sql/condition.cpp +++ b/src/sql/condition.cpp @@ -1,5 +1,7 @@ #include "matador/sql/condition.hpp" +#include "matador/sql/query_intermediates.hpp" + namespace matador::sql { condition::type>::condition(const column &fld, basic_condition::operand_t op, const placeholder &val) @@ -12,17 +14,33 @@ std::string condition::type>::evaluate return d.prepare_identifier(field_) + " " + operand + " " + d.next_placeholder(query.bind_vars); } -condition::condition(column col, basic_condition::operand_t op, query_context &q) +condition::condition(column col, basic_condition::operand_t op, const query_context &q) : basic_column_condition(std::move(col), op), query_(q) {} std::string condition::evaluate(const dialect &d, query_context &query) const { std::string result(d.prepare_identifier(field_) + " " + operand + " ("); - result += (")"); + result += query_.sql + (")"); return result; } +condition in( const column& col, const query_context &q ) { + return {col, basic_condition::operand_t::IN_LIST, q}; +} + +condition in( const column& col, const query_select& q ) { + return in(col, q.build()); +} + +condition like( const column& col, const std::string& val ) { + return {col, basic_condition::operand_t::LIKE, val}; +} + +condition equals( const column& col, query_context& q ) { + return {col, basic_condition::operand_t::EQUAL, q}; +} + condition operator==(const column &a, const column &b) { return {a, basic_condition::operand_t::EQUAL, b}; diff --git a/src/sql/connection.cpp b/src/sql/connection.cpp index 89dabea..77e4d6a 100644 --- a/src/sql/connection.cpp +++ b/src/sql/connection.cpp @@ -91,7 +91,7 @@ size_t connection::execute(const std::string &sql) const return connection_->execute(sql); } -sql::query connection::query(const sql::schema &schema) const +sql::query connection::query(const schema &schema) const { return sql::query(*const_cast(this), schema); } diff --git a/src/sql/dialect.cpp b/src/sql/dialect.cpp index 07433b0..16e6da2 100644 --- a/src/sql/dialect.cpp +++ b/src/sql/dialect.cpp @@ -51,8 +51,8 @@ std::string dialect::prepare_literal(const std::string &str) const void dialect::quote_identifier(std::string &str) const { - str.insert(0, token_at(token_t::START_QUOTE)); - str += token_at(token_t::END_QUOTE); + // str.insert(0, token_at(token_t::START_QUOTE)); + // str += token_at(token_t::END_QUOTE); } void dialect::escape_quotes_in_identifier(std::string &str) const diff --git a/src/sql/query_compiler.cpp b/src/sql/query_compiler.cpp index 59e8a5b..3b61102 100644 --- a/src/sql/query_compiler.cpp +++ b/src/sql/query_compiler.cpp @@ -54,7 +54,7 @@ void query_compiler::visit(query_select_part &select_part) void query_compiler::visit(query_from_part &from_part) { query_.table = from_part.table(); - if (dialect_.default_schema_name().empty()) { + 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 " + diff --git a/src/sql/schema.cpp b/src/sql/schema.cpp index b3b6c39..b2e857d 100644 --- a/src/sql/schema.cpp +++ b/src/sql/schema.cpp @@ -8,6 +8,13 @@ namespace matador::sql { schema::schema(std::string name) : name_(std::move(name)) {} +void schema::create(connection &c) { + for (const auto &ti : repository_) { + // ti.second.prototype + + } +} + std::string schema::name() const { return name_;