tracker r2042 - in branches/indexer-split: data/dbus src/libtracker src/trackerd



Author: ifrade
Date: Mon Aug 11 14:35:46 2008
New Revision: 2042
URL: http://svn.gnome.org/viewvc/tracker?rev=2042&view=rev

Log:
New methods GetSum, GetCount, GetUniqueValues. Patch by Mikael Ottela

Modified:
   branches/indexer-split/data/dbus/tracker-metadata.xml
   branches/indexer-split/src/libtracker/Makefile.am
   branches/indexer-split/src/libtracker/tracker.c
   branches/indexer-split/src/libtracker/tracker.h
   branches/indexer-split/src/trackerd/tracker-metadata.c
   branches/indexer-split/src/trackerd/tracker-metadata.h
   branches/indexer-split/src/trackerd/tracker-rdf-query.c
   branches/indexer-split/src/trackerd/tracker-rdf-query.h

Modified: branches/indexer-split/data/dbus/tracker-metadata.xml
==============================================================================
--- branches/indexer-split/data/dbus/tracker-metadata.xml	(original)
+++ branches/indexer-split/data/dbus/tracker-metadata.xml	Mon Aug 11 14:35:46 2008
@@ -52,5 +52,37 @@
       <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
       <arg type="as" name="result" direction="out" />
     </method>
+
+    <!-- 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">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <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="aas" name="result" direction="out" />
+    </method>
+
+    <method name="GetSum">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="s" name="service" direction="in" />
+      <arg type="s" name="field" direction="in" />
+      <arg type="s" name="query" direction="in" />
+      <arg type="i" name="result" direction="out" />
+    </method>
+
+    <method name="GetCount">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/>
+      <arg type="s" name="service" direction="in" />
+      <arg type="s" name="field" direction="in" />
+      <arg type="s" name="query" direction="in" />
+      <arg type="i" name="result" direction="out" />
+    </method>
+
   </interface>
 </node>

Modified: branches/indexer-split/src/libtracker/Makefile.am
==============================================================================
--- branches/indexer-split/src/libtracker/Makefile.am	(original)
+++ branches/indexer-split/src/libtracker/Makefile.am	Mon Aug 11 14:35:46 2008
@@ -29,7 +29,8 @@
 	tracker-stats				\
 	tracker-tag				\
 	tracker-files				\
-	tracker-status
+	tracker-status				\
+	tracker-unique
 
 tracker_search_SOURCES = tracker-search.c
 tracker_search_LDADD = $(libs) libtrackerclient.la
@@ -52,6 +53,9 @@
 tracker_status_SOURCES = tracker-status.c
 tracker_status_LDADD = $(libs) libtrackerclient.la
 
+tracker_unique_SOURCES = tracker-unique.c
+tracker_unique_LDADD = $(libs) libtrackerclient.la
+
 # Generate DBus files from XML data.
 dbus_sources = 					\
 	tracker-daemon-glue.h		\

Modified: branches/indexer-split/src/libtracker/tracker.c
==============================================================================
--- branches/indexer-split/src/libtracker/tracker.c	(original)
+++ branches/indexer-split/src/libtracker/tracker.c	Mon Aug 11 14:35:46 2008
@@ -512,8 +512,47 @@
 }
 
 
+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 *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;
+}
+
+int
+tracker_metadata_get_sum (TrackerClient *client, ServiceType service, char *field, char *query, GError **error)
+{
+        int sum;
+
+	char *service_str = tracker_service_types[service];
+  
+ 	if (!org_freedesktop_Tracker_Metadata_get_sum (client->proxy_metadata, service_str, field, query, &sum, &*error)) {
+ 		return -1;
+ 	}
+  
+ 	return sum;
+}
+
+int
+tracker_metadata_get_count (TrackerClient *client, ServiceType service, char *field, char *query, GError **error)
+{
+        int count;
 
+	char *service_str = tracker_service_types[service];
+  
+ 	if (!org_freedesktop_Tracker_Metadata_get_count (client->proxy_metadata, service_str, field, query, &count, &*error)) {
+ 		return -1;
+ 	}
+  
+ 	return count;
 
+}
 
 
 GPtrArray *	
@@ -1093,8 +1132,47 @@
 }
 
 
+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)
+{
+	
+        GPtrArrayCallBackStruct *callback_struct;
+	char *service_str = tracker_service_types[service];
 
+        callback_struct = g_new (GPtrArrayCallBackStruct, 1);
+        callback_struct->callback = callback;
+        callback_struct->data = user_data;
+	
+        client->last_pending_call = 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);
+	
+}
 
+void
+tracker_metadata_get_sum_async (TrackerClient *client, ServiceType service, char *field, char *query, TrackerIntReply callback, gpointer user_data)
+{
+	IntCallBackStruct *callback_struct;
+	char *service_str = tracker_service_types[service];
+
+	callback_struct = g_new (IntCallBackStruct, 1);
+	callback_struct->callback = callback;
+	callback_struct->data = user_data;
+
+	client->last_pending_call = org_freedesktop_Tracker_Metadata_get_sum_async (client->proxy_metadata, service_str, field, query, tracker_int_reply, callback_struct);
+}
+
+
+void
+tracker_metadata_get_count_async (TrackerClient *client, ServiceType service, char *field, char *query, TrackerIntReply callback, gpointer user_data)
+{
+	IntCallBackStruct *callback_struct;
+	char *service_str = tracker_service_types[service];
+
+	callback_struct = g_new (IntCallBackStruct, 1);
+	callback_struct->callback = callback;
+	callback_struct->data = user_data;
+
+	client->last_pending_call = org_freedesktop_Tracker_Metadata_get_count_async (client->proxy_metadata, service_str, field, query, tracker_int_reply, callback_struct);
+}
 
 
 void

Modified: branches/indexer-split/src/libtracker/tracker.h
==============================================================================
--- branches/indexer-split/src/libtracker/tracker.h	(original)
+++ branches/indexer-split/src/libtracker/tracker.h	Mon Aug 11 14:35:46 2008
@@ -127,7 +127,9 @@
 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);
-
+GPtrArray *	        tracker_metadata_get_unique_values              (TrackerClient *client, ServiceType service, char **meta_types, char *query, gboolean descending, int offset, int max_hits, GError **error);
+int	        tracker_metadata_get_sum                        (TrackerClient *client, ServiceType service, char *field, char *query, GError **error);
+int	        tracker_metadata_get_count                      (TrackerClient *client, ServiceType service, char *field, char *query, 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);
@@ -186,7 +188,9 @@
 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, ServiceType service, char **meta_types, const char *query, gboolean descending, int offset, int max_hits, TrackerGPtrArrayReply callback, gpointer user_data);
+void	        tracker_metadata_get_sum_async                          (TrackerClient *client, ServiceType service, char *field, char *query, TrackerIntReply callback, gpointer user_data);
+void	        tracker_metadata_get_count_async                        (TrackerClient *client, ServiceType service, char *field, char *query, TrackerIntReply 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: branches/indexer-split/src/trackerd/tracker-metadata.c
==============================================================================
--- branches/indexer-split/src/trackerd/tracker-metadata.c	(original)
+++ branches/indexer-split/src/trackerd/tracker-metadata.c	Mon Aug 11 14:35:46 2008
@@ -39,6 +39,8 @@
 #include "tracker-db.h"
 #include "tracker-marshal.h"
 
+#include "tracker-rdf-query.h"
+
 G_DEFINE_TYPE(TrackerMetadata, tracker_metadata, G_TYPE_OBJECT)
 
 static void
@@ -60,6 +62,58 @@
 /*
  * Functions
  */
+
+static TrackerFieldData *
+tracker_metadata_add_metadata_field (TrackerDBInterface *iface,
+		    const gchar        *service,
+		    GSList            **fields, 
+                    const gchar        *field_name, 
+                    gboolean            is_select, 
+                    gboolean            is_condition)
+{
+	TrackerFieldData *field_data;
+	gboolean          field_exists;
+	GSList           *l;
+
+	field_exists = FALSE;
+	field_data = NULL;
+
+	/* Check if field is already in list */
+	for (l = *fields; l; l = l->next) {
+                const gchar *this_field_name;
+
+                this_field_name = tracker_field_data_get_field_name (l->data);
+                if (!this_field_name) {
+                        continue;
+                }
+
+                if (strcasecmp (this_field_name, field_name) == 0) {
+                        field_data = l->data;
+                        field_exists = TRUE;
+
+                        if (is_condition) {
+                                tracker_field_data_set_is_condition (field_data, TRUE);
+                        }
+
+                        break;
+		}
+	}
+	
+	if (!field_exists) {
+		field_data = tracker_db_get_metadata_field (iface, 
+                                                            service, 
+                                                            field_name, 
+                                                            g_slist_length (*fields), 
+                                                            is_select, 
+                                                            is_condition);
+		if (field_data) {
+			*fields = g_slist_prepend (*fields, field_data);
+                } 
+	} 
+	
+	return field_data;
+}
+
 void
 tracker_metadata_get (TrackerMetadata        *object,
 		      const gchar            *service_type,
@@ -394,3 +448,416 @@
 
 	tracker_dbus_request_success (request_id);
 }
+
+void
+tracker_metadata_get_unique_values (TrackerMetadata        *object,
+				    const gchar            *service_type,
+				    gchar                 **fields,
+				    const gchar            *query_condition,
+				    gboolean                order_desc,
+				    gint                    offset,
+				    gint                    max_hits,
+				    DBusGMethodInvocation  *context,
+				    GError                **error)
+{
+	TrackerDBInterface *iface;
+	TrackerDBResultSet *result_set = NULL;
+	guint               request_id;
+
+	GPtrArray          *values = NULL;
+	GSList             *field_list = NULL;
+
+	GString            *sql_select;
+	GString            *sql_from;
+	GString            *sql_where;
+	GString            *sql_order;
+	gchar              *sql;
+
+	char               *rdf_where;
+	char               *rdf_from;
+	GError             *actual_error = NULL;
+
+	guint         i;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (service_type != NULL, context);
+	tracker_dbus_async_return_if_fail (fields != NULL, context);
+	tracker_dbus_async_return_if_fail (query_condition != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to get unique values, "
+				  "service type:'%s', query '%s'",
+                                  service_type,
+                                  query_condition);
+
+	if (!tracker_ontology_is_valid_service_type (service_type)) {
+		tracker_dbus_request_failed (request_id,
+					     &actual_error, 
+                                             "Service_Type '%s' is invalid or has not been implemented yet", 
+                                             service_type);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	iface = tracker_db_manager_get_db_interface_by_service (service_type);
+
+	sql_select = g_string_new ("SELECT ");
+	sql_from   = g_string_new ("\nFROM Services S ");
+	sql_where  = g_string_new ("\nWHERE ");
+	sql_order  = g_string_new ("\nORDER BY ");
+
+	for (i=0;i<g_strv_length(fields);i++) {
+		TrackerFieldData   *def = NULL;
+		def = tracker_metadata_add_metadata_field (iface, service_type, &field_list, fields[i], FALSE, TRUE);
+		
+		if (!def) {
+			g_string_free (sql_select, TRUE);
+			g_string_free (sql_from, TRUE);
+			g_string_free (sql_where, TRUE);
+			g_string_free (sql_order, TRUE);
+			
+			tracker_dbus_request_failed (request_id,
+						     &actual_error, 
+						     "Invalid or non-existant metadata type '%s' specified", 
+						     fields[i]);
+			dbus_g_method_return_error (context, actual_error);
+			g_error_free (actual_error);
+			return;
+		}
+
+		if (i) {
+			g_string_append_printf (sql_select, ",");
+			g_string_append_printf (sql_order, ",");
+		}
+
+		g_string_append_printf (sql_select, "DISTINCT %s", tracker_field_data_get_select_field (def));
+		g_string_append_printf (sql_order, " %s %s",
+					tracker_field_data_get_select_field (def),
+					order_desc ? "DESC" : "ASC" );
+	
+	}
+	
+	tracker_rdf_filter_to_sql (iface, query_condition, service_type,
+				   &field_list, &rdf_from, &rdf_where, &actual_error);
+	
+	if (actual_error) {
+
+		g_string_free (sql_select, TRUE);
+		g_string_free (sql_from, TRUE);
+		g_string_free (sql_where, TRUE);
+		g_string_free (sql_order, TRUE);
+
+
+		tracker_dbus_request_failed (request_id,
+					     &actual_error, 
+					     NULL);
+		
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	g_string_append_printf (sql_from, " %s ", rdf_from);
+	g_string_append_printf (sql_where, " %s ", rdf_where);
+
+	g_free (rdf_from);
+	g_free (rdf_where);
+
+	sql = g_strconcat (sql_select->str, " ", sql_from->str, " ", sql_where->str, " ", sql_order->str, NULL);
+
+	g_string_free (sql_select, TRUE);
+	g_string_free (sql_from, TRUE);
+	g_string_free (sql_where, TRUE);
+	g_string_free (sql_order, TRUE);
+
+	g_slist_foreach (field_list, (GFunc) g_object_unref, NULL);
+	g_slist_free (field_list);
+
+	g_message ("Unique values query executed:\n%s", sql);
+
+	result_set =  tracker_db_interface_execute_query (iface, NULL, sql);
+
+	g_free (sql);
+
+	values = tracker_dbus_query_result_to_ptr_array (result_set);
+
+	dbus_g_method_return (context, values);
+
+	tracker_dbus_results_ptr_array_free (&values);
+
+	if (result_set) {
+		g_object_unref (result_set);
+	}
+
+	tracker_dbus_request_success (request_id);
+
+	return;
+}
+
+static gboolean
+is_data_type_numeric (TrackerFieldType type) {
+	return (type == TRACKER_FIELD_TYPE_INTEGER 
+		|| type == TRACKER_FIELD_TYPE_DOUBLE);
+}
+
+
+void
+tracker_metadata_get_sum (TrackerMetadata        *object,
+			  const gchar            *service_type,
+			  const gchar            *field,
+			  const gchar            *query_condition,
+			  DBusGMethodInvocation  *context,
+			  GError                **error)
+{
+	TrackerDBInterface *iface;
+	TrackerDBResultSet *result_set = NULL;
+	guint               request_id;
+
+	gint                sum;
+	GSList             *fields = NULL;
+	TrackerFieldData   *def = NULL;
+	TrackerFieldType    data_type;
+	GString            *sql_select;
+	GString            *sql_from;
+	GString            *sql_where;
+	gchar              *sql;
+
+	char               *rdf_where;
+	char               *rdf_from;
+	GError             *actual_error = NULL;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (service_type != NULL, context);
+	tracker_dbus_async_return_if_fail (field != NULL, context);
+	tracker_dbus_async_return_if_fail (query_condition != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to get sum, "
+				  "service type:'%s', field '%s', query '%s'",
+                                  service_type,
+				  field,
+                                  query_condition);
+
+	if (!tracker_ontology_is_valid_service_type (service_type)) {
+		tracker_dbus_request_failed (request_id,
+					     &actual_error,
+					     "Service '%s' is invalid or has not been implemented yet",
+					     service_type);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	iface = tracker_db_manager_get_db_interface_by_service (service_type);
+
+	sql_select = g_string_new ("SELECT ");
+	sql_from   = g_string_new ("\nFROM Services S ");
+	sql_where  = g_string_new ("\nWHERE ");
+
+	def = tracker_metadata_add_metadata_field (iface, service_type, &fields, field, FALSE, TRUE);
+	
+	data_type = tracker_field_data_get_data_type (def);
+	if (!is_data_type_numeric (data_type)) {
+		g_string_free (sql_select, TRUE);
+		g_string_free (sql_from, TRUE);
+		g_string_free (sql_where, TRUE);
+		tracker_dbus_request_failed (request_id,
+					     &actual_error,
+					     "Cannot sum '%s': this metadata type is not numeric", 
+					     field);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+
+	if (!def) {
+		g_string_free (sql_select, TRUE);
+		g_string_free (sql_from, TRUE);
+		g_string_free (sql_where, TRUE);
+		tracker_dbus_request_failed (request_id,
+					     &actual_error,
+					     "Invalid or non-existant metadata type '%s' specified", 
+					     field);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	g_string_append_printf (sql_select, "SUM (%s)", tracker_field_data_get_select_field (def));
+	
+	tracker_rdf_filter_to_sql (iface, query_condition, service_type,
+				   &fields, &rdf_from, &rdf_where, &actual_error);
+	
+	if (actual_error) {
+
+		g_string_free (sql_select, TRUE);
+		g_string_free (sql_from, TRUE);
+		g_string_free (sql_where, TRUE);
+
+		tracker_dbus_request_failed (request_id, &actual_error, NULL);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	g_string_append_printf (sql_from, " %s ", rdf_from);
+	g_string_append_printf (sql_where, " %s ", rdf_where);
+
+	g_free (rdf_from);
+	g_free (rdf_where);
+
+	sql = g_strconcat (sql_select->str, " ", sql_from->str, " ", sql_where->str, NULL);
+
+	g_string_free (sql_select, TRUE);
+	g_string_free (sql_from, TRUE);
+	g_string_free (sql_where, TRUE);
+
+	g_slist_foreach (fields, (GFunc) g_object_unref, NULL);
+	g_slist_free (fields);
+
+	g_debug ("Sum query executed:\n%s", sql);
+
+	result_set =  tracker_db_interface_execute_query (iface, NULL, sql);
+
+	g_free (sql);
+
+	tracker_db_result_set_get (result_set, 0, &sum, -1);
+
+	if (result_set) {
+		g_object_unref (result_set);
+	}
+
+	dbus_g_method_return (context, sum);
+
+	tracker_dbus_request_success (request_id);
+
+	return;
+}
+
+
+void
+tracker_metadata_get_count (TrackerMetadata        *object,
+			    const gchar            *service_type,
+			    const gchar            *field,
+			    const gchar            *query_condition,
+			    DBusGMethodInvocation  *context,
+			    GError                **error)
+{
+	TrackerDBInterface *iface;
+	TrackerDBResultSet *result_set = NULL;
+	guint               request_id;
+	gint                count;
+	GSList             *fields = NULL;
+	TrackerFieldData   *def = NULL;
+
+	GString            *sql_select;
+	GString            *sql_from;
+	GString            *sql_where;
+	gchar              *sql;
+
+	char               *rdf_where;
+	char               *rdf_from;
+	GError             *actual_error = NULL;
+
+	request_id = tracker_dbus_get_next_request_id ();
+
+	tracker_dbus_async_return_if_fail (service_type != NULL, context);
+	tracker_dbus_async_return_if_fail (field != NULL, context);
+	tracker_dbus_async_return_if_fail (query_condition != NULL, context);
+
+	tracker_dbus_request_new (request_id,
+				  "DBus request to get count, "
+				  "service type:'%s', field '%s', query '%s'",
+                                  service_type,
+				  field,
+                                  query_condition);
+
+	if (!tracker_ontology_is_valid_service_type (service_type)) {
+		tracker_dbus_request_failed (request_id,
+					     &actual_error,
+					     "Service '%s' is invalid or has not been implemented yet",
+					     service_type);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	iface = tracker_db_manager_get_db_interface_by_service (service_type);
+
+	sql_select = g_string_new ("SELECT ");
+	sql_from   = g_string_new ("\nFROM Services S ");
+	sql_where  = g_string_new ("\nWHERE ");
+
+	def = tracker_metadata_add_metadata_field (iface, service_type, &fields, field, FALSE, TRUE);
+
+	if (!def) {
+		g_string_free (sql_select, TRUE);
+		g_string_free (sql_from, TRUE);
+		g_string_free (sql_where, TRUE);
+
+		tracker_dbus_request_failed (request_id,
+					     &actual_error,
+					     "Invalid or non-existant metadata type '%s' specified", 
+					     field);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	g_string_append_printf (sql_select, "COUNT (DISTINCT %s)", tracker_field_data_get_select_field (def));
+	
+	tracker_rdf_filter_to_sql (iface, query_condition, service_type,
+				   &fields, &rdf_from, &rdf_where, &actual_error);
+	
+	if (actual_error) {
+
+		g_string_free (sql_select, TRUE);
+		g_string_free (sql_from, TRUE);
+		g_string_free (sql_where, TRUE);
+
+		tracker_dbus_request_failed (request_id,
+					     &actual_error,
+					     NULL);
+		dbus_g_method_return_error (context, actual_error);
+		g_error_free (actual_error);
+		return;
+	}
+
+	g_string_append_printf (sql_from, " %s ", rdf_from);
+	g_string_append_printf (sql_where, " %s ", rdf_where);
+
+	g_free (rdf_from);
+	g_free (rdf_where);
+
+	sql = g_strconcat (sql_select->str, " ", sql_from->str, " ", sql_where->str, NULL);
+
+	g_string_free (sql_select, TRUE);
+	g_string_free (sql_from, TRUE);
+	g_string_free (sql_where, TRUE);
+
+	g_slist_foreach (fields, (GFunc) g_object_unref, NULL);
+	g_slist_free (fields);
+
+	g_message ("Count query executed:\n%s", sql);
+
+	result_set =  tracker_db_interface_execute_query (iface, NULL, sql);
+
+	g_free (sql);
+
+	tracker_db_result_set_get (result_set, 0, &count, -1);
+
+	if (result_set) {
+		g_object_unref (result_set);
+	}
+
+	dbus_g_method_return (context, count);
+
+	tracker_dbus_request_success (request_id);
+
+	return;
+}
+

Modified: branches/indexer-split/src/trackerd/tracker-metadata.h
==============================================================================
--- branches/indexer-split/src/trackerd/tracker-metadata.h	(original)
+++ branches/indexer-split/src/trackerd/tracker-metadata.h	Mon Aug 11 14:35:46 2008
@@ -52,30 +52,52 @@
 
 GType            tracker_metadata_get_type               (void);
 TrackerMetadata *tracker_metadata_new                    (void);
-void             tracker_metadata_get                    (TrackerMetadata         *object,
-							  const gchar             *service_type,
-							  const gchar             *uri,
-							  gchar                  **keys,
-							  DBusGMethodInvocation   *context,
-							  GError                 **error);
-void             tracker_metadata_set                    (TrackerMetadata         *object,
-							  const gchar             *service_type,
-							  const gchar             *uri,
-							  gchar                  **keys,
-							  gchar                  **metadata,
-							  DBusGMethodInvocation   *context,
-							  GError                 **error);
-void             tracker_metadata_get_type_details       (TrackerMetadata         *object,
-							  const gchar             *metadata,
-							  DBusGMethodInvocation   *context,
-							  GError                 **error);
-void             tracker_metadata_get_registered_types   (TrackerMetadata         *object,
-							  const gchar             *service_type,
-							  DBusGMethodInvocation   *context,
-							  GError                 **error);
-void             tracker_metadata_get_registered_classes (TrackerMetadata         *object,
-							  DBusGMethodInvocation   *context,
-							  GError                 **error);
+void             tracker_metadata_get                    (TrackerMetadata        *object,
+							  const gchar            *service_type,
+							  const gchar            *uri,
+							  gchar                 **keys,
+							  DBusGMethodInvocation  *context,
+							  GError                **error);
+void             tracker_metadata_set                    (TrackerMetadata        *object,
+							  const gchar            *service_type,
+							  const gchar            *uri,
+							  gchar                 **keys,
+							  gchar                 **metadata,
+							  DBusGMethodInvocation  *context,
+							  GError                **error);
+void             tracker_metadata_get_type_details       (TrackerMetadata        *object,
+							  const gchar            *metadata,
+							  DBusGMethodInvocation  *context,
+							  GError                **error);
+void             tracker_metadata_get_registered_types   (TrackerMetadata        *object,
+							  const gchar            *service_type,
+							  DBusGMethodInvocation  *context,
+							  GError                **error);
+void             tracker_metadata_get_registered_classes (TrackerMetadata        *object,
+							  DBusGMethodInvocation  *context,
+							  GError                **error);
+void             tracker_metadata_get_unique_values      (TrackerMetadata        *object,
+							  const gchar            *service_type,
+							  gchar                 **fields,
+							  const gchar            *query_condition,
+							  gboolean                order_desc,
+							  gint                    offset,
+							  gint                    max_hits,
+							  DBusGMethodInvocation  *context,
+							  GError                **error);
+void             tracker_metadata_get_sum                (TrackerMetadata        *object,
+							  const gchar            *service_type,
+							  const gchar            *field,
+							  const gchar            *query_condition,
+							  DBusGMethodInvocation  *context,
+							  GError                **error);
+void             tracker_metadata_get_count              (TrackerMetadata        *object,
+							  const gchar            *service_type,
+							  const gchar            *field,
+							  const gchar            *query_condition,
+							  DBusGMethodInvocation  *context,
+							  GError                **error);
+
 
 G_END_DECLS
 

Modified: branches/indexer-split/src/trackerd/tracker-rdf-query.c
==============================================================================
--- branches/indexer-split/src/trackerd/tracker-rdf-query.c	(original)
+++ branches/indexer-split/src/trackerd/tracker-rdf-query.c	Mon Aug 11 14:35:46 2008
@@ -373,6 +373,7 @@
                 const gchar *this_field_name;
 
                 this_field_name = tracker_field_data_get_field_name (l->data);
+		
                 if (!this_field_name) {
                         continue;
                 }
@@ -1346,3 +1347,123 @@
 }
 
 
+/* 
+ * 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 (TrackerDBInterface *iface,
+			   const char         *query, 
+			   const char         *service, 
+			   GSList            **fields,
+			   char              **from,
+			   char              **where,
+			   GError            **error)
+{
+	static gboolean inited = FALSE;
+	ParserData      data;
+
+	g_return_if_fail (TRACKER_IS_DB_INTERFACE (iface));
+        g_return_if_fail (service != NULL);
+        g_return_if_fail (from != NULL);
+        g_return_if_fail (where != NULL);
+
+	if (!inited) {
+		error_quark = g_quark_from_static_string ("RDF-parser-error-quark");
+		inited = TRUE;
+	}
+
+	memset (&data, 0, sizeof (data));
+	data.iface = iface;
+	data.statement_count = 0;
+	data.service = (char *) service;
+
+	data.sql_from = g_string_new ("");
+	data.sql_where = g_string_new ("");
+
+	data.fields = *fields;
+
+	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 ( (query != NULL) && (!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 {
+	        GSList *l;
+	  
+    	        for (l = data.fields; l; l = l->next) {
+			if (!tracker_field_data_get_is_condition (l->data)) {
+				if (tracker_field_data_get_needs_join (l->data)) {
+					g_string_append_printf (data.sql_from, 
+                                                                "\n LEFT OUTER JOIN %s %s ON (S.ID = %s.ServiceID and %s.MetaDataID = %s) ", 
+                                                                tracker_field_data_get_table_name (l->data), 
+                                                                tracker_field_data_get_alias (l->data),
+                                                                tracker_field_data_get_alias (l->data),
+                                                                tracker_field_data_get_alias (l->data),
+                                                                tracker_field_data_get_id_field (l->data));
+				}
+			} else {
+				gchar *related_metadata;
+
+                                related_metadata = tracker_db_metadata_get_related_names (iface, 
+                                                                                          tracker_field_data_get_field_name (l->data));
+				g_string_append_printf (data.sql_from, 
+                                                        "\n INNER JOIN %s %s ON (S.ID = %s.ServiceID and %s.MetaDataID in (%s)) ", 
+                                                        tracker_field_data_get_table_name (l->data), 
+                                                        tracker_field_data_get_alias (l->data),
+                                                        tracker_field_data_get_alias (l->data),
+                                                        tracker_field_data_get_alias (l->data),
+                                                        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);
+		
+
+	}
+
+	*fields = 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: branches/indexer-split/src/trackerd/tracker-rdf-query.h
==============================================================================
--- branches/indexer-split/src/trackerd/tracker-rdf-query.h	(original)
+++ branches/indexer-split/src/trackerd/tracker-rdf-query.h	Mon Aug 11 14:35:46 2008
@@ -39,6 +39,14 @@
 				 gint                 limit,
 				 GError              *error);
 
+void tracker_rdf_filter_to_sql  (TrackerDBInterface  *iface,
+				 const gchar         *query,
+				 const gchar         *service,
+				 GSList             **fields,
+				 gchar              **from,
+				 gchar              **where,
+				 GError             **error);
+
 G_END_DECLS
 
 #endif /* __TRACKERD_RDF_QUERY_H__ */



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