diff --git a/CHANGELOG.md b/CHANGELOG.md index 03710a3d17afebc1636ed47bd870742db3be9e04..d4d39bda064d6caf53ddfd816cdb398f1eed07de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added -- New functions getEnumNameFromValue() and getEnumValueFromName(). +* New functions getEnumNameFromValue() and getEnumValueFromName(). +* Extern C now supports datatypes, roles, and importances as enums, + and typed property values ### Changed diff --git a/include/caosdb/status_code.h b/include/caosdb/status_code.h index 573b126fa94435c4669ace37ea00cbdbbbde6545..5689b9ebeab94d01272ce049d3cb0e3f16d13665 100644 --- a/include/caosdb/status_code.h +++ b/include/caosdb/status_code.h @@ -61,6 +61,7 @@ enum StatusCode { FILE_DOES_NOT_EXIST_LOCALLY = 34, FILE_UPLOAD_ERROR = 35, FILE_DOWNLOAD_ERROR = 36, + ENUM_MAPPING_ERROR = 37, OTHER_CLIENT_ERROR = 9999, }; diff --git a/include/ccaosdb.h b/include/ccaosdb.h index d2f899fd7657fa4c3867f2e008ff9fb270ca8490..e23e3a72ad58167e060081757e97d84cbfeaa2b8 100644 --- a/include/ccaosdb.h +++ b/include/ccaosdb.h @@ -321,14 +321,32 @@ typedef struct { } caosdb_entity_message; // GETTERS FOR EVERYTHING -int caosdb_entity_entity_get_id(caosdb_entity_entity *entity, char *out); -int caosdb_entity_entity_get_role(caosdb_entity_entity *entity, char *out); -int caosdb_entity_entity_get_name(caosdb_entity_entity *entity, char *out); -int caosdb_entity_entity_get_description(caosdb_entity_entity *entity, char *out); -int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, char *out); -int caosdb_entity_entity_get_unit(caosdb_entity_entity *entity, char *out); -int caosdb_entity_entity_get_value(caosdb_entity_entity *entity, char *out); -int caosdb_entity_entity_get_version_id(caosdb_entity_entity *entity, char *out); +int caosdb_entity_entity_get_id(caosdb_entity_entity *entity, char **out); +int caosdb_entity_entity_get_role(caosdb_entity_entity *entity, char **out); +int caosdb_entity_entity_get_name(caosdb_entity_entity *entity, char **out); +int caosdb_entity_entity_get_description(caosdb_entity_entity *entity, char **out); +/** + * Get the name of the entity's datatype, whether it is a reference, and whether it is a list. + */ +int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, char **name, bool *is_ref, + bool *is_list); +int caosdb_entity_entity_get_unit(caosdb_entity_entity *entity, char **out); + +int caosdb_entity_entity_get_int_value(caosdb_entity_entity *entity, long *out); +int caosdb_entity_entity_get_double_value(caosdb_entity_entity *entity, double *out); +int caosdb_entity_entity_get_boolean_value(caosdb_entity_entity *entity, bool *out); +int caosdb_entity_entity_get_string_value(caosdb_entity_entity *entity, char **out); +int caosdb_entity_entity_get_int_list_value_at(caosdb_entity_entity *entity, long *out, + const int index); +int caosdb_entity_entity_get_double_list_value_at(caosdb_entity_entity *entity, double *out, + const int index); +int caosdb_entity_entity_get_boolean_list_value_at(caosdb_entity_entity *entity, bool *out, + const int index); +int caosdb_entity_entity_get_string_list_value_at(caosdb_entity_entity *entity, char **out, + const int index); +int caosdb_entity_entity_get_value_list_length(caosdb_entity_entity *entity, int *out); + +int caosdb_entity_entity_get_version_id(caosdb_entity_entity *entity, char **out); int caosdb_entity_entity_get_errors_size(caosdb_entity_entity *entity, int *out); int caosdb_entity_entity_get_error(caosdb_entity_entity *entity, caosdb_entity_message *out, int index); @@ -345,20 +363,37 @@ int caosdb_entity_entity_get_parents_size(caosdb_entity_entity *entity, int *out int caosdb_entity_entity_get_parent(caosdb_entity_entity *entity, caosdb_entity_parent *out, int index); -int caosdb_entity_property_get_id(caosdb_entity_property *property, char *out); -int caosdb_entity_property_get_name(caosdb_entity_property *property, char *out); -int caosdb_entity_property_get_description(caosdb_entity_property *property, char *out); -int caosdb_entity_property_get_importance(caosdb_entity_property *property, char *out); -int caosdb_entity_property_get_datatype(caosdb_entity_property *property, char *out); -int caosdb_entity_property_get_unit(caosdb_entity_property *property, char *out); -int caosdb_entity_property_get_value(caosdb_entity_property *property, char *out); - -int caosdb_entity_parent_get_id(caosdb_entity_parent *parent, char *out); -int caosdb_entity_parent_get_name(caosdb_entity_parent *parent, char *out); -int caosdb_entity_parent_get_description(caosdb_entity_parent *parent, char *out); +int caosdb_entity_property_get_id(caosdb_entity_property *property, char **out); +int caosdb_entity_property_get_name(caosdb_entity_property *property, char **out); +int caosdb_entity_property_get_description(caosdb_entity_property *property, char **out); +int caosdb_entity_property_get_importance(caosdb_entity_property *property, char **out); +/** + * Get the name of the property's datatype, whether it is a reference, and whether it is a list. + */ +int caosdb_entity_property_get_datatype(caosdb_entity_property *property, char **name, bool *is_ref, + bool *is_list); +int caosdb_entity_property_get_unit(caosdb_entity_property *property, char **out); + +int caosdb_entity_property_get_int_value(caosdb_entity_property *property, long *out); +int caosdb_entity_property_get_double_value(caosdb_entity_property *property, double *out); +int caosdb_entity_property_get_boolean_value(caosdb_entity_property *property, bool *out); +int caosdb_entity_property_get_string_value(caosdb_entity_property *property, char **out); +int caosdb_entity_property_get_int_list_value_at(caosdb_entity_property *property, long *out, + const int index); +int caosdb_entity_property_get_double_list_value_at(caosdb_entity_property *property, double *out, + const int index); +int caosdb_entity_property_get_boolean_list_value_at(caosdb_entity_property *property, bool *out, + const int index); +int caosdb_entity_property_get_string_list_value_at(caosdb_entity_property *property, char **out, + const int index); +int caosdb_entity_property_get_value_list_length(caosdb_entity_property *property, int *out); + +int caosdb_entity_parent_get_id(caosdb_entity_parent *parent, char **out); +int caosdb_entity_parent_get_name(caosdb_entity_parent *parent, char **out); +int caosdb_entity_parent_get_description(caosdb_entity_parent *parent, char **out); int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out); -int caosdb_entity_message_get_description(caosdb_entity_message *message, char *out); +int caosdb_entity_message_get_description(caosdb_entity_message *message, char **out); // CONSTRUCTORS AND DESTRUCTORS int caosdb_entity_create_entity(caosdb_entity_entity *out); @@ -372,9 +407,26 @@ int caosdb_entity_delete_parent(caosdb_entity_parent *out); int caosdb_entity_entity_set_role(caosdb_entity_entity *entity, const char *role); int caosdb_entity_entity_set_name(caosdb_entity_entity *entity, const char *name); int caosdb_entity_entity_set_description(caosdb_entity_entity *entity, const char *description); -int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity, const char *datatype); +/** + * Set the entity's datatype by name, and whether it is a reference or a list. + */ +int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity, const char *datatype, + const bool is_ref, const bool is_list); int caosdb_entity_entity_set_unit(caosdb_entity_entity *entity, const char *unit); -int caosdb_entity_entity_set_value(caosdb_entity_entity *entity, const char *value); +// TODO(fspreck) replace by more specific setters +int caosdb_entity_entity_set_int_value(caosdb_entity_entity *entity, const long value); +int caosdb_entity_entity_set_double_value(caosdb_entity_entity *entity, const double value); +int caosdb_entity_entity_set_boolean_value(caosdb_entity_entity *entity, const bool value); +int caosdb_entity_entity_set_string_value(caosdb_entity_entity *entity, const char *value); +int caosdb_entity_entity_set_int_list_value(caosdb_entity_entity *entity, const long *value, + const int length); +int caosdb_entity_entity_set_double_list_value(caosdb_entity_entity *entity, const double *value, + const int length); +int caosdb_entity_entity_set_boolean_list_value(caosdb_entity_entity *entity, const bool *value, + const int length); +int caosdb_entity_entity_set_string_list_value(caosdb_entity_entity *entity, const char **value, + const int length); + int caosdb_entity_entity_append_parent(caosdb_entity_entity *entity, caosdb_entity_parent *parent); int caosdb_entity_entity_remove_parent(caosdb_entity_entity *entity, int index); int caosdb_entity_entity_append_property(caosdb_entity_entity *entity, @@ -383,10 +435,26 @@ int caosdb_entity_entity_remove_property(caosdb_entity_entity *entity, int index int caosdb_entity_property_set_id(caosdb_entity_property *property, const char *id); int caosdb_entity_property_set_name(caosdb_entity_property *property, const char *name); -int caosdb_entity_property_set_datatype(caosdb_entity_property *property, const char *datatype); +/** + * Set the property's datatype by name, and whether it is a reference or a list. + */ +int caosdb_entity_property_set_datatype(caosdb_entity_property *property, const char *datatype, + const bool is_ref, const bool is_list); int caosdb_entity_property_set_importance(caosdb_entity_property *property, const char *importance); int caosdb_entity_property_set_unit(caosdb_entity_property *property, const char *unit); -int caosdb_entity_property_set_value(caosdb_entity_property *property, const char *value); + +int caosdb_entity_property_set_int_value(caosdb_entity_property *property, const long value); +int caosdb_entity_property_set_double_value(caosdb_entity_property *property, const double value); +int caosdb_entity_property_set_boolean_value(caosdb_entity_property *property, const bool value); +int caosdb_entity_property_set_string_value(caosdb_entity_property *property, const char *value); +int caosdb_entity_property_set_int_list_value(caosdb_entity_property *property, const long *value, + const int length); +int caosdb_entity_property_set_double_list_value(caosdb_entity_property *property, + const double *value, const int length); +int caosdb_entity_property_set_boolean_list_value(caosdb_entity_property *property, + const bool *value, const int length); +int caosdb_entity_property_set_string_list_value(caosdb_entity_property *property, + const char **value, const int length); int caosdb_entity_parent_set_id(caosdb_entity_parent *parent, const char *id); int caosdb_entity_parent_set_name(caosdb_entity_parent *parent, const char *name); diff --git a/src/caosdb/transaction.cpp b/src/caosdb/transaction.cpp index 75350b2680b55976d9a7a96b58962540216d4eae..5a7cb74683071f42e54f8ad056f37643092bb4ef 100644 --- a/src/caosdb/transaction.cpp +++ b/src/caosdb/transaction.cpp @@ -96,6 +96,8 @@ auto get_status_description(int code) -> const std::string & { {StatusCode::EXTERN_C_ASSIGNMENT_ERROR, "You tried to assign a new object to the wrapped void pointer. You have " "to delete the old pointee first."}, + {StatusCode::ENUM_MAPPING_ERROR, + "The role, importance, or datatype you specified does not exist."}, {StatusCode::OTHER_CLIENT_ERROR, "This is code is reserved to errors raised by other clients wrapping the " "C++ client (or its Extern C interface). This should never occur when " diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp index dce0970bf21343eb12ffac6098450d507de70e59..40a47227c5d146a97583e5068b033896e17b1cfe 100644 --- a/src/ccaosdb.cpp +++ b/src/ccaosdb.cpp @@ -22,6 +22,7 @@ #include "ccaosdb.h" #include "caosdb/connection.h" #include "caosdb/constants.h" +#include "caosdb/data_type.h" // for DataType, AtomicDat... #include "caosdb/utility.h" #include "caosdb/status_code.h" #include "caosdb/logging.h" @@ -37,6 +38,20 @@ extern "C" { #define CCAOSDB_LOGGER_NAME "ccaosdb" +#define WRAPPED_ENTITY_CAST(name) static_cast<caosdb::entity::Entity *>(name->wrapped_entity) + +#define WRAPPED_PROPERTY_CAST(name) static_cast<caosdb::entity::Property *>(name->wrapped_property) + +#define WRAPPED_PARENT_CAST(name) static_cast<caosdb::entity::Parent *>(name->wrapped_parent) + +#define WRAPPED_MESSAGE_CAST(name) static_cast<caosdb::entity::Message *>(name->wrapped_message) + +#define ENUM_NAME_FROM_VALUE(arg, etype) \ + caosdb::utility::getEnumNameFromValue<caosdb::entity::etype>(arg) + +#define ENUM_VALUE_FROM_NAME(arg, etype) \ + caosdb::utility::getEnumValueFromName<caosdb::entity::etype>(arg) + /* * Macro for wrapping every function into a try-catch clause. If an exception * occurs, the given StatusCode is being returned. @@ -55,12 +70,16 @@ extern "C" { /** * Macro for entity getters */ -#define CAOSDB_ENTITY_GET(element, body_part) \ +#define CAOSDB_ENTITY_GET(element, GetFunction) \ ERROR_RETURN_CODE( \ GENERIC_ERROR, \ - int caosdb_entity_entity_get_##element(caosdb_entity_entity *entity, char *out), { \ - auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); \ - body_part return 0; \ + int caosdb_entity_entity_get_##element(caosdb_entity_entity *entity, char **out), { \ + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); \ + char *tmp = (char *)malloc(sizeof(char) * wrapped_entity->GetFunction.length() + 1); \ + strcpy(tmp, wrapped_entity->GetFunction.c_str()); \ + delete[] * out; \ + *out = tmp; \ + return 0; \ }) /** @@ -70,20 +89,23 @@ extern "C" { ERROR_RETURN_CODE( \ GENERIC_ERROR, \ int caosdb_entity_entity_set_##element(caosdb_entity_entity *entity, const char *value), { \ - auto *wrapped_entity = static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); \ + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); \ body_part return 0; \ }) /** * Macro for property getters */ -#define CAOSDB_PROPERTY_GET(element, body_part) \ +#define CAOSDB_PROPERTY_GET(element, GetFunction) \ ERROR_RETURN_CODE( \ GENERIC_ERROR, \ - int caosdb_entity_property_get_##element(caosdb_entity_property *property, char *out), { \ - auto *wrapped_property = \ - static_cast<caosdb::entity::Property *>(property->wrapped_property); \ - body_part return 0; \ + int caosdb_entity_property_get_##element(caosdb_entity_property *property, char **out), { \ + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); \ + char *tmp = (char *)malloc(sizeof(char) * wrapped_property->GetFunction.length() + 1); \ + strcpy(tmp, wrapped_property->GetFunction.c_str()); \ + delete[] * out; \ + *out = tmp; \ + return 0; \ }) /** @@ -94,20 +116,23 @@ extern "C" { GENERIC_ERROR, \ int caosdb_entity_property_set_##element(caosdb_entity_property *property, const char *value), \ { \ - auto *wrapped_property = \ - static_cast<caosdb::entity::Property *>(property->wrapped_property); \ + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); \ body_part return 0; \ }) /** * Macro for parent getters */ -#define CAOSDB_PARENT_GET(element, body_part) \ +#define CAOSDB_PARENT_GET(element, GetFunction) \ ERROR_RETURN_CODE( \ GENERIC_ERROR, \ - int caosdb_entity_parent_get_##element(caosdb_entity_parent *parent, char *out), { \ - auto *wrapped_parent = static_cast<caosdb::entity::Parent *>(parent->wrapped_parent); \ - body_part return 0; \ + int caosdb_entity_parent_get_##element(caosdb_entity_parent *parent, char **out), { \ + auto *wrapped_parent = WRAPPED_PARENT_CAST(parent); \ + char *tmp = (char *)malloc(sizeof(char) * wrapped_parent->GetFunction.length() + 1); \ + strcpy(tmp, wrapped_parent->GetFunction.c_str()); \ + delete[] * out; \ + *out = tmp; \ + return 0; \ }) /** @@ -117,7 +142,7 @@ extern "C" { ERROR_RETURN_CODE( \ GENERIC_ERROR, \ int caosdb_entity_parent_set_##element(caosdb_entity_parent *parent, const char *value), { \ - auto *wrapped_parent = static_cast<caosdb::entity::Parent *>(parent->wrapped_parent); \ + auto *wrapped_parent = WRAPPED_PARENT_CAST(parent); \ body_part return 0; \ }) @@ -514,18 +539,130 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_parent(caosdb_entity_p return 0; }) -CAOSDB_ENTITY_GET(id, strcpy(out, wrapped_entity->GetId().c_str());) -// TODO(fspreck) -// CAOSDB_ENTITY_GET(role, strcpy(out, wrapped_entity->GetRole().c_str());) -CAOSDB_ENTITY_GET(name, strcpy(out, wrapped_entity->GetName().c_str());) -CAOSDB_ENTITY_GET(description, strcpy(out, wrapped_entity->GetDescription().c_str());) -// TODO(fspreck) -// CAOSDB_ENTITY_GET(datatype, strcpy(out, -// wrapped_entity->GetDatatype().c_str());) -// TODO(fspreck) -// CAOSDB_ENTITY_GET(value, strcpy(out, wrapped_entity->GetValue().c_str());) -CAOSDB_ENTITY_GET(unit, strcpy(out, wrapped_entity->GetUnit().c_str());) -CAOSDB_ENTITY_GET(version_id, strcpy(out, wrapped_entity->GetVersionId().c_str());) +CAOSDB_ENTITY_GET(id, GetId()) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_role(caosdb_entity_entity *entity, char **out), { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + std::string role_str = ENUM_NAME_FROM_VALUE(wrapped_entity->GetRole(), Role); + char *tmp = (char *)malloc(sizeof(char) * role_str.length() + 1); + strcpy(tmp, role_str.c_str()); + delete[] * out; + *out = tmp; + return 0; + }) +CAOSDB_ENTITY_GET(name, GetName()) +CAOSDB_ENTITY_GET(description, GetDescription()) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, char **name, + bool *is_ref, bool *is_list), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + const auto &datatype = wrapped_entity->GetDataType(); + *is_list = datatype.IsList(); + std::string datatype_name; + if (*is_list) { + const auto &list_datatype = datatype.AsList(); + *is_ref = list_datatype.IsListOfReference(); + if (*is_ref) { + datatype_name = list_datatype.GetReferenceDataType().GetName(); + } else { + datatype_name = + ENUM_NAME_FROM_VALUE(list_datatype.GetAtomicDataType(), AtomicDataType); + } + } else { + *is_ref = datatype.IsReference(); + if (*is_ref) { + datatype_name = datatype.AsReference().GetName(); + } else { + datatype_name = ENUM_NAME_FROM_VALUE(datatype.AsAtomic(), AtomicDataType); + } + } + char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1); + strcpy(tmp, datatype_name.c_str()); + delete[] * name; + *name = tmp; + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_int_value(caosdb_entity_entity *entity, long *out), { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + *out = wrapped_entity->GetValue().AsInteger(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_double_value(caosdb_entity_entity *entity, + double *out), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + *out = wrapped_entity->GetValue().AsDouble(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_boolean_value(caosdb_entity_entity *entity, + bool *out), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + *out = wrapped_entity->GetValue().AsBool(); + return 0; + }) +CAOSDB_ENTITY_GET(string_value, GetValue().AsString()) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_int_list_value_at(caosdb_entity_entity *entity, + long *out, const int index), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + auto value_list = wrapped_entity->GetValue().AsList(); + *out = value_list[index].AsInteger(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_double_list_value_at(caosdb_entity_entity *entity, + double *out, const int index), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + auto value_list = wrapped_entity->GetValue().AsList(); + *out = value_list[index].AsDouble(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_boolean_value_list_value_at( + caosdb_entity_entity *entity, bool *out, const int index), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + auto value_list = wrapped_entity->GetValue().AsList(); + *out = value_list[index].AsBool(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_string_list_value_at(caosdb_entity_entity *entity, + char **out, const int index), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + auto value_list = wrapped_entity->GetValue().AsList(); + char *tmp = + (char *)malloc(sizeof(char) * value_list[index].AsString().length() + 1); + strcpy(tmp, value_list[index].AsString().c_str()); + delete[] * out; + *out = tmp; + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_value_list_length(caosdb_entity_entity *entity, + int *out), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + if (wrapped_entity->GetValue().IsList()) { + *out = wrapped_entity->GetValue().AsList().size(); + } else { + *out = 0; + } + return 0; + }) + +CAOSDB_ENTITY_GET(unit, GetUnit()) +CAOSDB_ENTITY_GET(version_id, GetVersionId()) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_get_errors_size(caosdb_entity_entity *entity, int *out), @@ -643,54 +780,300 @@ ERROR_RETURN_CODE(GENERIC_ERROR, return 0; }) -CAOSDB_PARENT_GET(id, strcpy(out, wrapped_parent->GetId().c_str());) -CAOSDB_PARENT_GET(name, strcpy(out, wrapped_parent->GetName().c_str());) -CAOSDB_PARENT_GET(description, strcpy(out, wrapped_parent->GetDescription().c_str());) +CAOSDB_PARENT_GET(id, GetId()) +CAOSDB_PARENT_GET(name, GetName()) +CAOSDB_PARENT_GET(description, GetDescription()) -CAOSDB_PROPERTY_GET(id, strcpy(out, wrapped_property->GetId().c_str());) -CAOSDB_PROPERTY_GET(name, strcpy(out, wrapped_property->GetName().c_str());) -CAOSDB_PROPERTY_GET(description, strcpy(out, wrapped_property->GetDescription().c_str());) -// TODO(fspreck) -// CAOSDB_PROPERTY_GET(importance, -// strcpy(out, wrapped_property->GetImportance().c_str());) -// TODO(fspreck) -// CAOSDB_PROPERTY_GET(datatype, -// strcpy(out, wrapped_property->GetDatatype().c_str());) -CAOSDB_PROPERTY_GET(unit, strcpy(out, wrapped_property->GetUnit().c_str());) -// TODO(fspreck) -// CAOSDB_PROPERTY_GET(value, strcpy(out, -// wrapped_property->GetValue().c_str());) +CAOSDB_PROPERTY_GET(id, GetId()) +CAOSDB_PROPERTY_GET(name, GetName()) +CAOSDB_PROPERTY_GET(description, GetDescription()) ERROR_RETURN_CODE(GENERIC_ERROR, - int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out), { - auto *wrapped_message = - static_cast<caosdb::entity::Message *>(message->wrapped_message); - *out = wrapped_message->GetCode(); + int caosdb_entity_property_get_importance(caosdb_entity_property *property, + char **out), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + std::string importance_str = + ENUM_NAME_FROM_VALUE(wrapped_property->GetImportance(), Importance); + char *tmp = (char *)malloc(sizeof(char) * importance_str.length() + 1); + strcpy(tmp, importance_str.c_str()); + delete[] * out; + *out = tmp; return 0; }) ERROR_RETURN_CODE(GENERIC_ERROR, - int caosdb_entity_message_get_description(caosdb_entity_message *message, - char *out), + int caosdb_entity_property_get_datatype(caosdb_entity_property *property, + char **name, bool *is_ref, bool *is_list), { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + const auto &datatype = wrapped_property->GetDataType(); + *is_list = datatype.IsList(); + std::string datatype_name; + if (*is_list) { + const auto &list_datatype = datatype.AsList(); + *is_ref = list_datatype.IsListOfReference(); + if (*is_ref) { + datatype_name = list_datatype.GetReferenceDataType().GetName(); + } else { + datatype_name = + ENUM_NAME_FROM_VALUE(list_datatype.GetAtomicDataType(), AtomicDataType); + } + } else { + *is_ref = datatype.IsReference(); + if (*is_ref) { + datatype_name = datatype.AsReference().GetName(); + } else { + datatype_name = ENUM_NAME_FROM_VALUE(datatype.AsAtomic(), AtomicDataType); + } + } + char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1); + strcpy(tmp, datatype_name.c_str()); + delete[] * name; + *name = tmp; + return 0; + }) + +CAOSDB_PROPERTY_GET(unit, GetUnit()) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_int_value(caosdb_entity_property *property, + long *out), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + *out = wrapped_property->GetValue().AsInteger(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_double_value(caosdb_entity_property *property, + double *out), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + *out = wrapped_property->GetValue().AsDouble(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_boolean_value(caosdb_entity_property *property, + bool *out), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + *out = wrapped_property->GetValue().AsBool(); + return 0; + }) +CAOSDB_PROPERTY_GET(string_value, GetValue().AsString()) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_int_list_value_at(caosdb_entity_property *property, + long *out, const int index), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + auto value_list = wrapped_property->GetValue().AsList(); + *out = value_list[index].AsInteger(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_double_list_value_at( + caosdb_entity_property *property, double *out, const int index), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + auto value_list = wrapped_property->GetValue().AsList(); + *out = value_list[index].AsDouble(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_boolean_value_list_value_at( + caosdb_entity_property *property, bool *out, const int index), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + auto value_list = wrapped_property->GetValue().AsList(); + *out = value_list[index].AsBool(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_string_list_value_at( + caosdb_entity_property *property, char **out, const int index), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + auto value_list = wrapped_property->GetValue().AsList(); + char *tmp = + (char *)malloc(sizeof(char) * value_list[index].AsString().length() + 1); + strcpy(tmp, value_list[index].AsString().c_str()); + delete[] * out; + *out = tmp; + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_value_list_length(caosdb_entity_property *property, + int *out), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + if (wrapped_property->GetValue().IsList()) { + *out = wrapped_property->GetValue().AsList().size(); + } else { + *out = 0; + } + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out), { auto *wrapped_message = static_cast<caosdb::entity::Message *>(message->wrapped_message); - strcpy(out, wrapped_message->GetDescription().c_str()); + *out = wrapped_message->GetCode(); return 0; }) -// TODO(fspreck) -// CAOSDB_ENTITY_SET(role, role, wrapped_entity->SetRole(std::string(role));) +ERROR_RETURN_CODE( + GENERIC_ERROR, + int caosdb_entity_message_get_description(caosdb_entity_message *message, char **out), { + auto *wrapped_message = static_cast<caosdb::entity::Message *>(message->wrapped_message); + char *tmp = (char *)malloc(sizeof(char) * wrapped_message->GetDescription().length() + 1); + strcpy(tmp, wrapped_message->GetDescription().c_str()); + delete[] * out; + *out = tmp; + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_role(caosdb_entity_entity *entity, const char *role), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + try { + auto enum_value = ENUM_VALUE_FROM_NAME(std::string(role), Role); + wrapped_entity->SetRole(enum_value); + return 0; + } catch (const std::out_of_range &exc) { + caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what()); + return caosdb::StatusCode::ENUM_MAPPING_ERROR; + } + }) CAOSDB_ENTITY_SET(name, name, wrapped_entity->SetName(std::string(name));) CAOSDB_ENTITY_SET(description, description, wrapped_entity->SetDescription(std::string(description));) -// TODO(fspreck) -// CAOSDB_ENTITY_SET(datatype, datatype, -// wrapped_entity->SetDataType(std::string(datatype));) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity, + const char *datatype, const bool is_ref, + const bool is_list), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + if (is_ref) { + // Refernce datatype with name of reference + wrapped_entity->SetDataType(std::string(datatype), is_list); + return 0; + } else { + // Atomic datatype so get from enum + try { + auto enum_value = + ENUM_VALUE_FROM_NAME(std::string(datatype), AtomicDataType); + wrapped_entity->SetDataType(enum_value, is_list); + return 0; + } catch (const std::out_of_range &exc) { + caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what()); + return caosdb::StatusCode::ENUM_MAPPING_ERROR; + } + } + }) CAOSDB_ENTITY_SET(unit, unit, wrapped_entity->SetUnit(std::string(unit));) -// TODO(fspreck) -// CAOSDB_ENTITY_SET(value, value, -// wrapped_entity->SetValue(std::string(value));) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_int_value(caosdb_entity_entity *entity, + const long value), + { + auto *wrapped_entity = + static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); + wrapped_entity->SetValue(value); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_double_value(caosdb_entity_entity *entity, + const double value), + { + auto *wrapped_entity = + static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); + wrapped_entity->SetValue(value); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_boolean_value(caosdb_entity_entity *entity, + const bool value), + { + auto *wrapped_entity = + static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); + wrapped_entity->SetValue(value); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_string_value(caosdb_entity_entity *entity, + const char *value), + { + auto *wrapped_entity = + static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); + wrapped_entity->SetValue(std::string(value)); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_int_list_value(caosdb_entity_entity *entity, + const long *value, const int length), + { + auto *wrapped_entity = + static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); + std::vector<long> value_list; + for (int i = 0; i < length; i++) { + value_list.push_back(value[i]); + } + wrapped_entity->SetValue(value_list); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_double_list_value(caosdb_entity_entity *entity, + const double *value, + const int length), + { + auto *wrapped_entity = + static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); + std::vector<double> value_list; + for (int i = 0; i < length; i++) { + value_list.push_back(value[i]); + } + wrapped_entity->SetValue(value_list); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_boolean_list_value(caosdb_entity_entity *entity, + const bool *value, + const int length), + { + auto *wrapped_entity = + static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); + std::vector<bool> value_list; + for (int i = 0; i < length; i++) { + value_list.push_back(value[i]); + } + wrapped_entity->SetValue(value_list); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_string_list_value(caosdb_entity_entity *entity, + const char **value, + const int length), + { + auto *wrapped_entity = + static_cast<caosdb::entity::Entity *>(entity->wrapped_entity); + std::vector<std::string> value_list; + for (int i = 0; i < length; i++) { + value_list.push_back(std::string(value[i])); + } + wrapped_entity->SetValue(value_list); + return 0; + }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_append_parent(caosdb_entity_entity *entity, @@ -737,14 +1120,144 @@ CAOSDB_PARENT_SET(name, name, wrapped_parent->SetName(std::string(name));) CAOSDB_PROPERTY_SET(name, name, wrapped_property->SetName(std::string(name));) CAOSDB_PROPERTY_SET(id, id, wrapped_property->SetId(std::string(id));) -// TODO(fspreck) -// CAOSDB_PROPERTY_SET(datatype, datatype, -// wrapped_property->SetDataType(std::string(datatype));) -// TODO(fspreck) -// CAOSDB_PROPERTY_SET(importance, importance, -// wrapped_property->SetImportance(std::string(importance));) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_datatype(caosdb_entity_property *property, + const char *datatype, const bool is_ref, + const bool is_list), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + if (is_ref) { + // Refernce datatype with name of reference + wrapped_property->SetDataType(std::string(datatype), is_list); + return 0; + } else { + // Atomic datatype so get from enum + try { + auto enum_value = + ENUM_VALUE_FROM_NAME(std::string(datatype), AtomicDataType); + wrapped_property->SetDataType(enum_value, is_list); + return 0; + } catch (const std::out_of_range &exc) { + caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what()); + return caosdb::StatusCode::ENUM_MAPPING_ERROR; + } + } + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_importance(caosdb_entity_property *property, + const char *importance), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + try { + auto enum_value = ENUM_VALUE_FROM_NAME(std::string(importance), Importance); + wrapped_property->SetImportance(enum_value); + return 0; + } catch (const std::out_of_range &exc) { + caosdb::logging::caosdb_log_fatal(CCAOSDB_LOGGER_NAME, exc.what()); + return caosdb::StatusCode::ENUM_MAPPING_ERROR; + } + }) + CAOSDB_PROPERTY_SET(unit, unit, wrapped_property->SetUnit(std::string(unit));) -// TODO(fspreck) -// CAOSDB_PROPERTY_SET(value, value, -// wrapped_property->SetValue(std::string(value));) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_int_value(caosdb_entity_property *property, + const long value), + { + auto *wrapped_property = + static_cast<caosdb::entity::Property *>(property->wrapped_property); + wrapped_property->SetValue(value); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_double_value(caosdb_entity_property *property, + const double value), + { + auto *wrapped_property = + static_cast<caosdb::entity::Property *>(property->wrapped_property); + wrapped_property->SetValue(value); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_boolean_value(caosdb_entity_property *property, + const bool value), + { + auto *wrapped_property = + static_cast<caosdb::entity::Property *>(property->wrapped_property); + wrapped_property->SetValue(value); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_string_value(caosdb_entity_property *property, + const char *value), + { + auto *wrapped_property = + static_cast<caosdb::entity::Property *>(property->wrapped_property); + wrapped_property->SetValue(std::string(value)); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_int_list_value(caosdb_entity_property *property, + const long *value, + const int length), + { + auto *wrapped_property = + static_cast<caosdb::entity::Property *>(property->wrapped_property); + std::vector<long> value_list; + for (int i = 0; i < length; i++) { + value_list.push_back(value[i]); + } + wrapped_property->SetValue(value_list); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_double_list_value(caosdb_entity_property *property, + const double *value, + const int length), + { + auto *wrapped_property = + static_cast<caosdb::entity::Property *>(property->wrapped_property); + std::vector<double> value_list; + for (int i = 0; i < length; i++) { + value_list.push_back(value[i]); + } + wrapped_property->SetValue(value_list); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_boolean_list_value( + caosdb_entity_property *property, const bool *value, const int length), + { + auto *wrapped_property = + static_cast<caosdb::entity::Property *>(property->wrapped_property); + std::vector<bool> value_list; + for (int i = 0; i < length; i++) { + value_list.push_back(value[i]); + } + wrapped_property->SetValue(value_list); + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_string_list_value(caosdb_entity_property *property, + const char **value, + const int length), + { + auto *wrapped_property = + static_cast<caosdb::entity::Property *>(property->wrapped_property); + std::vector<std::string> value_list; + for (int i = 0; i < length; i++) { + value_list.push_back(std::string(value[i])); + } + wrapped_property->SetValue(value_list); + return 0; + }) } diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp index 2c45ef7bf3986c8461a9ffe0943e8d1ba1112621..22c59949d0b2e6356b45cf5c96e83d32e43116aa 100644 --- a/test/test_ccaosdb.cpp +++ b/test/test_ccaosdb.cpp @@ -97,22 +97,18 @@ TEST_F(test_ccaosdb, test_execute_transaction) { } TEST_F(test_ccaosdb, test_multi_retrieve) { - std::cout << "Entering test_multi_retrieve ..." << std::endl; caosdb_connection_connection connection; caosdb_connection_connection_manager_get_connection(&connection, "local-caosdb-admin"); - std::cout << "Creating transaction" << std::endl; caosdb_transaction_transaction multi_transaction; caosdb_connection_connection_create_transaction(&connection, &multi_transaction); // We explicitely want to define a C-style array here, so we disable // linting const char *ids[] = {"id1", "id2", "id3"}; // NOLINT - std::cout << "Adding mutli retrieval ..." << std::endl; int return_code(caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids, 3)); EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON); - std::cout << "Deleting transaction ..." << std::endl; return_code = caosdb_transaction_delete_transaction(&multi_transaction); EXPECT_EQ(return_code, 0); } @@ -151,33 +147,41 @@ TEST_F(test_ccaosdb, test_entity) { // the strings for the rest return_code = caosdb_entity_entity_set_name(&entity, "length"); EXPECT_EQ(return_code, 0); - char out[255] = {"a"}; // NOLINT - return_code = caosdb_entity_entity_get_name(&entity, out); + char *out = nullptr; // NOLINT + return_code = caosdb_entity_entity_get_name(&entity, &out); EXPECT_EQ(return_code, 0); EXPECT_EQ(strcmp(out, "length"), 0); - // TODO(fspreck) - // caosdb_entity_entity_set_role(&entity, "Property"); - // caosdb_entity_entity_get_role(&entity, out); - // EXPECT_EQ(strcmp(out, "Property"), 0); + // invalid role + return_code = caosdb_entity_entity_set_role(&entity, "Role does not exist"); + EXPECT_EQ(return_code, caosdb::StatusCode::ENUM_MAPPING_ERROR); + + caosdb_entity_entity_set_role(&entity, "PROPERTY"); + caosdb_entity_entity_get_role(&entity, &out); + EXPECT_EQ(strcmp(out, "PROPERTY"), 0); caosdb_entity_entity_set_description(&entity, "The length of an object"); - caosdb_entity_entity_get_description(&entity, out); + caosdb_entity_entity_get_description(&entity, &out); EXPECT_EQ(strcmp(out, "The length of an object"), 0); - // TODO(fspreck) - // caosdb_entity_entity_set_datatype(&entity, "DOUBLE"); - // caosdb_entity_entity_get_datatype(&entity, out); - // EXPECT_EQ(strcmp(out, "DOUBLE"), 0); + caosdb_entity_entity_set_datatype(&entity, "DOUBLE", false, false); + bool is_list[] = {false}; // NOLINT + bool is_ref[] = {false}; // NOLINT + caosdb_entity_entity_get_datatype(&entity, &out, is_ref, is_list); + EXPECT_EQ(strcmp(out, "DOUBLE"), 0); + EXPECT_FALSE(*is_list); + EXPECT_FALSE(*is_ref); caosdb_entity_entity_set_unit(&entity, "m"); - caosdb_entity_entity_get_unit(&entity, out); + caosdb_entity_entity_get_unit(&entity, &out); EXPECT_EQ(strcmp(out, "m"), 0); - // TODO(fspreck) - // caosdb_entity_entity_set_value(&entity, "5.0"); - // caosdb_entity_entity_get_value(&entity, out); - // EXPECT_EQ(strcmp(out, "5.0"), 0); + return_code = caosdb_entity_entity_set_double_value(&entity, 5.0); + EXPECT_EQ(return_code, 0); + double value[] = {0.0}; // NOLINT + return_code = caosdb_entity_entity_get_double_value(&entity, value); + EXPECT_EQ(return_code, 0); + EXPECT_EQ(*value, 5.0); return_code = caosdb_entity_delete_entity(&entity); EXPECT_EQ(return_code, 0); @@ -192,11 +196,11 @@ TEST_F(test_ccaosdb, test_parent) { caosdb_entity_parent_set_id(&parent, "some_id"); caosdb_entity_parent_set_name(&parent, "some_name"); - char out[255] = {"a"}; // NOLINT - caosdb_entity_parent_get_id(&parent, out); + char *out = nullptr; // NOLINT + caosdb_entity_parent_get_id(&parent, &out); EXPECT_EQ(strcmp(out, "some_id"), 0); - caosdb_entity_parent_get_name(&parent, out); + caosdb_entity_parent_get_name(&parent, &out); EXPECT_EQ(strcmp(out, "some_name"), 0); return_code = caosdb_entity_delete_parent(&parent); @@ -211,42 +215,77 @@ TEST_F(test_ccaosdb, test_property) { caosdb_entity_property_set_id(&property, "some_id"); caosdb_entity_property_set_name(&property, "some_name"); - // TODO(fspreck) - // caosdb_entity_property_set_datatype(&property, "some_datatype"); - // TODO(fspreck) - // caosdb_entity_property_set_importance(&property, "some_importance"); + + caosdb_entity_property_set_datatype(&property, "TEXT", false, false); + caosdb_entity_property_set_importance(&property, "FIX"); caosdb_entity_property_set_unit(&property, "some_unit"); - // TODO(fspreck) - // caosdb_entity_property_set_value(&property, "some_value"); + caosdb_entity_property_set_string_value(&property, "some_value"); - char out[255] = {"a"}; // NOLINT - caosdb_entity_property_get_id(&property, out); + char *out = nullptr; // NOLINT + caosdb_entity_property_get_id(&property, &out); EXPECT_EQ(strcmp(out, "some_id"), 0); - caosdb_entity_property_get_name(&property, out); + caosdb_entity_property_get_name(&property, &out); EXPECT_EQ(strcmp(out, "some_name"), 0); - // TODO(fspreck) - // caosdb_entity_property_get_datatype(&property, out); - // EXPECT_EQ(strcmp(out, "some_datatype"), 0); + bool is_ref[] = {false}; // NOLINT + bool is_list[] = {false}; // NOLINT + caosdb_entity_property_get_datatype(&property, &out, is_ref, is_list); + EXPECT_EQ(strcmp(out, "TEXT"), 0); + EXPECT_FALSE(*is_ref); + EXPECT_FALSE(*is_list); - // TODO(fspreck) - // caosdb_entity_property_get_importance(&property, out); - // EXPECT_EQ(strcmp(out, "some_importance"), 0); + caosdb_entity_property_get_importance(&property, &out); + EXPECT_EQ(strcmp(out, "FIX"), 0); - caosdb_entity_property_get_unit(&property, out); + caosdb_entity_property_get_unit(&property, &out); EXPECT_EQ(strcmp(out, "some_unit"), 0); - // TODO(fspreck) - // caosdb_entity_property_get_value(&property, out); - // EXPECT_EQ(strcmp(out, "some_value"), 0); + caosdb_entity_property_get_string_value(&property, &out); + EXPECT_EQ(strcmp(out, "some_value"), 0); + + return_code = caosdb_entity_delete_property(&property); + EXPECT_EQ(return_code, 0); +} + +TEST_F(test_ccaosdb, test_list_property) { + + caosdb_entity_property property; + int return_code(caosdb_entity_create_property(&property)); + EXPECT_EQ(return_code, 0); + + return_code = caosdb_entity_property_set_datatype(&property, "TEXT", false, true); + EXPECT_EQ(return_code, 0); + + const char *value_list[] = {"val0", "val1", "val2"}; // NOLINT + return_code = caosdb_entity_property_set_string_list_value(&property, value_list, 3); + EXPECT_EQ(return_code, 0); + + char *out = nullptr; // NOLINT + bool is_ref[] = {false}; // NOLINT + bool is_list[] = {false}; // NOLINT + return_code = caosdb_entity_property_get_datatype(&property, &out, is_ref, is_list); + EXPECT_EQ(return_code, 0); + EXPECT_EQ(strcmp(out, "TEXT"), 0); + EXPECT_FALSE(*is_ref); + EXPECT_TRUE(*is_list); + + int length[] = {0}; // NOLINT + return_code = caosdb_entity_property_get_value_list_length(&property, length); + EXPECT_EQ(return_code, 0); + EXPECT_EQ(*length, 3); + + for (int i = 0; i < *length; i++) { + return_code = caosdb_entity_property_get_string_list_value_at(&property, &out, i); + EXPECT_EQ(return_code, 0); + EXPECT_EQ(strcmp(value_list[i], out), 0); // NOLINT + } return_code = caosdb_entity_delete_property(&property); EXPECT_EQ(return_code, 0); } TEST_F(test_ccaosdb, test_entity_with_parent_and_property) { - std::cout << "Creating objects ... " << std::endl; caosdb_entity_parent input_parent; int return_code(caosdb_entity_create_parent(&input_parent)); EXPECT_EQ(return_code, 0); @@ -260,23 +299,20 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) { caosdb_entity_property_set_id(&input_property, "property_id"); caosdb_entity_property_set_name(&input_property, "property_name"); - // TODO(fspreck) - // caosdb_entity_property_set_datatype(&input_property, "property_datatype"); - // TODO(fspreck) - // caosdb_entity_property_set_value(&input_property, "property_value"); + + caosdb_entity_property_set_datatype(&input_property, "TEXT", false, false); + caosdb_entity_property_set_string_value(&input_property, "property_value"); caosdb_entity_entity entity; return_code = caosdb_entity_create_entity(&entity); EXPECT_EQ(return_code, 0); - std::cout << "Appending parent and property ..." << std::endl; return_code = caosdb_entity_entity_append_parent(&entity, &input_parent); EXPECT_EQ(return_code, 0); return_code = caosdb_entity_entity_append_property(&entity, &input_property); EXPECT_EQ(return_code, 0); - std::cout << "Counting parents and properties ..." << std::endl; int count[] = {0}; // NOLINT return_code = caosdb_entity_entity_get_parents_size(&entity, count); EXPECT_EQ(return_code, 0); @@ -286,54 +322,51 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) { EXPECT_EQ(return_code, 0); EXPECT_EQ(*count, 1); - char in[255] = {"a"}; // NOLINT - char out[255] = {"b"}; // NOLINT + char *in = nullptr; // NOLINT + char *out = nullptr; // NOLINT - std::cout << "Comparing ..." << std::endl; // cannot assign an already assigned property return_code = caosdb_entity_entity_get_property(&entity, &input_property, 0); EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR); caosdb_entity_property output_property; return_code = caosdb_entity_entity_get_property(&entity, &output_property, 0); - std::cout << "Got output property." << std::endl; EXPECT_EQ(return_code, 0); - caosdb_entity_property_get_id(&input_property, in); - std::cout << "Got input id." << std::endl; - caosdb_entity_property_get_id(&output_property, out); - std::cout << "Got output id." << std::endl; + caosdb_entity_property_get_id(&input_property, &in); + caosdb_entity_property_get_id(&output_property, &out); EXPECT_EQ(strcmp(in, out), 0); - caosdb_entity_property_get_name(&input_property, in); - caosdb_entity_property_get_name(&output_property, out); + caosdb_entity_property_get_name(&input_property, &in); + caosdb_entity_property_get_name(&output_property, &out); EXPECT_EQ(strcmp(in, out), 0); - // TODO(fspreck) - // caosdb_entity_property_get_datatype(&input_property, in); - // caosdb_entity_property_get_datatype(&output_property, out); - // EXPECT_EQ(strcmp(in, out), 0); + bool is_list[] = {false}; // NOLINT + bool is_ref[] = {false}; // NOLINT + caosdb_entity_property_get_datatype(&input_property, &in, is_ref, is_list); + EXPECT_FALSE(*is_list); + EXPECT_FALSE(*is_ref); + caosdb_entity_property_get_datatype(&output_property, &out, is_ref, is_list); + EXPECT_FALSE(*is_list); + EXPECT_FALSE(*is_ref); + EXPECT_EQ(strcmp(in, out), 0); - // TODO(fspreck) - // caosdb_entity_property_get_value(&input_property, in); - // caosdb_entity_property_get_value(&output_property, out); - // EXPECT_EQ(strcmp(in, out), 0); + caosdb_entity_property_get_string_value(&input_property, &in); + caosdb_entity_property_get_string_value(&output_property, &out); + EXPECT_EQ(strcmp(in, out), 0); - std::cout << "Comparing parent..." << std::endl; caosdb_entity_parent output_parent; return_code = caosdb_entity_entity_get_parent(&entity, &output_parent, 0); - std::cout << "Got output parent." << std::endl; EXPECT_EQ(return_code, 0); - caosdb_entity_parent_get_id(&input_parent, in); - caosdb_entity_parent_get_id(&output_parent, out); + caosdb_entity_parent_get_id(&input_parent, &in); + caosdb_entity_parent_get_id(&output_parent, &out); EXPECT_EQ(strcmp(in, out), 0); - caosdb_entity_parent_get_name(&input_parent, in); - caosdb_entity_parent_get_name(&output_parent, out); + caosdb_entity_parent_get_name(&input_parent, &in); + caosdb_entity_parent_get_name(&output_parent, &out); EXPECT_EQ(strcmp(in, out), 0); // Delete everything - std::cout << "Deleting ..." << std::endl; return_code = caosdb_entity_delete_parent(&input_parent); EXPECT_EQ(return_code, 0); return_code = caosdb_entity_delete_property(&input_property); @@ -393,13 +426,13 @@ TEST_F(test_ccaosdb, test_remove_property) { return_code = caosdb_entity_entity_get_property(&entity, &out_prop, 0); EXPECT_EQ(return_code, 0); - char in[255] = {"a"}; // NOLINT - char out[255] = {"b"}; // NOLINT + char *in = nullptr; // NOLINT + char *out = nullptr; // NOLINT // Deleted the first property, so the second one should remain. - return_code = caosdb_entity_property_get_name(&in_prop_2, in); + return_code = caosdb_entity_property_get_name(&in_prop_2, &in); EXPECT_EQ(return_code, 0); - return_code = caosdb_entity_property_get_name(&out_prop, out); + return_code = caosdb_entity_property_get_name(&out_prop, &out); EXPECT_EQ(return_code, 0); EXPECT_EQ(strcmp(in, out), 0);