[evolution-data-server] I#136 - Meta backends: Fails to remove locally created object in online mode
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#136 - Meta backends: Fails to remove locally created object in online mode
- Date: Wed, 21 Aug 2019 13:58:21 +0000 (UTC)
commit 4c674a581a2876b0b16b38760771a23353e5a721
Author: Milan Crha <mcrha redhat com>
Date: Wed Aug 21 15:56:42 2019 +0200
I#136 - Meta backends: Fails to remove locally created object in online mode
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/136
.../libedata-book/e-book-meta-backend.c | 3 +-
src/calendar/libedata-cal/e-cal-cache.c | 44 +++++++++
src/calendar/libedata-cal/e-cal-cache.h | 5 +
src/calendar/libedata-cal/e-cal-meta-backend.c | 3 +-
tests/libedata-book/test-book-meta-backend.c | 87 +++++++++++++++++
tests/libedata-cal/test-cal-meta-backend.c | 105 +++++++++++++++++++++
6 files changed, 245 insertions(+), 2 deletions(-)
---
diff --git a/src/addressbook/libedata-book/e-book-meta-backend.c
b/src/addressbook/libedata-book/e-book-meta-backend.c
index e3677dae1..3307d6a5f 100644
--- a/src/addressbook/libedata-book/e-book-meta-backend.c
+++ b/src/addressbook/libedata-book/e-book-meta-backend.c
@@ -1624,7 +1624,8 @@ ebmb_remove_contact_sync (EBookMetaBackend *meta_backend,
if (!e_book_cache_get_contact_extra (book_cache, uid, &extra, cancellable, NULL))
extra = NULL;
- if (*offline_flag == E_CACHE_IS_ONLINE) {
+ if (*offline_flag == E_CACHE_IS_ONLINE &&
+ e_cache_get_offline_state (E_CACHE (book_cache), uid, cancellable, NULL) !=
E_OFFLINE_STATE_LOCALLY_CREATED) {
gchar *vcard_string = NULL;
g_warn_if_fail (e_book_cache_get_vcard (book_cache, uid, FALSE, &vcard_string, cancellable,
NULL));
diff --git a/src/calendar/libedata-cal/e-cal-cache.c b/src/calendar/libedata-cal/e-cal-cache.c
index 85e040e51..d853294f3 100644
--- a/src/calendar/libedata-cal/e-cal-cache.c
+++ b/src/calendar/libedata-cal/e-cal-cache.c
@@ -3582,6 +3582,50 @@ e_cal_cache_get_offline_changes (ECalCache *cal_cache,
return changes;
}
+/**
+ * e_cal_cache_get_offline_state:
+ * @cal_cache: an #ECalCache
+ * @uid: a UID of the component
+ * @rid: (nullable): an optional Recurrence-ID
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * This is a wrapper of e_cache_get_offline_state(), ensuring that
+ * a correct #ECache UID will be used.
+ *
+ * Returns: Current offline state #EOfflineState for the given component.
+ * It returns %E_OFFLINE_STATE_UNKNOWN when the component could not be
+ * found or other error happened.
+ *
+ * Since: 3.34
+ **/
+EOfflineState
+e_cal_cache_get_offline_state (ECalCache *cal_cache,
+ const gchar *uid,
+ const gchar *rid,
+ GCancellable *cancellable,
+ GError **error)
+{
+ EOfflineState res;
+
+ g_return_val_if_fail (E_IS_CAL_CACHE (cal_cache), E_OFFLINE_STATE_UNKNOWN);
+ g_return_val_if_fail (uid != NULL, E_OFFLINE_STATE_UNKNOWN);
+
+ if (rid && *rid) {
+ gchar *id;
+
+ id = ecc_encode_id_sql (uid, rid);
+
+ res = e_cache_get_offline_state (E_CACHE (cal_cache), id, cancellable, error);
+
+ g_free (id);
+ } else {
+ res = e_cache_get_offline_state (E_CACHE (cal_cache), uid, cancellable, error);
+ }
+
+ return res;
+}
+
/**
* e_cal_cache_delete_attachments:
* @cal_cache: an #ECalCache
diff --git a/src/calendar/libedata-cal/e-cal-cache.h b/src/calendar/libedata-cal/e-cal-cache.h
index 4e3ca2668..f9fc3641a 100644
--- a/src/calendar/libedata-cal/e-cal-cache.h
+++ b/src/calendar/libedata-cal/e-cal-cache.h
@@ -319,6 +319,11 @@ gboolean e_cal_cache_search_with_callback
gpointer user_data,
GCancellable *cancellable,
GError **error);
+EOfflineState e_cal_cache_get_offline_state (ECalCache *cal_cache,
+ const gchar *uid,
+ const gchar *rid,
+ GCancellable *cancellable,
+ GError **error);
GSList * e_cal_cache_get_offline_changes (ECalCache *cal_cache,
GCancellable *cancellable,
GError **error);
diff --git a/src/calendar/libedata-cal/e-cal-meta-backend.c b/src/calendar/libedata-cal/e-cal-meta-backend.c
index 0e48f7825..68c57ecaa 100644
--- a/src/calendar/libedata-cal/e-cal-meta-backend.c
+++ b/src/calendar/libedata-cal/e-cal-meta-backend.c
@@ -2257,7 +2257,8 @@ ecmb_remove_object_sync (ECalMetaBackend *meta_backend,
extra = NULL;
if (mod == E_CAL_OBJ_MOD_ALL) {
- if (*offline_flag == E_CACHE_IS_ONLINE) {
+ if (*offline_flag == E_CACHE_IS_ONLINE &&
+ e_cal_cache_get_offline_state (cal_cache, uid, NULL, cancellable, NULL) !=
E_OFFLINE_STATE_LOCALLY_CREATED) {
gchar *ical_string = NULL;
/* Use the master object, if exists */
diff --git a/tests/libedata-book/test-book-meta-backend.c b/tests/libedata-book/test-book-meta-backend.c
index b288bf75e..7419e2cd6 100644
--- a/tests/libedata-book/test-book-meta-backend.c
+++ b/tests/libedata-book/test-book-meta-backend.c
@@ -1143,6 +1143,7 @@ test_remove_contacts (EBookMetaBackend *meta_backend)
EBookMetaBackendTest *test_backend;
EBookBackendSyncClass *backend_sync_class;
EBookCache *book_cache;
+ EOfflineState state;
const gchar *uids[2] = { NULL, NULL };
GSList *offline_changes;
GSList *removed_uids = NULL;
@@ -1235,6 +1236,92 @@ test_remove_contacts (EBookMetaBackend *meta_backend)
g_assert_no_error (error);
g_assert_cmpint (0, ==, g_slist_length (offline_changes));
+ /* Set a contact as being created in offline */
+ uids[0] = "custom-2";
+
+ success = e_cache_set_offline_state (E_CACHE (book_cache), uids[0], E_OFFLINE_STATE_LOCALLY_CREATED,
NULL, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ state = e_cache_get_offline_state (E_CACHE (book_cache), uids[0], NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (state, ==, E_OFFLINE_STATE_LOCALLY_CREATED);
+
+ success = backend_sync_class->remove_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
+ (const gchar * const *) uids, E_BOOK_OPERATION_FLAG_NONE, &removed_uids, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert_cmpint (test_backend->load_count, ==, 0);
+ g_assert_cmpint (test_backend->save_count, ==, 0);
+ g_assert_cmpint (test_backend->remove_count, ==, 1);
+ g_assert_cmpint (g_slist_length (removed_uids), ==, 1);
+ g_assert_cmpstr (removed_uids->data, ==, uids[0]);
+ g_slist_free_full (removed_uids, g_free);
+ removed_uids = NULL;
+
+ ebmb_test_hash_contains (test_backend->contacts, FALSE, FALSE,
+ uids[0], NULL,
+ NULL);
+ ebmb_test_cache_contains (book_cache, TRUE, FALSE,
+ uids[0], NULL,
+ NULL);
+
+ /* Set a contact as being modified in offline */
+ uids[0] = "custom-5";
+
+ success = e_cache_set_offline_state (E_CACHE (book_cache), uids[0], E_OFFLINE_STATE_LOCALLY_MODIFIED,
NULL, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ state = e_cache_get_offline_state (E_CACHE (book_cache), uids[0], NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (state, ==, E_OFFLINE_STATE_LOCALLY_MODIFIED);
+
+ success = backend_sync_class->remove_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
+ (const gchar * const *) uids, E_BOOK_OPERATION_FLAG_NONE, &removed_uids, NULL, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ g_assert_cmpint (test_backend->load_count, ==, 0);
+ g_assert_cmpint (test_backend->save_count, ==, 0);
+ g_assert_cmpint (test_backend->remove_count, ==, 2);
+ g_assert_cmpint (g_slist_length (removed_uids), ==, 1);
+ g_assert_cmpstr (removed_uids->data, ==, uids[0]);
+ g_slist_free_full (removed_uids, g_free);
+ removed_uids = NULL;
+
+ ebmb_test_hash_contains (test_backend->contacts, TRUE, FALSE,
+ uids[0], NULL,
+ NULL);
+ ebmb_test_cache_contains (book_cache, TRUE, FALSE,
+ uids[0], NULL,
+ NULL);
+
+ /* Set a contact as being deleted in offline */
+ uids[0] = "custom-6";
+
+ success = e_cache_set_offline_state (E_CACHE (book_cache), uids[0], E_OFFLINE_STATE_LOCALLY_DELETED,
NULL, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ state = e_cache_get_offline_state (E_CACHE (book_cache), uids[0], NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (state, ==, E_OFFLINE_STATE_LOCALLY_DELETED);
+
+ success = backend_sync_class->remove_contacts_sync (E_BOOK_BACKEND_SYNC (meta_backend),
+ (const gchar * const *) uids, E_BOOK_OPERATION_FLAG_NONE, &removed_uids, NULL, &error);
+ g_assert_error (error, E_BOOK_CLIENT_ERROR, E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND);
+ g_assert (!success);
+ g_assert_null (removed_uids);
+ g_clear_error (&error);
+
+ g_assert_cmpint (test_backend->load_count, ==, 0);
+ g_assert_cmpint (test_backend->save_count, ==, 0);
+ g_assert_cmpint (test_backend->remove_count, ==, 2);
+
+ ebmb_test_hash_contains (test_backend->contacts, FALSE, FALSE,
+ uids[0], NULL,
+ NULL);
+ ebmb_test_cache_contains (book_cache, TRUE, FALSE,
+ uids[0], NULL,
+ NULL);
+
g_object_unref (book_cache);
}
diff --git a/tests/libedata-cal/test-cal-meta-backend.c b/tests/libedata-cal/test-cal-meta-backend.c
index 327898188..a2637a37c 100644
--- a/tests/libedata-cal/test-cal-meta-backend.c
+++ b/tests/libedata-cal/test-cal-meta-backend.c
@@ -2257,7 +2257,10 @@ test_remove_objects (ECalMetaBackend *meta_backend)
ECalMetaBackendTest *test_backend;
ECalBackendSyncClass *backend_class;
ECalCache *cal_cache;
+ EOfflineState state;
GSList *ids, *old_components = NULL, *new_components = NULL, *offline_changes;
+ const gchar *uid;
+ gboolean success;
GError *error = NULL;
g_assert_nonnull (meta_backend);
@@ -2428,6 +2431,108 @@ test_remove_objects (ECalMetaBackend *meta_backend)
g_assert_no_error (error);
g_assert_cmpint (0, ==, g_slist_length (offline_changes));
+ /* Set an event as being created in offline */
+ uid = "event-7";
+ ids = g_slist_prepend (NULL, e_cal_component_id_new (uid, NULL));
+
+ success = e_cache_set_offline_state (E_CACHE (cal_cache), uid, E_OFFLINE_STATE_LOCALLY_CREATED, NULL,
&error);
+ g_assert_no_error (error);
+ g_assert (success);
+ state = e_cal_cache_get_offline_state (cal_cache, uid, NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (state, ==, E_OFFLINE_STATE_LOCALLY_CREATED);
+
+ backend_class->remove_objects_sync (E_CAL_BACKEND_SYNC (meta_backend),
+ NULL, NULL, ids, E_CAL_OBJ_MOD_ALL, 0, &old_components, &new_components, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (g_slist_length (old_components), ==, 1);
+ g_assert_cmpint (g_slist_length (new_components), ==, 1);
+ g_assert_null (new_components->data);
+ g_assert_cmpint (test_backend->load_count, ==, 0);
+ g_assert_cmpint (test_backend->save_count, ==, 0);
+ g_assert_cmpint (test_backend->remove_count, ==, 1);
+
+ ecmb_test_vcalendar_contains (test_backend->vcalendar, FALSE, FALSE,
+ uid, NULL,
+ NULL);
+ ecmb_test_cache_contains (cal_cache, TRUE, FALSE,
+ uid, NULL,
+ NULL);
+
+ g_slist_free_full (old_components, g_object_unref);
+ g_slist_free (new_components);
+ g_slist_free_full (ids, e_cal_component_id_free);
+ old_components = NULL;
+ new_components = NULL;
+
+ /* Set an event as being modified in offline */
+ uid = "event-8";
+ ids = g_slist_prepend (NULL, e_cal_component_id_new (uid, NULL));
+
+ success = e_cache_set_offline_state (E_CACHE (cal_cache), uid, E_OFFLINE_STATE_LOCALLY_MODIFIED,
NULL, &error);
+ g_assert_no_error (error);
+ g_assert (success);
+ state = e_cal_cache_get_offline_state (cal_cache, uid, NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (state, ==, E_OFFLINE_STATE_LOCALLY_MODIFIED);
+
+ backend_class->remove_objects_sync (E_CAL_BACKEND_SYNC (meta_backend),
+ NULL, NULL, ids, E_CAL_OBJ_MOD_ALL, 0, &old_components, &new_components, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (g_slist_length (old_components), ==, 1);
+ g_assert_cmpint (g_slist_length (new_components), ==, 1);
+ g_assert_null (new_components->data);
+ g_assert_cmpint (test_backend->load_count, ==, 0);
+ g_assert_cmpint (test_backend->save_count, ==, 0);
+ g_assert_cmpint (test_backend->remove_count, ==, 2);
+
+ ecmb_test_vcalendar_contains (test_backend->vcalendar, TRUE, FALSE,
+ uid, NULL,
+ NULL);
+ ecmb_test_cache_contains (cal_cache, TRUE, FALSE,
+ uid, NULL,
+ NULL);
+
+ g_slist_free_full (old_components, g_object_unref);
+ g_slist_free (new_components);
+ g_slist_free_full (ids, e_cal_component_id_free);
+ old_components = NULL;
+ new_components = NULL;
+
+ /* Set an event as being deleted in offline */
+ uid = "event-9";
+ ids = g_slist_prepend (NULL, e_cal_component_id_new (uid, NULL));
+
+ success = e_cache_set_offline_state (E_CACHE (cal_cache), uid, E_OFFLINE_STATE_LOCALLY_DELETED, NULL,
&error);
+ g_assert_no_error (error);
+ g_assert (success);
+ state = e_cal_cache_get_offline_state (cal_cache, uid, NULL, NULL, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (state, ==, E_OFFLINE_STATE_LOCALLY_DELETED);
+
+ backend_class->remove_objects_sync (E_CAL_BACKEND_SYNC (meta_backend),
+ NULL, NULL, ids, E_CAL_OBJ_MOD_ALL, 0, &old_components, &new_components, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (g_slist_length (old_components), ==, 1);
+ g_assert_cmpint (g_slist_length (new_components), ==, 1);
+ g_assert_null (new_components->data);
+ g_assert_cmpint (test_backend->load_count, ==, 0);
+ g_assert_cmpint (test_backend->save_count, ==, 0);
+ g_assert_cmpint (test_backend->remove_count, ==, 3);
+
+ ecmb_test_vcalendar_contains (test_backend->vcalendar, TRUE, FALSE,
+ uid, NULL,
+ NULL);
+ ecmb_test_cache_contains (cal_cache, TRUE, FALSE,
+ uid, NULL,
+ NULL);
+
+ g_slist_free_full (old_components, g_object_unref);
+ g_slist_free (new_components);
+ g_slist_free_full (ids, e_cal_component_id_free);
+ old_components = NULL;
+ new_components = NULL;
+
g_object_unref (cal_cache);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]