initial commit

This commit is contained in:
Sascha Kühl 2025-10-17 15:51:35 +02:00
commit 6ffa9de6d0
22 changed files with 506 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.idea/

7
CMakeLists.txt Normal file
View File

@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 4.0)
project(condition)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(src)

View File

@ -0,0 +1,23 @@
#ifndef CONDITION_BETWEEN_CONDITION_NODE_HPP
#define CONDITION_BETWEEN_CONDITION_NODE_HPP
#include "column.hpp"
#include "condition_node.hpp"
#include "value.hpp"
namespace matador::condition {
class between_condition_node final : public condition_node {
public:
between_condition_node() = delete;
between_condition_node(column column, value min, value max);
void accept(condition_node_visitor& visitor) const override;
private:
column column_;
value min_;
value max_;
};
}
#endif //CONDITION_BETWEEN_CONDITION_NODE_HPP

View File

@ -0,0 +1,31 @@
#ifndef CONDITION_BINARY_CONDITION_NODE_HPP
#define CONDITION_BINARY_CONDITION_NODE_HPP
#include "matador/condition/condition_node.hpp"
#include "matador/condition/column.hpp"
#include "matador/condition/value.hpp"
namespace matador::condition {
enum class binary_operator {
EQUALS,
NOT_EQUALS,
GREATER_THAN,
GREATER_THAN_OR_EQUAL,
LESS_THAN,
LESS_THAN_OR_EQUAL,
};
class binary_condition_node final : public condition_node {
public:
binary_condition_node() = delete;
binary_condition_node( column column, binary_operator operator_, value value );
void accept( condition_node_visitor& visitor ) const override;
private:
column column_;
binary_operator operator_{};
value value_;
};
}
#endif //CONDITION_BINARY_CONDITION_NODE_HPP

View File

@ -0,0 +1,27 @@
#ifndef CONDITION_COLLECTION_CONDITION_NODE_HPP
#define CONDITION_COLLECTION_CONDITION_NODE_HPP
#include "column.hpp"
#include "condition_node.hpp"
#include "value.hpp"
namespace matador::condition {
enum class collection_operator {
IN,
OUT
};
class collection_condition_node final : public condition_node {
public:
collection_condition_node() = delete;
collection_condition_node(column col, collection_operator operator_, std::vector<value> values);
collection_condition_node(column col, collection_operator operator_, std::initializer_list<value> values);
void accept(condition_node_visitor& visitor) const override;
private:
column column_;
collection_operator operator_;
std::vector<value> values_;
};
}
#endif //CONDITION_COLLECTION_CONDITION_NODE_HPP

View File

@ -0,0 +1,23 @@
#ifndef CONDITION_COLUMN_HPP
#define CONDITION_COLUMN_HPP
#include <string>
namespace matador::condition {
class column {
public:
explicit column(std::string name);
explicit column(std::string table_name, std::string name);
[[nodiscard]] const std::string& table() const;
[[nodiscard]] const std::string& name() const;
private:
std::string table_{};
std::string name_{};
};
column operator ""_col(const char *name, size_t len);
}
#endif //CONDITION_COLUMN_HPP

View File

@ -0,0 +1,20 @@
#ifndef CONDITION_CONDITION_NODE_HPP
#define CONDITION_CONDITION_NODE_HPP
#include <memory>
namespace matador::condition {
class condition_node_visitor;
class condition_node {
public:
virtual ~condition_node() = default;
virtual void accept(condition_node_visitor& visitor) const = 0;
};
using condition_node_ptr = std::unique_ptr<condition_node>;
}
#endif //CONDITION_CONDITION_NODE_HPP

View File

@ -0,0 +1,22 @@
#ifndef CONDITION_CONDITION_NODE_VISITOR_HPP
#define CONDITION_CONDITION_NODE_VISITOR_HPP
namespace matador::condition {
class between_condition_node;
class binary_condition_node;
class logical_condition_node;
class not_condition_node;
class collection_condition_node;
class condition_node_visitor {
public:
virtual ~condition_node_visitor() = default;
virtual void visit(const between_condition_node &node) = 0;
virtual void visit(const binary_condition_node &node) = 0;
virtual void visit(const collection_condition_node &node) = 0;
virtual void visit(const logical_condition_node &node) = 0;
virtual void visit(const not_condition_node &node) = 0;
};
}
#endif //CONDITION_CONDITION_NODE_VISITOR_HPP

View File

@ -0,0 +1,65 @@
#ifndef CONDITION_CONDITION_OPERATORS_HPP
#define CONDITION_CONDITION_OPERATORS_HPP
#include "matador/condition/binary_condition_node.hpp"
#include "matador/condition/collection_condition_node.hpp"
#include "matador/condition/column.hpp"
namespace matador::condition {
template<class Type>
condition_node_ptr operator==(const column &col, Type val) {
return std::make_unique<binary_condition_node>(col, binary_operator::EQUALS, val);
}
template<class Type>
condition_node_ptr operator!=(const column &col, Type val) {
return std::make_unique<binary_condition_node>(col, binary_operator::NOT_EQUALS, val);
}
template<class Type>
condition_node_ptr operator>(const column &col, Type val) {
return std::make_unique<binary_condition_node>(col, binary_operator::GREATER_THAN, val);
}
template<class Type>
condition_node_ptr operator>=(const column &col, Type val) {
return std::make_unique<binary_condition_node>(col, binary_operator::GREATER_THAN_OR_EQUAL, val);
}
template<class Type>
condition_node_ptr operator<(const column &col, Type val) {
return std::make_unique<binary_condition_node>(col, binary_operator::LESS_THAN, val);
}
template<class Type>
condition_node_ptr operator<=(const column &col, Type val) {
return std::make_unique<binary_condition_node>(col, binary_operator::LESS_THAN_OR_EQUAL, val);
}
condition_node_ptr operator&&(condition_node_ptr left, condition_node_ptr right);
condition_node_ptr operator||(condition_node_ptr left, condition_node_ptr right);
condition_node_ptr operator!(condition_node_ptr cond);
template < class Type >
condition_node_ptr in(const column &col, std::initializer_list<Type> args) {
std::vector<value> values;
for ( auto &&arg : args ) {
values.emplace_back(std::move(arg));
}
return std::make_unique<collection_condition_node>(col, collection_operator::IN, std::move(values));
}
template < class V >
condition_node_ptr out(const column &col, std::initializer_list<V> args) {
std::vector<value> values;
for ( auto &&arg : args ) {
values.emplace_back(std::move(arg));
}
return std::make_unique<collection_condition_node>(col, collection_operator::OUT, values);
}
}
#endif //CONDITION_CONDITION_OPERATORS_HPP

View File

@ -0,0 +1,25 @@
#ifndef CONDITION_LOGICAL_CONDITION_NODE_HPP
#define CONDITION_LOGICAL_CONDITION_NODE_HPP
#include "condition_node.hpp"
namespace matador::condition {
enum class logical_operator {
AND,
OR,
};
class logical_condition_node final : public condition_node {
public:
logical_condition_node() = delete;
logical_condition_node(condition_node_ptr left, logical_operator op, condition_node_ptr right);
void accept(condition_node_visitor& visitor) const override;
private:
std::unique_ptr<condition_node> left_;
logical_operator op_;
std::unique_ptr<condition_node> right_;
};
}
#endif //CONDITION_LOGICAL_CONDITION_NODE_HPP

View File

@ -0,0 +1,18 @@
#ifndef CONDITION_NOT_CONDITION_NODE_HPP
#define CONDITION_NOT_CONDITION_NODE_HPP
#include "matador/condition/condition_node.hpp"
namespace matador::condition {
class not_condition_node final : public condition_node {
public:
not_condition_node(condition_node_ptr condition);
void accept(condition_node_visitor& visitor) const override;
private:
condition_node_ptr condition_;
};
}
#endif //CONDITION_NOT_CONDITION_NODE_HPP

View File

@ -0,0 +1,23 @@
#ifndef CONDITION_TYPES_HPP
#define CONDITION_TYPES_HPP
#include <variant>
#include <string>
#include <vector>
namespace matador::condition {
using byte = unsigned char;
using blob = std::vector<byte>;
using basic_types = std::variant<
uint8_t, uint16_t, uint32_t, uint64_t,
int8_t, int16_t, int32_t, int64_t,
float, double,
bool,
const char*,
std::string,
blob,
nullptr_t>;
}
#endif //CONDITION_TYPES_HPP

View File

@ -0,0 +1,41 @@
#ifndef CONDITION_VALUE_HPP
#define CONDITION_VALUE_HPP
#include "types.hpp"
#include <optional>
namespace matador::condition {
class value final {
public:
value() = default;
template<typename Type>
value(const Type& value) : value_(value) {}
value(const value &x) = default;
value& operator=(const value &x) = default;
value(value &&x) noexcept = default;
value& operator=(value &&x) noexcept = default;
~value() = default;
template<class Type>
std::optional<Type> as() const {
if (std::holds_alternative<Type>(value_)) {
return std::get<Type>(value_);
}
return std::nullopt;
}
template<class Type>
bool is() const {
return std::holds_alternative<Type>(value_);
}
[[nodiscard]] std::string str() const;
private:
basic_types value_;
};
}
#endif //CONDITION_VALUE_HPP

26
src/CMakeLists.txt Normal file
View File

@ -0,0 +1,26 @@
SET(SOURCE
../include/matador/condition/collection_condition_node.hpp
../include/matador/condition/column.hpp
../include/matador/condition/condition_node.hpp
../include/matador/condition/condition_node_visitor.hpp
../include/matador/condition/condition_operators.hpp
../include/matador/condition/logical_condition_node.hpp
../include/matador/condition/types.hpp
../include/matador/condition/value.hpp
condition/binary_condition_node.cpp
condition/collection_condition_node.cpp
condition/column.cpp
condition/condition_operators.cpp
condition/not_condition_node.cpp
condition/logical_condition_node.cpp
../include/matador/condition/between_condition_node.hpp
condition/between_condition_node.cpp
)
add_library(matador-condition STATIC ${SOURCE})
target_include_directories(matador-condition PUBLIC ../include)
add_executable(main main.cpp)
target_include_directories(main PUBLIC ../include)
target_link_libraries(main matador-condition)

View File

@ -0,0 +1,15 @@
#include "matador/condition/between_condition_node.hpp"
#include "matador/condition/condition_node_visitor.hpp"
namespace matador::condition {
between_condition_node::between_condition_node( column column, value min, value max )
: column_(std::move(column))
, min_(std::move(min))
, max_(std::move(max))
{}
void between_condition_node::accept( condition_node_visitor& visitor ) const {
visitor.visit(*this);
}
}

View File

@ -0,0 +1,15 @@
#include "matador/condition/binary_condition_node.hpp"
#include "matador/condition/condition_node_visitor.hpp"
namespace matador::condition {
binary_condition_node::binary_condition_node( column column, const binary_operator operator_, value value )
: column_(std::move(column))
, operator_(operator_)
, value_(std::move(value))
{}
void binary_condition_node::accept( condition_node_visitor& visitor ) const {
visitor.visit(*this);
}
}

View File

@ -0,0 +1,21 @@
#include "matador/condition/collection_condition_node.hpp"
#include "matador/condition/condition_node_visitor.hpp"
namespace matador::condition {
collection_condition_node::collection_condition_node( column col, collection_operator operator_, std::vector<value> values )
: column_(std::move(col))
, operator_(operator_)
, values_(std::move(values))
{}
collection_condition_node::collection_condition_node(column col, const collection_operator operator_, const std::initializer_list<value> values )
: column_(std::move(col))
, operator_(operator_)
, values_(values)
{}
void collection_condition_node::accept( condition_node_visitor& visitor ) const {
visitor.visit(*this);
}
}

36
src/condition/column.cpp Normal file
View File

@ -0,0 +1,36 @@
#include "matador/condition/column.hpp"
#include <stdexcept>
namespace matador::condition {
column::column( std::string name )
: name_(std::move(name)) {}
column::column( std::string table_name, std::string name )
: table_(std::move(table_name))
, name_(std::move(name)){}
const std::string& column::table() const {
return table_;
}
const std::string& column::name() const {
return name_;
}
column operator ""_col( const char* name, size_t len ) {
const std::string str(name, len);
const auto pos = str.find('.');
if (pos == std::string::npos) {
return column{str};
}
if (str.find('.', pos + 1) != std::string::npos) {
// Invalid: more than one dot
throw std::invalid_argument("Invalid column name: multiple dots found");
}
return column{str.substr(0, pos), str.substr(pos + 1)};
}
}

View File

@ -0,0 +1,19 @@
#include "matador/condition/condition_operators.hpp"
#include "matador/condition/logical_condition_node.hpp"
#include "matador/condition/not_condition_node.hpp"
namespace matador::condition {
condition_node_ptr operator&&(condition_node_ptr left, condition_node_ptr right) {
return std::make_unique<logical_condition_node>(std::move(left), logical_operator::AND, std::move(right));
}
condition_node_ptr operator||(condition_node_ptr left, condition_node_ptr right) {
return std::make_unique<logical_condition_node>(std::move(left), logical_operator::OR, std::move(right));
}
condition_node_ptr operator!(condition_node_ptr cond) {
return std::make_unique<not_condition_node>(std::move(cond));
}
}

View File

@ -0,0 +1,15 @@
#include "matador/condition/logical_condition_node.hpp"
#include "matador/condition/condition_node_visitor.hpp"
namespace matador::condition {
logical_condition_node::logical_condition_node( condition_node_ptr left, const logical_operator op, condition_node_ptr right )
: left_(std::move(left))
, op_(op)
, right_(std::move(right))
{}
void logical_condition_node::accept(condition_node_visitor& visitor) const {
visitor.visit(*this);
}
}

View File

@ -0,0 +1,13 @@
#include "matador/condition/not_condition_node.hpp"
#include "matador/condition/condition_node_visitor.hpp"
namespace matador::condition {
not_condition_node::not_condition_node(condition_node_ptr condition)
: condition_(std::move(condition))
{}
void not_condition_node::accept( condition_node_visitor& visitor ) const {
visitor.visit(*this);
}
}

20
src/main.cpp Normal file
View File

@ -0,0 +1,20 @@
#include "matador/condition/column.hpp"
#include "matador/condition/condition_operators.hpp"
using namespace matador::condition;
int main() {
auto cond = "age"_col != 7 && "age"_col == 7;
cond = !("person.age"_col == 7);
cond = "age"_col > 7;
cond = "age"_col < 7;
cond = "age"_col >= 7;
cond = "age"_col <= 7;
cond = in("age"_col, {34, 35, 78});
cond = out("age"_col, {34, 35, 78});
// "age"_col != 7 && in("age"_col, {7,5,5,8});
// "(\"age\" <> 7 AND \"age\" IN (7, 5, 5, 8))"
}