[evolution-data-server/openismus-work-3-8: 24/43] EBookBackendFile: Ported to use the new SQLite API



commit b7c32f81e495093befaee8a298187059ef6c098a
Author: Tristan Van Berkom <tristanvb openismus com>
Date:   Sun Dec 1 16:55:33 2013 +0900

    EBookBackendFile: Ported to use the new SQLite API
    
    This could not be backported from master, manually done.

 addressbook/backends/file/e-book-backend-file.c |  495 +++++++++++------------
 1 files changed, 240 insertions(+), 255 deletions(-)
---
diff --git a/addressbook/backends/file/e-book-backend-file.c b/addressbook/backends/file/e-book-backend-file.c
index 430dcf7..484c4f9 100644
--- a/addressbook/backends/file/e-book-backend-file.c
+++ b/addressbook/backends/file/e-book-backend-file.c
@@ -56,9 +56,7 @@
 
 #define PAS_ID_PREFIX "pas-id-"
 
-#define SQLITEDB_EMAIL_ID    "addressbook localbackend com"
-#define SQLITEDB_FOLDER_ID   "folder_id"
-#define SQLITEDB_FOLDER_NAME "folder"
+#define SQLITE_REVISION_KEY  "revision"
 
 #define EDB_ERROR(_code)          e_data_book_create_error (E_DATA_BOOK_STATUS_ ## _code, NULL)
 #define EDB_ERROR_EX(_code, _msg) e_data_book_create_error (E_DATA_BOOK_STATUS_ ## _code, _msg)
@@ -86,7 +84,7 @@ struct _EBookBackendFilePrivate {
        GRWLock    lock;
        GList     *cursors;
 
-       EBookBackendSqliteDB *sqlitedb;
+       EBookSqlite *sqlitedb;
 };
 
 /****************************************************************
@@ -636,11 +634,10 @@ e_book_backend_file_bump_revision (EBookBackendFile *bf,
        gboolean success;
 
        new_revision = e_book_backend_file_new_revision (bf);
-
-       success = e_book_backend_sqlitedb_set_revision (bf->priv->sqlitedb,
-                                                       SQLITEDB_FOLDER_ID,
-                                                       new_revision,
-                                                       &local_error);
+       success = e_book_sqlite_set_key_value (bf->priv->sqlitedb,
+                                              SQLITE_REVISION_KEY,
+                                              new_revision,
+                                              &local_error);
 
        if (success) {
                g_free (bf->priv->revision);
@@ -665,10 +662,10 @@ e_book_backend_file_load_revision (EBookBackendFile *bf)
 {
        GError *error = NULL;
 
-       if (!e_book_backend_sqlitedb_get_revision (bf->priv->sqlitedb,
-                                                  SQLITEDB_FOLDER_ID,
-                                                  &bf->priv->revision,
-                                                  &error)) {
+       if (!e_book_sqlite_get_key_value (bf->priv->sqlitedb,
+                                         SQLITE_REVISION_KEY,
+                                         &bf->priv->revision,
+                                         &error)) {
                g_warning (
                        G_STRLOC ": Error loading database revision: %s",
                        error ? error->message : "Unknown error");
@@ -683,10 +680,9 @@ e_book_backend_file_load_locale (EBookBackendFile *bf)
 {
        GError *error = NULL;
 
-       if (!e_book_backend_sqlitedb_get_locale (bf->priv->sqlitedb,
-                                                SQLITEDB_FOLDER_ID,
-                                                &bf->priv->locale,
-                                                &error)) {
+       if (!e_book_sqlite_get_locale (bf->priv->sqlitedb,
+                                      &bf->priv->locale,
+                                      &error)) {
                g_warning (
                        G_STRLOC ": Error loading database locale setting: %s",
                        error ? error->message : "Unknown error");
@@ -705,27 +701,10 @@ set_revision (EBookBackendFile *bf,
        g_free (rev);
 }
 
-
 /****************************************************************
  *                   Dealing with cursor updates                *
  ****************************************************************/
 static void
-cursors_locale_changed (EBookBackendFile *bf)
-{
-       GList *l;
-
-       for (l = bf->priv->cursors; l; l = l->next) {
-               EDataBookCursor *cursor = l->data;
-               GError *error = NULL;
-
-               if (!e_data_book_cursor_load_locale (cursor, NULL, &error)) {
-                       g_warning ("Error loading cursor locale: %s", error->message);
-                       g_clear_error (&error);
-               }
-       }
-}
-
-static void
 cursors_contact_added (EBookBackendFile *bf,
                       EContact         *contact)
 {
@@ -765,6 +744,7 @@ static gboolean
 do_create (EBookBackendFile *bf,
            const GSList *vcards_req,
            GSList **contacts,
+          GCancellable *cancellable,
            GError **perror)
 {
        GSList *slist = NULL;
@@ -816,23 +796,23 @@ do_create (EBookBackendFile *bf,
 
        if (status != STATUS_ERROR) {
 
-               if (!e_book_backend_sqlitedb_new_contacts (bf->priv->sqlitedb,
-                                                          SQLITEDB_FOLDER_ID,
-                                                          slist, FALSE,
-                                                          &local_error)) {
-
-                       g_warning ("Failed to add contacts: %s", local_error->message);
+               if (!e_book_sqlite_add_contacts (bf->priv->sqlitedb,
+                                                slist, NULL, FALSE,
+                                                cancellable,
+                                                &local_error)) {
 
                        if (g_error_matches (local_error,
-                                            E_BOOK_SDB_ERROR,
-                                            E_BOOK_SDB_ERROR_CONSTRAINT)) {
+                                            E_BOOK_SQLITE_ERROR,
+                                            E_BOOK_SQLITE_ERROR_CONSTRAINT)) {
                                g_set_error (
                                        perror, E_DATA_BOOK_ERROR,
                                        E_DATA_BOOK_STATUS_CONTACTID_ALREADY_EXISTS,
                                        _("Conflicting UIDs found in added contacts"));
                                g_clear_error (&local_error);
-                       } else
+                       } else {
+                               g_warning ("Failed to add contacts: %s", local_error->message);
                                g_propagate_error (perror, local_error);
+                       }
 
                        status = STATUS_ERROR;
                }
@@ -866,32 +846,38 @@ e_book_backend_file_create_contacts (EBookBackendSync *backend,
                                      GError **perror)
 {
        EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
-       gboolean success;
+       gboolean success = TRUE;
 
        g_rw_lock_writer_lock (&(bf->priv->lock));
+       if (!e_book_sqlite_lock (bf->priv->sqlitedb,
+                                EBSQL_LOCK_WRITE,
+                                cancellable, perror)) {
+               g_rw_lock_writer_unlock (&(bf->priv->lock));
+               return;
+       }
 
-       success = e_book_backend_sqlitedb_lock_updates (bf->priv->sqlitedb, perror);
-
-       if (success)
-               success = do_create (bf, vcards, added_contacts, perror);
+       success = do_create (bf, vcards, added_contacts, cancellable, perror);
 
        if (success)
                success = e_book_backend_file_bump_revision (bf, perror);
 
+
        if (success)
-               success = e_book_backend_sqlitedb_unlock_updates (bf->priv->sqlitedb,
-                                                                 TRUE, perror);
+               success = e_book_sqlite_unlock (bf->priv->sqlitedb,
+                                               EBSQL_UNLOCK_COMMIT,
+                                               perror);
        else {
                GError *local_error = NULL;
 
                /* Rollback transaction */
-               if (!e_book_backend_sqlitedb_unlock_updates (bf->priv->sqlitedb, FALSE, &local_error)) {
+               if (!e_book_sqlite_unlock (bf->priv->sqlitedb,
+                                          EBSQL_UNLOCK_ROLLBACK,
+                                          &local_error)) {
                        g_warning ("Failed to rollback transaction after failing to add contacts: %s",
                                   local_error->message);
                        g_clear_error (&local_error);
                }
-       }
-
+       }
        g_rw_lock_writer_unlock (&(bf->priv->lock));
 }
 
@@ -906,12 +892,16 @@ e_book_backend_file_remove_contacts (EBookBackendSync *backend,
        EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
        GSList           *removed_ids = NULL, *removed_contacts = NULL;
        GError           *local_error = NULL;
-       gboolean          success;
+       gboolean          success = TRUE;
        const GSList     *l;
 
        g_rw_lock_writer_lock (&(bf->priv->lock));
-
-       success = e_book_backend_sqlitedb_lock_updates (bf->priv->sqlitedb, perror);
+       if (!e_book_sqlite_lock (bf->priv->sqlitedb,
+                                EBSQL_LOCK_WRITE,
+                                cancellable, perror)) {
+               g_rw_lock_writer_unlock (&(bf->priv->lock));
+               return;
+       }
 
        for (l = id_list; l != NULL && success; l = l->next) {
                const gchar *id;
@@ -926,20 +916,17 @@ e_book_backend_file_remove_contacts (EBookBackendSync *backend,
                 * 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) {
+               if (e_book_sqlite_get_contact (bf->priv->sqlitedb,
+                                              id, FALSE, &contact,
+                                              &local_error)) {
                        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)) {
+                                            E_BOOK_SQLITE_ERROR,
+                                            E_BOOK_SQLITE_ERROR_CONTACT_NOT_FOUND)) {
                                g_set_error (
                                        perror, E_DATA_BOOK_ERROR,
                                        E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND,
@@ -963,9 +950,8 @@ e_book_backend_file_remove_contacts (EBookBackendSync *backend,
                }
 
                /* Remove from summary as well */
-               if (!e_book_backend_sqlitedb_remove_contacts (bf->priv->sqlitedb,
-                                                     SQLITEDB_FOLDER_ID,
-                                                     removed_ids, &local_error)) {
+               if (!e_book_sqlite_remove_contacts (bf->priv->sqlitedb, removed_ids,
+                                                   cancellable, &local_error)) {
                        g_warning ("Failed to remove contacts: %s", local_error->message);
                        g_propagate_error (perror, local_error);
                }
@@ -980,16 +966,15 @@ e_book_backend_file_remove_contacts (EBookBackendSync *backend,
 
        /* Commit or rollback transaction */
        if (success) {
-               success = e_book_backend_sqlitedb_unlock_updates (bf->priv->sqlitedb,
-                                                                 TRUE, perror);
+               success = e_book_sqlite_unlock (bf->priv->sqlitedb, EBSQL_UNLOCK_COMMIT, perror);
        } else {
                /* Rollback transaction */
-               if (!e_book_backend_sqlitedb_unlock_updates (bf->priv->sqlitedb, FALSE, &local_error)) {
+               if (!e_book_sqlite_unlock (bf->priv->sqlitedb, EBSQL_UNLOCK_ROLLBACK, &local_error)) {
                        g_warning ("Failed to rollback transaction after failing to modify contacts: %s",
                                   local_error->message);
                        g_clear_error (&local_error);
                }
-        }
+       }
 
        /* After removing any contacts, notify any cursors that the contacts are removed */
        if (success) {
@@ -1019,9 +1004,10 @@ e_book_backend_file_modify_contacts (EBookBackendSync *backend,
        PhotoModifiedStatus status = STATUS_NORMAL;
 
        g_rw_lock_writer_lock (&(bf->priv->lock));
-
-       if (!e_book_backend_sqlitedb_lock_updates (bf->priv->sqlitedb, perror))
-               status = STATUS_ERROR;
+       if (!e_book_sqlite_lock (bf->priv->sqlitedb, EBSQL_LOCK_WRITE, cancellable, perror)) {
+               g_rw_lock_writer_unlock (&(bf->priv->lock));
+               return;
+       }
 
        for (l = vcards; l != NULL; l = l->next) {
                gchar *id;
@@ -1039,11 +1025,9 @@ e_book_backend_file_modify_contacts (EBookBackendSync *backend,
                        break;
                }
 
-               old_contact = e_book_backend_sqlitedb_get_contact (
-                       bf->priv->sqlitedb,
-                       SQLITEDB_FOLDER_ID, id,
-                       NULL, NULL, &local_error);
-               if (!old_contact) {
+               if (!e_book_sqlite_get_contact (bf->priv->sqlitedb,
+                                               id, FALSE, &old_contact,
+                                               &local_error)) {
                        g_warning (G_STRLOC ": Failed to load contact %s: %s", id, local_error->message);
                        g_propagate_error (perror, local_error);
                        local_error = NULL;
@@ -1110,10 +1094,9 @@ e_book_backend_file_modify_contacts (EBookBackendSync *backend,
                }
 
                /* Update summary as well */
-               if (!e_book_backend_sqlitedb_new_contacts (bf->priv->sqlitedb,
-                                                          SQLITEDB_FOLDER_ID,
-                                                          modified_contacts, TRUE,
-                                                          &local_error)) {
+               if (!e_book_sqlite_add_contacts (bf->priv->sqlitedb,
+                                                modified_contacts, NULL, TRUE,
+                                                cancellable, &local_error)) {
                        g_warning ("Failed to modify contacts: %s", local_error->message);
                        g_propagate_error (perror, local_error);
                        local_error = NULL;
@@ -1131,13 +1114,16 @@ e_book_backend_file_modify_contacts (EBookBackendSync *backend,
        /* Commit or rollback transaction */
        if (status != STATUS_ERROR) {
 
-               if (!e_book_backend_sqlitedb_unlock_updates (bf->priv->sqlitedb,
-                                                            TRUE, perror))
+               if (!e_book_sqlite_unlock (bf->priv->sqlitedb,
+                                          EBSQL_UNLOCK_COMMIT,
+                                          perror))
                        status = STATUS_ERROR;
 
        } else {
                /* Rollback transaction */
-               if (!e_book_backend_sqlitedb_unlock_updates (bf->priv->sqlitedb, FALSE, &local_error)) {
+               if (!e_book_sqlite_unlock (bf->priv->sqlitedb,
+                                          EBSQL_UNLOCK_ROLLBACK,
+                                          &local_error)) {
                        g_warning ("Failed to rollback transaction after failing to modify contacts: %s",
                                   local_error->message);
                        g_clear_error (&local_error);
@@ -1180,19 +1166,19 @@ e_book_backend_file_get_contact (EBookBackendSync *backend,
 {
        EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
        GError *local_error = NULL;
+       gboolean success;
 
        g_rw_lock_reader_lock (&(bf->priv->lock));
-
-       *vcard = e_book_backend_sqlitedb_get_vcard_string (bf->priv->sqlitedb,
-                                                          SQLITEDB_FOLDER_ID, id,
-                                                          NULL, NULL, &local_error);
+       success = e_book_sqlite_get_vcard (bf->priv->sqlitedb,
+                                          id, FALSE, vcard,
+                                          &local_error);
        g_rw_lock_reader_unlock (&(bf->priv->lock));
 
-       if (local_error) {
+       if (!success) {
 
                if (g_error_matches (local_error,
-                                    E_BOOK_SDB_ERROR,
-                                    E_BOOK_SDB_ERROR_CONTACT_NOT_FOUND)) {
+                                    E_BOOK_SQLITE_ERROR,
+                                    E_BOOK_SQLITE_ERROR_CONTACT_NOT_FOUND)) {
                        g_set_error (
                                perror, E_DATA_BOOK_ERROR,
                                E_DATA_BOOK_STATUS_CONTACT_NOT_FOUND,
@@ -1216,46 +1202,47 @@ e_book_backend_file_get_contact_list (EBookBackendSync *backend,
        GSList           *contact_list = NULL, *l;
        GSList           *summary_list = NULL;
        GError           *local_error = NULL;
+       gboolean          success;
 
        d (printf ("e_book_backend_file_get_contact_list (%s)\n", query));
 
        g_rw_lock_reader_lock (&(bf->priv->lock));
-       summary_list = e_book_backend_sqlitedb_search (
-               bf->priv->sqlitedb, SQLITEDB_FOLDER_ID,
-               query, NULL,
-               NULL, NULL, &local_error);
+       if (!e_book_sqlite_lock (bf->priv->sqlitedb,
+                                EBSQL_LOCK_READ,
+                                cancellable, perror)) {
+               g_rw_lock_writer_unlock (&(bf->priv->lock));
+               return;
+       }
+       success = e_book_sqlite_search (bf->priv->sqlitedb,
+                                       query,
+                                       FALSE,
+                                       &summary_list,
+                                       cancellable, 
+                                       &local_error);
+       e_book_sqlite_unlock (bf->priv->sqlitedb,
+                             EBSQL_UNLOCK_NONE,
+                             success ? &local_error : NULL);
        g_rw_lock_reader_unlock (&(bf->priv->lock));
 
-       if (summary_list) {
-
-               for (l = summary_list; l; l = l->next) {
-                       EbSdbSearchData *data = l->data;
-
-                       /* Steal the memory directly from the returned query */
-                       contact_list = g_slist_prepend (contact_list, data->vcard);
-                       data->vcard  = NULL;
-               }
-
-               g_slist_foreach (summary_list, (GFunc) e_book_backend_sqlitedb_search_data_free, NULL);
-               g_slist_free (summary_list);
+       if (!success) {
 
-       } else if (local_error != NULL) {
+               g_warn_if_fail (summary_list == NULL);
 
                if (g_error_matches (local_error,
-                                    E_BOOK_SDB_ERROR,
-                                    E_BOOK_SDB_ERROR_NOT_SUPPORTED)) {
+                                    E_BOOK_SQLITE_ERROR,
+                                    E_BOOK_SQLITE_ERROR_UNSUPPORTED_QUERY)) {
                        g_set_error (
-                               perror, E_DATA_BOOK_ERROR,
-                               E_DATA_BOOK_STATUS_NOT_SUPPORTED,
+                               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)) {
+                                    E_BOOK_SQLITE_ERROR,
+                                    E_BOOK_SQLITE_ERROR_INVALID_QUERY)) {
                        g_set_error (
-                               perror, E_DATA_BOOK_ERROR,
-                               E_DATA_BOOK_STATUS_INVALID_QUERY,
+                               perror, E_CLIENT_ERROR,
+                               E_CLIENT_ERROR_INVALID_QUERY,
                                _("Invalid Query '%s'"), query);
                        g_error_free (local_error);
 
@@ -1265,6 +1252,17 @@ e_book_backend_file_get_contact_list (EBookBackendSync *backend,
                }
        }
 
+       for (l = summary_list; l; l = l->next) {
+               EbSqlSearchData *data = l->data;
+
+               /* Steal the memory directly from the returned query */
+               contact_list = g_slist_prepend (contact_list, data->vcard);
+               data->vcard  = NULL;
+       }
+
+       g_slist_foreach (summary_list, (GFunc) e_book_sqlite_search_data_free, NULL);
+       g_slist_free (summary_list);
+
        *contacts = contact_list;
 }
 
@@ -1279,33 +1277,44 @@ e_book_backend_file_get_contact_list_uids (EBookBackendSync *backend,
        EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
        GSList           *uids = NULL;
        GError           *local_error = NULL;
+       gboolean          success;
 
        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);
+       if (!e_book_sqlite_lock (bf->priv->sqlitedb,
+                                EBSQL_LOCK_READ,
+                                cancellable, perror)) {
+               g_rw_lock_writer_unlock (&(bf->priv->lock));
+               return;
+       }
+       success = e_book_sqlite_search_uids (bf->priv->sqlitedb,
+                                            query,
+                                            &uids,
+                                            cancellable,
+                                            &local_error);
+       e_book_sqlite_unlock (bf->priv->sqlitedb,
+                             EBSQL_UNLOCK_NONE,
+                             success ? &local_error : NULL);
        g_rw_lock_reader_unlock (&(bf->priv->lock));
 
-       if (uids == NULL && local_error != NULL) {
+       if (!success) {
 
                if (g_error_matches (local_error,
-                                    E_BOOK_SDB_ERROR,
-                                    E_BOOK_SDB_ERROR_NOT_SUPPORTED)) {
+                                    E_BOOK_SQLITE_ERROR,
+                                    E_BOOK_SQLITE_ERROR_UNSUPPORTED_QUERY)) {
                        g_set_error (
-                               perror, E_DATA_BOOK_ERROR,
-                               E_DATA_BOOK_STATUS_NOT_SUPPORTED,
+                               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)) {
+                                    E_BOOK_SQLITE_ERROR,
+                                    E_BOOK_SQLITE_ERROR_INVALID_QUERY)) {
                        g_set_error (
-                               perror, E_DATA_BOOK_ERROR,
-                               E_DATA_BOOK_STATUS_INVALID_QUERY,
+                               perror, E_CLIENT_ERROR,
+                               E_CLIENT_ERROR_INVALID_QUERY,
                                _("Invalid Query '%s'"), query);
                        g_error_free (local_error);
 
@@ -1372,6 +1381,28 @@ notify_update_vcard (EDataBookView *book_view,
                e_data_book_view_notify_update_vcard (book_view, id, vcard);
 }
 
+static gboolean
+uid_rev_fields (GHashTable *fields_of_interest)
+{
+       GHashTableIter iter;
+       gpointer key, value;
+
+       if (!fields_of_interest || g_hash_table_size (fields_of_interest) > 2)
+               return FALSE;
+
+       g_hash_table_iter_init (&iter, fields_of_interest);
+       while (g_hash_table_iter_next (&iter, &key, &value)) {
+               const gchar *field_name = key;
+               EContactField field = e_contact_field_id (field_name);
+
+               if (field != E_CONTACT_UID &&
+                   field != E_CONTACT_REV)
+                       return FALSE;
+       }
+
+       return TRUE;
+}
+
 static gpointer
 book_view_thread (gpointer data)
 {
@@ -1383,6 +1414,7 @@ book_view_thread (gpointer data)
        GSList *summary_list, *l;
        GHashTable *fields_of_interest;
        GError *local_error = NULL;
+       gboolean meta_contact, success;
 
        g_return_val_if_fail (E_IS_DATA_BOOK_VIEW (data), NULL);
 
@@ -1404,6 +1436,7 @@ book_view_thread (gpointer data)
        query = e_book_backend_sexp_text (sexp);
 
        fields_of_interest = e_data_book_view_get_fields_of_interest (book_view);
+       meta_contact = uid_rev_fields (fields_of_interest);
 
        if ( !strcmp (query, "(contains \"x-evolution-any-field\" \"\")")) {
                e_data_book_view_notify_progress (book_view, -1, _("Loading..."));
@@ -1415,14 +1448,15 @@ book_view_thread (gpointer data)
        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);
+       success = e_book_sqlite_search (bf->priv->sqlitedb,
+                                       query,
+                                       meta_contact,
+                                       &summary_list,
+                                       NULL, /* GCancellable */
+                                       &local_error);
        g_rw_lock_reader_unlock (&(bf->priv->lock));
 
-       if (!summary_list && local_error != NULL) {
+       if (!success) {
                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, EDB_NOT_OPENED_ERROR);
@@ -1431,7 +1465,7 @@ book_view_thread (gpointer data)
        }
 
        for (l = summary_list; l; l = l->next) {
-               EbSdbSearchData *data = l->data;
+               EbSqlSearchData *data = l->data;
                gchar *vcard = NULL;
 
                vcard = data->vcard;
@@ -1441,7 +1475,7 @@ book_view_thread (gpointer data)
                g_free (vcard);
        }
 
-       g_slist_foreach (summary_list, (GFunc) e_book_backend_sqlitedb_search_data_free, NULL);
+       g_slist_foreach (summary_list, (GFunc) e_book_sqlite_search_data_free, NULL);
        g_slist_free (summary_list);
 
        if (e_flag_is_set (closure->running))
@@ -1579,61 +1613,6 @@ e_book_backend_file_sync (EBookBackend *backend)
 }
 
 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_is_summary_query (query) &&
-           e_book_backend_sqlitedb_is_summary_fields (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)
-{
-       GList *list, *link;
-
-       list = e_book_backend_list_views (backend);
-
-       for (link = list; link != NULL; link = g_list_next (link))
-               view_notify_update (
-                       E_BOOK_BACKEND_FILE (backend),
-                       E_DATA_BOOK_VIEW (link->data),
-                       (EContact *) contact);
-
-       g_list_free_full (list, (GDestroyNotify) g_object_unref);
-}
-
-static void
 e_book_backend_file_dispose (GObject *object)
 {
        EBookBackendFile *bf;
@@ -1675,64 +1654,69 @@ e_book_backend_file_finalize (GObject *object)
 }
 
 static void
+book_backend_file_vcard_changed (EbSqlChangeType     change_type,
+                                const gchar        *uid,
+                                const gchar        *extra,
+                                const gchar        *vcard,
+                                gpointer            user_data)
+{
+       EBookBackend *backend = E_BOOK_BACKEND (user_data);
+       EContact     *contact;
+
+       if (change_type == EBSQL_CHANGE_LOCALE_CHANGED) {
+               contact = e_contact_new_from_vcard_with_uid (vcard, uid);
+               e_book_backend_notify_update (backend, contact);
+               g_object_unref (contact);
+       }
+}
+
+static gboolean
 e_book_backend_file_set_locale (EBookBackend *backend,
-                               const gchar  *locale)
+                               const gchar  *locale,
+                               GCancellable *cancellable,
+                               GError **error)
 {
        EBookBackendFile *bf = E_BOOK_BACKEND_FILE (backend);
        gboolean success;
-       GError *error = NULL;
+       GList *l;
 
        g_rw_lock_writer_lock (&(bf->priv->lock));
-
-       success = e_book_backend_sqlitedb_lock_updates (bf->priv->sqlitedb,
-                                                       &error);
-
-       if (!success) {
-               g_warning ("Failed to start SQLite transaction: %s", error->message);
-               g_clear_error (&error);
-       }
-
-       if (success) {
-               success = e_book_backend_sqlitedb_set_locale (bf->priv->sqlitedb,
-                                                             SQLITEDB_FOLDER_ID,
-                                                             locale,
-                                                             &error);
-               if (!success) {
-                       g_warning ("Failed to set locale on SQLiteDB: %s", error->message);
-                       g_clear_error (&error);
-               }
+       if (!e_book_sqlite_lock (bf->priv->sqlitedb,
+                                EBSQL_LOCK_WRITE,
+                                cancellable, error)) {
+               g_rw_lock_writer_unlock (&(bf->priv->lock));
+               return FALSE;
        }
 
-       if (success) {
-               success = e_book_backend_file_bump_revision (bf, &error);
+       success = e_book_sqlite_set_locale (bf->priv->sqlitedb, locale,
+                                           cancellable, error);
 
-               if (!success) {
-                       g_warning ("Failed to set locale on SQLiteDB: %s", error->message);
-                       g_clear_error (&error);
-               }
-       }
+       if (success)
+               success = e_book_backend_file_bump_revision (bf, error);
 
        if (success) {
-               success = e_book_backend_sqlitedb_unlock_updates (bf->priv->sqlitedb,
-                                                                 TRUE, &error);
-
-               if (!success) {
-                       g_warning ("Failed to commit SQLite transaction: %s", error->message);
-                       g_clear_error (&error);
-               }
+               success = e_book_sqlite_unlock (bf->priv->sqlitedb,
+                                               EBSQL_UNLOCK_COMMIT,
+                                               error);
 
        } else {
                GError *error = NULL;
 
                /* Rollback transaction */
-               if (!e_book_backend_sqlitedb_unlock_updates (bf->priv->sqlitedb, FALSE, &error)) {
-                       g_warning ("Failed to rollback transaction after failing to add contacts: %s",
+               if (!e_book_sqlite_unlock (bf->priv->sqlitedb, EBSQL_UNLOCK_ROLLBACK, &error)) {
+                       g_warning ("Failed to rollback transaction after failing to set locale: %s",
                                   error->message);
                        g_clear_error (&error);
                }
        }
 
-       cursors_locale_changed (bf);
+       /* This must be done outside the EBookSqlite lock, as it may try to acquire the lock as well
+        */
+       for (l = bf->priv->cursors; success && l; l = l->next) {
+               EDataBookCursor *cursor = l->data;
+
+               success = e_data_book_cursor_load_locale (cursor, NULL, cancellable, error);
+       }
 
        /* We set the new locale, now update our local variable */
        if (success) {
@@ -1741,6 +1725,8 @@ e_book_backend_file_set_locale (EBookBackend *backend,
        }
 
        g_rw_lock_writer_unlock (&(bf->priv->lock));
+
+       return success;
 }
 
 static gchar *
@@ -1770,7 +1756,7 @@ e_book_backend_file_create_cursor (EBookBackend *backend,
 
        cursor = e_data_book_cursor_sqlite_new (backend,
                                                bf->priv->sqlitedb,
-                                               SQLITEDB_FOLDER_ID,
+                                               SQLITE_REVISION_KEY,
                                                sort_fields,
                                                sort_types,
                                                n_fields,
@@ -1825,6 +1811,7 @@ book_backend_file_initable_init (GInitable *initable,
        gchar *backup;
        gchar *dirname;
        gchar *filename;
+       gchar *fullpath;
        gboolean success = TRUE;
 
        priv = E_BOOK_BACKEND_FILE_GET_PRIVATE (initable);
@@ -1844,26 +1831,24 @@ book_backend_file_initable_init (GInitable *initable,
 
        filename = g_build_filename (dirname, "addressbook.db", NULL);
        backup = g_build_filename (dirname, "addressbook.db.old", NULL);
+       fullpath = g_build_filename (dirname, "contacts.db", NULL);
 
        /* The old BDB exists, lets migrate that to sqlite right away. */
        if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
-               priv->sqlitedb = e_book_backend_sqlitedb_new_full (
-                       dirname,
-                       SQLITEDB_EMAIL_ID,
-                       SQLITEDB_FOLDER_ID,
-                       SQLITEDB_FOLDER_NAME,
-                       TRUE, setup_extension,
-                       error);
+               priv->sqlitedb = e_book_sqlite_new_full (
+                       fullpath, setup_extension,
+                       NULL,
+                       book_backend_file_vcard_changed,
+                       initable, NULL, cancellable, error);
 
                if (priv->sqlitedb == NULL) {
                        success = FALSE;
                        goto exit;
                }
 
+               /* Do the migration from BDB, see e-book-backend-file-migrate-bdb.c */
                success = e_book_backend_file_migrate_bdb (
-                       priv->sqlitedb,
-                       SQLITEDB_FOLDER_ID,
-                       dirname, filename, error);
+                       priv->sqlitedb, dirname, filename, cancellable, error);
 
                if (!success)
                        goto exit;
@@ -1895,13 +1880,11 @@ book_backend_file_initable_init (GInitable *initable,
                        goto exit;
 
                /* Create the sqlitedb. */
-               priv->sqlitedb = e_book_backend_sqlitedb_new_full (
-                       dirname,
-                       SQLITEDB_EMAIL_ID,
-                       SQLITEDB_FOLDER_ID,
-                       SQLITEDB_FOLDER_NAME,
-                       TRUE, setup_extension,
-                       error);
+               priv->sqlitedb = e_book_sqlite_new_full (
+                       fullpath, setup_extension,
+                       NULL,
+                       book_backend_file_vcard_changed,
+                       initable, NULL, cancellable, error);
 
                if (priv->sqlitedb == NULL) {
                        success = FALSE;
@@ -1909,9 +1892,10 @@ book_backend_file_initable_init (GInitable *initable,
                }
 
                /* An sqlite DB only 'exists' if the populated flag is set. */
-               populated = e_book_backend_sqlitedb_get_is_populated (
+               e_book_sqlite_get_key_value_int (
                        priv->sqlitedb,
-                       SQLITEDB_FOLDER_ID,
+                       E_BOOK_SQL_IS_POPULATED_KEY,
+                       &populated,
                        &local_error);
 
                if (local_error != NULL) {
@@ -1922,10 +1906,11 @@ book_backend_file_initable_init (GInitable *initable,
 
                if (!populated) {
                        /* Set the populated flag. */
-                       success = e_book_backend_sqlitedb_set_is_populated (
+                       success = e_book_sqlite_set_key_value_int (
                                priv->sqlitedb,
-                               SQLITEDB_FOLDER_ID,
-                               TRUE, error);
+                               E_BOOK_SQL_IS_POPULATED_KEY,
+                               TRUE,
+                               error);
 
                        if (!success)
                                goto exit;
@@ -1943,6 +1928,7 @@ book_backend_file_initable_init (GInitable *initable,
 
 exit:
        g_free (dirname);
+       g_free (fullpath);
        g_free (filename);
        g_free (backup);
 
@@ -2005,7 +1991,6 @@ e_book_backend_file_class_init (EBookBackendFileClass *class)
        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;
        backend_class->set_locale               = e_book_backend_file_set_locale;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]