initial matador ng commit
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
#ifndef ATTRIBUTE_STRING_WRITER_HPP
|
||||
#define ATTRIBUTE_STRING_WRITER_HPP
|
||||
|
||||
#include "matador/utils/attribute_writer.hpp"
|
||||
|
||||
#include <optional>
|
||||
|
||||
namespace matador::sql {
|
||||
class dialect;
|
||||
class connection_impl;
|
||||
}
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class attribute_string_writer final : public utils::attribute_writer
|
||||
{
|
||||
public:
|
||||
attribute_string_writer(const sql::dialect &d, std::optional<std::reference_wrapper<const sql::connection_impl>> conn);
|
||||
|
||||
template<typename Type>
|
||||
[[nodiscard]] std::string to_string(const Type &value)
|
||||
{
|
||||
result_.clear();
|
||||
write_value(0, value);
|
||||
|
||||
return result_;
|
||||
}
|
||||
[[nodiscard]] const sql::dialect& dialect() const;
|
||||
|
||||
void write_value(size_t pos, const int8_t& x) override;
|
||||
void write_value(size_t pos, const int16_t& x) override;
|
||||
void write_value(size_t pos, const int32_t& x) override;
|
||||
void write_value(size_t pos, const int64_t& x) override;
|
||||
void write_value(size_t pos, const uint8_t& x) override;
|
||||
void write_value(size_t pos, const uint16_t& x) override;
|
||||
void write_value(size_t pos, const uint32_t& x) override;
|
||||
void write_value(size_t pos, const uint64_t& x) override;
|
||||
void write_value(size_t pos, const bool& x) override;
|
||||
void write_value(size_t pos, const float& x) override;
|
||||
void write_value(size_t pos, const double& x) override;
|
||||
void write_value(size_t pos, const time& x) override;
|
||||
void write_value(size_t pos, const date& x) override;
|
||||
void write_value(size_t pos, const char* x) override;
|
||||
void write_value(size_t pos, const char* x, size_t size) override;
|
||||
void write_value(size_t pos, const std::string& x) override;
|
||||
void write_value(size_t pos, const std::string& x, size_t size) override;
|
||||
void write_value(size_t pos, const utils::blob& x) override;
|
||||
void write_value(size_t pos, const utils::value& x, size_t size) override;
|
||||
|
||||
private:
|
||||
std::string result_;
|
||||
const sql::dialect &dialect_;
|
||||
std::optional<std::reference_wrapper<const sql::connection_impl>> conn_;
|
||||
};
|
||||
|
||||
// "This is a binary Data string" as binary data:
|
||||
// MySQL: X'5468697320697320612062616E617279204461746120737472696E67'
|
||||
// Postgres: E'\\x5468697320697320612062616E617279204461746120737472696E67'
|
||||
// MSSQL: 0x5468697320697320612062616E617279204461746120737472696E67
|
||||
// Sqlite: X'5468697320697320612062616E617279204461746120737472696E67'
|
||||
|
||||
}
|
||||
#endif //ATTRIBUTE_STRING_WRITER_HPP
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef QUERY_BASIC_CONDITION_HPP
|
||||
#define QUERY_BASIC_CONDITION_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace matador::sql {
|
||||
class dialect;
|
||||
struct query_context;
|
||||
}
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class basic_condition
|
||||
{
|
||||
public:
|
||||
basic_condition() = default;
|
||||
virtual ~basic_condition() = default;
|
||||
|
||||
enum class operand_type : uint8_t
|
||||
{
|
||||
EQUAL = 0,
|
||||
NOT_EQUAL,
|
||||
LESS,
|
||||
LESS_EQUAL,
|
||||
GREATER,
|
||||
GREATER_EQUAL,
|
||||
OR,
|
||||
AND,
|
||||
NOT,
|
||||
IN_LIST,
|
||||
LIKE
|
||||
};
|
||||
|
||||
virtual std::string evaluate(const sql::dialect &dialect, sql::query_context &query) const = 0;
|
||||
|
||||
static std::unordered_map<operand_type, std::string> operands;
|
||||
};
|
||||
|
||||
class basic_column_condition : public basic_condition
|
||||
{
|
||||
public:
|
||||
sql::column field_;
|
||||
std::string operand;
|
||||
|
||||
basic_column_condition(sql::column fld, operand_type op);
|
||||
};
|
||||
|
||||
class basic_in_condition : public basic_condition
|
||||
{
|
||||
public:
|
||||
sql::column field_;
|
||||
|
||||
explicit basic_in_condition(sql::column fld);
|
||||
|
||||
[[nodiscard]] virtual size_t size() const = 0;
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_BASIC_CONDITION_HPP
|
||||
@@ -0,0 +1,635 @@
|
||||
#ifndef QUERY_CONDITION_HPP
|
||||
#define QUERY_CONDITION_HPP
|
||||
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/sql/dialect.hpp"
|
||||
#include "matador/sql/query_context.hpp"
|
||||
|
||||
#include "matador/utils/placeholder.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
/**
|
||||
* @class condition
|
||||
* @brief Represents a sql query condition
|
||||
*
|
||||
* @tparam L Left hand operator type
|
||||
* @tparam R Right hand operator type
|
||||
* This class represents a condition part
|
||||
* of a sql query or update statement.
|
||||
* Each compare method returns a reference to
|
||||
* the condition itself. That way one can
|
||||
* concatenate conditions together.
|
||||
*/
|
||||
|
||||
/// @cond MATADOR_DEV
|
||||
|
||||
template<class L, class R, class Enabled = void>
|
||||
class condition;
|
||||
|
||||
template<>
|
||||
class condition<sql::column, utils::placeholder, std::enable_if_t<true>> final : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
condition(const sql::column &fld, operand_type op, const utils::placeholder &val);
|
||||
|
||||
utils::placeholder value;
|
||||
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override;
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class condition<sql::column, T, std::enable_if_t<
|
||||
std::is_scalar_v<T> &&
|
||||
!std::is_same_v<std::string, T> &&
|
||||
!std::is_same_v<const char*, T>>> final : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
condition(const sql::column &fld, const operand_type op, T val)
|
||||
: basic_column_condition(fld, op)
|
||||
, value(val)
|
||||
{ }
|
||||
|
||||
T value;
|
||||
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override
|
||||
{
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_condition(field_) + " " + operand + " " + std::to_string(value);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class condition<sql::column, T, std::enable_if_t<
|
||||
std::is_same_v<std::string, T> ||
|
||||
std::is_same_v<const char*, T>>>final : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
condition(const sql::column &fld, const operand_type op, T val)
|
||||
: basic_column_condition(fld, op)
|
||||
,value(val)
|
||||
{ }
|
||||
|
||||
T value;
|
||||
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override
|
||||
{
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_) + " " + operand + " '" + value + "'";
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class condition<T, sql::column, std::enable_if_t<
|
||||
std::is_scalar_v<T> &&
|
||||
!std::is_same_v<std::string, T> &&
|
||||
!std::is_same_v<const char*, T>>> final : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
condition(T val, const operand_type op, const sql::column &fld)
|
||||
: basic_column_condition(fld, op)
|
||||
, value(val)
|
||||
{ }
|
||||
|
||||
T value;
|
||||
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override
|
||||
{
|
||||
return std::to_string(value) + " " + operand + " " + d.prepare_identifier(field_);
|
||||
}
|
||||
};
|
||||
|
||||
template<class T>
|
||||
class condition<T, sql::column, std::enable_if_t<
|
||||
std::is_same_v<std::string, T> ||
|
||||
std::is_same_v<const char*, T>>> final : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
condition(T val, const operand_type op, const sql::column &fld)
|
||||
: basic_column_condition(fld, op)
|
||||
, value(val)
|
||||
{ }
|
||||
|
||||
T value;
|
||||
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override
|
||||
{
|
||||
return "'" + std::to_string(value) + "' " + operand + " " + d.prepare_identifier(field_);
|
||||
}
|
||||
};
|
||||
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* @brief Condition class representing an IN condition
|
||||
*
|
||||
* This class represents an query IN condition and evaluates to
|
||||
* this condition based on the current database d
|
||||
*
|
||||
* @code
|
||||
* WHERE age IN (29,34,56)
|
||||
* @endcode
|
||||
*/
|
||||
template < class V >
|
||||
class condition<sql::column, std::initializer_list<V>> final : public basic_in_condition {
|
||||
public:
|
||||
/**
|
||||
* @brief Creates an IN condition
|
||||
*
|
||||
* Creates an IN condition for the given sql::column and
|
||||
* the given list of arguments.
|
||||
*
|
||||
* @param col Column for the IN condition
|
||||
* @param args List of arguments
|
||||
*/
|
||||
condition(const sql::column &col, const std::initializer_list<V> &args)
|
||||
: basic_in_condition(col), args_(args) {}
|
||||
|
||||
/**
|
||||
* @brief Evaluates the condition
|
||||
*
|
||||
* Evaluates the condition to a part of the
|
||||
* query string based on the given compile type
|
||||
*
|
||||
* @param d The d used to evaluate
|
||||
* @param query Query to evaluate
|
||||
* @return A condition IN part of the query
|
||||
*/
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override {
|
||||
auto count = size();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
}
|
||||
|
||||
std::string result = d.prepare_identifier(field_) + " IN (";
|
||||
if (args_.size() < 2) {
|
||||
for (const auto &val : args_) {
|
||||
result.append(std::to_string(val));
|
||||
}
|
||||
} else {
|
||||
auto it = args_.begin();
|
||||
result.append(std::to_string(*it++));
|
||||
for(; it != args_.end(); ++it) {
|
||||
result.append(", " + std::to_string(*it));
|
||||
}
|
||||
}
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the number of arguments in the list
|
||||
* @return The number of arguments in the list
|
||||
*/
|
||||
[[nodiscard]] size_t size() const override {
|
||||
return args_.size();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<V> args_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Condition class representing an IN condition
|
||||
*
|
||||
* This class represents a query IN condition and evaluates to
|
||||
* this condition based on the current database d
|
||||
*
|
||||
* @code
|
||||
* WHERE age IN (select age_value from table)
|
||||
* @endcode
|
||||
*/
|
||||
template <>
|
||||
class condition<sql::column, sql::query_context> final : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a query IN condition
|
||||
*
|
||||
* Create an IN condition where the argument values come from
|
||||
* the given query. To evaluate the query a sql d must be
|
||||
* given.
|
||||
*
|
||||
* @param col Column for the IN condition
|
||||
* @param op Operand of the condition
|
||||
* @param q The query to be evaluated to the IN arguments
|
||||
*/
|
||||
condition(sql::column col, operand_type op, sql::query_context &q);
|
||||
|
||||
/**
|
||||
* @brief Evaluates the condition
|
||||
*
|
||||
* Evaluates the condition to a part of the
|
||||
* query string based on the given compile type
|
||||
*
|
||||
* @param d The d used to evaluate
|
||||
* @param query Query to evaluate
|
||||
* @return A condition IN part of the query
|
||||
*/
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override;
|
||||
|
||||
private:
|
||||
sql::query_context &query_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Between condition.
|
||||
*
|
||||
* The condition represents a between where clause
|
||||
* part.
|
||||
*
|
||||
* @tparam T The type of the boundary values
|
||||
*/
|
||||
template < class T >
|
||||
class condition<sql::column, std::pair<T, T>> final : public basic_condition {
|
||||
public:
|
||||
/**
|
||||
* @brief Create a new between condition
|
||||
*
|
||||
* @param col The column for the range check
|
||||
* @param range The boundary values defining the range
|
||||
*/
|
||||
condition(sql::column col, const std::pair<T, T> &range)
|
||||
: field_(std::move(col)), range_(range) {}
|
||||
|
||||
/**
|
||||
* @brief Evaluates the condition
|
||||
*
|
||||
* Evaluates the condition to a between part
|
||||
* based on the given compile type
|
||||
*
|
||||
* @param d The d used to evaluate
|
||||
* @param query Query to evaluate
|
||||
* @return A condition BETWEEN part of the query
|
||||
*/
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override {
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_) + " BETWEEN " + std::to_string(range_.first) + " AND " + std::to_string(range_.second);
|
||||
}
|
||||
|
||||
private:
|
||||
sql::column field_;
|
||||
std::pair<T, T> range_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Logical binary condition
|
||||
*
|
||||
* This class represents a logical binary condition
|
||||
* - AND
|
||||
* - OR
|
||||
*
|
||||
* @tparam L1 The left hand type of the left operator
|
||||
* @tparam R1 The right hand type of the left operator
|
||||
* @tparam L2 The left hand type of the right operator
|
||||
* @tparam R2 The right hand type of the right operator
|
||||
*/
|
||||
template<class L1, class R1, class L2, class R2>
|
||||
class condition<condition<L1, R1>, condition<L2, R2>> final : public basic_condition
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a binary logical condition
|
||||
* @param l Left hand operator of the condition
|
||||
* @param r right hand operator of the condition
|
||||
* @param op The operand (AND or OR)
|
||||
*/
|
||||
condition(condition<L1, R1> &&l, condition<L2, R2> &&r, const operand_type op)
|
||||
: left(std::move(l)), right(std::move(r)), operand(op) { }
|
||||
|
||||
/**
|
||||
* @brief Evaluates the condition
|
||||
*
|
||||
* @param d The d used to evaluate
|
||||
* @param query Query to evaluate
|
||||
* @return The evaluated string based on the compile type
|
||||
*/
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override
|
||||
{
|
||||
// ensure the numbering order for host vars
|
||||
auto cl = left.evaluate(d, query);
|
||||
auto cr = right.evaluate(d, query);
|
||||
if (operand == operand_type::AND) {
|
||||
return "(" + cl + " " + operands[operand] + " " + cr + ")";
|
||||
} else {
|
||||
return cl + " " + operands[operand] + " " + cr;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
condition<L1, R1> left;
|
||||
condition<L2, R2> right;
|
||||
basic_condition::operand_type operand;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Logical unary condition
|
||||
*
|
||||
* This class represents a logical unary NOT condition
|
||||
*
|
||||
* @tparam L Left hand type of the condition to be negated
|
||||
* @tparam R Right hand type of the condition to be negated
|
||||
*/
|
||||
template<class L, class R>
|
||||
class condition<condition<L, R>, void> final : public basic_condition
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Create a logical unary condition
|
||||
* @param c The condition to be negated
|
||||
*/
|
||||
condition(const condition<L, R> &c) // NOLINT(*-explicit-constructor)
|
||||
: cond(c), operand(operands[operand_type::NOT]) { }
|
||||
|
||||
/**
|
||||
* @brief Evaluates the condition
|
||||
*
|
||||
* @param d The d used to evaluate
|
||||
* @param query The context of the query
|
||||
* @return The evaluated string based on the compile type
|
||||
*/
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override
|
||||
{
|
||||
return operand + " (" + cond.evaluate(d, query) + ")";
|
||||
}
|
||||
|
||||
private:
|
||||
condition<L, R> cond;
|
||||
std::string operand;
|
||||
};
|
||||
|
||||
template<>
|
||||
class condition<sql::column, sql::column> final : public basic_column_condition
|
||||
{
|
||||
public:
|
||||
condition(const sql::column &a, const operand_type op, sql::column b)
|
||||
: basic_column_condition(a, op)
|
||||
, other_column_(std::move(b)) {}
|
||||
/**
|
||||
* @brief Evaluates the condition
|
||||
*
|
||||
* @param d The d used to evaluate
|
||||
* @param query The context of the query
|
||||
* @return The evaluated string based on the compile type
|
||||
*/
|
||||
std::string evaluate(const sql::dialect &d, sql::query_context &query) const override;
|
||||
|
||||
private:
|
||||
sql::column other_column_;
|
||||
};
|
||||
|
||||
/**
|
||||
* @file condition.hpp
|
||||
* @brief Contains functions to create query conditions
|
||||
*
|
||||
* This file contains some functions to create
|
||||
* query conditions. These functions wrap the
|
||||
* constructing of a concrete condition and allows
|
||||
* expression like condition programming.
|
||||
*
|
||||
* @code
|
||||
* cond1 == cond2
|
||||
* cond1 < cond2
|
||||
* cond2 != cond1 && cond3 < cond4
|
||||
* @endcode
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Creates an IN condition for a given column and a list of values
|
||||
*
|
||||
* @tparam V The type of the list arguments
|
||||
* @param col The column to compare
|
||||
* @param args The list of values
|
||||
* @return The condition object
|
||||
*/
|
||||
template < class V >
|
||||
condition<sql::column, std::initializer_list<V>> in(const sql::column &col, std::initializer_list<V> args)
|
||||
{
|
||||
return condition<sql::column, std::initializer_list<V>>(col, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates an IN condition for a given column and a query to be executed
|
||||
*
|
||||
* @param col The column to compare
|
||||
* @param q The query to be executes as sub select
|
||||
* @return The condition object
|
||||
*/
|
||||
condition<sql::column, sql::query_context> in(const sql::column &col, sql::query_context &&q);
|
||||
|
||||
/**
|
||||
* @brief Creates a between condition.
|
||||
*
|
||||
* Creates a between condition for the given column with
|
||||
* the given range consisting of a low and high value
|
||||
*
|
||||
* @tparam T The type of the column and range
|
||||
* @param col The column for the between condition
|
||||
* @param low The low value of the range
|
||||
* @param high The high value of the range
|
||||
* @return The condition object
|
||||
*/
|
||||
template<class T>
|
||||
condition<sql::column, std::pair<T, T>> between(const sql::column &col, T low, T high)
|
||||
{
|
||||
return condition<sql::column, std::pair<T, T>>(col, std::make_pair(low, high));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a like condition
|
||||
*
|
||||
* Creates a like condition for the given column
|
||||
* and the given value string.
|
||||
*
|
||||
* @param col The column for the like condition
|
||||
* @param val The value to the like operator
|
||||
* @return The like condition object
|
||||
*/
|
||||
condition<sql::column, std::string> like(const sql::column &col, const std::string &val);
|
||||
|
||||
/**
|
||||
* @brief Condition equality operator for a column and a value
|
||||
*
|
||||
* Creates a condition object of a column and a value
|
||||
* checked on equality.
|
||||
*
|
||||
* @tparam T The type of the value
|
||||
* @param col The column object
|
||||
* @param val The value to compare with
|
||||
* @return The condition object representing the equality operation
|
||||
*/
|
||||
template<class T>
|
||||
condition<sql::column, T> operator==(const sql::column &col, T val)
|
||||
{
|
||||
return condition<sql::column, T>(col, basic_condition::operand_type::EQUAL, val);
|
||||
}
|
||||
|
||||
condition<sql::column, sql::column> operator==(const sql::column &a, const sql::column &b);
|
||||
|
||||
/**
|
||||
* @brief Condition equality method for a column and a query
|
||||
*
|
||||
* Creates a condition object of a column and a query
|
||||
* checked on equality.
|
||||
*
|
||||
* @param col The column object
|
||||
* @param q The query to compare with
|
||||
* @return The condition object representing the equality operation
|
||||
*/
|
||||
condition<sql::column, sql::query_context> equals(const sql::column &col, sql::query_context &q);
|
||||
|
||||
/**
|
||||
* @brief Condition inequality operator for a column and a value
|
||||
*
|
||||
* Creates a condition object of a column and a value
|
||||
* checked on inequality.
|
||||
*
|
||||
* @tparam T The type of the value
|
||||
* @param col The column object
|
||||
* @param val The value to compare with
|
||||
* @return The condition object representing the inequality operation
|
||||
*/
|
||||
template<class T>
|
||||
condition<sql::column, T> operator!=(const sql::column &col, T val)
|
||||
{
|
||||
return condition<sql::column, T>(col, basic_condition::operand_type::NOT_EQUAL, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Condition less operator for a column and a value
|
||||
*
|
||||
* Creates a condition object checking if the value of the given column
|
||||
* is less than the given value.
|
||||
*
|
||||
* @tparam T The type of the value
|
||||
* @param col The column object
|
||||
* @param val The value to compare with
|
||||
* @return The condition object representing the less operation
|
||||
*/
|
||||
template<class T>
|
||||
condition<sql::column, T> operator<(const sql::column &col, T val)
|
||||
{
|
||||
return condition<sql::column, T>(col, basic_condition::operand_type::LESS, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Condition less or equal operator for a column and a value
|
||||
*
|
||||
* Creates a condition object checking if the value of the given column
|
||||
* is less or equal than the given value.
|
||||
*
|
||||
* @tparam T The type of the value
|
||||
* @param col The column object
|
||||
* @param val The value to compare with
|
||||
* @return The condition object representing the less or equal operation
|
||||
*/
|
||||
template<class T>
|
||||
condition<sql::column, T> operator<=(const sql::column &col, T val)
|
||||
{
|
||||
return condition<sql::column, T>(col, basic_condition::operand_type::LESS_EQUAL, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Condition greater operator for a column and a value
|
||||
*
|
||||
* Creates a condition object checking if the value of the given column
|
||||
* is greater than the given value.
|
||||
*
|
||||
* @tparam T The type of the value
|
||||
* @param col The column object
|
||||
* @param val The value to compare with
|
||||
* @return The condition object representing the greater operation
|
||||
*/
|
||||
template<class T>
|
||||
condition<sql::column, T> operator>(const sql::column &col, T val)
|
||||
{
|
||||
return condition<sql::column, T>(col, basic_condition::operand_type::GREATER, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Condition greater or equal operator for a column and a value
|
||||
*
|
||||
* Creates a condition object checking if the value of the given column
|
||||
* is greater or equal than the given value.
|
||||
*
|
||||
* @tparam T The type of the value
|
||||
* @param col The column object
|
||||
* @param val The value to compare with
|
||||
* @return The condition object representing the greater or equal operation
|
||||
*/
|
||||
template<class T>
|
||||
condition<sql::column, T> operator>=(const sql::column &col, T val)
|
||||
{
|
||||
return condition<sql::column, T>(col, basic_condition::operand_type::GREATER_EQUAL, val);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief AND operation condition consisting of a left and right hand condition
|
||||
*
|
||||
* @tparam L1 Left hand type of left hand condition
|
||||
* @tparam R1 Right hand type of left hand condition
|
||||
* @tparam L2 Left hand type of right hand condition
|
||||
* @tparam R2 Right hand type of right hand condition
|
||||
* @param l Left hand condition
|
||||
* @param r Right hand condition
|
||||
* @return An condition object representing the AND operation
|
||||
*/
|
||||
template<class L1, class R1, class L2, class R2>
|
||||
condition<condition<L1, R1>, condition<L2, R2>> operator&&(condition<L1, R1> l, condition<L2, R2> r)
|
||||
{
|
||||
return condition<condition<L1, R1>, condition<L2, R2>>(std::move(l), std::move(r), basic_condition::operand_type::AND);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief OR operation condition consisting of a left and right hand condition
|
||||
*
|
||||
* @tparam L1 Left hand type of left hand condition
|
||||
* @tparam R1 Right hand type of left hand condition
|
||||
* @tparam L2 Left hand type of right hand condition
|
||||
* @tparam R2 Right hand type of right hand condition
|
||||
* @param l Left hand condition
|
||||
* @param r Right hand condition
|
||||
* @return An condition object representing the OR operation
|
||||
*/
|
||||
template<class L1, class R1, class L2, class R2>
|
||||
condition<condition<L1, R1>, condition<L2, R2>> operator||(condition<L1, R1> l, condition<L2, R2> r)
|
||||
{
|
||||
return condition<condition<L1, R1>, condition<L2, R2>>(std::move(l), std::move(r), basic_condition::operand_type::OR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Negates a given condition.
|
||||
*
|
||||
* @tparam L The left hand type of the condition
|
||||
* @tparam R The right hand type of the condition
|
||||
* @param c The condition to negated
|
||||
* @return An condition object representing the NOT operation
|
||||
*/
|
||||
template<class L, class R>
|
||||
condition<condition<L, R>, void> operator!(condition<L, R> c)
|
||||
{
|
||||
return condition<condition<L, R>, void>(std::move(c));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Creates a unique condition from a given condition object
|
||||
*
|
||||
* @tparam L The left hand type of the condition
|
||||
* @tparam R The right hand type of the condition
|
||||
* @param cond The condition to be copied
|
||||
* @return A unique condition pointer representing the given condition
|
||||
*/
|
||||
template<class L, class R>
|
||||
std::unique_ptr<basic_condition> make_condition(const condition<L, R> &cond)
|
||||
{
|
||||
return std::make_unique<condition<L, R>>(cond);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_CONDITION_HPP
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef QUERY_FK_VALUE_EXTRACTOR_HPP
|
||||
#define QUERY_FK_VALUE_EXTRACTOR_HPP
|
||||
|
||||
#include "matador/utils/access.hpp"
|
||||
#include "matador/utils/field_attributes.hpp"
|
||||
#include "matador/utils/foreign_attributes.hpp"
|
||||
#include "matador/utils/types.hpp"
|
||||
|
||||
namespace matador::query::detail {
|
||||
|
||||
class fk_value_extractor
|
||||
{
|
||||
public:
|
||||
fk_value_extractor() = default;
|
||||
|
||||
template<class Type>
|
||||
utils::database_type extract(Type &x)
|
||||
{
|
||||
access::process(*this, x);
|
||||
return value_;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void on_primary_key(const char *, ValueType &pk, std::enable_if_t<std::is_integral_v<ValueType> && !std::is_same_v<bool, ValueType>>* = nullptr)
|
||||
{
|
||||
value_ = pk;
|
||||
}
|
||||
void on_primary_key(const char * /*id*/, std::string &pk, size_t size);
|
||||
void on_revision(const char * /*id*/, unsigned long long &/*rev*/) {}
|
||||
template < class Type >
|
||||
void on_attribute(const char * /*id*/, Type &/*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
||||
void on_attribute(const char * /*id*/, char * /*x*/, const utils::field_attributes &/*attr*/ = utils::null_attributes) {}
|
||||
template<class Pointer>
|
||||
void on_belongs_to(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
|
||||
template<class Pointer>
|
||||
void on_has_one(const char * /*id*/, Pointer &/*x*/, const utils::foreign_attributes &/*attr*/) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many_to_many(const char *, ContainerType &, const char * /*join_column*/, const char * /*inverse_join_column*/, const utils::foreign_attributes &/*attr*/) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many_to_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char * /*join_column*/, const utils::foreign_attributes &/*attr*/) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
|
||||
|
||||
|
||||
private:
|
||||
utils::database_type value_{};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_FK_VALUE_EXTRACTOR_HPP
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef EXECUTABLE_QUERY_HPP
|
||||
#define EXECUTABLE_QUERY_HPP
|
||||
|
||||
#include "query_intermediate.hpp"
|
||||
|
||||
#include "../../utils/error.hpp"
|
||||
#include "../../utils/result.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
class executor;
|
||||
class statement;
|
||||
}
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class executable_query : public query_intermediate {
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
[[nodiscard]] utils::result<size_t, utils::error> execute(const sql::executor &exec) const;
|
||||
[[nodiscard]] utils::result<sql::statement, utils::error> prepare(const sql::executor &exec) const;
|
||||
[[nodiscard]] std::string str(const sql::executor &exec) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //EXECUTABLE_QUERY_HPP
|
||||
@@ -0,0 +1,82 @@
|
||||
#ifndef FETCHABLE_QUERY_HPP
|
||||
#define FETCHABLE_QUERY_HPP
|
||||
|
||||
#include "query_intermediate.hpp"
|
||||
|
||||
#include "../query_compiler.hpp"
|
||||
|
||||
#include "../../sql/query_result.hpp"
|
||||
#include "../../sql/record.hpp"
|
||||
|
||||
#include "../../utils/error.hpp"
|
||||
#include "../../utils/result.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
class executor;
|
||||
class statement;
|
||||
}
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class fetchable_query : public query_intermediate
|
||||
{
|
||||
protected:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
public:
|
||||
template < class Type >
|
||||
utils::result<sql::query_result<Type>, utils::error> fetch_all(sql::executor &exec)
|
||||
{
|
||||
auto result = fetch(exec);
|
||||
if (!result.is_ok()) {
|
||||
return utils::error(result.err());
|
||||
}
|
||||
|
||||
return utils::ok(sql::query_result<Type>(result.release()));
|
||||
}
|
||||
[[nodiscard]] utils::result<sql::query_result<sql::record>, utils::error> fetch_all(const sql::executor &exec) const;
|
||||
|
||||
template < class Type >
|
||||
utils::result<std::unique_ptr<Type>, utils::error> fetch_one(const sql::executor &exec)
|
||||
{
|
||||
auto result = fetch(exec);
|
||||
if (!result.is_ok()) {
|
||||
return utils::error(result.err());
|
||||
}
|
||||
|
||||
auto objects = sql::query_result<Type>(result.release());
|
||||
auto first = objects.begin();
|
||||
if (first == objects.end()) {
|
||||
return utils::ok(std::unique_ptr<Type>{nullptr});
|
||||
}
|
||||
|
||||
return utils::ok(std::unique_ptr<Type>{first.release()});
|
||||
}
|
||||
|
||||
[[nodiscard]] utils::result<std::optional<sql::record>, utils::error> fetch_one(const sql::executor &exec) const;
|
||||
|
||||
template<typename Type>
|
||||
utils::result<std::optional<Type>, utils::error> fetch_value(const sql::executor &exec)
|
||||
{
|
||||
const auto result = fetch_one(exec);
|
||||
if (!result.is_ok()) {
|
||||
return utils::failure(result.err());
|
||||
}
|
||||
|
||||
if (result->has_value()) {
|
||||
return utils::ok(std::optional<Type>{result->value().at(0).as<Type>().value()});
|
||||
}
|
||||
return utils::ok(std::optional<Type>{std::nullopt});
|
||||
}
|
||||
|
||||
[[nodiscard]] utils::result<sql::statement, utils::error> prepare(const sql::executor &exec) const;
|
||||
|
||||
[[nodiscard]] std::string str(const sql::executor &exec) const;
|
||||
|
||||
private:
|
||||
[[nodiscard]] utils::result<std::unique_ptr<sql::query_result_impl>, utils::error> fetch(const sql::executor &exec) const;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //FETCHABLE_QUERY_HPP
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef QUERY_CREATE_INTERMEDIATE_HPP
|
||||
#define QUERY_CREATE_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_create_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
query_create_intermediate();
|
||||
|
||||
executable_query table(const sql::table &table, std::initializer_list<sql::column_definition> columns);
|
||||
executable_query table(const sql::table &table, const std::vector<sql::column_definition> &columns);
|
||||
// template<class Type>
|
||||
// executable_query table(const sql::table &table, const sql::schema &schema)
|
||||
// {
|
||||
// return this->table(table, column_definition_generator::generate<Type>(schema));
|
||||
// }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //QUERY_CREATE_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef QUERY_DELETE_FROM_INTERMEDIATE_HPP
|
||||
#define QUERY_DELETE_FROM_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/query/intermediates/query_execute_where_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_delete_from_intermediate : public executable_query
|
||||
{
|
||||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
template<class Condition>
|
||||
query_execute_where_intermediate where(const Condition &cond)
|
||||
{
|
||||
return where_clause(std::make_unique<Condition>(std::move(cond)));
|
||||
}
|
||||
|
||||
private:
|
||||
query_execute_where_intermediate where_clause(std::unique_ptr<basic_condition> &&cond);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_DELETE_FROM_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_DELETE_INTERMEDIATE_HPP
|
||||
#define QUERY_DELETE_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_delete_from_intermediate;
|
||||
|
||||
class query_delete_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
query_delete_intermediate();
|
||||
|
||||
query_delete_from_intermediate from(const sql::table &table);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_DELETE_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,18 @@
|
||||
#ifndef QUERY_DROP_INTERMEDIATE_HPP
|
||||
#define QUERY_DROP_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_drop_intermediate : query_intermediate
|
||||
{
|
||||
public:
|
||||
query_drop_intermediate();
|
||||
|
||||
executable_query table(const sql::table &table);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_DROP_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_EXECUTE_LIMIT_INTERMEDIATE_HPP
|
||||
#define QUERY_EXECUTE_LIMIT_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_execute_offset_intermediate;
|
||||
|
||||
class query_execute_limit_intermediate : public executable_query
|
||||
{
|
||||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
query_execute_offset_intermediate offset(size_t offset);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_EXECUTE_LIMIT_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_EXECUTE_OFFSET_INTERMEDIATE_HPP
|
||||
#define QUERY_EXECUTE_OFFSET_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_execute_limit_intermediate;
|
||||
|
||||
class query_execute_offset_intermediate : public executable_query
|
||||
{
|
||||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
query_execute_limit_intermediate limit(size_t limit);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_EXECUTE_OFFSET_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef QUERY_EXECUTE_ORDER_BY_INTERMEDIATE_HPP
|
||||
#define QUERY_EXECUTE_ORDER_BY_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_execute_order_direction_intermediate;
|
||||
|
||||
class query_execute_order_by_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_execute_order_direction_intermediate asc();
|
||||
query_execute_order_direction_intermediate desc();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_EXECUTE_ORDER_BY_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_EXECUTE_ORDER_DIRECTION_INTERMEDIATE_HPP
|
||||
#define QUERY_EXECUTE_ORDER_DIRECTION_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_execute_limit_intermediate;
|
||||
|
||||
class query_execute_order_direction_intermediate : public executable_query
|
||||
{
|
||||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
query_execute_limit_intermediate limit(size_t limit);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_EXECUTE_ORDER_DIRECTION_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef QUERY_EXECUTE_WHERE_INTERMEDIATE_HPP
|
||||
#define QUERY_EXECUTE_WHERE_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_execute_limit_intermediate;
|
||||
class query_execute_order_by_intermediate;
|
||||
|
||||
class query_execute_where_intermediate : public executable_query
|
||||
{
|
||||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
query_execute_limit_intermediate limit(size_t limit);
|
||||
query_execute_order_by_intermediate order_by(const sql::column &col);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_EXECUTE_WHERE_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,40 @@
|
||||
#ifndef QUERY_FROM_INTERMEDIATE_HPP
|
||||
#define QUERY_FROM_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/fetchable_query.hpp"
|
||||
#include "matador/query/join_data.hpp"
|
||||
|
||||
#include "matador/query/intermediates/query_where_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_join_intermediate;
|
||||
|
||||
class query_from_intermediate : public fetchable_query
|
||||
{
|
||||
public:
|
||||
using fetchable_query::fetchable_query;
|
||||
|
||||
query_join_intermediate join_left(const sql::table &t);
|
||||
query_from_intermediate join_left(join_data &data);
|
||||
query_from_intermediate join_left(std::vector<join_data> &data_vector);
|
||||
|
||||
template<class Condition>
|
||||
query_where_intermediate where(const Condition &cond)
|
||||
{
|
||||
return where_clause(std::make_unique<Condition>(std::move(cond)));
|
||||
}
|
||||
query_where_intermediate where(std::unique_ptr<basic_condition> &&cond)
|
||||
{
|
||||
return where_clause(std::move(cond));
|
||||
}
|
||||
query_group_by_intermediate group_by(const sql::column &col);
|
||||
query_order_by_intermediate order_by(const sql::column &col);
|
||||
|
||||
private:
|
||||
query_where_intermediate where_clause(std::unique_ptr<basic_condition> &&cond);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_FROM_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_GROUP_BY_INTERMEDIATE_HPP
|
||||
#define QUERY_GROUP_BY_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/fetchable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_order_by_intermediate;
|
||||
|
||||
class query_group_by_intermediate : public fetchable_query
|
||||
{
|
||||
public:
|
||||
using fetchable_query::fetchable_query;
|
||||
|
||||
query_order_by_intermediate order_by(const sql::column &col);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_GROUP_BY_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,27 @@
|
||||
#ifndef QUERY_INSERT_INTERMEDIATE_HPP
|
||||
#define QUERY_INSERT_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_into_intermediate;
|
||||
|
||||
class query_insert_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
query_insert_intermediate();
|
||||
|
||||
// template<class Type>
|
||||
// query_into_intermediate into(const sql::table &table, const sql::schema &schema) {
|
||||
// return into(table, column_generator::generate<Type>(schema));
|
||||
// }
|
||||
query_into_intermediate into(const sql::table &table, std::initializer_list<sql::column> columns);
|
||||
query_into_intermediate into(const sql::table &table, std::vector<sql::column> &&columns);
|
||||
query_into_intermediate into(const sql::table &table, const std::vector<std::string> &column_names);
|
||||
query_into_intermediate into(const sql::table &table);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_INSERT_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef QUERY_INTERMEDIATE_HPP
|
||||
#define QUERY_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/query_data.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_intermediate {
|
||||
public:
|
||||
query_intermediate();
|
||||
query_intermediate(const std::shared_ptr<query_data> &context); // NOLINT(*-explicit-constructor)
|
||||
|
||||
protected:
|
||||
std::shared_ptr<query_data> context_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,43 @@
|
||||
#ifndef QUERY_INTO_INTERMEDIATE_HPP
|
||||
#define QUERY_INTO_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
#include "matador/query/value_extractor.hpp"
|
||||
|
||||
#include "matador/utils/placeholder.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
// template < class Type >
|
||||
// std::vector<utils::any_type> as_placeholder(const Type &obj)
|
||||
// {
|
||||
// placeholder_generator generator;
|
||||
// access::process(generator, obj);
|
||||
|
||||
// return generator.placeholder_values;
|
||||
// }
|
||||
|
||||
class query_into_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
executable_query values(std::initializer_list<std::variant<utils::placeholder, utils::database_type>> values);
|
||||
executable_query values(std::vector<std::variant<utils::placeholder, utils::database_type>> &&values);
|
||||
// template<class Type>
|
||||
// executable_query values()
|
||||
// {
|
||||
// Type obj;
|
||||
// return values(std::move(as_placeholder(obj)));
|
||||
// }
|
||||
template<class Type>
|
||||
executable_query values(const Type &obj)
|
||||
{
|
||||
return values(std::move(value_extractor::extract(obj)));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_INTO_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,32 @@
|
||||
#ifndef QUERY_JOIN_INTERMEDIATE_HPP
|
||||
#define QUERY_JOIN_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_from_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
using query_on_intermediate = query_from_intermediate;
|
||||
|
||||
class query_join_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
template<class Condition>
|
||||
query_on_intermediate on(const Condition &cond)
|
||||
{
|
||||
return on_clause(std::make_unique<Condition>(std::move(cond)));
|
||||
}
|
||||
query_on_intermediate on(std::unique_ptr<basic_condition> &&cond)
|
||||
{
|
||||
return on_clause(std::move(cond));
|
||||
}
|
||||
|
||||
private:
|
||||
query_on_intermediate on_clause(std::unique_ptr<basic_condition> &&cond);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_JOIN_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_LIMIT_INTERMEDIATE_HPP
|
||||
#define QUERY_LIMIT_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/fetchable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_offset_intermediate;
|
||||
|
||||
class query_limit_intermediate : public fetchable_query
|
||||
{
|
||||
public:
|
||||
using fetchable_query::fetchable_query;
|
||||
|
||||
query_offset_intermediate offset(size_t offset);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_LIMIT_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_OFFSET_INTERMEDIATE_HPP
|
||||
#define QUERY_OFFSET_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/fetchable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_limit_intermediate;
|
||||
|
||||
class query_offset_intermediate : public fetchable_query
|
||||
{
|
||||
public:
|
||||
using fetchable_query::fetchable_query;
|
||||
|
||||
query_limit_intermediate limit(size_t limit);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_OFFSET_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef QUERY_ORDER_BY_INTERMEDIATE_HPP
|
||||
#define QUERY_ORDER_BY_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_order_direction_intermediate;
|
||||
|
||||
class query_order_by_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
using query_intermediate::query_intermediate;
|
||||
|
||||
query_order_direction_intermediate asc();
|
||||
query_order_direction_intermediate desc();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_ORDER_BY_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_ORDER_DIRECTION_INTERMEDIATE_HPP
|
||||
#define QUERY_ORDER_DIRECTION_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/fetchable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_limit_intermediate;
|
||||
|
||||
class query_order_direction_intermediate : public fetchable_query
|
||||
{
|
||||
public:
|
||||
using fetchable_query::fetchable_query;
|
||||
|
||||
query_limit_intermediate limit(size_t limit);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_ORDER_DIRECTION_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,20 @@
|
||||
#ifndef QUERY_SELECT_INTERMEDIATE_HPP
|
||||
#define QUERY_SELECT_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_from_intermediate;
|
||||
|
||||
class query_select_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
explicit query_select_intermediate(const std::vector<sql::column>& columns);
|
||||
|
||||
query_from_intermediate from(const sql::table& t);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_SELECT_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,29 @@
|
||||
#ifndef QUERY_SET_INTERMEDIATE_HPP
|
||||
#define QUERY_SET_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/query/intermediates/query_execute_where_intermediate.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_set_intermediate : public executable_query
|
||||
{
|
||||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
template<class Condition>
|
||||
query_execute_where_intermediate where(const Condition &cond)
|
||||
{
|
||||
return where_clause(std::make_unique<Condition>(std::move(cond)));
|
||||
}
|
||||
|
||||
private:
|
||||
query_execute_where_intermediate where_clause(std::unique_ptr<basic_condition> &&cond);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_SET_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef QUERY_UPDATE_INTERMEDIATE_HPP
|
||||
#define QUERY_UPDATE_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
|
||||
#include "matador/query/intermediates/query_set_intermediate.hpp"
|
||||
|
||||
#include "matador/query/key_value_generator.hpp"
|
||||
|
||||
#include "matador/query/internal/key_value_pair.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
// template < class Type >
|
||||
// std::vector<internal::key_value_pair> as_key_value_placeholder(const Type &obj)
|
||||
// {
|
||||
// placeholder_key_value_generator generator;
|
||||
// access::process(generator, obj);
|
||||
//
|
||||
// return generator.placeholder_values;
|
||||
// }
|
||||
|
||||
class query_update_intermediate : public query_intermediate
|
||||
{
|
||||
public:
|
||||
explicit query_update_intermediate(const sql::table& table);
|
||||
|
||||
query_set_intermediate set(std::initializer_list<internal::key_value_pair> columns);
|
||||
query_set_intermediate set(std::vector<internal::key_value_pair> &&columns);
|
||||
// template<class Type>
|
||||
// query_set_intermediate set()
|
||||
// {
|
||||
// Type obj;
|
||||
// return set(std::move(as_key_value_placeholder(obj)));
|
||||
// }
|
||||
template<class Type>
|
||||
query_set_intermediate set(const Type &obj)
|
||||
{
|
||||
return set(key_value_generator::generate(obj));
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_UPDATE_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,22 @@
|
||||
#ifndef QUERY_WHERE_INTERMEDIATE_HPP
|
||||
#define QUERY_WHERE_INTERMEDIATE_HPP
|
||||
|
||||
#include "matador/query/intermediates/fetchable_query.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_group_by_intermediate;
|
||||
class query_order_by_intermediate;
|
||||
|
||||
class query_where_intermediate : public fetchable_query
|
||||
{
|
||||
public:
|
||||
using fetchable_query::fetchable_query;
|
||||
|
||||
query_group_by_intermediate group_by(const sql::column &col);
|
||||
query_order_by_intermediate order_by(const sql::column &col);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_WHERE_INTERMEDIATE_HPP
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef QUERY_ANY_TYPE_TO_STRING_VISITOR_HPP
|
||||
#define QUERY_ANY_TYPE_TO_STRING_VISITOR_HPP
|
||||
|
||||
#include "matador/utils/types.hpp"
|
||||
|
||||
#include "matador/query/attribute_string_writer.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace matador {
|
||||
class date;
|
||||
class time;
|
||||
}
|
||||
|
||||
namespace matador::sql {
|
||||
class dialect;
|
||||
struct query_context;
|
||||
}
|
||||
|
||||
namespace matador::query::internal {
|
||||
|
||||
struct basic_type_to_string_visitor
|
||||
{
|
||||
explicit basic_type_to_string_visitor(attribute_string_writer &writer, sql::query_context &query);
|
||||
|
||||
void operator()(const int8_t &x) { result = writer->to_string(x); }
|
||||
void operator()(const int16_t &x) { result = writer->to_string(x); }
|
||||
void operator()(const int32_t &x) { result = writer->to_string(x); }
|
||||
void operator()(const int64_t &x) { result = writer->to_string(x); }
|
||||
void operator()(const uint8_t &x) { result = writer->to_string(x); }
|
||||
void operator()(const uint16_t &x) { result = writer->to_string(x); }
|
||||
void operator()(const uint32_t &x) { result = writer->to_string(x); }
|
||||
void operator()(const uint64_t &x) { result = writer->to_string(x); }
|
||||
void operator()(const bool &x) { result = writer->to_string(x); }
|
||||
void operator()(const float &x) { result = writer->to_string(x); }
|
||||
void operator()(const double &x) { result = writer->to_string(x); }
|
||||
void operator()(const char *x) { result = writer->to_string(x); }
|
||||
void operator()(const std::string &x) { result = writer->to_string(x); }
|
||||
void operator()(const matador::date &x) { result = writer->to_string(x); }
|
||||
void operator()(const matador::time &x) { result = writer->to_string(x); }
|
||||
void operator()(const utils::blob &x) { result = writer->to_string(x); }
|
||||
|
||||
attribute_string_writer *writer{};
|
||||
sql::query_context &query;
|
||||
std::string result;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_ANY_TYPE_TO_STRING_VISITOR_HPP
|
||||
@@ -0,0 +1,25 @@
|
||||
#ifndef QUERY_KEY_VALUE_PAIR_HPP
|
||||
#define QUERY_KEY_VALUE_PAIR_HPP
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
|
||||
#include "matador/utils/types.hpp"
|
||||
|
||||
namespace matador::query::internal {
|
||||
|
||||
class key_value_pair {
|
||||
public:
|
||||
key_value_pair(const sql::column &col, utils::database_type value);
|
||||
key_value_pair(std::string name, utils::database_type value);
|
||||
key_value_pair(const char *name, utils::database_type value);
|
||||
|
||||
[[nodiscard]] const std::string& name() const;
|
||||
[[nodiscard]] const utils::database_type& value() const;
|
||||
|
||||
private:
|
||||
std::string name_;
|
||||
utils::database_type value_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_KEY_VALUE_PAIR_HPP
|
||||
@@ -0,0 +1,326 @@
|
||||
#ifndef QUERY_QUERY_PARTS_HPP
|
||||
#define QUERY_QUERY_PARTS_HPP
|
||||
|
||||
#include "matador/query/query_part_visitor.hpp"
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/query/internal/key_value_pair.hpp"
|
||||
#include "matador/query/query_part.hpp"
|
||||
|
||||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/table.hpp"
|
||||
|
||||
#include "matador/utils/placeholder.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::query::internal {
|
||||
|
||||
/**
|
||||
* Represents the SQL SELECT part
|
||||
*/
|
||||
class query_select_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_select_part(std::vector<sql::column> columns);
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
[[nodiscard]] const std::vector<sql::column>& columns() const;
|
||||
|
||||
private:
|
||||
std::vector<sql::column> columns_;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the SQL FROM part
|
||||
*/
|
||||
class query_from_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_from_part(sql::table t);
|
||||
|
||||
[[nodiscard]] const sql::table& table() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::table table_;
|
||||
};
|
||||
|
||||
class query_join_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_join_part(sql::table t);
|
||||
|
||||
[[nodiscard]] const sql::table& table() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::table table_;
|
||||
};
|
||||
|
||||
class query_on_part final : public query_part
|
||||
{
|
||||
public:
|
||||
template < class Condition >
|
||||
explicit query_on_part(const Condition &cond)
|
||||
: query_part(sql::dialect_token::ON)
|
||||
, condition_(new Condition(cond)) {}
|
||||
explicit query_on_part(std::unique_ptr<basic_condition> &&cond);
|
||||
|
||||
[[nodiscard]] const basic_condition& condition() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<basic_condition> condition_;
|
||||
};
|
||||
|
||||
class query_where_part final : public query_part
|
||||
{
|
||||
public:
|
||||
template < class Condition >
|
||||
explicit query_where_part(const Condition &cond)
|
||||
: query_part(sql::dialect_token::WHERE)
|
||||
, condition_(new Condition(cond)) {}
|
||||
explicit query_where_part(std::unique_ptr<basic_condition> &&cond);
|
||||
|
||||
[[nodiscard]] const basic_condition& condition() const;
|
||||
|
||||
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 token, std::string table_name);
|
||||
|
||||
protected:
|
||||
std::string table_name_;
|
||||
};
|
||||
|
||||
class query_group_by_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_group_by_part(sql::column col);
|
||||
|
||||
[[nodiscard]] const sql::column& column() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::column column_;
|
||||
};
|
||||
|
||||
class query_order_by_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_order_by_part(sql::column col);
|
||||
|
||||
[[nodiscard]] const sql::column& column() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::column column_;
|
||||
};
|
||||
|
||||
class query_order_by_asc_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_order_by_asc_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_order_by_desc_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_order_by_desc_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_offset_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_offset_part(size_t offset);
|
||||
|
||||
[[nodiscard]] size_t offset() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
size_t offset_;
|
||||
};
|
||||
|
||||
class query_limit_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_limit_part(size_t limit);
|
||||
|
||||
[[nodiscard]] size_t limit() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
size_t limit_;
|
||||
};
|
||||
|
||||
class query_insert_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_insert_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_into_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_into_part(sql::table t, std::vector<sql::column> columns);
|
||||
|
||||
[[nodiscard]] const sql::table& table() const;
|
||||
[[nodiscard]] const std::vector<sql::column>& columns() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::table table_;
|
||||
std::vector<sql::column> columns_;
|
||||
};
|
||||
/**
|
||||
* Represents the SQL VALUES part
|
||||
*/
|
||||
class query_values_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_values_part(std::vector<std::variant<utils::placeholder, utils::database_type>> &&values);
|
||||
|
||||
[[nodiscard]] const std::vector<std::variant<utils::placeholder, utils::database_type>>& values() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::vector<std::variant<utils::placeholder, utils::database_type>> values_;
|
||||
};
|
||||
|
||||
class query_update_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_update_part(sql::table table);
|
||||
|
||||
[[nodiscard]] const sql::table& table() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::table table_;
|
||||
};
|
||||
|
||||
class query_set_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_set_part(const std::vector<internal::key_value_pair>& key_value_pairs);
|
||||
|
||||
[[nodiscard]] const std::vector<internal::key_value_pair>& key_values() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::vector<internal::key_value_pair> key_value_pairs_;
|
||||
};
|
||||
|
||||
class query_delete_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_delete_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_delete_from_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_delete_from_part(sql::table table);
|
||||
|
||||
[[nodiscard]] const sql::table& table() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::table table_;
|
||||
};
|
||||
|
||||
class query_create_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_create_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_create_table_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_create_table_part(sql::table table, std::vector<sql::column_definition> columns);
|
||||
|
||||
[[nodiscard]] const sql::table& table() const;
|
||||
[[nodiscard]] const std::vector<sql::column_definition>& columns() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::table table_;
|
||||
std::vector<sql::column_definition> columns_;
|
||||
};
|
||||
|
||||
class query_drop_part final : public query_part
|
||||
{
|
||||
public:
|
||||
query_drop_part();
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
};
|
||||
|
||||
class query_drop_table_part final : public query_part
|
||||
{
|
||||
public:
|
||||
explicit query_drop_table_part(sql::table table);
|
||||
|
||||
[[nodiscard]] const sql::table& table() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
sql::table table_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PARTS_HPP
|
||||
@@ -0,0 +1,19 @@
|
||||
#ifndef JOIN_DATA_HPP
|
||||
#define JOIN_DATA_HPP
|
||||
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/sql/table.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct join_data
|
||||
{
|
||||
std::shared_ptr<sql::table> join_table;
|
||||
std::unique_ptr<basic_condition> condition;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //JOIN_DATA_HPP
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef QUERY_KEY_VALUE_GENERATOR_HPP
|
||||
#define QUERY_KEY_VALUE_GENERATOR_HPP
|
||||
|
||||
#include "matador/query/fk_value_extractor.hpp"
|
||||
#include "matador/query/internal/key_value_pair.hpp"
|
||||
|
||||
#include "matador/utils/foreign_attributes.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class key_value_generator
|
||||
{
|
||||
private:
|
||||
public:
|
||||
explicit key_value_generator(std::vector<internal::key_value_pair> &result) : result_(result) {}
|
||||
|
||||
public:
|
||||
template < class Type >
|
||||
static std::vector<internal::key_value_pair> generate(const Type &obj)
|
||||
{
|
||||
std::vector<internal::key_value_pair> result;
|
||||
key_value_generator generator(result);
|
||||
access::process(generator, obj);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
template < class V >
|
||||
void on_primary_key(const char *id, V &x, typename std::enable_if<std::is_integral<V>::value && !std::is_same<bool, V>::value>::type* = 0)
|
||||
{
|
||||
result_.emplace_back(id, x);
|
||||
}
|
||||
void on_primary_key(const char *id, std::string &, size_t);
|
||||
void on_revision(const char *id, unsigned long long &/*rev*/);
|
||||
|
||||
template<typename Type>
|
||||
void on_attribute(const char *id, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
||||
{
|
||||
result_.emplace_back(id, x);
|
||||
}
|
||||
|
||||
template<class Type, template < class ... > class Pointer>
|
||||
void on_belongs_to(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/)
|
||||
{
|
||||
result_.emplace_back(id, fk_value_extractor_.extract(*x));
|
||||
}
|
||||
template<class Type, template < class ... > class Pointer>
|
||||
void on_has_one(const char *id, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/)
|
||||
{
|
||||
result_.emplace_back(id, fk_value_extractor_.extract(*x));
|
||||
}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const char *, const char *, const utils::foreign_attributes &/*attr*/) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char *, ContainerType &, const utils::foreign_attributes &/*attr*/) {}
|
||||
|
||||
private:
|
||||
detail::fk_value_extractor fk_value_extractor_;
|
||||
std::vector<internal::key_value_pair> &result_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_KEY_VALUE_GENERATOR_HPP
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef QUERY_QUERY_HPP
|
||||
#define QUERY_QUERY_HPP
|
||||
|
||||
#include "matador/query/query_intermediates.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
class connection;
|
||||
}
|
||||
namespace matador::query {
|
||||
|
||||
sql::column alias(const std::string &column, const std::string &as);
|
||||
sql::column alias(sql::column &&col, const std::string &as);
|
||||
sql::column count(const std::string &column);
|
||||
sql::column count_all();
|
||||
|
||||
class query
|
||||
{
|
||||
public:
|
||||
[[nodiscard]] static query_create_intermediate create();
|
||||
[[nodiscard]] static query_drop_intermediate drop();
|
||||
[[nodiscard]] static query_select_intermediate select(std::initializer_list<sql::column> columns);
|
||||
[[nodiscard]] static query_select_intermediate select(const std::vector<sql::column>& columns);
|
||||
[[nodiscard]] static query_select_intermediate select(const std::vector<std::string> &column_names);
|
||||
[[nodiscard]] static query_select_intermediate select(std::vector<sql::column> columns, std::initializer_list<sql::column> additional_columns);
|
||||
// template<class Type>
|
||||
// [[nodiscard]] static query_select_intermediate select(const sql::schema &schema) {
|
||||
// return select(sql::column_generator::generate<Type>(schema));
|
||||
// }
|
||||
[[nodiscard]] static query_insert_intermediate insert();
|
||||
[[nodiscard]] static query_update_intermediate update(const sql::table &table);
|
||||
[[nodiscard]] static query_delete_intermediate remove();
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_HPP
|
||||
@@ -0,0 +1,65 @@
|
||||
#ifndef QUERY_QUERY_COMPILER_HPP
|
||||
#define QUERY_QUERY_COMPILER_HPP
|
||||
|
||||
#include "matador/query/query_part_visitor.hpp"
|
||||
#include "matador/query/query_data.hpp"
|
||||
|
||||
#include "matador/sql/query_context.hpp"
|
||||
|
||||
namespace matador::sql {
|
||||
class connection_impl;
|
||||
class dialect;
|
||||
}
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
struct query_data;
|
||||
|
||||
class query_compiler final : public query_part_visitor
|
||||
{
|
||||
public:
|
||||
sql::query_context compile(const query_data &data,
|
||||
const sql::dialect &d,
|
||||
std::optional<std::reference_wrapper<const sql::connection_impl>> conn);
|
||||
|
||||
protected:
|
||||
void visit(internal::query_select_part &select_part) override;
|
||||
void visit(internal::query_from_part &from_part) override;
|
||||
void visit(internal::query_join_part &join_part) override;
|
||||
void visit(internal::query_on_part &on_part) override;
|
||||
void visit(internal::query_where_part &where_part) override;
|
||||
void visit(internal::query_group_by_part &group_by_part) override;
|
||||
void visit(internal::query_order_by_part &order_by_part) override;
|
||||
void visit(internal::query_order_by_asc_part &order_by_asc_part) override;
|
||||
void visit(internal::query_order_by_desc_part &order_by_desc_part) override;
|
||||
void visit(internal::query_offset_part &offset_part) override;
|
||||
void visit(internal::query_limit_part &limit_part) override;
|
||||
void visit(internal::query_insert_part &insert_part) override;
|
||||
void visit(internal::query_into_part &into_part) override;
|
||||
void visit(internal::query_values_part &values_part) override;
|
||||
|
||||
void visit(internal::query_update_part &update_part) override;
|
||||
void visit(internal::query_set_part &set_part) override;
|
||||
|
||||
void visit(internal::query_delete_part &delete_part) override;
|
||||
void visit(internal::query_delete_from_part &delete_from_part) override;
|
||||
|
||||
void visit(internal::query_create_part &create_part) override;
|
||||
void visit(internal::query_create_table_part &create_table_part) override;
|
||||
|
||||
void visit(internal::query_drop_part &drop_part) override;
|
||||
void visit(internal::query_drop_table_part &drop_table_part) override;
|
||||
|
||||
static std::string build_table_name(sql::dialect_token token, const sql::dialect &d, const sql::table& t);
|
||||
|
||||
protected:
|
||||
const query_data *data_{};
|
||||
sql::query_context query_;
|
||||
size_t table_index{0};
|
||||
const sql::dialect *dialect_{nullptr};
|
||||
std::optional<std::reference_wrapper<const sql::connection_impl>> connection_{};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_COMPILER_HPP
|
||||
@@ -0,0 +1,21 @@
|
||||
#ifndef QUERY_DATA_HPP
|
||||
#define QUERY_DATA_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "matador/sql/column_definition.hpp"
|
||||
#include "matador/sql/table.hpp"
|
||||
|
||||
#include "matador/query/query_part.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
struct query_data
|
||||
{
|
||||
std::vector<std::unique_ptr<query_part>> parts{};
|
||||
std::vector<sql::column_definition> columns{};
|
||||
std::unordered_map<std::string, sql::table> tables{};
|
||||
};
|
||||
}
|
||||
|
||||
#endif //QUERY_DATA_HPP
|
||||
@@ -0,0 +1,30 @@
|
||||
#ifndef QUERY_QUERY_INTERMEDIATES_HPP
|
||||
#define QUERY_QUERY_INTERMEDIATES_HPP
|
||||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
#include "matador/query/intermediates/fetchable_query.hpp"
|
||||
#include "matador/query/intermediates/query_create_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_delete_from_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_delete_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_drop_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_execute_limit_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_execute_offset_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_execute_order_by_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_execute_order_direction_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_execute_where_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_from_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_group_by_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_insert_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_into_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_join_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_limit_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_offset_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_order_by_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_order_direction_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_select_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_set_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_update_intermediate.hpp"
|
||||
#include "matador/query/intermediates/query_where_intermediate.hpp"
|
||||
|
||||
#endif //QUERY_QUERY_INTERMEDIATES_HPP
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef QUERY_QUERY_PART_HPP
|
||||
#define QUERY_QUERY_PART_HPP
|
||||
|
||||
#include "matador/sql/dialect_token.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class query_part_visitor;
|
||||
|
||||
class query_part
|
||||
{
|
||||
protected:
|
||||
explicit query_part(sql::dialect_token token);
|
||||
|
||||
public:
|
||||
virtual ~query_part() = default;
|
||||
virtual void accept(query_part_visitor &visitor) = 0;
|
||||
|
||||
[[nodiscard]] sql::dialect_token token() const;
|
||||
|
||||
protected:
|
||||
sql::dialect_token token_;
|
||||
};
|
||||
|
||||
}
|
||||
#endif //QUERY_QUERY_PART_HPP
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef QUERY_QUERY_PART_VISITOR_HPP
|
||||
#define QUERY_QUERY_PART_VISITOR_HPP
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
namespace internal {
|
||||
class query_select_part;
|
||||
class query_from_part;
|
||||
class query_join_part;
|
||||
class query_on_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_offset_part;
|
||||
class query_limit_part;
|
||||
class query_insert_part;
|
||||
class query_into_part;
|
||||
class query_values_part;
|
||||
class query_update_part;
|
||||
class query_set_part;
|
||||
class query_delete_part;
|
||||
class query_delete_from_part;
|
||||
class query_create_part;
|
||||
class query_create_table_part;
|
||||
class query_drop_part;
|
||||
class query_drop_table_part;
|
||||
}
|
||||
|
||||
class query_part_visitor
|
||||
{
|
||||
public:
|
||||
virtual ~query_part_visitor() = default;
|
||||
|
||||
virtual void visit(internal::query_select_part &select_part) = 0;
|
||||
virtual void visit(internal::query_from_part &from_part) = 0;
|
||||
virtual void visit(internal::query_join_part &join_part) = 0;
|
||||
virtual void visit(internal::query_on_part &on_part) = 0;
|
||||
virtual void visit(internal::query_where_part &where_part) = 0;
|
||||
virtual void visit(internal::query_group_by_part &group_by_part) = 0;
|
||||
virtual void visit(internal::query_order_by_part &order_by_part) = 0;
|
||||
virtual void visit(internal::query_order_by_asc_part &order_by_asc_part) = 0;
|
||||
virtual void visit(internal::query_order_by_desc_part &order_by_desc_part) = 0;
|
||||
virtual void visit(internal::query_offset_part &offset_part) = 0;
|
||||
virtual void visit(internal::query_limit_part &limit_part) = 0;
|
||||
|
||||
virtual void visit(internal::query_insert_part &insert_part) = 0;
|
||||
virtual void visit(internal::query_into_part &into_part) = 0;
|
||||
virtual void visit(internal::query_values_part &values_part) = 0;
|
||||
|
||||
virtual void visit(internal::query_update_part &update_part) = 0;
|
||||
virtual void visit(internal::query_set_part &set_part) = 0;
|
||||
|
||||
virtual void visit(internal::query_delete_part &delete_part) = 0;
|
||||
virtual void visit(internal::query_delete_from_part &delete_from_part) = 0;
|
||||
|
||||
virtual void visit(internal::query_create_part &create_part) = 0;
|
||||
virtual void visit(internal::query_create_table_part &create_table_part) = 0;
|
||||
|
||||
virtual void visit(internal::query_drop_part &drop_part) = 0;
|
||||
virtual void visit(internal::query_drop_table_part &drop_table_part) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_QUERY_PART_VISITOR_HPP
|
||||
@@ -0,0 +1,94 @@
|
||||
#ifndef QUERY_VALUE_EXTRACTOR_HPP
|
||||
#define QUERY_VALUE_EXTRACTOR_HPP
|
||||
|
||||
#include "matador/query/fk_value_extractor.hpp"
|
||||
|
||||
#include "matador/utils/attribute_writer.hpp"
|
||||
#include "matador/utils/default_type_traits.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
class value_extractor final : public utils::attribute_writer
|
||||
{
|
||||
private:
|
||||
explicit value_extractor(std::vector<utils::database_type> &values);
|
||||
|
||||
public:
|
||||
template < class Type >
|
||||
static std::vector<utils::database_type> extract(const Type &type)
|
||||
{
|
||||
std::vector<utils::database_type> values;
|
||||
value_extractor gen(values);
|
||||
access::process(gen, type);
|
||||
return values;
|
||||
}
|
||||
|
||||
template<typename ValueType>
|
||||
void on_primary_key(const char *, ValueType &x, std::enable_if_t<std::is_integral_v<ValueType> && !std::is_same_v<bool, ValueType>>* = nullptr)
|
||||
{
|
||||
utils::data_type_traits<ValueType>::bind_value(*this, 0, x);
|
||||
}
|
||||
void on_primary_key(const char *id, std::string &pk, size_t size);
|
||||
void on_revision(const char *id, uint64_t &rev);
|
||||
template < class Type >
|
||||
void on_attribute(const char *, Type &x, const utils::field_attributes &/*attr*/ = utils::null_attributes)
|
||||
{
|
||||
utils::data_type_traits<Type>::bind_value(*this, 0, x);
|
||||
}
|
||||
void on_attribute(const char *id, char *x, const utils::field_attributes &/*attr*/ = utils::null_attributes);
|
||||
void on_attribute(const char *id, std::string &x, const utils::field_attributes &/*attr*/ = utils::null_attributes);
|
||||
|
||||
template<class Type, template < class ... > class Pointer>
|
||||
void on_belongs_to(const char * /*id*/, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/)
|
||||
{
|
||||
values_.emplace_back(fk_value_extractor_.extract(*x));
|
||||
}
|
||||
template<class Type, template < class ... > class Pointer>
|
||||
void on_has_one(const char * /*id*/, Pointer<Type> &x, const utils::foreign_attributes &/*attr*/)
|
||||
{
|
||||
values_.emplace_back(fk_value_extractor_.extract(*x));
|
||||
}
|
||||
template<class ContainerType>
|
||||
void on_has_many(const char * /*id*/, ContainerType &, const char *, const utils::foreign_attributes &/*attr*/) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many_to_many(const char * /*id*/,
|
||||
ContainerType &/*c*/,
|
||||
const char * /*join_column*/,
|
||||
const char * /*inverse_join_column*/,
|
||||
const utils::foreign_attributes &/*attr*/) {}
|
||||
template<class ContainerType>
|
||||
void on_has_many_to_many(const char * /*id*/,
|
||||
ContainerType &/*c*/,
|
||||
const utils::foreign_attributes &/*attr*/) {}
|
||||
|
||||
public:
|
||||
void write_value(size_t pos, const int8_t &x) override;
|
||||
void write_value(size_t pos, const int16_t &x) override;
|
||||
void write_value(size_t pos, const int32_t &x) override;
|
||||
void write_value(size_t pos, const int64_t &x) override;
|
||||
void write_value(size_t pos, const uint8_t &x) override;
|
||||
void write_value(size_t pos, const uint16_t &x) override;
|
||||
void write_value(size_t pos, const uint32_t &x) override;
|
||||
void write_value(size_t pos, const uint64_t &x) override;
|
||||
void write_value(size_t pos, const bool &x) override;
|
||||
void write_value(size_t pos, const float &x) override;
|
||||
void write_value(size_t pos, const double &x) override;
|
||||
void write_value(size_t pos, const time &x ) override;
|
||||
void write_value(size_t pos, const date &x ) override;
|
||||
void write_value(size_t pos, const char *x) override;
|
||||
void write_value(size_t pos, const char *x, size_t size) override;
|
||||
void write_value(size_t pos, const std::string &x) override;
|
||||
void write_value(size_t pos, const std::string &x, size_t size) override;
|
||||
void write_value(size_t pos, const utils::blob &x) override;
|
||||
void write_value(size_t pos, const utils::value &x, size_t size) override;
|
||||
|
||||
private:
|
||||
detail::fk_value_extractor fk_value_extractor_;
|
||||
std::vector<utils::database_type> &values_;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif //QUERY_VALUE_EXTRACTOR_HPP
|
||||
Reference in New Issue
Block a user