[evolution-data-server] Be able to get all UID/id-s from book/cal cache with certain 'extra' data



commit 72b1db3f28ceb2d68410dbc84859cdc9cd17af34
Author: Milan Crha <mcrha redhat com>
Date:   Wed Jun 7 14:15:26 2017 +0200

    Be able to get all UID/id-s from book/cal cache with certain 'extra' data
    
    Even this could be achieved with general search functions (e_book_cache_search_with_callback(),
    e_cal_cache_search_with_callback()), it is too inefficient, thus added these new
    specialized functions e_book_cache_get_uids_with_extra() and
    e_cal_cache_get_ids_with_extra().

 src/addressbook/libedata-book/e-book-cache.c  |   72 ++++++++++++++++++++++
 src/addressbook/libedata-book/e-book-cache.h  |    6 ++
 src/calendar/libedata-cal/e-cal-cache.c       |   80 ++++++++++++++++++++++++-
 src/calendar/libedata-cal/e-cal-cache.h       |    5 ++
 tests/libedata-book/test-book-cache-offline.c |   22 +++++++
 tests/libedata-cal/test-cal-cache-offline.c   |   24 +++++++
 6 files changed, 208 insertions(+), 1 deletions(-)
---
diff --git a/src/addressbook/libedata-book/e-book-cache.c b/src/addressbook/libedata-book/e-book-cache.c
index db1c1cd..5eddec2 100644
--- a/src/addressbook/libedata-book/e-book-cache.c
+++ b/src/addressbook/libedata-book/e-book-cache.c
@@ -4166,6 +4166,25 @@ e_book_cache_get_string (ECache *cache,
 }
 
 static gboolean
+e_book_cache_get_strings (ECache *cache,
+                         gint ncols,
+                         const gchar **column_names,
+                         const gchar **column_values,
+                         gpointer user_data)
+{
+       GSList **pvalues = user_data;
+
+       g_return_val_if_fail (ncols == 1, FALSE);
+       g_return_val_if_fail (column_names != NULL, FALSE);
+       g_return_val_if_fail (column_values != NULL, FALSE);
+       g_return_val_if_fail (pvalues != NULL, FALSE);
+
+       *pvalues = g_slist_prepend (*pvalues, g_strdup (column_values[0]));
+
+       return TRUE;
+}
+
+static gboolean
 e_book_cache_get_old_contacts_cb (ECache *cache,
                                  gint ncols,
                                  const gchar *column_names[],
@@ -5129,6 +5148,59 @@ e_book_cache_get_contact_extra (EBookCache *book_cache,
 }
 
 /**
+ * e_book_cache_get_uids_with_extra:
+ * @book_cache: an #EBookCache
+ * @extra: an extra column value to search for
+ * @out_uids: (out) (transfer full) (element-type utf8): return location to store the UIDs to
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets all the UID-s the @extra data is set for.
+ *
+ * The @out_uids should be freed with
+ * g_slist_free_full (uids, g_free);
+ * when no longer needed.
+ *
+ * Returns: Whether succeeded.
+ *
+ * Since: 3.26
+ **/
+gboolean
+e_book_cache_get_uids_with_extra (EBookCache *book_cache,
+                                 const gchar *extra,
+                                 GSList **out_uids,
+                                 GCancellable *cancellable,
+                                 GError **error)
+{
+       gchar *stmt;
+       gboolean success;
+
+       g_return_val_if_fail (E_IS_BOOK_CACHE (book_cache), FALSE);
+       g_return_val_if_fail (extra != NULL, FALSE);
+       g_return_val_if_fail (out_uids != NULL, FALSE);
+
+       *out_uids = NULL;
+
+       stmt = e_cache_sqlite_stmt_printf (
+               "SELECT " E_CACHE_COLUMN_UID " FROM " E_CACHE_TABLE_OBJECTS
+               " WHERE " EBC_COLUMN_EXTRA "=%Q",
+               extra);
+
+       success = e_cache_sqlite_select (E_CACHE (book_cache), stmt, e_book_cache_get_strings, out_uids, 
cancellable, error);
+
+       e_cache_sqlite_stmt_free (stmt);
+
+       if (success && !*out_uids) {
+               g_set_error (error, E_CACHE_ERROR, E_CACHE_ERROR_NOT_FOUND, _("Object with extra ā€œ%sā€ not 
found"), extra);
+               success = FALSE;
+       } else {
+               *out_uids = g_slist_reverse (*out_uids);
+       }
+
+       return success;
+}
+
+/**
  * e_book_cache_search:
  * @book_cache: An #EBookCache
  * @sexp: (nullable): search expression; use %NULL or an empty string to list all stored contacts
diff --git a/src/addressbook/libedata-book/e-book-cache.h b/src/addressbook/libedata-book/e-book-cache.h
index 5e13799..1422437 100644
--- a/src/addressbook/libedata-book/e-book-cache.h
+++ b/src/addressbook/libedata-book/e-book-cache.h
@@ -262,6 +262,12 @@ gboolean   e_book_cache_get_contact_extra  (EBookCache *book_cache,
                                                 gchar **out_extra,
                                                 GCancellable *cancellable,
                                                 GError **error);
+gboolean       e_book_cache_get_uids_with_extra
+                                               (EBookCache *book_cache,
+                                                const gchar *extra,
+                                                GSList **out_uids, /* gchar * */
+                                                GCancellable *cancellable,
+                                                GError **error);
 gboolean       e_book_cache_search             (EBookCache *book_cache,
                                                 const gchar *sexp,
                                                 gboolean meta_contacts,
diff --git a/src/calendar/libedata-cal/e-cal-cache.c b/src/calendar/libedata-cal/e-cal-cache.c
index c897ef4..ac82a6c 100644
--- a/src/calendar/libedata-cal/e-cal-cache.c
+++ b/src/calendar/libedata-cal/e-cal-cache.c
@@ -476,6 +476,31 @@ ecc_decode_id_sql (const gchar *id,
        return TRUE;
 }
 
+static gboolean
+e_cal_cache_get_ids (ECache *cache,
+                    gint ncols,
+                    const gchar **column_names,
+                    const gchar **column_values,
+                    gpointer user_data)
+{
+       GSList **out_ids = user_data;
+       gchar *uid = NULL, *rid = NULL;
+
+       g_return_val_if_fail (ncols == 1, FALSE);
+       g_return_val_if_fail (column_names != NULL, FALSE);
+       g_return_val_if_fail (column_values != NULL, FALSE);
+       g_return_val_if_fail (out_ids != NULL, FALSE);
+
+       if (ecc_decode_id_sql (column_values[0], &uid, &rid)) {
+               *out_ids = g_slist_prepend (*out_ids, e_cal_component_id_new (uid, rid));
+
+               g_free (uid);
+               g_free (rid);
+       }
+
+       return TRUE;
+}
+
 static icaltimezone *
 ecc_resolve_tzid_cb (const gchar *tzid,
                     gpointer user_data)
@@ -2303,6 +2328,59 @@ e_cal_cache_get_component_extra (ECalCache *cal_cache,
        return success;
 }
 
+/**
+ * e_cal_cache_get_ids_with_extra:
+ * @cal_cache: an #ECalCache
+ * @extra: an extra column value to search for
+ * @out_ids: (out) (transfer full) (element-type ECalComponentId): return location to store the ids to
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets all the ID-s the @extra data is set for.
+ *
+ * The @out_ids should be freed with
+ * g_slist_free_full (ids, (GDestroyNotify) e_cal_component_free_id);
+ * when no longer needed.
+ *
+ * Returns: Whether succeeded.
+ *
+ * Since: 3.26
+ **/
+gboolean
+e_cal_cache_get_ids_with_extra (ECalCache *cal_cache,
+                               const gchar *extra,
+                               GSList **out_ids,
+                               GCancellable *cancellable,
+                               GError **error)
+{
+       gchar *stmt;
+       gboolean success;
+
+       g_return_val_if_fail (E_IS_CAL_CACHE (cal_cache), FALSE);
+       g_return_val_if_fail (extra != NULL, FALSE);
+       g_return_val_if_fail (out_ids != NULL, FALSE);
+
+       *out_ids = NULL;
+
+       stmt = e_cache_sqlite_stmt_printf (
+               "SELECT " E_CACHE_COLUMN_UID " FROM " E_CACHE_TABLE_OBJECTS
+               " WHERE " ECC_COLUMN_EXTRA "=%Q",
+               extra);
+
+       success = e_cache_sqlite_select (E_CACHE (cal_cache), stmt, e_cal_cache_get_ids, out_ids, 
cancellable, error);
+
+       e_cache_sqlite_stmt_free (stmt);
+
+       if (success && !*out_ids) {
+               g_set_error (error, E_CACHE_ERROR, E_CACHE_ERROR_NOT_FOUND, _("Object with extra ā€œ%sā€ not 
found"), extra);
+               success = FALSE;
+       } else {
+               *out_ids = g_slist_reverse (*out_ids);
+       }
+
+       return success;
+}
+
 static GSList *
 ecc_icalstrings_to_components (GSList *icalstrings)
 {
@@ -2684,7 +2762,7 @@ e_cal_cache_search_components (ECalCache *cal_cache,
  * Searches the @cal_cache with the given @sexp and returns ECalComponentId
  * for those components which satisfy the search expression.
  * The @out_ids should be freed with
- * g_slist_free_full (components, (GDestroyNotify) e_cal_component_free_id);
+ * g_slist_free_full (ids, (GDestroyNotify) e_cal_component_free_id);
  * when no longer needed.
  *
  * Returns: Whether succeeded.
diff --git a/src/calendar/libedata-cal/e-cal-cache.h b/src/calendar/libedata-cal/e-cal-cache.h
index 8d1b312..50d18c6 100644
--- a/src/calendar/libedata-cal/e-cal-cache.h
+++ b/src/calendar/libedata-cal/e-cal-cache.h
@@ -244,6 +244,11 @@ gboolean   e_cal_cache_get_component_extra (ECalCache *cal_cache,
                                                 gchar **out_extra,
                                                 GCancellable *cancellable,
                                                 GError **error);
+gboolean       e_cal_cache_get_ids_with_extra  (ECalCache *cal_cache,
+                                                const gchar *extra,
+                                                GSList **out_ids, /* ECalComponentId * */
+                                                GCancellable *cancellable,
+                                                GError **error);
 gboolean       e_cal_cache_get_components_by_uid
                                                (ECalCache *cal_cache,
                                                 const gchar *uid,
diff --git a/tests/libedata-book/test-book-cache-offline.c b/tests/libedata-book/test-book-cache-offline.c
index b6d4f1e..ba3ea81 100644
--- a/tests/libedata-book/test-book-cache-offline.c
+++ b/tests/libedata-book/test-book-cache-offline.c
@@ -434,6 +434,7 @@ test_offline_basics (TCUFixture *fixture,
        gint ii;
        const gchar *uid;
        gchar *saved_extra = NULL, *tmp;
+       GSList *uids = NULL;
        GError *error = NULL;
 
        /* Basic ECache stuff */
@@ -481,6 +482,14 @@ test_offline_basics (TCUFixture *fixture,
        g_free (saved_extra);
        saved_extra = NULL;
 
+       g_assert (e_book_cache_get_uids_with_extra (fixture->book_cache, "extra-0", &uids, NULL, &error));
+       g_assert_no_error (error);
+       g_assert_cmpint (g_slist_length (uids), ==, 1);
+       g_assert_cmpstr (uids->data, ==, uid);
+
+       g_slist_free_full (uids, g_free);
+       uids = NULL;
+
        e_contact_set (contact, E_CONTACT_REV, "rev-0");
 
        test_check_offline_state (fixture, uid, E_OFFLINE_STATE_SYNCED);
@@ -550,6 +559,14 @@ test_offline_basics (TCUFixture *fixture,
        test_verify_storage (fixture, uid, "rev-2", "extra-2", E_OFFLINE_STATE_SYNCED);
        test_check_offline_changes (fixture, NULL);
 
+       g_assert (e_book_cache_get_uids_with_extra (fixture->book_cache, "extra-2", &uids, NULL, &error));
+       g_assert_no_error (error);
+       g_assert_cmpint (g_slist_length (uids), ==, 1);
+       g_assert_cmpstr (uids->data, ==, uid);
+
+       g_slist_free_full (uids, g_free);
+       uids = NULL;
+
        g_assert_cmpint (e_cache_get_count (E_CACHE (fixture->book_cache), E_CACHE_EXCLUDE_DELETED, NULL, 
&error), ==, 3);
        g_assert_no_error (error);
 
@@ -580,6 +597,11 @@ test_offline_basics (TCUFixture *fixture,
        g_assert_null (saved_extra);
        g_clear_error (&error);
 
+       g_assert (!e_book_cache_get_uids_with_extra (fixture->book_cache, "extra-3", &uids, NULL, &error));
+       g_assert_error (error, E_CACHE_ERROR, E_CACHE_ERROR_NOT_FOUND);
+       g_assert_null (uids);
+       g_clear_error (&error);
+
        g_clear_object (&contact);
 
        /* Search after delete */
diff --git a/tests/libedata-cal/test-cal-cache-offline.c b/tests/libedata-cal/test-cal-cache-offline.c
index a831157..126eae0 100644
--- a/tests/libedata-cal/test-cal-cache-offline.c
+++ b/tests/libedata-cal/test-cal-cache-offline.c
@@ -339,6 +339,7 @@ test_offline_basics (TCUFixture *fixture,
        gint ii;
        const gchar *uid;
        gchar *saved_extra = NULL, *tmp;
+       GSList *ids = NULL;
        GError *error = NULL;
 
        /* Basic ECache stuff */
@@ -386,6 +387,15 @@ test_offline_basics (TCUFixture *fixture,
        g_free (saved_extra);
        saved_extra = NULL;
 
+       g_assert (e_cal_cache_get_ids_with_extra (fixture->cal_cache, "extra-0", &ids, NULL, &error));
+       g_assert_no_error (error);
+       g_assert_cmpint (g_slist_length (ids), ==, 1);
+       g_assert_nonnull (ids->data);
+       g_assert_cmpstr (((ECalComponentId *) ids->data)->uid, ==, uid);
+
+       g_slist_free_full (ids, (GDestroyNotify) e_cal_component_free_id);
+       ids = NULL;
+
        icalcomponent_set_summary (e_cal_component_get_icalcomponent (component), "summ-0");
 
        test_check_offline_state (fixture, uid, E_OFFLINE_STATE_SYNCED);
@@ -455,6 +465,15 @@ test_offline_basics (TCUFixture *fixture,
        test_verify_storage (fixture, uid, "summ-2", "extra-2", E_OFFLINE_STATE_SYNCED);
        test_check_offline_changes (fixture, NULL);
 
+       g_assert (e_cal_cache_get_ids_with_extra (fixture->cal_cache, "extra-2", &ids, NULL, &error));
+       g_assert_no_error (error);
+       g_assert_cmpint (g_slist_length (ids), ==, 1);
+       g_assert_nonnull (ids->data);
+       g_assert_cmpstr (((ECalComponentId *) ids->data)->uid, ==, uid);
+
+       g_slist_free_full (ids, (GDestroyNotify) e_cal_component_free_id);
+       ids = NULL;
+
        g_assert_cmpint (e_cache_get_count (E_CACHE (fixture->cal_cache), E_CACHE_EXCLUDE_DELETED, NULL, 
&error), ==, 3);
        g_assert_no_error (error);
 
@@ -485,6 +504,11 @@ test_offline_basics (TCUFixture *fixture,
        g_assert_null (saved_extra);
        g_clear_error (&error);
 
+       g_assert (!e_cal_cache_get_ids_with_extra (fixture->cal_cache, "extra-3", &ids, NULL, &error));
+       g_assert_error (error, E_CACHE_ERROR, E_CACHE_ERROR_NOT_FOUND);
+       g_assert_null (ids);
+       g_clear_error (&error);
+
        g_clear_object (&component);
 
        /* Search after delete */


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