removed condition classes, functions and operators
This commit is contained in:
parent
f29f642e72
commit
6fa56b2019
|
|
@ -1,66 +0,0 @@
|
||||||
#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
|
|
||||||
|
|
@ -1,635 +0,0 @@
|
||||||
#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
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
#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))
|
|
||||||
{ }
|
|
||||||
}
|
|
||||||
|
|
@ -1,44 +0,0 @@
|
||||||
#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};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,112 +0,0 @@
|
||||||
#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%'");
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue