[gom] sorting: Allow adding sorting clauses to an existing GomSorting
- From: Mathieu Bridon <mbridon src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gom] sorting: Allow adding sorting clauses to an existing GomSorting
- Date: Fri, 10 Jul 2015 16:43:58 +0000 (UTC)
commit e7a8801109b1d361b7aab144c08eadaaba998605
Author: Mathieu Bridon <bochecha daitauha fr>
Date: Wed Jul 8 23:05:06 2015 +0200
sorting: Allow adding sorting clauses to an existing GomSorting
This allows another way to use GomSorting objects.
In addition, it makes it possible to use GomSorting from GI-based
bindings.
As it turns out, GObject Introspection does not support variadic
functions, so gom_sorting_new just isn't usable from GI-based bindings.
But with this commit, GI-based bindings can now simply create a new,
empty GomSorting object, then add their sorting clauses to it.
https://bugzilla.gnome.org/show_bug.cgi?id=752141
gom/gom-sorting.c | 56 +++++++++++++++++++++++++------
gom/gom-sorting.h | 4 ++
tests/test-gom-sorting.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 131 insertions(+), 11 deletions(-)
---
diff --git a/gom/gom-sorting.c b/gom/gom-sorting.c
index 81e98fe..e547589 100644
--- a/gom/gom-sorting.c
+++ b/gom/gom-sorting.c
@@ -170,17 +170,7 @@ gom_sorting_new (GType first_resource_type,
va_start(args, first_sorting_mode);
while TRUE {
- GomOrderByTerm *o = g_new(GomOrderByTerm, 1);
-
- g_return_val_if_fail(g_type_is_a(resource_type, GOM_TYPE_RESOURCE),
- NULL);
- g_return_val_if_fail(property_name != NULL, NULL);
- g_return_val_if_fail(sorting_mode, NULL);
-
- o->resource_type = resource_type;
- o->property_name = strdup(property_name);
- o->mode = sorting_mode;
- g_queue_push_tail(sorting->priv->order_by_terms, o);
+ gom_sorting_add(sorting, resource_type, property_name, sorting_mode);
resource_type = va_arg(args, GType);
@@ -197,6 +187,50 @@ gom_sorting_new (GType first_resource_type,
}
/**
+ * gom_sorting_add:
+ * @sorting: A #GomSorting.
+ * @resource_type: A subclass of #GomResource.
+ * @property_name: A string.
+ * @sorting_mode: A #GomSortingMode.
+ *
+ * Add a new ORDER BY clause to the sorting object.
+ *
+ * This allows chaining ORDER BY clauses, adding them one at a time, rather
+ * than passing them all to the constructor.
+ *
+ * Example:
+ * |[<!-- language="C" -->
+ * GomSorting *sorting = g_object_new (GOM_TYPE_SORTING, NULL);
+ * gom_sorting_add (sorting, EPISODE_TYPE_RESOURCE, "season-number",
+ * GOM_SORTING_DESCENDING);
+ * gom_sorting_add (sorting, EPISODE_TYPE_RESOURCE, "episode-number",
+ * GOM_SORTING_ASCENDING);
+ * ]|
+ *
+ * The above example maps to the following SQL statement:
+ * |[<!-- language="SQL" -->
+ * ORDER BY 'episodes'.'season-number' DESC, 'episodes'.'episode-number'
+ * ]|
+ */
+void
+gom_sorting_add (GomSorting *sorting,
+ GType resource_type,
+ const gchar *property_name,
+ GomSortingMode sorting_mode)
+{
+ GomOrderByTerm *o = g_new(GomOrderByTerm, 1);
+
+ g_return_if_fail(g_type_is_a(resource_type, GOM_TYPE_RESOURCE));
+ g_return_if_fail(property_name != NULL);
+ g_return_if_fail(sorting_mode);
+
+ o->resource_type = resource_type;
+ o->property_name = g_strdup(property_name);
+ o->mode = sorting_mode;
+ g_queue_push_tail(sorting->priv->order_by_terms, o);
+}
+
+/**
* gom_sorting_get_sql:
* @sorting: (in): A #GomSorting.
* @table_map: (in): A #GHashTable.
diff --git a/gom/gom-sorting.h b/gom/gom-sorting.h
index 87fb1db..dc81a0b 100644
--- a/gom/gom-sorting.h
+++ b/gom/gom-sorting.h
@@ -62,6 +62,10 @@ GomSorting *gom_sorting_new (GType first_resource_type,
const gchar *first_property_name,
GomSortingMode first_sorting_mode,
...);
+void gom_sorting_add (GomSorting *sorting,
+ GType resource_type,
+ const gchar *property_name,
+ GomSortingMode sorting_mode);
G_END_DECLS
diff --git a/tests/test-gom-sorting.c b/tests/test-gom-sorting.c
index 1e2ce3c..a20a368 100644
--- a/tests/test-gom-sorting.c
+++ b/tests/test-gom-sorting.c
@@ -441,6 +441,86 @@ find_order_by_complex (void)
}
static void
+find_order_by_complex_add (void)
+{
+ GomAdapter *adapter;
+ GomRepository *repository;
+ GomFilter *filter;
+ GomSorting *sorting;
+ GomResourceGroup *group;
+ GValue value = { 0, };
+ GError *error = NULL;
+ EpisodeResource *eres;
+ guint count;
+ gchar *id;
+ guint8 season, episode;
+
+ create_memory_db(&adapter, &repository);
+
+ /* Select only the episode for a single show */
+ g_value_init(&value, G_TYPE_STRING);
+ g_value_set_string(&value, "84947");
+ filter = gom_filter_new_eq(EPISODE_TYPE_RESOURCE, "series-id", &value);
+ g_value_unset(&value);
+
+ /* Order by season, then by episode */
+ sorting = g_object_new(GOM_TYPE_SORTING, NULL);
+ gom_sorting_add(sorting, EPISODE_TYPE_RESOURCE, "season-number",
+ GOM_SORTING_DESCENDING);
+ gom_sorting_add(sorting, EPISODE_TYPE_RESOURCE, "episode-number",
+ GOM_SORTING_ASCENDING);
+
+ group = gom_repository_find_sorted_sync(repository, EPISODE_TYPE_RESOURCE,
+ filter, sorting, &error);
+ g_assert_no_error(error);
+ g_object_unref(sorting);
+
+ count = gom_resource_group_get_count(group);
+ g_assert_cmpuint(count, ==, 4);
+
+ gom_resource_group_fetch_sync(group, 0, count, &error);
+ g_assert_no_error(error);
+
+ eres = EPISODE_RESOURCE(gom_resource_group_get_index(group, 0));
+ g_assert(eres);
+ g_object_get(eres, "series-id", &id, "season-number", &season,
+ "episode-number", &episode, NULL);
+ g_assert_cmpstr(id, ==, "84947");
+ g_assert_cmpuint(season, ==, 5);
+ g_assert_cmpuint(episode, ==, 1);
+ g_object_unref(eres);
+
+ eres = EPISODE_RESOURCE(gom_resource_group_get_index(group, 1));
+ g_assert(eres);
+ g_object_get(eres, "series-id", &id, "season-number", &season,
+ "episode-number", &episode, NULL);
+ g_assert_cmpstr(id, ==, "84947");
+ g_assert_cmpuint(season, ==, 5);
+ g_assert_cmpuint(episode, ==, 2);
+ g_object_unref(eres);
+
+ eres = EPISODE_RESOURCE(gom_resource_group_get_index(group, 2));
+ g_assert(eres);
+ g_object_get(eres, "series-id", &id, "season-number", &season,
+ "episode-number", &episode, NULL);
+ g_assert_cmpstr(id, ==, "84947");
+ g_assert_cmpuint(season, ==, 4);
+ g_assert_cmpuint(episode, ==, 1);
+ g_object_unref(eres);
+
+ eres = EPISODE_RESOURCE(gom_resource_group_get_index(group, 3));
+ g_assert(eres);
+ g_object_get(eres, "series-id", &id, "season-number", &season,
+ "episode-number", &episode, NULL);
+ g_assert_cmpstr(id, ==, "84947");
+ g_assert_cmpuint(season, ==, 4);
+ g_assert_cmpuint(episode, ==, 2);
+ g_object_unref(eres);
+
+ free_memory_db(adapter, repository);
+}
+
+static void
find_cb (GObject *object,
GAsyncResult *result,
gpointer user_data)
@@ -547,6 +627,8 @@ main (gint argc, gchar *argv[])
g_test_add_func("/GomRepository/find-order-by-desc", find_order_by_desc);
g_test_add_func("/GomRepository/find-order-by-complex",
find_order_by_complex);
+ g_test_add_func("/GomRepository/find-order-by-complex-add",
+ find_order_by_complex_add);
g_test_add_func("/GomRepository/find-order-by-complex-async",
find_order_by_complex_async);
gMainLoop = g_main_loop_new(NULL, FALSE);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]