implement ikarus_project_get_*_by_name functions

Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
folling 2024-01-30 09:44:55 +01:00 committed by Folling
parent 4fe97b13cb
commit c66489d178
Signed by: folling
SSH key fingerprint: SHA256:S9qEx5WCFFLK49tE/LKnKuJYM5sw+++Dn6qJbbyxnCY
6 changed files with 80 additions and 19 deletions

View file

@ -17,7 +17,7 @@ IkarusBlueprint::IkarusBlueprint(IkarusProject * project, IkarusId id):
IkarusBlueprint * ikarus_blueprint_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, nullptr);
IKARUS_FAIL_IF_NAME_INVALID(name, project, nullptr, nullptr);
IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, project, nullptr, nullptr);
IKARUS_VTRYRV_OR_FAIL(
IkarusId const id,

View file

@ -12,7 +12,7 @@
IkarusEntity * ikarus_entity_create(struct IkarusProject * project, char const * name, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, nullptr);
IKARUS_FAIL_IF_NAME_INVALID(name, project, nullptr, nullptr);
IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, project, nullptr, nullptr);
IKARUS_VTRYRV_OR_FAIL(
IkarusId const id,

View file

@ -23,7 +23,7 @@ T * create_property(
IKARUS_FAIL_IF_NULL(project, nullptr);
IKARUS_FAIL_IF_NULL(property_scope, nullptr);
IKARUS_FAIL_IF_PROPERTY_SCOPE_INVALID(property_scope, nullptr);
IKARUS_FAIL_IF_NAME_INVALID(name, project, property_scope, nullptr);
IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, project, property_scope, nullptr);
IKARUS_VTRYRV_OR_FAIL(
IkarusId const id,

View file

@ -96,15 +96,18 @@ name_is_unique(IkarusProject * project, std::string_view name, IkarusProperty co
return name_is_unique(project, name, scope.get(), error_out);
}
#define IKARUS_FAIL_IF_NAME_INVALID(name, project, object, ret, ...) \
IKARUS_FAIL_IF_NULL(name, ret); \
IKARUS_FAIL_IF(cppbase::is_empty_or_blank(name), ret, "name must not be empty", IkarusErrorInfo_Client_InvalidInput); \
IKARUS_FAIL_IF( \
!ikarus::util::name_is_unique(project, name, object, error_out), \
ret, \
"name must be unique", \
IkarusErrorInfo_Client_InvalidInput \
); \
#define IKARUS_FAIL_IF_NAME_INVALID(name, ret) \
IKARUS_FAIL_IF_NULL(name, ret); \
IKARUS_FAIL_IF(cppbase::is_empty_or_blank(name), ret, "name must not be empty", IkarusErrorInfo_Client_InvalidInput);
#define IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, project, object, ret, ...) \
IKARUS_FAIL_IF_NAME_INVALID(name, ret); \
IKARUS_FAIL_IF( \
!ikarus::util::name_is_unique(project, name, object, error_out), \
ret, \
"name must be unique", \
IkarusErrorInfo_Client_InvalidInput \
); \
IKARUS_FAIL_IF_ERROR(ret);
template<typename O>
@ -112,7 +115,7 @@ void object_set_name(O * object, char const * name, IkarusErrorData * error_out)
IKARUS_FAIL_IF_NULL(object, );
IKARUS_FAIL_IF_OBJECT_MISSING(object, );
IKARUS_FAIL_IF_NULL(name, );
IKARUS_FAIL_IF_NAME_INVALID(name, object->project, object, );
IKARUS_FAIL_IF_NAME_INVALID_OR_DUPLICATE(name, object->project, object, );
IKARUS_TRYRV_OR_FAIL(
,

View file

@ -10,6 +10,7 @@
#include <ikarus/objects/properties/property.hpp>
#include <ikarus/objects/properties/text_property.hpp>
#include <ikarus/objects/properties/toggle_property.hpp>
#include <ikarus/objects/util.hpp>
#include <ikarus/persistence/migrations.hpp>
#include <ikarus/persistence/project.hpp>
@ -275,3 +276,60 @@ size_t ikarus_project_get_entity_count(IkarusProject * project, IkarusErrorData
return ret;
}
struct IkarusEntity * get_entity_by_name(IkarusProject * project, char const * name, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, nullptr);
IKARUS_FAIL_IF_NULL(name, nullptr);
IKARUS_FAIL_IF_NAME_INVALID(name, nullptr);
// TODO, 'InvalidInput' doesn't really make sense here, we'd need to adjust the macros to support distinguishing between different
// errors. In this case `sqlitecpp::MissingRow` and database related errors. Same for the other functions.
IKARUS_VTRYRV_OR_FAIL(
auto const id,
nullptr,
"unable to find entity in database: {}",
IkarusErrorInfo_Client_InvalidInput,
project->db->query_one<IkarusId>("SELECT `id` FROM `entities` WHERE `name` = ?", name)
);
return project->get_entity(id);
}
struct IkarusProperty *
get_property_by_name(IkarusProject * project, IkarusPropertyScope * scope, char const * name, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, nullptr);
IKARUS_FAIL_IF_NULL(name, nullptr);
IKARUS_FAIL_IF_NAME_INVALID(name, nullptr);
IKARUS_VTRYRV_OR_FAIL(
auto const id_and_type,
nullptr,
"unable to find property in database: {}",
IkarusErrorInfo_Client_InvalidInput,
project->db->query_one<IkarusId, IkarusPropertyType>(
"SELECT `id`, `type` FROM `properties` WHERE `name` = ? AND `scope` = ?",
name,
scope->get_id()
)
);
auto const [id, type] = id_and_type;
return project->get_property(id, type);
}
IkarusBlueprint * get_blueprints_by_name(IkarusProject * project, char const * name, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, nullptr);
IKARUS_FAIL_IF_NULL(name, nullptr);
IKARUS_FAIL_IF_NAME_INVALID(name, nullptr);
IKARUS_VTRYRV_OR_FAIL(
auto const id,
nullptr,
"unable to find blueprint in database: {}",
IkarusErrorInfo_Client_InvalidInput,
project->db->query_one<IkarusId>("SELECT `id` FROM `blueprints` WHERE `name` = ?", name)
);
return project->get_blueprint(id);
}