check result from 'ikarus_default_value' SQLite function creation

Signed-off-by: Folling <mail@folling.io>
This commit is contained in:
folling 2025-01-05 12:15:07 +01:00 committed by Folling
parent fa42b17178
commit 0d2b62a1cc
Signed by: folling
SSH key fingerprint: SHA256:S9qEx5WCFFLK49tE/LKnKuJYM5sw+++Dn6qJbbyxnCY

View file

@ -18,11 +18,8 @@
constexpr char const * DB_PROJECT_ID_KEY = "project_id";
constexpr char const * DB_PROJECT_NAME_KEY = "project_name";
auto create_impl(
std::string_view path,
std::string_view name,
IkarusErrorData * error_out
) -> std::unique_ptr<sqlitecpp::Connection> {
auto create_impl(std::string_view path, std::string_view name, IkarusErrorData * error_out)
-> std::unique_ptr<sqlitecpp::Connection> {
IKARUS_VTRYRV_OR_FAIL(
auto db,
nullptr,
@ -65,65 +62,46 @@ auto create_impl(
nullptr,
"failed to set project id",
IkarusErrorInfo_Database_QueryFailed,
db->execute(
"INSERT INTO `metadata`(`key`, `value`) VALUES(?, ?)",
DB_PROJECT_NAME_KEY,
name
)
.on_error(close_db)
db->execute("INSERT INTO `metadata`(`key`, `value`) VALUES(?, ?)", DB_PROJECT_NAME_KEY, name).on_error(close_db)
);
db->create_function(
"ikarus_default_value",
1,
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
IKARUS_TRYRV_OR_FAIL(
nullptr,
[](sqlite3_context * ctx, int argc, sqlite3_value ** argv) {
if (sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
sqlite3_result_error(
ctx,
"expected the 'schema' parameter to be of type text",
SQLITE_MISMATCH
);
return;
"failed to create custom `ikarus_default_value` SQLite function: {}",
IkarusErrorInfo_Database_QueryFailed,
db->create_function(
"ikarus_default_value",
1,
SQLITE_UTF8 | SQLITE_DETERMINISTIC,
nullptr,
[](sqlite3_context * ctx, int argc, sqlite3_value ** argv) {
if (sqlite3_value_type(argv[0]) != SQLITE_TEXT) {
sqlite3_result_error(ctx, "expected the 'schema' parameter to be of type text", SQLITE_MISMATCH);
return;
}
auto const schema_json = reinterpret_cast<char const *>(sqlite3_value_text(argv[0]));
auto schema_res = IkarusValueSchema::from_json_str(schema_json);
if (schema_res.is_error()) {
sqlite3_result_error(ctx, "failed to parse schema", SQLITE_ERROR);
return;
}
auto schema = std::move(schema_res).unwrap_value();
auto default_value_json = IkarusValue::to_json(schema.default_value()).dump();
sqlite3_result_text(ctx, default_value_json.data(), default_value_json.size(), SQLITE_TRANSIENT);
}
auto const schema_json =
reinterpret_cast<char const *>(sqlite3_value_text(argv[0]));
auto schema_res = IkarusValueSchema::from_json_str(schema_json);
if (schema_res.is_error()) {
sqlite3_result_error(
ctx,
"failed to parse schema",
SQLITE_ERROR
);
return;
}
auto schema = std::move(schema_res).unwrap_value();
auto default_value_json =
IkarusValue::to_json(schema.default_value()).dump();
sqlite3_result_text(
ctx,
default_value_json.data(),
default_value_json.size(),
SQLITE_TRANSIENT
);
}
)
);
return std::move(db);
}
IkarusProject * ikarus_project_create(
char const * path,
char const * name,
IkarusErrorData * error_out
) {
IkarusProject * ikarus_project_create(char const * path, char const * name, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(path, nullptr);
IKARUS_FAIL_IF_NULL(name, nullptr);
IKARUS_FAIL_IF(
@ -147,18 +125,10 @@ IkarusProject * ikarus_project_create(
IKARUS_FAIL_IF(
ec && ec != boost::system::errc::no_such_file_or_directory,
nullptr,
fmt::format(
"unable to check whether path is occupied: {}",
ec.message()
),
IkarusErrorInfo_Filesystem_AlreadyExists
);
IKARUS_FAIL_IF(
exists,
nullptr,
"path is already occupied",
fmt::format("unable to check whether path is occupied: {}", ec.message()),
IkarusErrorInfo_Filesystem_AlreadyExists
);
IKARUS_FAIL_IF(exists, nullptr, "path is already occupied", IkarusErrorInfo_Filesystem_AlreadyExists);
}
if (auto db = create_impl(fs_path.c_str(), name, error_out); !db) {
@ -167,18 +137,9 @@ IkarusProject * ikarus_project_create(
boost::system::error_code ec;
boost::filesystem::remove(fs_path, ec);
IKARUS_FAIL_IF(
ec,
nullptr,
"failed to remove project db",
IkarusErrorInfo_Filesystem_MissingPermissions
);
IKARUS_FAIL_IF(ec, nullptr, "failed to remove project db", IkarusErrorInfo_Filesystem_MissingPermissions);
IKARUS_FAIL(
nullptr,
"failed to insert project name into metadata: {}",
IkarusErrorInfo_Database_QueryFailed
);
IKARUS_FAIL(nullptr, "failed to insert project name into metadata: {}", IkarusErrorInfo_Database_QueryFailed);
return nullptr;
} else {
@ -186,10 +147,7 @@ IkarusProject * ikarus_project_create(
}
}
IkarusProject * ikarus_project_create_in_memory(
char const * name,
IkarusErrorData * error_out
) {
IkarusProject * ikarus_project_create_in_memory(char const * name, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(name, nullptr);
IKARUS_FAIL_IF(
cppbase::is_empty_or_blank(name),
@ -212,18 +170,13 @@ IkarusProject * ikarus_project_create_in_memory(
nullptr,
"failed to insert project name into metadata: {}",
IkarusErrorInfo_Database_QueryFailed,
db->execute(
"INSERT INTO `metadata`(`key`, `value`) VALUES(?, ?)",
DB_PROJECT_NAME_KEY,
name
)
db->execute("INSERT INTO `metadata`(`key`, `value`) VALUES(?, ?)", DB_PROJECT_NAME_KEY, name)
);
return new IkarusProject{name, ":memory:", std::move(db)};
}
}
IkarusProject *
ikarus_project_open(char const * path, IkarusErrorData * error_out) {
IkarusProject * ikarus_project_open(char const * path, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(path, nullptr);
IKARUS_FAIL_IF(
cppbase::is_empty_or_blank(path),
@ -252,29 +205,19 @@ ikarus_project_open(char const * path, IkarusErrorData * error_out) {
nullptr,
"failed to retrieve project name from metadata: {}",
IkarusErrorInfo_Database_QueryFailed,
db->query_one<std::string>(
"SELECT `value` FROM `metadata` WHERE `key` = ?",
DB_PROJECT_NAME_KEY
)
db->query_one<std::string>("SELECT `value` FROM `metadata` WHERE `key` = ?", DB_PROJECT_NAME_KEY)
);
return new IkarusProject{name, path, std::move(db)};
}
char const * ikarus_project_get_name(
IkarusProject const * project,
IkarusErrorData * error_out
) {
char const * ikarus_project_get_name(IkarusProject const * project, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, nullptr);
return project->name.data();
}
void ikarus_project_set_name(
IkarusProject * project,
char const * new_name,
IkarusErrorData * error_out
) {
void ikarus_project_set_name(IkarusProject * project, char const * new_name, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, IKARUS_VOID_RETURN);
IKARUS_FAIL_IF_NULL(new_name, IKARUS_VOID_RETURN);
@ -289,18 +232,11 @@ void ikarus_project_set_name(
IKARUS_VOID_RETURN,
"failed to update project name: {}",
IkarusErrorInfo_Database_QueryFailed,
project->db->execute(
"UPDATE `metadata` SET `value` = ? WHERE `key` = ?",
new_name,
DB_PROJECT_NAME_KEY
)
project->db->execute("UPDATE `metadata` SET `value` = ? WHERE `key` = ?", new_name, DB_PROJECT_NAME_KEY)
);
}
char const * ikarus_project_get_path(
IkarusProject const * project,
IkarusErrorData * error_out
) {
char const * ikarus_project_get_path(IkarusProject const * project, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, nullptr);
return project->path.c_str();
@ -323,18 +259,11 @@ void ikarus_project_get_entities(
IKARUS_VOID_RETURN,
"unable to fetch project entities from database: {}",
IkarusErrorInfo_Database_QueryFailed,
project->db->query_many_buffered<int64_t>(
"SELECT `id` FROM `entities`",
ids_out,
ids_out_size
)
project->db->query_many_buffered<int64_t>("SELECT `id` FROM `entities`", ids_out, ids_out_size)
);
}
size_t ikarus_project_get_entity_count(
IkarusProject const * project,
IkarusErrorData * error_out
) {
size_t ikarus_project_get_entity_count(IkarusProject const * project, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, 0);
IKARUS_VTRYRV_OR_FAIL(
@ -365,18 +294,11 @@ void ikarus_project_get_blueprints(
,
"unable to fetch project blueprints from database: {}",
IkarusErrorInfo_Database_QueryFailed,
project->db->query_many_buffered<int64_t>(
"SELECT `id` FROM `blueprints`",
ids_out,
ids_out_size
)
project->db->query_many_buffered<int64_t>("SELECT `id` FROM `blueprints`", ids_out, ids_out_size)
);
}
size_t ikarus_project_get_blueprint_count(
IkarusProject const * project,
IkarusErrorData * error_out
) {
size_t ikarus_project_get_blueprint_count(IkarusProject const * project, IkarusErrorData * error_out) {
IKARUS_FAIL_IF_NULL(project, 0);
IKARUS_VTRYRV_OR_FAIL(