[gom] gom: Add gom_resource_group_delete_[a]sync functions
- From: Alexander Larsson <alexl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gom] gom: Add gom_resource_group_delete_[a]sync functions
- Date: Tue, 14 Apr 2015 14:49:34 +0000 (UTC)
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]