tracker r1485 - in trunk: . data src/libtracker src/trackerd



Author: ifrade
Date: Mon May 26 10:37:39 2008
New Revision: 1485
URL: http://svn.gnome.org/viewvc/tracker?rev=1485&view=rev

Log:
Patch Mikael Ottela. GetUniqueValues updated

Added:
   trunk/src/libtracker/tracker-unique.c
Modified:
   trunk/ChangeLog
   trunk/data/sqlite-stored-procs.sql
   trunk/data/tracker-introspect.xml
   trunk/src/libtracker/Makefile.am
   trunk/src/libtracker/tracker.c
   trunk/src/libtracker/tracker.h
   trunk/src/trackerd/tracker-db-sqlite.c
   trunk/src/trackerd/tracker-dbus-metadata.c
   trunk/src/trackerd/tracker-dbus-search.c
   trunk/src/trackerd/tracker-dbus.c
   trunk/src/trackerd/tracker-rdf-query.c
   trunk/src/trackerd/tracker-rdf-query.h

Modified: trunk/data/sqlite-stored-procs.sql
==============================================================================
--- trunk/data/sqlite-stored-procs.sql	(original)
+++ trunk/data/sqlite-stored-procs.sql	Mon May 26 10:37:39 2008
@@ -87,6 +87,10 @@
 GetMetadataValues SELECT DISTINCT MetaDataDisplay FROM ServiceMetaData WHERE MetaDataID = ? LIMIT ?,?;
 GetMetadataNumericValues SELECT DISTINCT MetaDataValue FROM ServiceNumericMetaData WHERE MetaDataID = ? LIMIT ?,?;
 
+GetMetadataKeywordValues SELECT DISTINCT MetaDataValue FROM ServiceKeywordMetaData WHERE MetaDataID = ? LIMIT ?,?;
+GetMetadataValues SELECT DISTINCT MetaDataDisplay FROM ServiceMetaData WHERE MetaDataID = ? LIMIT ?,?;
+GetMetadataNumericValues SELECT DISTINCT MetaDataValue FROM ServiceNumericMetaData WHERE MetaDataID = ? LIMIT ?,?;
+
 SetMetadataKeyword INSERT INTO ServiceKeywordMetaData (ServiceID, MetaDataID, MetaDataValue) VALUES (?,?,?);
 SetMetadata INSERT INTO ServiceMetaData (ServiceID, MetaDataID, MetaDataValue, MetaDataDisplay) VALUES (?,?,?,?);
 SetMetadataNumeric INSERT INTO ServiceNumericMetaData (ServiceID, MetaDataID, MetaDataValue) VALUES (?,?,?);

Modified: trunk/data/tracker-introspect.xml
==============================================================================
--- trunk/data/tracker-introspect.xml	(original)
+++ trunk/data/tracker-introspect.xml	Mon May 26 10:37:39 2008
@@ -220,12 +220,18 @@
 			<arg type="as" name="result" direction="out" />
 		</method>
 
-		<!-- returns an array of all unique values of given metadata type -->
+		<!-- returns an array of all unique values of given metadata types. Optionally a rdf query can be
+		     used to filter the results. The results are sorted based on the metadata fields either in
+		     ascending or descending order.
+		-->
 		<method name="GetUniqueValues">
-			<arg type="s" name="meta_type" direction="in" />
+			<arg type="s" name="service" direction="in" />
+			<arg type="as" name="meta_types" direction="in" />
+			<arg type="s" name="query" direction="in" />
+			<arg type="b" name="descending" direction="in" />
 			<arg type="i" name="offset" direction="in" />
 			<arg type="i" name="max_hits" direction="in" />
-			<arg type="as" name="result" direction="out" />
+			<arg type="aas" name="result" direction="out" />
 		</method>
 
 		<!-- signal emitted whenever metadata for a service entity is changed. The keys are the metadata names that have changed -->

Modified: trunk/src/libtracker/Makefile.am
==============================================================================
--- trunk/src/libtracker/Makefile.am	(original)
+++ trunk/src/libtracker/Makefile.am	Mon May 26 10:37:39 2008
@@ -20,7 +20,7 @@
 
 include_HEADERS = tracker.h tracker-client.h		
 
-bin_PROGRAMS = tracker-search tracker-query tracker-meta-folder tracker-stats tracker-tag tracker-files tracker-status
+bin_PROGRAMS = tracker-search tracker-query tracker-meta-folder tracker-stats tracker-tag tracker-files tracker-status tracker-unique
 
 tracker_search_SOURCES = tracker-search.c
 
@@ -72,4 +72,11 @@
 		 	$(GOBJECT_LIBS)	\
 			libtrackerclient.la
  
+tracker_unique_SOURCES = tracker-unique.c
+
+tracker_unique_LDADD = 	$(GLIB2_LIBS) 	\
+		 	$(DBUS_LIBS)	\
+		 	$(GOBJECT_LIBS)	\
+			libtrackerclient.la
+
 CLEANFILES = $(BUILT_SOURCES)

Added: trunk/src/libtracker/tracker-unique.c
==============================================================================
--- (empty file)
+++ trunk/src/libtracker/tracker-unique.c	Mon May 26 10:37:39 2008
@@ -0,0 +1,187 @@
+/* Tracker - indexer and metadata database engine
+ * Copyright (C) 2006, Mr Jamie McCracken (jamiemcc gnome org)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA  02110-1301, USA.
+ */
+
+#include <locale.h>
+#include <sys/param.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <glib/gstdio.h>
+
+#include "../libtracker/tracker.h" 
+
+#include <config.h>
+#ifdef OS_WIN32
+#include "../trackerd/mingw-compat.h"
+#endif
+
+static char **fields = NULL;
+static gchar *service = NULL;
+static gchar *rdf = NULL;
+static gboolean descending = FALSE;
+
+static GOptionEntry entries[] = {
+	{"service", 's', 0, G_OPTION_ARG_STRING, &service, "search from a specific service", "service"},
+	{"rdf", 'r', 0, G_OPTION_ARG_STRING, &rdf, "use an rdf query as filter", "rdf"},	
+	{"desc", 'o', 0, G_OPTION_ARG_NONE, &descending, "sort to descending order", NULL},
+	{G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &fields, "Required fields", NULL},
+	{NULL}
+};
+
+
+static char *
+realpath_in_utf8 (const char *path)
+{
+	char *str_path_tmp = NULL, *str_path = NULL;
+
+	str_path_tmp = realpath (path, NULL);
+
+	if (str_path_tmp) {
+		str_path = g_filename_to_utf8 (str_path_tmp, -1, NULL, NULL, NULL);
+
+		g_free (str_path_tmp);
+	}
+
+	if (!str_path) {
+		g_warning ("realpath_in_utf8(): locale to UTF8 failed!");
+		return NULL;
+	}
+
+	return str_path;
+}
+
+static void
+get_meta_table_data (gpointer value)
+		    
+{
+	char **meta, **meta_p;
+
+	meta = (char **)value;
+
+	int i = 0;
+	for (meta_p = meta; *meta_p; meta_p++) {
+
+		char *str;
+
+		str = g_filename_from_utf8 (*meta_p, -1, NULL, NULL, NULL);
+
+		if (i == 0) {
+			g_print ("%s : ", str);
+
+		} else {
+			g_print ("%s, ", *meta_p);
+		}
+		i++;
+	}
+	g_print ("\n");
+}
+
+
+
+int
+main (int argc, char **argv) 
+{
+	GOptionContext *context = NULL;
+	ServiceType type;
+
+	char *buffer = NULL, *tmp;
+	gsize buffer_length;
+	GPtrArray *out_array = NULL;
+	GError *error = NULL;
+	TrackerClient *client = NULL;
+
+	setlocale (LC_ALL, "");
+
+	context = g_option_context_new ("MetaDataField [RDFQueryFile] - Get unique values with an optional rdf query filter");
+	g_option_context_add_main_entries (context, entries, NULL);
+	g_option_context_parse (context, &argc, &argv, &error);
+
+	if (error) {
+		g_printerr ("invalid arguments: %s\n", error->message);
+		return 1;
+	}
+
+	if (!fields) {
+		g_printerr ("missing metadata type specification, try --help for help\n");
+		return 1;
+	}
+	
+
+	if (!service) {
+		type = SERVICE_FILES;
+	} else {
+		type = tracker_service_name_to_type (service);
+
+		if (type == SERVICE_OTHER_FILES && g_ascii_strcasecmp (service, "Other")) {
+			g_printerr ("service not recognized, searching in Other Files...\n");
+		}
+	}
+
+	if (rdf) {
+
+	  char *str_path = realpath_in_utf8 (rdf);
+	  
+	  if (!str_path) {
+	    return 1;
+	  }
+	  
+	  if (!g_file_get_contents (str_path, &tmp, &buffer_length, NULL)) {
+	    g_print ("Could not read file %s\n", str_path);
+	    return 1;
+	  }
+	  
+	  g_free (str_path);
+	  
+	  buffer = g_locale_to_utf8 (tmp, buffer_length, NULL, NULL, NULL);
+	  
+	  if (!buffer) {
+	    g_warning ("Cannot convert query file to UTF8!");
+	    g_free (tmp);
+	    return 1;
+	  }
+	}
+
+	client =  tracker_connect (FALSE);
+
+	if (!client) {
+		g_print ("Could not initialise Tracker over dbus connection - exiting...\n");
+		return 1; 
+	}
+
+
+	out_array = tracker_metadata_get_unique_values (client, type, fields, buffer, descending, 0, 512, &error);
+
+	if (error) {
+		g_warning ("An error has occurred : %s\n", error->message);
+		g_error_free (error);
+		g_free (buffer);
+		return 1;
+	}
+
+	if (out_array) {
+		g_ptr_array_foreach (out_array, (GFunc)get_meta_table_data, NULL);
+		g_ptr_array_free (out_array, TRUE);
+	}
+
+	tracker_disconnect (client);	
+
+	g_free (buffer);
+
+	return 0;
+}

Modified: trunk/src/libtracker/tracker.c
==============================================================================
--- trunk/src/libtracker/tracker.c	(original)
+++ trunk/src/libtracker/tracker.c	Mon May 26 10:37:39 2008
@@ -510,17 +510,17 @@
 }
 
 
-
-char **		
-tracker_metadata_get_unique_values (TrackerClient *client, const char *meta_type, int offset, int max_hits, GError **error)
+GPtrArray *	
+tracker_metadata_get_unique_values (TrackerClient *client, ServiceType service, char **meta_types, char *query, gboolean descending, int offset, int max_hits, GError **error)
 {
-	char **array = NULL;
-
-	if (!org_freedesktop_Tracker_Metadata_get_unique_values (client->proxy_metadata, meta_type, offset, max_hits, &array, &*error)) {
-		return NULL;
-	}
-
-	return array;
+        GPtrArray *table;
+ 	char *service_str = tracker_service_types[service];
+  
+ 	if (!org_freedesktop_Tracker_Metadata_get_unique_values (client->proxy_metadata, service_str, (const char **)meta_types, query, descending, offset, max_hits, &table, &*error)) {
+ 		return NULL;
+ 	}
+  
+ 	return table;
 }
 
 
@@ -1108,18 +1108,18 @@
 }
 
 
-
 void
-tracker_metadata_get_unique_values_async (TrackerClient *client, const char *meta_type, int offset, int max_hits, TrackerArrayReply callback, gpointer user_data)
+tracker_metadata_get_unique_values_async (TrackerClient *client, ServiceType service, char **meta_types, const char *query, gboolean descending, int offset, int max_hits, TrackerGPtrArrayReply callback, gpointer user_data)
 {
 	
-        ArrayCallBackStruct *callback_struct;
+        GPtrArrayCallBackStruct *callback_struct;
+	char *service_str = tracker_service_types[service];
 
-        callback_struct = g_new (ArrayCallBackStruct, 1);
+        callback_struct = g_new (GPtrArrayCallBackStruct, 1);
         callback_struct->callback = callback;
         callback_struct->data = user_data;
 
-        org_freedesktop_Tracker_Metadata_get_unique_values_async (client->proxy_search, meta_type, offset, max_hits, tracker_array_reply, callback_struct);
+        org_freedesktop_Tracker_Metadata_get_unique_values_async (client->proxy_metadata, service_str, (const char **) meta_types, query, descending, offset, max_hits, tracker_GPtrArray_reply, callback_struct);
 	
 }
 
@@ -1559,6 +1559,3 @@
 	client->last_pending_call = org_freedesktop_Tracker_Files_search_by_text_and_location_async (client->proxy_files, query, location,  tracker_array_reply, callback_struct);
 	
 }
-
-
-

Modified: trunk/src/libtracker/tracker.h
==============================================================================
--- trunk/src/libtracker/tracker.h	(original)
+++ trunk/src/libtracker/tracker.h	Mon May 26 10:37:39 2008
@@ -125,7 +125,7 @@
 char **			tracker_metadata_get_registered_types		(TrackerClient *client, const char *classname, GError **error);
 char **			tracker_metadata_get_writeable_types		(TrackerClient *client, const char *classname, GError **error);
 char **			tracker_metadata_get_registered_classes		(TrackerClient *client, GError **error);
-char **		        tracker_metadata_get_unique_values              (TrackerClient *client, const char *meta_type, int offset, int max_hits, GError **error);
+GPtrArray *	        tracker_metadata_get_unique_values              (TrackerClient *client, ServiceType service, char **meta_types, char *query, gboolean descending, int offset, int max_hits, GError **error);
 
 GPtrArray *	tracker_keywords_get_list			(TrackerClient *client, ServiceType service, GError **error);
 char **		tracker_keywords_get				(TrackerClient *client, ServiceType service, const char *id, GError **error);
@@ -184,7 +184,7 @@
 void		tracker_metadata_get_registered_types_async 		(TrackerClient *client, const char *classname, TrackerArrayReply callback, gpointer user_data);
 void		tracker_metadata_get_writeable_types_async 		(TrackerClient *client, const char *classname, TrackerArrayReply callback, gpointer user_data);
 void		tracker_metadata_get_registered_classes_async 		(TrackerClient *client, TrackerArrayReply callback, gpointer user_data);
-void		tracker_metadata_get_unique_values_async                (TrackerClient *client, const char *meta_type, int offset, int max_hits, TrackerArrayReply callback, gpointer user_data);
+void		tracker_metadata_get_unique_values_async                (TrackerClient *client, ServiceType service, char **meta_types, const char *query, gboolean descending, int offset, int max_hits, TrackerGPtrArrayReply callback, gpointer user_data);
 
 void		tracker_keywords_get_list_async 			(TrackerClient *client, ServiceType service, TrackerGPtrArrayReply callback, gpointer user_data);
 void		tracker_keywords_get_async 				(TrackerClient *client, ServiceType service, const char *id, TrackerArrayReply callback, gpointer user_data);

Modified: trunk/src/trackerd/tracker-db-sqlite.c
==============================================================================
--- trunk/src/trackerd/tracker-db-sqlite.c	(original)
+++ trunk/src/trackerd/tracker-db-sqlite.c	Mon May 26 10:37:39 2008
@@ -21,6 +21,8 @@
 #define _GNU_SOURCE
 #endif
 
+#include "tracker-rdf-query.h"
+
 #include "config.h"
 
 #include <stdarg.h>
@@ -5186,8 +5188,8 @@
 			g_free (disp_field);
 			field_data->needs_join = TRUE;
 		}
-			
-		if (def->type == DATA_DOUBLE) {
+		g_print ("Type for %d is %d", field_count, def->type);
+		if (def->type == DATA_DOUBLE || def->type == DATA_STRING || def->type == DATA_INDEX) {
 			field_data->where_field = g_strdup_printf ("M%d.MetaDataDisplay", field_count);
 		} else {
 			field_data->where_field = g_strdup_printf ("M%d.MetaDataValue", field_count);

Modified: trunk/src/trackerd/tracker-dbus-metadata.c
==============================================================================
--- trunk/src/trackerd/tracker-dbus-metadata.c	(original)
+++ trunk/src/trackerd/tracker-dbus-metadata.c	Mon May 26 10:37:39 2008
@@ -121,6 +121,7 @@
 	dbus_message_unref (reply);
 }
 
+#include "tracker-rdf-query.h"
 
 
 void
@@ -573,21 +574,37 @@
 void
 tracker_dbus_method_metadata_get_unique_values (DBusRec *rec)
 {
-	DBConnection       *db_con;
-	DBusError          dbus_error;
-	DBusMessage        *reply;
-	gchar 	           *meta_type;
-	gchar 	           **array;
-	gint 	           limit, offset;
-	int	           row_count;
+	DBConnection *db_con;
+	DBusError    dbus_error;
+	gchar 	     **meta_types = NULL;
+	gchar        *service;
+	gchar        *query = NULL;
+	gint         meta_count;
+	gboolean     order_desc;
+	gint 	     limit, offset;
+
+	FieldDef     *def;
 	TrackerDBResultSet *result_set;
+	GString      *select;
+	GString      *from;
+	GString      *where;
+	GString      *group;
+	GString      *order;
+	char	     *str_offset, *str_limit;
+	gchar        *sql;
+
+	int          i;
+
 /*
 		<!-- returns an array of all unique values of given metadata type -->
 		<method name="GetUniqueValues">
-			<arg type="s" name="meta_type" direction="in" />
+		        <arg type="s" name="service" direction="in" />
+			<arg type="as" name="meta_types" direction="in" />
+			<arg type="s" name="query" direction="in" />
+		        <arg type="b" name="descending" direction="in" />
 			<arg type="i" name="offset" direction="in" />
 			<arg type="i" name="max_hits" direction="in" />
-			<arg type="as" name="result" direction="out" />
+			<arg type="aas" name="result" direction="out" />
 		</method>
 */
 
@@ -595,9 +612,14 @@
 
 	db_con = rec->user_data;
 
+	result_set = NULL;
+
         dbus_error_init (&dbus_error);
         if (!dbus_message_get_args (rec->message, NULL,
-                               DBUS_TYPE_STRING, &meta_type,
+			       DBUS_TYPE_STRING, &service,
+                               DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &meta_types, &meta_count,
+			       DBUS_TYPE_STRING, &query,
+			       DBUS_TYPE_BOOLEAN, &order_desc,
                                DBUS_TYPE_INT32, &offset,
                                DBUS_TYPE_INT32, &limit,
                                DBUS_TYPE_INVALID)) {
@@ -606,24 +628,139 @@
 	        return;
         }
 
-	result_set = tracker_db_get_unique_metadata_values (db_con, meta_type, offset, limit);
+	if (!tracker_service_manager_is_valid_service (service)) {
+		tracker_set_error (rec, "Invalid service %s or service has not been implemented yet", service);
+		return;
+	}
+
+	db_con = tracker_db_get_service_connection (db_con, service);
+
+	if (limit < 1) {
+		limit = 1024;
+	}
+
+	if(!meta_count) {
+		tracker_set_error (rec, "ERROR: No metadata type specified");
+		return;
+	}
+
+	str_offset = tracker_int_to_str (offset);
+	str_limit = tracker_int_to_str (limit);
+
+	select = g_string_new ("SELECT ");
+	from   = g_string_new ("\nFROM Services S ");
+	where  = g_string_new ("\nWHERE ");
+	order  = g_string_new ("\nORDER BY ");
+	group  = g_string_new ("\nGROUP BY ");
+
+	for (i=0;i<meta_count;i++) {
+		def = tracker_db_get_field_def (db_con, meta_types[i]);
 
-        array = NULL;
-        row_count = 0;
+		if (!def) {
+			tracker_set_error (rec, "ERROR: metadata not found for type %s", meta_types[i]);
+			return;
+		}
+	  
+		if (i) {
+			g_string_append_printf (where, " AND ");
+			g_string_append_printf (select, ", ");
+			g_string_append_printf (group, ", ");
+			g_string_append_printf (order, ", ");
+		}
+		
+		switch (def->type) {
+		  
+		case DATA_INDEX:
+		case DATA_STRING:
+		case DATA_DOUBLE:
+			g_string_append_printf (select, "D%d.MetaDataDisplay", i);
+			g_string_append_printf (from, "INNER JOIN ServiceMetaData D%d ON (S.ID = D%d.ServiceID) ", i,i);
+			g_string_append_printf (where, "(D%d.MetaDataID = %s)", i, def->id);
+			g_string_append_printf (group, "D%d.MetaDataDisplay", i);
+			if (order_desc) {
+				g_string_append_printf (order, "D%d.MetaDataDisplay DESC", i);
+			} else {
+				g_string_append_printf (order, "D%d.MetaDataDisplay ASC", i);
+			}
+			break;
+			
+		case DATA_INTEGER:
+		case DATA_DATE:
+			g_string_append_printf (select, "D%d.MetaDataValue", i);
+			g_string_append_printf (from, "INNER JOIN ServiceNumericMetaData D%d ON (S.ID = D%d.ServiceID) ", i, i);
+			g_string_append_printf (where, "(D%d.MetaDataID = %s)", i, def->id);
+			g_string_append_printf (group, "D%d.MetaDataValue", i);
+			if (order_desc) {
+				g_string_append_printf (order, "D%d.MetaDataValue DESC", i);
+			} else {
+				g_string_append_printf (order, "D%d.MetaDataValue ASC", i);
+			}
+			break;
+			
+		case DATA_KEYWORD:
+			g_string_append_printf (select, "D%d.MetaDataValue", i);
+			g_string_append_printf (from, "INNER JOIN ServiceKeywordMetaData D%d ON (S.ID = D%d.ServiceID) ", i, i);
+			g_string_append_printf (where, "(D%d.MetaDataID = %s)", i,def->id);
+			g_string_append_printf (group, "D%d.MetaDataValue", i);
+			if (order_desc) {
+				g_string_append_printf (order, "D%d.MetaDataValue DESC", i);
+			} else {
+				g_string_append_printf (order, "D%d.MetaDataValue ASC", i);
+			}
+			break;
+	    
+		default: 
+		        tracker_error ("ERROR: metadata could not be retrieved as type %d is not supported", def->type);
+			g_string_free (select, TRUE);
+			g_string_free (from, TRUE);
+			g_string_free (where, TRUE);
+			g_string_free (group, TRUE);
+			g_string_free (order, TRUE);
+		}
+	}
+	
+	g_string_append_printf (select, ", COUNT (*) ");
+	
+	if (query) {
+		char *rdf_where;
+		char *rdf_from;
+		GError *error = NULL;
+		
+		tracker_rdf_filter_to_sql (db_con, query, service, &rdf_from, &rdf_where, error);
+		
+		if (error) {
+			tracker_set_error (rec, "ERROR: Parse error: %s", error->message);
+			g_error_free (error);
+			return;
+		}
+		
+		g_string_append_printf (from, " %s ", rdf_from);
+		g_string_append_printf (where, " AND %s", rdf_where);
 
-        if (result_set) {
-                array = tracker_get_query_result_as_array (result_set, &row_count);
-                g_object_unref (result_set);
+		g_free (rdf_from);
+		g_free (rdf_where);
 	}
 
-        reply = dbus_message_new_method_return (rec->message);
+	g_string_append_printf (order, " LIMIT %s,%s", str_offset, str_limit);
+	sql = g_strconcat (select->str, " ", from->str, " ", where->str, " ", group->str, " ", order->str, NULL);
 
-        dbus_message_append_args (reply,
-                                  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &array, row_count,
-                                  DBUS_TYPE_INVALID);
+	g_string_free (select, TRUE);
+	g_string_free (from, TRUE);
+	g_string_free (where, TRUE);
+	g_string_free (group, TRUE);
+	g_string_free (order, TRUE);
+	g_free (str_offset);
+	g_free (str_limit);
 
-        tracker_free_array (array, row_count);
+	g_message ("Unique value query executed:\n%s", sql);
 
-        dbus_connection_send (rec->connection, reply, NULL);
-        dbus_message_unref (reply);
+	result_set =  tracker_db_interface_execute_query (db_con->db, NULL, sql);
+
+	g_free (sql);
+
+	tracker_dbus_reply_with_query_result (rec, result_set);
+
+	if (result_set) {
+	        g_object_unref (result_set);
+	}
 }

Modified: trunk/src/trackerd/tracker-dbus-search.c
==============================================================================
--- trunk/src/trackerd/tracker-dbus-search.c	(original)
+++ trunk/src/trackerd/tracker-dbus-search.c	Mon May 26 10:37:39 2008
@@ -863,7 +863,9 @@
 
 	tracker_dbus_reply_with_query_result (rec, result_set);
 
-	g_object_unref (result_set);
+	if (result_set) {
+	        g_object_unref (result_set);
+	}
 }
 
 

Modified: trunk/src/trackerd/tracker-dbus.c
==============================================================================
--- trunk/src/trackerd/tracker-dbus.c	(original)
+++ trunk/src/trackerd/tracker-dbus.c	Mon May 26 10:37:39 2008
@@ -452,6 +452,13 @@
 
 
 
+	} else if (dbus_message_is_method_call (message, TRACKER_INTERFACE_METADATA, TRACKER_METHOD_METADATA_GET_UNIQUE_VALUES)) {
+
+		dbus_message_ref (message);
+		rec->action = DBUS_ACTION_METADATA_GET_UNIQUE_VALUES;
+
+
+
 	} else if (dbus_message_is_method_call (message, TRACKER_INTERFACE_KEYWORDS, TRACKER_METHOD_KEYWORDS_GET_LIST)) {
 
 		dbus_message_ref (message);

Modified: trunk/src/trackerd/tracker-rdf-query.c
==============================================================================
--- trunk/src/trackerd/tracker-rdf-query.c	(original)
+++ trunk/src/trackerd/tracker-rdf-query.c	Mon May 26 10:37:39 2008
@@ -724,7 +724,7 @@
 			if (sub) {
 				g_string_append_printf (str, " (%s glob '%s') ", field_data->where_field, data->current_value);
 			} else {
-				if (field_data->data_type == DATA_DATE || field_data->data_type == DATA_INTEGER || field_data->data_type == DATA_DOUBLE) {
+				if (field_data->data_type == DATA_DATE || field_data->data_type == DATA_INTEGER || field_data->data_type == DATA_DOUBLE || field_data->data_type == DATA_STRING || field_data->data_type == DATA_INDEX) {
 					g_string_append_printf (str, " (%s = %s) ", field_data->where_field, value);
 				} else {
 					g_string_append_printf (str, " (%s = '%s') ", field_data->where_field, value);
@@ -1210,4 +1210,98 @@
 	return result;
 }
 
+/* 
+ * The following function turns an rdf query into a filter that can be used for example
+ * for getting unique values of a field with a certain query.
+ * FIXME It is not pretty. The calling function needs to define Services S that is joined in this method.
+ */
 
+void
+tracker_rdf_filter_to_sql (DBConnection *db_con, const char *query, const char *service, char **from, char **where, GError *error)
+{
+	static     gboolean inited = FALSE;
+	ParserData data;
+
+	if (!inited) {
+		error_quark = g_quark_from_static_string ("RDF-parser-error-quark");
+		inited = TRUE;
+	}
+
+	memset (&data, 0, sizeof (data));
+	data.db_con = db_con;
+	data.statement_count = 0;
+	data.service = (char *) service;
+
+	data.sql_from = g_string_new ("");
+	data.sql_where = g_string_new ("");
+
+	if (strlen (query) < 10) {
+		g_string_append_printf (data.sql_where, " (S.ServiceTypeID in (select TypeId from ServiceTypes where TypeName = '%s' or Parent = '%s')) ", service, service);
+	} else {
+		g_string_append_printf (data.sql_where, " (S.ServiceTypeID in (select TypeId from ServiceTypes where TypeName = '%s' or Parent = '%s')) AND ", service, service);
+	}
+
+	data.parser = g_new0 (GMarkupParser, 1);
+	data.parser->start_element = start_element_handler;
+	data.parser->text = text_handler;
+	data.parser->end_element = end_element_handler;
+	data.parser->error = error_handler;
+
+	data.current_operator = OP_NONE;
+	data.current_logic_operator = LOP_NONE;
+	data.query_okay = FALSE;
+
+	data.context = g_markup_parse_context_new (data.parser, 0, &data, NULL);
+
+	push_stack (&data, STATE_START);
+
+	if (!g_markup_parse_context_parse (data.context, query, -1, &error)) {
+
+                *from = NULL;
+		*where = NULL;
+
+		g_string_free (data.sql_from, TRUE);
+		g_string_free (data.sql_where, TRUE);
+
+	} else {
+		const GSList *tmp;
+		FieldData    *tmp_field;
+
+		for (tmp = data.fields; tmp; tmp = tmp->next) {
+			tmp_field = tmp->data;
+
+			if (!tmp_field->is_condition) {
+				if (tmp_field->needs_join) {
+					g_string_append_printf (data.sql_from, "\n LEFT OUTER JOIN %s %s ON (S.ID = %s.ServiceID and %s.MetaDataID = %s) ", tmp_field->table_name, tmp_field->alias, tmp_field->alias, tmp_field->alias, tmp_field->id_field);
+				}
+			} else {
+				char *related_metadata = tracker_get_related_metadata_names (db_con, tmp_field->field_name);
+				g_string_append_printf (data.sql_from, "\n INNER JOIN %s %s ON (S.ID = %s.ServiceID and %s.MetaDataID in (%s)) ", tmp_field->table_name, tmp_field->alias, tmp_field->alias, tmp_field->alias, related_metadata);
+				g_free (related_metadata);
+			}
+		}
+		
+		*from  = g_strdup (data.sql_from->str);
+		*where = g_strdup (data.sql_where->str);
+		g_string_free (data.sql_from, TRUE);
+		g_string_free (data.sql_where, TRUE);
+		
+
+	}
+
+	g_slist_foreach (data.fields, (GFunc) tracker_free_metadata_field, NULL);
+	g_slist_free (data.fields);
+
+	g_slist_free (data.stack);
+	g_markup_parse_context_free (data.context);
+
+	if (data.current_field) {
+		g_free (data.current_field);
+	}
+
+	if (data.current_value) {
+		g_free (data.current_value);
+	}
+
+	g_free (data.parser);
+}

Modified: trunk/src/trackerd/tracker-rdf-query.h
==============================================================================
--- trunk/src/trackerd/tracker-rdf-query.h	(original)
+++ trunk/src/trackerd/tracker-rdf-query.h	Mon May 26 10:37:39 2008
@@ -29,4 +29,5 @@
 
 char *	tracker_rdf_query_to_sql (DBConnection *db_con, const char *query, const char *service, char **fields, int field_count, const char *search_text, const char *keyword, gboolean sort_by_service, int offset, int limit, GError *error);
 
+void tracker_rdf_filter_to_sql (DBConnection *db_con, const char *query, const char *service, char **from, char **where, GError *error);
 #endif



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