[gom] filter: Add new _full variadic constructors



commit fa1f6031061becab0e722be080d272971a465c75
Author: Mathieu Bridon <bochecha daitauha fr>
Date:   Thu Nov 27 19:27:43 2014 +0100

    filter: Add new _full variadic constructors
    
    This allows AND-/OR-ing more than 2 subfilters at a time.
    
    A unit test is also added.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=740872

 gom/gom-filter.c               |   75 ++++++++++++++++++++++++++++++++++++++++
 gom/gom-filter.h               |    4 ++
 tests/test-gom-find-specific.c |   69 ++++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+), 0 deletions(-)
---
diff --git a/gom/gom-filter.c b/gom/gom-filter.c
index 1eec233..87525ed 100644
--- a/gom/gom-filter.c
+++ b/gom/gom-filter.c
@@ -16,6 +16,8 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <stdarg.h>
+
 #include <glib/gi18n.h>
 
 #include "gom-filter.h"
@@ -117,6 +119,31 @@ gom_filter_new_for_param (GType          resource_type,
    return filter;
 }
 
+static GomFilter *
+gom_filter_new_for_subfilters_full (GomFilterMode  mode,
+                                    GomFilter     *first,
+                                    va_list        filters)
+{
+   GomFilter *filter, *f;
+
+   g_return_val_if_fail(GOM_IS_FILTER(first), NULL);
+
+   filter = g_object_new(GOM_TYPE_FILTER, "mode", mode, NULL);
+   filter->priv->subfilters = g_queue_new();
+   g_queue_push_tail(filter->priv->subfilters, g_object_ref(first));
+
+   f = va_arg(filters, GomFilter*);
+
+   while (f != NULL) {
+      g_return_val_if_fail(GOM_IS_FILTER(f), NULL);
+      g_queue_push_tail(filter->priv->subfilters, g_object_ref(f));
+
+      f = va_arg(filters, GomFilter*);
+   }
+
+   return filter;
+}
+
 GomFilter *
 gom_filter_new_like (GType         resource_type,
                      const gchar  *property_name,
@@ -250,6 +277,30 @@ gom_filter_new_and (GomFilter *left,
 }
 
 /**
+ * gom_filter_new_and_full: (constructor)
+ * @first: (in): A #GomFilter.
+ * @...: (in): A %NULL-terminated list of #GomFilter.
+ *
+ * Creates a new filter that requires that all filters passed as arguments
+ * equate to #TRUE.
+ *
+ * Returns: (transfer full): A #GomFilter.
+ */
+GomFilter *
+gom_filter_new_and_full (GomFilter *first,
+                         ...)
+{
+   GomFilter *filter;
+   va_list args;
+
+   va_start(args, first);
+   filter = gom_filter_new_for_subfilters_full(GOM_FILTER_AND, first, args);
+   va_end(args);
+
+   return filter;
+}
+
+/**
  * gom_filter_new_or: (constructor)
  * @left: (in): A #GomFilter.
  * @right: (in): A #GomFilter.
@@ -278,6 +329,30 @@ gom_filter_new_or (GomFilter *left,
    return filter;
 }
 
+/**
+ * gom_filter_new_or_full: (constructor)
+ * @first: (in): A #GomFilter.
+ * @...: (in): A %NULL-terminated list of #GomFilter.
+ *
+ * Creates a new filter that requires either of the filters passed as
+ * arguments equate to #TRUE.
+ *
+ * Returns: (transfer full): A #GomFilter.
+ */
+GomFilter *
+gom_filter_new_or_full (GomFilter *first,
+                        ...)
+{
+   GomFilter *filter;
+   va_list args;
+
+   va_start(args, first);
+   filter = gom_filter_new_for_subfilters_full(GOM_FILTER_OR, first, args);
+   va_end(args);
+
+   return filter;
+}
+
 gchar *
 gom_filter_get_sql (GomFilter  *filter,
                     GHashTable *table_map)
diff --git a/gom/gom-filter.h b/gom/gom-filter.h
index 3494c6d..bc51f01 100644
--- a/gom/gom-filter.h
+++ b/gom/gom-filter.h
@@ -74,8 +74,12 @@ GomFilter   *gom_filter_new_sql       (const gchar  *sql,
                                        GArray       *values);
 GomFilter   *gom_filter_new_or        (GomFilter    *left,
                                        GomFilter    *right);
+GomFilter   *gom_filter_new_or_full   (GomFilter    *first,
+                                       ...);
 GomFilter   *gom_filter_new_and       (GomFilter    *left,
                                        GomFilter    *right);
+GomFilter   *gom_filter_new_and_full  (GomFilter    *first,
+                                       ...);
 GomFilter   *gom_filter_new_eq        (GType         resource_type,
                                        const gchar  *property_name,
                                        const GValue *value);
diff --git a/tests/test-gom-find-specific.c b/tests/test-gom-find-specific.c
index 8d66615..0f2a1dd 100644
--- a/tests/test-gom-find-specific.c
+++ b/tests/test-gom-find-specific.c
@@ -383,6 +383,74 @@ find_specific (void)
   free_memory_db (adapter, repository);
 }
 
+/* Same as find_specific, but using the _full filter constructors */
+static void
+find_specific_and_full (void)
+{
+  GError *error = NULL;
+  GValue value = { 0, };
+  GomFilter *filter1, *filter2, *filter3, *filter4;
+  char *s1, *s2;
+  GomResource *resource;
+  EpisodeResource *eres;
+  GomAdapter *adapter;
+  GomRepository *repository;
+
+  create_memory_db(&adapter, &repository);
+
+  /* Season Number */
+  g_value_init(&value, G_TYPE_INT64);
+  g_value_set_int64(&value, values[0].season_number);
+  filter1 = gom_filter_new_eq(EPISODE_TYPE_RESOURCE,
+                               EPISODE_COLUMN_SEASON_NUMBER,
+                               &value);
+  g_value_unset(&value);
+
+  /* Episode Number */
+  g_value_init(&value, G_TYPE_INT64);
+  g_value_set_int64(&value, values[0].episode_number);
+  filter2 = gom_filter_new_eq(EPISODE_TYPE_RESOURCE,
+                              EPISODE_COLUMN_EPISODE_NUMBER,
+                              &value);
+  g_value_unset(&value);
+
+  /* Series ID */
+  g_value_init(&value, G_TYPE_STRING);
+  g_value_set_string(&value, values[0].series_id);
+  filter3 = gom_filter_new_like(EPISODE_TYPE_RESOURCE,
+                                EPISODE_COLUMN_SERIES_ID,
+                                &value);
+  g_value_unset(&value);
+
+  /* Season Number and Episode Number and Series ID */
+  filter4 = gom_filter_new_and_full(filter1, filter2, filter3, NULL);
+  g_object_unref(filter1);
+  g_object_unref(filter2);
+  g_object_unref(filter3);
+
+  resource = gom_repository_find_one_sync(repository,
+                                          EPISODE_TYPE_RESOURCE,
+                                          filter4,
+                                          &error);
+  g_assert_no_error(error);
+  g_assert(resource);
+  g_object_unref(filter4);
+  eres = EPISODE_RESOURCE(resource);
+
+  g_object_get(eres,
+               EPISODE_COLUMN_SERIES_ID, &s1,
+               EPISODE_COLUMN_IMDB_ID, &s2,
+               NULL);
+  g_object_unref(eres);
+
+  g_assert_cmpstr(s1, ==, values[0].series_id);
+  g_assert_cmpstr(s2, ==, values[0].imdb_id);
+  g_free(s1);
+  g_free(s2);
+
+  free_memory_db(adapter, repository);
+}
+
 static void
 find_glob (void)
 {
@@ -436,6 +504,7 @@ main (gint argc, gchar *argv[])
    g_test_init (&argc, &argv, NULL);
    g_test_add_func ("/GomRepository/find-simple", find_simple);
    g_test_add_func ("/GomRepository/find-specific", find_specific);
+   g_test_add_func ("/GomRepository/find-specific-and-full", find_specific_and_full);
    g_test_add_func ("/GomRepository/find-glob", find_glob);
    gMainLoop = g_main_loop_new (NULL, FALSE);
    return g_test_run ();


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