tracker r2278 - in trunk: . src/libtracker-db src/trackerd tests/libtracker-db
- From: mottela svn gnome org
- To: svn-commits-list gnome org
- Subject: tracker r2278 - in trunk: . src/libtracker-db src/trackerd tests/libtracker-db
- Date: Tue, 30 Sep 2008 11:22:02 +0000 (UTC)
Author: mottela
Date: Tue Sep 30 11:22:02 2008
New Revision: 2278
URL: http://svn.gnome.org/viewvc/tracker?rev=2278&view=rev
Log:
Added multivalued field support to query
Modified:
trunk/ChangeLog
trunk/src/libtracker-db/tracker-db-dbus.c
trunk/src/libtracker-db/tracker-db-dbus.h
trunk/src/trackerd/tracker-rdf-query.c
trunk/src/trackerd/tracker-search.c
trunk/tests/libtracker-db/tracker-db-dbus-test.c
Modified: trunk/src/libtracker-db/tracker-db-dbus.c
==============================================================================
--- trunk/src/libtracker-db/tracker-db-dbus.c (original)
+++ trunk/src/libtracker-db/tracker-db-dbus.c Tue Sep 30 11:22:02 2008
@@ -19,10 +19,160 @@
* Boston, MA 02110-1301, USA.
*/
+#include <string.h>
+
#include <libtracker-common/tracker-dbus.h>
#include "tracker-db-dbus.h"
+typedef struct {
+ gint key;
+ gpointer value;
+} OneRow;
+
+typedef struct {
+ gpointer value;
+} OneElem;
+
+static inline void
+row_add (GPtrArray *row, gchar *value)
+{
+ OneElem *elem = g_slice_new (OneElem);
+ GSList *list = NULL;
+
+ list = g_slist_prepend (list, value);
+ elem->value = list;
+ g_ptr_array_add (row, elem);
+}
+
+static inline void
+row_insert (GPtrArray *row, gchar *value, guint index)
+{
+ OneElem *elem = g_ptr_array_index (row, index);
+ GSList *list = elem->value;
+ GSList *iter;
+
+ /* We check for duplicate values here so that
+ * we can have several multivalued fields in
+ * the same query.
+ */
+
+ for (iter = list; iter; iter=iter->next) {
+ if (strcmp (iter->data, value) == 0) {
+ return;
+ }
+ }
+
+ list = g_slist_prepend (list, value);
+ elem->value = list;
+}
+
+static inline void
+row_destroy (GPtrArray *row)
+{
+ guint i;
+
+ for (i = 0; i < row->len; i++) {
+ OneElem *elem;
+ GSList *list;
+
+ elem = g_ptr_array_index (row, i);
+ list = elem->value;
+ g_slist_foreach (list,
+ (GFunc) g_free,
+ NULL);
+ g_slist_free (list);
+ g_slice_free (OneElem, elem);
+ }
+
+ g_ptr_array_free (row, TRUE);
+}
+
+static inline gpointer
+rows_lookup (GPtrArray *rows, gint key)
+{
+ guint i;
+ gpointer value = NULL;
+
+ for (i = 0; i < rows->len; i++) {
+ OneRow *row = g_ptr_array_index (rows, i);
+ if (row->key == key) {
+ value = row->value;
+ break;
+ }
+ }
+
+ return value;
+}
+
+static inline void
+rows_destroy (GPtrArray *rows)
+{
+ guint i;
+
+ for (i = 0; i < rows->len; i++) {
+ OneRow *row;
+ row = g_ptr_array_index (rows, i);
+ row_destroy (row->value);
+ g_slice_free (OneRow, row);
+ }
+
+ g_ptr_array_free (rows, TRUE);
+}
+
+static inline void
+rows_add (GPtrArray *rows, gint key, gpointer value)
+{
+ OneRow *row = g_slice_new (OneRow);
+
+ row->key = key;
+ row->value = value;
+
+ g_ptr_array_add (rows, row);
+}
+
+static inline void
+rows_migrate (GPtrArray *rows, GPtrArray *result)
+{
+ guint i,j;
+
+ /* Go thought the lists and join with | separator */
+ for (i = 0; i < rows->len; i++) {
+ OneRow *row;
+ GPtrArray *array;
+ gchar **strv;
+
+ row = g_ptr_array_index (rows, i);
+ array = row->value;
+
+ strv = g_new0 (gchar*, array->len + 1);
+
+ for (j = 0; j < array->len; j++) {
+ OneElem *elem;
+ GSList *list;
+ GSList *iter;
+ GString *string;
+
+ elem = g_ptr_array_index (array, j);
+ list = elem->value;
+ string = g_string_new((gchar *)list->data);
+
+ for (iter = list->next; iter; iter = iter->next) {
+ g_string_append_printf (string, "|%s", (gchar *)iter->data);
+ }
+
+ strv[j] = string->str;
+
+ g_string_free (string, FALSE);
+ }
+
+ strv[array->len] = NULL;
+
+ g_ptr_array_add (result, strv);
+ }
+}
+
+
static gchar **
dbus_query_result_to_strv (TrackerDBResultSet *result_set,
gint column,
@@ -234,8 +384,8 @@
}
while (valid) {
- GSList *list = NULL;
- gchar **p;
+ GSList *list = NULL;
+ gchar **p;
/* Append fields to the array */
for (i = 0; i < columns; i++) {
@@ -281,3 +431,91 @@
return ptr_array;
}
+GPtrArray *
+tracker_dbus_query_result_multi_to_ptr_array (TrackerDBResultSet *result_set)
+{
+ GPtrArray *result;
+ GPtrArray *rows;
+ gboolean valid = FALSE;
+ gint columns;
+
+ rows = g_ptr_array_new ();
+
+ if (result_set) {
+ valid = TRUE;
+
+ /* Make sure we rewind before iterating the result set */
+ tracker_db_result_set_rewind (result_set);
+
+ /* Find out how many columns to iterate */
+ columns = tracker_db_result_set_get_n_columns (result_set);
+ }
+
+ while (valid) {
+ gint key;
+ GPtrArray *row;
+
+ gint column;
+ gboolean add = FALSE;
+ GValue value_in = {0, };
+
+ /* Get the key and the matching row if exists */
+ _tracker_db_result_set_get_value (result_set, 0, &value_in);
+ key = g_value_get_int (&value_in);
+ row = rows_lookup (rows, key);
+ if (!row) {
+ row = g_ptr_array_new ();
+ add = TRUE;
+ }
+
+ /* Append fields or values to the array */
+ for (column = 1; column < columns; column++) {
+ GValue transform = { 0, };
+ GValue value = { 0, };
+ gchar *str;
+
+ g_value_init (&transform, G_TYPE_STRING);
+
+ _tracker_db_result_set_get_value (result_set,
+ column,
+ &value);
+
+ if (g_value_transform (&value, &transform)) {
+ str = g_value_dup_string (&transform);
+
+ if (!str) {
+ str = g_strdup ("");
+ } else if (!g_utf8_validate (str, -1, NULL)) {
+ g_warning ("Could not add string:'%s' to GStrv, invalid UTF-8", str);
+ g_free (str);
+ str = g_strdup ("");
+ }
+ } else {
+ str = g_strdup ("");
+ }
+
+ if (add) {
+ row_add (row, str);
+ } else {
+ row_insert (row, str, column-1);
+ }
+
+ g_value_unset (&value);
+ g_value_unset (&transform);
+ }
+
+
+ if (add) {
+ rows_add (rows, key, row);
+ }
+
+ valid = tracker_db_result_set_iter_next (result_set);
+ }
+
+ result = g_ptr_array_new();
+
+ rows_migrate (rows, result);
+ rows_destroy (rows);
+
+ return result;
+}
Modified: trunk/src/libtracker-db/tracker-db-dbus.h
==============================================================================
--- trunk/src/libtracker-db/tracker-db-dbus.h (original)
+++ trunk/src/libtracker-db/tracker-db-dbus.h Tue Sep 30 11:22:02 2008
@@ -40,6 +40,8 @@
gboolean rewind);
GHashTable *tracker_dbus_query_result_to_hash_table (TrackerDBResultSet *result_set);
GPtrArray * tracker_dbus_query_result_to_ptr_array (TrackerDBResultSet *result_set);
+GPtrArray * tracker_dbus_query_result_multi_to_ptr_array (TrackerDBResultSet *result_set);
+
G_END_DECLS
Modified: trunk/src/trackerd/tracker-rdf-query.c
==============================================================================
--- trunk/src/trackerd/tracker-rdf-query.c (original)
+++ trunk/src/trackerd/tracker-rdf-query.c Tue Sep 30 11:22:02 2008
@@ -1116,11 +1116,11 @@
case 6:
case 7:
case 8:
- g_string_append_printf (result, " Select DISTINCT (S.Path || '%s' || S.Name) as uri, GetServiceName(S.ServiceTypeID) as stype ", G_DIR_SEPARATOR_S);
+ g_string_append_printf (result, " Select DISTINCT S.ID, (S.Path || '%s' || S.Name) as uri, GetServiceName(S.ServiceTypeID) as stype ", G_DIR_SEPARATOR_S);
break;
default :
- g_string_append_printf (result, " Select DISTINCT (S.Path || '%s' || S.Name) as uri, GetServiceName(S.ServiceTypeID) as stype ", G_DIR_SEPARATOR_S);
+ g_string_append_printf (result, " Select DISTINCT S.ID, (S.Path || '%s' || S.Name) as uri, GetServiceName(S.ServiceTypeID) as stype ", G_DIR_SEPARATOR_S);
break;
}
Modified: trunk/src/trackerd/tracker-search.c
==============================================================================
--- trunk/src/trackerd/tracker-search.c (original)
+++ trunk/src/trackerd/tracker-search.c Tue Sep 30 11:22:02 2008
@@ -1182,7 +1182,7 @@
g_free (query_translated);
}
- values = tracker_dbus_query_result_to_ptr_array (result_set);
+ values = tracker_dbus_query_result_multi_to_ptr_array (result_set);
dbus_g_method_return (context, values);
Modified: trunk/tests/libtracker-db/tracker-db-dbus-test.c
==============================================================================
--- trunk/tests/libtracker-db/tracker-db-dbus-test.c (original)
+++ trunk/tests/libtracker-db/tracker-db-dbus-test.c Tue Sep 30 11:22:02 2008
@@ -55,6 +55,50 @@
}
+static TrackerDBResultSet *
+get_mock_tracker_db_multi_result (gint results, gint columns, gboolean set_null) {
+
+ TrackerDBResultSet *mock;
+ gint i, j, multi;
+
+ mock = _tracker_db_result_set_new (columns+1);
+
+ for (i = 0; i < results; i++) {
+
+ for (multi = 0; multi < 2 ; multi++) {
+
+ _tracker_db_result_set_append (mock);
+
+ {
+ GValue id_value = {0,};
+
+ g_value_init (&id_value, G_TYPE_INT);
+ g_value_set_int (&id_value, i);
+ _tracker_db_result_set_set_value (mock, 0, &id_value);
+
+ g_value_unset (&id_value);
+ }
+
+ for (j = 1; j < columns+1; j++) {
+
+ GValue value = {0,};
+ gchar * text = g_strdup_printf ("value %d", j+multi*j%2);
+
+ g_value_init (&value, G_TYPE_STRING);
+ g_value_set_string (&value, (set_null ? NULL : text));
+ _tracker_db_result_set_set_value (mock, j, &value);
+
+ g_value_unset (&value);
+ g_free (text);
+ }
+ }
+ }
+
+ tracker_db_result_set_rewind (mock);
+
+ return mock;
+
+}
static void
@@ -155,6 +199,59 @@
g_object_unref (result_set);
}
+
+static void
+test_dbus_query_result_multi_to_ptr_array ()
+{
+ TrackerDBResultSet *result_set = NULL;
+ GPtrArray *result = NULL;
+
+ /* NULL */
+ result = tracker_dbus_query_result_multi_to_ptr_array (result_set);
+ g_assert_cmpint (result->len, ==, 0);
+ free_string_ptr_array (result);
+
+ /* 5 results, 1 column */
+ result_set = get_mock_tracker_db_multi_result (5, 1, FALSE);
+ result = tracker_dbus_query_result_multi_to_ptr_array (result_set);
+
+ g_assert_cmpint (result->len, ==, 5);
+ free_string_ptr_array (result);
+
+ g_object_unref (result_set);
+
+ /* 0 results, 1 columns */
+ result_set = get_mock_tracker_db_multi_result (0, 1, FALSE);
+ if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDERR)) {
+ result = tracker_dbus_query_result_multi_to_ptr_array (result_set);
+ free_string_ptr_array (result);
+ }
+ g_test_trap_assert_failed ();
+ /* Should raise g_critical (priv->array...); */
+
+ g_object_unref (result_set);
+
+ /* 1 result ... NULL */
+ result_set = get_mock_tracker_db_multi_result (1, 1, TRUE);
+ result = tracker_dbus_query_result_multi_to_ptr_array (result_set);
+ g_assert_cmpint (result->len, ==, 1);
+ free_string_ptr_array (result);
+
+ g_object_unref (result_set);
+
+
+ /* 5 results, 5 columns */
+ result_set = get_mock_tracker_db_multi_result (5, 5, FALSE);
+ result = tracker_dbus_query_result_multi_to_ptr_array (result_set);
+
+ g_assert_cmpint (result->len, ==, 5);
+ free_string_ptr_array (result);
+
+ g_object_unref (result_set);
+
+}
+
+
gint
main (gint argc, gchar **argv)
{
@@ -170,7 +267,8 @@
test_dbus_query_result_to_hash_table);
g_test_add_func ("/libtracker-db/tracker-db-dbus/query_result_to_ptr_array",
test_dbus_query_result_to_ptr_array);
-
+ g_test_add_func ("/libtracker-db/tracker-db-dbus/query_result_multi_to_ptr_array",
+ test_dbus_query_result_multi_to_ptr_array);
result = g_test_run ();
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]