From dd94ed1020a0361a8c8e52afe7fc1203d7d92606 Mon Sep 17 00:00:00 2001 From: Sascha Kuehl Date: Sun, 10 Mar 2024 11:51:07 +0100 Subject: [PATCH] added field class --- include/matador/sql/field.hpp | 89 ++++++++++++++++++++++++++++++----- src/sql/field.cpp | 41 +++++++++++++--- test/CMakeLists.txt | 3 +- test/FieldTest.cpp | 38 +++++++++++++++ 4 files changed, 153 insertions(+), 18 deletions(-) create mode 100644 test/FieldTest.cpp diff --git a/include/matador/sql/field.hpp b/include/matador/sql/field.hpp index b6c7867..9c0f477 100644 --- a/include/matador/sql/field.hpp +++ b/include/matador/sql/field.hpp @@ -4,40 +4,107 @@ #include "matador/sql/any_type.hpp" #include "matador/sql/any_type_to_visitor.hpp" +#include "matador/utils/types.hpp" + +#include #include namespace matador::sql { +enum class field_type { + Integer, + FloatingPoint, + String, + Boolean, + Blob, + Null +}; + +template < typename Type, typename Enable = void > +struct field_traits; + +template +struct field_traits::value && !std::is_same::value>::type> +{ + static field_type type() { return field_type::Integer; } +}; + +template +struct field_traits::value>::type> +{ + static field_type type() { return field_type::FloatingPoint; } +}; + +template +struct field_traits::value>::type> +{ + static field_type type() { return field_type::String; } +}; + +template +struct field_traits::value>::type> +{ + static field_type type() { return field_type::Boolean; } +}; + +template +struct field_traits::value>::type> +{ + static field_type type() { return field_type::Null; } +}; + +template +struct field_traits::value>::type> +{ + static field_type type() { return field_type::Blob; } +}; + class field { public: + explicit field(std::string name); + template + field(std::string name, Type value) + : name_(std::move(name)) + , value_(value) + , type_(field_traits::type()) {} + field(const field &x) = default; + field& operator=(const field &x) = default; + field(field &&x) noexcept; + field& operator=(field &&x) noexcept; + + template + field& operator=(Type value) { + value_ = std::move(value); + type_ = field_traits::type(); + return *this; + } [[nodiscard]] const std::string& name() const; template - Type as() const + std::optional as() const { - const Type* ptr= std::get_if(&value_); - if (ptr) { - return *ptr; - } any_type_to_visitor visitor; std::visit(visitor, const_cast(value_)); return visitor.result; } - bool is_integer() const; - bool is_floating_point() const; - bool is_bool() const; - bool is_string() const; - bool is_blob() const; - bool is_null() const; + [[nodiscard]] std::string str() const; + + [[nodiscard]] bool is_integer() const; + [[nodiscard]] bool is_floating_point() const; + [[nodiscard]] bool is_bool() const; + [[nodiscard]] bool is_string() const; + [[nodiscard]] bool is_blob() const; + [[nodiscard]] bool is_null() const; friend std::ostream& operator<<(std::ostream &out, const field &col); private: std::string name_; any_type value_; + field_type type_; }; } diff --git a/src/sql/field.cpp b/src/sql/field.cpp index d7b88de..be005a4 100644 --- a/src/sql/field.cpp +++ b/src/sql/field.cpp @@ -2,6 +2,28 @@ namespace matador::sql { +field::field(std::string name) + : name_(std::move(name)), value_(nullptr), type_(field_traits::type()) +{} + +field::field(field &&x) noexcept + : name_(std::move(x.name_)), value_(std::move(x.value_)), type_(x.type_) +{ + x.value_ = nullptr; + x.type_ = field_type::Null; +} + +field &field::operator=(field &&x) noexcept +{ + name_ = std::move(x.name_); + value_ = std::move(x.value_); + type_ = x.type_; + x.value_ = nullptr; + x.type_ = field_type::Null; + + return *this; +} + const std::string &field::name() const { return name_; @@ -9,36 +31,43 @@ const std::string &field::name() const std::ostream &operator<<(std::ostream &out, const field &col) { + out << col.str(); return out; } +std::string field::str() const +{ + return as().value(); +} + bool field::is_integer() const { - return false; + return type_ == field_type::Integer; } bool field::is_floating_point() const { - return false; + return type_ == field_type::FloatingPoint; } bool field::is_bool() const { - return false; + return type_ == field_type::Boolean; } bool field::is_string() const { - return false; + return type_ == field_type::String; } bool field::is_blob() const { - return false; + return type_ == field_type::Blob; } bool field::is_null() const { - return false; + return type_ == field_type::Null; } + } \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f6384ee..7ba9e52 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -38,7 +38,8 @@ add_executable(tests DummyConnection.cpp EntityQueryBuilderTest.cpp models/author.hpp - models/book.hpp) + models/book.hpp + FieldTest.cpp) target_link_libraries(tests PRIVATE Catch2::Catch2WithMain diff --git a/test/FieldTest.cpp b/test/FieldTest.cpp new file mode 100644 index 0000000..287088f --- /dev/null +++ b/test/FieldTest.cpp @@ -0,0 +1,38 @@ +#include + +#include "matador/sql/field.hpp" + +using namespace matador::sql; + +TEST_CASE("Field test", "[field]") { + field f("name"); + + REQUIRE(f.name() == "name"); + REQUIRE(f.is_null()); + REQUIRE(!f.is_integer()); + REQUIRE(!f.is_floating_point()); + REQUIRE(!f.is_blob()); + REQUIRE(!f.is_bool()); + REQUIRE(!f.is_string()); + + f = 7UL; + REQUIRE(!f.is_null()); + REQUIRE(f.is_integer()); + REQUIRE(!f.is_floating_point()); + REQUIRE(!f.is_blob()); + REQUIRE(!f.is_bool()); + REQUIRE(!f.is_string()); + + auto int_val = f.as(); + REQUIRE(int_val.has_value()); + REQUIRE(int_val.value() == 7); + auto float_val = f.as(); + REQUIRE(float_val.has_value()); + REQUIRE(float_val.value() == 7.0); + auto str_val = f.as(); + REQUIRE(str_val.has_value()); + REQUIRE(str_val.value() == "7"); + auto bool_val = f.as(); + REQUIRE(bool_val.has_value()); + REQUIRE(bool_val.value()); +} \ No newline at end of file