query compiler progress
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
#ifndef QUERY_COLUMN_HPP
|
||||
#define QUERY_COLUMN_HPP
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class column {
|
||||
public:
|
||||
column(const char *name); // NOLINT(*-explicit-constructor)
|
||||
column(std::string name); // NOLINT(*-explicit-constructor)
|
||||
column(std::string table_name, std::string name, std::string as);
|
||||
|
||||
column& as(std::string a);
|
||||
|
||||
std::string table;
|
||||
std::string name;
|
||||
std::string alias;
|
||||
};
|
||||
|
||||
column operator "" _col(const char *name, size_t len);
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_COLUMN_HPP
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef QUERY_QUERY_HPP
|
||||
#define QUERY_QUERY_HPP
|
||||
|
||||
#include "matador/query/query_parts.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class connection;
|
||||
class query
|
||||
{
|
||||
public:
|
||||
explicit query(connection &c);
|
||||
|
||||
query& select(const std::vector<column> &columns);
|
||||
query& from(const std::string &table, const std::string &as = "");
|
||||
|
||||
private:
|
||||
connection &connection_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_HPP
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef QUERY_QUERY_BUILDER_HPP
|
||||
#define QUERY_QUERY_BUILDER_HPP
|
||||
|
||||
#include "matador/query/column.hpp"
|
||||
#include "matador/query/query_intermediates.hpp"
|
||||
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_builder
|
||||
{
|
||||
public:
|
||||
explicit query_builder(const std::shared_ptr<sql::schema> &scm);
|
||||
query_select_intermediate select(std::initializer_list<column> columns);
|
||||
|
||||
private:
|
||||
std::shared_ptr<sql::schema> schema_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_BUILDER_HPP
|
||||
@@ -0,0 +1,37 @@
|
||||
#ifndef QUERY_QUERY_COMPILER_HPP
|
||||
#define QUERY_QUERY_COMPILER_HPP
|
||||
|
||||
#include "matador/query/query_part_visitor.hpp"
|
||||
#include "matador/query/query_parts.hpp"
|
||||
|
||||
|
||||
#include <typeindex>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
class dialect;
|
||||
}
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct query_data;
|
||||
|
||||
class query_compiler : public query_part_visitor
|
||||
{
|
||||
public:
|
||||
explicit query_compiler(sql::dialect& d);
|
||||
|
||||
std::string compile(const query_data *data);
|
||||
|
||||
private:
|
||||
void visit(query_select_part &select_part) override;
|
||||
void visit(query_from_part &from_part) override;
|
||||
|
||||
private:
|
||||
sql::dialect &dialect_;
|
||||
std::string sql_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_COMPILER_HPP
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef QUERY_QUERY_DATA_HPP
|
||||
#define QUERY_QUERY_DATA_HPP
|
||||
|
||||
#include "matador/query/query_parts.hpp"
|
||||
#include "matador/query/sql_commands.hpp"
|
||||
#include "matador/query/table.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct query_data
|
||||
{
|
||||
SqlCommands command;
|
||||
std::vector<std::unique_ptr<query_part>> parts;
|
||||
std::vector<column> columns;
|
||||
std::unordered_map<std::type_index, table_data> table_map_by_index;
|
||||
using table_data_ref = std::reference_wrapper<table_data>;
|
||||
std::unordered_map<std::string, table_data_ref> table_map_by_name;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_DATA_HPP
|
||||
@@ -0,0 +1,132 @@
|
||||
#ifndef QUERY_QUERY_INTERMEDIATES_HPP
|
||||
#define QUERY_QUERY_INTERMEDIATES_HPP
|
||||
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
namespace matador::sql {
|
||||
class basic_condition;
|
||||
}
|
||||
namespace matador::query {
|
||||
|
||||
class query_from_intermediate;
|
||||
class query_join_intermediate;
|
||||
class query_on_intermediate;
|
||||
class query_where_intermediate;
|
||||
class query_group_by_intermediate;
|
||||
class query_order_by_intermediate;
|
||||
class query_order_direction_intermediate;
|
||||
class query_offset_intermediate;
|
||||
class query_limit_intermediate;
|
||||
|
||||
class query_intermediate
|
||||
{
|
||||
public:
|
||||
explicit query_intermediate(const std::shared_ptr<sql::schema> &scm);
|
||||
|
||||
protected:
|
||||
sql::schema& schema() const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<sql::schema> schema_;
|
||||
};
|
||||
|
||||
class query_select_finish_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
void compile();
|
||||
};
|
||||
|
||||
class query_select_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_from_intermediate from(const std::string &table, const std::string &as = "");
|
||||
};
|
||||
|
||||
class query_from_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_join_intermediate join(const std::string &join_table_name, const std::string &as);
|
||||
query_where_intermediate where(const sql::basic_condition &cond);
|
||||
query_group_by_intermediate group_by(const std::string &name);
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
class query_join_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_on_intermediate on(const std::string &column, const std::string &join_column);
|
||||
};
|
||||
|
||||
class query_on_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_join_intermediate join(const std::string &join_table_name, const std::string &as);
|
||||
query_where_intermediate where(const sql::basic_condition &cond);
|
||||
query_group_by_intermediate group_by(const std::string &name);
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
class query_where_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_group_by_intermediate group_by(const std::string &name);
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
class query_group_by_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
};
|
||||
|
||||
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_order_direction_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
|
||||
query_offset_intermediate offset(size_t offset);
|
||||
query_limit_intermediate limit(size_t limit);
|
||||
};
|
||||
|
||||
class query_offset_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_limit_intermediate limit(size_t limit);
|
||||
};
|
||||
|
||||
class query_limit_intermediate : public query_select_finish_intermediate
|
||||
{
|
||||
public:
|
||||
using query_select_finish_intermediate::query_intermediate;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_INTERMEDIATES_HPP
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef QUERY_QUERY_PART_VISITOR_HPP
|
||||
#define QUERY_QUERY_PART_VISITOR_HPP
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_select_part;
|
||||
class query_from_part;
|
||||
|
||||
class query_part_visitor
|
||||
{
|
||||
public:
|
||||
virtual ~query_part_visitor() = default;
|
||||
|
||||
virtual void visit(query_select_part &select_part) = 0;
|
||||
virtual void visit(query_from_part &from_part) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PART_VISITOR_HPP
|
||||
@@ -0,0 +1,55 @@
|
||||
#ifndef QUERY_QUERY_PARTS_HPP
|
||||
#define QUERY_QUERY_PARTS_HPP
|
||||
|
||||
#include "matador/query/query_part_visitor.hpp"
|
||||
#include "matador/query/column.hpp"
|
||||
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_part
|
||||
{
|
||||
protected:
|
||||
explicit query_part(sql::dialect::token_t token);
|
||||
|
||||
public:
|
||||
virtual ~query_part() = default;
|
||||
virtual void accept(query_part_visitor &visitor) = 0;
|
||||
|
||||
protected:
|
||||
sql::dialect::token_t token_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL SELECT part
|
||||
*/
|
||||
class query_select_part : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_select_part(std::vector<column> columns);
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::vector<column> columns_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL FROM part
|
||||
*/
|
||||
class query_from_part : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_from_part(std::string table_name);
|
||||
query_from_part(std::string table_name, std::string as);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::string table_;
|
||||
std::string alias_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PARTS_HPP
|
||||
@@ -0,0 +1,31 @@
|
||||
#ifndef QUERY_SQL_COMMANDS_HPP
|
||||
#define QUERY_SQL_COMMANDS_HPP
|
||||
|
||||
#include "matador/utils/enum_mapper.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
enum class SqlCommands
|
||||
{
|
||||
UNKNOWN, /**< Unknown query command */
|
||||
CREATE, /**< Create query command */
|
||||
DROP, /**< Drop query command */
|
||||
SELECT, /**< Select query command */
|
||||
INSERT, /**< Insert query command */
|
||||
UPDATE, /**< Update query command */
|
||||
REMOVE /**< Remove query command */
|
||||
};
|
||||
|
||||
static const utils::enum_mapper<SqlCommands> sql_command_enum({
|
||||
{SqlCommands::UNKNOWN, "unknown"},
|
||||
{SqlCommands::CREATE, "create"},
|
||||
{SqlCommands::DROP, "drop"},
|
||||
{SqlCommands::SELECT, "select"},
|
||||
{SqlCommands::INSERT, "insert"},
|
||||
{SqlCommands::UPDATE, "update"},
|
||||
{SqlCommands::REMOVE, "delete"}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_SQL_COMMANDS_HPP
|
||||
@@ -0,0 +1,16 @@
|
||||
#ifndef QUERY_TABLE_HPP
|
||||
#define QUERY_TABLE_HPP
|
||||
|
||||
#include <typeindex>
|
||||
#include <string>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct table_data
|
||||
{
|
||||
std::type_index index;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_TABLE_HPP
|
||||
+25
-154
@@ -1,174 +1,45 @@
|
||||
#ifndef QUERY_COLUMN_HPP
|
||||
#define QUERY_COLUMN_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/any_type_to_visitor.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
enum class null_option : uint8_t {
|
||||
NULLABLE, NOT_NULL
|
||||
enum class sql_function_t {
|
||||
NONE,
|
||||
COUNT,
|
||||
AVG,
|
||||
SUM,
|
||||
MIN,
|
||||
MAX
|
||||
};
|
||||
|
||||
class column {
|
||||
public:
|
||||
column(sql_function_t func, std::string name);
|
||||
column(const char *name, std::string alias = ""); // NOLINT(*-explicit-constructor)
|
||||
column(std::string name, std::string alias = ""); // NOLINT(*-explicit-constructor)
|
||||
struct column
|
||||
{
|
||||
column(const char *name) : name(name) {} // NOLINT(*-explicit-constructor)
|
||||
column(std::string name) : name(std::move(name)) {} // NOLINT(*-explicit-constructor)
|
||||
column(sql_function_t func, std::string name) : name(std::move(name)), function_(func) {} // NOLINT(*-explicit-constructor)
|
||||
column(std::string table_name, std::string name, std::string as)
|
||||
: table(std::move(table_name))
|
||||
, name(std::move(name))
|
||||
, alias(std::move(as)) {} // NOLINT(*-explicit-constructor)
|
||||
|
||||
column(const column&) = default;
|
||||
column& operator=(const column&) = default;
|
||||
column(column&&) noexcept = default;
|
||||
column& operator=(column&&) noexcept = default;
|
||||
|
||||
template<typename Type>
|
||||
explicit column(std::string name, utils::field_attributes attr)
|
||||
: column(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr)
|
||||
{}
|
||||
|
||||
template<typename Type>
|
||||
column(std::string name, const Type &, utils::field_attributes attr, null_option null_opt)
|
||||
: column(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr, null_opt)
|
||||
{}
|
||||
|
||||
column(std::string name, data_type_t type, utils::field_attributes attr, null_option null_opt, size_t index = 0);
|
||||
|
||||
template<typename Type>
|
||||
column(std::string name, std::string ref_table, std::string ref_column, utils::field_attributes attr, null_option null_opt)
|
||||
: column(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), ref_table, ref_column, attr, null_opt)
|
||||
{}
|
||||
|
||||
column(std::string name, data_type_t type, size_t index, std::string ref_table, std::string ref_column, utils::field_attributes attr, null_option null_opt);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] size_t index() const;
|
||||
[[nodiscard]] const utils::field_attributes& attributes() const;
|
||||
[[nodiscard]] bool is_nullable() const;
|
||||
[[nodiscard]] data_type_t type() const;
|
||||
[[nodiscard]] const std::string& alias() const;
|
||||
[[nodiscard]] const std::string& ref_table() const;
|
||||
[[nodiscard]] const std::string& ref_column() const;
|
||||
|
||||
void type(data_type_t type);
|
||||
void alias(const std::string &as);
|
||||
|
||||
template< typename Type >
|
||||
[[nodiscard]] bool is_type_of() const {
|
||||
return std::holds_alternative<Type>(value_);
|
||||
column& as(std::string a) {
|
||||
alias = std::move(a);
|
||||
return *this;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string str() const;
|
||||
|
||||
template<typename Type>
|
||||
void set(const Type &value, const utils::field_attributes &attr = utils::null_attributes)
|
||||
{
|
||||
type_ = data_type_traits<Type>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
[[nodiscard]] bool is_function() const {
|
||||
return function_ != sql_function_t::NONE;
|
||||
}
|
||||
|
||||
void set(const std::string &value, const utils::field_attributes &attr)
|
||||
{
|
||||
type_ = data_type_traits<std::string>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
void set(const char *value, const utils::field_attributes &attr)
|
||||
{
|
||||
type_ = data_type_traits<std::string>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
Type as() const
|
||||
{
|
||||
const Type* ptr= std::get_if<Type>(&value_);
|
||||
if (ptr) {
|
||||
return *ptr;
|
||||
}
|
||||
any_type_to_visitor<Type> visitor;
|
||||
std::visit(visitor, const_cast<any_type&>(value_));
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool is_function() const;
|
||||
[[nodiscard]] sql_function_t function() const;
|
||||
|
||||
private:
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
op.on_attribute(name_.c_str(), value_, type_, attributes_);
|
||||
}
|
||||
|
||||
using data_type_index = std::vector<data_type_t>;
|
||||
|
||||
private:
|
||||
friend class record;
|
||||
|
||||
static const data_type_index data_type_index_;
|
||||
|
||||
std::string name_;
|
||||
size_t index_{};
|
||||
utils::field_attributes attributes_;
|
||||
null_option null_option_{null_option::NOT_NULL};
|
||||
data_type_t type_{data_type_t::type_unknown};
|
||||
any_type value_;
|
||||
std::string table;
|
||||
std::string name;
|
||||
std::string alias;
|
||||
sql_function_t function_{sql_function_t::NONE};
|
||||
std::string alias_;
|
||||
std::string ref_table_;
|
||||
std::string ref_column_;
|
||||
};
|
||||
|
||||
/**
|
||||
* User defined literal to have a shortcut creating a column object
|
||||
* @param name Name of the column
|
||||
* @param len Length of the column name
|
||||
* @return A column object with given name
|
||||
*/
|
||||
column operator "" _col(const char *name, size_t len);
|
||||
|
||||
column make_column(const std::string &name, data_type_t type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL);
|
||||
|
||||
template < typename Type >
|
||||
column make_column(const std::string &name, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL)
|
||||
{
|
||||
return make_column(name, data_type_traits<Type>::builtin_type(0), attr, null_opt);
|
||||
}
|
||||
template <>
|
||||
column make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt);
|
||||
|
||||
template < typename Type >
|
||||
column make_pk_column(const std::string &name, size_t size = 0)
|
||||
{
|
||||
return make_column<Type>(name, { size, utils::constraints::PRIMARY_KEY });
|
||||
}
|
||||
|
||||
template <>
|
||||
column make_pk_column<std::string>(const std::string &name, size_t size);
|
||||
|
||||
template < typename Type >
|
||||
column make_fk_column(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(size), ref_table, ref_column, { size, utils::constraints::FOREIGN_KEY }};
|
||||
}
|
||||
|
||||
template < typename Type >
|
||||
[[maybe_unused]] column make_fk_column(const std::string &name, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(0), 0, ref_table, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||
}
|
||||
|
||||
template <>
|
||||
column make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column);
|
||||
|
||||
}
|
||||
#endif //QUERY_COLUMN_HPP
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
#ifndef QUERY_COLUMN_DEFINITION_HPP
|
||||
#define QUERY_COLUMN_DEFINITION_HPP
|
||||
|
||||
#include "matador/sql/any_type.hpp"
|
||||
#include "matador/sql/any_type_to_visitor.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
enum class null_option : uint8_t {
|
||||
NULLABLE, NOT_NULL
|
||||
};
|
||||
|
||||
class column_definition {
|
||||
public:
|
||||
explicit column_definition(const char *name); // NOLINT(*-explicit-constructor)
|
||||
explicit column_definition(std::string name); // NOLINT(*-explicit-constructor)
|
||||
|
||||
column_definition(const column_definition&) = default;
|
||||
column_definition& operator=(const column_definition&) = default;
|
||||
column_definition(column_definition&&) noexcept = default;
|
||||
column_definition& operator=(column_definition&&) noexcept = default;
|
||||
|
||||
template<typename Type>
|
||||
explicit column_definition(std::string name, utils::field_attributes attr)
|
||||
: column_definition(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr)
|
||||
{}
|
||||
|
||||
template<typename Type>
|
||||
column_definition(std::string name, const Type &, utils::field_attributes attr, null_option null_opt)
|
||||
: column_definition(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), attr, null_opt)
|
||||
{}
|
||||
|
||||
column_definition(std::string name, data_type_t type, utils::field_attributes attr, null_option null_opt, size_t index = 0);
|
||||
|
||||
template<typename Type>
|
||||
column_definition(std::string name, std::string ref_table, std::string ref_column, utils::field_attributes attr, null_option null_opt)
|
||||
: column_definition(std::move(name), data_type_traits<Type>::builtin_type(attr.size()), ref_table, ref_column, attr, null_opt)
|
||||
{}
|
||||
|
||||
column_definition(std::string name, data_type_t type, size_t index, std::string ref_table, std::string ref_column, utils::field_attributes attr, null_option null_opt);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] size_t index() const;
|
||||
[[nodiscard]] const utils::field_attributes& attributes() const;
|
||||
[[nodiscard]] bool is_nullable() const;
|
||||
[[nodiscard]] data_type_t type() const;
|
||||
[[nodiscard]] const std::string& ref_table() const;
|
||||
[[nodiscard]] const std::string& ref_column() const;
|
||||
|
||||
void type(data_type_t type);
|
||||
|
||||
template< typename Type >
|
||||
[[nodiscard]] bool is_type_of() const {
|
||||
return std::holds_alternative<Type>(value_);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string str() const;
|
||||
|
||||
template<typename Type>
|
||||
void set(const Type &value, const utils::field_attributes &attr = utils::null_attributes)
|
||||
{
|
||||
type_ = data_type_traits<Type>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
void set(const std::string &value, const utils::field_attributes &attr)
|
||||
{
|
||||
type_ = data_type_traits<std::string>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
void set(const char *value, const utils::field_attributes &attr)
|
||||
{
|
||||
type_ = data_type_traits<std::string>::builtin_type(attr.size());
|
||||
attributes_ = attr;
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
Type as() const
|
||||
{
|
||||
const Type* ptr= std::get_if<Type>(&value_);
|
||||
if (ptr) {
|
||||
return *ptr;
|
||||
}
|
||||
any_type_to_visitor<Type> visitor;
|
||||
std::visit(visitor, const_cast<any_type&>(value_));
|
||||
return visitor.result;
|
||||
}
|
||||
|
||||
private:
|
||||
template<class Operator>
|
||||
void process(Operator &op)
|
||||
{
|
||||
op.on_attribute(name_.c_str(), value_, type_, attributes_);
|
||||
}
|
||||
|
||||
using data_type_index = std::vector<data_type_t>;
|
||||
|
||||
private:
|
||||
friend class record;
|
||||
|
||||
static const data_type_index data_type_index_;
|
||||
|
||||
std::string name_;
|
||||
size_t index_{};
|
||||
utils::field_attributes attributes_;
|
||||
null_option null_option_{null_option::NOT_NULL};
|
||||
data_type_t type_{data_type_t::type_unknown};
|
||||
any_type value_;
|
||||
std::string ref_table_;
|
||||
std::string ref_column_;
|
||||
};
|
||||
|
||||
/**
|
||||
* User defined literal to have a shortcut creating a column object
|
||||
* @param name Name of the column
|
||||
* @param len Length of the column name
|
||||
* @return A column object with given name
|
||||
*/
|
||||
column_definition make_column(const std::string &name, data_type_t type, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL);
|
||||
|
||||
template < typename Type >
|
||||
column_definition make_column(const std::string &name, utils::field_attributes attr = utils::null_attributes, null_option null_opt = null_option::NOT_NULL)
|
||||
{
|
||||
return make_column(name, data_type_traits<Type>::builtin_type(0), attr, null_opt);
|
||||
}
|
||||
template <>
|
||||
column_definition make_column<std::string>(const std::string &name, utils::field_attributes attr, null_option null_opt);
|
||||
|
||||
template < typename Type >
|
||||
column_definition make_pk_column(const std::string &name, size_t size = 0)
|
||||
{
|
||||
return make_column<Type>(name, { size, utils::constraints::PRIMARY_KEY });
|
||||
}
|
||||
|
||||
template <>
|
||||
column_definition make_pk_column<std::string>(const std::string &name, size_t size);
|
||||
|
||||
template < typename Type >
|
||||
column_definition make_fk_column(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(size), ref_table, ref_column, { size, utils::constraints::FOREIGN_KEY }};
|
||||
}
|
||||
|
||||
template < typename Type >
|
||||
[[maybe_unused]] column_definition make_fk_column(const std::string &name, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
return {name, data_type_traits<Type>::builtin_type(0), 0, ref_table, ref_column, { 0, utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||
}
|
||||
|
||||
template <>
|
||||
column_definition make_fk_column<std::string>(const std::string &name, size_t size, const std::string &ref_table, const std::string &ref_column);
|
||||
|
||||
}
|
||||
#endif //QUERY_COLUMN_DEFINITION_HPP
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef QUERY_COLUMN_GENERATOR_HPP
|
||||
#define QUERY_COLUMN_GENERATOR_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
@@ -21,10 +21,10 @@ public:
|
||||
fk_column_generator() = default;
|
||||
|
||||
template<class Type>
|
||||
column generate(const char *id, Type &x, const std::string &ref_table, const std::string &ref_column)
|
||||
column_definition generate(const char *id, Type &x, const std::string &ref_table, const std::string &ref_column)
|
||||
{
|
||||
utils::access::process(*this, x);
|
||||
return column{id, type_, 0, ref_table, ref_column, { utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||
return column_definition{id, type_, 0, ref_table, ref_column, {utils::constraints::FOREIGN_KEY }, null_option::NOT_NULL};
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
@@ -53,15 +53,15 @@ private:
|
||||
class column_generator
|
||||
{
|
||||
private:
|
||||
column_generator(std::vector<column> &columns, const schema &repo);
|
||||
column_generator(std::vector<column_definition> &columns, const schema &repo);
|
||||
|
||||
public:
|
||||
~column_generator() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<column> generate(const schema &repo)
|
||||
static std::vector<column_definition> generate(const schema &repo)
|
||||
{
|
||||
std::vector<column> columns;
|
||||
std::vector<column_definition> columns;
|
||||
column_generator gen(columns, repo);
|
||||
Type obj;
|
||||
matador::utils::access::process(gen, obj);
|
||||
@@ -101,7 +101,7 @@ private:
|
||||
|
||||
private:
|
||||
size_t index_ = 0;
|
||||
std::vector<column> &columns_;
|
||||
std::vector<column_definition> &columns_;
|
||||
const schema &repo_;
|
||||
|
||||
fk_column_generator fk_column_generator_;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
#include "matador/utils/foreign_attributes.hpp"
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include <string>
|
||||
@@ -13,29 +14,22 @@
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
struct column_info
|
||||
{
|
||||
std::string table;
|
||||
std::string name;
|
||||
std::string alias;
|
||||
};
|
||||
|
||||
class column_name_generator
|
||||
{
|
||||
private:
|
||||
column_name_generator(std::vector<column_info> &column_infos, const sql::schema &ts, const std::string &table_name);
|
||||
column_name_generator(std::vector<column> &column_infos, const sql::schema &ts, const std::string &table_name);
|
||||
|
||||
public:
|
||||
~column_name_generator() = default;
|
||||
|
||||
template < class Type >
|
||||
static std::vector<column_info> generate(const sql::schema &ts)
|
||||
static std::vector<column> generate(const sql::schema &ts)
|
||||
{
|
||||
const auto info = ts.info<Type>();
|
||||
if (!info) {
|
||||
return {};
|
||||
}
|
||||
std::vector<column_info> columns;
|
||||
std::vector<column> columns;
|
||||
column_name_generator gen(columns, ts, info.value().name);
|
||||
Type obj;
|
||||
matador::utils::access::process(gen, obj);
|
||||
@@ -93,7 +87,7 @@ private:
|
||||
|
||||
private:
|
||||
std::stack<std::string> table_name_stack_;
|
||||
std::vector<column_info> &column_infos_;
|
||||
std::vector<column> &column_infos_;
|
||||
const sql::schema &table_schema_;
|
||||
int column_index{0};
|
||||
};
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "matador/sql/query_context.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
@@ -55,8 +56,8 @@ public:
|
||||
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
return d.prepare_identifier(field_.name()) + " " + operand + " " + std::to_string(value);
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_.name) + " " + operand + " " + std::to_string(value);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -75,8 +76,8 @@ public:
|
||||
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
return d.prepare_identifier(field_.name()) + " " + operand + " '" + value + "'";
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_.name) + " " + operand + " '" + value + "'";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -96,7 +97,7 @@ public:
|
||||
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
return std::to_string(value) + " " + operand + " " + d.prepare_identifier(field_.name());
|
||||
return std::to_string(value) + " " + operand + " " + d.prepare_identifier(field_.name);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -115,7 +116,7 @@ public:
|
||||
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
return "'" + std::to_string(value) + "' " + operand + " " + d.prepare_identifier(field_.name());
|
||||
return "'" + std::to_string(value) + "' " + operand + " " + d.prepare_identifier(field_.name);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -158,10 +159,10 @@ public:
|
||||
std::string evaluate(dialect &d, query_context &query) const override {
|
||||
auto count = size();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
}
|
||||
|
||||
std::string result = d.prepare_identifier(field_.name()) + " IN (";
|
||||
std::string result = d.prepare_identifier(field_.name) + " IN (";
|
||||
if (args_.size() < 2) {
|
||||
for (const auto &val : args_) {
|
||||
result.append(std::to_string(val));
|
||||
@@ -261,9 +262,9 @@ public:
|
||||
* @return A condition BETWEEN part of the query
|
||||
*/
|
||||
std::string evaluate(dialect &d, query_context &query) const override {
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
query.bind_vars.emplace_back(field_.name());
|
||||
return d.prepare_identifier(field_.name()) + " BETWEEN " + std::to_string(range_.first) + " AND " + std::to_string(range_.second);
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_.name) + " BETWEEN " + std::to_string(range_.first) + " AND " + std::to_string(range_.second);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -355,6 +356,28 @@ private:
|
||||
std::string operand;
|
||||
};
|
||||
|
||||
template<>
|
||||
class condition<column, column> : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
condition(const column &a, basic_condition::operand_t op, column b)
|
||||
: basic_column_condition(a, op)
|
||||
, other_column_(std::move(b)) {}
|
||||
/**
|
||||
* @brief Evaluates the condition
|
||||
*
|
||||
* @param d The d used to evaluate
|
||||
* @return The evaluated string based on the compile type
|
||||
*/
|
||||
std::string evaluate(dialect &d, query_context &query) const override
|
||||
{
|
||||
return d.prepare_identifier(field_.name) + " " + operand + " " + d.prepare_identifier(other_column_.name);
|
||||
}
|
||||
|
||||
private:
|
||||
column other_column_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @file condition.hpp
|
||||
* @brief Contains functions to create query conditions
|
||||
@@ -441,6 +464,8 @@ condition<column, T> operator==(const column &col, T val)
|
||||
return condition<column, T>(col, basic_condition::operand_t::EQUAL, val);
|
||||
}
|
||||
|
||||
condition<column, column> operator==(const column &a, const column &b);
|
||||
|
||||
/**
|
||||
* @brief Condition equality method for a column and a query
|
||||
*
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
#include "matador/sql/connection_info.hpp"
|
||||
#include "matador/sql/connection_impl.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
#include "matador/sql/query_intermediates.hpp"
|
||||
#include "matador/sql/query.hpp"
|
||||
#include "matador/sql/query_context.hpp"
|
||||
#include "matador/sql/query_result.hpp"
|
||||
#include "matador/sql/record.hpp"
|
||||
#include "matador/sql/statement.hpp"
|
||||
#include "matador/sql/schema.hpp"
|
||||
|
||||
#include "matador/utils/logger.hpp"
|
||||
|
||||
@@ -19,8 +20,8 @@ namespace matador::sql {
|
||||
class connection
|
||||
{
|
||||
public:
|
||||
explicit connection(connection_info info, const std::shared_ptr<schema> &repo = std::make_shared<schema>());
|
||||
explicit connection(const std::string& dns, const std::shared_ptr<schema> &repo = std::make_shared<schema>());
|
||||
explicit connection(connection_info info, const std::shared_ptr<schema> &repo = std::make_shared<sql::schema>());
|
||||
explicit connection(const std::string& dns, const std::shared_ptr<schema> &repo = std::make_shared<sql::schema>());
|
||||
connection(const connection &x);
|
||||
connection& operator=(const connection &x);
|
||||
connection(connection &&x) noexcept = default;
|
||||
@@ -31,19 +32,12 @@ public:
|
||||
[[nodiscard]] bool is_open() const;
|
||||
[[nodiscard]] const connection_info& info() const;
|
||||
|
||||
query_create_intermediate create();
|
||||
query_drop_intermediate drop();
|
||||
template < class Type >
|
||||
query_select_intermediate select();
|
||||
query_select_intermediate select(std::initializer_list<column> columns);
|
||||
query_insert_intermediate insert();
|
||||
query_update_intermediate update(const std::string &table);
|
||||
query_delete_intermediate remove();
|
||||
|
||||
[[nodiscard]] record describe(const std::string &table_name) const;
|
||||
[[nodiscard]] bool exists(const std::string &schema_name, const std::string &table_name) const;
|
||||
[[nodiscard]] bool exists(const std::string &table_name) const;
|
||||
|
||||
sql::query query() const;
|
||||
|
||||
query_result<record> fetch(const query_context &q) const;
|
||||
[[nodiscard]] std::unique_ptr<query_result_impl> fetch(const std::string &sql) const;
|
||||
[[nodiscard]] size_t execute(const std::string &sql) const;
|
||||
@@ -51,21 +45,15 @@ public:
|
||||
statement prepare(query_context &&query) const;
|
||||
|
||||
const class dialect& dialect() const;
|
||||
std::shared_ptr<schema> tables() const;
|
||||
std::shared_ptr<sql::schema> schema() const;
|
||||
|
||||
private:
|
||||
connection_info connection_info_;
|
||||
std::unique_ptr<connection_impl> connection_;
|
||||
utils::logger logger_;
|
||||
const class dialect &dialect_;
|
||||
std::shared_ptr<schema> schema_;
|
||||
std::shared_ptr<sql::schema> schema_;
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
query_select_intermediate connection::select()
|
||||
{
|
||||
return query_select_intermediate{*this, column_generator::generate<Type>(*schema_)};
|
||||
}
|
||||
|
||||
}
|
||||
#endif //QUERY_CONNECTION_HPP
|
||||
|
||||
@@ -41,16 +41,6 @@ enum class data_type_t : uint8_t {
|
||||
type_unknown /*!< Data type unknown */
|
||||
};
|
||||
|
||||
enum class sql_function_t {
|
||||
NONE,
|
||||
COUNT,
|
||||
AVG,
|
||||
SUM,
|
||||
MIN,
|
||||
MAX
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @tparam T The type of the traits
|
||||
* @brief Type traits for database types
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifndef QUERY_DIALECT_HPP
|
||||
#define QUERY_DIALECT_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/data_type_traits.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
@@ -11,8 +12,6 @@
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class column;
|
||||
|
||||
class dialect final
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef QUERY_QUERY_HPP
|
||||
#define QUERY_QUERY_HPP
|
||||
|
||||
#include "matador/sql/query_intermediates.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class connection;
|
||||
|
||||
class query
|
||||
{
|
||||
public:
|
||||
explicit query(connection &c);
|
||||
query(const query &) = delete;
|
||||
query& operator=(const query &) = delete;
|
||||
|
||||
query_create_intermediate create();
|
||||
query_drop_intermediate drop();
|
||||
template < class Type >
|
||||
query_select_intermediate select();
|
||||
template < class Type >
|
||||
query_select_intermediate select(std::initializer_list<column> columns);
|
||||
query_select_intermediate select(std::initializer_list<column> columns);
|
||||
query_insert_intermediate insert();
|
||||
query_update_intermediate update(const std::string &table);
|
||||
query_delete_intermediate remove();
|
||||
|
||||
private:
|
||||
[[nodiscard]] const sql::schema& schema() const;
|
||||
|
||||
private:
|
||||
connection &connection_;
|
||||
};
|
||||
|
||||
template<class Type>
|
||||
query_select_intermediate query::select()
|
||||
{
|
||||
return query_select_intermediate{connection_, column_name_generator::generate<Type>(this->schema())};
|
||||
}
|
||||
|
||||
template<class Type>
|
||||
query_select_intermediate query::select(std::initializer_list<column> columns)
|
||||
{
|
||||
return query_select_intermediate{connection_, column_name_generator::generate<Type>(this->schema())};
|
||||
}
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_HPP
|
||||
@@ -2,6 +2,7 @@
|
||||
#define QUERY_QUERY_BUILDER_HPP
|
||||
|
||||
#include "matador/sql/basic_condition.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
#include "matador/sql/key_value_pair.hpp"
|
||||
@@ -123,11 +124,11 @@ public:
|
||||
query_builder& update(const std::string &table);
|
||||
query_builder& remove();
|
||||
|
||||
query_builder& table(const std::string &table, std::initializer_list<column> columns);
|
||||
query_builder& table(const std::string &table, const std::vector<column> &columns);
|
||||
query_builder& table(const std::string &table, std::initializer_list<column_definition> columns);
|
||||
query_builder& table(const std::string &table, const std::vector<column_definition> &columns);
|
||||
query_builder& table(const std::string &table);
|
||||
query_builder& into(const std::string &table, std::initializer_list<column_info> column_names);
|
||||
query_builder& into(const std::string &table, const std::vector<column_info> &column_names);
|
||||
query_builder& into(const std::string &table, std::initializer_list<column> column_names);
|
||||
query_builder& into(const std::string &table, const std::vector<column> &column_names);
|
||||
query_builder& values(std::initializer_list<any_type> values);
|
||||
query_builder& values(const std::vector<any_type> &values);
|
||||
query_builder& from(const std::string &table, const std::string &as = "");
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef QUERY_QUERY_COMPILER_HPP
|
||||
#define QUERY_QUERY_COMPILER_HPP
|
||||
|
||||
#include "matador/sql/query_part_visitor.hpp"
|
||||
#include "matador/sql/query_parts.hpp"
|
||||
#include "matador/sql/query_context.hpp"
|
||||
|
||||
#include <typeindex>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class dialect;
|
||||
|
||||
struct query_data;
|
||||
|
||||
class query_compiler : public query_part_visitor
|
||||
{
|
||||
public:
|
||||
explicit query_compiler(const sql::dialect& d);
|
||||
|
||||
query_context compile(const query_data *data);
|
||||
|
||||
private:
|
||||
void visit(query_select_part &select_part) override;
|
||||
void visit(query_from_part &from_part) override;
|
||||
void visit(query_where_part &where_part) override;
|
||||
void visit(query_group_by_part &group_by_part) override;
|
||||
void visit(query_order_by_part &order_by_part) override;
|
||||
void visit(query_order_by_asc_part &order_by_asc_part) override;
|
||||
void visit(query_order_by_desc_part &order_by_desc_part) override;
|
||||
|
||||
void visit(query_insert_part &insert_part) override;
|
||||
void visit(query_values_part &values_part) override;
|
||||
|
||||
void visit(query_update_part &update_part) override;
|
||||
|
||||
void visit(query_delete_part &delete_part) override;
|
||||
|
||||
void visit(query_create_part &create_part) override;
|
||||
|
||||
void visit(query_drop_part &drop_part) override;
|
||||
|
||||
private:
|
||||
const sql::dialect &dialect_;
|
||||
query_context query_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_COMPILER_HPP
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef QUERY_QUERY_DATA_HPP
|
||||
#define QUERY_QUERY_DATA_HPP
|
||||
|
||||
#include "matador/sql/query_parts.hpp"
|
||||
#include "matador/sql/table.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
struct query_data
|
||||
{
|
||||
// SqlCommands command;
|
||||
std::vector<std::unique_ptr<query_part>> parts;
|
||||
std::vector<column_definition> columns;
|
||||
std::unordered_map<std::type_index, table> table_map_by_index;
|
||||
using table_ref = std::reference_wrapper<table>;
|
||||
std::unordered_map<std::string, table_ref> table_map_by_name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_DATA_HPP
|
||||
@@ -1,14 +1,14 @@
|
||||
#ifndef QUERY_QUERY_INTERMEDIATES_HPP
|
||||
#define QUERY_QUERY_INTERMEDIATES_HPP
|
||||
|
||||
#include "matador/sql/column.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_builder.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"
|
||||
@@ -36,10 +36,10 @@ protected:
|
||||
class query_intermediate : public basic_query_intermediate
|
||||
{
|
||||
public:
|
||||
query_intermediate(connection &db, query_builder &query);
|
||||
query_intermediate(connection &db, query_data &data);
|
||||
|
||||
protected:
|
||||
query_builder &builder_;
|
||||
query_data &data_;
|
||||
};
|
||||
|
||||
class query_execute_finish : public query_intermediate
|
||||
@@ -146,7 +146,7 @@ class query_join_intermediate : public query_intermediate
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_on_intermediate on(const std::string &column, const std::string &join_column);
|
||||
query_on_intermediate on(const basic_condition &cond);
|
||||
};
|
||||
|
||||
class query_from_intermediate : public query_select_finish
|
||||
@@ -154,7 +154,7 @@ class query_from_intermediate : public query_select_finish
|
||||
public:
|
||||
using query_select_finish::query_select_finish;
|
||||
|
||||
query_join_intermediate join(const std::string &join_table_name, const std::string &as);
|
||||
query_join_intermediate join_left(const std::string &join_table_name, const std::string &as = "");
|
||||
query_where_intermediate where(const basic_condition &cond);
|
||||
query_group_by_intermediate group_by(const std::string &name);
|
||||
query_order_by_intermediate order_by(const std::string &name);
|
||||
@@ -163,10 +163,10 @@ public:
|
||||
class query_start_intermediate : public basic_query_intermediate
|
||||
{
|
||||
public:
|
||||
explicit query_start_intermediate(connection &s);
|
||||
explicit query_start_intermediate(connection &db);
|
||||
|
||||
protected:
|
||||
query_builder builder_;
|
||||
query_data data_;
|
||||
};
|
||||
|
||||
class query_select_intermediate : public query_start_intermediate
|
||||
@@ -192,16 +192,19 @@ 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;
|
||||
return {connection_, builder_.values(as_placeholder(obj))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.values(as_placeholder(obj))};
|
||||
}
|
||||
template<class Type>
|
||||
query_execute_finish values(const Type &obj)
|
||||
{
|
||||
return {connection_, builder_.values(value_extractor::extract(obj))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.values(value_extractor::extract(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -210,15 +213,16 @@ class query_create_intermediate : public query_start_intermediate
|
||||
public:
|
||||
explicit query_create_intermediate(connection &db);
|
||||
|
||||
query_execute_finish table(const std::string &table_name, std::initializer_list<column> columns);
|
||||
query_execute_finish table(const std::string &table_name, const std::vector<column> &columns);
|
||||
query_execute_finish table(const std::string &table_name, std::initializer_list<column_definition> columns);
|
||||
query_execute_finish table(const std::string &table_name, const std::vector<column_definition> &columns);
|
||||
template<class Type>
|
||||
query_execute_finish table(const std::string &table_name)
|
||||
{
|
||||
if (!tables()->exists<Type>()) {
|
||||
tables()->attach<Type>(table_name);
|
||||
}
|
||||
return {connection_, builder_.table(table_name, column_generator::generate<Type>(*tables()))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.table(table_name, column_generator::generate<Type>(*tables()))};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -235,17 +239,19 @@ class query_insert_intermediate : public query_start_intermediate
|
||||
public:
|
||||
explicit query_insert_intermediate(connection &s);
|
||||
|
||||
query_into_intermediate into(const std::string &table, std::initializer_list<column_info> column_names);
|
||||
query_into_intermediate into(const std::string &table, std::initializer_list<column> column_names);
|
||||
template<class Type>
|
||||
query_into_intermediate into(const std::string &table)
|
||||
{
|
||||
return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))};
|
||||
}
|
||||
template<class Type>
|
||||
query_execute_finish into(const std::string &table, const Type &obj)
|
||||
{
|
||||
return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))
|
||||
.values(value_extractor::extract(obj))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.into(table, column_name_generator::generate<Type>(*tables()))
|
||||
// .values(value_extractor::extract(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
@@ -274,7 +280,8 @@ public:
|
||||
template<class Type>
|
||||
query_set_intermediate set(const Type &obj)
|
||||
{
|
||||
return {connection_, builder_.set(key_value_generator::generate(obj))};
|
||||
return {connection_, data_};
|
||||
// return {connection_, builder_.set(key_value_generator::generate(obj))};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
#ifndef QUERY_QUERY_PART_VISITOR_HPP
|
||||
#define QUERY_QUERY_PART_VISITOR_HPP
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class query_select_part;
|
||||
class query_from_part;
|
||||
class query_where_part;
|
||||
class query_group_by_part;
|
||||
class query_order_by_part;
|
||||
class query_order_by_asc_part;
|
||||
class query_order_by_desc_part;
|
||||
class query_insert_part;
|
||||
class query_values_part;
|
||||
class query_update_part;
|
||||
class query_delete_part;
|
||||
class query_create_part;
|
||||
class query_drop_part;
|
||||
|
||||
class query_part_visitor
|
||||
{
|
||||
public:
|
||||
virtual ~query_part_visitor() = default;
|
||||
|
||||
virtual void visit(query_select_part &select_part) = 0;
|
||||
virtual void visit(query_from_part &from_part) = 0;
|
||||
virtual void visit(query_where_part &where_part) = 0;
|
||||
virtual void visit(query_group_by_part &group_by_part) = 0;
|
||||
virtual void visit(query_order_by_part &order_by_part) = 0;
|
||||
virtual void visit(query_order_by_asc_part &order_by_asc_part) = 0;
|
||||
virtual void visit(query_order_by_desc_part &order_by_desc_part) = 0;
|
||||
|
||||
virtual void visit(query_insert_part &insert_part) = 0;
|
||||
virtual void visit(query_values_part &values_part) = 0;
|
||||
|
||||
virtual void visit(query_update_part &update_part) = 0;
|
||||
|
||||
virtual void visit(query_delete_part &delete_part) = 0;
|
||||
|
||||
virtual void visit(query_create_part &create_part) = 0;
|
||||
virtual void visit(query_drop_part &drop_part) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_PART_VISITOR_HPP
|
||||
@@ -0,0 +1,181 @@
|
||||
#ifndef QUERY_QUERY_PARTS_HPP
|
||||
#define QUERY_QUERY_PARTS_HPP
|
||||
|
||||
#include "matador/sql/query_part_visitor.hpp"
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
class basic_condition;
|
||||
|
||||
class query_part
|
||||
{
|
||||
protected:
|
||||
explicit query_part(sql::dialect::token_t token);
|
||||
|
||||
public:
|
||||
virtual ~query_part() = default;
|
||||
virtual void accept(query_part_visitor &visitor) = 0;
|
||||
|
||||
protected:
|
||||
sql::dialect::token_t token_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL SELECT part
|
||||
*/
|
||||
class query_select_part : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_select_part(std::vector<column> columns);
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
[[nodiscard]] const std::vector<column>& columns() const;
|
||||
|
||||
private:
|
||||
std::vector<column> columns_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL FROM part
|
||||
*/
|
||||
class query_from_part : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_from_part(std::string table_name);
|
||||
query_from_part(std::string table_name, std::string as);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::string table_;
|
||||
std::string alias_;
|
||||
};
|
||||
|
||||
class query_where_part : public query_part
|
||||
{
|
||||
public:
|
||||
template < class Condition >
|
||||
explicit query_where_part(const Condition &cond)
|
||||
: query_part(dialect::token_t::WHERE)
|
||||
, condition_(new Condition(cond)) {}
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<basic_condition> condition_;
|
||||
};
|
||||
|
||||
class query_table_name_part : public query_part
|
||||
{
|
||||
protected:
|
||||
explicit query_table_name_part(sql::dialect::token_t token, std::string table_name);
|
||||
|
||||
protected:
|
||||
std::string table_name_;
|
||||
};
|
||||
|
||||
class query_group_by_part : public query_table_name_part
|
||||
{
|
||||
public:
|
||||
explicit query_group_by_part(const std::string &table_name);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_order_by_part : public query_table_name_part
|
||||
{
|
||||
public:
|
||||
explicit query_order_by_part(const std::string &table_name);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_order_by_asc_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_order_by_asc_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_order_by_desc_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_order_by_desc_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_insert_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_insert_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL VALUES part
|
||||
*/
|
||||
class query_values_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_values_part(std::initializer_list<any_type> values);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::vector<any_type> values_;
|
||||
};
|
||||
|
||||
class query_update_part : public query_table_name_part
|
||||
{
|
||||
public:
|
||||
explicit query_update_part(const std::string &table_name);
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_delete_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_delete_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_create_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_create_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_drop_part : public query_part
|
||||
{
|
||||
public:
|
||||
query_drop_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PARTS_HPP
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <unordered_map>
|
||||
@@ -13,8 +13,8 @@ namespace matador::sql {
|
||||
class record
|
||||
{
|
||||
private:
|
||||
using column_by_index = std::vector<column>;
|
||||
using column_index_pair = std::pair<std::reference_wrapper<column>, size_t>;
|
||||
using column_by_index = std::vector<column_definition>;
|
||||
using column_index_pair = std::pair<std::reference_wrapper<column_definition>, size_t>;
|
||||
using column_by_name_map = std::unordered_map<std::string, column_index_pair>;
|
||||
|
||||
public:
|
||||
@@ -22,8 +22,8 @@ public:
|
||||
using const_iterator = column_by_index::const_iterator;
|
||||
|
||||
record() = default;
|
||||
record(std::initializer_list<column> columns);
|
||||
explicit record(const std::vector<column> &columns);
|
||||
record(std::initializer_list<column_definition> columns);
|
||||
explicit record(const std::vector<column_definition> &columns);
|
||||
record(const record &x);
|
||||
record& operator=(const record &x);
|
||||
record(record&&) noexcept = default;
|
||||
@@ -43,15 +43,15 @@ public:
|
||||
append(make_column<Type>(name, size));
|
||||
}
|
||||
|
||||
void append(column col);
|
||||
void append(column_definition col);
|
||||
|
||||
[[nodiscard]] bool has_primary_key() const;
|
||||
[[nodiscard]] const column& primary_key() const;
|
||||
[[nodiscard]] const column_definition& primary_key() const;
|
||||
|
||||
[[nodiscard]] const std::vector<column>& columns() const;
|
||||
[[nodiscard]] const std::vector<column_definition>& columns() const;
|
||||
|
||||
[[nodiscard]] const column& at(const std::string &name) const;
|
||||
[[nodiscard]] const column& at(size_t index) const;
|
||||
[[nodiscard]] const column_definition& at(const std::string &name) const;
|
||||
[[nodiscard]] const column_definition& at(size_t index) const;
|
||||
|
||||
iterator find(const std::string &column_name);
|
||||
[[nodiscard]] const_iterator find(const std::string &column_name) const;
|
||||
@@ -72,7 +72,7 @@ public:
|
||||
|
||||
private:
|
||||
void init();
|
||||
void add_to_map(column &col, size_t index);
|
||||
void add_to_map(column_definition &col, size_t index);
|
||||
|
||||
private:
|
||||
column_by_index columns_;
|
||||
|
||||
@@ -28,6 +28,8 @@ public:
|
||||
using iterator = repository::iterator;
|
||||
using const_iterator = repository::const_iterator;
|
||||
|
||||
std::string name() const;
|
||||
|
||||
template<typename Type>
|
||||
const table_info& attach(const std::string &table_name)
|
||||
{
|
||||
@@ -68,6 +70,7 @@ public:
|
||||
[[nodiscard]] bool empty() const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
repository repository_;
|
||||
};
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ entity<Type> session::insert(Type *obj)
|
||||
if (!info) {
|
||||
return {};
|
||||
}
|
||||
c->insert().into<Type>(info->name).values(*obj).execute();
|
||||
c->query().insert().into<Type>(info->name).values(*obj).execute();
|
||||
|
||||
return entity{obj};
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#ifndef QUERY_TABLE_HPP
|
||||
#define QUERY_TABLE_HPP
|
||||
|
||||
#include <typeindex>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
|
||||
struct table
|
||||
{
|
||||
std::type_index index;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_TABLE_HPP
|
||||
@@ -38,7 +38,7 @@ std::string to_string(const blob &data);
|
||||
* given stream
|
||||
*
|
||||
* @tparam R Type og the range (e.g. map, list, vector, etc)
|
||||
* @param range The range with the elements to join
|
||||
* @param range The range with the elements to join_left
|
||||
* @param delim The delimiter for the elements
|
||||
* @return The ostream reference
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user