query/include/matador/sql/query_intermediates.hpp

328 lines
8.6 KiB
C++

#ifndef QUERY_QUERY_INTERMEDIATES_HPP
#define QUERY_QUERY_INTERMEDIATES_HPP
#include "matador/sql/column_definition.hpp"
#include "matador/sql/column_generator.hpp"
#include "matador/sql/column_name_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 <string>
namespace matador::sql {
class basic_condition;
class connection;
class basic_query_intermediate
{
public:
explicit basic_query_intermediate(connection &db, const std::shared_ptr<sql::schema> &schema);
protected:
connection &connection_;
std::shared_ptr<sql::schema> schema_;
};
class query_intermediate : public basic_query_intermediate
{
public:
query_intermediate(connection &db, const std::shared_ptr<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]] std::string str() const;
};
class query_select_finish : public query_intermediate
{
protected:
using query_intermediate::query_intermediate;
public:
template < class Type >
query_result<Type> fetch_all()
{
return query_result<Type>(fetch());
}
query_result<record> fetch_all();
record fetch_one();
template<typename Type>
Type fetch_value()
{
return fetch_one().at(0).as<Type>();
}
statement prepare();
[[nodiscard]] std::string str() const;
private:
std::unique_ptr<query_result_impl> 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<class Condition>
query_where_intermediate where(const Condition &cond)
{
data_.parts.push_back(std::make_unique<query_where_part>(cond));
return {connection_, schema_, data_};
}
query_group_by_intermediate group_by(const column &col);
query_order_by_intermediate order_by(const column &col);
};
class query_join_intermediate : public query_intermediate
{
public:
using query_intermediate::query_intermediate;
template<class Condition>
query_on_intermediate on(const Condition &cond)
{
data_.parts.push_back(std::make_unique<query_on_part>(cond));
return {connection_, schema_, data_};
}
};
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<class Condition>
query_where_intermediate where(const Condition &cond)
{
data_.parts.push_back(std::make_unique<query_where_part>(cond));
return {connection_, schema_, data_};
}
query_group_by_intermediate group_by(const column &col);
query_order_by_intermediate order_by(const column &col);
};
class query_start_intermediate : public basic_query_intermediate
{
public:
explicit query_start_intermediate(connection &db, const std::shared_ptr<sql::schema> &schema);
protected:
query_data data_;
};
class query_select_intermediate : public query_start_intermediate
{
public:
query_select_intermediate(connection &db, const std::shared_ptr<sql::schema> &schema, const std::vector<column>& columns);
query_from_intermediate from(const table& t);
};
template < class Type >
std::vector<any_type> 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<any_type> values);
query_execute_finish values(const std::vector<any_type>& values);
template<class Type>
query_execute_finish values()
{
Type obj;
data_.parts.push_back(std::make_unique<query_values_part>(as_placeholder(obj)));
return {connection_, schema_, data_};
}
template<class Type>
query_execute_finish values(const Type &obj)
{
data_.parts.push_back(std::make_unique<query_values_part>(value_extractor::extract(obj)));
return {connection_, schema_, data_};
}
};
class query_create_intermediate : public query_start_intermediate
{
public:
explicit query_create_intermediate(connection &db, const std::shared_ptr<sql::schema> &schema);
query_execute_finish table(const sql::table &table, std::initializer_list<column_definition> columns);
query_execute_finish table(const sql::table &table, const std::vector<column_definition> &columns);
template<class Type>
query_execute_finish table(const sql::table &table)
{
if (!schema_->exists<Type>()) {
schema_->attach<Type>(table.name);
}
data_.parts.push_back(std::make_unique<query_create_table_part>(table, column_generator::generate<Type>(*schema_)));
return {connection_, schema_, data_};
}
};
class query_drop_intermediate : query_start_intermediate
{
public:
explicit query_drop_intermediate(connection &db, const std::shared_ptr<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 std::shared_ptr<sql::schema> &schema);
query_into_intermediate into(const sql::table &table, std::initializer_list<column> column_names);
template<class Type>
query_into_intermediate into(const sql::table &table)
{;
data_.parts.push_back(std::make_unique<query_into_part>(table, column_name_generator::generate<Type>(*schema_)));
return {connection_, schema_, data_};
}
};
class query_execute_where_intermediate : public query_execute_finish
{
public:
using query_execute_finish::query_execute_finish;
query_execute_finish limit(int limit);
};
class query_set_intermediate : public query_execute_finish
{
public:
using query_execute_finish::query_execute_finish;
template<class Condition>
query_execute_where_intermediate where(const Condition &cond)
{
data_.parts.push_back(std::make_unique<query_where_part>(cond));
return {connection_, schema_, data_};
}
};
class query_update_intermediate : public query_start_intermediate
{
public:
query_update_intermediate(connection &db, const std::shared_ptr<sql::schema> &schema, const sql::table& table);
query_set_intermediate set(std::initializer_list<key_value_pair> columns);
template<class Type>
query_set_intermediate set(const Type &obj)
{
data_.parts.push_back(std::make_unique<query_set_part>(key_value_generator::generate(obj)));
return {connection_, schema_, data_};
}
};
class query_delete_from_intermediate : public query_execute_finish
{
public:
using query_execute_finish::query_execute_finish;
template<class Condition>
query_execute_where_intermediate where(const Condition &cond)
{
data_.parts.push_back(std::make_unique<query_where_part>(cond));
return {connection_, schema_, data_};
}
};
class query_delete_intermediate : public query_start_intermediate
{
public:
explicit query_delete_intermediate(connection &db, const std::shared_ptr<sql::schema> &schema);
query_delete_from_intermediate from(const sql::table &table);
};
}
#endif //QUERY_QUERY_INTERMEDIATES_HPP