From 6fa56b2019c8eefa181e2108b51f424b8aec1a66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20K=C3=BChl?= Date: Mon, 27 Oct 2025 16:24:51 +0100 Subject: [PATCH] removed condition classes, functions and operators --- include/matador/query/basic_condition.hpp | 66 --- include/matador/query/condition.hpp | 635 ---------------------- source/orm/query/basic_condition.cpp | 26 - source/orm/query/condition.cpp | 44 -- test/orm/query/ConditionTests.cpp | 112 ---- 5 files changed, 883 deletions(-) delete mode 100644 include/matador/query/basic_condition.hpp delete mode 100644 include/matador/query/condition.hpp delete mode 100644 source/orm/query/basic_condition.cpp delete mode 100644 source/orm/query/condition.cpp delete mode 100644 test/orm/query/ConditionTests.cpp diff --git a/include/matador/query/basic_condition.hpp b/include/matador/query/basic_condition.hpp deleted file mode 100644 index 65b0456..0000000 --- a/include/matador/query/basic_condition.hpp +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef QUERY_BASIC_CONDITION_HPP -#define QUERY_BASIC_CONDITION_HPP - -#include "matador/sql/column.hpp" - -#include -#include -#include - -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 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 diff --git a/include/matador/query/condition.hpp b/include/matador/query/condition.hpp deleted file mode 100644 index 91013fd..0000000 --- a/include/matador/query/condition.hpp +++ /dev/null @@ -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 -#include - -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 condition; - -template<> -class condition> 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 condition && - !std::is_same_v && - !std::is_same_v>> 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 condition || - std::is_same_v>>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 condition && - !std::is_same_v && - !std::is_same_v>> 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 condition || - std::is_same_v>> 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> 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 &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 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 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> 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 &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 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 condition, condition> 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 &&l, condition &&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 left; - condition 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 condition, void> final : public basic_condition -{ -public: - /** - * @brief Create a logical unary condition - * @param c The condition to be negated - */ - condition(const condition &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 cond; - std::string operand; -}; - -template<> -class condition 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> in(const sql::column &col, std::initializer_list args) -{ - return condition>(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 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 -condition> between(const sql::column &col, T low, T high) -{ - return condition>(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 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 -condition operator==(const sql::column &col, T val) -{ - return condition(col, basic_condition::operand_type::EQUAL, val); -} - -condition 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 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 -condition operator!=(const sql::column &col, T val) -{ - return condition(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 -condition operator<(const sql::column &col, T val) -{ - return condition(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 -condition operator<=(const sql::column &col, T val) -{ - return condition(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 -condition operator>(const sql::column &col, T val) -{ - return condition(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 -condition operator>=(const sql::column &col, T val) -{ - return condition(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 -condition, condition> operator&&(condition l, condition r) -{ - return condition, condition>(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 -condition, condition> operator||(condition l, condition r) -{ - return condition, condition>(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 -condition, void> operator!(condition c) -{ - return condition, 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 -std::unique_ptr make_condition(const condition &cond) -{ - return std::make_unique>(cond); -} - -} - -#endif //QUERY_CONDITION_HPP diff --git a/source/orm/query/basic_condition.cpp b/source/orm/query/basic_condition.cpp deleted file mode 100644 index 1d07bbd..0000000 --- a/source/orm/query/basic_condition.cpp +++ /dev/null @@ -1,26 +0,0 @@ -#include "matador/query/basic_condition.hpp" - -namespace matador::query { - -std::unordered_map 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)) -{ } -} \ No newline at end of file diff --git a/source/orm/query/condition.cpp b/source/orm/query/condition.cpp deleted file mode 100644 index f9c8c6e..0000000 --- a/source/orm/query/condition.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include "matador/query/condition.hpp" - -namespace matador::query { - -condition::condition(const sql::column &fld, const operand_type op, const utils::placeholder &val) -: basic_column_condition(fld, op), value(val) -{} - -std::string condition::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::condition(sql::column col, const operand_type op, sql::query_context &q) -: basic_column_condition(std::move(col), op), query_(q) -{} - -std::string condition::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::evaluate(const sql::dialect &d, sql::query_context &/*query*/) const { - return d.prepare_condition(field_) + " " + operand + " " + d.prepare_condition(other_column_); -} - -condition in_old(const sql::column &col, sql::query_context &&q) -{ - return {col, basic_condition::operand_type::IN_LIST, q}; -} - -condition like_old(const sql::column &col, const std::string &val) { - return { col, basic_condition::operand_type::LIKE, val }; -} - -condition operator==(const sql::column &a, const sql::column &b) -{ - return {a, basic_condition::operand_type::EQUAL, b}; -} -} \ No newline at end of file diff --git a/test/orm/query/ConditionTests.cpp b/test/orm/query/ConditionTests.cpp deleted file mode 100644 index 0e6fa41..0000000 --- a/test/orm/query/ConditionTests.cpp +++ /dev/null @@ -1,112 +0,0 @@ -#include - -#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%'"); -}