]> Pileus Git - ~andy/gtk/commitdiff
search: update for tracker 0.8 API
authorTomas Bzatek <tbzatek@redhat.com>
Fri, 19 Mar 2010 13:40:11 +0000 (14:40 +0100)
committerTristan Van Berkom <tristan.van.berkom@gmail.com>
Sun, 4 Apr 2010 00:59:17 +0000 (20:59 -0400)
Tracker 0.8 series (and late 0.7.xx) introduces new API based on SPARQL
query language. The queries here use fulltext search, just like with
with previous tracker versions. Old tracker 0.6 support is still maintained.

gtk/gtksearchenginetracker.c

index 62447f8c29788d6666b61e9cc85afc11b7972eca..7a8e26c9fee462a401b08c057c6e47cd18a8b099 100644 (file)
@@ -23,9 +23,6 @@
 #include "config.h"
 #include <gmodule.h>
 #include "gtksearchenginetracker.h"
-#if 0
-#include <tracker.h>
-#endif
 
 /* we dlopen() libtracker at runtime */
 
@@ -34,9 +31,12 @@ typedef struct _TrackerClient TrackerClient;
 typedef enum
 {
   TRACKER_0_6 = 1 << 0,
-  TRACKER_0_7 = 1 << 1
+  TRACKER_0_7 = 1 << 1,
+  TRACKER_0_8 = 1 << 2
 } TrackerVersion;
 
+
+/* tracker 0.6 API */
 typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data);
 
 static TrackerClient * (*tracker_connect) (gboolean enable_warnings, gint timeout) = NULL;
@@ -53,6 +53,23 @@ static void (*tracker_search_metadata_by_text_and_location_async) (TrackerClient
                                                                   const char *location, 
                                                                   TrackerArrayReply callback, 
                                                                   gpointer user_data) = NULL;
+/* tracker 0.8 API */
+typedef enum {
+       TRACKER_CLIENT_ENABLE_WARNINGS = 1 << 0
+} TrackerClientFlags;
+
+typedef void (*TrackerReplyGPtrArray) (GPtrArray *result,
+                                      GError    *error,
+                                      gpointer   user_data);
+
+static TrackerClient * (*tracker_client_new)                   (TrackerClientFlags      flags,
+                                                                gint                    timeout) = NULL;
+static gchar *         (*tracker_sparql_escape)                (const gchar            *str) = NULL;
+static guint           (*tracker_resources_sparql_query_async) (TrackerClient          *client,
+                                                                const gchar            *query,
+                                                                TrackerReplyGPtrArray   callback,
+                                                                gpointer                user_data) = NULL;
+
 
 static struct TrackerDlMapping
 {
@@ -65,9 +82,12 @@ static struct TrackerDlMapping
   MAP (tracker_connect, TRACKER_0_6 | TRACKER_0_7),
   MAP (tracker_disconnect, TRACKER_0_6 | TRACKER_0_7),
   MAP (tracker_get_version, TRACKER_0_6),
-  MAP (tracker_cancel_last_call, TRACKER_0_6 | TRACKER_0_7),
+  MAP (tracker_cancel_last_call, TRACKER_0_6 | TRACKER_0_7 | TRACKER_0_8),
   MAP (tracker_search_metadata_by_text_async, TRACKER_0_6 | TRACKER_0_7),
   MAP (tracker_search_metadata_by_text_and_location_async, TRACKER_0_6 | TRACKER_0_7),
+  MAP (tracker_client_new, TRACKER_0_8),
+  MAP (tracker_sparql_escape, TRACKER_0_8),
+  MAP (tracker_resources_sparql_query_async, TRACKER_0_8)
 #undef MAP
 };
 
@@ -76,6 +96,7 @@ open_libtracker (void)
 {
   static gboolean done = FALSE;
   static TrackerVersion version = 0;
+  gpointer x;
 
   if (!done)
     {
@@ -89,6 +110,11 @@ open_libtracker (void)
       tracker = g_module_open ("libtracker-client-0.7.so.0", flags);
       version = TRACKER_0_7;
 
+      if (tracker && g_module_symbol (tracker, "tracker_resources_sparql_query_async", &x))
+        {
+            version = TRACKER_0_8;
+        }
+
       if (!tracker)
         {
           tracker = g_module_open ("libtrackerclient.so.0", flags);
@@ -151,20 +177,43 @@ finalize (GObject *object)
       tracker->priv->query = NULL;
     }
 
-  tracker_disconnect (tracker->priv->client);
+  if (tracker->priv->version == TRACKER_0_8)
+    g_object_unref (tracker->priv->client);
+  else
+    tracker_disconnect (tracker->priv->client);
 
   G_OBJECT_CLASS (_gtk_search_engine_tracker_parent_class)->finalize (object);
 }
 
 
+/* stolen from tracker sources, tracker.c */
+static void
+sparql_append_string_literal (GString     *sparql,
+                              const gchar *str)
+{
+  char *s;
+
+  s = tracker_sparql_escape (str);
+
+  g_string_append_c (sparql, '"');
+  g_string_append (sparql, s);
+  g_string_append_c (sparql, '"');
+
+  g_free (s);
+}
+
+
 static void
-search_callback (gchar  **results, 
+search_callback (gpointer results,
                 GError  *error, 
                 gpointer user_data)
 {
   GtkSearchEngineTracker *tracker;
   gchar **results_p;
   GList *hit_uris;
+  GPtrArray *OUT_result;
+  gchar *uri;
+  gint i;
   
   tracker = GTK_SEARCH_ENGINE_TRACKER (user_data);
   hit_uris = NULL;
@@ -173,33 +222,47 @@ search_callback (gchar  **results,
 
   if (error) 
     {
-      _gtk_search_engine_error ( GTK_SEARCH_ENGINE (tracker), error->message);
+      _gtk_search_engine_error (GTK_SEARCH_ENGINE (tracker), error->message);
       g_error_free (error);
       return;
     }
 
   if (!results)
     return;
-       
-  for (results_p = results; *results_p; results_p++) 
+
+  if (tracker->priv->version == TRACKER_0_8)
     {
-      gchar *uri;
+      OUT_result = (GPtrArray*) results;
 
-      if (tracker->priv->version == TRACKER_0_6)
-        uri = g_filename_to_uri (*results_p, NULL, NULL);
-      else
-        uri = *results_p;
+      for (i = 0; i < OUT_result->len; i++)
+        {
+          uri = g_strdup (((gchar **) OUT_result->pdata[i])[0]);
+          if (uri)
+            hit_uris = g_list_prepend (hit_uris, uri);
+        }
 
-      if (uri)
-       hit_uris = g_list_prepend (hit_uris, uri);
+      g_ptr_array_foreach (OUT_result, (GFunc) g_free, NULL);
+      g_ptr_array_free (OUT_result, TRUE);
+    }
+  else
+    {
+      for (results_p = results; *results_p; results_p++)
+        {
+          if (tracker->priv->version == TRACKER_0_6)
+            uri = g_filename_to_uri (*results_p, NULL, NULL);
+          else
+            uri = g_strdup (*results_p);
+
+          if (uri)
+            hit_uris = g_list_prepend (hit_uris, uri);
+        }
+      g_strfreev ((gchar **) results);
     }
 
   _gtk_search_engine_hits_added (GTK_SEARCH_ENGINE (tracker), hit_uris);
   _gtk_search_engine_finished (GTK_SEARCH_ENGINE (tracker));
 
-  g_strfreev  (results);
-  if (tracker->priv->version == TRACKER_0_6)
-    g_list_foreach (hit_uris, (GFunc)g_free, NULL);
+  g_list_foreach (hit_uris, (GFunc) g_free, NULL);
   g_list_free (hit_uris);
 }
 
@@ -209,6 +272,7 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine)
 {
   GtkSearchEngineTracker *tracker;
   gchar        *search_text, *location, *location_uri;
+  GString *sparql;
 
   tracker = GTK_SEARCH_ENGINE_TRACKER (engine);
 
@@ -233,25 +297,46 @@ gtk_search_engine_tracker_start (GtkSearchEngine *engine)
         location = location_uri;
     }
 
-  if (location) 
+  if (tracker->priv->version == TRACKER_0_8)
     {
-      tracker_search_metadata_by_text_and_location_async (tracker->priv->client,
-                                                         search_text, 
-                                                          location, 
-                                                          search_callback,
-                                                          tracker);
-      g_free (location);
+      sparql = g_string_new ("SELECT ?url WHERE { ?file a nfo:FileDataObject; nie:url ?url; fts:match ");
+      sparql_append_string_literal (sparql, search_text);
+      if (location)
+        {
+          g_string_append (sparql, " . FILTER (fn:starts-with(?url,");
+          sparql_append_string_literal (sparql, location);
+          g_string_append (sparql, "))");
+        }
+      g_string_append (sparql, " }");
+
+      tracker_resources_sparql_query_async (tracker->priv->client,
+                                            sparql->str,
+                                            (TrackerReplyGPtrArray) search_callback,
+                                            tracker);
+      g_string_free (sparql, TRUE);
     }
   else 
     {
-      tracker_search_metadata_by_text_async (tracker->priv->client,
-                                             search_text, 
-                                             search_callback,
-                                             tracker);
+      if (location)
+        {
+          tracker_search_metadata_by_text_and_location_async (tracker->priv->client,
+                                                              search_text,
+                                                              location,
+                                                              (TrackerArrayReply) search_callback,
+                                                              tracker);
+        }
+      else
+        {
+          tracker_search_metadata_by_text_async (tracker->priv->client,
+                                                 search_text,
+                                                 (TrackerArrayReply) search_callback,
+                                                 tracker);
+        }
     }
 
   tracker->priv->query_pending = TRUE;
   g_free (search_text);
+  g_free (location);
 }
 
 static void
@@ -326,14 +411,22 @@ _gtk_search_engine_tracker_new (void)
 
   version = open_libtracker ();
 
-  if (!tracker_connect)
-    return NULL;
+  if (version == TRACKER_0_8)
+    {
+      tracker_client = tracker_client_new (TRACKER_CLIENT_ENABLE_WARNINGS, G_MAXINT);
+    }
+  else
+    {
+      if (!tracker_connect)
+        return NULL;
+
+      tracker_client = tracker_connect (FALSE, -1);
+    }
 
-  tracker_client = tracker_connect (FALSE, -1);
-  
   if (!tracker_client)
     return NULL;
 
+
   if (version == TRACKER_0_6)
     {
       if (!tracker_get_version)