[evolution-data-server/openismus-work: 7/7] Allow asynchronous storing of data in ECal.
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server/openismus-work: 7/7] Allow asynchronous storing of data in ECal.
- Date: Wed, 3 Aug 2011 19:36:48 +0000 (UTC)
commit 6906fa279c4d9a26767c90a7eea8315327ab38dd
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Sat Jul 23 18:05:32 2011 -0400
Allow asynchronous storing of data in ECal.
Patch adds the functions:
o e_cal_create_object_async()
o e_cal_modify_object_async()
o e_cal_remove_object_async()
o e_cal_remove_object_with_mod_async()
And updates the test cases to test the _async() variants:
calendar/tests/ecal/test-ecal-create-object.c
calendar/tests/ecal/test-ecal-modify-object.c
calendar/tests/ecal/test-ecal-remove-object.c
Addresses bug: https://bugzilla.gnome.org/show_bug.cgi?id=652174
calendar/libecal/e-cal.c | 235 +++++++++++++++++++++++++
calendar/libecal/e-cal.h | 21 +++
calendar/tests/ecal/test-ecal-create-object.c | 53 +++++-
calendar/tests/ecal/test-ecal-modify-object.c | 101 +++++++++--
calendar/tests/ecal/test-ecal-remove-object.c | 41 +++++-
5 files changed, 430 insertions(+), 21 deletions(-)
---
diff --git a/calendar/libecal/e-cal.c b/calendar/libecal/e-cal.c
index fcdc9f2..fc10525 100644
--- a/calendar/libecal/e-cal.c
+++ b/calendar/libecal/e-cal.c
@@ -122,6 +122,12 @@ struct _ECalPrivate {
GStaticRecMutex cache_lock;
};
+typedef struct {
+ ECal *cal;
+ gpointer callback;
+ gpointer user_data;
+} AsyncData;
+
/* Signal IDs */
@@ -3629,6 +3635,73 @@ e_cal_create_object (ECal *ecal, icalcomponent *icalcomp, gchar **uid, GError **
}
}
+static void
+create_object_reply (GObject *gdbus_cal, GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+ AsyncData *data = user_data;
+ ECalIdAsyncCallback callback = data->callback;
+ gchar *id = NULL;
+
+ if (!e_gdbus_cal_call_create_object_finish (E_GDBUS_CAL (gdbus_cal), &id, res, &error))
+ g_warning ("Error finishing createContact: %s", error->message);
+
+ unwrap_gerror (&error);
+
+ if (callback)
+ callback (data->cal, error, id, data->user_data);
+
+ if (error)
+ g_error_free (error);
+
+ g_free (id);
+ g_object_unref (data->cal);
+ g_slice_free (AsyncData, data);
+}
+
+/**
+ * e_cal_create_object_async:
+ * @ecal: A calendar client.
+ * @icalcomp: The component to create.
+ * @callback: A #ECalIdAsyncCallback which will be called when the operation is complete, or %NULL.
+ * @user_data: The pointer to be given to @callback
+ *
+ * Requests the calendar backend to create the object specified by the @icalcomp
+ * argument. Some backends would assign a specific UID to the newly created object,
+ * in those cases that UID would be returned as the id parameter of @callback when
+ * the operation is done.
+ *
+ * Returns: %TRUE if the async message was sent, %FALSE if some preconditions were not satisfied.
+ */
+gboolean
+e_cal_create_object_async (ECal *ecal,
+ icalcomponent *icalcomp,
+ ECalIdAsyncCallback callback,
+ gpointer user_data)
+{
+ ECalPrivate *priv;
+ gchar *obj;
+ AsyncData *data;
+
+ g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+ g_return_val_if_fail (icalcomp != NULL, FALSE);
+ g_return_val_if_fail (icalcomponent_is_valid (icalcomp), FALSE);
+ priv = ecal->priv;
+ g_return_val_if_fail (priv->gdbus_cal, FALSE);
+
+ data = g_slice_new0 (AsyncData);
+ data->cal = g_object_ref (ecal);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ obj = icalcomponent_as_ical_string_r (icalcomp);
+ e_gdbus_cal_call_create_object (priv->gdbus_cal, obj, NULL, create_object_reply, data);
+ g_free (obj);
+
+ return TRUE;
+}
+
+
/**
* e_cal_modify_object:
* @ecal: A calendar client.
@@ -3681,6 +3754,84 @@ e_cal_modify_object (ECal *ecal, icalcomponent *icalcomp, CalObjModType mod, GEr
E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
}
+static void
+modify_object_reply (GObject *gdbus_cal, GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+ AsyncData *data = user_data;
+ ECalAsyncCallback callback = data->callback;
+
+ if (!e_gdbus_cal_call_modify_object_finish (E_GDBUS_CAL (gdbus_cal), res, &error))
+ g_warning ("Error finishing modifyContact: %s", error->message);
+
+ unwrap_gerror (&error);
+
+ if (callback)
+ callback (data->cal, error, data->user_data);
+
+ if (error)
+ g_error_free (error);
+
+ g_object_unref (data->cal);
+ g_slice_free (AsyncData, data);
+}
+
+/**
+ * e_cal_modify_object_async:
+ * @ecal: A calendar client.
+ * @icalcomp: Component to modify.
+ * @mod: Type of modification.
+ * @callback: A #ECalAsyncCallback which will be called when the operation is complete, or %NULL.
+ * @user_data: The pointer to be given to @callback
+ *
+ * Requests the calendar backend to modify an existing object. If the object
+ * does not exist on the calendar, an error will be returned in the async callback.
+ *
+ * For recurrent appointments, the @mod argument specifies what to modify,
+ * if all instances (CALOBJ_MOD_ALL), a single instance (CALOBJ_MOD_THIS),
+ * or a specific set of instances (CALOBJ_MOD_THISNADPRIOR and
+ * CALOBJ_MOD_THISANDFUTURE).
+ *
+ * Returns: %TRUE if the async message was sent, %FALSE if some preconditions were not satisfied.
+ */
+gboolean
+e_cal_modify_object_async (ECal *ecal,
+ icalcomponent *icalcomp,
+ CalObjModType mod,
+ ECalAsyncCallback callback,
+ gpointer user_data)
+{
+ ECalPrivate *priv;
+ gchar *obj;
+ AsyncData *data;
+
+ g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+ g_return_val_if_fail (icalcomp, FALSE);
+ g_return_val_if_fail (icalcomponent_is_valid (icalcomp), FALSE);
+ switch (mod) {
+ case CALOBJ_MOD_THIS:
+ case CALOBJ_MOD_THISANDPRIOR:
+ case CALOBJ_MOD_THISANDFUTURE:
+ case CALOBJ_MOD_ALL:
+ break;
+ default:
+ g_return_val_if_fail ("valid CalObjModType" && FALSE, FALSE);
+ }
+ priv = ecal->priv;
+ g_return_val_if_fail (priv->gdbus_cal, FALSE);
+
+ data = g_slice_new0 (AsyncData);
+ data->cal = g_object_ref (ecal);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ obj = icalcomponent_as_ical_string_r (icalcomp);
+ e_gdbus_cal_call_modify_object (priv->gdbus_cal, obj, mod, NULL, modify_object_reply, data);
+ g_free (obj);
+
+ return TRUE;
+}
+
/**
* e_cal_remove_object_with_mod:
* @ecal: A calendar client.
@@ -3758,6 +3909,73 @@ e_cal_remove_object_with_mod (ECal *ecal, const gchar *uid,
E_CALENDAR_CHECK_STATUS (E_CALENDAR_STATUS_OK, error);
}
+static void
+remove_object_reply (GObject *gdbus_cal, GAsyncResult *res, gpointer user_data)
+{
+ GError *error = NULL;
+ AsyncData *data = user_data;
+ ECalAsyncCallback callback = data->callback;
+
+ if (!e_gdbus_cal_call_remove_object_finish (E_GDBUS_CAL (gdbus_cal), res, &error))
+ g_warning ("Error finishing removeContact: %s", error->message);
+
+ unwrap_gerror (&error);
+
+ if (callback)
+ callback (data->cal, error, data->user_data);
+
+ if (error)
+ g_error_free (error);
+
+ g_object_unref (data->cal);
+ g_slice_free (AsyncData, data);
+}
+
+/**
+ * e_cal_remove_object_with_mod_async:
+ * @ecal: A calendar client.
+ * @uid: UID of the object to remove.
+ * @rid: Recurrence ID of the specific recurrence to remove.
+ * @mod: Type of removal.
+ * @callback: A #ECalAsyncCallback which will be called when the operation is complete, or %NULL.
+ * @user_data: The pointer to be given to @callback
+ *
+ * An asynchronous method for removing objects, see e_cal_remove_object_with_mod() for full details.
+ *
+ * Returns: %TRUE if the async message was sent, %FALSE if some preconditions were not satisfied.
+ */
+gboolean
+e_cal_remove_object_with_mod_async (ECal *ecal, const gchar *uid, const gchar *rid, CalObjModType mod, ECalAsyncCallback callback, gpointer user_data)
+{
+ ECalPrivate *priv;
+ AsyncData *data;
+
+ g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+ g_return_val_if_fail (uid, FALSE);
+ switch (mod) {
+ case CALOBJ_MOD_THIS:
+ case CALOBJ_MOD_THISANDPRIOR:
+ case CALOBJ_MOD_THISANDFUTURE:
+ case CALOBJ_MOD_ONLY_THIS:
+ case CALOBJ_MOD_ALL:
+ break;
+ default:
+ g_return_val_if_fail ("valid CalObjModType" && FALSE, FALSE);
+ }
+ priv = ecal->priv;
+ g_return_val_if_fail (priv->gdbus_cal, FALSE);
+
+ data = g_slice_new0 (AsyncData);
+ data->cal = g_object_ref (ecal);
+ data->callback = callback;
+ data->user_data = user_data;
+
+ e_gdbus_cal_call_remove_object (priv->gdbus_cal, uid, rid ? rid : "", mod, NULL,
+ remove_object_reply, data);
+
+ return TRUE;
+}
+
/**
* e_cal_remove_object:
* @ecal: A calendar client.
@@ -3780,6 +3998,23 @@ e_cal_remove_object (ECal *ecal, const gchar *uid, GError **error)
}
/**
+ * e_cal_remove_object_async:
+ * @ecal: A calendar client.
+ * @uid: UID of the object to remove.
+ * @callback: A #ECalAsyncCallback which will be called when the operation is complete, or %NULL.
+ * @user_data: The pointer to be given to @callback
+ *
+ * An asynchronous method for removing objects, see e_cal_remove_object() for the synchronous version.
+ *
+ * Returns: %TRUE if the async message was sent, %FALSE if some preconditions were not satisfied.
+ */
+gboolean
+e_cal_remove_object_async (ECal *ecal, const gchar *uid, ECalAsyncCallback callback, gpointer user_data)
+{
+ return e_cal_remove_object_with_mod_async (ecal, uid, NULL, CALOBJ_MOD_THIS, callback, user_data);
+}
+
+/**
* e_cal_receive_objects:
* @ecal: A calendar client.
* @icalcomp: An icalcomponent.
diff --git a/calendar/libecal/e-cal.h b/calendar/libecal/e-cal.h
index ead68c6..c7bd500 100644
--- a/calendar/libecal/e-cal.h
+++ b/calendar/libecal/e-cal.h
@@ -47,6 +47,20 @@ typedef struct _ECal ECal;
typedef struct _ECalClass ECalClass;
typedef struct _ECalPrivate ECalPrivate;
+
+/**
+ * ECalAsyncCallback:
+ *
+ **/
+typedef void (*ECalAsyncCallback) (ECal *cal, const GError *error, gpointer user_data);
+
+/**
+ * ECalIdAsyncCallback:
+ *
+ **/
+typedef void (*ECalIdAsyncCallback) (ECal *cal, const GError *error, const gchar *id, gpointer user_data);
+
+
typedef enum {
E_CAL_SOURCE_TYPE_EVENT,
E_CAL_SOURCE_TYPE_TODO,
@@ -176,9 +190,16 @@ gboolean e_cal_get_alarms_for_object (ECal *ecal, const ECalComponentId *id,
ECalComponentAlarms **alarms);
gboolean e_cal_create_object (ECal *ecal, icalcomponent *icalcomp, gchar **uid, GError **error);
+gboolean e_cal_create_object_async (ECal *ecal, icalcomponent *icalcomp, ECalIdAsyncCallback callback, gpointer user_data);
+
gboolean e_cal_modify_object (ECal *ecal, icalcomponent *icalcomp, CalObjModType mod, GError **error);
+gboolean e_cal_modify_object_async (ECal *ecal, icalcomponent *icalcomp, CalObjModType mod, ECalAsyncCallback callback, gpointer user_data);
+
gboolean e_cal_remove_object (ECal *ecal, const gchar *uid, GError **error);
+gboolean e_cal_remove_object_async (ECal *ecal, const gchar *uid, ECalAsyncCallback callback, gpointer user_data);
+
gboolean e_cal_remove_object_with_mod (ECal *ecal, const gchar *uid, const gchar *rid, CalObjModType mod, GError **error);
+gboolean e_cal_remove_object_with_mod_async (ECal *ecal, const gchar *uid, const gchar *rid, CalObjModType mod, ECalAsyncCallback callback, gpointer user_data);
gboolean e_cal_discard_alarm (ECal *ecal, ECalComponent *comp, const gchar *auid, GError **error);
diff --git a/calendar/tests/ecal/test-ecal-create-object.c b/calendar/tests/ecal/test-ecal-create-object.c
index e9f2301..c0074c1 100644
--- a/calendar/tests/ecal/test-ecal-create-object.c
+++ b/calendar/tests/ecal/test-ecal-create-object.c
@@ -6,31 +6,76 @@
#include "ecal-test-utils.h"
+
+icalcomponent *component = NULL;
+
+
+static void
+object_created_cb (ECal *cal, const GError *error, const gchar *id, gpointer user_data)
+{
+ GMainLoop *loop = (GMainLoop *)user_data;
+ icalcomponent *component_final;
+
+ if (error)
+ g_error ("Error removing object: %s", error->message);
+
+ g_assert (id != NULL);
+
+ /* We only get the uid after the backend adds the component, set the uid
+ * here before comparing the newly returned 'component_final' */
+ icalcomponent_set_uid (component, id);
+
+ component_final = ecal_test_utils_cal_get_object (cal, id);
+ ecal_test_utils_cal_assert_objects_equal_shallow (component, component_final);
+
+ test_print ("e_cal_create_object_async() created id '%s'\n", id);
+
+ icalcomponent_free (component_final);
+
+ g_main_loop_quit (loop);
+}
+
gint
main (gint argc, gchar **argv)
{
ECal *cal;
gchar *uri = NULL;
- icalcomponent *component;
- icalcomponent *component_final;
gchar *uid;
+ icalcomponent *component_final;
+ GMainLoop *loop;
g_type_init ();
cal = ecal_test_utils_cal_new_temp (&uri, E_CAL_SOURCE_TYPE_EVENT);
ecal_test_utils_cal_open (cal, FALSE);
+ /* Sync Version */
component = icalcomponent_new (ICAL_VEVENT_COMPONENT);
uid = ecal_test_utils_cal_create_object (cal, component);
component_final = ecal_test_utils_cal_get_object (cal, uid);
ecal_test_utils_cal_assert_objects_equal_shallow (component, component_final);
- ecal_test_utils_cal_remove (cal);
-
g_free (uid);
icalcomponent_free (component);
icalcomponent_free (component_final);
+ uid = NULL;
+
+ /* Async Version */
+ loop = g_main_loop_new (NULL, FALSE);
+
+ component = icalcomponent_new (ICAL_VEVENT_COMPONENT);
+
+ e_cal_create_object_async (cal, component,
+ object_created_cb,
+ loop);
+
+ g_main_loop_run (loop);
+
+ icalcomponent_free (component);
+
+ ecal_test_utils_cal_remove (cal);
+ g_main_loop_unref (loop);
return 0;
}
diff --git a/calendar/tests/ecal/test-ecal-modify-object.c b/calendar/tests/ecal/test-ecal-modify-object.c
index b1c9933..4351485 100644
--- a/calendar/tests/ecal/test-ecal-modify-object.c
+++ b/calendar/tests/ecal/test-ecal-modify-object.c
@@ -14,56 +14,125 @@
#define FINAL_BEGIN_TIME "20091221T090000Z"
#define FINAL_BEGIN_TIMEZONE "UTC"
+
+typedef struct {
+ GMainLoop *loop;
+ ECal *cal;
+ ECalComponent *e_component;
+ const gchar *uid;
+} AsyncData;
+
+static void
+verify (ECal *cal, ECalComponent *e_component, const gchar *uid)
+{
+ icalcomponent *component;
+ icalcomponent *component_final;
+ ECalComponent *e_component_final;
+
+ component = e_cal_component_get_icalcomponent (e_component);
+
+ component_final = ecal_test_utils_cal_get_object (cal, uid);
+ e_component_final = e_cal_component_new ();
+ ecal_test_utils_cal_component_set_icalcomponent (e_component_final,
+ component_final);
+
+ ecal_test_utils_cal_assert_e_cal_components_equal (e_component,
+ e_component_final);
+
+ g_object_unref (e_component_final);
+}
+
+static void
+object_modified_cb (ECal *cal, const GError *error, gpointer user_data)
+{
+ AsyncData *data = (AsyncData *)user_data;
+
+ if (error)
+ g_error ("Error modifying object: %s", error->message);
+
+ /* verify */
+ verify (data->cal, data->e_component, data->uid);
+
+ test_print ("e_cal_modify_object_async() passed for uid '%s'\n", data->uid);
+
+ g_main_loop_quit (data->loop);
+}
+
gint
main (gint argc, gchar **argv)
{
ECal *cal;
gchar *uri = NULL;
ECalComponent *e_component;
- ECalComponent *e_component_final;
icalcomponent *component;
icalcomponent *component_final;
struct icaltimetype icaltime;
gchar *uid;
+ GMainLoop *loop;
+ AsyncData data = { 0, };
g_type_init ();
cal = ecal_test_utils_cal_new_temp (&uri, E_CAL_SOURCE_TYPE_EVENT);
ecal_test_utils_cal_open (cal, FALSE);
+ /*
+ * Sync Version
+ */
ecal_test_utils_create_component (cal, INITIAL_BEGIN_TIME,
INITIAL_BEGIN_TIMEZONE, INITIAL_END_TIME,
- INITIAL_END_TIMEZONE, EVENT_SUMMARY, &e_component,
- &uid);
+ INITIAL_END_TIMEZONE, EVENT_SUMMARY, &e_component, &uid);
component = e_cal_component_get_icalcomponent (e_component);
component_final = ecal_test_utils_cal_get_object (cal, uid);
- ecal_test_utils_cal_assert_objects_equal_shallow (component,
- component_final);
+ ecal_test_utils_cal_assert_objects_equal_shallow (component, component_final);
icalcomponent_free (component_final);
/* make and commit changes */
icaltime = icaltime_from_string (FINAL_BEGIN_TIME);
icalcomponent_set_dtstart (component, icaltime);
- ecal_test_utils_cal_component_set_icalcomponent (e_component,
- component);
+ ecal_test_utils_cal_component_set_icalcomponent (e_component, component);
ecal_test_utils_cal_modify_object (cal, component, CALOBJ_MOD_ALL);
/* verify */
- component_final = ecal_test_utils_cal_get_object (cal, uid);
- e_component_final = e_cal_component_new ();
- ecal_test_utils_cal_component_set_icalcomponent (e_component_final,
- component_final);
+ verify (cal, e_component, uid);
- ecal_test_utils_cal_assert_e_cal_components_equal (e_component,
- e_component_final);
+ g_free (uid);
+ icalcomponent_free (component);
- /* Clean-up */
- ecal_test_utils_cal_remove (cal);
+ /*
+ * Async Version
+ */
+ ecal_test_utils_create_component (cal, INITIAL_BEGIN_TIME,
+ INITIAL_BEGIN_TIMEZONE, INITIAL_END_TIME,
+ INITIAL_END_TIMEZONE, EVENT_SUMMARY, &e_component, &uid);
+ component = e_cal_component_get_icalcomponent (e_component);
+
+ component_final = ecal_test_utils_cal_get_object (cal, uid);
+ ecal_test_utils_cal_assert_objects_equal_shallow (component, component_final);
+ icalcomponent_free (component_final);
+
+ /* make and commit changes */
+ icaltime = icaltime_from_string (FINAL_BEGIN_TIME);
+ icalcomponent_set_dtstart (component, icaltime);
+ ecal_test_utils_cal_component_set_icalcomponent (e_component, component);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ data.loop = loop;
+ data.cal = cal;
+ data.e_component = e_component;
+ data.uid = uid;
+
+ e_cal_modify_object_async (cal, component, CALOBJ_MOD_ALL, object_modified_cb, &data);
+
+ g_main_loop_run (loop);
+ g_main_loop_unref (loop);
- g_object_unref (e_component_final);
g_free (uid);
icalcomponent_free (component);
+ /* Clean-up */
+ ecal_test_utils_cal_remove (cal);
+
return 0;
}
diff --git a/calendar/tests/ecal/test-ecal-remove-object.c b/calendar/tests/ecal/test-ecal-remove-object.c
index 1bc9e1c..75ded85 100644
--- a/calendar/tests/ecal/test-ecal-remove-object.c
+++ b/calendar/tests/ecal/test-ecal-remove-object.c
@@ -6,6 +6,19 @@
#include "ecal-test-utils.h"
+static void
+object_removed_cb (ECal *cal, const GError *error, gpointer user_data)
+{
+ GMainLoop *loop = (GMainLoop *)user_data;
+
+ if (error)
+ g_error ("Error removing object: %s", error->message);
+
+ test_print ("e_cal_remove_object_async() passed successfully\n");
+
+ g_main_loop_quit (loop);
+}
+
gint
main (gint argc, gchar **argv)
{
@@ -14,23 +27,49 @@ main (gint argc, gchar **argv)
icalcomponent *component;
icalcomponent *component_final;
gchar *uid;
+ GMainLoop *loop;
g_type_init ();
cal = ecal_test_utils_cal_new_temp (&uri, E_CAL_SOURCE_TYPE_EVENT);
ecal_test_utils_cal_open (cal, FALSE);
+ /*
+ * Sync Version
+ */
component = icalcomponent_new (ICAL_VEVENT_COMPONENT);
uid = ecal_test_utils_cal_create_object (cal, component);
component_final = ecal_test_utils_cal_get_object (cal, uid);
ecal_test_utils_cal_assert_objects_equal_shallow (component, component_final);
ecal_test_utils_cal_remove_object (cal, uid);
- ecal_test_utils_cal_remove (cal);
g_free (uid);
icalcomponent_free (component);
icalcomponent_free (component_final);
+ /*
+ * Async Version
+ */
+ component = icalcomponent_new (ICAL_VEVENT_COMPONENT);
+ uid = ecal_test_utils_cal_create_object (cal, component);
+
+ component_final = ecal_test_utils_cal_get_object (cal, uid);
+ ecal_test_utils_cal_assert_objects_equal_shallow (component, component_final);
+
+ loop = g_main_loop_new (NULL, FALSE);
+ e_cal_remove_object_async (cal, uid, object_removed_cb, loop);
+
+ g_main_loop_run (loop);
+
+ g_free (uid);
+ icalcomponent_free (component);
+ icalcomponent_free (component_final);
+
+ /* Cleanup */
+ ecal_test_utils_cal_remove (cal);
+
+ g_main_loop_unref (loop);
+
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]