initial matador ng commit

This commit is contained in:
2025-02-02 20:37:12 +01:00
parent 19de5714f4
commit ded3daceb3
378 changed files with 14913 additions and 13431 deletions
@@ -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
+66
View File
@@ -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
+635
View File
@@ -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
+19
View File
@@ -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
+35
View File
@@ -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
+65
View File
@@ -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
+21
View File
@@ -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
+26
View File
@@ -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
+94
View File
@@ -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