#ifndef QUERY_QUERY_INTERMEDIATES_HPP #define QUERY_QUERY_INTERMEDIATES_HPP #include "matador/sql/column_definition.hpp" #include "matador/sql/column_definition_generator.hpp" #include "matador/sql/column_generator.hpp" #include "matador/sql/key_value_generator.hpp" #include "matador/sql/key_value_pair.hpp" #include "matador/sql/placeholder_generator.hpp" #include "matador/sql/query_result.hpp" #include "matador/sql/query_data.hpp" #include "matador/sql/record.hpp" #include "matador/sql/statement.hpp" #include "matador/sql/schema.hpp" #include "matador/sql/value_extractor.hpp" #include namespace matador::sql { class basic_condition; class connection; class basic_query_intermediate { public: explicit basic_query_intermediate(connection &db, const sql::schema &schema); protected: connection &connection_; const sql::schema &schema_; }; class query_intermediate : public basic_query_intermediate { public: query_intermediate(connection &db, const sql::schema &schema, query_data &data); protected: query_data &data_; }; class query_execute_finish : public query_intermediate { public: using query_intermediate::query_intermediate; size_t execute(); statement prepare(); [[nodiscard]] query_context build() const; }; class query_select_finish : public query_intermediate { protected: using query_intermediate::query_intermediate; public: template < class Type > query_result fetch_all() { return query_result(fetch()); } query_result fetch_all(); template < class Type > std::optional fetch_one() { auto result = query_result(fetch()); auto first = result.begin(); if (first == result.end()) { return std::nullopt; } return *first.get(); } std::optional fetch_one(); template std::optional fetch_value() { const auto result = fetch_one(); if (result.has_value()) { return result.value().at(0).as().value(); } return std::nullopt; } statement prepare(); [[nodiscard]] query_context build() const; private: std::unique_ptr fetch(); }; class query_offset_intermediate; class query_limit_intermediate : public query_select_finish { public: using query_select_finish::query_select_finish; query_offset_intermediate offset(size_t offset); }; class query_offset_intermediate : public query_select_finish { public: using query_select_finish::query_select_finish; query_limit_intermediate limit(size_t limit); }; class query_order_direction_intermediate : public query_select_finish { public: using query_select_finish::query_select_finish; query_limit_intermediate limit(size_t limit); }; class query_order_by_intermediate; class query_group_by_intermediate : public query_select_finish { public: using query_select_finish::query_select_finish; query_order_by_intermediate order_by(const column &col); }; class query_order_by_intermediate : public query_intermediate { public: using query_intermediate::query_intermediate; query_order_direction_intermediate asc(); query_order_direction_intermediate desc(); }; class query_where_intermediate : public query_select_finish { public: using query_select_finish::query_select_finish; query_group_by_intermediate group_by(const column &col); query_order_by_intermediate order_by(const column &col); }; class query_join_intermediate; class query_on_intermediate : public query_select_finish { public: using query_select_finish::query_select_finish; query_join_intermediate join_left(const table &t); template query_where_intermediate where(const Condition &cond) { return where_clause(std::make_unique(std::move(cond))); } query_group_by_intermediate group_by(const column &col); query_order_by_intermediate order_by(const column &col); private: query_where_intermediate where_clause(std::unique_ptr &&cond); }; class query_join_intermediate : public query_intermediate { public: using query_intermediate::query_intermediate; template query_on_intermediate on(const Condition &cond) { return on_clause(std::make_unique(std::move(cond))); } private: query_on_intermediate on_clause(std::unique_ptr &&cond); }; class query_from_intermediate : public query_select_finish { public: using query_select_finish::query_select_finish; query_join_intermediate join_left(const table &t); template query_where_intermediate where(const Condition &cond) { return where_clause(std::make_unique(std::move(cond))); } query_group_by_intermediate group_by(const column &col); query_order_by_intermediate order_by(const column &col); private: query_where_intermediate where_clause(std::unique_ptr &&cond); }; class query_start_intermediate : public basic_query_intermediate { public: explicit query_start_intermediate(connection &db, const sql::schema &schema); protected: query_data data_; }; class query_select_intermediate : public query_start_intermediate { public: query_select_intermediate(connection &db, const sql::schema &schema, const std::vector& columns); query_from_intermediate from(const table& t); }; template < class Type > std::vector as_placeholder(const Type &obj) { placeholder_generator generator; matador::utils::access::process(generator, obj); return generator.placeholder_values; } class query_into_intermediate : public query_intermediate { public: using query_intermediate::query_intermediate; query_execute_finish values(std::initializer_list values); query_execute_finish values(std::vector &&values); template query_execute_finish values() { Type obj; return values(std::move(as_placeholder(obj))); } template query_execute_finish values(const Type &obj) { return values(std::move(value_extractor::extract(obj))); } }; class query_create_intermediate : public query_start_intermediate { public: explicit query_create_intermediate(connection &db, const sql::schema &schema); query_execute_finish table(const sql::table &table, std::initializer_list columns); query_execute_finish table(const sql::table &table, const std::vector &columns); template query_execute_finish table(const sql::table &table) { return this->table(table, column_definition_generator::generate(schema_)); } }; class query_drop_intermediate : query_start_intermediate { public: explicit query_drop_intermediate(connection &db, const sql::schema &schema); query_execute_finish table(const sql::table &table); }; class query_insert_intermediate : public query_start_intermediate { public: explicit query_insert_intermediate(connection &db, const sql::schema &schema); query_into_intermediate into(const sql::table &table, std::initializer_list column_names); query_into_intermediate into(const sql::table &table, std::vector &&column_names); query_into_intermediate into(const sql::table &table); }; class query_execute_where_intermediate : public query_execute_finish { public: using query_execute_finish::query_execute_finish; query_order_by_intermediate order_by(const column &col); }; class query_set_intermediate : public query_execute_finish { public: using query_execute_finish::query_execute_finish; template query_execute_where_intermediate where(const Condition &cond) { return where_clause(std::make_unique(std::move(cond))); } private: query_execute_where_intermediate where_clause(std::unique_ptr &&cond); }; class query_update_intermediate : public query_start_intermediate { public: query_update_intermediate(connection &db, const sql::schema &schema, const sql::table& table); query_set_intermediate set(std::initializer_list columns); query_set_intermediate set(std::vector &&columns); template query_set_intermediate set(const Type &obj) { return set(key_value_generator::generate(obj)); } }; class query_delete_from_intermediate : public query_execute_finish { public: using query_execute_finish::query_execute_finish; template query_execute_where_intermediate where(const Condition &cond) { return where_clause(std::make_unique(std::move(cond))); } private: query_execute_where_intermediate where_clause(std::unique_ptr &&cond); }; class query_delete_intermediate : public query_start_intermediate { public: explicit query_delete_intermediate(connection &db, const sql::schema &schema); query_delete_from_intermediate from(const sql::table &table); }; } #endif //QUERY_QUERY_INTERMEDIATES_HPP