change error system & function signatures

Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
folling 2024-01-02 15:14:39 +01:00 committed by Folling
parent ee85c53354
commit e17e346768
Signed by: folling
SSH key fingerprint: SHA256:S9qEx5WCFFLK49tE/LKnKuJYM5sw+++Dn6qJbbyxnCY
28 changed files with 633 additions and 651 deletions

View file

@ -1,22 +1,71 @@
#include "ikarus/errors.h"
#include "cppbase/functional.hpp"
#include <string.h>
#include <ranges>
#include <fmt/format.h>
char const * get_error_info_name(IkarusErrorInfo info) {
switch (info) {
case IkarusErrorInfo_Source_None: return "IkarusErrorInfo_Source_None";
case IkarusErrorInfo_Source_Client: return "IkarusErrorInfo_Source_Client";
case IkarusErrorInfo_Source_SubSystem: return "IkarusErrorInfo_Source_SubSystem";
case IkarusErrorInfo_Source_LibIkarus: return "IkarusErrorInfo_Source_LibIkarus";
case IkarusErrorInfo_Source_Unknown: return "IkarusErrorInfo_Source_Unknown";
case IkarusErrorInfo_Type_None: return "IkarusErrorInfo_Type_None";
case IkarusErrorInfo_Type_Client_Misuse: return "IkarusErrorInfo_Type_Client_Misuse";
case IkarusErrorInfo_Type_Client_Input: return "IkarusErrorInfo_Type_Client_Input";
case IkarusErrorInfo_Type_SubSystem_Dependency: return "IkarusErrorInfo_Type_SubSystem_Dependency";
case IkarusErrorInfo_Type_SubSystem_Database: return "IkarusErrorInfo_Type_SubSystem_Database";
case IkarusErrorInfo_Type_SubSystem_Filesystem: return "IkarusErrorInfo_Type_SubSystem_Filesystem";
case IkarusErrorInfo_Type_LibIkarus_InvalidState: return "IkarusErrorInfo_Type_LibIkarus_InvalidState";
case IkarusErrorInfo_Type_LibIkarus_CannotPerformOperation: return "IkarusErrorInfo_Type_LibIkarus_CannotPerformOperation";
case IkarusErrorInfo_Type_LibIkarus_Timeout: return "IkarusErrorInfo_Type_LibIkarus_Timeout";
case IkarusErrorInfo_Type_Unknown: return "IkarusErrorInfo_Type_Unknown";
default: return "Unknown";
case IkarusErrorInfo_None: return "None";
case IkarusErrorInfo_Client: return "Client";
case IkarusErrorInfo_Dependency: return "Dependency";
case IkarusErrorInfo_Filesystem: return "Filesystem";
case IkarusErrorInfo_Database: return "Database";
case IkarusErrorInfo_OS: return "OS";
case IkarusErrorInfo_LibIkarus: return "libikarus";
case IkarusErrorInfo_Client_Misuse: return "Misuse";
case IkarusErrorInfo_Client_InvalidInput: return "InvalidInput";
case IkarusErrorInfo_Client_InvalidFormat: return "InvalidFormat";
case IkarusErrorInfo_Client_ConstraintViolated: return "ConstraintViolated";
case IkarusErrorInfo_Filesystem_NotFound: return "NotFound";
case IkarusErrorInfo_Filesystem_AlreadyExists: return "AlreadyExists";
case IkarusErrorInfo_Filesystem_MissingPermissions: return "MissingPermissions";
case IkarusErrorInfo_Filesystem_InsufficientSpace: return "InsufficientSpace";
case IkarusErrorInfo_Filesystem_InvalidPath: return "InvalidPath";
case IkarusErrorInfo_Database_ConnectionFailed: return "ConnectionFailed";
case IkarusErrorInfo_Database_QueryFailed: return "QueryFailed";
case IkarusErrorInfo_Database_MigrationFailed: return "MigrationFailed";
case IkarusErrorInfo_Database_InvalidState: return "InvalidState";
case IkarusErrorInfo_OS_SystemCallFailed: return "SystemCallFailed";
case IkarusErrorInfo_OS_InvalidReturnValue: return "InvalidReturnValue";
case IkarusErrorInfo_OS_InsufficientMemory: return "InsufficientMemory";
case IkarusErrorInfo_LibIkarus_InvalidState: return "InvalidState";
case IkarusErrorInfo_LibIkarus_Timeout: return "Timeout";
default: return "Invalid";
}
}
bool ikarus_error_data_is_success(IkarusErrorData const * data) {
return data->infos[0] == IkarusErrorInfo_None;
}
bool ikarus_error_data_is_error(IkarusErrorData const * data) {
return data->infos[0] != IkarusErrorInfo_None;
}
char const * ikarus_error_data_pretty_format(IkarusErrorData const * data) {
if (ikarus_error_data_is_success(data)) {
return "Success";
}
auto const formatted = fmt::format(
"{} - {}",
fmt::join(
data->infos | std::views::take_while(cppbase::pred_ne(IkarusErrorInfo_None)) | std::views::transform(get_error_info_name),
"->"
),
data->message
);
return strndup(formatted.data(), formatted.size());
}

View file

@ -1,7 +1,6 @@
#include "ikarus/objects/blueprint.h"
#include "objects/blueprint.hpp"
#include "util.hpp"
#include <cppbase/logger.hpp>
#include <cppbase/result.hpp>
@ -9,25 +8,44 @@
#include <objects/entity.hpp>
#include <objects/properties/property.hpp>
#include <objects/util.hpp>
#include <persistence/function_context.hpp>
#include <persistence/project.hpp>
IkarusBlueprint::IkarusBlueprint(IkarusProject * project, IkarusId id):
IkarusObject{project, id} {}
IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name) {
return ikarus::util::insert_object(
project,
IkarusObjectType_Blueprint,
name,
[](auto * db, IkarusId id) { return db->execute("INSERT INTO `blueprints`(`id`) VALUES(?)", id); },
[project](IkarusId id) { return project->get_blueprint(id); }
).unwrap_value_or(nullptr);
if (cppbase::is_empty_or_blank(name)) {
project->set_error("blueprint name must not be empty", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input);
return nullptr;
}
project->db
->transact([name](auto * db) {
TRY(db->execute("INSERT INTO `objects`(`type`, `name`) VALUES(?, ?, ?)", IkarusObjectType_Blueprint, name));
auto id = ikarus_id_from_data_and_type(db->last_insert_rowid(), IkarusObjectType_Blueprint);
TRY(db->execute("INSERT INTO `blueprints`(`id`) VALUES(?)", id));
return cppbase::ok();
})
.on_error([project](auto const & err) {
project->set_error(
fmt::format("failed to create blueprint: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
});
}
void ikarus_blueprint_delete(IkarusBlueprint * blueprint) {
ikarus::util::delete_object(blueprint);
blueprint->project->db->execute("DELETE FROM `objects` WHERE `id` = ?", blueprint->id).on_error([blueprint](auto const & err) {
blueprint->project->set_error(
fmt::format("failed to delete blueprint from objects table: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
});
}
void ikarus_blueprint_get_properties(
@ -35,41 +53,34 @@ void ikarus_blueprint_get_properties(
struct IkarusProperty ** properties_out,
size_t properties_out_size
) {
ikarus::util::fetch_multiple_buffered<IkarusId>(
blueprint,
ikarus::util::MultipleBufferQueryData{
.table_name = "properties",
.select_field_name = "id",
.where_field_name = "blueprint",
.relation_desc = "properties"
},
properties_out,
properties_out_size,
[&](IkarusProject * project, IkarusFunctionContext * ctx, IkarusId id) -> cppbase::Result<IkarusProperty *, sqlitecpp::QueryError> {
VTRY(auto const type, IkarusProperty::get_property_type(blueprint->project, id).on_error([ctx, id](auto const & err) {
ctx->set_error(
fmt::format("failed to fetch property {}'s type: {}", id, err),
IkarusId ids[properties_out_size];
TRYRV(
,
blueprint->project->db
->query_many_buffered<IkarusId>("SELECT `id` FROM `properties` WHERE `source` = ?", ids, properties_out_size, blueprint->id)
.on_error([&](auto const & err) {
blueprint->project->set_error(
fmt::format("failed to fetch blueprint properties from database: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
}));
return cppbase::ok(project->get_property(id, type));
}
})
);
// not atomic, could be switched to two loops if necessary
for (size_t i = 0; i < properties_out_size; ++i) {
IkarusId id = ids[i];
VTRYRV(auto const type, , IkarusProperty::get_property_type(blueprint->project, id));
properties_out[i] = blueprint->project->get_property(id, type);
}
}
size_t ikarus_blueprint_get_property_count(IkarusBlueprint const * blueprint) {
return ikarus::util::fetch_count(
blueprint,
ikarus::util::CountQueryData{
.table_name = "blueprint_properties",
.select_field_name = "property",
.where_field_name = "blueprint",
.relation_desc = "properties"
}
)
return blueprint->project->db->query_one<int64_t>("SELECT COUNT(*) FROM `properties` WHERE `source` = ?", blueprint->id)
.unwrap_value_or(0);
}
@ -78,31 +89,34 @@ void ikarus_blueprint_get_linked_entities(
struct IkarusEntity ** entities_out,
size_t entities_out_size
) {
ikarus::util::fetch_multiple_buffered<IkarusId>(
blueprint,
ikarus::util::MultipleBufferQueryData{
.table_name = "entity_blueprint_links",
.select_field_name = "entity",
.where_field_name = "blueprint",
.relation_desc = "linked entities"
},
entities_out,
entities_out_size,
[&](IkarusProject * project, [[maybe_unused]] IkarusFunctionContext * ctx, IkarusId id
) -> cppbase::Result<IkarusEntity *, sqlitecpp::QueryError> { return cppbase::ok(project->get_entity(id)); }
IkarusId ids[entities_out_size];
TRYRV(
,
blueprint->project->db
->query_many_buffered<IkarusId>(
"SELECT `entity` FROM `entity_blueprint_links` WHERE `blueprint` = ?",
ids,
entities_out_size,
blueprint->id
)
.on_error([&](auto const & err) {
blueprint->project->set_error(
fmt::format("failed to fetch linked entities from database: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
})
);
for (size_t i = 0; i < entities_out_size; ++i) {
entities_out[i] = blueprint->project->get_entity(ids[i]);
}
}
size_t ikarus_blueprint_get_linked_entity_count(IkarusBlueprint const * blueprint) {
return ikarus::util::fetch_count(
blueprint,
ikarus::util::CountQueryData{
.table_name = "entity_blueprint_links",
.select_field_name = "entity",
.where_field_name = "blueprint",
.relation_desc = "linked entities"
}
)
return blueprint->project->db->query_one<int64_t>("SELECT COUNT(*) FROM `entity_blueprint_links` WHERE `blueprint` = ?", blueprint->id)
.unwrap_value_or(0);
}

View file

@ -4,7 +4,6 @@
#include <objects/blueprint.hpp>
#include <objects/util.hpp>
#include <persistence/function_context.hpp>
#include <persistence/project.hpp>
IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name) {

View file

@ -5,7 +5,6 @@
#include <ikarus/objects/properties/property_type.h>
#include <objects/properties/property_source.hpp>
#include <persistence/function_context.hpp>
#include <persistence/project.hpp>
#include <sys/stat.h>
#include <values/value.hpp>
@ -23,12 +22,10 @@ IkarusProperty::Data const & IkarusProperty::get_data() const {
}
cppbase::Result<IkarusPropertyType, sqlitecpp::SingleQueryError> IkarusProperty::get_property_type(IkarusProject * project, IkarusId id) {
auto * ctx = project->get_function_context();
VTRY(
auto const type,
project->get_db()->query_one<int>("SELECT `type` FROM `properties` WHERE `id` = ?", id).on_error([ctx](auto const & err) {
ctx->set_error(
project->db->query_one<int>("SELECT `type` FROM `properties` WHERE `id` = ?", id).on_error([project](auto const & err) {
project->set_error(
fmt::format("failed to fetch unboxed property type: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,
@ -41,16 +38,17 @@ cppbase::Result<IkarusPropertyType, sqlitecpp::SingleQueryError> IkarusProperty:
}
IKA_API void ikarus_property_delete(IkarusProperty * property) {
auto * ctx = property->project->get_function_context();
TRYRV(, property->project->get_db()->execute("DELETE FROM `objects` WHERE `id` = ?", property->id).on_error([ctx](auto const & err) {
ctx->set_error(
fmt::format("failed to delete property from objects table: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
}));
TRYRV(
,
property->project->db->execute("DELETE FROM `objects` WHERE `id` = ?", property->id).on_error([property](auto const & err) {
property->project->set_error(
fmt::format("failed to delete property from objects table: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
})
);
property->project->uncache(property);
}
@ -60,15 +58,13 @@ IkarusPropertyType ikarus_property_get_type(IkarusProperty const * property) {
}
IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * property) {
auto * ctx = property->project->get_function_context();
VTRYRV(
auto const source,
nullptr,
property->project->get_db()
property->project->db
->query_one<int>("SELECT `source` FROM `properties` WHERE `id` = ?", property->id)
.on_error([ctx](auto const & err) {
ctx->set_error(
.on_error([property](auto const & err) {
property->project->set_error(
fmt::format("failed to fetch property's source: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,
@ -81,7 +77,7 @@ IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * p
case IkarusObjectType_Blueprint: return new IkarusPropertySource{property->project->get_blueprint(source)};
case IkarusObjectType_Entity: return new IkarusPropertySource{property->project->get_entity(source)};
default: {
ctx->set_error(
property->project->set_error(
fmt::format("PropertySource is neither blueprint nor entity"),
true,
IkarusErrorInfo_Source_LibIkarus,
@ -94,15 +90,13 @@ IkarusPropertySource const * ikarus_property_get_source(IkarusProperty const * p
}
IkarusValue * ikarus_property_get_default_value(IkarusProperty const * property) {
auto * ctx = property->project->get_function_context();
VTRYRV(
auto const value,
nullptr,
property->project->get_db()
property->project->db
->query_one<int>("SELECT `default_value` FROM `properties` WHERE `id` = ?", property->id)
.on_error([ctx](auto const & err) {
ctx->set_error(
.on_error([property](auto const & err) {
property->project->set_error(
fmt::format("failed to fetch property's default value: {}", err),
true,
IkarusErrorInfo_Source_SubSystem,

View file

@ -1,241 +0,0 @@
#pragma once
#include "util.hpp"
#include <concepts>
#include <cppbase/result.hpp>
#include <cppbase/strings.hpp>
#include <ikarus/id.h>
#include <ikarus/objects/object_type.h>
#include <persistence/function_context.hpp>
namespace ikarus::util {
struct EmptyNameError {};
COMPOUND_ERROR(InsertObjectError, EmptyNameError, sqlitecpp::TransactionError);
template<typename InsertFunction, typename ObjectFactory>
[[nodiscard]] cppbase::Result<std::invoke_result_t<ObjectFactory, IkarusId>, InsertObjectError> insert_object(
IkarusProject * project,
IkarusObjectType type,
std::string_view name,
InsertFunction insert_function,
ObjectFactory object_factory
) {
auto const * object_type_str = ikarus_object_type_to_string(type);
auto * ctx = project->get_function_context();
if (cppbase::is_empty_or_blank(name)) {
ctx->set_error("name is empty or blank", true, IkarusErrorInfo_Source_Client, IkarusErrorInfo_Type_Client_Input);
return cppbase::err(EmptyNameError{});
}
VTRY(
auto const id,
project->get_db()
->transact([&](auto * db) -> cppbase::Result<IkarusId, sqlitecpp::TransactionError> {
TRY(db->execute("INSERT INTO `objects` (`object_type`, `name`) VALUES(?, ?);", static_cast<int>(type), name));
auto id = ikarus_id_from_data_and_type(db->last_insert_rowid(), IkarusObjectType_Blueprint);
TRY(insert_function(db, id));
return cppbase::ok(id);
})
.on_error([&](auto const & err) {
ctx->set_error(
fmt::format("unable to insert {} into database: {}", object_type_str, err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
})
);
return cppbase::ok(object_factory(id));
}
template<typename Object>
requires std::derived_from<Object, IkarusObject>
void delete_object(Object * object) {
auto object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
auto * ctx = object->project->get_function_context();
TRYRV(, object->project->get_db()->execute("DELETE FROM `objects` WHERE `id` = ?", object->id).on_error([&](auto const & err) {
ctx->set_error(
fmt::format("failed to delete {} from objects table: {}", object_type_str, err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
}));
object->project->uncache(object);
}
struct SingleQueryData {
std::string_view table_name;
std::string_view select_field_name;
};
template<typename T, typename Object>
requires std::derived_from<Object, IkarusObject>
cppbase::Result<T, sqlitecpp::SingleQueryError> fetch_single_field(Object const * object, SingleQueryData const & query_data) {
auto object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
auto * ctx = object->project->get_function_context();
VTRY(
T value,
object->project->get_db()
->template query_one<T>(
fmt::format("SELECT `{}` FROM `{}` WHERE `id` = ?", query_data.select_field_name, query_data.table_name),
object->id
)
.on_error([&](auto const & err) {
ctx->set_error(
fmt::format("failed to fetch {} {} from database: {}", object_type_str, query_data.select_field_name, err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
})
);
return value;
}
struct MultipleBufferQueryData {
std::string_view table_name;
std::string_view select_field_name;
std::string_view where_field_name;
std::string_view relation_desc;
};
template<typename Selected, typename Mapped, typename Object, typename F>
requires std::derived_from<Object, IkarusObject>
void fetch_multiple_buffered(
Object const * object,
MultipleBufferQueryData const & query_data,
Mapped * mapped_buffer,
size_t buffer_size,
F transformer
)
requires cppbase::is_result_with_value_type_v<Mapped, std::invoke_result_t<F, IkarusProject *, IkarusFunctionContext *, Selected>>
{
auto * ctx = object->project->get_function_context();
auto object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
Selected select_buffer[buffer_size];
TRYRV(
,
object->project->get_db()
->template query_many_buffered<Selected>(
fmt::format(
"SELECT `{}` FROM `{}` WHERE `{}` = ?",
query_data.select_field_name,
query_data.table_name,
query_data.where_field_name
),
select_buffer,
buffer_size,
object->id
)
.on_error([&](auto const & err) {
ctx->set_error(
fmt::format("failed to fetch {} {} from database: {}", object_type_str, query_data.relation_desc, err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
})
);
for (size_t i = 0; i < buffer_size; ++i) {
VTRYRV(mapped_buffer[i], , transformer(object->project, ctx, select_buffer[i]));
}
}
struct CountQueryData {
std::string_view table_name;
std::string_view select_field_name;
std::string_view where_field_name;
std::string_view relation_desc;
};
template<typename Object>
requires std::derived_from<Object, IkarusObject>
cppbase::Result<cppbase::usize, sqlitecpp::QueryError> fetch_count(Object const * object, CountQueryData const & query_data) {
auto * object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
auto * ctx = object->project->get_function_context();
VTRY(
auto count,
object->project->get_db()
->template query_one<int>(
fmt::format(
"SELECT COUNT(`{}`) FROM `{}` WHERE `{}` = ?;",
query_data.select_field_name,
query_data.table_name,
query_data.where_field_name
),
object->id
)
.on_error([&](auto const & err) {
ctx->set_error(
fmt::format("failed to fetch {} {} count: {}", object_type_str, query_data.relation_desc, err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
})
);
return cppbase::ok(static_cast<size_t>(count));
}
template<typename T>
struct ExistsQueryData {
std::string_view table_name;
std::string_view where_field_name;
T where_field_value;
std::string_view relation_desc;
};
template<typename Object, typename T>
requires std::derived_from<Object, IkarusObject>
cppbase::Result<bool, sqlitecpp::QueryError> check_exists(Object const * object, ExistsQueryData<T> const & query_data) {
auto * object_type_str = ikarus_object_type_to_string(ikarus_id_get_object_type(object->id));
auto * ctx = object->project->get_function_context();
VTRY(
auto exists,
object->project->get_db()
->template query_one<int>(
fmt::format("SELECT EXISTS(SELECT 1 FROM `{}` WHERE `{}` = ?);", query_data.table_name, query_data.where_field_name),
query_data.where_field_value
)
.on_error([&](auto const & err) {
ctx->set_error(
fmt::format("failed to check whether {} {} exists: {}", object_type_str, query_data.relation_desc, err),
true,
IkarusErrorInfo_Source_SubSystem,
IkarusErrorInfo_Type_SubSystem_Database
);
})
);
return cppbase::ok(static_cast<bool>(exists));
}
} // namespace ikarus::util

View file

@ -1,18 +0,0 @@
#include "function_context.hpp"
IkarusFunctionContext::IkarusFunctionContext(IkarusProject * project):
_project{project} {}
IkarusFunctionContext::~IkarusFunctionContext() {
if (_project->_function_contexts.size() == 1) {
if (_project->error_message_buffer.empty()) {
_project->error_message_buffer.push_back('\0');
} else {
_project->error_message_buffer[0] = '\0';
}
_project->error_infos = {};
}
_project->_function_contexts.pop_back();
}

View file

@ -1,49 +0,0 @@
#pragma once
#include <ranges>
#include <string_view>
#include <type_traits>
#include <fmt/format.h>
#include <cppbase/logger.hpp>
#include <ikarus/errors.h>
#include <persistence/project.hpp>
struct IkarusFunctionContext {
public:
explicit IkarusFunctionContext(struct IkarusProject * project);
IkarusFunctionContext(IkarusFunctionContext const &) noexcept = default;
IkarusFunctionContext(IkarusFunctionContext &&) noexcept = default;
auto operator=(IkarusFunctionContext const &) noexcept -> IkarusFunctionContext & = default;
auto operator=(IkarusFunctionContext &&) noexcept -> IkarusFunctionContext & = default;
~IkarusFunctionContext();
public:
template<typename... Infos>
requires(std::is_same_v<IkarusErrorInfo, Infos> && ...) && (sizeof...(Infos) <= MAXIMUM_ERROR_INFOS)
auto set_error(std::string_view error_message, bool log_error, Infos... infos) -> void {
if (error_message.size() > _project->error_message_buffer.size()) {
_project->error_message_buffer.resize(error_message.size() + 1);
}
for (int i = 0; i < error_message.size(); ++i) {
_project->error_message_buffer[i] = error_message[i];
}
_project->error_message_buffer[error_message.size()] = '\0';
_project->error_infos = {infos...};
if (log_error) {
LOG_ERROR("Error({}): {}", fmt::join(_project->error_infos | std::views::transform(get_error_info_name), ", "), error_message);
}
}
private:
struct IkarusProject * _project;
};

View file

@ -8,27 +8,14 @@
#include <objects/properties/property.hpp>
#include <objects/properties/text_property.hpp>
#include <objects/properties/toggle_property.hpp>
#include <persistence/function_context.hpp>
auto IkarusProject::get_name() const -> std::string_view {
return _name;
}
auto IkarusProject::get_path() const -> std::filesystem::path const & {
return _path;
}
auto IkarusProject::get_db() -> sqlitecpp::Connection * {
return _db.get();
}
auto IkarusProject::get_db() const -> sqlitecpp::Connection const * {
return _db.get();
}
auto IkarusProject::get_function_context() -> IkarusFunctionContext * {
return &_function_contexts.emplace_back(this);
}
IkarusProject::IkarusProject(std::string_view name, std::filesystem::path path):
name{name},
path{path},
db{nullptr},
_blueprints{},
_properties{},
_entities{} {}
IkarusBlueprint * IkarusProject::get_blueprint(IkarusId id) {
return get_cached_object<IkarusBlueprint>(id, this->_blueprints);

View file

@ -11,20 +11,10 @@
#include <ikarus/id.h>
#include <ikarus/objects/properties/property_type.h>
constexpr inline auto MAXIMUM_ERROR_INFOS = 8;
/// \private
struct IkarusProject {
public:
[[nodiscard]] auto get_name() const -> std::string_view;
[[nodiscard]] auto get_path() const -> std::filesystem::path const &;
[[nodiscard]] auto get_db() -> sqlitecpp::Connection *;
[[nodiscard]] auto get_db() const -> sqlitecpp::Connection const *;
public:
[[nodiscard]] auto get_function_context() -> struct IkarusFunctionContext *;
IkarusProject(std::string_view name, std::filesystem::path path);
public:
[[nodiscard]] auto get_blueprint(IkarusId id) -> struct IkarusBlueprint *;
@ -53,19 +43,13 @@ private:
cache.erase(object->id);
}
public:
std::string name;
std::filesystem::path path;
std::unique_ptr<sqlitecpp::Connection> db;
private:
friend struct IkarusFunctionContext;
std::string _name;
std::filesystem::path _path;
std::unique_ptr<sqlitecpp::Connection> _db;
std::array<IkarusErrorInfo, MAXIMUM_ERROR_INFOS> error_infos;
std::string error_message_buffer;
std::unordered_map<IkarusId, std::unique_ptr<IkarusBlueprint>> _blueprints;
std::unordered_map<IkarusId, std::unique_ptr<IkarusProperty>> _properties;
std::unordered_map<IkarusId, std::unique_ptr<IkarusEntity>> _entities;
std::vector<IkarusFunctionContext> _function_contexts;
std::unordered_map<IkarusId, std::unique_ptr<struct IkarusBlueprint>> _blueprints;
std::unordered_map<IkarusId, std::unique_ptr<struct IkarusProperty>> _properties;
std::unordered_map<IkarusId, std::unique_ptr<struct IkarusEntity>> _entities;
};