added assignment from value, conversion to database_type and appropriate tests
This commit is contained in:
parent
9e4660c4ee
commit
1806e2670c
|
|
@ -42,6 +42,7 @@ public:
|
|||
[[nodiscard]] utils::constraints type() const;
|
||||
[[nodiscard]] size_t size() const;
|
||||
[[nodiscard]] int index() const;
|
||||
[[nodiscard]] utils::value value() const;
|
||||
|
||||
template<class Type>
|
||||
std::optional<Type> as() const {
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ namespace matador::utils {
|
|||
|
||||
enum class utils_error {
|
||||
InvalidVersionString,
|
||||
IdentifierTypeMismatch
|
||||
};
|
||||
|
||||
class utils_category_impl final : public std::error_category
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
#include <variant>
|
||||
|
||||
namespace matador::utils {
|
||||
class value;
|
||||
class identifier_serializer {
|
||||
public:
|
||||
virtual ~identifier_serializer() = default;
|
||||
|
|
@ -94,7 +95,6 @@ public:
|
|||
>;
|
||||
|
||||
identifier();
|
||||
|
||||
template<typename Type, std::enable_if_t<is_identifier_supported_v<Type>, int> = 0>
|
||||
explicit identifier(Type &&id)
|
||||
: value_(std::forward<Type>(id)) {
|
||||
|
|
@ -117,17 +117,20 @@ public:
|
|||
}
|
||||
|
||||
identifier& operator=(const std::string &value);
|
||||
|
||||
identifier& operator=(const char *value);
|
||||
|
||||
template<typename Type, std::enable_if_t<is_identifier_supported_v<Type> && std::is_same_v<std::decay_t<Type>, bool>, int> = 0>
|
||||
identifier &operator=(Type &&value) {
|
||||
identifier& operator=(Type &&value) {
|
||||
value_ = std::forward<Type>(value);
|
||||
return *this;
|
||||
}
|
||||
|
||||
~identifier() = default;
|
||||
|
||||
result<void, error> assign(const value &val);
|
||||
|
||||
static result<identifier, error> from_value(const value &val);
|
||||
[[nodiscard]] database_type to_database_type() const;
|
||||
|
||||
bool operator==(const identifier &x) const;
|
||||
bool operator!=(const identifier &x) const;
|
||||
bool operator<(const identifier &x) const;
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ std::string utils_category_impl::message(const int ev) const {
|
|||
switch (static_cast<utils_error>(ev)) {
|
||||
case (utils_error::InvalidVersionString):
|
||||
return "Invalid version string";
|
||||
case utils_error::IdentifierTypeMismatch:
|
||||
return "Identifier type mismatch";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "matador/utils/identifier.hpp"
|
||||
|
||||
#include "matador/utils/value.hpp"
|
||||
#include "matador/utils/errors.hpp"
|
||||
|
||||
#include <ostream>
|
||||
#include <stdexcept>
|
||||
#include <utility>
|
||||
|
||||
namespace matador::utils {
|
||||
|
|
@ -121,6 +123,73 @@ identifier & identifier::operator=(const char *value) {
|
|||
return *this;
|
||||
}
|
||||
|
||||
result<identifier, error> identifier::from_value(const value &val) {
|
||||
identifier id;
|
||||
if (const auto result = id.assign(val); result.is_error()) {
|
||||
return failure(result.err());
|
||||
}
|
||||
|
||||
return ok(id);
|
||||
}
|
||||
|
||||
database_type identifier::to_database_type() const {
|
||||
return std::visit([](const auto &v) -> database_type {
|
||||
using T = std::decay_t<decltype(v)>;
|
||||
|
||||
if constexpr (std::is_same_v<T, std::monostate>) {
|
||||
return nullptr;
|
||||
} else if constexpr (std::is_same_v<T, std::string>) {
|
||||
return v;
|
||||
} else {
|
||||
return static_cast<T>(v);
|
||||
}
|
||||
}, value_);
|
||||
}
|
||||
|
||||
result<void, error> identifier::assign(const value &val) {
|
||||
switch (val.type()) {
|
||||
case basic_type::Null:
|
||||
value_ = std::monostate{};
|
||||
return ok<void>{};
|
||||
|
||||
case basic_type::Int8:
|
||||
if (auto v = val.as<int8_t>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
case basic_type::Int16:
|
||||
if (auto v = val.as<int16_t>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
case basic_type::Int32:
|
||||
if (auto v = val.as<int32_t>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
case basic_type::Int64:
|
||||
if (auto v = val.as<int64_t>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
|
||||
case basic_type::UInt8:
|
||||
if (auto v = val.as<uint8_t>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
case basic_type::UInt16:
|
||||
if (auto v = val.as<uint16_t>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
case basic_type::UInt32:
|
||||
if (auto v = val.as<uint32_t>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
case basic_type::UInt64:
|
||||
if (auto v = val.as<uint64_t>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
|
||||
case basic_type::Text:
|
||||
case basic_type::Varchar:
|
||||
if (auto v = val.as<std::string>()) { value_ = *v; return ok<void>{}; }
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return failure(error{utils_error::IdentifierTypeMismatch});
|
||||
}
|
||||
|
||||
bool identifier::operator==(const identifier &x) const {
|
||||
return value_ == x.value_;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,6 +62,10 @@ int field::index() const {
|
|||
return index_;
|
||||
}
|
||||
|
||||
utils::value field::value() const {
|
||||
return value_;
|
||||
}
|
||||
|
||||
std::ostream &operator<<(std::ostream &out, const field &col) {
|
||||
out << col.str();
|
||||
return out;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "matador/utils/identifier.hpp"
|
||||
#include "matador/utils/default_type_traits.hpp"
|
||||
#include "matador/utils/value.hpp"
|
||||
|
||||
using namespace matador::utils;
|
||||
|
||||
|
|
@ -279,3 +280,87 @@ TEST_CASE("identifier as() and convert() behave consistently for same integer ty
|
|||
REQUIRE(conv_u64.is_ok());
|
||||
REQUIRE(*conv_u64 == 77);
|
||||
}
|
||||
|
||||
TEST_CASE("identifier assign from value", "[utils][identifier][assign]") {
|
||||
identifier id;
|
||||
|
||||
value v1{int32_t{17}};
|
||||
const auto r1 = id.assign(v1);
|
||||
REQUIRE(r1.is_ok());
|
||||
REQUIRE(id.is_integer());
|
||||
REQUIRE(id.str() == "17");
|
||||
|
||||
value v2{std::string{"abc"}};
|
||||
const auto r2 = id.assign(v2);
|
||||
REQUIRE(r2.is_ok());
|
||||
REQUIRE(id.is_varchar());
|
||||
REQUIRE(id.str() == "abc");
|
||||
|
||||
value v3{basic_type::Double, 0};
|
||||
const auto r3 = id.assign(v3);
|
||||
REQUIRE(r3.is_error());
|
||||
}
|
||||
|
||||
TEST_CASE("identifier assign from value with exact type mapping", "[utils][identifier][assign]") {
|
||||
identifier id;
|
||||
|
||||
SECTION("integer types") {
|
||||
value v{int16_t{12}};
|
||||
const auto r = id.assign(v);
|
||||
REQUIRE(r.is_ok());
|
||||
REQUIRE(id.is_integer());
|
||||
REQUIRE(id.str() == "12");
|
||||
}
|
||||
|
||||
SECTION("string types") {
|
||||
value v{std::string{"abc"}};
|
||||
const auto r = id.assign(v);
|
||||
REQUIRE(r.is_ok());
|
||||
REQUIRE(id.is_varchar());
|
||||
REQUIRE(id.str() == "abc");
|
||||
}
|
||||
|
||||
SECTION("null") {
|
||||
value v{basic_type::Null, 0};
|
||||
const auto r = id.assign(v);
|
||||
REQUIRE(r.is_ok());
|
||||
REQUIRE(id.is_null());
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("identifier::to_database_type converts internal value to database_type", "[identifier]") {
|
||||
SECTION("null identifier becomes nullptr") {
|
||||
identifier id{nullptr};
|
||||
|
||||
const auto db_value = id.to_database_type();
|
||||
|
||||
REQUIRE(std::holds_alternative<std::nullptr_t>(db_value));
|
||||
}
|
||||
|
||||
SECTION("signed integral identifier becomes same signed database type") {
|
||||
identifier id{int32_t{42}};
|
||||
|
||||
const auto db_value = id.to_database_type();
|
||||
|
||||
REQUIRE(std::holds_alternative<int32_t>(db_value));
|
||||
REQUIRE(std::get<int32_t>(db_value) == 42);
|
||||
}
|
||||
|
||||
SECTION("unsigned integral identifier becomes same unsigned database type") {
|
||||
identifier id{uint64_t{123456789ULL}};
|
||||
|
||||
const auto db_value = id.to_database_type();
|
||||
|
||||
REQUIRE(std::holds_alternative<uint64_t>(db_value));
|
||||
REQUIRE(std::get<uint64_t>(db_value) == 123456789ULL);
|
||||
}
|
||||
|
||||
SECTION("string identifier becomes std::string database type") {
|
||||
identifier id{std::string{"customer_1"}};
|
||||
|
||||
const auto db_value = id.to_database_type();
|
||||
|
||||
REQUIRE(std::holds_alternative<std::string>(db_value));
|
||||
REQUIRE(std::get<std::string>(db_value) == "customer_1");
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue