Add e_data_factory_ref_initable_backend().
authorMatthew Barnes <mbarnes@redhat.com>
Tue, 22 Jan 2013 21:28:05 +0000 (16:28 -0500)
committerMatthew Barnes <mbarnes@redhat.com>
Mon, 4 Feb 2013 16:24:11 +0000 (11:24 -0500)
Similar to e_data_factory_ref_backend(), but allows for backends that
implement the GInitable interface so they can fail gracefully if they
are unable to initialize critical resources, such as a cache database.

addressbook/libedata-book/e-data-book-factory.c
calendar/libedata-cal/e-data-cal-factory.c
docs/reference/libebackend/libebackend-sections.txt
libebackend/e-data-factory.c
libebackend/e-data-factory.h

index bd91104..9a7f8f4 100644 (file)
@@ -97,14 +97,8 @@ data_book_factory_ref_backend (EDataFactory *factory,
                return NULL;
        }
 
-       backend = e_data_factory_ref_backend (factory, backend_name, source);
-
-       if (backend == NULL)
-               g_set_error (
-                       error, E_DATA_BOOK_ERROR,
-                       E_DATA_BOOK_STATUS_NO_SUCH_BOOK,
-                       _("Invalid backend name '%s' in source '%s'"),
-                       backend_name, e_source_get_display_name (source));
+       backend = e_data_factory_ref_initable_backend (
+               factory, backend_name, source, NULL, error);
 
        g_free (backend_name);
 
index 474bdd6..405249e 100644 (file)
@@ -101,15 +101,10 @@ data_cal_factory_ref_backend (EDataFactory *factory,
        }
 
        hash_key = g_strdup_printf ("%s:%s", backend_name, type_string);
-       backend = e_data_factory_ref_backend (factory, hash_key, source);
+       backend = e_data_factory_ref_initable_backend (
+               factory, hash_key, source, NULL, error);
        g_free (hash_key);
 
-       if (backend == NULL)
-               g_set_error (
-                       error, E_DATA_CAL_ERROR, NoSuchCal,
-                       _("Invalid backend name '%s' in source '%s'"),
-                       backend_name, e_source_get_display_name (source));
-
        g_free (backend_name);
 
        return backend;
index 9d2be5f..9854be2 100644 (file)
@@ -170,6 +170,7 @@ ECollectionBackendFactoryPrivate
 <TITLE>EDataFactory</TITLE>
 EDataFactory
 e_data_factory_ref_backend
+e_data_factory_ref_initable_backend
 e_data_factory_ref_backend_factory
 <SUBSECTION Standard>
 E_DATA_FACTORY
index efaac1f..d98df68 100644 (file)
@@ -25,6 +25,7 @@
 #include "e-data-factory.h"
 
 #include <config.h>
+#include <glib/gi18n-lib.h>
 
 #include <libebackend/e-extensible.h>
 #include <libebackend/e-backend-factory.h>
@@ -243,6 +244,49 @@ e_data_factory_ref_backend (EDataFactory *data_factory,
                             const gchar *hash_key,
                             ESource *source)
 {
+       return e_data_factory_ref_initable_backend (
+               data_factory, hash_key, source, NULL, NULL);
+}
+
+/**
+ * e_data_factory_ref_initable_backend:
+ * @data_factory: an #EDataFactory
+ * @hash_key: hash key for an #EBackendFactory
+ * @source: an #ESource
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Similar to e_data_factory_ref_backend(), but allows for backends that
+ * implement the #GInitable interface so they can fail gracefully if they
+ * are unable to initialize critical resources, such as a cache database.
+ *
+ * Returns either a newly-created or existing #EBackend for #ESource.
+ * The returned #EBackend is referenced for thread-safety and must be
+ * unreferenced with g_object_unref() when finished with it.
+ *
+ * If the newly-created backend implements the #GInitable interface, then
+ * g_initable_init() is also called on it using @cancellable and @error.
+ *
+ * The @data_factory retains a weak reference to @backend so it can return
+ * the same instance while @backend is in use.  When the last strong reference
+ * to @backend is dropped, @data_factory will lose its weak reference and will
+ * have to create a new #EBackend instance the next time the same @hash_key
+ * and @source are requested.
+ *
+ * If no suitable #EBackendFactory exists, or if the #EBackend fails to
+ * initialize, the function sets @error and returns %NULL.
+ *
+ * Returns: an #EBackend for @source, or %NULL
+ *
+ * Since: 3.8
+ **/
+EBackend *
+e_data_factory_ref_initable_backend (EDataFactory *data_factory,
+                                     const gchar *hash_key,
+                                     ESource *source,
+                                     GCancellable *cancellable,
+                                     GError **error)
+{
        EBackendFactory *backend_factory;
        GWeakRef *weak_ref;
        EBackend *backend;
@@ -270,12 +314,26 @@ e_data_factory_ref_backend (EDataFactory *data_factory,
        backend_factory =
                e_data_factory_ref_backend_factory (data_factory, hash_key);
 
-       if (backend_factory == NULL)
+       if (backend_factory == NULL) {
+               g_set_error (
+                       error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
+                       _("No backend factory for hash key '%s'"),
+                       hash_key);
                goto exit;
+       }
 
        /* Create a new backend for the given source and store it. */
        backend = e_backend_factory_new_backend (backend_factory, source);
 
+       if (G_IS_INITABLE (backend)) {
+               GInitable *initable = G_INITABLE (backend);
+
+               if (!g_initable_init (initable, cancellable, error)) {
+                       g_object_unref (backend);
+                       backend = NULL;
+               }
+       }
+
        /* This still does the right thing if backend is NULL. */
        g_weak_ref_set (weak_ref, backend);
 
index 2c8ee2a..e370a1b 100644 (file)
@@ -80,6 +80,12 @@ GType                e_data_factory_get_type         (void) G_GNUC_CONST;
 EBackend *     e_data_factory_ref_backend      (EDataFactory *data_factory,
                                                 const gchar *hash_key,
                                                 ESource *source);
+EBackend *     e_data_factory_ref_initable_backend
+                                               (EDataFactory *data_factory,
+                                                const gchar *hash_key,
+                                                ESource *source,
+                                                GCancellable *cancellable,
+                                                GError **error);
 EBackendFactory *
                e_data_factory_ref_backend_factory
                                                (EDataFactory *data_factory,