Compare commits
No commits in common. "93785a6bc27608ae95a8b67e7267707662cd5333" and "69ce2c34cf789122fcd6311358df19653a5138b8" have entirely different histories.
93785a6bc2
...
69ce2c34cf
|
|
@ -13,7 +13,7 @@
|
|||
return "$" + std::to_string(index);
|
||||
})
|
||||
.with_token_replace_map({
|
||||
{dialect_token::BeginBinaryData, "'\\x"}
|
||||
{dialect_token::BEGIN_BINARY_DATA, "'\\x"}
|
||||
})
|
||||
.with_data_type_replace_map({
|
||||
{matador::utils::basic_type::type_int8, "SMALLINT"},
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#include "matador/orm/error_code.hpp"
|
||||
#include "matador/orm/session_query_builder.hpp"
|
||||
|
||||
#include "matador/query/criteria.hpp"
|
||||
#include "matador/query/condition.hpp"
|
||||
#include "matador/query/query.hpp"
|
||||
|
||||
#include "matador/sql/column_generator.hpp"
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "matador/orm/query_builder_exception.hpp"
|
||||
|
||||
#include "matador/query/criteria.hpp"
|
||||
#include "matador/query/condition.hpp"
|
||||
#include "matador/query/query_intermediates.hpp"
|
||||
|
||||
#include "matador/object/repository.hpp"
|
||||
|
|
@ -14,8 +14,8 @@
|
|||
namespace matador::orm {
|
||||
struct entity_insert_data {
|
||||
sql::table table;
|
||||
std::vector<std::string> columns{};
|
||||
std::vector<utils::database_type> values{};
|
||||
std::vector<std::string> columns;
|
||||
std::vector<utils::database_type> values;
|
||||
};
|
||||
|
||||
enum class insert_build_error : std::uint8_t {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "matador/orm/query_builder_exception.hpp"
|
||||
|
||||
#include "matador/query/criteria.hpp"
|
||||
#include "matador/query/condition.hpp"
|
||||
#include "matador/query/query.hpp"
|
||||
|
||||
#include "matador/sql/executor.hpp"
|
||||
|
|
@ -27,7 +27,7 @@ struct entity_query_data {
|
|||
std::vector<sql::column> columns{};
|
||||
std::unordered_map<std::string, sql::statement> lazy_loading_statements{};
|
||||
std::vector<query::join_data> joins{};
|
||||
query::criteria_ptr where_clause;
|
||||
std::unique_ptr<query::basic_condition> where_clause{};
|
||||
};
|
||||
|
||||
class session_query_builder final {
|
||||
|
|
@ -87,9 +87,8 @@ public:
|
|||
}
|
||||
entity_query_data_.pk_column_name = id;
|
||||
if (!pk_.is_null()) {
|
||||
const auto c = sql::column{table_info_stack_.top().table, id, ""};
|
||||
using namespace matador::query;
|
||||
auto co = c == utils::_;
|
||||
auto c = sql::column{table_info_stack_.top().table, id, ""};
|
||||
auto co = std::make_unique<query::condition<sql::column, utils::placeholder>>(c, query::basic_condition::operand_type::EQUAL, utils::_);
|
||||
entity_query_data_.where_clause = std::move(co);
|
||||
}
|
||||
}
|
||||
|
|
@ -241,13 +240,13 @@ private:
|
|||
std::shared_ptr<sql::table> table;
|
||||
};
|
||||
|
||||
std::stack<table_info> table_info_stack_{};
|
||||
std::unordered_map<std::string, std::shared_ptr<sql::table>> processed_tables_{};
|
||||
std::stack<table_info> table_info_stack_;
|
||||
std::unordered_map<std::string, std::shared_ptr<sql::table>> processed_tables_;
|
||||
const object::repository &schema_;
|
||||
entity_query_data entity_query_data_{};
|
||||
entity_query_data entity_query_data_;
|
||||
unsigned int column_index{0};
|
||||
unsigned int table_index{0};
|
||||
object::join_columns_collector join_columns_collector_{};
|
||||
object::join_columns_collector join_columns_collector_;
|
||||
sql::executor &executor_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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_old(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_old(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
|
||||
|
|
@ -19,8 +19,8 @@ public:
|
|||
void accept(criteria_visitor& visitor) const override;
|
||||
|
||||
[[nodiscard]] const sql::column& column() const;
|
||||
[[nodiscard]] const criteria_value &minimum() const;
|
||||
[[nodiscard]] const criteria_value &maximum() const;
|
||||
[[nodiscard]] const criteria_value &min() const;
|
||||
[[nodiscard]] const criteria_value &max() const;
|
||||
|
||||
private:
|
||||
sql::column column_;
|
||||
|
|
|
|||
|
|
@ -32,22 +32,5 @@ private:
|
|||
binary_operator operator_{};
|
||||
criteria_value value_;
|
||||
};
|
||||
|
||||
class binary_column_criteria final : public abstract_criteria {
|
||||
public:
|
||||
binary_column_criteria() = delete;
|
||||
binary_column_criteria(sql::column left_column, binary_operator operand, sql::column right_column);
|
||||
|
||||
void accept(criteria_visitor& visitor) const override;
|
||||
|
||||
[[nodiscard]] const sql::column& left_column() const;
|
||||
[[nodiscard]] binary_operator operand() const;
|
||||
[[nodiscard]] const sql::column& right_column() const;
|
||||
|
||||
private:
|
||||
sql::column left_column_;
|
||||
binary_operator operator_{};
|
||||
sql::column right_column_;
|
||||
};
|
||||
}
|
||||
#endif //CRITERIA_BINARY_CRITERIA_NODE_HPP
|
||||
|
|
@ -9,33 +9,13 @@
|
|||
|
||||
namespace matador::query {
|
||||
enum class collection_operator {
|
||||
In,
|
||||
Out
|
||||
IN,
|
||||
OUT
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Criteria 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 (29,34,56)
|
||||
* @endcode
|
||||
*/
|
||||
class collection_criteria final : public abstract_criteria {
|
||||
public:
|
||||
collection_criteria() = delete;
|
||||
/**
|
||||
* @brief Creates an IN condition
|
||||
*
|
||||
* Creates an IN or OUT criteria for the given sql::column and
|
||||
* the given list of arguments.
|
||||
*
|
||||
* @param col Column for the IN condition
|
||||
* @param operand_ Operator to use
|
||||
* @param values List of values
|
||||
*/
|
||||
collection_criteria(sql::column col, collection_operator operand_, std::vector<criteria_value> values);
|
||||
collection_criteria(sql::column col, collection_operator operand_, std::initializer_list<criteria_value> values);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ criteria_ptr operator==(const sql::column &col, Type val) {
|
|||
return std::make_unique<binary_criteria>(col, binary_operator::EQUALS, utils::value(val));
|
||||
}
|
||||
|
||||
criteria_ptr operator==(const sql::column &col_left, const sql::column &col_right);
|
||||
|
||||
template<class Type>
|
||||
criteria_ptr operator!=(const sql::column &col, Type val) {
|
||||
return std::make_unique<binary_criteria>(col, binary_operator::NOT_EQUALS, utils::value(val));
|
||||
|
|
@ -65,7 +63,7 @@ criteria_ptr in(const sql::column &col, std::initializer_list<Type> args) {
|
|||
for ( auto &&arg : args ) {
|
||||
values.emplace_back(utils::value{std::move(arg)});
|
||||
}
|
||||
return std::make_unique<collection_criteria>(col, collection_operator::In, std::move(values));
|
||||
return std::make_unique<collection_criteria>(col, collection_operator::IN, std::move(values));
|
||||
}
|
||||
|
||||
template <>
|
||||
|
|
@ -79,7 +77,7 @@ criteria_ptr out(const sql::column &col, std::initializer_list<Type> args) {
|
|||
for ( auto &&arg : args ) {
|
||||
values.emplace_back(utils::value{std::move(arg)});
|
||||
}
|
||||
return std::make_unique<collection_criteria>(col, collection_operator::Out, values);
|
||||
return std::make_unique<collection_criteria>(col, collection_operator::OUT, values);
|
||||
}
|
||||
|
||||
template <>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
namespace matador::query {
|
||||
class between_criteria;
|
||||
class binary_criteria;
|
||||
class binary_column_criteria;
|
||||
class like_criteria;
|
||||
class logical_criteria;
|
||||
class not_criteria;
|
||||
|
|
@ -17,7 +16,6 @@ public:
|
|||
|
||||
virtual void visit(const between_criteria &node) = 0;
|
||||
virtual void visit(const binary_criteria &node) = 0;
|
||||
virtual void visit(const binary_column_criteria &node) = 0;
|
||||
virtual void visit(const collection_criteria &node) = 0;
|
||||
virtual void visit(const collection_query_criteria &node) = 0;
|
||||
virtual void visit(const like_criteria &node) = 0;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ public:
|
|||
|
||||
void visit(const between_criteria &node) override;
|
||||
void visit(const binary_criteria &node) override;
|
||||
void visit(const binary_column_criteria &node) override;
|
||||
void visit(const collection_criteria &node) override;
|
||||
void visit(const collection_query_criteria &node) override;
|
||||
void visit(const like_criteria &node) override;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
#include "matador/query/criteria/abstract_criteria.hpp"
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/query/intermediates/query_execute_where_intermediate.hpp"
|
||||
|
||||
|
|
@ -14,10 +14,14 @@ class query_delete_from_intermediate : public executable_query
|
|||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
query_execute_where_intermediate where(std::unique_ptr<abstract_criteria> cond);
|
||||
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<abstract_criteria> &&cond);
|
||||
query_execute_where_intermediate where_clause(std::unique_ptr<basic_condition> &&cond);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,17 +19,20 @@ public:
|
|||
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<abstract_criteria> &&cond);
|
||||
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<abstract_criteria> &&cond);
|
||||
query_where_intermediate where_clause(std::unique_ptr<basic_condition> &&cond);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,15 +13,18 @@ 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<abstract_criteria> &&cond);
|
||||
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<abstract_criteria> &&cond);
|
||||
query_on_intermediate on_clause(std::unique_ptr<basic_condition> &&cond);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include "matador/query/intermediates/executable_query.hpp"
|
||||
|
||||
#include "matador/query/criteria/abstract_criteria.hpp"
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/query/intermediates/query_execute_where_intermediate.hpp"
|
||||
|
||||
|
|
@ -14,12 +14,14 @@ class query_set_intermediate : public executable_query
|
|||
public:
|
||||
using executable_query::executable_query;
|
||||
|
||||
query_execute_where_intermediate where(std::unique_ptr<abstract_criteria> cond) {
|
||||
return where_clause(std::move(cond));
|
||||
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<abstract_criteria> &&cond);
|
||||
query_execute_where_intermediate where_clause(std::unique_ptr<basic_condition> &&cond);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#define QUERY_QUERY_PARTS_HPP
|
||||
|
||||
#include "matador/query/query_part_visitor.hpp"
|
||||
#include "matador/query/criteria.hpp"
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/query/internal/key_value_pair.hpp"
|
||||
#include "matador/query/query_part.hpp"
|
||||
|
|
@ -68,17 +68,17 @@ 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)
|
||||
: query_part(sql::dialect_token::ON)
|
||||
, condition_(new Condition(cond)) {}
|
||||
explicit query_on_part(std::unique_ptr<abstract_criteria> &&cond);
|
||||
explicit query_on_part(std::unique_ptr<basic_condition> &&cond);
|
||||
|
||||
[[nodiscard]] const abstract_criteria& condition() const;
|
||||
[[nodiscard]] const basic_condition& condition() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<abstract_criteria> condition_;
|
||||
std::unique_ptr<basic_condition> condition_;
|
||||
};
|
||||
|
||||
class query_where_part final : public query_part
|
||||
|
|
@ -86,17 +86,17 @@ 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)
|
||||
: query_part(sql::dialect_token::WHERE)
|
||||
, condition_(new Condition(cond)) {}
|
||||
explicit query_where_part(std::unique_ptr<abstract_criteria> &&cond);
|
||||
explicit query_where_part(std::unique_ptr<basic_condition> &&cond);
|
||||
|
||||
[[nodiscard]] const abstract_criteria& condition() const;
|
||||
[[nodiscard]] const basic_condition& condition() const;
|
||||
|
||||
private:
|
||||
void accept(query_part_visitor &visitor) override;
|
||||
|
||||
private:
|
||||
std::unique_ptr<abstract_criteria> condition_;
|
||||
std::unique_ptr<basic_condition> condition_;
|
||||
};
|
||||
|
||||
class query_table_name_part : public query_part
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef JOIN_DATA_HPP
|
||||
#define JOIN_DATA_HPP
|
||||
|
||||
#include "matador/query/criteria/abstract_criteria.hpp"
|
||||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
#include "matador/sql/table.hpp"
|
||||
|
||||
|
|
@ -9,9 +9,10 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
struct join_data {
|
||||
struct join_data
|
||||
{
|
||||
std::shared_ptr<sql::table> join_table;
|
||||
std::unique_ptr<abstract_criteria> condition;
|
||||
std::unique_ptr<basic_condition> condition;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,8 +26,8 @@ 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);
|
||||
const sql::dialect &d,
|
||||
std::optional<std::reference_wrapper<const sql::connection_impl>> conn);
|
||||
|
||||
protected:
|
||||
void visit(internal::query_select_part &select_part) override;
|
||||
|
|
|
|||
|
|
@ -139,50 +139,50 @@ private:
|
|||
// std::unique_ptr<query_compiler> compiler_;
|
||||
|
||||
token_to_string_map tokens_ {
|
||||
{dialect_token::Create, "CREATE"},
|
||||
{dialect_token::Drop, "DROP"},
|
||||
{dialect_token::Remove, "DELETE"},
|
||||
{dialect_token::Insert, "INSERT"},
|
||||
{dialect_token::Table, "TABLE"},
|
||||
{dialect_token::Into, "INTO"},
|
||||
{dialect_token::Values, "VALUES"},
|
||||
{dialect_token::Update, "UPDATE"},
|
||||
{dialect_token::Select, "SELECT"},
|
||||
{dialect_token::Columns, "COLUMNS"},
|
||||
{dialect_token::Column, "COLUMN"},
|
||||
{dialect_token::From, "FROM"},
|
||||
{dialect_token::Join, "LEFT JOIN"},
|
||||
{dialect_token::On, "ON"},
|
||||
{dialect_token::Where, "WHERE"},
|
||||
{dialect_token::And, "AND"},
|
||||
{dialect_token::Or, "OR"},
|
||||
{dialect_token::Not, "NOT"},
|
||||
{dialect_token::Like, "LIKE"},
|
||||
{dialect_token::Between, "BETWEEN"},
|
||||
{dialect_token::In, "IN"},
|
||||
{dialect_token::OrderBy, "ORDER BY"},
|
||||
{dialect_token::GroupBy, "GROUP BY"},
|
||||
{dialect_token::Asc, "ASC"},
|
||||
{dialect_token::Desc, "DESC"},
|
||||
{dialect_token::Offset, "OFFSET"},
|
||||
{dialect_token::Limit, "LIMIT"},
|
||||
{dialect_token::As, "AS"},
|
||||
{dialect_token::Offset, "OFFSET"},
|
||||
{dialect_token::Distinct, "DISTINCT"},
|
||||
{dialect_token::Set, "SET"},
|
||||
{dialect_token::NotNull, "NOT NULL"},
|
||||
{dialect_token::PrimaryKey, "PRIMARY KEY"},
|
||||
{dialect_token::Begin, "BEGIN TRANSACTION"},
|
||||
{dialect_token::Commit, "COMMIT TRANSACTION"},
|
||||
{dialect_token::Rollback, "ROLLBACK TRANSACTION"},
|
||||
{dialect_token::StartQuote, "\""},
|
||||
{dialect_token::EndQuote, "\""},
|
||||
{dialect_token::StringQuote, "'"},
|
||||
{dialect_token::BeginBinaryData, "X'"},
|
||||
{dialect_token::EndBinaryData, "'"},
|
||||
{dialect_token::BeginStringData, "'"},
|
||||
{dialect_token::EndStringData, "'"},
|
||||
{dialect_token::None, ""}
|
||||
{dialect_token::CREATE, "CREATE"},
|
||||
{dialect_token::DROP, "DROP"},
|
||||
{dialect_token::REMOVE, "DELETE"},
|
||||
{dialect_token::INSERT, "INSERT"},
|
||||
{dialect_token::TABLE, "TABLE"},
|
||||
{dialect_token::INTO, "INTO"},
|
||||
{dialect_token::VALUES, "VALUES"},
|
||||
{dialect_token::UPDATE, "UPDATE"},
|
||||
{dialect_token::SELECT, "SELECT"},
|
||||
{dialect_token::COLUMNS, "COLUMNS"},
|
||||
{dialect_token::COLUMN, "COLUMN"},
|
||||
{dialect_token::FROM, "FROM"},
|
||||
{dialect_token::JOIN, "LEFT JOIN"},
|
||||
{dialect_token::ON, "ON"},
|
||||
{dialect_token::WHERE, "WHERE"},
|
||||
{dialect_token::AND, "AND"},
|
||||
{dialect_token::OR, "OR"},
|
||||
{dialect_token::NOT, "NOT"},
|
||||
{dialect_token::LIKE, "LIKE"},
|
||||
{dialect_token::BETWEEN, "BETWEEN"},
|
||||
{dialect_token::IN, "IN"},
|
||||
{dialect_token::ORDER_BY, "ORDER BY"},
|
||||
{dialect_token::GROUP_BY, "GROUP BY"},
|
||||
{dialect_token::ASC, "ASC"},
|
||||
{dialect_token::DESC, "DESC"},
|
||||
{dialect_token::OFFSET, "OFFSET"},
|
||||
{dialect_token::LIMIT, "LIMIT"},
|
||||
{dialect_token::AS, "AS"},
|
||||
{dialect_token::OFFSET, "OFFSET"},
|
||||
{dialect_token::DISTINCT, "DISTINCT"},
|
||||
{dialect_token::SET, "SET"},
|
||||
{dialect_token::NOT_NULL, "NOT NULL"},
|
||||
{dialect_token::PRIMARY_KEY, "PRIMARY KEY"},
|
||||
{dialect_token::BEGIN, "BEGIN TRANSACTION"},
|
||||
{dialect_token::COMMIT, "COMMIT TRANSACTION"},
|
||||
{dialect_token::ROLLBACK, "ROLLBACK TRANSACTION"},
|
||||
{dialect_token::START_QUOTE, "\""},
|
||||
{dialect_token::END_QUOTE, "\""},
|
||||
{dialect_token::STRING_QUOTE, "'"},
|
||||
{dialect_token::BEGIN_BINARY_DATA, "X'"},
|
||||
{dialect_token::END_BINARY_DATA, "'"},
|
||||
{dialect_token::BEGIN_STRING_DATA, "'"},
|
||||
{dialect_token::END_STRING_DATA, "'"},
|
||||
{dialect_token::NONE, ""}
|
||||
};
|
||||
|
||||
data_type_to_string_map data_types_ {
|
||||
|
|
|
|||
|
|
@ -6,55 +6,55 @@
|
|||
namespace matador::sql {
|
||||
|
||||
enum class dialect_token : uint8_t {
|
||||
Create = 0,
|
||||
Drop,
|
||||
Remove,
|
||||
Insert,
|
||||
Update,
|
||||
Select,
|
||||
Alter,
|
||||
Schema,
|
||||
Database,
|
||||
Table,
|
||||
Values,
|
||||
InsertValues,
|
||||
Columns,
|
||||
Column,
|
||||
From,
|
||||
Join,
|
||||
On,
|
||||
Into,
|
||||
Where,
|
||||
WhereClause,
|
||||
And,
|
||||
Or,
|
||||
Not,
|
||||
Like,
|
||||
Between,
|
||||
In,
|
||||
OrderBy,
|
||||
GroupBy,
|
||||
Asc,
|
||||
Desc,
|
||||
Limit,
|
||||
As,
|
||||
Offset,
|
||||
Distinct,
|
||||
Set,
|
||||
UpdateValues,
|
||||
NotNull,
|
||||
PrimaryKey,
|
||||
Begin,
|
||||
Commit,
|
||||
Rollback,
|
||||
StartQuote,
|
||||
EndQuote,
|
||||
StringQuote,
|
||||
BeginBinaryData,
|
||||
EndBinaryData,
|
||||
BeginStringData,
|
||||
EndStringData,
|
||||
None
|
||||
CREATE = 0,
|
||||
DROP,
|
||||
REMOVE,
|
||||
INSERT,
|
||||
UPDATE,
|
||||
SELECT,
|
||||
ALTER,
|
||||
SCHEMA,
|
||||
DATABASE,
|
||||
TABLE,
|
||||
VALUES,
|
||||
INSERT_VALUES,
|
||||
COLUMNS,
|
||||
COLUMN,
|
||||
FROM,
|
||||
JOIN,
|
||||
ON,
|
||||
INTO,
|
||||
WHERE,
|
||||
WHERE_CLAUSE,
|
||||
AND,
|
||||
OR,
|
||||
NOT,
|
||||
LIKE,
|
||||
BETWEEN,
|
||||
IN,
|
||||
ORDER_BY,
|
||||
GROUP_BY,
|
||||
ASC,
|
||||
DESC,
|
||||
LIMIT,
|
||||
AS,
|
||||
OFFSET,
|
||||
DISTINCT,
|
||||
SET,
|
||||
UPDATE_VALUES,
|
||||
NOT_NULL,
|
||||
PRIMARY_KEY,
|
||||
BEGIN,
|
||||
COMMIT,
|
||||
ROLLBACK,
|
||||
START_QUOTE,
|
||||
END_QUOTE,
|
||||
STRING_QUOTE,
|
||||
BEGIN_BINARY_DATA,
|
||||
END_BINARY_DATA,
|
||||
BEGIN_STRING_DATA,
|
||||
END_STRING_DATA,
|
||||
NONE
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ add_library(matador-orm STATIC
|
|||
../../include/matador/orm/session_insert_builder.hpp
|
||||
../../include/matador/orm/session_query_builder.hpp
|
||||
../../include/matador/query/attribute_string_writer.hpp
|
||||
../../include/matador/query/basic_condition.hpp
|
||||
../../include/matador/query/criteria/abstract_criteria.hpp
|
||||
../../include/matador/query/criteria/between_criteria.hpp
|
||||
../../include/matador/query/criteria/collection_criteria.hpp
|
||||
|
|
@ -13,6 +14,7 @@ add_library(matador-orm STATIC
|
|||
../../include/matador/query/criteria/criteria_visitor.hpp
|
||||
../../include/matador/query/criteria/like_criteria.hpp
|
||||
../../include/matador/query/criteria/logical_criteria.hpp
|
||||
../../include/matador/query/condition.hpp
|
||||
../../include/matador/query/fk_value_extractor.hpp
|
||||
../../include/matador/query/intermediates/executable_query.hpp
|
||||
../../include/matador/query/intermediates/fetchable_query.hpp
|
||||
|
|
@ -83,6 +85,7 @@ add_library(matador-orm STATIC
|
|||
orm/session_insert_builder.cpp
|
||||
orm/session_query_builder.cpp
|
||||
query/attribute_string_writer.cpp
|
||||
query/basic_condition.cpp
|
||||
query/criteria/between_criteria.cpp
|
||||
query/criteria/binary_criteria.cpp
|
||||
query/criteria/collection_criteria.cpp
|
||||
|
|
@ -90,6 +93,7 @@ add_library(matador-orm STATIC
|
|||
query/criteria/like_criteria.cpp
|
||||
query/criteria/logical_criteria.cpp
|
||||
query/criteria/not_criteria.cpp
|
||||
query/condition.cpp
|
||||
query/intermediates/executable_query.cpp
|
||||
query/intermediates/fetchable_query.cpp
|
||||
query/intermediates/query_create_intermediate.cpp
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
#include "matador/orm/session.hpp"
|
||||
|
||||
#include "matador/sql/backend_provider.hpp"
|
||||
#include "matador/sql/dialect.hpp"
|
||||
|
||||
#include "matador/query/query.hpp"
|
||||
|
||||
#include <queue>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace matador::orm {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ void session_query_builder::append_join(const sql::column &left, const sql::colu
|
|||
using namespace matador::query;
|
||||
entity_query_data_.joins.push_back({
|
||||
{right.table_},
|
||||
left == right
|
||||
make_condition(left == right)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -98,9 +98,9 @@ void attribute_string_writer::write_value(size_t /*pos*/, const utils::blob& x )
|
|||
// MSSQL: 0x5468697320697320612062616E617279204461746120737472696E67
|
||||
// Sqlite: X'5468697320697320612062616E617279204461746120737472696E67'
|
||||
if (conn_.has_value()) {
|
||||
result_ = dialect_.token_at(sql::dialect_token::BeginBinaryData) + conn_.value().get().to_escaped_string(x) + dialect_.token_at(sql::dialect_token::EndBinaryData);
|
||||
result_ = dialect_.token_at(sql::dialect_token::BEGIN_BINARY_DATA) + conn_.value().get().to_escaped_string(x) + dialect_.token_at(sql::dialect_token::END_BINARY_DATA);
|
||||
} else {
|
||||
result_ = dialect_.token_at(sql::dialect_token::BeginBinaryData) + dialect_.to_escaped_string(x) + dialect_.token_at(sql::dialect_token::EndBinaryData);
|
||||
result_ = dialect_.token_at(sql::dialect_token::BEGIN_BINARY_DATA) + dialect_.to_escaped_string(x) + dialect_.token_at(sql::dialect_token::END_BINARY_DATA);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
#include "matador/query/basic_condition.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
std::unordered_map<basic_condition::operand_type, std::string> basic_condition::operands{
|
||||
{operand_type::EQUAL, "="},
|
||||
{operand_type::NOT_EQUAL, "<>"},
|
||||
{operand_type::LESS, "<"},
|
||||
{operand_type::LESS_EQUAL, "<="},
|
||||
{operand_type::GREATER, ">"},
|
||||
{operand_type::GREATER_EQUAL, ">="},
|
||||
{operand_type::OR, "OR"},
|
||||
{operand_type::AND, "AND"},
|
||||
{operand_type::NOT, "NOT"},
|
||||
{operand_type::IN_LIST, "IN"},
|
||||
{operand_type::LIKE, "LIKE"}
|
||||
};
|
||||
|
||||
basic_column_condition::basic_column_condition(sql::column fld, const operand_type op)
|
||||
: field_(std::move(fld)), operand(operands[op])
|
||||
{ }
|
||||
|
||||
basic_in_condition::basic_in_condition(sql::column fld)
|
||||
: field_(std::move(fld))
|
||||
{ }
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#include "matador/query/condition.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
|
||||
condition<sql::column, utils::placeholder>::condition(const sql::column &fld, const operand_type op, const utils::placeholder &val)
|
||||
: basic_column_condition(fld, op), value(val)
|
||||
{}
|
||||
|
||||
std::string condition<sql::column, utils::placeholder>::evaluate(const sql::dialect &d, sql::query_context &query) const
|
||||
{
|
||||
query.bind_vars.emplace_back(field_.name);
|
||||
return d.prepare_identifier(field_) + " " + operand + " " + d.next_placeholder(query.bind_vars);
|
||||
}
|
||||
|
||||
condition<sql::column, sql::query_context>::condition(sql::column col, const operand_type op, sql::query_context &q)
|
||||
: basic_column_condition(std::move(col), op), query_(q)
|
||||
{}
|
||||
|
||||
std::string condition<sql::column, sql::query_context>::evaluate(const sql::dialect &d, sql::query_context &/*query*/) const
|
||||
{
|
||||
std::string result(d.prepare_identifier(field_) + " " + operand + " (");
|
||||
result += query_.sql;
|
||||
result += ")";
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string condition<sql::column, sql::column>::evaluate(const sql::dialect &d, sql::query_context &/*query*/) const {
|
||||
return d.prepare_condition(field_) + " " + operand + " " + d.prepare_condition(other_column_);
|
||||
}
|
||||
|
||||
condition<sql::column, sql::query_context> in_old(const sql::column &col, sql::query_context &&q)
|
||||
{
|
||||
return {col, basic_condition::operand_type::IN_LIST, q};
|
||||
}
|
||||
|
||||
condition<sql::column, std::string> like_old(const sql::column &col, const std::string &val) {
|
||||
return { col, basic_condition::operand_type::LIKE, val };
|
||||
}
|
||||
|
||||
condition<sql::column, sql::column> operator==(const sql::column &a, const sql::column &b)
|
||||
{
|
||||
return {a, basic_condition::operand_type::EQUAL, b};
|
||||
}
|
||||
}
|
||||
|
|
@ -23,11 +23,11 @@ const sql::column & between_criteria::column() const {
|
|||
return column_;
|
||||
}
|
||||
|
||||
const criteria_value &between_criteria::minimum() const {
|
||||
const criteria_value &between_criteria::min() const {
|
||||
return min_;
|
||||
}
|
||||
|
||||
const criteria_value &between_criteria::maximum() const {
|
||||
const criteria_value &between_criteria::max() const {
|
||||
return max_;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,25 +24,4 @@ binary_operator binary_criteria::operand() const {
|
|||
const criteria_value& binary_criteria::value() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
binary_column_criteria::binary_column_criteria( sql::column left_column, binary_operator operand, sql::column right_column )
|
||||
: left_column_(std::move(left_column))
|
||||
, operator_(operand)
|
||||
, right_column_(std::move(right_column)){}
|
||||
|
||||
void binary_column_criteria::accept(criteria_visitor& visitor) const {
|
||||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
const sql::column& binary_column_criteria::left_column() const {
|
||||
return left_column_;
|
||||
}
|
||||
|
||||
binary_operator binary_column_criteria::operand() const {
|
||||
return operator_;
|
||||
}
|
||||
|
||||
const sql::column& binary_column_criteria::right_column() const {
|
||||
return right_column_;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,6 @@
|
|||
#include "matador/query/criteria/not_criteria.hpp"
|
||||
|
||||
namespace matador::query {
|
||||
criteria_ptr operator==( const sql::column& col_left, const sql::column& col_right ) {
|
||||
return std::make_unique<binary_column_criteria>(col_left, binary_operator::EQUALS, col_right);
|
||||
}
|
||||
|
||||
criteria_ptr operator==(const sql::column &col, utils::placeholder p) {
|
||||
return std::make_unique<binary_criteria>(col, binary_operator::EQUALS, p);
|
||||
}
|
||||
|
|
@ -53,11 +49,11 @@ criteria_ptr in(const sql::column &col, const std::initializer_list<utils::place
|
|||
for ( auto &&arg : args ) {
|
||||
values.emplace_back(arg);
|
||||
}
|
||||
return std::make_unique<collection_criteria>(col, collection_operator::In, std::move(values));
|
||||
return std::make_unique<collection_criteria>(col, collection_operator::IN, std::move(values));
|
||||
}
|
||||
|
||||
criteria_ptr in(const sql::column &col, sql::query_context &&ctx) {
|
||||
return std::make_unique<collection_query_criteria>(col, collection_operator::In, std::move(ctx));
|
||||
return std::make_unique<collection_query_criteria>(col, collection_operator::IN, std::move(ctx));
|
||||
}
|
||||
|
||||
template <>
|
||||
|
|
@ -66,11 +62,11 @@ criteria_ptr out(const sql::column &col, const std::initializer_list<utils::plac
|
|||
for ( auto &&arg : args ) {
|
||||
values.emplace_back(arg);
|
||||
}
|
||||
return std::make_unique<collection_criteria>(col, collection_operator::Out, values);
|
||||
return std::make_unique<collection_criteria>(col, collection_operator::OUT, values);
|
||||
}
|
||||
|
||||
criteria_ptr out(const sql::column &col, sql::query_context &&ctx) {
|
||||
return std::make_unique<collection_query_criteria>(col, collection_operator::In, std::move(ctx));
|
||||
return std::make_unique<collection_query_criteria>(col, collection_operator::IN, std::move(ctx));
|
||||
}
|
||||
|
||||
criteria_ptr between(const sql::column &col, const int64_t min, const int64_t max) {
|
||||
|
|
|
|||
|
|
@ -40,10 +40,10 @@ std::string criteria_evaluator::evaluate(const abstract_criteria &node) {
|
|||
void criteria_evaluator::visit(const between_criteria &node) {
|
||||
query_.bind_vars.emplace_back(node.column().name);
|
||||
query_.bind_vars.emplace_back(node.column().name);
|
||||
clause_ += dialect_.prepare_identifier(node.column()) + " " + dialect_.token_at(sql::dialect_token::Between) + " ";
|
||||
evaluate_value(node.minimum());
|
||||
clause_ += " " + dialect_.token_at(sql::dialect_token::And) + " ";
|
||||
evaluate_value(node.maximum());
|
||||
clause_ += dialect_.prepare_identifier(node.column()) + " " + dialect_.token_at(sql::dialect_token::BETWEEN) + " ";
|
||||
evaluate_value(node.min());
|
||||
clause_ += " " + dialect_.token_at(sql::dialect_token::AND) + " ";
|
||||
evaluate_value(node.max());
|
||||
}
|
||||
|
||||
template<class... Ts> struct overload : Ts... { using Ts::operator()...; };
|
||||
|
|
@ -55,10 +55,6 @@ void criteria_evaluator::visit(const binary_criteria &node) {
|
|||
evaluate_value(node.value());
|
||||
}
|
||||
|
||||
void criteria_evaluator::visit( const binary_column_criteria& node ) {
|
||||
clause_ += dialect_.prepare_condition(node.left_column()) + " " + detail::BinaryOperatorEnum.to_string(node.operand()) + " " + dialect_.prepare_condition(node.right_column());
|
||||
}
|
||||
|
||||
void criteria_evaluator::visit(const collection_criteria &node) {
|
||||
const auto count = node.values().size();
|
||||
for (size_t i = 0; i < count; ++i) {
|
||||
|
|
@ -66,8 +62,8 @@ void criteria_evaluator::visit(const collection_criteria &node) {
|
|||
}
|
||||
|
||||
clause_ += dialect_.prepare_identifier(node.column()) +
|
||||
(node.operand() == collection_operator::Out ? " " + dialect_.token_at(sql::dialect_token::Not) + " " : " ") +
|
||||
dialect_.token_at(sql::dialect_token::In) + " (";
|
||||
(node.operand() == collection_operator::OUT ? " " + dialect_.token_at(sql::dialect_token::NOT) + " " : " ") +
|
||||
dialect_.token_at(sql::dialect_token::IN) + " (";
|
||||
if (node.values().size() < 2) {
|
||||
for (const auto &val: node.values()) {
|
||||
evaluate_value(val);
|
||||
|
|
@ -85,28 +81,28 @@ void criteria_evaluator::visit(const collection_criteria &node) {
|
|||
|
||||
void criteria_evaluator::visit(const collection_query_criteria &node) {
|
||||
clause_ += dialect_.prepare_identifier(node.column()) +
|
||||
(node.operand() == collection_operator::Out ? " " + dialect_.token_at(sql::dialect_token::Not) + " " : " ") +
|
||||
dialect_.token_at(sql::dialect_token::In) + " (" +node.context().sql + ")";
|
||||
(node.operand() == collection_operator::OUT ? " " + dialect_.token_at(sql::dialect_token::NOT) + " " : " ") +
|
||||
dialect_.token_at(sql::dialect_token::IN) + " (" +node.context().sql + ")";
|
||||
}
|
||||
|
||||
void criteria_evaluator::visit(const like_criteria &node) {
|
||||
clause_ += dialect_.prepare_condition(node.column()) + " " + dialect_.token_at(sql::dialect_token::Like) +
|
||||
" " + dialect_.token_at(sql::dialect_token::BeginStringData) + node.pattern() + dialect_.token_at(
|
||||
sql::dialect_token::EndStringData);
|
||||
clause_ += dialect_.prepare_condition(node.column()) + " " + dialect_.token_at(sql::dialect_token::LIKE) +
|
||||
" " + dialect_.token_at(sql::dialect_token::BEGIN_STRING_DATA) + node.pattern() + dialect_.token_at(
|
||||
sql::dialect_token::END_STRING_DATA);
|
||||
}
|
||||
|
||||
void criteria_evaluator::visit(const logical_criteria &node) {
|
||||
clause_ += "(";
|
||||
node.left_clause()->accept(*this);
|
||||
clause_ += " " + dialect_.token_at(node.operand() == logical_operator::AND
|
||||
? sql::dialect_token::And
|
||||
: sql::dialect_token::Or) + " ";
|
||||
? sql::dialect_token::AND
|
||||
: sql::dialect_token::OR) + " ";
|
||||
node.right_clause()->accept(*this);
|
||||
clause_ += ")";
|
||||
}
|
||||
|
||||
void criteria_evaluator::visit(const not_criteria &node) {
|
||||
clause_ += dialect_.token_at(sql::dialect_token::Not) + " (";
|
||||
clause_ += dialect_.token_at(sql::dialect_token::NOT) + " (";
|
||||
node.clause()->accept(*this);
|
||||
clause_ += ")";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,12 +4,10 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
query_execute_where_intermediate query_delete_from_intermediate::where_clause(std::unique_ptr<abstract_criteria> &&cond) {
|
||||
query_execute_where_intermediate query_delete_from_intermediate::where_clause(std::unique_ptr<basic_condition> &&cond)
|
||||
{
|
||||
context_->parts.push_back(std::make_unique<internal::query_where_part>(std::move(cond)));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
query_execute_where_intermediate query_delete_from_intermediate::where( std::unique_ptr<abstract_criteria> cond ) {
|
||||
return where_clause(std::move(cond));
|
||||
}
|
||||
}
|
||||
|
|
@ -8,42 +8,44 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
query_join_intermediate query_from_intermediate::join_left(const sql::table &t) {
|
||||
query_join_intermediate query_from_intermediate::join_left(const sql::table &t)
|
||||
{
|
||||
context_->parts.push_back(std::make_unique<internal::query_join_part>(t));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
query_from_intermediate query_from_intermediate::join_left(join_data &data) {
|
||||
query_from_intermediate query_from_intermediate::join_left(join_data &data)
|
||||
{
|
||||
context_->parts.push_back(std::make_unique<internal::query_join_part>(*data.join_table));
|
||||
context_->parts.push_back(std::make_unique<internal::query_on_part>(std::move(data.condition)));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
query_from_intermediate query_from_intermediate::join_left(std::vector<join_data> &data_vector) {
|
||||
for (auto &[join_table, condition] : data_vector) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_join_part>(*join_table));
|
||||
context_->parts.push_back(std::make_unique<internal::query_on_part>(std::move(condition)));
|
||||
query_from_intermediate query_from_intermediate::join_left(std::vector<join_data> &data_vector)
|
||||
{
|
||||
for (auto &data : data_vector) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_join_part>(*data.join_table));
|
||||
context_->parts.push_back(std::make_unique<internal::query_on_part>(std::move(data.condition)));
|
||||
}
|
||||
return {context_};
|
||||
}
|
||||
|
||||
query_where_intermediate query_from_intermediate::where( std::unique_ptr<abstract_criteria>&& cond ) {
|
||||
return where_clause(std::move(cond));
|
||||
}
|
||||
|
||||
query_where_intermediate query_from_intermediate::where_clause(std::unique_ptr<abstract_criteria> &&cond) {
|
||||
query_where_intermediate query_from_intermediate::where_clause(std::unique_ptr<basic_condition> &&cond)
|
||||
{
|
||||
if (cond) {
|
||||
context_->parts.push_back(std::make_unique<internal::query_where_part>(std::move(cond)));
|
||||
}
|
||||
return {context_};
|
||||
}
|
||||
|
||||
query_group_by_intermediate query_from_intermediate::group_by(const sql::column &col) {
|
||||
query_group_by_intermediate query_from_intermediate::group_by(const sql::column &col)
|
||||
{
|
||||
context_->parts.push_back(std::make_unique<internal::query_group_by_part>(col));
|
||||
return {context_};
|
||||
}
|
||||
|
||||
query_order_by_intermediate query_from_intermediate::order_by(const sql::column &col) {
|
||||
query_order_by_intermediate query_from_intermediate::order_by(const sql::column &col)
|
||||
{
|
||||
context_->parts.push_back(std::make_unique<internal::query_order_by_part>(col));
|
||||
return {context_};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,8 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
query_on_intermediate query_join_intermediate::on( std::unique_ptr<abstract_criteria>&& cond ) {
|
||||
return on_clause(std::move(cond));
|
||||
}
|
||||
|
||||
query_on_intermediate query_join_intermediate::on_clause(std::unique_ptr<abstract_criteria> &&cond) {
|
||||
query_on_intermediate query_join_intermediate::on_clause(std::unique_ptr<basic_condition> &&cond)
|
||||
{
|
||||
context_->parts.push_back(std::make_unique<internal::query_on_part>(std::move(cond)));
|
||||
return {context_};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
namespace matador::query {
|
||||
|
||||
query_execute_where_intermediate query_set_intermediate::where_clause(std::unique_ptr<abstract_criteria> &&cond)
|
||||
query_execute_where_intermediate query_set_intermediate::where_clause(std::unique_ptr<basic_condition> &&cond)
|
||||
{
|
||||
context_->parts.push_back(std::make_unique<internal::query_where_part>(std::move(cond)));
|
||||
return {context_};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
namespace matador::query::internal {
|
||||
|
||||
query_select_part::query_select_part(std::vector<sql::column> columns)
|
||||
: query_part(sql::dialect_token::Select)
|
||||
: query_part(sql::dialect_token::SELECT)
|
||||
, columns_(std::move(columns)) {}
|
||||
|
||||
void query_select_part::accept(query_part_visitor &visitor)
|
||||
|
|
@ -19,7 +19,7 @@ const std::vector<sql::column>& query_select_part::columns() const
|
|||
}
|
||||
|
||||
query_from_part::query_from_part(sql::table t)
|
||||
: query_part(sql::dialect_token::From)
|
||||
: query_part(sql::dialect_token::FROM)
|
||||
, table_(std::move(t)) {}
|
||||
|
||||
const sql::table &query_from_part::table() const
|
||||
|
|
@ -33,7 +33,7 @@ void query_from_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_join_part::query_join_part(sql::table t)
|
||||
: query_part(sql::dialect_token::Join)
|
||||
: query_part(sql::dialect_token::JOIN)
|
||||
, table_(std::move(t)) {}
|
||||
|
||||
const sql::table &query_join_part::table() const
|
||||
|
|
@ -46,11 +46,11 @@ void query_join_part::accept(query_part_visitor &visitor)
|
|||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_on_part::query_on_part(std::unique_ptr<abstract_criteria> &&cond)
|
||||
: query_part(sql::dialect_token::On)
|
||||
query_on_part::query_on_part(std::unique_ptr<basic_condition> &&cond)
|
||||
: query_part(sql::dialect_token::ON)
|
||||
, condition_(std::move(cond)) {}
|
||||
|
||||
const abstract_criteria &query_on_part::condition() const
|
||||
const basic_condition &query_on_part::condition() const
|
||||
{
|
||||
return *condition_;
|
||||
}
|
||||
|
|
@ -60,8 +60,8 @@ void query_on_part::accept(query_part_visitor &visitor)
|
|||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
query_where_part::query_where_part(std::unique_ptr<abstract_criteria> &&cond)
|
||||
: query_part(sql::dialect_token::Where)
|
||||
query_where_part::query_where_part(std::unique_ptr<basic_condition> &&cond)
|
||||
: query_part(sql::dialect_token::WHERE)
|
||||
, condition_(std::move(cond)) {}
|
||||
|
||||
void query_where_part::accept(query_part_visitor &visitor)
|
||||
|
|
@ -69,7 +69,7 @@ void query_where_part::accept(query_part_visitor &visitor)
|
|||
visitor.visit(*this);
|
||||
}
|
||||
|
||||
const abstract_criteria &query_where_part::condition() const
|
||||
const basic_condition &query_where_part::condition() const
|
||||
{
|
||||
return *condition_;
|
||||
}
|
||||
|
|
@ -79,7 +79,7 @@ query_table_name_part::query_table_name_part(sql::dialect_token token, std::stri
|
|||
, table_name_(std::move(table_name)) {}
|
||||
|
||||
query_group_by_part::query_group_by_part(sql::column col)
|
||||
: query_part(sql::dialect_token::GroupBy)
|
||||
: query_part(sql::dialect_token::GROUP_BY)
|
||||
, column_(std::move(col))
|
||||
{}
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ void query_group_by_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_order_by_part::query_order_by_part(sql::column col)
|
||||
: query_part(sql::dialect_token::OrderBy)
|
||||
: query_part(sql::dialect_token::ORDER_BY)
|
||||
, column_(std::move(col))
|
||||
{}
|
||||
|
||||
|
|
@ -109,7 +109,7 @@ void query_order_by_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_order_by_asc_part::query_order_by_asc_part()
|
||||
: query_part(sql::dialect_token::Asc)
|
||||
: query_part(sql::dialect_token::ASC)
|
||||
{}
|
||||
|
||||
void query_order_by_asc_part::accept(query_part_visitor &visitor)
|
||||
|
|
@ -118,7 +118,7 @@ void query_order_by_asc_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_order_by_desc_part::query_order_by_desc_part()
|
||||
: query_part(sql::dialect_token::Desc)
|
||||
: query_part(sql::dialect_token::DESC)
|
||||
{}
|
||||
|
||||
void query_order_by_desc_part::accept(query_part_visitor &visitor)
|
||||
|
|
@ -127,7 +127,7 @@ void query_order_by_desc_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_offset_part::query_offset_part(size_t offset)
|
||||
: query_part(sql::dialect_token::Offset)
|
||||
: query_part(sql::dialect_token::OFFSET)
|
||||
, offset_(offset) {}
|
||||
|
||||
size_t query_offset_part::offset() const
|
||||
|
|
@ -141,7 +141,7 @@ void query_offset_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_limit_part::query_limit_part(size_t limit)
|
||||
: query_part(sql::dialect_token::Limit)
|
||||
: query_part(sql::dialect_token::LIMIT)
|
||||
, limit_(limit) {}
|
||||
|
||||
size_t query_limit_part::limit() const
|
||||
|
|
@ -155,7 +155,7 @@ void query_limit_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_insert_part::query_insert_part()
|
||||
: query_part(sql::dialect_token::Insert) {}
|
||||
: query_part(sql::dialect_token::INSERT) {}
|
||||
|
||||
void query_insert_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
|
|
@ -163,7 +163,7 @@ void query_insert_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_into_part::query_into_part(sql::table t, std::vector<sql::column> columns)
|
||||
: query_part(sql::dialect_token::Insert)
|
||||
: query_part(sql::dialect_token::INSERT)
|
||||
, table_(std::move(t))
|
||||
, columns_(std::move(columns)) {}
|
||||
|
||||
|
|
@ -183,7 +183,7 @@ void query_into_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_values_part::query_values_part(std::vector<std::variant<utils::placeholder, utils::database_type>> &&values)
|
||||
: query_part(sql::dialect_token::Values)
|
||||
: query_part(sql::dialect_token::VALUES)
|
||||
, values_(std::move(values)) {}
|
||||
|
||||
const std::vector<std::variant<utils::placeholder, utils::database_type>>& query_values_part::values() const
|
||||
|
|
@ -197,7 +197,7 @@ void query_values_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_update_part::query_update_part(sql::table table)
|
||||
: query_part(sql::dialect_token::Update)
|
||||
: query_part(sql::dialect_token::UPDATE)
|
||||
, table_(std::move(table)) {}
|
||||
|
||||
const sql::table& query_update_part::table() const
|
||||
|
|
@ -211,7 +211,7 @@ void query_update_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_set_part::query_set_part(const std::vector<key_value_pair>& key_value_pairs)
|
||||
: query_part(sql::dialect_token::Set)
|
||||
: query_part(sql::dialect_token::SET)
|
||||
, key_value_pairs_(key_value_pairs) {}
|
||||
|
||||
const std::vector<key_value_pair> &query_set_part::key_values() const
|
||||
|
|
@ -225,7 +225,7 @@ void query_set_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_delete_part::query_delete_part()
|
||||
: query_part(sql::dialect_token::Remove) {}
|
||||
: query_part(sql::dialect_token::REMOVE) {}
|
||||
|
||||
void query_delete_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
|
|
@ -233,7 +233,7 @@ void query_delete_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_delete_from_part::query_delete_from_part(sql::table table)
|
||||
: query_part(sql::dialect_token::From)
|
||||
: query_part(sql::dialect_token::FROM)
|
||||
, table_(std::move(table)) {}
|
||||
|
||||
const sql::table &query_delete_from_part::table() const
|
||||
|
|
@ -247,7 +247,7 @@ void query_delete_from_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_create_part::query_create_part()
|
||||
: query_part(sql::dialect_token::Create) {}
|
||||
: query_part(sql::dialect_token::CREATE) {}
|
||||
|
||||
void query_create_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
|
|
@ -255,7 +255,7 @@ void query_create_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_create_table_part::query_create_table_part(sql::table table, std::vector<object::attribute_definition> columns)
|
||||
: query_part(sql::dialect_token::Table)
|
||||
: query_part(sql::dialect_token::TABLE)
|
||||
, table_(std::move(table))
|
||||
, columns_(std::move(columns)) {}
|
||||
|
||||
|
|
@ -275,7 +275,7 @@ void query_create_table_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_drop_part::query_drop_part()
|
||||
: query_part(sql::dialect_token::Drop) {}
|
||||
: query_part(sql::dialect_token::DROP) {}
|
||||
|
||||
void query_drop_part::accept(query_part_visitor &visitor)
|
||||
{
|
||||
|
|
@ -283,7 +283,7 @@ void query_drop_part::accept(query_part_visitor &visitor)
|
|||
}
|
||||
|
||||
query_drop_table_part::query_drop_table_part(sql::table table)
|
||||
: query_part(sql::dialect_token::Table)
|
||||
: query_part(sql::dialect_token::TABLE)
|
||||
, table_(std::move(table)) {}
|
||||
|
||||
const sql::table &query_drop_table_part::table() const
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
#include "matador/query/attribute_string_writer.hpp"
|
||||
#include "matador/query/query_data.hpp"
|
||||
#include "matador/query/criteria_evaluator.hpp"
|
||||
|
||||
#include "matador/query/internal/basic_type_to_string_visitor.hpp"
|
||||
#include "matador/query/internal/query_parts.hpp"
|
||||
|
|
@ -17,7 +16,7 @@ namespace matador::query {
|
|||
|
||||
sql::query_context query_compiler::compile(const query_data &data,
|
||||
const sql::dialect &d,
|
||||
const std::optional<std::reference_wrapper<const sql::connection_impl>> conn)
|
||||
std::optional<std::reference_wrapper<const sql::connection_impl>> conn)
|
||||
{
|
||||
data_ = &data;
|
||||
dialect_ = &d;
|
||||
|
|
@ -54,7 +53,7 @@ std::string handle_column(sql::query_context &ctx, const sql::dialect *d, const
|
|||
void query_compiler::visit(internal::query_select_part &select_part)
|
||||
{
|
||||
query_.command = sql::sql_command::SQL_SELECT;
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::Select) + " ";
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::SELECT) + " ";
|
||||
|
||||
query_.prototype.clear();
|
||||
|
||||
|
|
@ -87,58 +86,59 @@ void query_compiler::visit(internal::query_join_part &join_part)
|
|||
query_.sql += " " + query_compiler::build_table_name(join_part.token(), *dialect_, join_part.table());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_on_part &on_part) {
|
||||
criteria_evaluator evaluator(*dialect_, query_);
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::On) +
|
||||
" " + evaluator.evaluate(on_part.condition());
|
||||
void query_compiler::visit(internal::query_on_part &on_part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::ON) +
|
||||
" " + on_part.condition().evaluate(*dialect_, query_);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_where_part &where_part) {
|
||||
criteria_evaluator evaluator(*dialect_, query_);
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Where) +
|
||||
" " + evaluator.evaluate(where_part.condition());
|
||||
void query_compiler::visit(internal::query_where_part &where_part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::WHERE) +
|
||||
" " + where_part.condition().evaluate(*dialect_, query_);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_group_by_part &group_by_part) {
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::GroupBy) + " " + dialect_->prepare_identifier(group_by_part.column());
|
||||
void query_compiler::visit(internal::query_group_by_part &group_by_part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::GROUP_BY) + " " + dialect_->prepare_identifier(group_by_part.column());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_order_by_part &order_by_part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::OrderBy) +
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::ORDER_BY) +
|
||||
" " + dialect_->prepare_condition(order_by_part.column());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_order_by_asc_part &/*order_by_asc_part*/)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Asc);
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::ASC);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_order_by_desc_part &/*order_by_desc_part*/)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Desc);
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::DESC);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_offset_part &offset_part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Offset) + " " + std::to_string(offset_part.offset());
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::OFFSET) + " " + std::to_string(offset_part.offset());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_limit_part &limit_part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Limit) + " " + std::to_string(limit_part.limit());
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::LIMIT) + " " + std::to_string(limit_part.limit());
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_insert_part &/*insert_part*/)
|
||||
{
|
||||
query_.command = sql::sql_command::SQL_INSERT;
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::Insert);
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::INSERT);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_into_part &into_part)
|
||||
{
|
||||
query_.table = into_part.table();
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Into) +
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::INTO) +
|
||||
" " + dialect_->prepare_identifier_string(into_part.table().name);
|
||||
|
||||
std::string result{"("};
|
||||
|
|
@ -185,7 +185,7 @@ std::string query_compiler::determine_value(value_visitor &visitor, const std::v
|
|||
}
|
||||
|
||||
void query_compiler::visit(internal::query_values_part &values_part) {
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Values);
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::VALUES);
|
||||
|
||||
attribute_string_writer writer(*dialect_, connection_);
|
||||
|
||||
|
|
@ -220,7 +220,7 @@ void query_compiler::visit(internal::query_update_part &update_part)
|
|||
void query_compiler::visit(internal::query_delete_part &/*delete_part*/)
|
||||
{
|
||||
query_.command = sql::sql_command::SQL_DELETE;
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::Remove);
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::REMOVE);
|
||||
}
|
||||
|
||||
void query_compiler::visit(internal::query_delete_from_part &delete_from_part)
|
||||
|
|
@ -232,7 +232,7 @@ void query_compiler::visit(internal::query_delete_from_part &delete_from_part)
|
|||
void query_compiler::visit(internal::query_create_part &/*create_part*/)
|
||||
{
|
||||
query_.command = sql::sql_command::SQL_CREATE_TABLE;
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::Create);
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::CREATE);
|
||||
}
|
||||
|
||||
struct fk_context {
|
||||
|
|
@ -250,7 +250,7 @@ std::string build_create_column(const object::attribute_definition &col, const s
|
|||
|
||||
void query_compiler::visit(internal::query_create_table_part &create_table_part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Table) + " " + dialect_->prepare_identifier_string(create_table_part.table().name) + " ";
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::TABLE) + " " + dialect_->prepare_identifier_string(create_table_part.table().name) + " ";
|
||||
query_.table = create_table_part.table();
|
||||
|
||||
std::string result = "(";
|
||||
|
|
@ -290,7 +290,7 @@ void query_compiler::visit(internal::query_create_table_part &create_table_part)
|
|||
void query_compiler::visit(internal::query_drop_part &/*drop_part*/)
|
||||
{
|
||||
query_.command = sql::sql_command::SQL_DROP_TABLE;
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::Drop);
|
||||
query_.sql = dialect_->token_at(sql::dialect_token::DROP);
|
||||
}
|
||||
|
||||
std::string query_compiler::determine_set_value(internal::basic_type_to_string_visitor &visitor, const utils::database_type &val) {
|
||||
|
|
@ -305,7 +305,7 @@ std::string query_compiler::determine_set_value(internal::basic_type_to_string_v
|
|||
|
||||
void query_compiler::visit(internal::query_set_part &set_part)
|
||||
{
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::Set) + " ";
|
||||
query_.sql += " " + dialect_->token_at(sql::dialect_token::SET) + " ";
|
||||
|
||||
attribute_string_writer writer(*dialect_, connection_);
|
||||
internal::basic_type_to_string_visitor visitor(writer, query_);
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ std::string connection::type() const {
|
|||
}
|
||||
|
||||
utils::result<void, utils::error> connection::begin() const {
|
||||
const auto res = connection_->execute(dialect().token_at(dialect_token::Begin));
|
||||
const auto res = connection_->execute(dialect().token_at(dialect_token::BEGIN));
|
||||
if (res.is_error()) {
|
||||
return utils::failure(res.err());
|
||||
}
|
||||
|
|
@ -120,7 +120,7 @@ utils::result<void, utils::error> connection::begin() const {
|
|||
}
|
||||
|
||||
utils::result<void, utils::error> connection::commit() const {
|
||||
const auto res = connection_->execute(dialect().token_at(dialect_token::Commit));
|
||||
const auto res = connection_->execute(dialect().token_at(dialect_token::COMMIT));
|
||||
if (res.is_error()) {
|
||||
return utils::failure(res.err());
|
||||
}
|
||||
|
|
@ -129,7 +129,7 @@ utils::result<void, utils::error> connection::commit() const {
|
|||
}
|
||||
|
||||
utils::result<void, utils::error> connection::rollback() const {
|
||||
const auto res = connection_->execute(dialect().token_at(dialect_token::Rollback));
|
||||
const auto res = connection_->execute(dialect().token_at(dialect_token::ROLLBACK));
|
||||
if (res.is_error()) {
|
||||
return utils::failure(res.err());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ std::string dialect::to_sql_string(const utils::value &val) const {
|
|||
return "NULL";
|
||||
}
|
||||
if (val.is_string()) {
|
||||
return token_at(dialect_token::BeginStringData) + val.str() + token_at(dialect_token::BeginStringData);
|
||||
return token_at(dialect_token::BEGIN_STRING_DATA) + val.str() + token_at(dialect_token::BEGIN_STRING_DATA);
|
||||
}
|
||||
|
||||
return val.str();
|
||||
|
|
@ -94,14 +94,14 @@ std::string dialect::prepare_literal(const std::string &str) const
|
|||
|
||||
void dialect::quote_identifier(std::string &str) const
|
||||
{
|
||||
str.insert(0, token_at(dialect_token::StartQuote));
|
||||
str += token_at(dialect_token::EndQuote);
|
||||
str.insert(0, token_at(dialect_token::START_QUOTE));
|
||||
str += token_at(dialect_token::END_QUOTE);
|
||||
}
|
||||
|
||||
void dialect::escape_quotes_in_identifier(std::string &str) const
|
||||
{
|
||||
const std::string open_char(token_at(dialect_token::StartQuote));
|
||||
const std::string close_char(token_at(dialect_token::EndQuote));
|
||||
const std::string open_char(token_at(dialect_token::START_QUOTE));
|
||||
const std::string close_char(token_at(dialect_token::END_QUOTE));
|
||||
if (identifier_escape_type() == escape_identifier_t::ESCAPE_CLOSING_BRACKET) {
|
||||
utils::replace_all(str, close_char, close_char + close_char);
|
||||
} else {
|
||||
|
|
@ -111,8 +111,8 @@ void dialect::escape_quotes_in_identifier(std::string &str) const
|
|||
|
||||
void dialect::escape_quotes_in_literals(std::string &str) const
|
||||
{
|
||||
const std::string single_quote(token_at(dialect_token::StringQuote));
|
||||
const std::string double_quote(token_at(dialect_token::StringQuote) + token_at(dialect_token::StringQuote));
|
||||
const std::string single_quote(token_at(dialect_token::STRING_QUOTE));
|
||||
const std::string double_quote(token_at(dialect_token::STRING_QUOTE) + token_at(dialect_token::STRING_QUOTE));
|
||||
utils::replace_all(str, single_quote, double_quote);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ TEST_CASE_METHOD( QueryFixture, "Test quoted identifier", "[query][quotes][ident
|
|||
TEST_CASE_METHOD( QueryFixture, "Test quoted column names", "[query][quotes][column]" ) {
|
||||
using namespace matador::sql;
|
||||
|
||||
const auto start_quote = db.dialect().token_at(matador::sql::dialect_token::StartQuote);
|
||||
const auto end_quote = db.dialect().token_at(matador::sql::dialect_token::EndQuote);
|
||||
const auto start_quote = db.dialect().token_at(matador::sql::dialect_token::START_QUOTE);
|
||||
const auto end_quote = db.dialect().token_at(matador::sql::dialect_token::END_QUOTE);
|
||||
|
||||
const std::string column_name = "name_with_" + start_quote + "open_close_quotes" + end_quote + "_in_backend_ctx";
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ add_executable(OrmTests
|
|||
backend/test_statement.hpp
|
||||
orm/SessionInsertBuilderTest.cpp
|
||||
orm/SessionQueryBuilderTest.cpp
|
||||
query/ConditionTests.cpp
|
||||
query/QueryBuilderTest.cpp
|
||||
query/QueryFixture.cpp
|
||||
query/QueryFixture.hpp
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include "matador/sql/column.hpp"
|
||||
#include "matador/sql/table.hpp"
|
||||
|
||||
#include "matador/query/criteria_evaluator.hpp"
|
||||
#include "matador/query/query.hpp"
|
||||
|
||||
#include "matador/orm/session_query_builder.hpp"
|
||||
|
|
@ -63,16 +62,15 @@ TEST_CASE("Create sql query data for entity with eager has one", "[query][entity
|
|||
|
||||
query_context qc;
|
||||
size_t index{0};
|
||||
criteria_evaluator evaluator(db.dialect(), qc);
|
||||
for (const auto &[join_table, condition] : data->joins) {
|
||||
REQUIRE(join_table->name == expected_join_data[index].first);
|
||||
REQUIRE(evaluator.evaluate(*condition) == expected_join_data[index].second);
|
||||
for (const auto &jd : data->joins) {
|
||||
REQUIRE(jd.join_table->name == expected_join_data[index].first);
|
||||
REQUIRE(jd.condition->evaluate(db.dialect(), qc) == expected_join_data[index].second);
|
||||
++index;
|
||||
}
|
||||
|
||||
REQUIRE(data->where_clause.get());
|
||||
auto cond = evaluator.evaluate(*data->where_clause);
|
||||
REQUIRE(cond == R"("t01"."id" = ?)");
|
||||
REQUIRE(data->where_clause);
|
||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||
REQUIRE(cond == R"("t01"."id" = 17)");
|
||||
}
|
||||
|
||||
TEST_CASE("Create sql query data for entity with eager belongs to", "[query][entity][builder]") {
|
||||
|
|
@ -113,16 +111,15 @@ TEST_CASE("Create sql query data for entity with eager belongs to", "[query][ent
|
|||
|
||||
query_context qc;
|
||||
size_t index{0};
|
||||
criteria_evaluator evaluator(db.dialect(), qc);
|
||||
for (const auto &jd : data->joins) {
|
||||
REQUIRE(jd.join_table->name == expected_join_data[index].first);
|
||||
REQUIRE(evaluator.evaluate(*jd.condition) == expected_join_data[index].second);
|
||||
REQUIRE(jd.condition->evaluate(db.dialect(), qc) == expected_join_data[index].second);
|
||||
++index;
|
||||
}
|
||||
|
||||
REQUIRE(data->where_clause.get());
|
||||
auto cond = evaluator.evaluate(*data->where_clause);
|
||||
REQUIRE(cond == R"("t01"."id" = ?)");
|
||||
REQUIRE(data->where_clause);
|
||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||
REQUIRE(cond == R"("t01"."id" = 17)");
|
||||
|
||||
auto q = matador::query::query::select(data->columns)
|
||||
.from(data->root_table->name);
|
||||
|
|
@ -183,16 +180,15 @@ TEST_CASE("Create sql query data for entity with eager has many belongs to", "[q
|
|||
|
||||
query_context qc;
|
||||
size_t index{0};
|
||||
criteria_evaluator evaluator(db.dialect(), qc);
|
||||
for (const auto &jd : data->joins) {
|
||||
REQUIRE(jd.join_table->name == expected_join_data[index].first);
|
||||
REQUIRE(evaluator.evaluate(*jd.condition) == expected_join_data[index].second);
|
||||
REQUIRE(jd.condition->evaluate(db.dialect(), qc) == expected_join_data[index].second);
|
||||
++index;
|
||||
}
|
||||
|
||||
REQUIRE(data->where_clause.get());
|
||||
auto cond = evaluator.evaluate(*data->where_clause);
|
||||
REQUIRE(cond == R"("t01"."order_id" = ?)");
|
||||
REQUIRE(data->where_clause);
|
||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||
REQUIRE(cond == R"("t01"."order_id" = 17)");
|
||||
}
|
||||
|
||||
TEST_CASE("Create sql query data for entity with eager many to many", "[query][entity][builder]") {
|
||||
|
|
@ -229,16 +225,15 @@ TEST_CASE("Create sql query data for entity with eager many to many", "[query][e
|
|||
|
||||
query_context qc;
|
||||
size_t index{0};
|
||||
criteria_evaluator evaluator(db.dialect(), qc);
|
||||
for (const auto &jd : data->joins) {
|
||||
REQUIRE(jd.join_table->name == expected_join_data[index].first);
|
||||
REQUIRE(evaluator.evaluate(*jd.condition) == expected_join_data[index].second);
|
||||
REQUIRE(jd.condition->evaluate(db.dialect(), qc) == expected_join_data[index].second);
|
||||
++index;
|
||||
}
|
||||
|
||||
REQUIRE(data->where_clause.get());
|
||||
auto cond = evaluator.evaluate(*data->where_clause);
|
||||
REQUIRE(cond == R"("t01"."id" = ?)");
|
||||
REQUIRE(data->where_clause);
|
||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||
REQUIRE(cond == R"("t01"."id" = 17)");
|
||||
}
|
||||
|
||||
TEST_CASE("Create sql query data for entity with eager many to many (inverse part)", "[query][entity][builder]") {
|
||||
|
|
@ -275,16 +270,15 @@ TEST_CASE("Create sql query data for entity with eager many to many (inverse par
|
|||
|
||||
query_context qc;
|
||||
size_t index{0};
|
||||
criteria_evaluator evaluator(db.dialect(), qc);
|
||||
for (const auto &jd : data->joins) {
|
||||
REQUIRE(jd.join_table->name == expected_join_data[index].first);
|
||||
REQUIRE(evaluator.evaluate(*jd.condition) == expected_join_data[index].second);
|
||||
REQUIRE(jd.condition->evaluate(db.dialect(), qc) == expected_join_data[index].second);
|
||||
++index;
|
||||
}
|
||||
|
||||
REQUIRE(data->where_clause.get());
|
||||
auto cond = evaluator.evaluate(*data->where_clause);
|
||||
REQUIRE(cond == R"("t01"."id" = ?)");
|
||||
REQUIRE(data->where_clause);
|
||||
auto cond = data->where_clause->evaluate(db.dialect(), qc);
|
||||
REQUIRE(cond == R"("t01"."id" = 17)");
|
||||
}
|
||||
|
||||
TEST_CASE("Test eager relationship", "[session][eager]") {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,112 @@
|
|||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
#include "matador/query/condition.hpp"
|
||||
|
||||
#include "matador/sql/dialect_builder.hpp"
|
||||
|
||||
using namespace matador::sql;
|
||||
using namespace matador::query;
|
||||
|
||||
class ConditionFixture {
|
||||
protected:
|
||||
dialect dlc = dialect_builder::builder()
|
||||
.create()
|
||||
.build();
|
||||
query_context ctx;
|
||||
};
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test column user defined literal", "[column][literal]") {
|
||||
const auto col = "name"_col;
|
||||
|
||||
REQUIRE(col.name == "name");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test logical condition", "[condition][logical]") {
|
||||
const auto name_col = "name"_col;
|
||||
|
||||
REQUIRE(name_col.name == "name");
|
||||
|
||||
auto cond1 = name_col != "george";
|
||||
|
||||
auto clause = cond1.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "\"name\" <> 'george'");
|
||||
|
||||
auto cond2 = "age"_col != 9;
|
||||
clause = cond2.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "\"age\" <> 9");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test and condition", "[condition][bin][and]") {
|
||||
const auto name_col = "name"_col;
|
||||
|
||||
REQUIRE(name_col.name == "name");
|
||||
|
||||
const auto cond = name_col == "Hans" && name_col == "Dieter";
|
||||
|
||||
auto clause = cond.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "(\"name\" = 'Hans' AND \"name\" = 'Dieter')");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test or condition", "[condition][bin][or]") {
|
||||
const auto name_col = "name"_col;
|
||||
|
||||
REQUIRE(name_col.name == "name");
|
||||
|
||||
const auto cond = name_col == "Hans" || name_col == "Dieter";
|
||||
|
||||
auto clause = cond.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "\"name\" = 'Hans' OR \"name\" = 'Dieter'");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test not condition", "[condition][not]") {
|
||||
const auto name_col = "name"_col;
|
||||
|
||||
REQUIRE(name_col.name == "name");
|
||||
|
||||
const auto cond = !(name_col != "Hans");
|
||||
|
||||
auto clause = cond.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "NOT (\"name\" <> 'Hans')");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test in condition", "[condition][in]") {
|
||||
const auto age_col = "age"_col;
|
||||
|
||||
REQUIRE(age_col.name == "age");
|
||||
auto cond = age_col != 7 && in(age_col, {7,5,5,8});
|
||||
|
||||
auto clause = cond.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "(\"age\" <> 7 AND \"age\" IN (7, 5, 5, 8))");
|
||||
|
||||
cond = age_col != 7 && in(age_col, {7});
|
||||
clause = cond.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "(\"age\" <> 7 AND \"age\" IN (7))");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test in query condition", "[condition][in query]") {
|
||||
const auto age_col = "age"_col;
|
||||
const auto name_col = "name"_col;
|
||||
|
||||
query_context sub_ctx;
|
||||
sub_ctx.sql = R"(SELECT "name" FROM "test")";
|
||||
|
||||
auto cond = age_col != 7 && in_old(name_col, std::move(sub_ctx));
|
||||
auto clause = cond.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "(\"age\" <> 7 AND \"name\" IN (SELECT \"name\" FROM \"test\"))");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test between condition", "[condition][between]") {
|
||||
const auto age_col = "age"_col;
|
||||
|
||||
auto cond = age_col != 7 && between(age_col, 21, 30);
|
||||
auto clause = cond.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "(\"age\" <> 7 AND \"age\" BETWEEN 21 AND 30)");
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(ConditionFixture, "Test like condition", "[condition][like]") {
|
||||
const auto name_col = "name"_col;
|
||||
|
||||
auto cond = like_old(name_col, "%er%");
|
||||
auto clause = cond.evaluate(dlc, ctx);
|
||||
REQUIRE(clause == "\"name\" LIKE '%er%'");
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "QueryFixture.hpp"
|
||||
|
||||
#include <matador/query/criteria.hpp>
|
||||
#include <matador/query/condition.hpp>
|
||||
#include <matador/query/query.hpp>
|
||||
|
||||
#include "matador/object/attribute_definition_generator.hpp"
|
||||
|
|
|
|||
Loading…
Reference in New Issue