[gom] gom: Add gom_resource_group_delete_[a]sync functions



commit 9fe1ed826d15bda1c4acb12a80ba254b2bfcc28b
Author: Alexander Larsson <alexl redhat com>
Date:   Tue Apr 14 15:49:43 2015 +0200

    gom: Add gom_resource_group_delete_[a]sync functions
    
    These are for deleting a group of objects as a transaction.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=747849

 gom/gom-resource-group.c |  146 ++++++++++++++++++++++++++++++++++++++++++++++
 gom/gom-resource-group.h |    8 +++
 gom/gom-resource-priv.h  |    3 +
 gom/gom-resource.c       |    2 +-
 tests/test-gom-stress.c  |   20 ++++++
 5 files changed, 178 insertions(+), 1 deletions(-)
---
diff --git a/gom/gom-resource-group.c b/gom/gom-resource-group.c
index 8adc4c4..f6bbfa3 100644
--- a/gom/gom-resource-group.c
+++ b/gom/gom-resource-group.c
@@ -272,6 +272,152 @@ gom_resource_group_write_finish (GomResourceGroup  *group,
    return ret;
 }
 
+static void
+gom_resource_group_delete_cb (GomAdapter *adapter,
+                              gpointer    user_data)
+{
+   GSimpleAsyncResult *simple = user_data;
+   GomResourceGroup *group;
+   GError *error = NULL;
+   GAsyncQueue *queue;
+   guint i;
+   gboolean got_error;
+   GPtrArray *items;
+
+   g_return_if_fail(GOM_IS_ADAPTER(adapter));
+   g_return_if_fail(G_IS_SIMPLE_ASYNC_RESULT(simple));
+
+   group = GOM_RESOURCE_GROUP(g_async_result_get_source_object(G_ASYNC_RESULT(simple)));
+
+   g_assert(GOM_IS_ADAPTER(adapter));
+
+   items = g_object_get_data(G_OBJECT(simple), "items");
+   queue = g_object_get_data(G_OBJECT(simple), "queue");
+
+   /* do BEGIN */
+   EXECUTE_OR_GOTO(adapter, "BEGIN;", &error, rollback);
+
+   got_error = FALSE;
+
+   for (i = 0; i < items->len; i++) {
+      GomResource *item;
+
+      item = g_ptr_array_index(items, i);
+      if (got_error ||
+          !gom_resource_do_delete (item, adapter, &error)) {
+        got_error = TRUE;
+      }
+   }
+
+   if (got_error)
+      goto rollback;
+
+   EXECUTE_OR_GOTO(adapter, "COMMIT;", &error, rollback);
+
+   g_simple_async_result_set_op_res_gboolean(simple, TRUE);
+   goto out;
+
+rollback:
+   EXECUTE_OR_GOTO(adapter, "ROLLBACK;", NULL, error);
+
+error:
+   g_assert(error);
+   g_simple_async_result_take_error(simple, error);
+
+out:
+   g_object_unref(group);
+   if (!queue)
+      g_simple_async_result_complete_in_idle(simple);
+   else
+      g_async_queue_push(queue, GINT_TO_POINTER(TRUE));
+}
+
+gboolean
+gom_resource_group_delete_sync (GomResourceGroup  *group,
+                                GError           **error)
+{
+   GSimpleAsyncResult *simple;
+   gboolean ret;
+   GAsyncQueue *queue;
+   GomAdapter *adapter;
+
+   g_return_val_if_fail(GOM_IS_RESOURCE_GROUP(group), FALSE);
+   g_return_val_if_fail(group->priv->is_writable, FALSE);
+
+   queue = g_async_queue_new();
+
+   simple = g_simple_async_result_new(G_OBJECT(group), NULL, NULL,
+                                      gom_resource_group_delete_sync);
+   if (!group->priv->to_write)
+      return TRUE;
+
+   g_object_set_data(G_OBJECT(simple), "queue", queue);
+   g_object_set_data_full(G_OBJECT(simple), "items", group->priv->to_write, 
(GDestroyNotify)g_ptr_array_unref);
+   group->priv->to_write = NULL;
+
+   adapter = gom_repository_get_adapter(group->priv->repository);
+   gom_adapter_queue_write(adapter, gom_resource_group_delete_cb, simple);
+   g_async_queue_pop(queue);
+   g_async_queue_unref(queue);
+
+   if (!(ret = g_simple_async_result_get_op_res_gboolean(simple))) {
+      g_simple_async_result_propagate_error(simple, error);
+   }
+   g_object_unref(simple);
+
+   return ret;
+}
+
+void
+gom_resource_group_delete_async (GomResourceGroup    *group,
+                                 GAsyncReadyCallback  callback,
+                                 gpointer             user_data)
+{
+   GomResourceGroupPrivate *priv;
+   GSimpleAsyncResult *simple;
+   GomAdapter *adapter;
+
+   g_return_if_fail(GOM_IS_RESOURCE_GROUP(group));
+   g_return_if_fail(callback != NULL);
+   g_return_if_fail(group->priv->is_writable);
+
+   priv = group->priv;
+
+   simple = g_simple_async_result_new(G_OBJECT(group), callback, user_data,
+                                      gom_resource_group_delete_async);
+   if (!group->priv->to_write) {
+      g_simple_async_result_set_op_res_gboolean(simple, TRUE);
+      g_simple_async_result_complete_in_idle(simple);
+      return;
+   }
+
+   g_object_set_data_full(G_OBJECT(simple), "items", group->priv->to_write, 
(GDestroyNotify)g_ptr_array_unref);
+   group->priv->to_write = NULL;
+
+   adapter = gom_repository_get_adapter(priv->repository);
+   gom_adapter_queue_read(adapter, gom_resource_group_delete_cb, simple);
+}
+
+gboolean
+gom_resource_group_delete_finish (GomResourceGroup  *group,
+                                  GAsyncResult      *result,
+                                  GError           **error)
+{
+   GSimpleAsyncResult *simple = (GSimpleAsyncResult *)result;
+   gboolean ret;
+
+   g_return_val_if_fail(GOM_IS_RESOURCE_GROUP(group), FALSE);
+   g_return_val_if_fail(G_IS_SIMPLE_ASYNC_RESULT(simple), FALSE);
+   g_return_val_if_fail(group->priv->is_writable, FALSE);
+
+   if (!(ret = g_simple_async_result_get_op_res_gboolean(simple))) {
+      g_simple_async_result_propagate_error(simple, error);
+   }
+   g_object_unref(simple);
+
+   return ret;
+}
+
 static GomFilter *
 gom_resource_group_get_filter (GomResourceGroup *group)
 {
diff --git a/gom/gom-resource-group.h b/gom/gom-resource-group.h
index c8d99b7..60e223e 100644
--- a/gom/gom-resource-group.h
+++ b/gom/gom-resource-group.h
@@ -62,6 +62,14 @@ void              gom_resource_group_write_async  (GomResourceGroup    *group,
 gboolean          gom_resource_group_write_finish (GomResourceGroup    *group,
                                                    GAsyncResult        *result,
                                                    GError             **error);
+gboolean          gom_resource_group_delete_sync  (GomResourceGroup    *group,
+                                                   GError             **error);
+void              gom_resource_group_delete_async (GomResourceGroup    *group,
+                                                   GAsyncReadyCallback  callback,
+                                                   gpointer             user_data);
+gboolean          gom_resource_group_delete_finish(GomResourceGroup    *group,
+                                                   GAsyncResult        *result,
+                                                   GError             **error);
 
 void         gom_resource_group_fetch_async   (GomResourceGroup     *group,
                                                guint                 index_,
diff --git a/gom/gom-resource-priv.h b/gom/gom-resource-priv.h
index 41f27c3..adabe12 100644
--- a/gom/gom-resource-priv.h
+++ b/gom/gom-resource-priv.h
@@ -30,6 +30,9 @@ gboolean gom_resource_has_dynamic_pkey         (GType         type);
 gboolean gom_resource_do_save                  (GomResource  *resource,
                                                 GomAdapter   *adapter,
                                                 GError      **error);
+gboolean gom_resource_do_delete                (GomResource  *resource,
+                                                GomAdapter   *adapter,
+                                                GError      **error);
 void     gom_resource_build_save_cmd           (GomResource  *resource,
                                                 GomAdapter   *adapter);
 void     gom_resource_set_post_save_properties (GomResource  *resource);
diff --git a/gom/gom-resource.c b/gom/gom-resource.c
index 3a4b844..f3029eb 100644
--- a/gom/gom-resource.c
+++ b/gom/gom-resource.c
@@ -289,7 +289,7 @@ gom_resource_set_repository (GomResource   *resource,
    }
 }
 
-static gboolean
+gboolean
 gom_resource_do_delete (GomResource  *resource,
                         GomAdapter   *adapter,
                         GError      **error)
diff --git a/tests/test-gom-stress.c b/tests/test-gom-stress.c
index 72e06f9..dd01a05 100644
--- a/tests/test-gom-stress.c
+++ b/tests/test-gom-stress.c
@@ -314,6 +314,26 @@ stress2 (void)
    g_free(s1);
    g_free(s2);
 
+   /* Test deleting all but one item */
+   group = gom_resource_group_new(repository);
+
+   for (l = items; l != NULL; l = l->next) {
+      ItemResource *item = l->data;
+      if (item->priv->id != ITEM_TO_GET)
+         gom_resource_group_append(group, GOM_RESOURCE(item));
+   }
+
+   gom_resource_group_delete_sync(group, &error);
+   g_assert_no_error(error);
+   g_object_unref(group);
+
+   /* We should have only one item now */
+   group = gom_repository_find_sync (repository, ITEM_TYPE_RESOURCE, NULL, &error);
+   g_assert_no_error(error);
+   g_assert (group != NULL);
+   g_assert_cmpint(gom_resource_group_get_count (group), ==,  1);
+   g_object_unref(group);
+
    g_list_free_full (items, g_object_unref);
 
    ret = gom_adapter_close_sync(adapter, &error);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]