[evolution-ews] Add cursor support to addressbook
- From: David Woodhouse <dwmw2 src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-ews] Add cursor support to addressbook
- Date: Wed, 10 Sep 2014 15:20:32 +0000 (UTC)
commit e11b4b8e34ef4650352e7a278fc82230a8d6112a
Author: David Woodhouse <David Woodhouse intel com>
Date: Tue Sep 2 16:15:47 2014 +0100
Add cursor support to addressbook
src/addressbook/e-book-backend-ews.c | 156 ++++++++++++++++++++++++++++++++--
1 files changed, 148 insertions(+), 8 deletions(-)
---
diff --git a/src/addressbook/e-book-backend-ews.c b/src/addressbook/e-book-backend-ews.c
index 4b4f065..442def5 100644
--- a/src/addressbook/e-book-backend-ews.c
+++ b/src/addressbook/e-book-backend-ews.c
@@ -63,6 +63,9 @@ static gboolean
ebews_fetch_items (EBookBackendEws *ebews, GSList *items, GSList **contacts,
GCancellable *cancellable, GError **error);
+static void cursors_contact_added (EBookBackendEws *bf, EContact *contact);
+static void cursors_contact_removed (EBookBackendEws *bf, EContact *contact);
+
typedef struct {
GCond cond;
GMutex mutex;
@@ -98,6 +101,8 @@ struct _EBookBackendEwsPrivate {
guint rev_counter;
gchar *locale;
+
+ GList *cursors;
};
/* using this for backward compatibility with E_DATA_BOOK_MODE */
@@ -1389,6 +1394,7 @@ ews_create_contact_cb (GObject *object,
contacts = g_slist_append (NULL, create_contact->contact);
e_data_book_respond_create_contacts (create_contact->book, create_contact->opid,
EDB_ERROR (SUCCESS), contacts);
g_slist_free (contacts);
+ cursors_contact_added (ebews, create_contact->contact);
}
/*
@@ -1532,6 +1538,7 @@ ews_book_remove_contact_cb (GObject *object,
EBookBackendEws *ebews = remove_contact->ebews;
EBookBackendEwsPrivate *priv = ebews->priv;
GSimpleAsyncResult *simple;
+ GSList *l, *contacts = NULL;
GError *error = NULL;
simple = G_SIMPLE_ASYNC_RESULT (res);
@@ -1540,6 +1547,13 @@ ews_book_remove_contact_cb (GObject *object,
if (!g_simple_async_result_propagate_error (simple, &error) &&
e_book_sqlite_lock (priv->summary, EBSQL_LOCK_WRITE, remove_contact->cancellable, &error)) {
+ /* Wtf? Do we really have to fetch deleted contacts in full, just to tell the cursors? */
+ for (l = remove_contact->sl_ids; l != NULL; l = g_slist_next (l)) {
+ EContact *contact = NULL;
+ e_book_sqlite_get_contact (priv->summary, l->data, FALSE, &contact, NULL);
+ if (contact)
+ contacts = g_slist_prepend (contacts, contact);
+ }
if (e_book_sqlite_remove_contacts (priv->summary, remove_contact->sl_ids,
remove_contact->cancellable, &error) &&
ebews_bump_revision (ebews, &error))
e_book_sqlite_unlock (priv->summary, EBSQL_UNLOCK_COMMIT, &error);
@@ -1547,14 +1561,17 @@ ews_book_remove_contact_cb (GObject *object,
e_book_sqlite_unlock (priv->summary, EBSQL_UNLOCK_ROLLBACK, NULL);
}
- if (error == NULL)
+ if (error == NULL) {
e_data_book_respond_remove_contacts (remove_contact->book, remove_contact->opid, EDB_ERROR
(SUCCESS), remove_contact->sl_ids);
- else {
+ for (l = contacts; l != NULL; l = g_slist_next (l))
+ cursors_contact_removed (ebews, E_CONTACT (l->data));
+ } else {
e_data_book_respond_remove_contacts (remove_contact->book, remove_contact->opid, EDB_ERROR_EX
(OTHER_ERROR, error->message), NULL);
g_warning ("\nError removing contact %s \n", error->message);
}
+ g_slist_free_full (contacts, g_object_unref);
g_slist_free_full (remove_contact->sl_ids, g_free);
g_object_unref (remove_contact->ebews);
g_object_unref (remove_contact->book);
@@ -1681,6 +1698,8 @@ ews_modify_contact_cb (GObject *object,
new_contacts = g_slist_append (NULL, modify_contact->new_contact);
e_data_book_respond_modify_contacts (modify_contact->book, modify_contact->opid,
EDB_ERROR (SUCCESS), new_contacts);
g_slist_free (new_contacts);
+ cursors_contact_removed (ebews, modify_contact->old_contact);
+ cursors_contact_added (ebews, modify_contact->new_contact);
}
g_slist_free (items);
@@ -2462,8 +2481,10 @@ ews_gal_store_contact (EContact *contact,
TRUE, data->cancellable, error) &&
ebews_bump_revision (data->cbews, error)) {
if (e_book_sqlite_unlock (priv->summary, EBSQL_UNLOCK_COMMIT, error)) {
- for (l = data->contact_collector; l != NULL; l = g_slist_next (l))
+ for (l = data->contact_collector; l != NULL; l = g_slist_next (l)) {
e_book_backend_notify_update (E_BOOK_BACKEND (data->cbews),
E_CONTACT (l->data));
+ cursors_contact_added (data->cbews, E_CONTACT (l->data));
+ }
}
} else
e_book_sqlite_unlock (priv->summary, EBSQL_UNLOCK_ROLLBACK, NULL);
@@ -2575,9 +2596,18 @@ ews_replace_gal_in_db (EBookBackendEws *cbews,
d (g_print ("GAL removing %d contacts\n", g_slist_length (stale_uids)));
/* Remove attachments. This will be easier once we add cursor support. */
+ // XXX: Tell cursors
if (!e_book_sqlite_lock (priv->summary, EBSQL_LOCK_WRITE, cancellable, error))
ret = FALSE;
else {
+ GSList *contacts = NULL, *l;
+ /* Wtf? Do we really have to fetch deleted contacts in full, just to tell the cursors? */
+ for (l = stale_uids; l != NULL; l = g_slist_next (l)) {
+ EContact *contact = NULL;
+ e_book_sqlite_get_contact (priv->summary, l->data, FALSE, &contact, NULL);
+ if (contact)
+ contacts = g_slist_prepend (contacts, contact);
+ }
if ((stale_uids && !e_book_sqlite_remove_contacts (priv->summary, stale_uids, cancellable,
error)) ||
!ebews_bump_revision (cbews, error) ||
!e_book_sqlite_set_key_value_int (priv->summary, E_BOOK_SQL_IS_POPULATED_KEY, TRUE,
error)) {
@@ -2585,7 +2615,11 @@ ews_replace_gal_in_db (EBookBackendEws *cbews,
e_book_sqlite_unlock (priv->summary, EBSQL_UNLOCK_ROLLBACK, NULL);
} else {
ret = e_book_sqlite_unlock (priv->summary, EBSQL_UNLOCK_COMMIT, error);
+ if (ret)
+ for (l = contacts; l != NULL; l = g_slist_next (l))
+ cursors_contact_removed (cbews, E_CONTACT (l->data));
}
+ g_slist_free_full (contacts, g_object_unref);
}
t2 = g_get_monotonic_time ();
@@ -2794,14 +2828,17 @@ ebews_sync_deleted_items (EBookBackendEws *ebews,
for (l = *deleted_ids; l != NULL; l = g_slist_next (l)) {
gchar *id = (gchar *) l->data;
- gboolean exists = FALSE;
-
- if (e_book_sqlite_has_contact (priv->summary, id, &exists, NULL) && exists) {
+ EContact *contact = NULL;
- if (e_book_sqlite_remove_contact (priv->summary, id, cancellable, error))
+ if (e_book_sqlite_get_contact (priv->summary, id, FALSE, &contact, NULL)) {
+ if (e_book_sqlite_remove_contact (priv->summary, id, cancellable, error)) {
+ cursors_contact_removed (ebews, contact);
+ g_object_unref (contact);
e_book_backend_notify_remove (E_BOOK_BACKEND (ebews), id);
- else
+ } else {
+ g_object_unref (contact);
return FALSE;
+ }
}
}
@@ -4076,6 +4113,11 @@ e_book_backend_ews_dispose (GObject *object)
priv->summary = NULL;
}
+ if (priv->cursors) {
+ g_list_free_full (priv->cursors, g_object_unref);
+ priv->cursors = NULL;
+ }
+
g_free (priv->locale);
priv->locale = NULL;
@@ -4159,6 +4201,92 @@ book_backend_ews_try_password_sync (ESourceAuthenticator *authenticator,
return result;
}
+
+static void
+cursors_contact_added (EBookBackendEws *ebews,
+ EContact *contact)
+{
+ GList *l;
+
+ for (l = ebews->priv->cursors; l; l = l->next) {
+ EDataBookCursor *cursor = l->data;
+
+ e_data_book_cursor_contact_added (cursor, contact);
+ }
+}
+
+static void
+cursors_contact_removed (EBookBackendEws *ebews,
+ EContact *contact)
+{
+ GList *l;
+
+ for (l = ebews->priv->cursors; l; l = l->next) {
+ EDataBookCursor *cursor = l->data;
+
+ e_data_book_cursor_contact_removed (cursor, contact);
+ }
+}
+
+static EDataBookCursor *
+e_book_backend_ews_create_cursor (EBookBackend *backend,
+ EContactField *sort_fields,
+ EBookCursorSortType *sort_types,
+ guint n_fields,
+ GError **error)
+{
+ EBookBackendEws *ebews = E_BOOK_BACKEND_EWS (backend);
+ EDataBookCursor *cursor;
+
+ PRIV_LOCK (ebews->priv);
+
+ cursor = e_data_book_cursor_sqlite_new (
+ backend,
+ ebews->priv->summary,
+ "revision",
+ sort_fields,
+ sort_types,
+ n_fields,
+ error);
+
+ if (cursor != NULL) {
+ ebews->priv->cursors =
+ g_list_prepend (ebews->priv->cursors, cursor);
+ }
+
+ PRIV_UNLOCK (ebews->priv);
+
+ return cursor;
+}
+
+static gboolean
+e_book_backend_ews_delete_cursor (EBookBackend *backend,
+ EDataBookCursor *cursor,
+ GError **error)
+{
+ EBookBackendEws *ebews = E_BOOK_BACKEND_EWS (backend);
+ GList *link;
+
+ PRIV_LOCK (ebews->priv);
+
+ link = g_list_find (ebews->priv->cursors, cursor);
+
+ if (link != NULL) {
+ ebews->priv->cursors = g_list_delete_link (ebews->priv->cursors, link);
+ g_object_unref (cursor);
+ } else {
+ g_set_error_literal (
+ error,
+ E_CLIENT_ERROR,
+ E_CLIENT_ERROR_INVALID_ARG,
+ _("Requested to delete an unrelated cursor"));
+ }
+
+ PRIV_UNLOCK (ebews->priv);
+
+ return link != NULL;
+}
+
static gboolean
e_book_backend_ews_set_locale (EBookBackend *backend,
const gchar *locale,
@@ -4167,6 +4295,7 @@ e_book_backend_ews_set_locale (EBookBackend *backend,
{
EBookBackendEws *ebews = E_BOOK_BACKEND_EWS (backend);
gboolean success = FALSE;
+ GList *l;
PRIV_LOCK (ebews->priv);
@@ -4184,6 +4313,15 @@ e_book_backend_ews_set_locale (EBookBackend *backend,
ebews->priv->locale = g_strdup (locale);
}
+ /* This must be done outside the EBookSqlite lock,
+ * as it may try to acquire the lock as well. */
+ for (l = ebews->priv->cursors; success && l; l = l->next) {
+ EDataBookCursor *cursor = l->data;
+
+ success = e_data_book_cursor_load_locale (
+ cursor, NULL, cancellable, error);
+ }
+
PRIV_LOCK (ebews->priv);
return success;
@@ -4227,6 +4365,8 @@ e_book_backend_ews_class_init (EBookBackendEwsClass *klass)
parent_class->get_contact_list = e_book_backend_ews_get_contact_list;
parent_class->start_view = e_book_backend_ews_start_view;
parent_class->stop_view = e_book_backend_ews_stop_view;
+ parent_class->create_cursor = e_book_backend_ews_create_cursor;
+ parent_class->delete_cursor = e_book_backend_ews_delete_cursor;
parent_class->set_locale = e_book_backend_ews_set_locale;
parent_class->dup_locale = e_book_backend_ews_dup_locale;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]