[evolution-data-server] Simplify direct access to address books.



commit e72e1a50f7d4716d554f694fc29591d64b5d76e4
Author: Matthew Barnes <mbarnes redhat com>
Date:   Fri Mar 29 17:49:12 2013 -0400

    Simplify direct access to address books.
    
    EBookBackend's new public API allows Direct Access Mode to bypass
    EDataBook and talk to the EBookBackend directly, which is appropriate
    since EDataBook is just glue code for remote D-Bus method invocations.

 addressbook/libebook/e-book-client-view.c          |  104 ++-
 addressbook/libebook/e-book-client.c               |  212 ++++-
 addressbook/libedata-book/e-data-book.c            | 1038 +++-----------------
 addressbook/libedata-book/e-data-book.h            |   69 --
 .../libedata-book/libedata-book-sections.txt       |   14 -
 5 files changed, 375 insertions(+), 1062 deletions(-)
---
diff --git a/addressbook/libebook/e-book-client-view.c b/addressbook/libebook/e-book-client-view.c
index 151f427..e4e0bec 100644
--- a/addressbook/libebook/e-book-client-view.c
+++ b/addressbook/libebook/e-book-client-view.c
@@ -47,7 +47,7 @@ struct _EBookClientViewPrivate {
        guint running : 1;
        guint complete : 1;
 
-       EDataBook *direct_book;
+       EBookBackend *direct_backend;
 
        gulong objects_added_handler_id;
        gulong objects_modified_handler_id;
@@ -69,7 +69,7 @@ enum {
        PROP_0,
        PROP_CLIENT,
        PROP_CONNECTION,
-       PROP_DIRECT_BOOK,
+       PROP_DIRECT_BACKEND,
        PROP_OBJECT_PATH
 };
 
@@ -317,15 +317,20 @@ direct_contacts_ready (GObject *source_object,
                        gpointer user_data)
 {
        NotificationData *data = (NotificationData *) user_data;
-       GSList *contacts = NULL;
+       GQueue queue = G_QUEUE_INIT;
+       GSList *list = NULL;
        GError *error = NULL;
 
-       e_data_book_get_contacts_finish (
-               E_DATA_BOOK (source_object),
-               result, &contacts, &error);
+       e_book_backend_get_contact_list_finish (
+               E_BOOK_BACKEND (source_object), result, &queue, &error);
+
+       while (!g_queue_is_empty (&queue))
+               list = g_slist_prepend (list, g_queue_pop_head (&queue));
+
+       list = g_slist_reverse (list);
 
        if (error != NULL) {
-               g_warn_if_fail (contacts == NULL);
+               g_warn_if_fail (list == NULL);
                g_warning (
                        "Error fetching contacts directly: %s\n",
                        error->message);
@@ -334,15 +339,15 @@ direct_contacts_ready (GObject *source_object,
        } else if (data->signum == OBJECTS_ADDED) {
                /* Takes ownership of the linked list. */
                book_client_view_emit_objects_added (
-                       data->client_view, contacts);
+                       data->client_view, list);
 
        } else if (data->signum == OBJECTS_MODIFIED) {
                /* Takes ownership of the linked list. */
                book_client_view_emit_objects_modified (
-                       data->client_view, contacts);
+                       data->client_view, list);
 
        } else {
-               g_slist_free_full (contacts, (GDestroyNotify) g_object_unref);
+               g_slist_free_full (list, (GDestroyNotify) g_object_unref);
        }
 
        g_object_unref (data->client_view);
@@ -354,22 +359,32 @@ direct_contacts_fetch (EBookClientView *client_view,
                        const gchar * const *uids,
                        guint signum)
 {
+       EBookBackend *backend;
        NotificationData *data;
        gchar *sexp = direct_contacts_query (uids);
 
+       backend = client_view->priv->direct_backend;
+
        /* Until the view has completely loaded, we need to make
         * sync calls to the backend
         */
        if (!client_view->priv->complete) {
-               GSList *contacts = NULL;
+               GQueue queue = G_QUEUE_INIT;
+               GSList *list = NULL;
                GError *error = NULL;
 
-               e_data_book_get_contacts_sync (
-                       client_view->priv->direct_book,
-                       sexp, &contacts, NULL, &error);
+               e_book_backend_get_contact_list_sync (
+                       backend, sexp, &queue, NULL, &error);
+
+               while (!g_queue_is_empty (&queue)) {
+                       list = g_slist_prepend (
+                               list, g_queue_pop_head (&queue));
+               }
+
+               list = g_slist_reverse (list);
 
                if (error != NULL) {
-                       g_warn_if_fail (contacts == NULL);
+                       g_warn_if_fail (list == NULL);
                        g_warning (
                                "Error fetching contacts directly: %s\n",
                                error->message);
@@ -378,16 +393,16 @@ direct_contacts_fetch (EBookClientView *client_view,
                } else if (signum == OBJECTS_ADDED) {
                        /* Takes ownership of the linked list. */
                        book_client_view_emit_objects_added (
-                               client_view, contacts);
+                               client_view, list);
 
                } else if (signum == OBJECTS_MODIFIED) {
                        /* Takes ownership of the linked list. */
                        book_client_view_emit_objects_modified (
-                               client_view, contacts);
+                               client_view, list);
 
                } else {
                        g_slist_free_full (
-                               contacts, (GDestroyNotify) g_object_unref);
+                               list, (GDestroyNotify) g_object_unref);
                }
 
        } else {
@@ -398,9 +413,8 @@ direct_contacts_fetch (EBookClientView *client_view,
                data->client_view = g_object_ref (client_view);
                data->signum = signum;
 
-               e_data_book_get_contacts (
-                       client_view->priv->direct_book,
-                       sexp, NULL, direct_contacts_ready, data);
+               e_book_backend_get_contact_list (
+                       backend, sexp, NULL, direct_contacts_ready, data);
        }
 
        g_free (sexp);
@@ -418,7 +432,7 @@ book_client_view_objects_added_cb (EGdbusBookView *object,
                return;
 
        /* array contains UIDs only */
-       if (client_view->priv->direct_book != NULL) {
+       if (client_view->priv->direct_backend != NULL) {
                direct_contacts_fetch (client_view, vcards, OBJECTS_ADDED);
                return;
        }
@@ -451,7 +465,7 @@ book_client_view_objects_modified_cb (EGdbusBookView *object,
                return;
 
        /* array contains UIDs only */
-       if (client_view->priv->direct_book != NULL) {
+       if (client_view->priv->direct_backend != NULL) {
                direct_contacts_fetch (client_view, vcards, OBJECTS_MODIFIED);
                return;
        }
@@ -637,14 +651,16 @@ book_client_view_set_connection (EBookClientView *client_view,
 }
 
 static void
-book_client_view_set_direct_book (EBookClientView *client_view,
-                                  EDataBook *book)
+book_client_view_set_direct_backend (EBookClientView *client_view,
+                                     EBookBackend *backend)
 {
-       g_return_if_fail (book == NULL || E_IS_DATA_BOOK (book));
-       g_return_if_fail (client_view->priv->direct_book == NULL);
+       if (backend == NULL)
+               return;
 
-       if (book != NULL)
-               client_view->priv->direct_book = g_object_ref (book);
+       g_return_if_fail (E_IS_BOOK_BACKEND (backend));
+       g_return_if_fail (client_view->priv->direct_backend == NULL);
+
+       client_view->priv->direct_backend = g_object_ref (backend);
 }
 
 static void
@@ -676,8 +692,8 @@ book_client_view_set_property (GObject *object,
                                g_value_get_object (value));
                        return;
 
-               case PROP_DIRECT_BOOK:
-                       book_client_view_set_direct_book (
+               case PROP_DIRECT_BACKEND:
+                       book_client_view_set_direct_backend (
                                E_BOOK_CLIENT_VIEW (object),
                                g_value_get_object (value));
                        return;
@@ -738,9 +754,9 @@ book_client_view_dispose (GObject *object)
                priv->connection = NULL;
        }
 
-       if (priv->direct_book != NULL) {
-               g_object_unref (priv->direct_book);
-               priv->direct_book = NULL;
+       if (priv->direct_backend != NULL) {
+               g_object_unref (priv->direct_backend);
+               priv->direct_backend = NULL;
        }
 
        if (priv->dbus_proxy != NULL) {
@@ -835,9 +851,8 @@ book_client_view_initable_init (GInitable *initable,
        priv->complete_handler_id = handler_id;
 
        /* When in direct read access mode, we add a special field
-        * to fields-of-interest indicating we only want uids sent
-        */
-       if (priv->direct_book)
+        * to fields-of-interest indicating we only want uids sent. */
+       if (priv->direct_backend != NULL)
                e_book_client_view_set_fields_of_interest (
                        E_BOOK_CLIENT_VIEW (initable), NULL, NULL);
 
@@ -884,14 +899,14 @@ e_book_client_view_class_init (EBookClientViewClass *class)
 
        g_object_class_install_property (
                object_class,
-               PROP_DIRECT_BOOK,
+               PROP_DIRECT_BACKEND,
                g_param_spec_object (
-                       "direct-book",
-                       "Direct Book",
-                       "The EDataBook to fetch contact "
+                       "direct-backend",
+                       "Direct Backend",
+                       "The EBookBackend to fetch contact "
                        "data from, if direct read access "
                        "is enabled",
-                       E_TYPE_DATA_BOOK,
+                       E_TYPE_BOOK_BACKEND,
                        G_PARAM_WRITABLE |
                        G_PARAM_CONSTRUCT_ONLY |
                        G_PARAM_STATIC_STRINGS));
@@ -1184,9 +1199,8 @@ e_book_client_view_set_fields_of_interest (EBookClientView *client_view,
         * backend is configured to only send us UIDs for everything,
         *
         * Just ignore the fields_of_interest and use them locally
-        * when filtering cards to be returned in direct reads.
-        */
-       if (client_view->priv->direct_book) {
+        * when filtering cards to be returned in direct reads. */
+       if (client_view->priv->direct_backend != NULL) {
                GSList uid_field = { 0, };
 
                uid_field.data = (gpointer)"x-evolution-uids-only";
diff --git a/addressbook/libebook/e-book-client.c b/addressbook/libebook/e-book-client.c
index 990215d..feab850 100644
--- a/addressbook/libebook/e-book-client.c
+++ b/addressbook/libebook/e-book-client.c
@@ -54,7 +54,7 @@ typedef struct _RunInThreadClosure RunInThreadClosure;
 
 struct _EBookClientPrivate {
        EDBusAddressBook *dbus_proxy;
-       EDataBook *direct_book;
+       EBookBackend *direct_backend;
        guint name_watcher_id;
 
        gulong dbus_proxy_error_handler_id;
@@ -178,6 +178,104 @@ run_in_thread_closure_free (RunInThreadClosure *run_in_thread_closure)
  *   @CLIENT_BACKEND_PROPERTY_CACHE_DIR, @CLIENT_BACKEND_PROPERTY_CAPABILITIES
  */
 
+static EBookBackend *
+book_client_load_direct_backend (ESourceRegistry *registry,
+                                 ESource *source,
+                                 const gchar *backend_path,
+                                 const gchar *backend_name,
+                                 const gchar *config,
+                                 GError **error)
+{
+       static GHashTable *modules_table = NULL;
+       G_LOCK_DEFINE_STATIC (modules_table);
+
+       EModule *module;
+       GType factory_type;
+       EBookBackend *backend;
+       EBookBackendFactoryClass *factory_class;
+
+       g_return_val_if_fail (backend_path != NULL, NULL);
+       g_return_val_if_fail (backend_name != NULL, NULL);
+
+       G_LOCK (modules_table);
+
+       if (modules_table == NULL)
+               modules_table = g_hash_table_new (
+                       (GHashFunc) g_str_hash,
+                       (GEqualFunc) g_str_equal);
+
+       module = g_hash_table_lookup (modules_table, backend_path);
+
+       if (module == NULL) {
+               module = e_module_new (backend_path);
+               g_hash_table_insert (
+                       modules_table, g_strdup (backend_path), module);
+       }
+
+       G_UNLOCK (modules_table);
+
+       if (!g_type_module_use (G_TYPE_MODULE (module))) {
+               g_set_error (
+                       error, E_CLIENT_ERROR,
+                       E_CLIENT_ERROR_OTHER_ERROR,
+                       "Failed to use EModule at path '%s'",
+                       backend_path);
+               return NULL;
+       }
+
+       factory_type = g_type_from_name (backend_name);
+       if (factory_type == G_TYPE_INVALID) {
+               g_set_error (
+                       error, E_CLIENT_ERROR,
+                       E_CLIENT_ERROR_OTHER_ERROR,
+                       "Failed to get backend factory '%s' "
+                       "from EModule at path '%s'",
+                       backend_name, backend_path);
+               g_type_module_unuse (G_TYPE_MODULE (module));
+               return NULL;
+       }
+
+       factory_class = g_type_class_ref (factory_type);
+
+       backend = g_object_new (
+               factory_class->backend_type,
+               "registry", registry,
+               "source", source, NULL);
+
+       /* The backend must be configured for direct access
+        * before calling g_initable_init(), since backends
+        * can access their content in initable_init(). */
+       e_book_backend_configure_direct (backend, config);
+
+       if (!g_initable_init (G_INITABLE (backend), NULL, error)) {
+               g_type_module_unuse (G_TYPE_MODULE (module));
+               g_object_unref (backend);
+               backend = NULL;
+       }
+
+       g_type_class_unref (factory_class);
+
+       /* XXX Until backend methods can be updated, EBookBackend
+        *     still needs an EDataBook to catch "respond" calls. */
+       if (backend != NULL) {
+               EDataBook *data_book;
+
+               data_book = g_initable_new (
+                       E_TYPE_DATA_BOOK, NULL, error,
+                       "backend", backend, NULL);
+
+               if (data_book == NULL) {
+                       g_type_module_unuse (G_TYPE_MODULE (module));
+                       g_object_unref (backend);
+                       backend = NULL;
+               }
+
+               g_clear_object (&data_book);
+       }
+
+       return backend;
+}
+
 static gpointer
 book_client_dbus_thread (gpointer user_data)
 {
@@ -548,10 +646,9 @@ book_client_dispose (GObject *object)
                priv->dbus_proxy = NULL;
        }
 
-       if (priv->direct_book != NULL) {
-               e_data_book_close_sync (priv->direct_book, NULL, NULL);
-               g_object_unref (priv->direct_book);
-               priv->direct_book = NULL;
+       if (priv->direct_backend != NULL) {
+               g_object_unref (priv->direct_backend);
+               priv->direct_backend = NULL;
        }
 
        /* Chain up to parent's dispose() method. */
@@ -1244,14 +1341,14 @@ e_book_client_connect_direct_sync (ESourceRegistry *registry,
        backend_name = e_dbus_direct_book_get_backend_name (direct_config);
        config = e_dbus_direct_book_get_backend_config (direct_config);
 
-       if (backend_path && backend_path[0] &&
-           backend_name && backend_name[0]) {
-               priv->direct_book = e_data_book_new_direct (
+       if (backend_path != NULL && *backend_path != '\0' &&
+           backend_name != NULL && *backend_name != '\0') {
+               priv->direct_backend = book_client_load_direct_backend (
                        registry, source,
                        backend_path,
                        backend_name,
                        config, &local_error);
-               if (!priv->direct_book) {
+               if (local_error != NULL) {
                        g_warning (
                                "Failed to open addressbook in direct read "
                                "access mode, falling back to normal read "
@@ -1268,16 +1365,21 @@ e_book_client_connect_direct_sync (ESourceRegistry *registry,
 
        g_object_unref (direct_config);
 
-       /* We have to perform the opeining of the direct book separately
+       /* We have to perform the opening of the direct backend separately
         * from the EClient->open() implementation, because the direct
-        * book does not exist yet
-        */
-       if (priv->direct_book &&
-           !e_data_book_open_sync (priv->direct_book, cancellable, error)) {
-               g_warning (
-                       "Unable to open direct read access book, "
-                       "falling back to normal read access mode");
-               g_clear_object (&priv->direct_book);
+        * backend does not exist yet. */
+       if (priv->direct_backend != NULL) {
+               gboolean success;
+
+               success = e_book_backend_open_sync (
+                       priv->direct_backend, cancellable, error);
+
+               if (!success) {
+                       g_warning (
+                               "Unable to open direct read access book, "
+                               "falling back to normal read access mode");
+                       g_clear_object (&priv->direct_backend);
+               }
        }
 
        return client;
@@ -2663,10 +2765,22 @@ e_book_client_get_contact_sync (EBookClient *client,
        g_return_val_if_fail (uid != NULL, FALSE);
        g_return_val_if_fail (out_contact != NULL, FALSE);
 
-       if (client->priv->direct_book != NULL)
-               return e_data_book_get_contact_sync (
-                       client->priv->direct_book, uid,
-                       out_contact, cancellable, error);
+       if (client->priv->direct_backend != NULL) {
+               EContact *contact;
+               gboolean success = FALSE;
+
+               contact = e_book_backend_get_contact_sync (
+                       client->priv->direct_backend,
+                       uid, cancellable, error);
+
+               if (contact != NULL) {
+                       *out_contact = g_object_ref (contact);
+                       g_object_unref (contact);
+                       success = TRUE;
+               }
+
+               return success;
+       }
 
        utf8_uid = e_util_utf8_make_valid (uid);
 
@@ -2839,10 +2953,28 @@ e_book_client_get_contacts_sync (EBookClient *client,
        g_return_val_if_fail (sexp != NULL, FALSE);
        g_return_val_if_fail (out_contacts != NULL, FALSE);
 
-       if (client->priv->direct_book != NULL)
-               return e_data_book_get_contacts_sync (
-                       client->priv->direct_book,
-                       sexp, out_contacts, cancellable, error);
+       if (client->priv->direct_backend != NULL) {
+               GQueue queue = G_QUEUE_INIT;
+               GSList *list = NULL;
+               gboolean success;
+
+               success = e_book_backend_get_contact_list_sync (
+                       client->priv->direct_backend,
+                       sexp, &queue, cancellable, error);
+
+               if (success) {
+                       while (!g_queue_is_empty (&queue)) {
+                               EContact *contact;
+
+                               contact = g_queue_pop_head (&queue);
+                               list = g_slist_prepend (list, contact);
+                       }
+
+                       *out_contacts = g_slist_reverse (list);
+               }
+
+               return success;
+       }
 
        utf8_sexp = e_util_utf8_make_valid (sexp);
 
@@ -3024,10 +3156,28 @@ e_book_client_get_contacts_uids_sync (EBookClient *client,
        g_return_val_if_fail (sexp != NULL, FALSE);
        g_return_val_if_fail (out_contact_uids != NULL, FALSE);
 
-       if (client->priv->direct_book != NULL)
-               return e_data_book_get_contacts_uids_sync (
-                       client->priv->direct_book, sexp,
-                       out_contact_uids, cancellable, error);
+       if (client->priv->direct_backend != NULL) {
+               GQueue queue = G_QUEUE_INIT;
+               GSList *list = NULL;
+               gboolean success;
+
+               success = e_book_backend_get_contact_list_uids_sync (
+                       client->priv->direct_backend,
+                       sexp, &queue, cancellable, error);
+
+               if (success) {
+                       while (!g_queue_is_empty (&queue)) {
+                               gchar *uid;
+
+                               uid = g_queue_pop_head (&queue);
+                               list = g_slist_prepend (list, uid);
+                       }
+
+                       *out_contact_uids = g_slist_reverse (list);
+               }
+
+               return success;
+       }
 
        utf8_sexp = e_util_utf8_make_valid (sexp);
 
@@ -3103,7 +3253,7 @@ book_client_get_view_in_dbus_thread (GSimpleAsyncResult *simple,
                        "client", client,
                        "connection", connection,
                        "object-path", object_path,
-                       "direct-book", client->priv->direct_book,
+                       "direct-backend", client->priv->direct_backend,
                        NULL);
 
                /* Sanity check. */
diff --git a/addressbook/libedata-book/e-data-book.c b/addressbook/libedata-book/e-data-book.c
index 5f81fe6..d9008be 100644
--- a/addressbook/libedata-book/e-data-book.c
+++ b/addressbook/libedata-book/e-data-book.c
@@ -69,13 +69,6 @@ enum {
        PROP_OBJECT_PATH
 };
 
-/* EModule's can never be free'd, however the use count can change
- * Here we ensure that there is only one ever created by way of
- * static variables and locks
- */
-static GHashTable *modules_table = NULL;
-G_LOCK_DEFINE (modules_table);
-
 /* Forward Declarations */
 static void e_data_book_initable_init (GInitableIface *interface);
 
@@ -202,31 +195,6 @@ async_context_free (AsyncContext *async_context)
        g_slice_free (AsyncContext, async_context);
 }
 
-static EModule *
-load_module (const gchar *module_path)
-{
-       EModule *module = NULL;
-
-       G_LOCK (modules_table);
-
-       if (!modules_table)
-               modules_table = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
-       module = g_hash_table_lookup (modules_table, module_path);
-
-       if (!module) {
-               module = e_module_new (module_path);
-               if (!module)
-                       g_warning ("Failed to open EModule at path: %s", module_path);
-               else
-                       g_hash_table_insert (modules_table, g_strdup (module_path), module);
-       }
-
-       G_UNLOCK (modules_table);
-
-       return module;
-}
-
 static gchar *
 construct_bookview_path (void)
 {
@@ -1672,6 +1640,71 @@ data_book_finalize (GObject *object)
        G_OBJECT_CLASS (e_data_book_parent_class)->finalize (object);
 }
 
+static void
+data_book_constructed (GObject *object)
+{
+       EDataBook *book = E_DATA_BOOK (object);
+       EBookBackend *backend;
+       const gchar *prop_name;
+       gchar *prop_value;
+
+       /* Chain up to parent's constructed() method. */
+       G_OBJECT_CLASS (e_data_book_parent_class)->constructed (object);
+
+       backend = e_data_book_ref_backend (book);
+       g_warn_if_fail (backend != NULL);
+
+       /* Attach ourselves to the EBookBackend. */
+       e_book_backend_set_data_book (backend, book);
+
+       g_object_bind_property (
+               backend, "cache-dir",
+               book->priv->dbus_interface, "cache-dir",
+               G_BINDING_SYNC_CREATE);
+
+       g_object_bind_property (
+               backend, "online",
+               book->priv->dbus_interface, "online",
+               G_BINDING_SYNC_CREATE);
+
+       g_object_bind_property (
+               backend, "writable",
+               book->priv->dbus_interface, "writable",
+               G_BINDING_SYNC_CREATE);
+
+       /* XXX Initialize the rest of the properties. */
+
+       prop_name = CLIENT_BACKEND_PROPERTY_CAPABILITIES;
+       prop_value = e_book_backend_get_backend_property_sync (
+               backend, prop_name, NULL, NULL);
+       e_data_book_report_backend_property_changed (
+               book, prop_name, prop_value);
+       g_free (prop_value);
+
+       prop_name = CLIENT_BACKEND_PROPERTY_REVISION;
+       prop_value = e_book_backend_get_backend_property_sync (
+               backend, prop_name, NULL, NULL);
+       e_data_book_report_backend_property_changed (
+               book, prop_name, prop_value);
+       g_free (prop_value);
+
+       prop_name = BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS;
+       prop_value = e_book_backend_get_backend_property_sync (
+               backend, prop_name, NULL, NULL);
+       e_data_book_report_backend_property_changed (
+               book, prop_name, prop_value);
+       g_free (prop_value);
+
+       prop_name = BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS;
+       prop_value = e_book_backend_get_backend_property_sync (
+               backend, prop_name, NULL, NULL);
+       e_data_book_report_backend_property_changed (
+               book, prop_name, prop_value);
+       g_free (prop_value);
+
+       g_object_unref (backend);
+}
+
 static gboolean
 data_book_initable_init (GInitable *initable,
                          GCancellable *cancellable,
@@ -1679,124 +1712,40 @@ data_book_initable_init (GInitable *initable,
 {
        EBookBackend *backend;
        EDataBook *book;
-       gboolean success = TRUE;
 
        book = E_DATA_BOOK (initable);
 
-       backend = e_data_book_ref_backend (book);
+       /* XXX If we're serving a direct access backend only for the
+        *     purpose of catching "respond" calls, skip this stuff. */
+       if (book->priv->connection == NULL)
+               return TRUE;
+       if (book->priv->object_path == NULL)
+               return TRUE;
 
-       /* Attach ourselves to the EBookBackend. */
-       e_book_backend_set_data_book (backend, book);
+       /* This will be NULL for a backend that
+        * does not support direct read access. */
+       backend = e_data_book_ref_backend (book);
+       book->priv->direct_book = e_book_backend_get_direct_book (backend);
+       g_object_unref (backend);
 
-       if (book->priv->connection != NULL && book->priv->object_path != NULL) {
-               const gchar *prop_name;
-               gchar *prop_value;
-
-               book->priv->dbus_interface =
-                       e_dbus_address_book_skeleton_new ();
-
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-open",
-                       G_CALLBACK (data_book_handle_open_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-refresh",
-                       G_CALLBACK (data_book_handle_refresh_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-get-contact",
-                       G_CALLBACK (data_book_handle_get_contact_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-get-contact-list",
-                       G_CALLBACK (data_book_handle_get_contact_list_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-get-contact-list-uids",
-                       G_CALLBACK (data_book_handle_get_contact_list_uids_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-create-contacts",
-                       G_CALLBACK (data_book_handle_create_contacts_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-remove-contacts",
-                       G_CALLBACK (data_book_handle_remove_contacts_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-modify-contacts",
-                       G_CALLBACK (data_book_handle_modify_contacts_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-get-view",
-                       G_CALLBACK (data_book_handle_get_view_cb), book);
-               g_signal_connect (
-                       book->priv->dbus_interface, "handle-close",
-                       G_CALLBACK (data_book_handle_close_cb), book);
-
-               /* This will be NULL for a backend that does not support
-                * direct read access. */
-               book->priv->direct_book =
-                       e_book_backend_get_direct_book (backend);
-
-               if (book->priv->direct_book != NULL) {
-                       success = e_data_book_direct_register_gdbus_object (
-                               book->priv->direct_book,
-                               book->priv->connection,
-                               book->priv->object_path,
-                               error);
-                       if (!success)
-                               goto exit;
-               }
+       if (book->priv->direct_book != NULL) {
+               gboolean success;
 
-               g_object_bind_property (
-                       backend, "cache-dir",
-                       book->priv->dbus_interface, "cache-dir",
-                       G_BINDING_SYNC_CREATE);
-
-               g_object_bind_property (
-                       backend, "online",
-                       book->priv->dbus_interface, "online",
-                       G_BINDING_SYNC_CREATE);
-
-               g_object_bind_property (
-                       backend, "writable",
-                       book->priv->dbus_interface, "writable",
-                       G_BINDING_SYNC_CREATE);
-
-               /* XXX Initialize the rest of the properties. */
-
-               prop_name = CLIENT_BACKEND_PROPERTY_CAPABILITIES;
-               prop_value = e_book_backend_get_backend_property_sync (
-                       backend, prop_name, NULL, NULL);
-               e_data_book_report_backend_property_changed (
-                       book, prop_name, prop_value);
-               g_free (prop_value);
-
-               prop_name = CLIENT_BACKEND_PROPERTY_REVISION;
-               prop_value = e_book_backend_get_backend_property_sync (
-                       backend, prop_name, NULL, NULL);
-               e_data_book_report_backend_property_changed (
-                       book, prop_name, prop_value);
-               g_free (prop_value);
-
-               prop_name = BOOK_BACKEND_PROPERTY_REQUIRED_FIELDS;
-               prop_value = e_book_backend_get_backend_property_sync (
-                       backend, prop_name, NULL, NULL);
-               e_data_book_report_backend_property_changed (
-                       book, prop_name, prop_value);
-               g_free (prop_value);
-
-               prop_name = BOOK_BACKEND_PROPERTY_SUPPORTED_FIELDS;
-               prop_value = e_book_backend_get_backend_property_sync (
-                       backend, prop_name, NULL, NULL);
-               e_data_book_report_backend_property_changed (
-                       book, prop_name, prop_value);
-               g_free (prop_value);
-
-               success = g_dbus_interface_skeleton_export (
-                       G_DBUS_INTERFACE_SKELETON (book->priv->dbus_interface),
+               success = e_data_book_direct_register_gdbus_object (
+                       book->priv->direct_book,
                        book->priv->connection,
                        book->priv->object_path,
                        error);
-       }
 
-exit:
-       g_clear_object (&backend);
+               if (!success)
+                       return FALSE;
+       }
 
-       return success;
+       return g_dbus_interface_skeleton_export (
+               G_DBUS_INTERFACE_SKELETON (book->priv->dbus_interface),
+               book->priv->connection,
+               book->priv->object_path,
+               error);
 }
 
 static void
@@ -1811,6 +1760,7 @@ e_data_book_class_init (EDataBookClass *class)
        object_class->get_property = data_book_get_property;
        object_class->dispose = data_book_dispose;
        object_class->finalize = data_book_finalize;
+       object_class->constructed = data_book_constructed;
 
        g_object_class_install_property (
                object_class,
@@ -1860,8 +1810,13 @@ e_data_book_initable_init (GInitableIface *interface)
 static void
 e_data_book_init (EDataBook *data_book)
 {
+       EDBusAddressBook *dbus_interface;
+
        data_book->priv = E_DATA_BOOK_GET_PRIVATE (data_book);
 
+       dbus_interface = e_dbus_address_book_skeleton_new ();
+       data_book->priv->dbus_interface = dbus_interface;
+
        g_mutex_init (&data_book->priv->sender_lock);
 
        data_book->priv->sender_table = g_hash_table_new_full (
@@ -1869,6 +1824,47 @@ e_data_book_init (EDataBook *data_book)
                (GEqualFunc) g_str_equal,
                (GDestroyNotify) g_free,
                (GDestroyNotify) g_ptr_array_unref);
+
+       g_signal_connect (
+               dbus_interface, "handle-open",
+               G_CALLBACK (data_book_handle_open_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-refresh",
+               G_CALLBACK (data_book_handle_refresh_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-get-contact",
+               G_CALLBACK (data_book_handle_get_contact_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-get-contact-list",
+               G_CALLBACK (data_book_handle_get_contact_list_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-get-contact-list-uids",
+               G_CALLBACK (data_book_handle_get_contact_list_uids_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-create-contacts",
+               G_CALLBACK (data_book_handle_create_contacts_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-remove-contacts",
+               G_CALLBACK (data_book_handle_remove_contacts_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-modify-contacts",
+               G_CALLBACK (data_book_handle_modify_contacts_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-get-view",
+               G_CALLBACK (data_book_handle_get_view_cb),
+               data_book);
+       g_signal_connect (
+               dbus_interface, "handle-close",
+               G_CALLBACK (data_book_handle_close_cb),
+               data_book);
 }
 
 /**
@@ -1904,111 +1900,6 @@ e_data_book_new (EBookBackend *backend,
 }
 
 /**
- * e_data_book_new_direct:
- * @registry: The #ESourceRegistry
- * @source: The #ESource to create a book for
- * @backend_path: The full path to the backend module to use
- * @backend_name: The #EDataFactory type name to use from the module specified by @backend_path
- * @config: The backend specific configuration string specified by the #EDataBookDirect
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Creates an #EDataBook for Direct Read Access, the @backend_path, @backend_name and @config
- * parameters are fetched from an #EDataBookDirect reported over D-Bus from the server side
- * counter part of a given backend.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Returns: (transfer full): A newly created #EDataBook for direct read access,
- *          otherwise %NULL is returned and @error is set.
- *
- * Since: 3.8
- */
-EDataBook *
-e_data_book_new_direct (ESourceRegistry *registry,
-                        ESource *source,
-                        const gchar *backend_path,
-                        const gchar *backend_name,
-                        const gchar *config,
-                        GError **error)
-{
-       EDataBook *book = NULL;
-       EModule *module;
-       EBookBackend *backend;
-       GType backend_type;
-       GType factory_type;
-       GTypeClass *factory_class;
-
-       g_return_val_if_fail (E_IS_SOURCE_REGISTRY (registry), NULL);
-       g_return_val_if_fail (E_IS_SOURCE (source), NULL);
-       g_return_val_if_fail (backend_path && backend_path[0], NULL);
-       g_return_val_if_fail (backend_name && backend_name[0], NULL);
-
-       module = load_module (backend_path);
-       if (!module) {
-               g_set_error (
-                       error, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_OTHER_ERROR,
-                       "Failed to load module at specified path: %s", backend_path);
-               goto new_direct_finish;
-       }
-
-       if (!g_type_module_use (G_TYPE_MODULE (module))) {
-               g_set_error (
-                       error, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_OTHER_ERROR,
-                       "Failed to use EModule at path: %s", backend_path);
-               goto new_direct_finish;
-       }
-
-       factory_type = g_type_from_name (backend_name);
-       if (factory_type == 0) {
-               g_set_error (
-                       error, E_CLIENT_ERROR,
-                       E_CLIENT_ERROR_OTHER_ERROR,
-                       "Failed to get backend factory '%s' from EModule at path: %s",
-                       backend_name, backend_path);
-               g_type_module_unuse (G_TYPE_MODULE (module));
-               goto new_direct_finish;
-       }
-
-       factory_class = g_type_class_ref (factory_type);
-       backend_type  = E_BOOK_BACKEND_FACTORY_CLASS (factory_class)->backend_type;
-       g_type_class_unref (factory_class);
-
-       backend = g_object_new (
-               backend_type,
-               "registry", registry,
-               "source", source, NULL);
-
-       /* The backend must be configured for direct access
-        * before calling g_initable_init() because backends
-        * now can open thier content at initable_init() time. */
-       e_book_backend_configure_direct (backend, config);
-
-       if (!g_initable_init (G_INITABLE (backend), NULL, error)) {
-               g_object_unref (backend);
-               g_type_module_unuse (G_TYPE_MODULE (module));
-               goto new_direct_finish;
-       }
-
-       book = g_initable_new (
-               E_TYPE_DATA_BOOK, NULL, error,
-               "backend", backend, NULL);
-
-       if (!book) {
-               g_type_module_unuse (G_TYPE_MODULE (module));
-               goto new_direct_finish;
-       }
-
-       book->priv->direct_module = module;
-
- new_direct_finish:
-
-       return book;
-}
-
-/**
  * e_data_book_ref_backend:
  * @book: an #EDataBook
  *
@@ -2094,662 +1985,3 @@ e_data_book_is_opened (EDataBook *book)
        return book->priv->opened;
 }
 
-/*************************************************************************
- *                        Direct Read Access APIs                        *
- *************************************************************************/
-
-/**
- * e_data_book_open_sync:
- * @book: an #EDataBook
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Opens the #EDataBook and it's backend.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Returns: %TRUE on success. If %FALSE is returned, @error will be set
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_open_sync (EDataBook *book,
-                       GCancellable *cancellable,
-                       GError **error)
-{
-       EBookBackend *backend;
-       gboolean success;
-
-       g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
-
-       backend = e_data_book_ref_backend (book);
-       g_return_val_if_fail (backend != NULL, FALSE);
-
-       success = e_book_backend_open_sync (backend, cancellable, error);
-
-       g_object_unref (backend);
-
-       return success;
-}
-
-/**
- * e_data_book_close:
- * @book: an #EDataBook
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @callback: (scope async): a #GAsyncReadyCallback to call when the request
- *            is satisfied
- * @user_data: (closure): data to pass to @callback
- *
- * Closes the @book and its backend.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Since: 3.8
- */
-void
-e_data_book_close (EDataBook *book,
-                   GCancellable *cancellable,
-                   GAsyncReadyCallback callback,
-                   gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-
-       g_return_if_fail (E_IS_DATA_BOOK (book));
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (book), callback,
-               user_data, e_data_book_close);
-
-       g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-       /* XXX This operation has no GDBusMethodInvocation,
-        *     so there's nothing to do. */
-       g_simple_async_result_complete_in_idle (simple);
-
-       g_object_unref (simple);
-}
-
-/**
- * e_data_book_close_finish:
- * @book: an #EDataBook
- * @result: a #GAsyncResult
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Finishes the operation started with e_data_book_close().  If an
- * error occurs, then this function sets @error and returns %FALSE.
- *
- * Returns: %TRUE on success
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_close_finish (EDataBook *book,
-                          GAsyncResult *result,
-                          GError **error)
-{
-       GSimpleAsyncResult *simple;
-
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (book), e_data_book_close), FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-
-       /* Assume success unless a GError is set. */
-       return !g_simple_async_result_propagate_error (simple, error);
-}
-
-/**
- * e_data_book_close_sync:
- * @book: an #EDataBook
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Closes the @book and its backend.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Returns: %TRUE on success. If %FALSE is returned, @error will be set
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_close_sync (EDataBook *book,
-                        GCancellable *cancellable,
-                        GError **error)
-{
-       /* XXX This operation has no GDBusMethodInvocation,
-        *     so there's nothing to do. */
-       return TRUE;
-}
-
-static void
-data_book_get_contact_cb (GObject *source_object,
-                          GAsyncResult *result,
-                          gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       EContact *contact;
-       GError *error = NULL;
-
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
-       contact = e_book_backend_get_contact_finish (
-               E_BOOK_BACKEND (source_object), result, &error);
-
-       /* Sanity check. */
-       g_return_if_fail (
-               ((contact != NULL) && (error == NULL)) ||
-               ((contact == NULL) && (error != NULL)));
-
-       if (contact != NULL) {
-               g_simple_async_result_set_op_res_gpointer (
-                       simple, g_object_ref (contact),
-                       (GDestroyNotify) g_object_unref);
-               g_object_unref (contact);
-       }
-
-       if (error != NULL)
-               g_simple_async_result_take_error (simple, error);
-
-       g_simple_async_result_complete (simple);
-
-       g_object_unref (simple);
-}
-
-/**
- * e_data_book_get_contact:
- * @book: an #EDataBook
- * @uid: a unique string ID specifying the contact
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @callback: (scope async): a #GAsyncReadyCallback to call when the request
- *            is satisfied
- * @user_data: (closure): data to pass to @callback
- *
- * Retrieves #EContact from the @book for the gived @uid.
- * The call is finished by e_data_book_get_contact_finish()
- * from the @callback.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Since: 3.8
- */
-void
-e_data_book_get_contact (EDataBook *book,
-                         const gchar *uid,
-                         GCancellable *cancellable,
-                         GAsyncReadyCallback callback,
-                         gpointer user_data)
-{
-       EBookBackend *backend;
-       GSimpleAsyncResult *simple;
-
-       g_return_if_fail (E_IS_DATA_BOOK (book));
-       g_return_if_fail (uid && uid[0]);
-
-       backend = e_data_book_ref_backend (book);
-       g_return_if_fail (backend != NULL);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (book), callback,
-               user_data, e_data_book_get_contact);
-
-       e_book_backend_get_contact (
-               backend, uid, cancellable,
-               data_book_get_contact_cb,
-               g_object_ref (simple));
-
-       g_object_unref (simple);
-       g_object_unref (backend);
-}
-
-/**
- * e_data_book_get_contact_finish:
- * @book: an #EDataBook
- * @result: a #GAsyncResult
- * @contact: return location for the fetched #EContact
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Finishes the operation started with e_data_book_get_contact().  If an
- * error occurs, then this function sets @error and returns %FALSE.
- *
- * Returns: %TRUE on success
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_get_contact_finish (EDataBook *book,
-                                GAsyncResult *result,
-                                EContact **contact,
-                                GError **error)
-{
-       GSimpleAsyncResult *simple;
-       EContact *ret_contact;
-
-       g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
-       g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-       ret_contact = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       g_return_val_if_fail (ret_contact != NULL, FALSE);
-
-       if (contact != NULL)
-               *contact = g_object_ref (ret_contact);
-
-       return TRUE;
-}
-
-/**
- * e_data_book_get_contact_sync:
- * @book: an #EDataBook
- * @uid: a unique string ID specifying the contact
- * @contact: return location for the fetched #EContact
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Retrieves an #EContact from the @book for the gived @uid.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Returns: %TRUE on success. If %FALSE is returned, @error will be set
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_get_contact_sync (EDataBook *book,
-                              const gchar *uid,
-                              EContact **contact,
-                              GCancellable *cancellable,
-                              GError **error)
-{
-       EBookBackend *backend;
-       EContact *ret_contact;
-       gboolean success = FALSE;
-
-       g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
-       g_return_val_if_fail (uid && uid[0], FALSE);
-
-       backend = e_data_book_ref_backend (book);
-       g_return_val_if_fail (backend != NULL, FALSE);
-
-       ret_contact = e_book_backend_get_contact_sync (
-               backend, uid, cancellable, error);
-
-       if (ret_contact != NULL) {
-               if (contact != NULL)
-                       *contact = g_object_ref (ret_contact);
-
-               g_object_unref (ret_contact);
-
-               success = TRUE;
-       }
-
-       g_object_unref (backend);
-
-       return success;
-}
-
-static void
-data_book_get_contacts_cb (GObject *source_object,
-                           GAsyncResult *result,
-                           gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       GQueue queue = G_QUEUE_INIT;
-       GError *error = NULL;
-
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
-       e_book_backend_get_contact_list_finish (
-               E_BOOK_BACKEND (source_object), result, &queue, &error);
-
-       if (error == NULL) {
-               GSList *list = NULL;
-
-               while (!g_queue_is_empty (&queue)) {
-                       EContact *contact;
-
-                       contact = g_queue_pop_tail (&queue);
-                       list = g_slist_prepend (list, contact);
-               }
-
-               /* XXX This assumes the finish() function will be called. */
-               g_simple_async_result_set_op_res_gpointer (
-                       simple, list, (GDestroyNotify) NULL);
-       } else {
-               g_simple_async_result_take_error (simple, error);
-       }
-
-       g_simple_async_result_complete (simple);
-
-       g_object_unref (simple);
-}
-
-/**
- * e_data_book_get_contacts:
- * @book: an #EDataBook
- * @sexp: an S-expression representing the query
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @callback: (scope async): a #GAsyncReadyCallback to call when the request
- *            is satisfied
- * @user_data: (closure): data to pass to @callback
- *
- * Query @book with @sexp, receiving a list of contacts which
- * matched. The call is finished by e_data_book_get_contacts_finish()
- * from the @callback.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Since: 3.8
- */
-void
-e_data_book_get_contacts (EDataBook *book,
-                          const gchar *sexp,
-                          GCancellable *cancellable,
-                          GAsyncReadyCallback callback,
-                          gpointer user_data)
-{
-       EBookBackend *backend;
-       GSimpleAsyncResult *simple;
-
-       g_return_if_fail (E_IS_DATA_BOOK (book));
-
-       backend = e_data_book_ref_backend (book);
-       g_return_if_fail (backend != NULL);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (book), callback, user_data,
-               e_data_book_get_contacts);
-
-       g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-       e_book_backend_get_contact_list (
-               backend, sexp, cancellable,
-               data_book_get_contacts_cb,
-               g_object_ref (simple));
-
-       g_object_unref (simple);
-       g_object_unref (backend);
-}
-
-/**
- * e_data_book_get_contacts_finish:
- * @book: an #EDataBook
- * @result: a #GAsyncResult
- * @contacts: (element-type EContact) (out): a #GSList of matched #EContacts
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Finishes the operation started with e_data_book_get_contacts(). If an
- * error occurs, then this function sets @error and returns %FALSE.
- *
- * Returns: %TRUE on success
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_get_contacts_finish (EDataBook *book,
-                                 GAsyncResult *result,
-                                 GSList **contacts,
-                                 GError **error)
-{
-       GSimpleAsyncResult *simple;
-       GSList *list;
-
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (book),
-               e_data_book_get_contacts), FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       list = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (contacts != NULL)
-               *contacts = list;
-       else
-               g_slist_free_full (list, (GDestroyNotify) g_object_unref);
-
-       return TRUE;
-}
-
-/**
- * e_data_book_get_contacts_sync:
- * @book: an #EDataBook
- * @sexp: an S-expression representing the query
- * @contacts: (element-type EContact) (out): a #GSList of matched #EContacts
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Query @book with @sexp, receiving a list of contacts which
- * matched.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Returns: %TRUE on success. If %FALSE is returned, @error will be set
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_get_contacts_sync (EDataBook *book,
-                               const gchar *sexp,
-                               GSList **contacts,
-                               GCancellable *cancellable,
-                               GError **error)
-{
-       EBookBackend *backend;
-       GQueue queue = G_QUEUE_INIT;
-       gboolean success;
-
-       g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
-
-       backend = e_data_book_ref_backend (book);
-       g_return_val_if_fail (backend != NULL, FALSE);
-
-       success = e_book_backend_get_contact_list_sync (
-               backend, sexp, &queue, cancellable, error);
-
-       if (contacts != NULL) {
-               while (!g_queue_is_empty (&queue))
-                       *contacts = g_slist_prepend (
-                               *contacts, g_queue_pop_tail (&queue));
-       } else {
-               while (!g_queue_is_empty (&queue))
-                       g_object_unref (g_queue_pop_head (&queue));
-       }
-
-       g_object_unref (backend);
-
-       return success;
-}
-
-static void
-data_book_get_contacts_uids_cb (GObject *source_object,
-                                GAsyncResult *result,
-                                gpointer user_data)
-{
-       GSimpleAsyncResult *simple;
-       GQueue queue = G_QUEUE_INIT;
-       GError *error = NULL;
-
-       simple = G_SIMPLE_ASYNC_RESULT (user_data);
-
-       e_book_backend_get_contact_list_uids_finish (
-               E_BOOK_BACKEND (source_object), result, &queue, &error);
-
-       if (error == NULL) {
-               GSList *list = NULL;
-
-               while (!g_queue_is_empty (&queue)) {
-                       gchar *uid;
-
-                       uid = g_queue_pop_tail (&queue);
-                       list = g_slist_prepend (list, uid);
-               }
-
-               /* XXX This assumes the finish() function will be called. */
-               g_simple_async_result_set_op_res_gpointer (
-                       simple, list, (GDestroyNotify) NULL);
-       } else {
-               g_simple_async_result_take_error (simple, error);
-       }
-
-       g_simple_async_result_complete (simple);
-
-       g_object_unref (simple);
-}
-
-/**
- * e_data_book_get_contacts_uids:
- * @book: an #EDataBook
- * @sexp: an S-expression representing the query
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @callback: (scope async): a #GAsyncReadyCallback to call when the request
- *            is satisfied
- * @user_data: (closure): data to pass to @callback
- *
- * Query @book with @sexp, receiving a list of contacts UIDs which
- * matched. The call is finished by e_data_book_get_contacts_uids_finish()
- * from the @callback.
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Since: 3.8
- */
-void
-e_data_book_get_contacts_uids (EDataBook *book,
-                               const gchar *sexp,
-                               GCancellable *cancellable,
-                               GAsyncReadyCallback callback,
-                               gpointer user_data)
-{
-       EBookBackend *backend;
-       GSimpleAsyncResult *simple;
-
-       g_return_if_fail (E_IS_DATA_BOOK (book));
-
-       backend = e_data_book_ref_backend (book);
-       g_return_if_fail (backend != NULL);
-
-       simple = g_simple_async_result_new (
-               G_OBJECT (book), callback, user_data,
-               e_data_book_get_contacts_uids);
-
-       g_simple_async_result_set_check_cancellable (simple, cancellable);
-
-       e_book_backend_get_contact_list_uids (
-               backend, sexp, cancellable,
-               data_book_get_contacts_uids_cb,
-               g_object_ref (simple));
-
-       g_object_unref (simple);
-       g_object_unref (backend);
-}
-
-/**
- * e_data_book_get_contacts_uids_finish:
- * @book: an #EDataBook
- * @result: a #GAsyncResult
- * @contacts_uids: (element-type utf8) (out): a #GSList of matched contact UIDs stored as strings
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Finishes the operation started with e_data_book_get_contacts_uids(). If an
- * error occurs, then this function sets @error and returns %FALSE.
- *
- * Returns: %TRUE on success
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_get_contacts_uids_finish (EDataBook *book,
-                                      GAsyncResult *result,
-                                      GSList **contacts_uids,
-                                      GError **error)
-{
-       GSimpleAsyncResult *simple;
-       GSList *list;
-
-       g_return_val_if_fail (
-               g_simple_async_result_is_valid (
-               result, G_OBJECT (book),
-               e_data_book_get_contacts_uids), FALSE);
-
-       simple = G_SIMPLE_ASYNC_RESULT (result);
-
-       if (g_simple_async_result_propagate_error (simple, error))
-               return FALSE;
-
-       list = g_simple_async_result_get_op_res_gpointer (simple);
-
-       if (contacts_uids != NULL)
-               *contacts_uids = list;
-       else
-               g_slist_free_full (list, (GDestroyNotify) g_free);
-
-       return TRUE;
-}
-
-/**
- * e_data_book_get_contacts_uids_sync:
- * @book: an #EDataBook
- * @sexp: an S-expression representing the query
- * @contacts_uids: (element-type utf8) (out): a #GSList of matched contact UIDs stored as strings
- * @cancellable: (allow-none): optional #GCancellable object, or %NULL
- * @error: (allow-none): return location for a #GError, or %NULL
- *
- * Query @book with @sexp, receiving a list of contacts UIDs which
- * matched. 
- *
- * <note><para>This API is intended for internal use only, if you want client side
- * direct read access then use e_book_client_connect_direct_sync() instead</para></note>
- *
- * Returns: %TRUE on success. If %FALSE is returned, @error will be set
- *
- * Since: 3.8
- */
-gboolean
-e_data_book_get_contacts_uids_sync (EDataBook *book,
-                                    const gchar *sexp,
-                                    GSList **contacts_uids,
-                                    GCancellable *cancellable,
-                                    GError **error)
-{
-       EBookBackend *backend;
-       GQueue queue = G_QUEUE_INIT;
-       gboolean success;
-
-       g_return_val_if_fail (E_IS_DATA_BOOK (book), FALSE);
-
-       backend = e_data_book_ref_backend (book);
-       g_return_val_if_fail (backend != NULL, FALSE);
-
-       success = e_book_backend_get_contact_list_uids_sync (
-               backend, sexp, &queue, cancellable, error);
-
-       if (contacts_uids != NULL) {
-               while (!g_queue_is_empty (&queue))
-                       *contacts_uids = g_slist_prepend (
-                               *contacts_uids, g_queue_pop_tail (&queue));
-       } else {
-               while (!g_queue_is_empty (&queue))
-                       g_free (g_queue_pop_head (&queue));
-       }
-
-       g_object_unref (backend);
-
-       return success;
-}
diff --git a/addressbook/libedata-book/e-data-book.h b/addressbook/libedata-book/e-data-book.h
index 289048d..82453f7 100644
--- a/addressbook/libedata-book/e-data-book.h
+++ b/addressbook/libedata-book/e-data-book.h
@@ -142,12 +142,6 @@ EDataBook *        e_data_book_new                 (struct _EBookBackend *backend,
                                                 GDBusConnection *connection,
                                                 const gchar *object_path,
                                                 GError **error);
-EDataBook *    e_data_book_new_direct          (ESourceRegistry *registry,
-                                                ESource *source,
-                                                const gchar *backend_path,
-                                                const gchar *backend_name,
-                                                const gchar *config,
-                                                GError **error);
 struct _EBookBackend *
                e_data_book_ref_backend         (EDataBook *book);
 GDBusConnection *
@@ -206,69 +200,6 @@ void               e_data_book_report_backend_property_changed
 gchar *                e_data_book_string_slist_to_comma_string
                                                (const GSList *strings);
 
-/* Direct read access apis */
-gboolean       e_data_book_open_sync           (EDataBook *book,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
-void           e_data_book_close               (EDataBook *book,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_data_book_close_finish        (EDataBook *book,
-                                                GAsyncResult *result,
-                                                GError **error);
-gboolean       e_data_book_close_sync          (EDataBook *book,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
-void           e_data_book_get_contact         (EDataBook *book,
-                                                const gchar *uid,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_data_book_get_contact_finish  (EDataBook *book,
-                                                GAsyncResult *result,
-                                                EContact **contact,
-                                                GError **error);
-gboolean       e_data_book_get_contact_sync    (EDataBook *book,
-                                                const gchar *uid,
-                                                EContact **contact,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
-void           e_data_book_get_contacts        (EDataBook *book,
-                                                const gchar *sexp,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_data_book_get_contacts_finish (EDataBook *book,
-                                                GAsyncResult *result,
-                                                GSList **contacts,
-                                                GError **error);
-gboolean       e_data_book_get_contacts_sync   (EDataBook *book,
-                                                const gchar *sexp,
-                                                GSList **contacts,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
-void           e_data_book_get_contacts_uids   (EDataBook *book,
-                                                const gchar *sexp,
-                                                GCancellable *cancellable,
-                                                GAsyncReadyCallback callback,
-                                                gpointer user_data);
-gboolean       e_data_book_get_contacts_uids_finish
-                                                (EDataBook *book,
-                                                GAsyncResult *result,
-                                                GSList **contacts_uids,
-                                                GError **error);
-gboolean       e_data_book_get_contacts_uids_sync
-                                                (EDataBook *book,
-                                                const gchar *sexp,
-                                                GSList **contacts_uids,
-                                                GCancellable *cancellable,
-                                                GError **error);
-
 G_END_DECLS
 
 #endif /* E_DATA_BOOK_H */
diff --git a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt 
b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
index eb8405b..8372233 100644
--- a/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
+++ b/docs/reference/addressbook/libedata-book/libedata-book-sections.txt
@@ -297,20 +297,6 @@ e_data_book_respond_get_contact_list_uids
 e_data_book_report_error
 e_data_book_report_backend_property_changed
 e_data_book_string_slist_to_comma_string
-e_data_book_new_direct
-e_data_book_open_sync
-e_data_book_close
-e_data_book_close_finish
-e_data_book_close_sync
-e_data_book_get_contact
-e_data_book_get_contact_finish
-e_data_book_get_contact_sync
-e_data_book_get_contacts
-e_data_book_get_contacts_finish
-e_data_book_get_contacts_sync
-e_data_book_get_contacts_uids
-e_data_book_get_contacts_uids_finish
-e_data_book_get_contacts_uids_sync
 <SUBSECTION Standard>
 E_DATA_BOOK
 E_IS_DATA_BOOK


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