From 0fbad0dadd83624c61c304271794b64b661958e1 Mon Sep 17 00:00:00 2001 From: Matthew Barnes Date: Tue, 22 Jan 2013 16:28:05 -0500 Subject: [PATCH] Add e_data_factory_ref_initable_backend(). 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 | 10 +--- calendar/libedata-cal/e-data-cal-factory.c | 9 +--- .../reference/libebackend/libebackend-sections.txt | 1 + libebackend/e-data-factory.c | 60 +++++++++++++++++++++- libebackend/e-data-factory.h | 6 +++ 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/addressbook/libedata-book/e-data-book-factory.c b/addressbook/libedata-book/e-data-book-factory.c index bd91104..9a7f8f4 100644 --- a/addressbook/libedata-book/e-data-book-factory.c +++ b/addressbook/libedata-book/e-data-book-factory.c @@ -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); diff --git a/calendar/libedata-cal/e-data-cal-factory.c b/calendar/libedata-cal/e-data-cal-factory.c index 474bdd6..405249e 100644 --- a/calendar/libedata-cal/e-data-cal-factory.c +++ b/calendar/libedata-cal/e-data-cal-factory.c @@ -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; diff --git a/docs/reference/libebackend/libebackend-sections.txt b/docs/reference/libebackend/libebackend-sections.txt index 9d2be5f..9854be2 100644 --- a/docs/reference/libebackend/libebackend-sections.txt +++ b/docs/reference/libebackend/libebackend-sections.txt @@ -170,6 +170,7 @@ ECollectionBackendFactoryPrivate EDataFactory EDataFactory e_data_factory_ref_backend +e_data_factory_ref_initable_backend e_data_factory_ref_backend_factory E_DATA_FACTORY diff --git a/libebackend/e-data-factory.c b/libebackend/e-data-factory.c index efaac1f..d98df68 100644 --- a/libebackend/e-data-factory.c +++ b/libebackend/e-data-factory.c @@ -25,6 +25,7 @@ #include "e-data-factory.h" #include +#include #include #include @@ -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); diff --git a/libebackend/e-data-factory.h b/libebackend/e-data-factory.h index 2c8ee2a..e370a1b 100644 --- a/libebackend/e-data-factory.h +++ b/libebackend/e-data-factory.h @@ -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, -- 2.7.4