[nautilus] Load tracker/beagle at runtime



commit e1e1fe0d505bdb9b53d7204bba0abeee52f73bca
Author: Tomas Bzatek <tbzatek redhat com>
Date:   Mon Mar 8 12:01:49 2010 +0100

    Load tracker/beagle at runtime
    
    Dynamically load tracker (preferred) and beagle client libraries on demand if available.
    This allows more flexibility for packagers and users.
    
    See bug 589345 for details.

 configure.in                                       |   62 ----
 libnautilus-private/Makefile.am                    |   20 +-
 .../nautilus-search-engine-beagle.c                |  132 +++++++-
 .../nautilus-search-engine-tracker.c               |  386 ++++++++++++++++----
 libnautilus-private/nautilus-search-engine.c       |   10 +-
 5 files changed, 446 insertions(+), 164 deletions(-)
---
diff --git a/configure.in b/configure.in
index 92dbbe6..11ff2aa 100644
--- a/configure.in
+++ b/configure.in
@@ -196,66 +196,6 @@ if test "x$enable_xmp" != "xno"; then
 fi
 
 dnl ==========================================================================
-dnl search implementations
-dnl ****************************
-
-AM_CONDITIONAL(HAVE_TRACKER, false)
-
-dnl libtracker checking
-			    			  
-AC_ARG_ENABLE(tracker, 
-	AC_HELP_STRING([--disable-tracker], 
-			[build without tracker support]))
-msg_tracker=no
-if test "x$enable_tracker" != "xno"; then
-	PKG_CHECK_MODULES(TRACKER, tracker-client-0.7, [
-	                  AM_CONDITIONAL(HAVE_TRACKER, true)
-			  AC_DEFINE(HAVE_TRACKER, 1, [Define to enable tracker support])
-			  AC_DEFINE(HAVE_TRACKER_0_7, 1, [Define to enable tracker support])
-			  ]
-                          msg_tracker=yes,
-	                  [
-	                  PKG_CHECK_MODULES(TRACKER, tracker >= tracker_minver, [
-	                                    AM_CONDITIONAL(HAVE_TRACKER, true)
-			                    AC_DEFINE(HAVE_TRACKER, 1, [Define to enable tracker support])
-			                    ]
-		                            msg_tracker=yes,
-	                                   [AM_CONDITIONAL(HAVE_TRACKER, false)])
-	                  ])
-        AC_SUBST(TRACKER_CFLAGS)
-	AC_SUBST(TRACKER_LIBS)
-fi
-
-dnl ==========================================================================
-
-
-AM_CONDITIONAL(HAVE_BEAGLE, false)
-
-dnl libbeagle checking
-
-AC_ARG_ENABLE(beagle, 
-	AC_HELP_STRING([--disable-beagle], 
-			[build without beagle support]))
-msg_beagle=no
-if test "x$enable_beagle" != "xno"; then
-	BEAGLE_PKGCONFIG=
-	if $PKG_CONFIG --exists libbeagle-1.0; then
-		BEAGLE_PKGCONFIG=libbeagle-1.0
-	else
-		BEAGLE_PKGCONFIG=libbeagle-0.0
-	fi
-
-	PKG_CHECK_MODULES(BEAGLE, $BEAGLE_PKGCONFIG >= beagle_minver, [
-		  	  AM_CONDITIONAL(HAVE_BEAGLE, true)
-			  AC_DEFINE(HAVE_BEAGLE, 1, [Define to enable beagle support])
-			  ]
-                          msg_beagle=yes,
-	          	  [AM_CONDITIONAL(HAVE_BEAGLE, false)])
-        AC_SUBST(BEAGLE_CFLAGS)
-	AC_SUBST(BEAGLE_LIBS)
-fi
-
-dnl ==========================================================================
 
 dnl ****************************
 dnl *** Check for libselinux ***
@@ -466,8 +406,6 @@ nautilus-$VERSION:
 	prefix:                 ${prefix}
 	source code location:	${srcdir}
 	compiler:		${CC}
-	tracker support:	$msg_tracker
-	beagle support:		$msg_beagle
 	xmp support:		$msg_xmp
 	PackageKit support:     $msg_packagekit
 
diff --git a/libnautilus-private/Makefile.am b/libnautilus-private/Makefile.am
index b2a47ce..3cd721a 100644
--- a/libnautilus-private/Makefile.am
+++ b/libnautilus-private/Makefile.am
@@ -154,6 +154,10 @@ libnautilus_private_la_SOURCES = \
 	nautilus-search-engine.h \
 	nautilus-search-engine-simple.c \
 	nautilus-search-engine-simple.h \
+	nautilus-search-engine-beagle.c \
+	nautilus-search-engine-beagle.h \
+	nautilus-search-engine-tracker.c \
+	nautilus-search-engine-tracker.h \
 	nautilus-sidebar-provider.c \
 	nautilus-sidebar-provider.h \
 	nautilus-sidebar.c \
@@ -195,22 +199,6 @@ libnautilus_private_la_SOURCES = \
 	nautilus-window-slot-info.h \
 	$(NULL)
 
-BEAGLE_SOURCES = \
-	nautilus-search-engine-beagle.c \
-	nautilus-search-engine-beagle.h
-
-if HAVE_BEAGLE
-libnautilus_private_la_SOURCES += $(BEAGLE_SOURCES)
-endif
-
-TRACKER_SOURCES = \
-	nautilus-search-engine-tracker.c \
-	nautilus-search-engine-tracker.h
-
-if HAVE_TRACKER
-libnautilus_private_la_SOURCES += $(TRACKER_SOURCES)
-endif
-
 $(lib_LTLIBRARIES): $(dependency_static_libs)
 
 nautilus-marshal.h: nautilus-marshal.list $(GLIB_GENMARSHAL)
diff --git a/libnautilus-private/nautilus-search-engine-beagle.c b/libnautilus-private/nautilus-search-engine-beagle.c
index 3ab6507..930923f 100644
--- a/libnautilus-private/nautilus-search-engine-beagle.c
+++ b/libnautilus-private/nautilus-search-engine-beagle.c
@@ -23,10 +23,20 @@
 
 #include <config.h>
 #include "nautilus-search-engine-beagle.h"
-#include <beagle/beagle.h>
 
 #include <eel/eel-gtk-macros.h>
 #include <eel/eel-glib-extensions.h>
+#include <gmodule.h>
+
+typedef struct _BeagleHit BeagleHit;
+typedef struct _BeagleQuery BeagleQuery;
+typedef struct _BeagleClient BeagleClient;
+typedef struct _BeagleRequest BeagleRequest;
+typedef struct _BeagleFinishedResponse BeagleFinishedResponse;
+typedef struct _BeagleHitsAddedResponse BeagleHitsAddedResponse;
+typedef struct _BeagleQueryPartProperty BeagleQueryPartProperty;
+typedef struct _BeagleQueryPart BeagleQueryPart;
+typedef struct _BeagleHitsSubtractedResponse BeagleHitsSubtractedResponse;
 
 struct NautilusSearchEngineBeagleDetails {
 	BeagleClient *client;
@@ -37,6 +47,121 @@ struct NautilusSearchEngineBeagleDetails {
 	gboolean query_finished;
 };
 
+/* We dlopen() all the following from libbeagle at runtime */
+#define BEAGLE_HIT(x) ((BeagleHit *)(x))
+#define BEAGLE_REQUEST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), beagle_request_get_type(), BeagleRequest))
+#define BEAGLE_QUERY_PART(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), beagle_query_part_get_type(), BeagleQueryPart))
+
+typedef enum {
+	BEAGLE_QUERY_PART_LOGIC_REQUIRED   = 1,
+	BEAGLE_QUERY_PART_LOGIC_PROHIBITED = 2
+} BeagleQueryPartLogic;
+
+typedef enum {
+	BEAGLE_PROPERTY_TYPE_UNKNOWN = 0,
+	BEAGLE_PROPERTY_TYPE_TEXT    = 1,
+	BEAGLE_PROPERTY_TYPE_KEYWORD = 2,
+	BEAGLE_PROPERTY_TYPE_DATE    = 3,
+	BEAGLE_PROPERTY_TYPE_LAST    = 4
+} BeaglePropertyType;
+
+/* *static* wrapper function pointers */
+static gboolean (*beagle_client_send_request_async) (BeagleClient  *client,
+                                                    BeagleRequest  *request,
+                                                    GError        **err) = NULL;
+static G_CONST_RETURN char *(*beagle_hit_get_uri) (BeagleHit *hit) = NULL;
+static GSList *(*beagle_hits_added_response_get_hits) (BeagleHitsAddedResponse *response) = NULL;
+static BeagleQuery *(*beagle_query_new) (void) = NULL;
+static void (*beagle_query_add_text) (BeagleQuery     *query,
+				      const char      *str) = NULL;
+static BeagleQueryPartProperty *(*beagle_query_part_property_new) (void) = NULL;
+static void (*beagle_query_part_set_logic) (BeagleQueryPart      *part,
+					    BeagleQueryPartLogic  logic) = NULL;
+static void (*beagle_query_part_property_set_key) (BeagleQueryPartProperty *part,
+						   const char              *key) = NULL;
+static void (*beagle_query_part_property_set_value) (BeagleQueryPartProperty *part,
+						     const char *             value) = NULL;
+static void (*beagle_query_part_property_set_property_type) (BeagleQueryPartProperty *part,
+							     BeaglePropertyType       prop_type) = NULL;
+static void (*beagle_query_add_part) (BeagleQuery     *query,
+				      BeagleQueryPart *part) = NULL;
+static GType (*beagle_request_get_type) (void) = NULL;
+static GType (*beagle_query_part_get_type) (void) = NULL;
+static gboolean (*beagle_util_daemon_is_running) (void) = NULL;
+static BeagleClient *(*beagle_client_new_real) (const char *client_name) = NULL;
+static void (*beagle_query_set_max_hits) (BeagleQuery *query,
+					  int max_hits) = NULL;
+static GSList *(*beagle_hits_subtracted_response_get_uris) (BeagleHitsSubtractedResponse *response) = NULL;
+
+static struct BeagleDlMapping
+{
+  const char *fn_name;
+  gpointer *fn_ptr_ref;
+} beagle_dl_mapping[] =
+{
+#define MAP(a) { #a, (gpointer *)&a }
+  MAP (beagle_client_send_request_async),
+  MAP (beagle_hit_get_uri),
+  MAP (beagle_hits_added_response_get_hits),
+  MAP (beagle_query_new),
+  MAP (beagle_query_add_text),
+  MAP (beagle_query_part_property_new),
+  MAP (beagle_query_part_set_logic),
+  MAP (beagle_query_part_property_set_key),
+  MAP (beagle_query_part_property_set_value),
+  MAP (beagle_query_part_property_set_property_type),
+  MAP (beagle_query_add_part),
+  MAP (beagle_request_get_type),
+  MAP (beagle_query_part_get_type),
+  MAP (beagle_util_daemon_is_running),
+  MAP (beagle_query_set_max_hits),
+  MAP (beagle_hits_subtracted_response_get_uris),
+#undef MAP
+  { "beagle_client_new", (gpointer *)&beagle_client_new_real },
+};
+
+static void 
+open_libbeagle (void)
+{
+  static gboolean done = FALSE;
+
+  if (!done)
+    {
+      int i;
+      GModule *beagle;
+      
+      done = TRUE;
+ 
+      beagle = g_module_open ("libbeagle.so.1", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+      if (!beagle)
+	return;
+      
+      for (i = 0; i < G_N_ELEMENTS (beagle_dl_mapping); i++)
+	{
+	  if (!g_module_symbol (beagle, beagle_dl_mapping[i].fn_name,
+				beagle_dl_mapping[i].fn_ptr_ref))
+	    {
+	      g_warning ("Missing symbol '%s' in libbeagle\n",
+			 beagle_dl_mapping[i].fn_name);
+	      g_module_close (beagle);
+
+	      for (i = 0; i < G_N_ELEMENTS (beagle_dl_mapping); i++)
+		beagle_dl_mapping[i].fn_ptr_ref = NULL;
+
+	      return;
+	    }
+	}
+    }
+}
+
+static BeagleClient *
+beagle_client_new (const char *client_name)
+{
+  if (beagle_client_new_real)
+    return beagle_client_new_real (client_name);
+
+  return NULL;
+}
 
 static void  nautilus_search_engine_beagle_class_init       (NautilusSearchEngineBeagleClass *class);
 static void  nautilus_search_engine_beagle_init             (NautilusSearchEngineBeagle      *engine);
@@ -276,8 +401,11 @@ nautilus_search_engine_beagle_new (void)
 {
 	NautilusSearchEngineBeagle *engine;
 	BeagleClient *client;
+
+	open_libbeagle ();
 	
-	if (!beagle_util_daemon_is_running ()) {
+	if (beagle_util_daemon_is_running == NULL ||
+	    !beagle_util_daemon_is_running ()) {
 		/* check whether daemon is running as beagle_client_new
 		 * doesn't fail when a stale socket file exists */
 		return NULL;
diff --git a/libnautilus-private/nautilus-search-engine-tracker.c b/libnautilus-private/nautilus-search-engine-tracker.c
index eec8d74..6c56a71 100644
--- a/libnautilus-private/nautilus-search-engine-tracker.c
+++ b/libnautilus-private/nautilus-search-engine-tracker.c
@@ -25,14 +25,162 @@
 #include "nautilus-search-engine-tracker.h"
 #include <eel/eel-gtk-macros.h>
 #include <eel/eel-glib-extensions.h>
+#include <gmodule.h>
+#include <string.h>
+
+
+typedef struct _TrackerClient TrackerClient;
+
+
+/* tracker 0.6 API */
+typedef void (*TrackerArrayReply) (char **result, GError *error, gpointer user_data);
+
+static TrackerClient *	(*tracker_connect)		(gboolean enable_warnings) = NULL;
+static TrackerClient *	(*tracker_connect_07)		(gboolean enable_warnings,
+							 gint     timeout) = NULL;
+static void		(*tracker_disconnect)		(TrackerClient *client) = NULL;
+static void		(*tracker_cancel_last_call)	(TrackerClient *client) = NULL;
+static int		(*tracker_get_version)		(TrackerClient *client, GError **error) = NULL;
+
+
+static void (*tracker_search_metadata_by_text_async) (TrackerClient *client,
+						      const char *query,
+						      TrackerArrayReply callback,
+						      gpointer user_data) = NULL;
+static void (*tracker_search_metadata_by_text_and_mime_async) (TrackerClient *client,
+							       const char *query,
+							       const char **mimes,
+							       TrackerArrayReply callback,
+							       gpointer user_data) = NULL;
+static void (*tracker_search_metadata_by_text_and_location_async) (TrackerClient *client,
+								   const char *query,
+								   const char *location,
+								   TrackerArrayReply callback,
+								   gpointer user_data) = NULL;
+static void (*tracker_search_metadata_by_text_and_mime_and_location_async) (TrackerClient *client,
+									    const char *query,
+									    const char **mimes,
+									    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 gboolean		(*tracker_cancel_call)			(TrackerClient          *client,
+								 guint                   call_id) = NULL;
+
+/*  -- we reuse tracker_cancel_last_call() from above, declaration is equal
+ *
+ *  static gboolean		(*tracker_cancel_last_call)		(TrackerClient          *client) = 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;
+
+
+#define MAP(a, b) { #a, (gpointer *)&a, b }
+
+typedef struct {
+	const char	*fn_name;
+	gpointer	*fn_ptr_ref;
+	gboolean	 mandatory;
+} TrackerDlMapping;
+
+static TrackerDlMapping tracker_dl_mapping[] = {
+	MAP (tracker_connect, TRUE),
+	MAP (tracker_disconnect, TRUE),
+	MAP (tracker_cancel_last_call, TRUE),
+	MAP (tracker_search_metadata_by_text_async, TRUE),
+	MAP (tracker_search_metadata_by_text_and_mime_async, TRUE),
+	MAP (tracker_search_metadata_by_text_and_location_async, TRUE),
+	MAP (tracker_search_metadata_by_text_and_mime_and_location_async, TRUE),
+	MAP (tracker_get_version, FALSE)
+};
 
-#ifdef HAVE_TRACKER_0_7
-#include <libtracker-client/tracker.h>
-#else
-#include <tracker.h>
-#endif
+static TrackerDlMapping tracker_dl_mapping_08[] = {
+	MAP (tracker_client_new, TRUE),
+	MAP (tracker_cancel_call, TRUE),
+	MAP (tracker_cancel_last_call, TRUE),
+	MAP (tracker_sparql_escape, TRUE),
+	MAP (tracker_resources_sparql_query_async, TRUE)
+};
+#undef MAP
+
+
+static gboolean tracker_07;
+static gboolean tracker_08;
 
 
+static gboolean
+load_symbols (GModule *tracker, TrackerDlMapping mapping[], gint num_elements)
+{
+	int i;
+
+	for (i = 0; i < num_elements; i++) {
+		if (! g_module_symbol (tracker, mapping[i].fn_name,
+		                       mapping[i].fn_ptr_ref) &&
+		      mapping[i].mandatory) {
+			g_warning ("Missing symbol '%s' in libtracker\n",
+				    mapping[i].fn_name);
+			g_module_close (tracker);
+
+			for (i = 0; i < num_elements; i++)
+				mapping[i].fn_ptr_ref = NULL;
+
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+static void
+open_libtracker (void)
+{
+	static gboolean done = FALSE;
+
+	if (! done) {
+		GModule *tracker;
+
+		done = TRUE;
+		tracker_07 = TRUE;
+		tracker_08 = TRUE;
+
+		tracker = g_module_open ("libtracker-client-0.7.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+		if (! tracker) {
+			tracker = g_module_open ("libtrackerclient.so.0", G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
+			tracker_07 = FALSE;
+			tracker_08 = FALSE;
+		}
+		if (! tracker)
+			return;
+
+		if (tracker_08)
+			tracker_08 = load_symbols (tracker, tracker_dl_mapping_08, G_N_ELEMENTS (tracker_dl_mapping_08));
+		if (! tracker_08) {
+			if (! load_symbols (tracker, tracker_dl_mapping, G_N_ELEMENTS (tracker_dl_mapping)))
+				return;
+			if (tracker_07)
+				tracker_connect_07 = (gpointer)tracker_connect;
+		}
+	}
+}
+
 
 struct NautilusSearchEngineTrackerDetails {
 	NautilusQuery 	*query;
@@ -62,7 +210,11 @@ finalize (GObject *object)
 		tracker->details->query = NULL;
 	}
 
-	tracker_disconnect (tracker->details->client);
+	if (tracker_08) {
+		g_object_unref (tracker->details->client);
+	} else {
+		tracker_disconnect (tracker->details->client);
+	}
 
 	g_free (tracker->details);
 
@@ -70,12 +222,32 @@ finalize (GObject *object)
 }
 
 
+/* stolen from tracker sources, tracker.c */
 static void
-search_callback (char **results, GError *error, gpointer user_data)
+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 (gpointer results, GError *error, gpointer user_data)
 {
 	NautilusSearchEngineTracker *tracker;
 	char **results_p;
+	GPtrArray *OUT_result;
 	GList *hit_uris;
+	gint i;
+	char *uri;
 	
 	tracker = NAUTILUS_SEARCH_ENGINE_TRACKER (user_data);
 	hit_uris = NULL;
@@ -83,32 +255,42 @@ search_callback (char **results, GError *error, gpointer user_data)
 	tracker->details->query_pending = FALSE;
 
 	if (error) {
-		nautilus_search_engine_error ( NAUTILUS_SEARCH_ENGINE (tracker), error->message);
+		nautilus_search_engine_error (NAUTILUS_SEARCH_ENGINE (tracker), error->message);
 		g_error_free (error);
 		return;
 	}
 
-	if (!results) {
+	if (! results) {
 		return;
 	}
 	
-	for (results_p = results; *results_p; results_p++) {
-		
-		char *uri;
-
-#ifdef HAVE_TRACKER_0_7
-		uri = g_strdup ((char *)*results_p);
-#else
-		uri = g_filename_to_uri ((char *)*results_p, NULL, NULL);
-#endif
-		if (uri) {
-			hit_uris = g_list_prepend (hit_uris, (char *)uri);
+	if (tracker_08) {
+		/* new tracker 0.8 API */
+		OUT_result = (GPtrArray*) results;
+
+		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, (char *)uri);
+			}
+		}
+
+		g_ptr_array_foreach (OUT_result, (GFunc) g_free, NULL);
+		g_ptr_array_free (OUT_result, TRUE);
+
+	} else {
+		/* old tracker 0.6 API */
+		for (results_p = results; *results_p; results_p++) {
+			uri = tracker_07 ? g_strdup ((char *)*results_p) : g_filename_to_uri ((char *)*results_p, NULL, NULL);
+			if (uri) {
+				hit_uris = g_list_prepend (hit_uris, (char *)uri);
+			}
 		}
+		g_strfreev ((gchar **)results);
 	}
 
 	nautilus_search_engine_hits_added (NAUTILUS_SEARCH_ENGINE (tracker), hit_uris);
 	nautilus_search_engine_finished (NAUTILUS_SEARCH_ENGINE (tracker));
-	g_strfreev  (results);
 	eel_g_list_free_deep (hit_uris);
 }
 
@@ -121,9 +303,11 @@ nautilus_search_engine_tracker_start (NautilusSearchEngine *engine)
 	char 	*search_text, *location, *location_uri;
 	char 	**mimes;
 	int 	i, mime_count;
+	GString *sparql;
 
 	tracker = NAUTILUS_SEARCH_ENGINE_TRACKER (engine);
 
+
 	if (tracker->details->query_pending) {
 		return;
 	}
@@ -131,7 +315,7 @@ nautilus_search_engine_tracker_start (NautilusSearchEngine *engine)
 	if (tracker->details->query == NULL) {
 		return;
 	}
-	
+
 	search_text = nautilus_query_get_text (tracker->details->query);
 
 	mimetypes = nautilus_query_get_mime_types (tracker->details->query);
@@ -139,11 +323,7 @@ nautilus_search_engine_tracker_start (NautilusSearchEngine *engine)
 	location_uri = nautilus_query_get_location (tracker->details->query);
 
 	if (location_uri) {
-#ifdef HAVE_TRACKER_0_7
-		location = g_strdup (location_uri);
-#else
-		location = g_filename_from_uri (location_uri, NULL, NULL);
-#endif
+		location = (tracker_07 && !tracker_08) ? g_strdup (location_uri) : g_filename_from_uri (location_uri, NULL, NULL);
 		g_free (location_uri);
 	} else {
 		location = NULL;
@@ -152,52 +332,95 @@ nautilus_search_engine_tracker_start (NautilusSearchEngine *engine)
 	mime_count  = g_list_length (mimetypes);
 
 	i = 0;
+	sparql = NULL;
+
+	if (tracker_08) {
+		/* new tracker 0.8 API */
+		if (mime_count > 0) {
+			sparql = g_string_new ("SELECT nie:url(?file) WHERE { ?file a nfo:FileDataObject ; nie:mimeType ?mime ; fts:match ");
+			sparql_append_string_literal (sparql, search_text);
+
+			g_string_append (sparql, " . FILTER (");
+			if (location) {
+				g_string_append (sparql, "fn:starts-with(?file,");
+				sparql_append_string_literal (sparql, location);
+				g_string_append (sparql, ")");
+				g_string_append (sparql, " && (");
+			}
+
+
+			for (l = mimetypes; l != NULL; l = l->next) {
+				if (l != mimetypes) {
+					g_string_append (sparql, " || ");
+				}
+
+				g_string_append (sparql, "?mime = ");
+				sparql_append_string_literal (sparql, l->data);
+			}
+
+			if (location)
+				g_string_append (sparql, ")");
+			g_string_append (sparql, ") }");
+		} else {
+			sparql = g_string_new ("SELECT nie:url(?file) WHERE { ?file a nfo:FileDataObject ; fts:match ");
+			sparql_append_string_literal (sparql, search_text);
+			if (location) {
+				g_string_append (sparql, " . FILTER (fn:starts-with(?file,");
+				sparql_append_string_literal (sparql, location);
+				g_string_append (sparql, "))");
+			}
+			g_string_append (sparql, " }");
+		}
 
-	/* convert list into array */
-	if (mime_count > 0) {
+		tracker_resources_sparql_query_async (tracker->details->client, sparql->str, (TrackerReplyGPtrArray) search_callback, tracker);
+		g_string_free (sparql, TRUE);
+	} else {
+		/* old tracker 0.6 API */
+		if (mime_count > 0) {
+			/* convert list into array */
+			mimes = g_new (char *, (mime_count + 1));
 
-		mimes = g_new (char *, (mime_count + 1));
-		
-		for (l = mimetypes; l != NULL; l = l->next) {
-			mimes[i] = g_strdup (l->data);
-			i++;
-		}
+			for (l = mimetypes; l != NULL; l = l->next) {
+				mimes[i] = g_strdup (l->data);
+				i++;
+			}
 
-		mimes[mime_count] = NULL;			
+			mimes[mime_count] = NULL;
 
-		if (location) {
-			tracker_search_metadata_by_text_and_mime_and_location_async (tracker->details->client,
-										     search_text, (const char **)mimes, location,
-										     search_callback, 
-										     tracker);
-			g_free (location);
-		} else {
-			tracker_search_metadata_by_text_and_mime_async (tracker->details->client, 
-									search_text, (const char**)mimes, 
-									search_callback,
-									tracker);
-		}
+			if (location) {
+				tracker_search_metadata_by_text_and_mime_and_location_async (tracker->details->client,
+											     search_text, (const char **)mimes, location,
+											     (TrackerArrayReply) search_callback,
+											     tracker);
+			} else {
+				tracker_search_metadata_by_text_and_mime_async (tracker->details->client,
+										search_text, (const char**)mimes,
+										(TrackerArrayReply) search_callback,
+										tracker);
+			}
+
+			g_strfreev (mimes);
 
-		g_strfreev (mimes);
-		
 
-	} else {
-		if (location) {
-			tracker_search_metadata_by_text_and_location_async (tracker->details->client,
-									    search_text, 
-									    location, 
-								 	    search_callback,
-									    tracker);
-			g_free (location);
 		} else {
-			tracker_search_metadata_by_text_async (tracker->details->client, 
-							       search_text, 
-							       search_callback,
-							       tracker);
+			if (location) {
+				tracker_search_metadata_by_text_and_location_async (tracker->details->client,
+										    search_text,
+										    location,
+										    (TrackerArrayReply) search_callback,
+										    tracker);
+			} else {
+				tracker_search_metadata_by_text_async (tracker->details->client,
+								       search_text,
+								       (TrackerArrayReply) search_callback,
+								       tracker);
+			}
+
 		}
-		
 	}
 
+	g_free (location);
+
 	tracker->details->query_pending = TRUE;
 	g_free (search_text);
 	eel_g_list_free_deep (mimetypes);
@@ -209,7 +432,7 @@ nautilus_search_engine_tracker_stop (NautilusSearchEngine *engine)
 	NautilusSearchEngineTracker *tracker;
 
 	tracker = NAUTILUS_SEARCH_ENGINE_TRACKER (engine);
-
+	
 	if (tracker->details->query && tracker->details->query_pending) {
 		tracker_cancel_last_call (tracker->details->client);
 		tracker->details->query_pending = FALSE;
@@ -271,27 +494,36 @@ nautilus_search_engine_tracker_new (void)
 	NautilusSearchEngineTracker *engine;
 	TrackerClient *tracker_client;
 
-#ifdef HAVE_TRACKER_0_7
-	tracker_client = tracker_connect (FALSE, -1);
-#else
-	tracker_client = tracker_connect (FALSE);
-#endif
+	open_libtracker ();
+
+	if (tracker_08) {
+		tracker_client = tracker_client_new (TRACKER_CLIENT_ENABLE_WARNINGS, G_MAXINT);
+	} else {
+		if (! tracker_connect)
+			return NULL;
+
+		if (tracker_07) {
+			tracker_client = tracker_connect_07 (FALSE, -1);
+		} else {
+			tracker_client = tracker_connect (FALSE);
+		}
+	}
 
 	if (!tracker_client) {
 		return NULL;
 	}
 
-#ifndef HAVE_TRACKER_0_7
-	GError *err = NULL;
+	if (! tracker_07 && ! tracker_08) {
+		GError *err = NULL;
 
-	tracker_get_version (tracker_client, &err);
+		tracker_get_version (tracker_client, &err);
 
-	if (err != NULL) {
-		g_error_free (err);
-		tracker_disconnect (tracker_client);
-		return NULL;
+		if (err != NULL) {
+			g_error_free (err);
+			tracker_disconnect (tracker_client);
+			return NULL;
+		}
 	}
-#endif
 
 	engine = g_object_new (NAUTILUS_TYPE_SEARCH_ENGINE_TRACKER, NULL);
 
diff --git a/libnautilus-private/nautilus-search-engine.c b/libnautilus-private/nautilus-search-engine.c
index 2030d95..2dd4bd3 100644
--- a/libnautilus-private/nautilus-search-engine.c
+++ b/libnautilus-private/nautilus-search-engine.c
@@ -126,20 +126,16 @@ nautilus_search_engine_new (void)
 {
 	NautilusSearchEngine *engine;
 	
-#ifdef HAVE_BEAGLE
-	engine = nautilus_search_engine_beagle_new ();
+	engine = nautilus_search_engine_tracker_new ();
 	if (engine) {
 		return engine;
 	}
-#endif
 	
-#ifdef HAVE_TRACKER
-	engine = nautilus_search_engine_tracker_new ();
+	engine = nautilus_search_engine_beagle_new ();
 	if (engine) {
 		return engine;
 	}
-#endif
-
+	
 	engine = nautilus_search_engine_simple_new ();
 	return engine;
 }



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