From 751cdc6c0235a0623ed980b24b71acb85e94dacf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Thu, 20 Feb 2020 21:22:03 +0100 Subject: UUID record item type --- CMakeLists.txt | 1 + include/erebos/storage.h | 15 +++++++++++++++ src/storage.cpp | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7685ae..ccb2527 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,5 +10,6 @@ find_package(Threads REQUIRED) find_package(ZLIB REQUIRED) find_package(OpenSSL REQUIRED) find_library(B2_LIBRARY b2 REQUIRED) +find_library(UUID_LIBRARY uuid REQUIRED) add_subdirectory(src) diff --git a/include/erebos/storage.h b/include/erebos/storage.h index 5812783..0859dc8 100644 --- a/include/erebos/storage.h +++ b/include/erebos/storage.h @@ -9,6 +9,8 @@ #include #include +#include + namespace erebos { class Storage; @@ -154,6 +156,17 @@ protected: Ref(const std::shared_ptr p): PartialRef(p) {} }; +struct UUID +{ + explicit UUID(std::string); + explicit operator std::string() const; + + bool operator==(const UUID &) const; + bool operator!=(const UUID &) const; + + uuid_t uuid; +}; + template class RecordT { @@ -171,6 +184,7 @@ public: int, std::string, std::vector, + UUID, typename S::Ref, UnknownType> Variant; @@ -190,6 +204,7 @@ public: std::optional asInteger() const; std::optional asText() const; std::optional> asBinary() const; + std::optional asUUID() const; std::optional asRef() const; std::optional asUnknown() const; diff --git a/src/storage.cpp b/src/storage.cpp index 07fef51..e0819d4 100644 --- a/src/storage.cpp +++ b/src/storage.cpp @@ -536,6 +536,30 @@ const Storage & Ref::storage() const } +UUID::UUID(string str) +{ + if (uuid_parse(str.c_str(), uuid) != 0) + throw runtime_error("invalid UUID"); +} + +UUID::operator string() const +{ + string str(UUID_STR_LEN - 1, '\0'); + uuid_unparse_lower(uuid, str.data()); + return str; +} + +bool UUID::operator==(const UUID & other) const +{ + return std::equal(std::begin(uuid), std::end(uuid), std::begin(other.uuid)); +} + +bool UUID::operator!=(const UUID & other) const +{ + return !(*this == other); +} + + template RecordT::Item::operator bool() const { @@ -566,6 +590,14 @@ optional> RecordT::Item::asBinary() const return nullopt; } +template +optional RecordT::Item::asUUID() const +{ + if (holds_alternative(value)) + return std::get(value); + return nullopt; +} + template optional RecordT::Item::asRef() const { @@ -623,6 +655,8 @@ optional> RecordT::decode(const S & st, items->emplace_back(name, value); else if (type == "b") items->emplace_back(name, base64::decode(value)); + else if (type == "u") + items->emplace_back(name, UUID(value)); else if (type == "r.b2") { if constexpr (is_same_v) { if (auto ref = st.ref(Digest(value))) @@ -702,6 +736,9 @@ vector RecordT::encodeInner() const } else if (auto x = item.asBinary()) { type = "b"; value = base64::encode(*x); + } else if (auto x = item.asUUID()) { + type = "u"; + value = string(*x); } else if (auto x = item.asRef()) { type = "r.b2"; value = string(x->digest()); -- cgit v1.2.3