finalize schema/data setup
Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
parent
70820129ae
commit
195f51d3d0
89 changed files with 2324 additions and 6271 deletions
|
|
@ -1,98 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/json.hpp>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <cppbase/result.hpp>
|
||||
|
||||
#include <ikarus/errors.hpp>
|
||||
#include <ikarus/persistence/project.hpp>
|
||||
#include <ikarus/values/value_cardinality.h>
|
||||
|
||||
constexpr auto IKARUS_VALUE_JSON_TYPE_KEY = "type";
|
||||
constexpr auto IKARUS_VALUE_JSON_CARDINALITY_KEY = "card";
|
||||
constexpr auto IKARUS_VALUE_JSON_DATA_KEY = "data";
|
||||
#include <ikarus/values/data.hpp>
|
||||
#include <ikarus/values/errors.hpp>
|
||||
#include <ikarus/values/schema.hpp>
|
||||
|
||||
struct IkarusValue {
|
||||
public:
|
||||
using Data = std::variant<struct IkarusToggleValue *, struct IkarusNumberValue *, struct IkarusTextValue *>;
|
||||
constexpr static auto SMALL_VEC_VALUE_SIZE = 8;
|
||||
IkarusValueSchema schema;
|
||||
IkarusValueData data;
|
||||
|
||||
public:
|
||||
explicit IkarusValue(Data data, IkarusValueCardinality cardinality);
|
||||
|
||||
IkarusValue(IkarusValue const &) = default;
|
||||
IkarusValue(IkarusValue &&) noexcept = default;
|
||||
|
||||
IkarusValue & operator=(IkarusValue const &) = default;
|
||||
IkarusValue & operator=(IkarusValue &&) noexcept = default;
|
||||
|
||||
virtual ~IkarusValue() = default;
|
||||
|
||||
public:
|
||||
struct FromJsonError {};
|
||||
|
||||
[[nodiscard]] static cppbase::Result<IkarusValue *, FromJsonError> from_json(boost::json::value json);
|
||||
[[nodiscard]] boost::json::value to_json() const;
|
||||
|
||||
public:
|
||||
Data data;
|
||||
IkarusValueCardinality cardinality;
|
||||
static auto from_json(nlohmann::json const & json)
|
||||
-> cppbase::Result<IkarusValue, IkarusValueParseError>;
|
||||
static auto to_json(nlohmann::json & json, IkarusValue const & value)
|
||||
-> void;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct fmt::formatter<IkarusValue::FromJsonError> {
|
||||
template<typename FormatParseContext>
|
||||
constexpr static auto parse(FormatParseContext & ctx) {
|
||||
return ctx.end();
|
||||
}
|
||||
struct IkarusValues {
|
||||
static auto from_json(nlohmann::json const & json)
|
||||
-> cppbase::Result<IkarusValues, IkarusValuesParseError>;
|
||||
static auto to_json(nlohmann::json & json, IkarusValues const & values)
|
||||
-> void;
|
||||
|
||||
constexpr static auto format([[maybe_unused]] IkarusValue::FromJsonError const & error, fmt::format_context & ctx) {
|
||||
return fmt::format_to(ctx.out(), "unable to parse ikarus value JSON");
|
||||
}
|
||||
std::vector<std::pair<std::string, IkarusValue>> values;
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
IkarusValue * fetch_value_from_db(IkarusProject * project, IkarusErrorData * error_out, std::string_view query, Args &&... args) {
|
||||
IKARUS_VTRYRV_OR_FAIL(
|
||||
auto const value_str,
|
||||
nullptr,
|
||||
"unable to fetch entity property value from database: {}",
|
||||
IkarusErrorInfo_Database_QueryFailed,
|
||||
project->db->query_one<std::string>(query, std::forward<Args>(args)...)
|
||||
);
|
||||
|
||||
boost::json::error_code ec{};
|
||||
boost::json::value json_value = boost::json::parse(value_str, ec);
|
||||
|
||||
if (ec) {
|
||||
IKARUS_SET_ERROR(fmt::format("invalid json is stored in database: {}", ec.message()), IkarusErrorInfo_Database_InvalidState);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IKARUS_VTRYRV_OR_FAIL(
|
||||
auto const ret,
|
||||
nullptr,
|
||||
"unable to fetch entity property value: {}",
|
||||
IkarusErrorInfo_LibIkarus_CannotPerformOperation,
|
||||
IkarusValue::from_json(std::move(json_value))
|
||||
);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define IKARUS_FAIL_IF_VALUE_MISSING_IMPL(var_name, entity, name, ret) \
|
||||
IKARUS_VTRYRV_OR_FAIL( \
|
||||
bool const var_name, \
|
||||
ret, \
|
||||
"unable to check whether value exists: {}", \
|
||||
IkarusErrorInfo_Database_QueryFailed, \
|
||||
(entity)->project->db->template query_one<bool>( \
|
||||
"SELECT EXISTS(SELECT 1 FROM `entity_values` WHERE `entity` = ? AND `name` = ?)", \
|
||||
(entity)->id, \
|
||||
name \
|
||||
) \
|
||||
) \
|
||||
\
|
||||
IKARUS_FAIL_IF(!(var_name), ret, "entity value does not exist", IkarusErrorInfo_Client_Misuse);
|
||||
|
||||
#define IKARUS_FAIL_IF_VALUE_MISSING(entity, name, ret) IKARUS_FAIL_IF_VALUE_MISSING_IMPL(CPPBASE_UNIQUE_NAME(exists), entity, name, ret);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue