[evolution-data-server] I#49 - [CardDAV] Local cache made broken after update
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] I#49 - [CardDAV] Local cache made broken after update
- Date: Tue, 23 Oct 2018 09:57:13 +0000 (UTC)
commit 66966a2f6a73b77556e907774e5a41bd369c47c1
Author: Milan Crha <mcrha redhat com>
Date: Tue Oct 23 11:57:34 2018 +0200
I#49 - [CardDAV] Local cache made broken after update
Closes https://gitlab.gnome.org/GNOME/evolution-data-server/issues/49
.../backends/carddav/e-book-backend-carddav.c | 3 ++
src/addressbook/libedata-book/e-book-cache.c | 1 +
.../backends/caldav/e-cal-backend-caldav.c | 3 ++
src/libebackend/e-cache.c | 58 +++++++++++++++++++++-
src/libebackend/e-cache.h | 6 +++
5 files changed, 69 insertions(+), 2 deletions(-)
---
diff --git a/src/addressbook/backends/carddav/e-book-backend-carddav.c
b/src/addressbook/backends/carddav/e-book-backend-carddav.c
index b2afae39a..60a824b74 100644
--- a/src/addressbook/backends/carddav/e-book-backend-carddav.c
+++ b/src/addressbook/backends/carddav/e-book-backend-carddav.c
@@ -1142,6 +1142,9 @@ ebb_carddav_save_contact_sync (EBookMetaBackend *meta_backend,
}
g_free (new_etag);
+ } else if (uid && vcard_string) {
+ success = FALSE;
+ g_propagate_error (error, EDB_ERROR_EX (E_DATA_BOOK_STATUS_OTHER_ERROR, _("Missing
information about vCard URL, local cache is possibly incomplete or broken. Remove it, please.")));
} else {
success = FALSE;
g_propagate_error (error, EDB_ERROR_EX (E_DATA_BOOK_STATUS_OTHER_ERROR, _("Object to save is
not a valid vCard")));
diff --git a/src/addressbook/libedata-book/e-book-cache.c b/src/addressbook/libedata-book/e-book-cache.c
index 1401d8f40..515d990a1 100644
--- a/src/addressbook/libedata-book/e-book-cache.c
+++ b/src/addressbook/libedata-book/e-book-cache.c
@@ -4260,6 +4260,7 @@ e_book_cache_fill_pgp_cert_column (ECache *cache,
e_cache_column_values_take_value (*out_other_columns, e_contact_field_name (E_CONTACT_PGP_CERT),
g_strdup_printf ("%d", cert ? 1 : 0));
e_contact_cert_free (cert);
+ g_object_unref (contact);
return TRUE;
}
diff --git a/src/calendar/backends/caldav/e-cal-backend-caldav.c
b/src/calendar/backends/caldav/e-cal-backend-caldav.c
index ca80748a9..24c9dd560 100644
--- a/src/calendar/backends/caldav/e-cal-backend-caldav.c
+++ b/src/calendar/backends/caldav/e-cal-backend-caldav.c
@@ -1315,6 +1315,9 @@ ecb_caldav_save_component_sync (ECalMetaBackend *meta_backend,
}
g_free (new_etag);
+ } else if (uid && ical_string) {
+ success = FALSE;
+ g_propagate_error (error, EDC_ERROR_EX (InvalidObject, _("Missing information about component
URL, local cache is possibly incomplete or broken. Remove it, please.")));
} else {
success = FALSE;
g_propagate_error (error, EDC_ERROR (InvalidObject));
diff --git a/src/libebackend/e-cache.c b/src/libebackend/e-cache.c
index 0b2edd584..cfc13b0ec 100644
--- a/src/libebackend/e-cache.c
+++ b/src/libebackend/e-cache.c
@@ -2111,7 +2111,7 @@ e_cache_foreach_update_cb (ECache *cache,
rd->revision = g_strdup (column_values[fu->revision_index]);
rd->object = g_strdup (column_values[fu->object_index]);
rd->offline_state = offline_state;
- rd->ncols = ncols;
+ rd->ncols = cvalues->len;
rd->column_values = cvalues;
if (cnames)
@@ -2119,7 +2119,7 @@ e_cache_foreach_update_cb (ECache *cache,
fu->rows = g_slist_prepend (fu->rows, rd);
- g_return_val_if_fail (fu->column_names && (gint) fu->column_names->len != ncols, FALSE);
+ g_return_val_if_fail (fu->column_names && (gint) fu->column_names->len == rd->ncols, FALSE);
return TRUE;
}
@@ -2140,6 +2140,10 @@ e_cache_foreach_update_cb (ECache *cache,
* was successful, not whether there are any changes to be saved. If anything
* fails during the call then the all changes are reverted.
*
+ * When there are requested any changes by the @func, this function also
+ * calls e_cache_copy_missing_to_column_values() to ensure no descendant
+ * column data is lost.
+ *
* Returns: Whether succeeded.
*
* Since: 3.26
@@ -2235,6 +2239,14 @@ e_cache_foreach_update (ECache *cache,
(new_object && g_strcmp0 (new_object, fr->object) != 0) ||
(new_offline_state != fr->offline_state) ||
(new_other_columns && e_cache_column_values_get_size
(new_other_columns) > 0))) {
+ if (!new_other_columns)
+ new_other_columns = e_cache_column_values_new ();
+
+ e_cache_copy_missing_to_column_values (cache, fr->ncols,
+ (const gchar **) fu.column_names->pdata,
+ (const gchar **) fr->column_values->pdata,
+ new_other_columns);
+
success = e_cache_put_locked (cache,
fr->uid,
new_revision ? new_revision : fr->revision,
@@ -2269,6 +2281,48 @@ e_cache_foreach_update (ECache *cache,
return success;
}
+/**
+ * e_cache_copy_missing_to_column_values:
+ * @cache: an #ECache
+ * @ncols: count of columns, items in column_names and column_values
+ * @column_names: column names
+ * @column_values: column values
+ * @other_columns: (in out): an #ECacheColumnValues to fill
+ *
+ * Adds every column value which is not part of the @other_columns to it,
+ * except of E_CACHE_COLUMN_UID, E_CACHE_COLUMN_REVISION, E_CACHE_COLUMN_OBJECT
+ * and E_CACHE_COLUMN_STATE columns.
+ *
+ * This can be used within the callback of e_cache_foreach_update().
+ *
+ * Since: 3.32
+ **/
+void
+e_cache_copy_missing_to_column_values (ECache *cache,
+ gint ncols,
+ const gchar *column_names[],
+ const gchar *column_values[],
+ ECacheColumnValues *other_columns)
+{
+ gint ii;
+
+ g_return_if_fail (E_IS_CACHE (cache));
+ g_return_if_fail (column_names != NULL);
+ g_return_if_fail (column_values != NULL);
+ g_return_if_fail (other_columns != NULL);
+
+ for (ii = 0; ii < ncols; ii++) {
+ if (column_names[ii] && column_values[ii] &&
+ !e_cache_column_values_contains (other_columns, column_names[ii]) &&
+ g_ascii_strcasecmp (column_names[ii], E_CACHE_COLUMN_UID) != 0 &&
+ g_ascii_strcasecmp (column_names[ii], E_CACHE_COLUMN_REVISION) != 0 &&
+ g_ascii_strcasecmp (column_names[ii], E_CACHE_COLUMN_OBJECT) != 0 &&
+ g_ascii_strcasecmp (column_names[ii], E_CACHE_COLUMN_STATE) != 0) {
+ e_cache_column_values_put (other_columns, column_names[ii], column_values[ii]);
+ }
+ }
+}
+
/**
* e_cache_get_offline_state:
* @cache: an #ECache
diff --git a/src/libebackend/e-cache.h b/src/libebackend/e-cache.h
index 3ff428a72..3230cdec5 100644
--- a/src/libebackend/e-cache.h
+++ b/src/libebackend/e-cache.h
@@ -462,6 +462,12 @@ gboolean e_cache_foreach_update (ECache *cache,
gpointer user_data,
GCancellable *cancellable,
GError **error);
+void e_cache_copy_missing_to_column_values
+ (ECache *cache,
+ gint ncols,
+ const gchar *column_names[],
+ const gchar *column_values[],
+ ECacheColumnValues *other_columns);
/* Offline support */
EOfflineState e_cache_get_offline_state (ECache *cache,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]