From 13cb4e769a0b5308316142e07177f0d235664831 Mon Sep 17 00:00:00 2001
From: florian <f.spreckelsen@inidscale.com>
Date: Thu, 19 Aug 2021 18:55:00 +0200
Subject: [PATCH] ENH: Re-implement setters and getters for role and importance

---
 include/ccaosdb.h     |  24 +++++++--
 src/ccaosdb.cpp       | 111 ++++++++++++++++++++++++++++++------------
 test/test_ccaosdb.cpp |  17 ++++---
 3 files changed, 109 insertions(+), 43 deletions(-)

diff --git a/include/ccaosdb.h b/include/ccaosdb.h
index 82b33fa..e23e3a7 100644
--- a/include/ccaosdb.h
+++ b/include/ccaosdb.h
@@ -325,7 +325,11 @@ 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);
+/**
+ * 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);
@@ -363,7 +367,11 @@ 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);
+/**
+ * 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);
@@ -399,7 +407,11 @@ 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);
 // TODO(fspreck) replace by more specific setters
 int caosdb_entity_entity_set_int_value(caosdb_entity_entity *entity, const long value);
@@ -423,7 +435,11 @@ 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);
 
diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp
index f34089e..ad0ac71 100644
--- a/src/ccaosdb.cpp
+++ b/src/ccaosdb.cpp
@@ -46,6 +46,12 @@ extern "C" {
 
 #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.
@@ -69,8 +75,8 @@ extern "C" {
     GENERIC_ERROR,                                                                                 \
     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());                                          \
+      char *tmp = (char *)malloc(sizeof(char) * wrapped_entity->GetFunction.length() + 1);         \
+      strcpy(tmp, wrapped_entity->GetFunction.c_str());                                            \
       delete[] * out;                                                                              \
       *out = tmp;                                                                                  \
       return 0;                                                                                    \
@@ -95,8 +101,8 @@ extern "C" {
     GENERIC_ERROR,                                                                                 \
     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());                                        \
+      char *tmp = (char *)malloc(sizeof(char) * wrapped_property->GetFunction.length() + 1);       \
+      strcpy(tmp, wrapped_property->GetFunction.c_str());                                          \
       delete[] * out;                                                                              \
       *out = tmp;                                                                                  \
       return 0;                                                                                    \
@@ -122,8 +128,8 @@ extern "C" {
     GENERIC_ERROR,                                                                                 \
     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());                                          \
+      char *tmp = (char *)malloc(sizeof(char) * wrapped_parent->GetFunction.length() + 1);         \
+      strcpy(tmp, wrapped_parent->GetFunction.c_str());                                            \
       delete[] * out;                                                                              \
       *out = tmp;                                                                                  \
       return 0;                                                                                    \
@@ -533,16 +539,22 @@ ERROR_RETURN_CODE(GENERIC_ERROR, int caosdb_entity_delete_parent(caosdb_entity_p
   return 0;
 })
 
-CAOSDB_ENTITY_GET(id, GetId)
-// TODO(fspreck)
-// CAOSDB_ENTITY_GET(role, strcpy(out, wrapped_entity->GetRole().c_str());)
-CAOSDB_ENTITY_GET(name, GetName)
-CAOSDB_ENTITY_GET(description, GetDescription)
+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())
 // 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());)
 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);
@@ -565,7 +577,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     *out = wrapped_entity->GetValue().AsBool();
                     return 0;
                   })
-CAOSDB_ENTITY_GET(string_value, GetValue().AsString)
+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,
@@ -621,8 +633,8 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     return 0;
                   })
 
-CAOSDB_ENTITY_GET(unit, GetUnit)
-CAOSDB_ENTITY_GET(version_id, GetVersionId)
+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),
@@ -740,23 +752,32 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     return 0;
                   })
 
-CAOSDB_PARENT_GET(id, GetId)
-CAOSDB_PARENT_GET(name, GetName)
-CAOSDB_PARENT_GET(description, GetDescription)
+CAOSDB_PARENT_GET(id, GetId())
+CAOSDB_PARENT_GET(name, GetName())
+CAOSDB_PARENT_GET(description, GetDescription())
 
-CAOSDB_PROPERTY_GET(id, GetId)
-CAOSDB_PROPERTY_GET(name, GetName)
-CAOSDB_PROPERTY_GET(description, GetDescription)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_GET(importance,
-//                    strcpy(out, wrapped_property->GetImportance().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_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;
+                  })
 // TODO(fspreck)
 // CAOSDB_PROPERTY_GET(datatype,
 //                    strcpy(out, wrapped_property->GetDatatype().c_str());)
-CAOSDB_PROPERTY_GET(unit, GetUnit)
-// TODO(fspreck)
-// CAOSDB_PROPERTY_GET(value, strcpy(out,
-// wrapped_property->GetValue().c_str());)
+CAOSDB_PROPERTY_GET(unit, GetUnit())
+
 ERROR_RETURN_CODE(GENERIC_ERROR,
                   int caosdb_entity_property_get_int_value(caosdb_entity_property *property,
                                                            long *out),
@@ -781,7 +802,7 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     *out = wrapped_property->GetValue().AsBool();
                     return 0;
                   })
-CAOSDB_PROPERTY_GET(string_value, GetValue().AsString)
+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,
@@ -856,8 +877,19 @@ ERROR_RETURN_CODE(
     return 0;
   })
 
-// TODO(fspreck)
-// CAOSDB_ENTITY_SET(role, role, wrapped_entity->SetRole(std::string(role));)
+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));)
@@ -1016,6 +1048,21 @@ CAOSDB_PROPERTY_SET(id, id, wrapped_property->SetId(std::string(id));)
 // TODO(fspreck)
 // CAOSDB_PROPERTY_SET(importance, importance,
 //                    wrapped_property->SetImportance(std::string(importance));)
+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));)
 
 ERROR_RETURN_CODE(GENERIC_ERROR,
diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp
index 35f2cf3..0a5e432 100644
--- a/test/test_ccaosdb.cpp
+++ b/test/test_ccaosdb.cpp
@@ -156,10 +156,13 @@ TEST_F(test_ccaosdb, test_entity) {
   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);
@@ -219,7 +222,7 @@ TEST_F(test_ccaosdb, test_property) {
   // TODO(fspreck)
   // caosdb_entity_property_set_datatype(&property, "TEXT");
   // TODO(fspreck)
-  // caosdb_entity_property_set_importance(&property, "FIX");
+  caosdb_entity_property_set_importance(&property, "FIX");
   caosdb_entity_property_set_unit(&property, "some_unit");
   caosdb_entity_property_set_string_value(&property, "some_value");
 
@@ -235,8 +238,8 @@ TEST_F(test_ccaosdb, test_property) {
   // EXPECT_EQ(strcmp(out, "TEXT"), 0);
 
   // TODO(fspreck)
-  // caosdb_entity_property_get_importance(&property, out);
-  // EXPECT_EQ(strcmp(out, "FIX"), 0);
+  caosdb_entity_property_get_importance(&property, &out);
+  EXPECT_EQ(strcmp(out, "FIX"), 0);
 
   caosdb_entity_property_get_unit(&property, &out);
   EXPECT_EQ(strcmp(out, "some_unit"), 0);
-- 
GitLab