From 364b951934b236f823d2ecba8481119779123ad6 Mon Sep 17 00:00:00 2001
From: florian <f.spreckelsen@inidscale.com>
Date: Tue, 10 Aug 2021 11:37:59 +0200
Subject: [PATCH] ENH: Add destructor for transactions to Extern C

---
 include/ccaosdb.h     | 15 ++++++++++++---
 src/ccaosdb.cpp       | 28 +++++++++++++++++++++++++++-
 test/test_ccaosdb.cpp | 14 +++++++++++++-
 3 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/include/ccaosdb.h b/include/ccaosdb.h
index 76d59b1..152062d 100644
--- a/include/ccaosdb.h
+++ b/include/ccaosdb.h
@@ -265,9 +265,17 @@ typedef struct {
   void *wrapped_transaction;
 } caosdb_transaction_transaction;
 
+/**
+ * Create a transaction on an existing connection.
+ *
+ * This transaction has to be deleted manually by
+ * caosdb_transaction_delete_transaction() later on.
+ */
 int caosdb_connection_connection_create_transaction(
   caosdb_connection_connection *connection,
   caosdb_transaction_transaction *out);
+int caosdb_transaction_delete_transaction(
+  caosdb_transaction_transaction *transaction);
 int caosdb_transaction_transaction_retrieve_by_id(
   caosdb_transaction_transaction *transaction, const char *id);
 int caosdb_transaction_transaction_retrieve_by_ids(
@@ -302,9 +310,10 @@ typedef struct {
   char **version_id;
 } caosdb_entity_entity;
 
-int caosdb_transaction_result_set_get_entity(
-  caosdb_transaction_result_set *result_set, caosdb_entity_entity *entity,
-  int index);
+int caosdb_transaction_result_set_at(caosdb_transaction_result_set *result_set,
+                                     caosdb_entity_entity *entity, int index);
+int caosdb_transaction_result_set_size(
+  caosdb_transaction_result_set *result_set, int *out);
 
 typedef struct {
   void *wrapped_property;
diff --git a/src/ccaosdb.cpp b/src/ccaosdb.cpp
index 6f63499..023bea0 100644
--- a/src/ccaosdb.cpp
+++ b/src/ccaosdb.cpp
@@ -276,7 +276,16 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                       static_cast<caosdb::connection::Connection *>(
                         connection->wrapped_connection);
                     out->wrapped_transaction =
-                      wrapped_connection->CreateTransaction().get();
+                      wrapped_connection->CreateTransaction().release();
+                    return 0;
+                  })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_transaction_delete_transaction(
+                    caosdb_transaction_transaction *transaction),
+                  {
+                    delete static_cast<caosdb::transaction::Transaction *>(
+                      transaction->wrapped_transaction);
                     return 0;
                   })
 
@@ -352,4 +361,21 @@ ERROR_RETURN_CODE(GENERIC_ERROR,
                     *out = cr;
                     return 0;
                   })
+
+ERROR_RETURN_CODE(GENERIC_ERROR,
+                  int caosdb_transaction_result_set_at(
+                    caosdb_transaction_result_set *result_set,
+                    caosdb_entity_entity *entity, int index),
+                  {
+                    // TODO(fspreck) how do we treat this? ResultSet
+                    // is an abstract class, can we always fall back
+                    // to MultiResultSet?
+                    auto *wrapped_result_set =
+                      static_cast<caosdb::transaction::MultiResultSet *>(
+                        result_set->wrapped_result_set);
+                    auto requested_entity = wrapped_result_set->At(index);
+                    entity->wrapped_entity = (void *)(&requested_entity);
+
+                    return 0;
+                  })
 }
diff --git a/test/test_ccaosdb.cpp b/test/test_ccaosdb.cpp
index 71ec2f2..70ee14d 100644
--- a/test/test_ccaosdb.cpp
+++ b/test/test_ccaosdb.cpp
@@ -75,11 +75,14 @@ TEST_F(test_ccaosdb, test_execute_transaction) {
 
   int return_code(
     caosdb_transaction_transaction_retrieve_by_id(&transaction, "some_id"));
-  EXPECT_EQ(return_code, 0);
+  EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
 
   return_code = caosdb_transaction_transaction_execute(&transaction);
   EXPECT_EQ(return_code, caosdb::StatusCode::CONNECTION_ERROR);
 
+  return_code = caosdb_transaction_delete_transaction(&transaction);
+  EXPECT_EQ(return_code, 0);
+
   caosdb_transaction_transaction multi_transaction;
   caosdb_connection_connection_create_transaction(&connection,
                                                   &multi_transaction);
@@ -89,6 +92,9 @@ TEST_F(test_ccaosdb, test_execute_transaction) {
   const char *ids[] = {"id1", "id2", "id3"}; // NOLINT
   return_code =
     caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids);
+  EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
+
+  return_code = caosdb_transaction_delete_transaction(&multi_transaction);
   EXPECT_EQ(return_code, 0);
 }
 
@@ -106,6 +112,9 @@ TEST_F(test_ccaosdb, test_multi_retrieve) {
   const char *ids[] = {"id1", "id2", "id3"}; // NOLINT
   int return_code(
     caosdb_transaction_transaction_retrieve_by_ids(&multi_transaction, ids));
+  EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
+
+  return_code = caosdb_transaction_delete_transaction(&multi_transaction);
   EXPECT_EQ(return_code, 0);
 }
 
@@ -119,5 +128,8 @@ TEST_F(test_ccaosdb, test_query) {
 
   int return_code(caosdb_transaction_transaction_query(
     &transaction, "FIND ENTITY WITH id=123"));
+  EXPECT_EQ(return_code, caosdb::StatusCode::GO_ON);
+
+  return_code = caosdb_transaction_delete_transaction(&transaction);
   EXPECT_EQ(return_code, 0);
 }
-- 
GitLab