[tracker/sparql-update-delete-id-passing] libtracker-data, tracker-store: Pass IDs instead of strings for DELETE subjects



commit d88e3eaa2778f385554c6096253a9d382ff40a11
Author: Philip Van Hoof <philip codeminded be>
Date:   Wed Mar 23 14:07:44 2011 +0100

    libtracker-data, tracker-store: Pass IDs instead of strings for DELETE subjects

 src/libtracker-data/libtracker-data.vapi           |    8 +-
 src/libtracker-data/tracker-data-manager.c         |   10 ++--
 src/libtracker-data/tracker-data-update.c          |   48 +++++++------
 src/libtracker-data/tracker-data-update.h          |    7 ++-
 src/libtracker-data/tracker-sparql-expression.vala |   25 +++++++
 src/libtracker-data/tracker-sparql-pattern.vala    |    6 +-
 src/libtracker-data/tracker-sparql-query.vala      |   73 +++++++++++++++-----
 src/tracker-store/tracker-events.c                 |    2 -
 src/tracker-store/tracker-events.h                 |    2 -
 src/tracker-store/tracker-events.vapi              |    4 +-
 src/tracker-store/tracker-resources.vala           |   12 ++--
 src/tracker-store/tracker-writeback.c              |    1 -
 src/tracker-store/tracker-writeback.h              |    1 -
 src/tracker-store/tracker-writeback.vapi           |    2 +-
 14 files changed, 133 insertions(+), 68 deletions(-)
---
diff --git a/src/libtracker-data/libtracker-data.vapi b/src/libtracker-data/libtracker-data.vapi
index ba5033b..eb817b3 100644
--- a/src/libtracker-data/libtracker-data.vapi
+++ b/src/libtracker-data/libtracker-data.vapi
@@ -155,7 +155,7 @@ namespace Tracker {
 		public unowned Property[] get_properties ();
 	}
 
-	public delegate void StatementCallback (int graph_id, string? graph, int subject_id, string subject, int predicate_id, int object_id, string object, GLib.PtrArray rdf_types);
+	public delegate void StatementCallback (int graph_id, string? graph, int subject_id, string? subject, int predicate_id, int object_id, string object, GLib.PtrArray rdf_types);
 	public delegate void CommitCallback (bool start_timer);
 
 	[CCode (cheader_filename = "libtracker-data/tracker-data-query.h,libtracker-data/tracker-data-update.h,libtracker-data/tracker-data-backup.h")]
@@ -171,13 +171,13 @@ namespace Tracker {
 		public GLib.Variant update_sparql_blank (string update) throws Sparql.Error;
 		public void load_turtle_file (GLib.File file) throws Sparql.Error;
 		public void notify_transaction (bool start_timer);
-		public void delete_statement (string? graph, string subject, string predicate, string object) throws Sparql.Error, DateError;
+		public void delete_statement (string? graph, string subject, int s_id, string predicate, string object) throws Sparql.Error, DateError;
 		public void update_statement (string? graph, string subject, string predicate, string object) throws Sparql.Error, DateError;
 		public void insert_statement (string? graph, string subject, string predicate, string object) throws Sparql.Error, DateError;
 		public void insert_statement_with_uri (string? graph, string subject, string predicate, string object) throws Sparql.Error;
 		public void insert_statement_with_string (string? graph, string subject, string predicate, string object) throws Sparql.Error, DateError;
-		public void update_buffer_flush () throws DBInterfaceError;
-		public void update_buffer_might_flush () throws DBInterfaceError;
+		public void update_buffer_flush (bool delete_statements = false) throws DBInterfaceError;
+		public void update_buffer_might_flush (bool delete_statements = false) throws DBInterfaceError;
 		public void sync ();
 
 		public void add_insert_statement_callback (StatementCallback callback);
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index f90a250..a0a48a9 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -432,9 +432,9 @@ update_property_value (const gchar      *ontology_path,
 				}
 
 				if (!unsup_onto_err) {
-					tracker_data_delete_statement (NULL, subject, predicate, str, &error);
+					tracker_data_delete_statement (NULL, subject, 0, predicate, str, &error);
 					if (!error)
-						tracker_data_update_buffer_flush (&error);
+						tracker_data_update_buffer_flush (FALSE, &error);
 				}
 			}
 
@@ -459,7 +459,7 @@ update_property_value (const gchar      *ontology_path,
 		                               predicate, object,
 		                               &error);
 		if (!error)
-			tracker_data_update_buffer_flush (&error);
+			tracker_data_update_buffer_flush (FALSE, &error);
 	}
 
 	if (error) {
@@ -1285,7 +1285,7 @@ check_for_deleted_domain_index (TrackerClass *class)
 			tracker_property_del_domain_index (prop, class);
 			tracker_class_del_domain_index (class, prop);
 
-			tracker_data_delete_statement (NULL, tracker_class_get_uri (class),
+			tracker_data_delete_statement (NULL, tracker_class_get_uri (class), 0,
 			                               TRACKER_PREFIX "domainIndex",
 			                               tracker_property_get_uri (prop),
 			                               &error);
@@ -1294,7 +1294,7 @@ check_for_deleted_domain_index (TrackerClass *class)
 				g_critical ("Ontology change, %s", error->message);
 				g_clear_error (&error);
 			} else {
-				tracker_data_update_buffer_flush (&error);
+				tracker_data_update_buffer_flush (FALSE, &error);
 				if (error) {
 					g_critical ("Ontology change, %s", error->message);
 					g_clear_error (&error);
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index df9322f..9a1bb03 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -990,12 +990,13 @@ static void resource_buffer_free (TrackerDataUpdateBufferResource *resource)
 }
 
 void
-tracker_data_update_buffer_flush (GError **error)
+tracker_data_update_buffer_flush (gboolean   delete_statements,
+                                  GError   **error)
 {
 	GHashTableIter iter;
 	GError *actual_error = NULL;
 
-	if (in_journal_replay) {
+	if (in_journal_replay || delete_statements) {
 		g_hash_table_iter_init (&iter, update_buffer.resources_by_id);
 		while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &resource_buffer)) {
 			tracker_data_resource_buffer_flush (&actual_error);
@@ -1022,12 +1023,13 @@ tracker_data_update_buffer_flush (GError **error)
 }
 
 void
-tracker_data_update_buffer_might_flush (GError **error)
+tracker_data_update_buffer_might_flush (gboolean   delete_statements,
+                                        GError   **error)
 {
 	/* avoid high memory usage by update buffer */
 	if (g_hash_table_size (update_buffer.resources) +
 	    g_hash_table_size (update_buffer.resources_by_id) >= 1000) {
-		tracker_data_update_buffer_flush (error);
+		tracker_data_update_buffer_flush (delete_statements, error);
 	}
 }
 
@@ -2049,9 +2051,10 @@ static void
 resource_buffer_switch (const gchar *graph,
                         gint         graph_id,
                         const gchar *subject,
-                        gint         subject_id)
+                        gint         subject_id,
+                        gboolean     in_delete_statement)
 {
-	if (in_journal_replay) {
+	if (in_journal_replay || in_delete_statement) {
 		/* journal replay only provides subject id
 		   resource_buffer->subject is only used in error messages and callbacks
 		   both should never occur when in journal replay */
@@ -2072,7 +2075,7 @@ resource_buffer_switch (const gchar *graph,
 		/* large INSERTs with thousands of resources could lead to
 		   high peak memory usage due to the update buffer
 		   flush the buffer if it already contains 1000 resources */
-		tracker_data_update_buffer_might_flush (NULL);
+		tracker_data_update_buffer_might_flush (in_delete_statement, NULL);
 
 		/* subject not yet in cache, retrieve or create ID */
 		resource_buffer = g_slice_new0 (TrackerDataUpdateBufferResource);
@@ -2096,7 +2099,7 @@ resource_buffer_switch (const gchar *graph,
 		resource_buffer->predicates = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, (GDestroyNotify) g_value_array_free);
 		resource_buffer->tables = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cache_table_free);
 
-		if (in_journal_replay) {
+		if (in_journal_replay || in_delete_statement) {
 			g_hash_table_insert (update_buffer.resources_by_id, GINT_TO_POINTER (subject_id), resource_buffer);
 		} else {
 			g_hash_table_insert (update_buffer.resources, subject_dup, resource_buffer);
@@ -2111,6 +2114,7 @@ resource_buffer_switch (const gchar *graph,
 void
 tracker_data_delete_statement (const gchar  *graph,
                                const gchar  *subject,
+                               gint          s_id,
                                const gchar  *predicate,
                                const gchar  *object,
                                GError      **error)
@@ -2119,19 +2123,19 @@ tracker_data_delete_statement (const gchar  *graph,
 	gint                subject_id = 0;
 	gboolean            change = FALSE;
 
-	g_return_if_fail (subject != NULL);
+	g_return_if_fail (s_id != 0 || subject != NULL);
 	g_return_if_fail (predicate != NULL);
 	g_return_if_fail (object != NULL);
 	g_return_if_fail (in_transaction);
 
-	subject_id = query_resource_id (subject);
+	subject_id = (s_id != 0) ? s_id : query_resource_id (subject);
 
 	if (subject_id == 0) {
 		/* subject not in database */
 		return;
 	}
 
-	resource_buffer_switch (graph, 0, subject, subject_id);
+	resource_buffer_switch (graph, 0, NULL, subject_id, TRUE);
 
 	if (object && g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
 		class = tracker_ontologies_get_class_by_uri (object);
@@ -2274,7 +2278,7 @@ tracker_data_insert_statement_common (const gchar            *graph,
 		return FALSE;
 	}
 
-	resource_buffer_switch (graph, 0, subject, 0);
+	resource_buffer_switch (graph, 0, subject, 0, FALSE);
 
 	return TRUE;
 }
@@ -2991,7 +2995,7 @@ tracker_data_commit_transaction (GError **error)
 
 	iface = tracker_db_manager_get_db_interface ();
 
-	tracker_data_update_buffer_flush (&actual_error);
+	tracker_data_update_buffer_flush (FALSE, &actual_error);
 	if (actual_error) {
 		tracker_data_rollback_transaction ();
 		g_propagate_error (error, actual_error);
@@ -3218,7 +3222,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 			tracker_data_begin_transaction_for_replay (tracker_db_journal_reader_get_time (), NULL);
 		} else if (type == TRACKER_DB_JOURNAL_END_TRANSACTION) {
 			GError *new_error = NULL;
-			tracker_data_update_buffer_might_flush (&new_error);
+			tracker_data_update_buffer_might_flush (FALSE, &new_error);
 
 			tracker_data_commit_transaction (&new_error);
 			if (new_error) {
@@ -3239,7 +3243,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 			tracker_db_journal_reader_get_statement (&graph_id, &subject_id, &predicate_id, &object);
 
 			if (last_operation_type == -1) {
-				tracker_data_update_buffer_flush (&new_error);
+				tracker_data_update_buffer_flush (FALSE, &new_error);
 				if (new_error) {
 					g_warning ("Journal replay error: '%s'", new_error->message);
 					g_clear_error (&new_error);
@@ -3253,7 +3257,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 			}
 
 			if (property) {
-				resource_buffer_switch (NULL, graph_id, NULL, subject_id);
+				resource_buffer_switch (NULL, graph_id, NULL, subject_id, FALSE);
 
 				if (type == TRACKER_DB_JOURNAL_UPDATE_STATEMENT) {
 					cache_update_metadata_decomposed (property, object, 0, NULL, graph_id, &new_error);
@@ -3278,7 +3282,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 			tracker_db_journal_reader_get_statement_id (&graph_id, &subject_id, &predicate_id, &object_id);
 
 			if (last_operation_type == -1) {
-				tracker_data_update_buffer_flush (&new_error);
+				tracker_data_update_buffer_flush (FALSE, &new_error);
 				if (new_error) {
 					g_warning ("Journal replay error: '%s'", new_error->message);
 					g_clear_error (&new_error);
@@ -3295,7 +3299,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 				if (tracker_property_get_data_type (property) != TRACKER_PROPERTY_TYPE_RESOURCE) {
 					g_warning ("Journal replay error: 'property with ID %d does not account URIs'", predicate_id);
 				} else {
-					resource_buffer_switch (NULL, graph_id, NULL, subject_id);
+					resource_buffer_switch (NULL, graph_id, NULL, subject_id, FALSE);
 
 					if (property == rdf_type) {
 						uri = tracker_ontologies_get_uri_by_id (object_id);
@@ -3334,7 +3338,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 			tracker_db_journal_reader_get_statement (&graph_id, &subject_id, &predicate_id, &object);
 
 			if (last_operation_type == 1) {
-				tracker_data_update_buffer_flush (&new_error);
+				tracker_data_update_buffer_flush (FALSE, &new_error);
 				if (new_error) {
 					g_warning ("Journal replay error: '%s'", new_error->message);
 					g_clear_error (&new_error);
@@ -3342,7 +3346,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 			}
 			last_operation_type = -1;
 
-			resource_buffer_switch (NULL, graph_id, NULL, subject_id);
+			resource_buffer_switch (NULL, graph_id, NULL, subject_id, FALSE);
 
 			uri = tracker_ontologies_get_uri_by_id (predicate_id);
 			if (uri) {
@@ -3385,7 +3389,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 			tracker_db_journal_reader_get_statement_id (&graph_id, &subject_id, &predicate_id, &object_id);
 
 			if (last_operation_type == 1) {
-				tracker_data_update_buffer_flush (&new_error);
+				tracker_data_update_buffer_flush (FALSE, &new_error);
 				if (new_error) {
 					g_warning ("Journal replay error: '%s'", new_error->message);
 					g_clear_error (&new_error);
@@ -3400,7 +3404,7 @@ tracker_data_replay_journal (TrackerBusyCallback   busy_callback,
 
 			if (property) {
 
-				resource_buffer_switch (NULL, graph_id, NULL, subject_id);
+				resource_buffer_switch (NULL, graph_id, NULL, subject_id, FALSE);
 
 				if (property == rdf_type) {
 					uri = tracker_ontologies_get_uri_by_id (object_id);
diff --git a/src/libtracker-data/tracker-data-update.h b/src/libtracker-data/tracker-data-update.h
index 1bed0d9..9da1a88 100644
--- a/src/libtracker-data/tracker-data-update.h
+++ b/src/libtracker-data/tracker-data-update.h
@@ -51,6 +51,7 @@ GQuark   tracker_data_error_quark                   (void);
 /* Metadata */
 void     tracker_data_delete_statement              (const gchar               *graph,
                                                      const gchar               *subject,
+                                                     gint                       s_id,
                                                      const gchar               *predicate,
                                                      const gchar               *object,
                                                      GError                   **error);
@@ -86,8 +87,10 @@ void     tracker_data_update_sparql                 (const gchar               *
 GVariant *
          tracker_data_update_sparql_blank           (const gchar               *update,
                                                      GError                   **error);
-void     tracker_data_update_buffer_flush           (GError                   **error);
-void     tracker_data_update_buffer_might_flush     (GError                   **error);
+void     tracker_data_update_buffer_flush           (gboolean                   delete_statements,
+                                                     GError                   **error);
+void     tracker_data_update_buffer_might_flush     (gboolean                   delete_statements,
+                                                     GError                   **error);
 void     tracker_data_load_turtle_file              (GFile                     *file,
                                                      GError                   **error);
 
diff --git a/src/libtracker-data/tracker-sparql-expression.vala b/src/libtracker-data/tracker-sparql-expression.vala
index ce111b0..9f6aae4 100644
--- a/src/libtracker-data/tracker-sparql-expression.vala
+++ b/src/libtracker-data/tracker-sparql-expression.vala
@@ -300,6 +300,31 @@ class Tracker.Sparql.Expression : Object {
 		}
 	}
 
+	internal static void append_expression_as_int (StringBuilder sql, string expression, PropertyType type) {
+		long begin = sql.len;
+		sql.append (expression);
+		convert_expression_to_int (sql, type, begin);
+	}
+
+	static void convert_expression_to_int (StringBuilder sql, PropertyType type, long begin) {
+		switch (type) {
+		case PropertyType.STRING:
+		case PropertyType.INTEGER:
+		case PropertyType.RESOURCE:
+		case PropertyType.BOOLEAN:
+		case PropertyType.DATETIME:
+			// nothing to convert
+			// do not use CAST to convert integers to strings as this breaks use
+			// of index when sorting by variable introduced in select expression
+			break;
+		default:
+			// let sqlite convert the expression to integer
+			sql.insert (begin, "CAST (");
+			sql.append (" AS INTEGER)");
+			break;
+		}
+	}
+
 	void translate_expression_as_string (StringBuilder sql) throws Sparql.Error {
 		switch (current ()) {
 		case SparqlTokenType.IRI_REF:
diff --git a/src/libtracker-data/tracker-sparql-pattern.vala b/src/libtracker-data/tracker-sparql-pattern.vala
index 99b47ac..7e78656 100644
--- a/src/libtracker-data/tracker-sparql-pattern.vala
+++ b/src/libtracker-data/tracker-sparql-pattern.vala
@@ -485,9 +485,10 @@ class Tracker.Sparql.Pattern : Object {
 			next ();
 			result = query.resolve_prefixed_name ("", get_last_string ().substring (1));
 		} else if (accept (SparqlTokenType.BLANK_NODE)) {
+			int id;
 			// _:foo
 			expect (SparqlTokenType.COLON);
-			result = query.generate_bnodeid (get_last_string ().substring (1));
+			result = query.generate_bnodeid (get_last_string ().substring (1), out id);
 		} else if (current () == SparqlTokenType.STRING_LITERAL1) {
 			result = expression.parse_string_literal ();
 		} else if (current () == SparqlTokenType.STRING_LITERAL2) {
@@ -512,9 +513,10 @@ class Tracker.Sparql.Pattern : Object {
 			next ();
 			result = "false";
 		} else if (current () == SparqlTokenType.OPEN_BRACKET) {
+			int id;
 			next ();
 
-			result = query.generate_bnodeid (null);
+			result = query.generate_bnodeid (null, out id);
 
 			string old_subject = current_subject;
 			bool old_subject_is_var = current_subject_is_var;
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index 21b936d..d55fae6 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -197,6 +197,7 @@ public class Tracker.Sparql.Query : Object {
 
 	string current_graph;
 	string current_subject;
+	int current_subject_id;
 	bool current_subject_is_var;
 	string current_predicate;
 	bool current_predicate_is_var;
@@ -258,7 +259,9 @@ public class Tracker.Sparql.Query : Object {
 			sha1, sha1.substring (8), sha1.substring (12), sha1.substring (16), sha1.substring (20));
 	}
 
-	internal string generate_bnodeid (string? user_bnodeid) {
+	internal string generate_bnodeid (string? user_bnodeid, out int id) {
+		int resource_id = 0;
+
 		// user_bnodeid is NULL for anonymous nodes
 		if (user_bnodeid == null) {
 			return ":%d".printf (++bnodeid);
@@ -275,7 +278,7 @@ public class Tracker.Sparql.Query : Object {
 			uri = get_uuid_for_name (base_uuid, user_bnodeid);
 
 			if (blank_nodes != null) {
-				while (Data.query_resource_id (uri) > 0) {
+				while ((resource_id = Data.query_resource_id (uri)) > 0) {
 					// uri collision, generate new UUID
 					uchar[] new_base_uuid = new uchar[16];
 					uuid_generate (new_base_uuid);
@@ -285,6 +288,8 @@ public class Tracker.Sparql.Query : Object {
 				blank_nodes.insert (user_bnodeid, uri);
 			}
 
+			id = resource_id;
+
 			return uri;
 		}
 	}
@@ -666,7 +671,11 @@ public class Tracker.Sparql.Query : Object {
 			if (variable.binding == null) {
 				throw get_error ("use of undefined variable `%s'".printf (variable.name));
 			}
-			Expression.append_expression_as_string (sql, variable.sql_expression, variable.binding.data_type);
+			if (delete_statements){
+				Expression.append_expression_as_int (sql, variable.sql_expression, variable.binding.data_type);
+			} else {
+				Expression.append_expression_as_string (sql, variable.sql_expression, variable.binding.data_type);
+			}
 		}
 
 		if (first) {
@@ -706,7 +715,7 @@ public class Tracker.Sparql.Query : Object {
 				update_blank_nodes.add_value (blank_nodes);
 			}
 
-			Data.update_buffer_might_flush ();
+			Data.update_buffer_might_flush (delete_statements);
 		}
 
 		if (!data) {
@@ -715,7 +724,7 @@ public class Tracker.Sparql.Query : Object {
 		}
 
 		// ensure possible WHERE clause in next part gets the correct results
-		Data.update_buffer_flush ();
+		Data.update_buffer_flush (delete_statements);
 		bindings = null;
 
 		context = context.parent_context;
@@ -752,12 +761,13 @@ public class Tracker.Sparql.Query : Object {
 		while (current () != SparqlTokenType.CLOSE_BRACE) {
 			if (accept (SparqlTokenType.GRAPH)) {
 				var old_graph = current_graph;
-				current_graph = parse_construct_var_or_term (var_value_map);
+				int id;
+				current_graph = parse_construct_var_or_term (var_value_map, out id, false);
 
 				expect (SparqlTokenType.OPEN_BRACE);
 
 				while (current () != SparqlTokenType.CLOSE_BRACE) {
-					current_subject = parse_construct_var_or_term (var_value_map);
+					current_subject = parse_construct_var_or_term (var_value_map, out current_subject_id, delete_statements);
 					parse_construct_property_list_not_empty (var_value_map);
 					if (!accept (SparqlTokenType.DOT)) {
 						// no triples following
@@ -769,7 +779,7 @@ public class Tracker.Sparql.Query : Object {
 
 				current_graph = old_graph;
 			} else {
-				current_subject = parse_construct_var_or_term (var_value_map);
+				current_subject = parse_construct_var_or_term (var_value_map, out current_subject_id, delete_statements);
 				parse_construct_property_list_not_empty (var_value_map);
 				if (!accept (SparqlTokenType.DOT) && current () != SparqlTokenType.GRAPH) {
 					// neither GRAPH nor triples following
@@ -783,11 +793,23 @@ public class Tracker.Sparql.Query : Object {
 
 	bool anon_blank_node_open = false;
 
-	string? parse_construct_var_or_term (HashTable<string,string> var_value_map) throws Sparql.Error, DateError {
+	string? parse_construct_var_or_term (HashTable<string,string> var_value_map, out int id, bool for_del_sub) throws Sparql.Error, DateError {
 		string result = "";
+		int s_id = 0;
+
 		if (current () == SparqlTokenType.VAR) {
+			string as_str;
+
 			next ();
-			result = var_value_map.lookup (get_last_string ().substring (1));
+			as_str = var_value_map.lookup (get_last_string ().substring (1));
+
+			if (for_del_sub) {
+				s_id = as_str.to_int ();
+				result = null;
+			} else {
+				result = as_str;
+			}
+
 		} else if (current () == SparqlTokenType.IRI_REF) {
 			next ();
 			result = get_last_string (1);
@@ -804,7 +826,7 @@ public class Tracker.Sparql.Query : Object {
 		} else if (accept (SparqlTokenType.BLANK_NODE)) {
 			// _:foo
 			expect (SparqlTokenType.COLON);
-			result = generate_bnodeid (get_last_string ().substring (1));
+			result = generate_bnodeid (get_last_string ().substring (1), out s_id);
 		} else if (current () == SparqlTokenType.MINUS) {
 			next ();
 			if (current () == SparqlTokenType.INTEGER ||
@@ -847,21 +869,27 @@ public class Tracker.Sparql.Query : Object {
 			anon_blank_node_open = true;
 			next ();
 
-			result = generate_bnodeid (null);
+			result = generate_bnodeid (null, out s_id);
 
+			int old_subject_id = current_subject_id;
 			string old_subject = current_subject;
 			bool old_subject_is_var = current_subject_is_var;
 
+			current_subject_id = s_id;
 			current_subject = result;
 			parse_construct_property_list_not_empty (var_value_map);
 			expect (SparqlTokenType.CLOSE_BRACKET);
 			anon_blank_node_open = false;
 
+			current_subject_id = old_subject_id;
 			current_subject = old_subject;
 			current_subject_is_var = old_subject_is_var;
 		} else {
 			throw get_error ("expected variable or term");
 		}
+
+		id = s_id;
+
 		return result;
 	}
 
@@ -913,19 +941,28 @@ public class Tracker.Sparql.Query : Object {
 	}
 
 	void parse_construct_object (HashTable<string,string> var_value_map) throws Sparql.Error, DateError {
-		string object = parse_construct_var_or_term (var_value_map);
-		if (current_subject == null || current_predicate == null || object == null) {
-			// the SPARQL specification says that triples containing unbound variables
-			// should be excluded from the output RDF graph of CONSTRUCT
-			return;
+		int id;
+		string object = parse_construct_var_or_term (var_value_map, out id, false);
+
+		// the SPARQL specification says that triples containing unbound variables
+		// should be excluded from the output RDF graph of CONSTRUCT
+		if (delete_statements) {
+			if (current_subject_id == 0 || current_predicate == null || object == null) {
+				return;
+			}
+		} else {
+			if (current_subject == null || current_predicate == null || object == null) {
+				return;
+			}
 		}
+
 		try {
 			if (update_statements) {
 				// update triple in database
 				Data.update_statement (current_graph, current_subject, current_predicate, object);
 			} else if (delete_statements) {
 				// delete triple from database
-				Data.delete_statement (current_graph, current_subject, current_predicate, object);
+				Data.delete_statement (current_graph, current_subject, current_subject_id, current_predicate, object);
 			} else {
 				// insert triple into database
 				Data.insert_statement (current_graph, current_subject, current_predicate, object);
diff --git a/src/tracker-store/tracker-events.c b/src/tracker-store/tracker-events.c
index 8c8f46d..54689bf 100644
--- a/src/tracker-store/tracker-events.c
+++ b/src/tracker-store/tracker-events.c
@@ -53,7 +53,6 @@ tracker_events_get_total (gboolean and_reset)
 void
 tracker_events_add_insert (gint         graph_id,
                            gint         subject_id,
-                           const gchar *subject,
                            gint         pred_id,
                            gint         object_id,
                            const gchar *object,
@@ -83,7 +82,6 @@ tracker_events_add_insert (gint         graph_id,
 void
 tracker_events_add_delete (gint         graph_id,
                            gint         subject_id,
-                           const gchar *subject,
                            gint         pred_id,
                            gint         object_id,
                            const gchar *object,
diff --git a/src/tracker-store/tracker-events.h b/src/tracker-store/tracker-events.h
index 26f5ccb..9c3f93c 100644
--- a/src/tracker-store/tracker-events.h
+++ b/src/tracker-store/tracker-events.h
@@ -34,14 +34,12 @@ void           tracker_events_init              (void);
 void           tracker_events_shutdown          (void);
 void           tracker_events_add_insert        (gint         graph_id,
                                                  gint         subject_id,
-                                                 const gchar *subject,
                                                  gint         pred_id,
                                                  gint         object_id,
                                                  const gchar *object,
                                                  GPtrArray   *rdf_types);
 void           tracker_events_add_delete        (gint         graph_id,
                                                  gint         subject_id,
-                                                 const gchar *subject,
                                                  gint         pred_id,
                                                  gint         object_id,
                                                  const gchar *object,
diff --git a/src/tracker-store/tracker-events.vapi b/src/tracker-store/tracker-events.vapi
index f9f7787..8b81502 100644
--- a/src/tracker-store/tracker-events.vapi
+++ b/src/tracker-store/tracker-events.vapi
@@ -22,8 +22,8 @@ namespace Tracker {
 	namespace Events {
 		public void init ();
 		public void shutdown ();
-		public void add_insert (int graph_id, int subject_id, string subject, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
-		public void add_delete (int graph_id, int subject_id, string subject, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
+		public void add_insert (int graph_id, int subject_id, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
+		public void add_delete (int graph_id, int subject_id, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
 		public uint get_total (bool and_reset);
 		public void reset_pending ();
 		public void freeze ();
diff --git a/src/tracker-store/tracker-resources.vala b/src/tracker-store/tracker-resources.vala
index a31f380..631c8a3 100644
--- a/src/tracker-store/tracker-resources.vala
+++ b/src/tracker-store/tracker-resources.vala
@@ -296,15 +296,15 @@ public class Tracker.Resources : Object {
 		}
 	}
 
-	void on_statement_inserted (int graph_id, string? graph, int subject_id, string subject, int pred_id, int object_id, string? object, PtrArray rdf_types) {
-		Tracker.Events.add_insert (graph_id, subject_id, subject, pred_id, object_id, object, rdf_types);
-		Tracker.Writeback.check (graph_id, graph, subject_id, subject, pred_id, object_id, object, rdf_types);
+	void on_statement_inserted (int graph_id, string? graph, int subject_id, string? subject, int pred_id, int object_id, string? object, PtrArray rdf_types) {
+		Tracker.Events.add_insert (graph_id, subject_id, pred_id, object_id, object, rdf_types);
+		Tracker.Writeback.check (graph_id, graph, subject_id, pred_id, object_id, object, rdf_types);
 		check_graph_updated_signal ();
 	}
 
-	void on_statement_deleted (int graph_id, string? graph, int subject_id, string subject, int pred_id, int object_id, string? object, PtrArray rdf_types) {
-		Tracker.Events.add_delete (graph_id, subject_id, subject, pred_id, object_id, object, rdf_types);
-		Tracker.Writeback.check (graph_id, graph, subject_id, subject, pred_id, object_id, object, rdf_types);
+	void on_statement_deleted (int graph_id, string? graph, int subject_id, string? subject, int pred_id, int object_id, string? object, PtrArray rdf_types) {
+		Tracker.Events.add_delete (graph_id, subject_id, pred_id, object_id, object, rdf_types);
+		Tracker.Writeback.check (graph_id, graph, subject_id, pred_id, object_id, object, rdf_types);
 		check_graph_updated_signal ();
 	}
 
diff --git a/src/tracker-store/tracker-writeback.c b/src/tracker-store/tracker-writeback.c
index bdd02d5..52bc86e 100644
--- a/src/tracker-store/tracker-writeback.c
+++ b/src/tracker-store/tracker-writeback.c
@@ -60,7 +60,6 @@ void
 tracker_writeback_check (gint         graph_id,
                          const gchar *graph,
                          gint         subject_id,
-                         const gchar *subject,
                          gint         pred_id,
                          gint         object_id,
                          const gchar *object,
diff --git a/src/tracker-store/tracker-writeback.h b/src/tracker-store/tracker-writeback.h
index 2fecdee..d03003a 100644
--- a/src/tracker-store/tracker-writeback.h
+++ b/src/tracker-store/tracker-writeback.h
@@ -34,7 +34,6 @@ void        tracker_writeback_shutdown      (void);
 void        tracker_writeback_check         (gint         graph_id,
                                              const gchar *graph,
                                              gint         subject_id,
-                                             const gchar *subject,
                                              gint         pred_id,
                                              gint         object_id,
                                              const gchar *object,
diff --git a/src/tracker-store/tracker-writeback.vapi b/src/tracker-store/tracker-writeback.vapi
index 1c50eca..4c96694 100644
--- a/src/tracker-store/tracker-writeback.vapi
+++ b/src/tracker-store/tracker-writeback.vapi
@@ -25,7 +25,7 @@ namespace Tracker {
 	namespace Writeback {
 		public void init (WritebackGetPredicatesFunc callback);
 		public void shutdown ();
-		public void check (int graph_id, string graph, int subject_id, string subject, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
+		public void check (int graph_id, string graph, int subject_id, int pred_id, int object_id, string object, GLib.PtrArray rdf_types);
 		public unowned GLib.HashTable<int, GLib.Array<int>> get_ready ();
 		public void reset_pending ();
 		public void reset_ready ();



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