diff --git a/include/caosdb/entity.h b/include/caosdb/entity.h index 6b96c907f1e24eae4894bc652173ffc8e52ee387..de6d4928771af83edca68d748d73b58f690a35f7 100644 --- a/include/caosdb/entity.h +++ b/include/caosdb/entity.h @@ -515,7 +515,7 @@ public: * Set the value of this property. */ auto SetValue(const Value &value) -> StatusCode; - // auto SetValue(const AbstractValue &value) -> StatusCode; + auto SetValue(const AbstractValue &value) -> StatusCode; auto SetValue(const std::string &value) -> StatusCode; auto SetValue(const char *value) -> StatusCode; auto SetValue(const double value) -> StatusCode; @@ -688,7 +688,7 @@ public: */ auto SetDescription(const std::string &description) -> void; - // auto SetValue(const AbstractValue &value) -> StatusCode; + auto SetValue(const AbstractValue &value) -> StatusCode; auto SetValue(const Value &value) -> StatusCode; auto SetValue(const std::string &value) -> StatusCode; auto SetValue(const char *value) -> StatusCode; diff --git a/include/caosdb/value.h b/include/caosdb/value.h index f6de040dcf02fb1600f170f2e18817ed4e2db883..b7da9903eece341955bb1d9a93e3e89d72f866eb 100644 --- a/include/caosdb/value.h +++ b/include/caosdb/value.h @@ -158,6 +158,7 @@ public: * The return value is undefined if IsVector is false. */ [[nodiscard]] virtual auto GetAsVector() const noexcept -> const std::vector<ScalarValue> & = 0; + [[nodiscard]] virtual auto ToString() const noexcept -> const std::string = 0; friend class Value; protected: @@ -246,6 +247,11 @@ public: static const std::vector<ScalarValue> empty_collection; return empty_collection; } + inline auto ToString() const noexcept -> const std::string { + CAOSDB_DEBUG_MESSAGE_STRING(*wrapped, out) + return out; + } + friend class Value; protected: @@ -282,7 +288,9 @@ public: explicit inline Value(const ScalarValue &value) : Value() { this->wrapped->mutable_scalar_value()->CopyFrom(*value.wrapped); } - explicit inline Value(const AbstractValue &value) : Value(value.GetProtoValue()) {} + explicit inline Value(const AbstractValue &value) : Value() { + this->wrapped->CopyFrom(*value.GetProtoValue()); + } explicit inline Value(ProtoValue *wrapped) : ProtoMessageWrapper<ProtoValue>(wrapped) {} explicit inline Value(const std::string &value) : ProtoMessageWrapper<ProtoValue>() { this->wrapped->mutable_scalar_value()->set_string_value(value); diff --git a/include/ccaosdb.h b/include/ccaosdb.h index 61b86817532b77ccfd24ccb791b18cc31afc6faa..b9296349b6f9592bed9e60362ae4848faf95a649 100644 --- a/include/ccaosdb.h +++ b/include/ccaosdb.h @@ -264,8 +264,6 @@ int caosdb_connection_connection_manager_get_connection(caosdb_connection_connec * ENTITY STUFF AND TRANSACTIONS ****************************************************************************/ -// TODO(fspreck) implementations needed, and probably these declarations are -// not sufficient yet. typedef struct caosdb_transaction_transaction { void *wrapped_transaction; bool _deletable = false; @@ -379,10 +377,8 @@ 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_local_path(caosdb_entity_entity *entity, char **out); -// TODO(fspreck) implementation int caosdb_entity_entity_get_datatype(caosdb_entity_entity *entity, caosdb_entity_datatype *out); int caosdb_entity_entity_get_unit(caosdb_entity_entity *entity, char **out); -// TODO(fspreck) implementation int caosdb_entity_entity_get_value(caosdb_entity_entity *entity, caosdb_entity_value *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); @@ -405,11 +401,9 @@ 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); -// TODO(fspreck) implementation int caosdb_entity_property_get_datatype(caosdb_entity_property *property, caosdb_entity_datatype *out); int caosdb_entity_property_get_unit(caosdb_entity_property *property, char **out); -// TODO(fspreck) implementation int caosdb_entity_property_get_value(caosdb_entity_property *property, caosdb_entity_value *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); @@ -418,7 +412,12 @@ int caosdb_entity_parent_get_description(caosdb_entity_parent *parent, char **ou int caosdb_entity_message_get_code(caosdb_entity_message *message, int *out); int caosdb_entity_message_get_description(caosdb_entity_message *message, char **out); -// TODO(fspreck) getters for value and datatypes +int caosdb_entity_datatype_is_atomic(caosdb_entity_datatype *datatype, bool *out); +int caosdb_entity_datatype_is_reference(caosdb_entity_datatype *datatype, bool *out); +int caosdb_entity_datatype_is_list_of_atomic(caosdb_entity_datatype *datatype, bool *out); +int caosdb_entity_datatype_is_list_of_reference(caosdb_entity_datatype *datatype, bool *out); +int caosdb_entity_datatype_get_datatype_name(caosdb_entity_datatype *datatype, char **out); + int caosdb_entity_value_is_null(caosdb_entity_value *value, bool *out); int caosdb_entity_value_is_string(caosdb_entity_value *value, bool *out); int caosdb_entity_value_is_double(caosdb_entity_value *value, bool *out); @@ -440,9 +439,14 @@ int caosdb_entity_create_property(caosdb_entity_property *out); int caosdb_entity_delete_property(caosdb_entity_property *out); int caosdb_entity_create_parent(caosdb_entity_parent *out); int caosdb_entity_delete_parent(caosdb_entity_parent *out); -// TODO(fspreck) implementations, also list_datatypes, list_values... -int caosdb_entity_create_datatype(caosdb_entity_datatype *out); + +// DATATYPE CONSTRUCTORS for atomic and reference datatypes and lists thereof +int caosdb_entity_create_atomic_datatype(caosdb_entity_datatype *out, const char *name); +int caosdb_entity_create_reference_datatype(caosdb_entity_datatype *out, const char *name); +int caosdb_entity_create_atomic_list_datatype(caosdb_entity_datatype *out, const char *name); +int caosdb_entity_create_reference_list_datatype(caosdb_entity_datatype *out, const char *name); int caosdb_entity_delete_datatype(caosdb_entity_datatype *out); + // VALUE CONSTRUCTORS (resolve overloaded constructors) int caosdb_entity_create_int_value(caosdb_entity_value *out, const int64_t value); int caosdb_entity_create_string_value(caosdb_entity_value *out, const char *value); @@ -464,11 +468,9 @@ 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_local_path(caosdb_entity_entity *entity, const char *name); int caosdb_entity_entity_set_file_path(caosdb_entity_entity *entity, const char *name); -// TODO(fspreck) implementation int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity, caosdb_entity_datatype *datatype); int caosdb_entity_entity_set_unit(caosdb_entity_entity *entity, const char *unit); -// TODO(fspreck) implementation int caosdb_entity_entity_set_value(caosdb_entity_entity *entity, caosdb_entity_value *value); int caosdb_entity_entity_append_parent(caosdb_entity_entity *entity, caosdb_entity_parent *parent); @@ -479,20 +481,15 @@ 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); -// TODO(fspreck) implementation int caosdb_entity_property_set_datatype(caosdb_entity_property *property, caosdb_entity_datatype *datatype); 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); - -// TODO(fspreck) implementation int caosdb_entity_property_set_value(caosdb_entity_property *property, caosdb_entity_value *value); 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); -// TODO(fspreck) setters for datatype - #ifdef __cplusplus } #endif diff --git a/src/caosdb/entity.cpp b/src/caosdb/entity.cpp index 8f737602bbda62bbae8e8dcf8f287e95fd82aa09..c409a46e8ad37aee93b67b2a36109b1fe8f8c640 100644 --- a/src/caosdb/entity.cpp +++ b/src/caosdb/entity.cpp @@ -108,8 +108,7 @@ auto Property::SetImportance(Importance importance) -> void { auto Property::SetValue(const Value &value) -> StatusCode { return this->value.CopyFrom(value); } -// auto Property::SetValue(const AbstractValue &value) -> StatusCode { return -// SetValue(Value(value)); } +auto Property::SetValue(const AbstractValue &value) -> StatusCode { return SetValue(Value(value)); } auto Property::SetValue(const std::string &value) -> StatusCode { return SetValue(Value(value)); } @@ -205,8 +204,7 @@ auto Entity::SetValue(const Value &value) -> StatusCode { return this->value.CopyFrom(value); } -// auto Entity::SetValue(const AbstractValue &value) -> StatusCode { return SetValue(Value(value)); -// } +auto Entity::SetValue(const AbstractValue &value) -> StatusCode { return SetValue(Value(value)); } auto Entity::SetValue(const std::string &value) -> StatusCode { return SetValue(Value(value)); } diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp index 8a7ae4131f513d257e3c0c1b69f975fde595f9dc..a18c56d90a2b72449ef7fcb60c0dd3e79603dafc 100644 --- a/src/ccaosdb.cpp +++ b/src/ccaosdb.cpp @@ -48,6 +48,8 @@ extern "C" { #define WRAPPED_MESSAGE_CAST(name) static_cast<caosdb::entity::Message *>(name->wrapped_message) +#define WRAPPED_DATATYPE_CAST(name) static_cast<caosdb::entity::DataType *>(name->wrapped_datatype) + #define WRAPPED_VALUE_CAST(name) static_cast<caosdb::entity::AbstractValue *>(name->wrapped_value) #define ENUM_NAME_FROM_VALUE(arg, etype) \ @@ -56,6 +58,11 @@ extern "C" { #define ENUM_VALUE_FROM_NAME(arg, etype) \ caosdb::utility::getEnumValueFromName<caosdb::entity::etype>(arg) +#define RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(name) \ + if (name->_deletable) { \ + return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; \ + } + /* * Macro for wrapping every function into a try-catch clause. If an exception * occurs, the given StatusCode is being returned. @@ -156,9 +163,7 @@ extern "C" { #define CREATE_VALUE(fname, arg) \ ERROR_RETURN_CODE(GENERIC_ERROR, \ int caosdb_entity_create_##fname(caosdb_entity_value *out, arg), { \ - if (out->_deletable) { \ - return caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR; \ - } \ + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) \ out->wrapped_value = new caosdb::entity::Value(value); \ out->_deletable = true; \ return 0; \ @@ -683,6 +688,65 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_parent(caosdb_entity_p return 0; }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_create_atomic_datatype(caosdb_entity_datatype *out, + const char *name), + { + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) + try { + auto enum_value = ENUM_VALUE_FROM_NAME(std::string(name), AtomicDataType); + out->wrapped_datatype = new caosdb::entity::DataType(enum_value); + out->_deletable = true; + 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_create_reference_datatype(caosdb_entity_datatype *out, + const char *name), + { + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) + out->wrapped_datatype = new caosdb::entity::DataType(std::string(name)); + out->_deletable = true; + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_create_atomic_list_datatype(caosdb_entity_datatype *out, + const char *name), + { + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) + try { + auto enum_value = ENUM_VALUE_FROM_NAME(std::string(name), AtomicDataType); + out->wrapped_datatype = + new caosdb::entity::DataType(caosdb::entity::DataType::ListOf(enum_value)); + out->_deletable = true; + 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_create_reference_list_datatype(caosdb_entity_datatype *out, + const char *name), + { + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) + out->wrapped_datatype = new caosdb::entity::DataType( + caosdb::entity::DataType::ListOf(std::string(name))); + out->_deletable = true; + return 0; + }) + +ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_datatype(caosdb_entity_datatype *out), { + if (out->_deletable) { + delete WRAPPED_DATATYPE_CAST(out); + } + out->_deletable = false; + return 0; +}) + CREATE_VALUE(int_value, const int64_t value) CREATE_VALUE(string_value, const char *value) CREATE_VALUE(double_value, const double value) @@ -725,41 +789,26 @@ ERROR_RETURN_CODE(GENERIC_ERROR, }) // CAOSDB_ENTITY_GET(file_path, GetFilePath()) TODO(henrik) CAOSDB_ENTITY_GET(description, GetDescription()) -// TODO(fspreck) -// 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_datatype(caosdb_entity_entity *entity, + caosdb_entity_datatype *out), + { + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + out->wrapped_datatype = (void *)(&(wrapped_entity->GetDataType())); + out->_deletable = false; + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_get_value(caosdb_entity_entity *entity, + caosdb_entity_value *out), + { + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + out->wrapped_value = (void *)(&(wrapped_entity->GetValue())); + out->_deletable = false; + return 0; + }) CAOSDB_ENTITY_GET(unit, GetUnit()) CAOSDB_ENTITY_GET(version_id, GetVersionId()) @@ -901,43 +950,26 @@ ERROR_RETURN_CODE(GENERIC_ERROR, *out = tmp; return 0; }) - -// TODO(fspreck) -// ERROR_RETURN_CODE(GENERIC_ERROR, -// 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; -// }) - +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_datatype(caosdb_entity_property *property, + caosdb_entity_datatype *out), + { + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + out->wrapped_datatype = (void *)(&(wrapped_property->GetDataType())); + out->_deletable = false; + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_get_value(caosdb_entity_property *property, + caosdb_entity_value *out), + { + RETURN_ASSIGNEMENT_ERROR_IF_DELETABLE(out) + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + out->wrapped_value = (void *)(&(wrapped_property->GetValue())); + out->_deletable = false; + return 0; + }) CAOSDB_PROPERTY_GET(unit, GetUnit()) ERROR_RETURN_CODE(GENERIC_ERROR, @@ -959,6 +991,73 @@ ERROR_RETURN_CODE( return 0; }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_datatype_is_atomic(caosdb_entity_datatype *datatype, bool *out), + { + auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype); + *out = wrapped_datatype->IsAtomic(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_datatype_is_reference(caosdb_entity_datatype *datatype, + bool *out), + { + auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype); + *out = wrapped_datatype->IsReference(); + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_datatype_is_list_of_atomic(caosdb_entity_datatype *datatype, + bool *out), + { + auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype); + if (wrapped_datatype->IsList()) { + const auto &list_datatype = wrapped_datatype->GetAsList(); + *out = list_datatype.IsListOfAtomic(); + } else { + *out = false; + } + return 0; + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_datatype_is_list_of_reference(caosdb_entity_datatype *datatype, + bool *out), + { + auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype); + if (wrapped_datatype->IsList()) { + const auto &list_datatype = wrapped_datatype->GetAsList(); + *out = list_datatype.IsListOfReference(); + } else { + *out = false; + } + return 0; + }) +ERROR_RETURN_CODE( + GENERIC_ERROR, + int caosdb_entity_datatype_get_datatype_name(caosdb_entity_datatype *datatype, char **out), { + auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype); + std::string datatype_name; + if (wrapped_datatype->IsList()) { + const auto &list_datatype = wrapped_datatype->GetAsList(); + if (list_datatype.IsListOfAtomic()) { + datatype_name = ENUM_NAME_FROM_VALUE(list_datatype.GetAtomicDataType(), AtomicDataType); + } else { + datatype_name = list_datatype.GetReferenceDataType().GetName(); + } + } else { + if (wrapped_datatype->IsAtomic()) { + datatype_name = ENUM_NAME_FROM_VALUE(wrapped_datatype->GetAsAtomic(), AtomicDataType); + } else { + datatype_name = wrapped_datatype->GetAsReference().GetName(); + } + } + char *tmp = (char *)malloc(sizeof(char) * datatype_name.length() + 1); + strcpy(tmp, datatype_name.c_str()); + delete[] * out; + *out = tmp; + return 0; + }) + VALUE_IS(null, IsNull) VALUE_IS(string, IsString) VALUE_IS(double, IsDouble) @@ -1012,31 +1111,25 @@ CAOSDB_ENTITY_SET(local_path, local_path, CAOSDB_ENTITY_SET(file_path, file_path, wrapped_entity->SetFilePath(std::string(file_path));) CAOSDB_ENTITY_SET(description, description, wrapped_entity->SetDescription(std::string(description));) -// TODO(fspreck) -// 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));) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_datatype(caosdb_entity_entity *entity, + caosdb_entity_datatype *datatype), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype); + + return wrapped_entity->SetDataType(*wrapped_datatype); + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_entity_set_value(caosdb_entity_entity *entity, + caosdb_entity_value *value), + { + auto *wrapped_entity = WRAPPED_ENTITY_CAST(entity); + auto *wrapped_value = WRAPPED_VALUE_CAST(value); + + return wrapped_entity->SetValue(*wrapped_value); + }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_entity_append_parent(caosdb_entity_entity *entity, @@ -1083,31 +1176,24 @@ 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));) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_datatype(caosdb_entity_property *property, + caosdb_entity_datatype *datatype), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + auto *wrapped_datatype = WRAPPED_DATATYPE_CAST(datatype); -// TODO(fspreck) -// 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; -// } -// } -// }) + return wrapped_property->SetDataType(*wrapped_datatype); + }) +ERROR_RETURN_CODE(GENERIC_ERROR, + int caosdb_entity_property_set_value(caosdb_entity_property *property, + caosdb_entity_value *value), + { + auto *wrapped_property = WRAPPED_PROPERTY_CAST(property); + auto *wrapped_value = WRAPPED_VALUE_CAST(value); + + return wrapped_property->SetValue(*wrapped_value); + }) ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_property_set_importance(caosdb_entity_property *property, diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp index 4322c135db0024ca90aca52ed783523ba88dc104..361b0918060e46cf71b435e519b3a7ec20b1ee46 100644 --- a/test/test_ccaosdb.cpp +++ b/test/test_ccaosdb.cpp @@ -127,6 +127,108 @@ TEST_F(test_ccaosdb, test_query) { EXPECT_EQ(return_code, 0); } +TEST_F(test_ccaosdb, test_datatype) { + + caosdb_entity_datatype atomic; + // check that this fails + int return_code(caosdb_entity_create_atomic_datatype(&atomic, "some type")); + EXPECT_EQ(return_code, caosdb::StatusCode::ENUM_MAPPING_ERROR); + + return_code = caosdb_entity_create_atomic_datatype(&atomic, "INTEGER"); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype reference; + return_code = caosdb_entity_create_reference_datatype(&reference, "MyType"); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype list_of_atomics; + return_code = caosdb_entity_create_atomic_list_datatype(&list_of_atomics, "DATETIME"); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype list_of_references; + return_code = caosdb_entity_create_reference_list_datatype(&list_of_references, "MyType"); + EXPECT_EQ(return_code, 0); + + bool is_a(false); + return_code = caosdb_entity_datatype_is_atomic(&atomic, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_TRUE(is_a); + return_code = caosdb_entity_datatype_is_reference(&atomic, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_atomic(&atomic, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_reference(&atomic, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + + return_code = caosdb_entity_datatype_is_atomic(&reference, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_reference(&reference, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_TRUE(is_a); + return_code = caosdb_entity_datatype_is_list_of_atomic(&reference, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_reference(&reference, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + + return_code = caosdb_entity_datatype_is_atomic(&list_of_atomics, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_reference(&list_of_atomics, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_atomic(&list_of_atomics, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_TRUE(is_a); + return_code = caosdb_entity_datatype_is_list_of_reference(&list_of_atomics, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + + return_code = caosdb_entity_datatype_is_atomic(&list_of_references, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_reference(&list_of_references, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_atomic(&list_of_references, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_reference(&list_of_references, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_TRUE(is_a); + + char *name = nullptr; // NOLINT + return_code = caosdb_entity_datatype_get_datatype_name(&atomic, &name); + EXPECT_EQ(return_code, 0); + EXPECT_STREQ(name, "INTEGER"); + + return_code = caosdb_entity_datatype_get_datatype_name(&reference, &name); + EXPECT_EQ(return_code, 0); + EXPECT_STREQ(name, "MyType"); + + return_code = caosdb_entity_datatype_get_datatype_name(&list_of_atomics, &name); + EXPECT_EQ(return_code, 0); + EXPECT_STREQ(name, "DATETIME"); + + return_code = caosdb_entity_datatype_get_datatype_name(&list_of_references, &name); + EXPECT_EQ(return_code, 0); + EXPECT_STREQ(name, "MyType"); + + return_code = caosdb_entity_delete_datatype(&atomic); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_datatype(&reference); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_datatype(&list_of_atomics); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_datatype(&list_of_references); + EXPECT_EQ(return_code, 0); +} + TEST_F(test_ccaosdb, test_value) { caosdb_entity_value string_value; @@ -207,7 +309,6 @@ TEST_F(test_ccaosdb, test_value) { caosdb_entity_value_is_vector(&bool_vector_value, &is_a); EXPECT_TRUE(is_a); - // TODO(fspreck) Test as... functions char *out_string = nullptr; // NOLINT return_code = caosdb_entity_value_get_as_string(&string_value, &out_string); EXPECT_EQ(return_code, 0); @@ -322,35 +423,95 @@ TEST_F(test_ccaosdb, test_entity) { 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", 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_datatype(&entity, "Person", true, true); - // caosdb_entity_entity_get_datatype(&entity, &out, is_ref, is_list); - // EXPECT_EQ(strcmp(out, "Person"), 0); - // EXPECT_TRUE(*is_list); - // EXPECT_TRUE(*is_ref); + caosdb_entity_datatype in_type; + caosdb_entity_create_atomic_datatype(&in_type, "DOUBLE"); + caosdb_entity_entity_set_datatype(&entity, &in_type); + + // verify that this doesn't work ... + return_code = caosdb_entity_entity_get_datatype(&entity, &in_type); + EXPECT_EQ(return_code, caosdb::StatusCode::EXTERN_C_ASSIGNMENT_ERROR); + caosdb_entity_datatype out_type; + // ... but does with a clean property + return_code = caosdb_entity_entity_get_datatype(&entity, &out_type); + EXPECT_EQ(return_code, 0); + bool is_a(false); + return_code = caosdb_entity_datatype_is_atomic(&out_type, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_TRUE(is_a); + return_code = caosdb_entity_datatype_is_reference(&out_type, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_atomic(&out_type, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_reference(&out_type, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + + caosdb_entity_datatype_get_datatype_name(&out_type, &out); + EXPECT_STREQ(out, "DOUBLE"); + + caosdb_entity_value in_value; + return_code = caosdb_entity_create_double_value(&in_value, 5.0); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_entity_set_value(&entity, &in_value); + EXPECT_EQ(return_code, 0); + + caosdb_entity_value out_value; + return_code = caosdb_entity_entity_get_value(&entity, &out_value); + EXPECT_EQ(return_code, 0); + + caosdb_entity_value_is_double(&out_value, &is_a); + EXPECT_TRUE(is_a); + caosdb_entity_value_is_null(&out_value, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_value_is_string(&out_value, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_value_is_bool(&out_value, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_value_is_integer(&out_value, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_value_is_vector(&out_value, &is_a); + EXPECT_FALSE(is_a); + + double out_double(0); + caosdb_entity_value_get_as_double(&out_value, &out_double); + EXPECT_EQ(out_double, 5.0); + + // clear to re-use + return_code = caosdb_entity_delete_datatype(&in_type); + EXPECT_EQ(return_code, 0); + caosdb_entity_create_reference_list_datatype(&in_type, "Person"); + caosdb_entity_entity_set_datatype(&entity, &in_type); + + // works without clearing since datatype is managed by the owning entity + caosdb_entity_entity_get_datatype(&entity, &out_type); + return_code = caosdb_entity_datatype_is_atomic(&out_type, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_reference(&out_type, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_atomic(&out_type, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_FALSE(is_a); + return_code = caosdb_entity_datatype_is_list_of_reference(&out_type, &is_a); + EXPECT_EQ(return_code, 0); + EXPECT_TRUE(is_a); + + caosdb_entity_datatype_get_datatype_name(&out_type, &out); + EXPECT_STREQ(out, "Person"); caosdb_entity_entity_set_unit(&entity, "m"); caosdb_entity_entity_get_unit(&entity, &out); EXPECT_EQ(strcmp(out, "m"), 0); - // TODO(fspreck) - // 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); + return_code = caosdb_entity_delete_datatype(&in_type); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_value(&in_value); + EXPECT_EQ(return_code, 0); } TEST_F(test_ccaosdb, test_parent) { @@ -382,12 +543,14 @@ 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, "TEXT", false, false); + caosdb_entity_datatype in_type; + caosdb_entity_create_atomic_datatype(&in_type, "TEXT"); + caosdb_entity_property_set_datatype(&property, &in_type); caosdb_entity_property_set_importance(&property, "FIX"); caosdb_entity_property_set_unit(&property, "some_unit"); - // TODO(fspreck) - // caosdb_entity_property_set_string_value(&property, "some_value"); + caosdb_entity_value in_value; + caosdb_entity_create_string_value(&in_value, "some_value"); + caosdb_entity_property_set_value(&property, &in_value); char *out = nullptr; // NOLINT caosdb_entity_property_get_id(&property, &out); @@ -396,13 +559,22 @@ TEST_F(test_ccaosdb, test_property) { caosdb_entity_property_get_name(&property, &out); EXPECT_EQ(strcmp(out, "some_name"), 0); - // TODO(fspreck) - // 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); + caosdb_entity_datatype out_type; + return_code = caosdb_entity_property_get_datatype(&property, &out_type); + EXPECT_EQ(return_code, 0); + bool is_a(false); + + caosdb_entity_datatype_is_atomic(&out_type, &is_a); + EXPECT_TRUE(is_a); + caosdb_entity_datatype_is_reference(&out_type, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_datatype_is_list_of_atomic(&out_type, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_datatype_is_list_of_reference(&out_type, &is_a); + EXPECT_FALSE(is_a); + + caosdb_entity_datatype_get_datatype_name(&out_type, &out); + EXPECT_STREQ(out, "TEXT"); caosdb_entity_property_get_importance(&property, &out); EXPECT_EQ(strcmp(out, "FIX"), 0); @@ -410,127 +582,202 @@ TEST_F(test_ccaosdb, test_property) { caosdb_entity_property_get_unit(&property, &out); EXPECT_EQ(strcmp(out, "some_unit"), 0); - // TODO(fspreck) - // caosdb_entity_property_get_string_value(&property, &out); - // EXPECT_EQ(strcmp(out, "some_value"), 0); + caosdb_entity_value out_value; + return_code = caosdb_entity_property_get_value(&property, &out_value); + EXPECT_EQ(return_code, 0); + caosdb_entity_value_is_string(&out_value, &is_a); + EXPECT_TRUE(is_a); + caosdb_entity_value_get_as_string(&out_value, &out); + EXPECT_STREQ(out, "some_value"); return_code = caosdb_entity_delete_property(&property); EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_datatype(&in_type); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_value(&in_value); + EXPECT_EQ(return_code, 0); } -// TODO(fspreck) -// TEST_F(test_ccaosdb, test_string_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 = -1; // 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_int_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, "INTEGER", false, true); -// EXPECT_EQ(return_code, 0); - -// const int64_t value_list[] = {1, 2, 3}; // NOLINT -// return_code = caosdb_entity_property_set_int_list_value(&property, &(value_list)[0], 3); -// EXPECT_EQ(return_code, 0); - -// char *dt_out = nullptr; // NOLINT -// bool is_ref[] = {false}; // NOLINT -// bool is_list[] = {false}; // NOLINT -// return_code = caosdb_entity_property_get_datatype(&property, &dt_out, is_ref, is_list); -// EXPECT_EQ(return_code, 0); -// EXPECT_STREQ(dt_out, "INTEGER"); -// EXPECT_FALSE(*is_ref); -// EXPECT_TRUE(*is_list); - -// int length = -1; // 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++) { -// int64_t out = -1; -// return_code = caosdb_entity_property_get_int_list_value_at(&property, &out, i); -// EXPECT_EQ(return_code, 0); -// EXPECT_EQ(value_list[i], out); // NOLINT -// } - -// return_code = caosdb_entity_delete_property(&property); -// EXPECT_EQ(return_code, 0); -// } - -// TEST_F(test_ccaosdb, test_bool_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, "BOOLEAN", false, true); -// EXPECT_EQ(return_code, 0); - -// const bool value_list[] = {true, true, false}; // NOLINT -// return_code = caosdb_entity_property_set_boolean_list_value(&property, &(value_list)[0], 3); -// EXPECT_EQ(return_code, 0); - -// char *dt_out = nullptr; // NOLINT -// bool is_ref[] = {false}; // NOLINT -// bool is_list[] = {false}; // NOLINT -// return_code = caosdb_entity_property_get_datatype(&property, &dt_out, is_ref, is_list); -// EXPECT_EQ(return_code, 0); -// EXPECT_STREQ(dt_out, "BOOLEAN"); -// EXPECT_FALSE(*is_ref); -// EXPECT_TRUE(*is_list); - -// int length = -1; // 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++) { -// bool out = true; -// return_code = caosdb_entity_property_get_boolean_list_value_at(&property, &out, i); -// EXPECT_EQ(return_code, 0); -// EXPECT_EQ(value_list[i], out); // NOLINT -// } - -// return_code = caosdb_entity_delete_property(&property); -// EXPECT_EQ(return_code, 0); -// } +TEST_F(test_ccaosdb, test_string_list_property) { + + caosdb_entity_property property; + int return_code(caosdb_entity_create_property(&property)); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype in_type; + return_code = caosdb_entity_create_atomic_list_datatype(&in_type, "TEXT"); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_property_set_datatype(&property, &in_type); + EXPECT_EQ(return_code, 0); + + caosdb_entity_value in_value; + const char *value_list[] = {"val0", "val1", "val2"}; // NOLINT + return_code = caosdb_entity_create_string_vector_value(&in_value, value_list, 3); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_property_set_value(&property, &in_value); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype out_type; + return_code = caosdb_entity_property_get_datatype(&property, &out_type); + EXPECT_EQ(return_code, 0); + + bool is_a(false); + caosdb_entity_datatype_is_atomic(&out_type, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_datatype_is_reference(&out_type, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_datatype_is_list_of_atomic(&out_type, &is_a); + EXPECT_TRUE(is_a); + caosdb_entity_datatype_is_list_of_reference(&out_type, &is_a); + EXPECT_FALSE(is_a); + char *out = nullptr; // NOLINT + caosdb_entity_datatype_get_datatype_name(&out_type, &out); + EXPECT_STREQ(out, "TEXT"); + + caosdb_entity_value out_value; + caosdb_entity_property_get_value(&property, &out_value); + caosdb_entity_value_is_vector(&out_value, &is_a); + EXPECT_TRUE(is_a); + int length(-1); + caosdb_entity_value_get_as_vector_size(&out_value, &length); + EXPECT_EQ(length, 3); + + caosdb_entity_value list_elt; + for (int i = 0; i < length; i++) { + return_code = caosdb_entity_value_get_as_vector_at(&out_value, &list_elt, i); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_value_get_as_string(&list_elt, &out); + EXPECT_EQ(return_code, 0); + EXPECT_STREQ(value_list[i], out); // NOLINT + } + + return_code = caosdb_entity_delete_property(&property); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_datatype(&in_type); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_value(&in_value); + EXPECT_EQ(return_code, 0); +} + +TEST_F(test_ccaosdb, test_int_list_property) { + + caosdb_entity_property property; + int return_code(caosdb_entity_create_property(&property)); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype in_type; + caosdb_entity_create_atomic_list_datatype(&in_type, "INTEGER"); + return_code = caosdb_entity_property_set_datatype(&property, &in_type); + EXPECT_EQ(return_code, 0); + + const int64_t value_list[] = {1, 2, 3}; // NOLINT + caosdb_entity_value in_value; + caosdb_entity_create_int_vector_value(&in_value, value_list, 3); + return_code = caosdb_entity_property_set_value(&property, &in_value); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype out_type; + return_code = caosdb_entity_property_get_datatype(&property, &out_type); + EXPECT_EQ(return_code, 0); + + bool is_a(false); + caosdb_entity_datatype_is_atomic(&out_type, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_datatype_is_reference(&out_type, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_datatype_is_list_of_atomic(&out_type, &is_a); + EXPECT_TRUE(is_a); + caosdb_entity_datatype_is_list_of_reference(&out_type, &is_a); + EXPECT_FALSE(is_a); + char *out = nullptr; // NOLINT + caosdb_entity_datatype_get_datatype_name(&out_type, &out); + EXPECT_STREQ(out, "INTEGER"); + + caosdb_entity_value out_value; + caosdb_entity_property_get_value(&property, &out_value); + caosdb_entity_value_is_vector(&out_value, &is_a); + EXPECT_TRUE(is_a); + int length(-1); + caosdb_entity_value_get_as_vector_size(&out_value, &length); + EXPECT_EQ(length, 3); + + int64_t out_int = -1; + caosdb_entity_value list_elt; + for (int i = 0; i < length; i++) { + return_code = caosdb_entity_value_get_as_vector_at(&out_value, &list_elt, i); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_value_get_as_integer(&list_elt, &out_int); + EXPECT_EQ(return_code, 0); + EXPECT_EQ(value_list[i], out_int); // NOLINT + } + + return_code = caosdb_entity_delete_property(&property); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_datatype(&in_type); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_value(&in_value); + EXPECT_EQ(return_code, 0); +} + +TEST_F(test_ccaosdb, test_bool_list_property) { + + caosdb_entity_property property; + int return_code(caosdb_entity_create_property(&property)); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype in_type; + caosdb_entity_create_atomic_list_datatype(&in_type, "BOOLEAN"); + return_code = caosdb_entity_property_set_datatype(&property, &in_type); + EXPECT_EQ(return_code, 0); + + const bool value_list[] = {true, true, false}; // NOLINT + caosdb_entity_value in_value; + caosdb_entity_create_bool_vector_value(&in_value, value_list, 3); + return_code = caosdb_entity_property_set_value(&property, &in_value); + EXPECT_EQ(return_code, 0); + + caosdb_entity_datatype out_type; + return_code = caosdb_entity_property_get_datatype(&property, &out_type); + EXPECT_EQ(return_code, 0); + + bool is_a(false); + caosdb_entity_datatype_is_atomic(&out_type, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_datatype_is_reference(&out_type, &is_a); + EXPECT_FALSE(is_a); + caosdb_entity_datatype_is_list_of_atomic(&out_type, &is_a); + EXPECT_TRUE(is_a); + caosdb_entity_datatype_is_list_of_reference(&out_type, &is_a); + EXPECT_FALSE(is_a); + char *out = nullptr; // NOLINT + caosdb_entity_datatype_get_datatype_name(&out_type, &out); + EXPECT_STREQ(out, "BOOLEAN"); + + caosdb_entity_value out_value; + caosdb_entity_property_get_value(&property, &out_value); + caosdb_entity_value_is_vector(&out_value, &is_a); + EXPECT_TRUE(is_a); + int length(-1); + caosdb_entity_value_get_as_vector_size(&out_value, &length); + EXPECT_EQ(length, 3); + + bool out_bool(false); + caosdb_entity_value list_elt; + for (int i = 0; i < length; i++) { + return_code = caosdb_entity_value_get_as_vector_at(&out_value, &list_elt, i); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_value_get_as_bool(&list_elt, &out_bool); + EXPECT_EQ(return_code, 0); + EXPECT_EQ(value_list[i], out_bool); // NOLINT + } + + return_code = caosdb_entity_delete_property(&property); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_datatype(&in_type); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_value(&in_value); + EXPECT_EQ(return_code, 0); +} TEST_F(test_ccaosdb, test_entity_with_parent_and_property) { caosdb_entity_parent input_parent; @@ -547,9 +794,12 @@ 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, "TEXT", false, false); - // caosdb_entity_property_set_string_value(&input_property, "property_value"); + caosdb_entity_datatype in_type; + caosdb_entity_create_atomic_datatype(&in_type, "TEXT"); + caosdb_entity_value in_value; + caosdb_entity_create_string_value(&in_value, "property_value"); + caosdb_entity_property_set_datatype(&input_property, &in_type); + caosdb_entity_property_set_value(&input_property, &in_value); caosdb_entity_entity entity; return_code = caosdb_entity_create_entity(&entity); @@ -588,21 +838,37 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) { caosdb_entity_property_get_name(&output_property, &out); EXPECT_EQ(strcmp(in, out), 0); - // TODO(fspreck) - // 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_string_value(&input_property, &in); - // caosdb_entity_property_get_string_value(&output_property, &out); - // EXPECT_EQ(strcmp(in, out), 0); + caosdb_entity_datatype out_type; + caosdb_entity_property_get_datatype(&output_property, &out_type); + + bool in_is(false); + bool out_is(false); + caosdb_entity_datatype_is_atomic(&in_type, &in_is); + caosdb_entity_datatype_is_atomic(&out_type, &out_is); + EXPECT_EQ(in_is, out_is); + caosdb_entity_datatype_is_reference(&in_type, &in_is); + caosdb_entity_datatype_is_reference(&out_type, &out_is); + EXPECT_EQ(in_is, out_is); + caosdb_entity_datatype_is_list_of_atomic(&in_type, &in_is); + caosdb_entity_datatype_is_list_of_atomic(&out_type, &out_is); + EXPECT_EQ(in_is, out_is); + caosdb_entity_datatype_is_list_of_reference(&in_type, &in_is); + caosdb_entity_datatype_is_list_of_reference(&out_type, &out_is); + EXPECT_EQ(in_is, out_is); + + caosdb_entity_datatype_get_datatype_name(&in_type, &in); + caosdb_entity_datatype_get_datatype_name(&out_type, &out); + EXPECT_STREQ(in, out); + + caosdb_entity_value out_value; + caosdb_entity_property_get_value(&output_property, &out_value); + caosdb_entity_value_is_string(&in_value, &in_is); + EXPECT_TRUE(in_is); + caosdb_entity_value_is_string(&out_value, &out_is); + EXPECT_TRUE(out_is); + caosdb_entity_value_get_as_string(&in_value, &in); + caosdb_entity_value_get_as_string(&out_value, &out); + EXPECT_STREQ(in, out); caosdb_entity_parent output_parent; return_code = caosdb_entity_entity_get_parent(&entity, &output_parent, 0); @@ -623,6 +889,10 @@ TEST_F(test_ccaosdb, test_entity_with_parent_and_property) { EXPECT_EQ(return_code, 0); return_code = caosdb_entity_delete_entity(&entity); EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_datatype(&in_type); + EXPECT_EQ(return_code, 0); + return_code = caosdb_entity_delete_value(&in_value); + EXPECT_EQ(return_code, 0); // This tests the `_deletable` flag. The wrapped cpp objects of // `output_parent` and `output_property` are owned by the entity, so diff --git a/test/test_value.cpp b/test/test_value.cpp index 15d70a391265530798b756f2bd0ba4b50a932031..25f8a12909e52fee4e3ed3a6b688b1871a41a32f 100644 --- a/test/test_value.cpp +++ b/test/test_value.cpp @@ -147,4 +147,31 @@ TEST(test_value, test_scalar_value_to_value) { EXPECT_EQ(scalar_value.GetAsInt64(), value.GetAsInt64()); } +TEST(test_value, test_abstract_value) { + std::vector<double> vals; + for (double num : {0.0, 5.6, 27.5}) { + vals.push_back(num); + } + Value value(vals); + EXPECT_TRUE(value.IsVector()); + + AbstractValue *abstract_value = &value; + EXPECT_TRUE(abstract_value->IsVector()); + + Value value2(*abstract_value); + EXPECT_TRUE(value2.IsVector()); + + ScalarValue scalar_value = value.GetAsVector().at(2); + EXPECT_TRUE(scalar_value.IsDouble()); + EXPECT_EQ(scalar_value.GetAsDouble(), 27.5); + + AbstractValue *abstract_scalar_value = &scalar_value; + EXPECT_TRUE(abstract_scalar_value->IsDouble()); + EXPECT_EQ(abstract_scalar_value->GetAsDouble(), 27.5); + + Value scalar_value2(*abstract_scalar_value); + EXPECT_TRUE(scalar_value2.IsDouble()); + EXPECT_EQ(scalar_value2.GetAsDouble(), 27.5); +} + } // namespace caosdb::entity