From 09f305f43279c3f567b03aac65924bc456d212e5 Mon Sep 17 00:00:00 2001
From: florian <f.spreckelsen@inidscale.com>
Date: Thu, 19 Aug 2021 17:54:56 +0200
Subject: [PATCH] ENH: Add get_list_value_at getters

---
 include/ccaosdb.h     | 24 ++++++++-----
 src/ccaosdb.cpp       | 82 +++++++++++++++++++++++++++++++++++++++----
 test/test_ccaosdb.cpp | 14 ++++----
 3 files changed, 98 insertions(+), 22 deletions(-)

diff --git a/include/ccaosdb.h b/include/ccaosdb.h
index fdda0b1..82b33fa 100644
--- a/include/ccaosdb.h
+++ b/include/ccaosdb.h
@@ -332,10 +332,14 @@ 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(caosdb_entity_entity *entity, long *out);
-int caosdb_entity_entity_get_double_list_value(caosdb_entity_entity *entity, double *out);
-int caosdb_entity_entity_get_boolean_list_value(caosdb_entity_entity *entity, bool *out);
-int caosdb_entity_entity_get_string_list_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);
@@ -366,10 +370,14 @@ int caosdb_entity_property_get_int_value(caosdb_entity_property *property, long
 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(caosdb_entity_property *property, long **out);
-int caosdb_entity_property_get_double_list_value(caosdb_entity_property *property, double *out);
-int caosdb_entity_property_get_boolean_list_value(caosdb_entity_property *property, bool *out);
-int caosdb_entity_property_get_string_list_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);
diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp
index 9d08cc0..451e131 100644
--- a/src/ccaosdb.cpp
+++ b/src/ccaosdb.cpp
@@ -566,16 +566,45 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     return 0;
                   })
 CAOSDB_ENTITY_GET(string_value, GetValue().AsString)
+
 ERROR_RETURN_CODE(GENERIC_ERROR,
-                  int caosdb_entity_entity_get_int_list_value(caosdb_entity_entity *entity,
-                                                              long *out),
+                  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();
-                    int i = 0;
-                    for (const auto elt : value_list) {
-                      out[i++] = elt.AsInteger();
-                    }
+                    *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;
                   })
 
@@ -754,6 +783,47 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                   })
 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;
+                  })
+
 // TODO(fspreck) Fix this somehow. It segfaults. Bleh.
 // ERROR_RETURN_CODE(GENERIC_ERROR,
 //                   int caosdb_entity_property_get_string_list_value(
diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp
index 294c8aa..7540177 100644
--- a/test/test_ccaosdb.cpp
+++ b/test/test_ccaosdb.cpp
@@ -277,14 +277,12 @@ TEST_F(test_ccaosdb, test_list_property) {
   EXPECT_EQ(*length, 3);
 
   // TODO(fspreck) get and compare values in list. Segfaults as it is right now.
-  // char **out_list = nullptr; // NOLINT
-  // std::cout << "Getting list values" << std::endl;
-  // return_code =
-  //   caosdb_entity_property_get_string_list_value(&property, &out_list);
-  // EXPECT_EQ(return_code, 0);
-  // for (int i = 0; i < *length; i++) {
-  //   EXPECT_EQ(strcmp(value_list[i], out_list[i]), 0); // NOLINT
-  // }
+  char *out = nullptr; // NOLINT
+  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);
-- 
GitLab