[evolution-data-server] EBookBackendFile cleanups.
- From: Matthew Barnes <mbarnes src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] EBookBackendFile cleanups.
- Date: Wed, 3 Apr 2013 20:56:28 +0000 (UTC)
commit fafd0685d2bdb92ddddbcaeb7466796da65f5a20
Author: Matthew Barnes <mbarnes redhat com>
Date: Wed Apr 3 12:41:36 2013 -0400
EBookBackendFile cleanups.
addressbook/backends/file/e-book-backend-file.c | 975 +++++++++++------------
1 files changed, 487 insertions(+), 488 deletions(-)
---
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index 9da18fb..9231ef8 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -787,117 +787,319 @@ do_create (EBookBackendFile *bf,
return (status != STATUS_ERROR);
}
+typedef struct {
+ EBookBackendFile *bf;
+ GThread *thread;
+ EFlag *running;
+} FileBackendSearchClosure;
+
static void
-e_book_backend_file_create_contacts (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- const GSList *vcards,
- GSList **added_contacts,
- GError **perror)
+closure_destroy (FileBackendSearchClosure *closure)
{
- EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
+ d (printf ("destroying search closure\n"));
+ e_flag_free (closure->running);
+ if (closure->thread)
+ g_thread_unref (closure->thread);
+ g_free (closure);
+}
- g_rw_lock_writer_lock (&(bf->priv->lock));
+static FileBackendSearchClosure *
+init_closure (EDataBookView *book_view,
+ EBookBackendFile *bf)
+{
+ FileBackendSearchClosure *closure = g_new (FileBackendSearchClosure, 1);
- if (do_create (bf, vcards, added_contacts, perror)) {
- e_book_backend_file_bump_revision (bf);
- }
+ closure->bf = bf;
+ closure->thread = NULL;
+ closure->running = e_flag_new ();
- g_rw_lock_writer_unlock (&(bf->priv->lock));
+ g_object_set_data_full (
+ G_OBJECT (book_view),
+ "EBookBackendFile.BookView::closure",
+ closure, (GDestroyNotify) closure_destroy);
+
+ return closure;
+}
+
+static FileBackendSearchClosure *
+get_closure (EDataBookView *book_view)
+{
+ return g_object_get_data (
+ G_OBJECT (book_view),
+ "EBookBackendFile.BookView::closure");
}
static void
-e_book_backend_file_remove_contacts (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- const GSList *id_list,
- GSList **ids,
- GError **perror)
+notify_update_vcard (EDataBookView *book_view,
+ gboolean prefiltered,
+ const gchar *id,
+ const gchar *vcard)
{
- EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
- GSList *removed_ids = NULL, *removed_contacts = NULL;
- GError *local_error = NULL;
- gboolean delete_failed = FALSE;
- const GSList *l;
+ if (prefiltered)
+ e_data_book_view_notify_update_prefiltered_vcard (book_view, id, vcard);
+ else
+ e_data_book_view_notify_update_vcard (book_view, id, vcard);
+}
- g_rw_lock_writer_lock (&(bf->priv->lock));
+static gpointer
+book_view_thread (gpointer data)
+{
+ EDataBookView *book_view;
+ FileBackendSearchClosure *closure;
+ EBookBackendFile *bf;
+ EBookBackendSExp *sexp;
+ const gchar *query;
+ GSList *summary_list, *l;
+ GHashTable *fields_of_interest;
+ GError *local_error = NULL;
- for (l = id_list; l != NULL; l = l->next) {
- const gchar *id;
- EContact *contact;
+ g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (data), NULL);
- id = l->data;
+ book_view = data;
+ closure = get_closure (book_view);
+ if (!closure) {
+ g_warning (G_STRLOC ": NULL closure in book view thread");
+ return NULL;
+ }
+ bf = closure->bf;
- /* First load the EContacts which need to be removed, we might delete some
- * photos from disk because of this...
- *
- * Note: sqlitedb backend can probably make this faster by executing a
- * single query to fetch a list of contacts for a list of ids, the
- * current method makes a query for each UID.
- */
- contact = e_book_backend_sqlitedb_get_contact (
- bf->priv->sqlitedb,
- SQLITEDB_FOLDER_ID, id,
- NULL, NULL, &local_error);
+ d (printf ("starting initial population of book view\n"));
- if (contact) {
- removed_ids = g_slist_prepend (removed_ids, g_strdup (id));
- removed_contacts = g_slist_prepend (removed_contacts, contact);
- } else {
- g_warning ("Failed to fetch contact to be removed: %s", local_error->message);
+ /* ref the book view because it'll be removed and unrefed
+ * when/if it's stopped */
+ g_object_ref (book_view);
- if (g_error_matches (local_error,
- E_BOOK_SDB_ERROR,
- E_BOOK_SDB_ERROR_CONTACT_NOT_FOUND)) {
- g_set_error (
- perror, E_BOOK_CLIENT_ERROR,
- E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND,
- _("Contact '%s' not found"), id);
- g_error_free (local_error);
- } else
- g_propagate_error (perror, local_error);
+ sexp = e_data_book_view_get_sexp (book_view);
+ query = e_book_backend_sexp_text (sexp);
- /* Abort as soon as missing contact is to be deleted */
- delete_failed = TRUE;
- break;
- }
+ fields_of_interest = e_data_book_view_get_fields_of_interest (book_view);
+
+ if ( !strcmp (query, "(contains \"x-evolution-any-field\" \"\")")) {
+ e_data_book_view_notify_progress (book_view, -1, _("Loading..."));
+ } else {
+ e_data_book_view_notify_progress (book_view, -1, _("Searching..."));
}
- if (!delete_failed) {
+ d (printf ("signalling parent thread\n"));
+ e_flag_set (closure->running);
- /* Delete URI associated to those contacts */
- for (l = removed_contacts; l; l = l->next) {
- maybe_delete_unused_uris (bf, E_CONTACT (l->data), NULL);
+ g_rw_lock_reader_lock (&(bf->priv->lock));
+ summary_list = e_book_backend_sqlitedb_search (
+ bf->priv->sqlitedb,
+ SQLITEDB_FOLDER_ID,
+ query, fields_of_interest,
+ NULL, NULL, &local_error);
+ g_rw_lock_reader_unlock (&(bf->priv->lock));
+
+ if (!summary_list && local_error != NULL) {
+ g_warning (G_STRLOC ": Failed to query initial contacts: %s", local_error->message);
+ g_error_free (local_error);
+ e_data_book_view_notify_complete (
+ book_view,
+ g_error_new_literal (
+ E_CLIENT_ERROR,
+ E_CLIENT_ERROR_NOT_OPENED,
+ e_client_error_to_string (
+ E_CLIENT_ERROR_NOT_OPENED)));
+ g_object_unref (book_view);
+ return NULL;
+ }
+
+ for (l = summary_list; l; l = l->next) {
+ EbSdbSearchData *data = l->data;
+ gchar *vcard = NULL;
+
+ vcard = data->vcard;
+ data->vcard = NULL;
+
+ notify_update_vcard (book_view, TRUE, data->uid, vcard);
+ g_free (vcard);
+ }
+
+ g_slist_foreach (summary_list, (GFunc) e_book_backend_sqlitedb_search_data_free, NULL);
+ g_slist_free (summary_list);
+
+ if (e_flag_is_set (closure->running))
+ e_data_book_view_notify_complete (book_view, NULL /* Success */);
+
+ g_object_unref (book_view);
+
+ d (printf ("finished population of book view\n"));
+
+ return NULL;
+}
+
+static void
+view_notify_update (EBookBackendFile *backend,
+ EDataBookView *view,
+ EContact *contact)
+{
+ EBookBackendSExp *sexp;
+ GHashTable *fields = e_data_book_view_get_fields_of_interest (view);
+ const gchar *query;
+ gboolean notified = FALSE;
+ gboolean with_all_required_fields = FALSE;
+
+ sexp = e_data_book_view_get_sexp (view);
+ query = e_book_backend_sexp_text (sexp);
+
+ if (e_book_backend_sqlitedb_check_summary_query (backend->priv->sqlitedb, query, NULL) &&
+ e_book_backend_sqlitedb_check_summary_fields (backend->priv->sqlitedb, fields)) {
+
+ const gchar *uid = e_contact_get_const (contact, E_CONTACT_UID);
+ gchar *vcard;
+
+ vcard = e_book_backend_sqlitedb_get_vcard_string (
+ backend->priv->sqlitedb,
+ SQLITEDB_FOLDER_ID, uid,
+ fields, &with_all_required_fields, NULL);
+
+ if (vcard) {
+ if (with_all_required_fields) {
+ e_data_book_view_notify_update_prefiltered_vcard (view, uid, vcard);
+ notified = TRUE;
+ }
+ g_free (vcard);
}
+ }
- /* Remove from summary as well */
- if (!e_book_backend_sqlitedb_remove_contacts (bf->priv->sqlitedb,
- SQLITEDB_FOLDER_ID,
- removed_ids, &local_error)) {
- g_warning ("Failed to remove contacts: %s", local_error->message);
- g_propagate_error (perror, local_error);
+ if (!notified)
+ e_data_book_view_notify_update (view, contact);
+}
+
+static void
+book_backend_file_dispose (GObject *object)
+{
+ EBookBackendFile *bf;
+
+ bf = E_BOOK_BACKEND_FILE (object);
+
+ if (bf->priv->sqlitedb) {
+ g_object_unref (bf->priv->sqlitedb);
+ bf->priv->sqlitedb = NULL;
+ }
+
+ G_OBJECT_CLASS (e_book_backend_file_parent_class)->dispose (object);
+}
+
+static void
+book_backend_file_finalize (GObject *object)
+{
+ EBookBackendFilePrivate *priv;
+
+ priv = E_BOOK_BACKEND_FILE_GET_PRIVATE (object);
+
+ g_free (priv->photo_dirname);
+ g_free (priv->revision);
+ g_free (priv->base_directory);
+ g_rw_lock_clear (&(priv->lock));
+
+ /* Chain up to parent's finalize() method. */
+ G_OBJECT_CLASS (e_book_backend_file_parent_class)->finalize (object);
+}
+
+static gchar *
+book_backend_file_get_backend_property (EBookBackend *backend,
+ const gchar *prop_name)
+{
+ EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
+
+ g_return_val_if_fail (prop_name != NULL, NULL);
+
+ if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
+ return g_strdup ("local,do-initial-query,bulk-adds,bulk-modifies,bulk-removes,contact-lists");
+
+ } else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
+ return g_strdup (e_contact_field_name (E_CONTACT_FILE_AS));
+
+ } else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
+ GString *fields;
+ gint ii;
+
+ fields = g_string_sized_new (1024);
+
+ /* XXX we need a way to say "we support everything", since the
+ * file backend does */
+ for (ii = 1; ii < E_CONTACT_FIELD_LAST; ii++) {
+ if (fields->len > 0)
+ g_string_append_c (fields, ',');
+ g_string_append (fields, e_contact_field_name (ii));
}
- e_book_backend_file_bump_revision (bf);
+ return g_string_free (fields, FALSE);
+
+ } else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REVISION)) {
+ gchar *prop_value;
+
+ g_rw_lock_reader_lock (&(bf->priv->lock));
+ prop_value = g_strdup (bf->priv->revision);
+ g_rw_lock_reader_unlock (&(bf->priv->lock));
+
+ return prop_value;
+ }
+
+ /* Chain up to parent's get_backend_property() method. */
+ return E_BOOK_BACKEND_CLASS (e_book_backend_file_parent_class)->
+ get_backend_property (backend, prop_name);
+}
+
+static void
+book_backend_file_open (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ gboolean only_if_exists,
+ GError **perror)
+{
+ EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
+ ESource *source;
+ ESourceRevisionGuards *guards;
+
+ source = e_backend_get_source (E_BACKEND (backend));
+
+ g_type_ensure (E_TYPE_SOURCE_REVISION_GUARDS);
+ guards = e_source_get_extension (source, E_SOURCE_EXTENSION_REVISION_GUARDS);
+
+ bf->priv->revision_guards = e_source_revision_guards_get_enabled (guards);
+
+ g_rw_lock_writer_lock (&(bf->priv->lock));
+ if (!bf->priv->revision) {
+ e_book_backend_file_load_revision (bf);
+ e_book_backend_notify_property_changed (E_BOOK_BACKEND (backend),
+ BOOK_BACKEND_PROPERTY_REVISION,
+ bf->priv->revision);
+ }
+ g_rw_lock_writer_unlock (&(bf->priv->lock));
+
+ e_backend_set_online (E_BACKEND (backend), TRUE);
+ e_book_backend_set_writable (E_BOOK_BACKEND (backend), TRUE);
+}
+
+static void
+book_backend_file_create_contacts (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const GSList *vcards,
+ GSList **added_contacts,
+ GError **perror)
+{
+ EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
+
+ g_rw_lock_writer_lock (&(bf->priv->lock));
- *ids = removed_ids;
- } else {
- *ids = NULL;
- g_slist_free_full (removed_ids, (GDestroyNotify) g_free);
+ if (do_create (bf, vcards, added_contacts, perror)) {
+ e_book_backend_file_bump_revision (bf);
}
g_rw_lock_writer_unlock (&(bf->priv->lock));
-
- g_slist_free_full (removed_contacts, (GDestroyNotify) g_object_unref);
}
static void
-e_book_backend_file_modify_contacts (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- const GSList *vcards,
- GSList **contacts,
- GError **perror)
+book_backend_file_modify_contacts (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const GSList *vcards,
+ GSList **contacts,
+ GError **perror)
{
EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
const GSList *lold, *l;
@@ -1026,12 +1228,97 @@ e_book_backend_file_modify_contacts (EBookBackendSync *backend,
}
static void
-e_book_backend_file_get_contact (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- const gchar *id,
- gchar **vcard,
- GError **perror)
+book_backend_file_remove_contacts (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const GSList *id_list,
+ GSList **ids,
+ GError **perror)
+{
+ EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
+ GSList *removed_ids = NULL, *removed_contacts = NULL;
+ GError *local_error = NULL;
+ gboolean delete_failed = FALSE;
+ const GSList *l;
+
+ g_rw_lock_writer_lock (&(bf->priv->lock));
+
+ for (l = id_list; l != NULL; l = l->next) {
+ const gchar *id;
+ EContact *contact;
+
+ id = l->data;
+
+ /* First load the EContacts which need to be removed, we might delete some
+ * photos from disk because of this...
+ *
+ * Note: sqlitedb backend can probably make this faster by executing a
+ * single query to fetch a list of contacts for a list of ids, the
+ * current method makes a query for each UID.
+ */
+ contact = e_book_backend_sqlitedb_get_contact (
+ bf->priv->sqlitedb,
+ SQLITEDB_FOLDER_ID, id,
+ NULL, NULL, &local_error);
+
+ if (contact) {
+ removed_ids = g_slist_prepend (removed_ids, g_strdup (id));
+ removed_contacts = g_slist_prepend (removed_contacts, contact);
+ } else {
+ g_warning ("Failed to fetch contact to be removed: %s", local_error->message);
+
+ if (g_error_matches (local_error,
+ E_BOOK_SDB_ERROR,
+ E_BOOK_SDB_ERROR_CONTACT_NOT_FOUND)) {
+ g_set_error (
+ perror, E_BOOK_CLIENT_ERROR,
+ E_BOOK_CLIENT_ERROR_CONTACT_NOT_FOUND,
+ _("Contact '%s' not found"), id);
+ g_error_free (local_error);
+ } else
+ g_propagate_error (perror, local_error);
+
+ /* Abort as soon as missing contact is to be deleted */
+ delete_failed = TRUE;
+ break;
+ }
+ }
+
+ if (!delete_failed) {
+
+ /* Delete URI associated to those contacts */
+ for (l = removed_contacts; l; l = l->next) {
+ maybe_delete_unused_uris (bf, E_CONTACT (l->data), NULL);
+ }
+
+ /* Remove from summary as well */
+ if (!e_book_backend_sqlitedb_remove_contacts (bf->priv->sqlitedb,
+ SQLITEDB_FOLDER_ID,
+ removed_ids, &local_error)) {
+ g_warning ("Failed to remove contacts: %s", local_error->message);
+ g_propagate_error (perror, local_error);
+ }
+
+ e_book_backend_file_bump_revision (bf);
+
+ *ids = removed_ids;
+ } else {
+ *ids = NULL;
+ g_slist_free_full (removed_ids, (GDestroyNotify) g_free);
+ }
+
+ g_rw_lock_writer_unlock (&(bf->priv->lock));
+
+ g_slist_free_full (removed_contacts, (GDestroyNotify) g_object_unref);
+}
+
+static void
+book_backend_file_get_contact (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const gchar *id,
+ gchar **vcard,
+ GError **perror)
{
EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
GError *local_error = NULL;
@@ -1060,19 +1347,19 @@ e_book_backend_file_get_contact (EBookBackendSync *backend,
}
static void
-e_book_backend_file_get_contact_list (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- const gchar *query,
- GSList **contacts,
- GError **perror)
+book_backend_file_get_contact_list (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const gchar *query,
+ GSList **contacts,
+ GError **perror)
{
EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
GSList *contact_list = NULL, *l;
GSList *summary_list = NULL;
GError *local_error = NULL;
- d (printf ("e_book_backend_file_get_contact_list (%s)\n", query));
+ d (printf ("book_backend_file_get_contact_list (%s)\n", query));
g_rw_lock_reader_lock (&(bf->priv->lock));
summary_list = e_book_backend_sqlitedb_search (
@@ -1120,204 +1407,62 @@ e_book_backend_file_get_contact_list (EBookBackendSync *backend,
}
}
- *contacts = contact_list;
-}
-
-static void
-e_book_backend_file_get_contact_list_uids (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- const gchar *query,
- GSList **contacts_uids,
- GError **perror)
-{
- EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
- GSList *uids = NULL;
- GError *local_error = NULL;
-
- d (printf ("e_book_backend_file_get_contact_list (%s)\n", query));
-
- g_rw_lock_reader_lock (&(bf->priv->lock));
- uids = e_book_backend_sqlitedb_search_uids (
- bf->priv->sqlitedb,
- SQLITEDB_FOLDER_ID,
- query, NULL, &local_error);
- g_rw_lock_reader_unlock (&(bf->priv->lock));
-
- if (uids == NULL && local_error != NULL) {
-
- if (g_error_matches (local_error,
- E_BOOK_SDB_ERROR,
- E_BOOK_SDB_ERROR_NOT_SUPPORTED)) {
- g_set_error (
- perror, E_CLIENT_ERROR,
- E_CLIENT_ERROR_NOT_SUPPORTED,
- _("Query '%s' not supported"), query);
- g_error_free (local_error);
-
- } else if (g_error_matches (local_error,
- E_BOOK_SDB_ERROR,
- E_BOOK_SDB_ERROR_INVALID_QUERY)) {
- g_set_error (
- perror, E_CLIENT_ERROR,
- E_CLIENT_ERROR_INVALID_QUERY,
- _("Invalid Query '%s'"), query);
- g_error_free (local_error);
-
- } else {
- g_warning ("Failed to fetch contact ids: %s", local_error->message);
- g_propagate_error (perror, local_error);
- }
- }
-
- *contacts_uids = g_slist_reverse (uids);
-}
-
-typedef struct {
- EBookBackendFile *bf;
- GThread *thread;
- EFlag *running;
-} FileBackendSearchClosure;
-
-static void
-closure_destroy (FileBackendSearchClosure *closure)
-{
- d (printf ("destroying search closure\n"));
- e_flag_free (closure->running);
- if (closure->thread)
- g_thread_unref (closure->thread);
- g_free (closure);
-}
-
-static FileBackendSearchClosure *
-init_closure (EDataBookView *book_view,
- EBookBackendFile *bf)
-{
- FileBackendSearchClosure *closure = g_new (FileBackendSearchClosure, 1);
-
- closure->bf = bf;
- closure->thread = NULL;
- closure->running = e_flag_new ();
-
- g_object_set_data_full (
- G_OBJECT (book_view),
- "EBookBackendFile.BookView::closure",
- closure, (GDestroyNotify) closure_destroy);
-
- return closure;
-}
-
-static FileBackendSearchClosure *
-get_closure (EDataBookView *book_view)
-{
- return g_object_get_data (
- G_OBJECT (book_view),
- "EBookBackendFile.BookView::closure");
-}
-
-static void
-notify_update_vcard (EDataBookView *book_view,
- gboolean prefiltered,
- const gchar *id,
- const gchar *vcard)
-{
- if (prefiltered)
- e_data_book_view_notify_update_prefiltered_vcard (book_view, id, vcard);
- else
- e_data_book_view_notify_update_vcard (book_view, id, vcard);
-}
-
-static gpointer
-book_view_thread (gpointer data)
-{
- EDataBookView *book_view;
- FileBackendSearchClosure *closure;
- EBookBackendFile *bf;
- EBookBackendSExp *sexp;
- const gchar *query;
- GSList *summary_list, *l;
- GHashTable *fields_of_interest;
- GError *local_error = NULL;
-
- g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (data), NULL);
-
- book_view = data;
- closure = get_closure (book_view);
- if (!closure) {
- g_warning (G_STRLOC ": NULL closure in book view thread");
- return NULL;
- }
- bf = closure->bf;
-
- d (printf ("starting initial population of book view\n"));
-
- /* ref the book view because it'll be removed and unrefed
- * when/if it's stopped */
- g_object_ref (book_view);
-
- sexp = e_data_book_view_get_sexp (book_view);
- query = e_book_backend_sexp_text (sexp);
-
- fields_of_interest = e_data_book_view_get_fields_of_interest (book_view);
-
- if ( !strcmp (query, "(contains \"x-evolution-any-field\" \"\")")) {
- e_data_book_view_notify_progress (book_view, -1, _("Loading..."));
- } else {
- e_data_book_view_notify_progress (book_view, -1, _("Searching..."));
- }
-
- d (printf ("signalling parent thread\n"));
- e_flag_set (closure->running);
-
- g_rw_lock_reader_lock (&(bf->priv->lock));
- summary_list = e_book_backend_sqlitedb_search (
- bf->priv->sqlitedb,
- SQLITEDB_FOLDER_ID,
- query, fields_of_interest,
- NULL, NULL, &local_error);
- g_rw_lock_reader_unlock (&(bf->priv->lock));
-
- if (!summary_list && local_error != NULL) {
- g_warning (G_STRLOC ": Failed to query initial contacts: %s", local_error->message);
- g_error_free (local_error);
- e_data_book_view_notify_complete (
- book_view,
- g_error_new_literal (
- E_CLIENT_ERROR,
- E_CLIENT_ERROR_NOT_OPENED,
- e_client_error_to_string (
- E_CLIENT_ERROR_NOT_OPENED)));
- g_object_unref (book_view);
- return NULL;
- }
+ *contacts = contact_list;
+}
- for (l = summary_list; l; l = l->next) {
- EbSdbSearchData *data = l->data;
- gchar *vcard = NULL;
+static void
+book_backend_file_get_contact_list_uids (EBookBackendSync *backend,
+ EDataBook *book,
+ GCancellable *cancellable,
+ const gchar *query,
+ GSList **contacts_uids,
+ GError **perror)
+{
+ EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
+ GSList *uids = NULL;
+ GError *local_error = NULL;
- vcard = data->vcard;
- data->vcard = NULL;
+ d (printf ("book_backend_file_get_contact_list (%s)\n", query));
- notify_update_vcard (book_view, TRUE, data->uid, vcard);
- g_free (vcard);
- }
+ g_rw_lock_reader_lock (&(bf->priv->lock));
+ uids = e_book_backend_sqlitedb_search_uids (
+ bf->priv->sqlitedb,
+ SQLITEDB_FOLDER_ID,
+ query, NULL, &local_error);
+ g_rw_lock_reader_unlock (&(bf->priv->lock));
- g_slist_foreach (summary_list, (GFunc) e_book_backend_sqlitedb_search_data_free, NULL);
- g_slist_free (summary_list);
+ if (uids == NULL && local_error != NULL) {
- if (e_flag_is_set (closure->running))
- e_data_book_view_notify_complete (book_view, NULL /* Success */);
+ if (g_error_matches (local_error,
+ E_BOOK_SDB_ERROR,
+ E_BOOK_SDB_ERROR_NOT_SUPPORTED)) {
+ g_set_error (
+ perror, E_CLIENT_ERROR,
+ E_CLIENT_ERROR_NOT_SUPPORTED,
+ _("Query '%s' not supported"), query);
+ g_error_free (local_error);
- g_object_unref (book_view);
+ } else if (g_error_matches (local_error,
+ E_BOOK_SDB_ERROR,
+ E_BOOK_SDB_ERROR_INVALID_QUERY)) {
+ g_set_error (
+ perror, E_CLIENT_ERROR,
+ E_CLIENT_ERROR_INVALID_QUERY,
+ _("Invalid Query '%s'"), query);
+ g_error_free (local_error);
- d (printf ("finished population of book view\n"));
+ } else {
+ g_warning ("Failed to fetch contact ids: %s", local_error->message);
+ g_propagate_error (perror, local_error);
+ }
+ }
- return NULL;
+ *contacts_uids = g_slist_reverse (uids);
}
static void
-e_book_backend_file_start_view (EBookBackend *backend,
- EDataBookView *book_view)
+book_backend_file_start_view (EBookBackend *backend,
+ EDataBookView *book_view)
{
FileBackendSearchClosure *closure = init_closure (book_view, E_BOOK_BACKEND_FILE (backend));
@@ -1331,8 +1476,8 @@ e_book_backend_file_start_view (EBookBackend *backend,
}
static void
-e_book_backend_file_stop_view (EBookBackend *backend,
- EDataBookView *book_view)
+book_backend_file_stop_view (EBookBackend *backend,
+ EDataBookView *book_view)
{
FileBackendSearchClosure *closure = get_closure (book_view);
gboolean need_join;
@@ -1351,132 +1496,8 @@ e_book_backend_file_stop_view (EBookBackend *backend,
}
static void
-e_book_backend_file_open (EBookBackendSync *backend,
- EDataBook *book,
- GCancellable *cancellable,
- gboolean only_if_exists,
- GError **perror)
-{
- EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
- ESource *source;
- ESourceRevisionGuards *guards;
-
- source = e_backend_get_source (E_BACKEND (backend));
-
- g_type_ensure (E_TYPE_SOURCE_REVISION_GUARDS);
- guards = e_source_get_extension (source, E_SOURCE_EXTENSION_REVISION_GUARDS);
-
- bf->priv->revision_guards = e_source_revision_guards_get_enabled (guards);
-
- g_rw_lock_writer_lock (&(bf->priv->lock));
- if (!bf->priv->revision) {
- e_book_backend_file_load_revision (bf);
- e_book_backend_notify_property_changed (E_BOOK_BACKEND (backend),
- BOOK_BACKEND_PROPERTY_REVISION,
- bf->priv->revision);
- }
- g_rw_lock_writer_unlock (&(bf->priv->lock));
-
- e_backend_set_online (E_BACKEND (backend), TRUE);
- e_book_backend_set_writable (E_BOOK_BACKEND (backend), TRUE);
-}
-
-static gchar *
-e_book_backend_file_get_backend_property (EBookBackend *backend,
- const gchar *prop_name)
-{
- EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
-
- g_return_val_if_fail (prop_name != NULL, NULL);
-
- if (g_str_equal (prop_name, CLIENT_BACKEND_PROPERTY_CAPABILITIES)) {
- return g_strdup ("local,do-initial-query,bulk-adds,bulk-modifies,bulk-removes,contact-lists");
-
- } else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS)) {
- return g_strdup (e_contact_field_name (E_CONTACT_FILE_AS));
-
- } else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS)) {
- GString *fields;
- gint ii;
-
- fields = g_string_sized_new (1024);
-
- /* XXX we need a way to say "we support everything", since the
- * file backend does */
- for (ii = 1; ii < E_CONTACT_FIELD_LAST; ii++) {
- if (fields->len > 0)
- g_string_append_c (fields, ',');
- g_string_append (fields, e_contact_field_name (ii));
- }
-
- return g_string_free (fields, FALSE);
-
- } else if (g_str_equal (prop_name, BOOK_BACKEND_PROPERTY_REVISION)) {
- gchar *prop_value;
-
- g_rw_lock_reader_lock (&(bf->priv->lock));
- prop_value = g_strdup (bf->priv->revision);
- g_rw_lock_reader_unlock (&(bf->priv->lock));
-
- return prop_value;
- }
-
- /* Chain up to parent's get_backend_property() method. */
- return E_BOOK_BACKEND_CLASS (e_book_backend_file_parent_class)->
- get_backend_property (backend, prop_name);
-}
-
-static void
-e_book_backend_file_sync (EBookBackend *backend)
-{
- EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
-
- g_return_if_fail (bf != NULL);
-
- /* FIXME: Tell sqlite to dump NOW ! */
-}
-
-static void
-view_notify_update (EBookBackendFile *backend,
- EDataBookView *view,
- EContact *contact)
-{
- EBookBackendSExp *sexp;
- GHashTable *fields = e_data_book_view_get_fields_of_interest (view);
- const gchar *query;
- gboolean notified = FALSE;
- gboolean with_all_required_fields = FALSE;
-
- sexp = e_data_book_view_get_sexp (view);
- query = e_book_backend_sexp_text (sexp);
-
- if (e_book_backend_sqlitedb_check_summary_query (backend->priv->sqlitedb, query, NULL) &&
- e_book_backend_sqlitedb_check_summary_fields (backend->priv->sqlitedb, fields)) {
-
- const gchar *uid = e_contact_get_const (contact, E_CONTACT_UID);
- gchar *vcard;
-
- vcard = e_book_backend_sqlitedb_get_vcard_string (
- backend->priv->sqlitedb,
- SQLITEDB_FOLDER_ID, uid,
- fields, &with_all_required_fields, NULL);
-
- if (vcard) {
- if (with_all_required_fields) {
- e_data_book_view_notify_update_prefiltered_vcard (view, uid, vcard);
- notified = TRUE;
- }
- g_free (vcard);
- }
- }
-
- if (!notified)
- e_data_book_view_notify_update (view, contact);
-}
-
-static void
-e_book_backend_file_notify_update (EBookBackend *backend,
- const EContact *contact)
+book_backend_file_notify_update (EBookBackend *backend,
+ const EContact *contact)
{
GList *list, *link;
@@ -1491,35 +1512,54 @@ e_book_backend_file_notify_update (EBookBackend *backend,
g_list_free_full (list, (GDestroyNotify) g_object_unref);
}
-static void
-e_book_backend_file_dispose (GObject *object)
+static EDataBookDirect *
+book_backend_file_get_direct_book (EBookBackend *backend)
{
- EBookBackendFile *bf;
+ EDataBookDirect *direct;
+ ESourceRegistry *registry;
+ ESource *source;
+ gchar *backend_path;
+ gchar *dirname;
+ const gchar *modules_env = NULL;
- bf = E_BOOK_BACKEND_FILE (object);
+ modules_env = g_getenv (EDS_ADDRESS_BOOK_MODULES);
- if (bf->priv->sqlitedb) {
- g_object_unref (bf->priv->sqlitedb);
- bf->priv->sqlitedb = NULL;
- }
+ source = e_backend_get_source (E_BACKEND (backend));
+ registry = e_book_backend_get_registry (backend);
+ dirname = e_book_backend_file_extract_path_from_source (
+ registry, source, GET_PATH_DB_DIR);
- G_OBJECT_CLASS (e_book_backend_file_parent_class)->dispose (object);
+ /* Support in-tree testing / relocated modules */
+ if (modules_env)
+ backend_path = g_build_filename (modules_env, "libebookbackendfile.so", NULL);
+ else
+ backend_path = g_build_filename (BACKENDDIR, "libebookbackendfile.so", NULL);
+ direct = e_data_book_direct_new (backend_path, "EBookBackendFileFactory", dirname);
+
+ g_free (backend_path);
+ g_free (dirname);
+
+ return direct;
}
static void
-e_book_backend_file_finalize (GObject *object)
+book_backend_file_configure_direct (EBookBackend *backend,
+ const gchar *config)
{
EBookBackendFilePrivate *priv;
- priv = E_BOOK_BACKEND_FILE_GET_PRIVATE (object);
+ priv = E_BOOK_BACKEND_FILE_GET_PRIVATE (backend);
+ priv->base_directory = g_strdup (config);
+}
- g_free (priv->photo_dirname);
- g_free (priv->revision);
- g_free (priv->base_directory);
- g_rw_lock_clear (&(priv->lock));
+static void
+book_backend_file_sync (EBookBackend *backend)
+{
+ EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
- /* Chain up to parent's finalize() method. */
- G_OBJECT_CLASS (e_book_backend_file_parent_class)->finalize (object);
+ g_return_if_fail (bf != NULL);
+
+ /* FIXME: Tell sqlite to dump NOW ! */
}
static gboolean
@@ -1656,77 +1696,36 @@ exit:
return success;
}
-static EDataBookDirect *
-e_book_backend_file_get_direct_book (EBookBackend *backend)
-{
- EDataBookDirect *direct;
- ESourceRegistry *registry;
- ESource *source;
- gchar *backend_path;
- gchar *dirname;
- const gchar *modules_env = NULL;
-
- modules_env = g_getenv (EDS_ADDRESS_BOOK_MODULES);
-
- source = e_backend_get_source (E_BACKEND (backend));
- registry = e_book_backend_get_registry (backend);
- dirname = e_book_backend_file_extract_path_from_source (
- registry, source, GET_PATH_DB_DIR);
-
- /* Support in-tree testing / relocated modules */
- if (modules_env)
- backend_path = g_build_filename (modules_env, "libebookbackendfile.so", NULL);
- else
- backend_path = g_build_filename (BACKENDDIR, "libebookbackendfile.so", NULL);
- direct = e_data_book_direct_new (backend_path, "EBookBackendFileFactory", dirname);
-
- g_free (backend_path);
- g_free (dirname);
-
- return direct;
-}
-
-static void
-e_book_backend_file_configure_direct (EBookBackend *backend,
- const gchar *config)
-{
- EBookBackendFilePrivate *priv;
-
- priv = E_BOOK_BACKEND_FILE_GET_PRIVATE (backend);
- priv->base_directory = g_strdup (config);
-}
-
static void
e_book_backend_file_class_init (EBookBackendFileClass *class)
{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- EBookBackendSyncClass *sync_class;
+ GObjectClass *object_class;
EBookBackendClass *backend_class;
+ EBookBackendSyncClass *sync_class;
g_type_class_add_private (class, sizeof (EBookBackendFilePrivate));
- sync_class = E_BOOK_BACKEND_SYNC_CLASS (class);
+ object_class = G_OBJECT_CLASS (class);
+ object_class->dispose = book_backend_file_dispose;
+ object_class->finalize = book_backend_file_finalize;
+
backend_class = E_BOOK_BACKEND_CLASS (class);
+ backend_class->get_backend_property = book_backend_file_get_backend_property;
+ backend_class->start_view = book_backend_file_start_view;
+ backend_class->stop_view = book_backend_file_stop_view;
+ backend_class->notify_update = book_backend_file_notify_update;
+ backend_class->get_direct_book = book_backend_file_get_direct_book;
+ backend_class->configure_direct = book_backend_file_configure_direct;
+ backend_class->sync = book_backend_file_sync;
- /* Set the virtual methods. */
- backend_class->get_backend_property = e_book_backend_file_get_backend_property;
- backend_class->start_view = e_book_backend_file_start_view;
- backend_class->stop_view = e_book_backend_file_stop_view;
- backend_class->sync = e_book_backend_file_sync;
- backend_class->notify_update = e_book_backend_file_notify_update;
- backend_class->get_direct_book = e_book_backend_file_get_direct_book;
- backend_class->configure_direct = e_book_backend_file_configure_direct;
-
- sync_class->open_sync = e_book_backend_file_open;
- sync_class->create_contacts_sync = e_book_backend_file_create_contacts;
- sync_class->remove_contacts_sync = e_book_backend_file_remove_contacts;
- sync_class->modify_contacts_sync = e_book_backend_file_modify_contacts;
- sync_class->get_contact_sync = e_book_backend_file_get_contact;
- sync_class->get_contact_list_sync = e_book_backend_file_get_contact_list;
- sync_class->get_contact_list_uids_sync = e_book_backend_file_get_contact_list_uids;
-
- object_class->dispose = e_book_backend_file_dispose;
- object_class->finalize = e_book_backend_file_finalize;
+ sync_class = E_BOOK_BACKEND_SYNC_CLASS (class);
+ sync_class->open_sync = book_backend_file_open;
+ sync_class->create_contacts_sync = book_backend_file_create_contacts;
+ sync_class->modify_contacts_sync = book_backend_file_modify_contacts;
+ sync_class->remove_contacts_sync = book_backend_file_remove_contacts;
+ sync_class->get_contact_sync = book_backend_file_get_contact;
+ sync_class->get_contact_list_sync = book_backend_file_get_contact_list;
+ sync_class->get_contact_list_uids_sync = book_backend_file_get_contact_list_uids;
}
static void
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]