[tracker/writeback] Added support for INTO and FROM to SPARQL UPDATE extension



commit 93e4d52be2572247c290c77d6a6ce026bf60b715
Author: Philip Van Hoof <philip codeminded be>
Date:   Thu Nov 5 12:45:12 2009 +0100

    Added support for INTO and FROM to SPARQL UPDATE extension
    
    This adds support for INTO and FROM to the SPARQL UPDATE extension, it doesn't
    store the uri being passed. It only passes it as parameter from to all
    functions involved. This will be used by for example the write-back feature
    that'll soon be developed.

 src/libtracker-data/libtracker-data.vapi       |   10 +-
 src/libtracker-data/tracker-data-update.c      |  256 +++++++++++++++++-------
 src/libtracker-data/tracker-data-update.h      |   66 ++++---
 src/libtracker-data/tracker-sparql-query.vala  |   28 +++-
 src/libtracker-data/tracker-turtle-reader.vala |    7 +-
 src/tracker-store/tracker-resources.c          |   30 ++--
 src/tracker-store/tracker-store.c              |   50 +-----
 src/tracker-store/tracker-store.h              |    6 -
 8 files changed, 272 insertions(+), 181 deletions(-)
---
diff --git a/src/libtracker-data/libtracker-data.vapi b/src/libtracker-data/libtracker-data.vapi
index b8e1a81..1d63b9b 100644
--- a/src/libtracker-data/libtracker-data.vapi
+++ b/src/libtracker-data/libtracker-data.vapi
@@ -30,11 +30,11 @@ namespace Tracker {
 		public int query_resource_id (string uri);
 		public void begin_transaction ();
 		public void commit_transaction ();
-		public void delete_statement (string subject, string predicate, string object) throws DataError;
-		public void insert_statement (string subject, string predicate, string object) throws DataError;
-		public void insert_statement_with_uri (string subject, string predicate, string object) throws DataError;
-		public void insert_statement_with_string (string subject, string predicate, string object) throws DataError;
-		public void delete_resource_description (string uri) throws DataError;
+		public void delete_statement (string from, string subject, string predicate, string object) throws DataError;
+		public void insert_statement (string from, string subject, string predicate, string object) throws DataError;
+		public void insert_statement_with_uri (string from, string subject, string predicate, string object) throws DataError;
+		public void insert_statement_with_string (string from, string subject, string predicate, string object) throws DataError;
+		public void delete_resource_description (string from, string uri) throws DataError;
 		public void update_buffer_flush ();
 	}
 }
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 26187c9..ca6f5c7 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -50,6 +50,8 @@ typedef struct _TrackerDataUpdateBufferPredicate TrackerDataUpdateBufferPredicat
 typedef struct _TrackerDataUpdateBufferProperty TrackerDataUpdateBufferProperty;
 typedef struct _TrackerDataUpdateBufferTable TrackerDataUpdateBufferTable;
 typedef struct _TrackerDataBlankBuffer TrackerDataBlankBuffer;
+typedef struct _TrackerStatementDelegate TrackerStatementDelegate;
+typedef struct _TrackerCommitDelegate TrackerCommitDelegate;
 
 struct _TrackerDataUpdateBuffer {
 	GHashTable *resource_cache;
@@ -93,6 +95,17 @@ struct _TrackerDataBlankBuffer {
 	gchar *subject;
 	GArray *predicates;
 	GArray *objects;
+	GArray *graphs;
+};
+
+struct _TrackerStatementDelegate {
+	TrackerStatementCallback callback;
+	gpointer user_data;
+};
+
+struct _TrackerCommitDelegate {
+	TrackerCommitCallback callback;
+	gpointer user_data;
 };
 
 static gboolean in_transaction = FALSE;
@@ -101,45 +114,73 @@ static TrackerDataUpdateBuffer update_buffer;
 static TrackerDataUpdateBufferResource *resource_buffer;
 static TrackerDataBlankBuffer blank_buffer;
 
-static TrackerStatementCallback insert_callback = NULL;
-static gpointer insert_data;
-static TrackerStatementCallback delete_callback = NULL;
-static gpointer delete_data;
-static TrackerCommitCallback commit_callback = NULL;
-static gpointer commit_data;
-static TrackerCommitCallback rollback_callback = NULL;
-static gpointer rollback_data;
+static GPtrArray *insert_callbacks = NULL;
+static GPtrArray *delete_callbacks = NULL;
+static GPtrArray *commit_callbacks = NULL;
+static GPtrArray *rollback_callbacks = NULL;
 
 void 
-tracker_data_set_commit_statement_callback (TrackerCommitCallback    callback,
+tracker_data_add_commit_statement_callback (TrackerCommitCallback    callback,
 					    gpointer                 user_data)
 {
-	commit_callback = callback;
-	commit_data = user_data;
+	TrackerCommitDelegate *delegate = g_new0 (TrackerCommitDelegate, 1);
+
+	if (!commit_callbacks) {
+		commit_callbacks = g_ptr_array_new ();
+	}
+
+	delegate->callback = callback;
+	delegate->user_data = user_data;
+
+	g_ptr_array_add (commit_callbacks, delegate);
 }
 
 void
-tracker_data_set_rollback_statement_callback (TrackerCommitCallback    callback,
+tracker_data_add_rollback_statement_callback (TrackerCommitCallback    callback,
 					      gpointer                 user_data)
 {
-	rollback_callback = callback;
-	rollback_data = user_data;
+	TrackerCommitDelegate *delegate = g_new0 (TrackerCommitDelegate, 1);
+
+	if (!rollback_callbacks) {
+		rollback_callbacks = g_ptr_array_new ();
+	}
+
+	delegate->callback = callback;
+	delegate->user_data = user_data;
+
+	g_ptr_array_add (rollback_callbacks, delegate);
 }
 
 void
-tracker_data_set_insert_statement_callback (TrackerStatementCallback callback,
+tracker_data_add_insert_statement_callback (TrackerStatementCallback callback,
 					    gpointer                 user_data)
 {
-	insert_callback = callback;
-	insert_data = user_data;
+	TrackerStatementDelegate *delegate = g_new0 (TrackerStatementDelegate, 1);
+
+	if (!insert_callbacks) {
+		insert_callbacks = g_ptr_array_new ();
+	}
+
+	delegate->callback = callback;
+	delegate->user_data = user_data;
+
+	g_ptr_array_add (insert_callbacks, delegate);
 }
 
 void 
-tracker_data_set_delete_statement_callback (TrackerStatementCallback callback,
+tracker_data_add_delete_statement_callback (TrackerStatementCallback callback,
 					    gpointer                 user_data)
 {
-	delete_callback = callback;
-	delete_data = user_data;
+	TrackerStatementDelegate *delegate = g_new0 (TrackerStatementDelegate, 1);
+
+	if (!delete_callbacks) {
+		delete_callbacks = g_ptr_array_new ();
+	}
+
+	delegate->callback = callback;
+	delegate->user_data = user_data;
+
+	g_ptr_array_add (delete_callbacks, delegate);
 }
 
 GQuark tracker_data_error_quark (void) {
@@ -592,18 +633,21 @@ tracker_data_blank_buffer_flush (void)
 		/* uri not found
 		   replay piled up statements to create resource */
 		for (i = 0; i < blank_buffer.predicates->len; i++) {
-			tracker_data_insert_statement (blank_uri,
-				g_array_index (blank_buffer.predicates, gchar *, i),
-				g_array_index (blank_buffer.objects, gchar *, i),
-				NULL);
+			tracker_data_insert_statement (g_array_index (blank_buffer.graphs, gchar *, i),
+			                               blank_uri,
+			                               g_array_index (blank_buffer.predicates, gchar *, i),
+			                               g_array_index (blank_buffer.objects, gchar *, i),
+			                               NULL);
 		}
 	}
 
 	/* free piled up statements */
 	for (i = 0; i < blank_buffer.predicates->len; i++) {
+		g_free (g_array_index (blank_buffer.graphs, gchar *, i));
 		g_free (g_array_index (blank_buffer.predicates, gchar *, i));
 		g_free (g_array_index (blank_buffer.objects, gchar *, i));
 	}
+	g_array_free (blank_buffer.graphs, TRUE);
 	g_array_free (blank_buffer.predicates, TRUE);
 	g_array_free (blank_buffer.objects, TRUE);
 
@@ -612,7 +656,8 @@ tracker_data_blank_buffer_flush (void)
 }
 
 static void
-cache_create_service_decomposed (TrackerClass           *cl)
+cache_create_service_decomposed (TrackerClass *cl,
+                                 const gchar  *graph)
 {
 	TrackerClass       **super_classes;
 	GValue              gvalue = { 0 };
@@ -622,7 +667,7 @@ cache_create_service_decomposed (TrackerClass           *cl)
 	/* also create instance of all super classes */
 	super_classes = tracker_class_get_super_classes (cl);
 	while (*super_classes) {
-		cache_create_service_decomposed (*super_classes);
+		cache_create_service_decomposed (*super_classes, graph);
 		super_classes++;
 	}
 
@@ -645,9 +690,18 @@ cache_create_service_decomposed (TrackerClass           *cl)
 	cache_insert_value ("rdfs:Resource_rdf:type", "rdf:type", &gvalue, TRUE, FALSE);
 
 	tracker_class_set_count (cl, tracker_class_get_count (cl) + 1);
-	if (insert_callback) {
-		insert_callback (resource_buffer->subject, RDF_PREFIX "type", class_uri, 
-		                 resource_buffer->types, insert_data);
+	if (insert_callbacks) {
+		guint n;
+
+		for (n = 0; n < insert_callbacks->len; n++) {
+			TrackerStatementDelegate *delegate;
+
+			delegate = g_ptr_array_index (insert_callbacks, n);
+			delegate->callback (graph, resource_buffer->subject,
+			                    RDF_PREFIX "type", class_uri, 
+			                    resource_buffer->types, 
+			                    delegate->user_data);
+		}
 	}
 }
 
@@ -1005,7 +1059,8 @@ delete_metadata_decomposed (TrackerProperty  *property,
 }
 
 static void
-cache_delete_resource_type (TrackerClass *class)
+cache_delete_resource_type (TrackerClass *class,
+                            const gchar  *graph)
 {
 	TrackerDBInterface *iface;
 	TrackerDBStatement *stmt;
@@ -1044,7 +1099,7 @@ cache_delete_resource_type (TrackerClass *class)
 			gchar *class_uri;
 
 			tracker_db_result_set_get (result_set, 0, &class_uri, -1);
-			cache_delete_resource_type (tracker_ontology_get_class_by_uri (class_uri));
+			cache_delete_resource_type (tracker_ontology_get_class_by_uri (class_uri), graph);
 			g_free (class_uri);
 		} while (tracker_db_result_set_iter_next (result_set));
 
@@ -1098,16 +1153,27 @@ cache_delete_resource_type (TrackerClass *class)
 	cache_delete_row (class);
 
 	tracker_class_set_count (class, tracker_class_get_count (class) - 1);
-	if (delete_callback) {
-		delete_callback (resource_buffer->subject, RDF_PREFIX "type", tracker_class_get_uri (class), resource_buffer->types, delete_data);
+
+	if (delete_callbacks) {
+		guint n;
+		for (n = 0; n < delete_callbacks->len; n++) {
+			TrackerStatementDelegate *delegate;
+
+			delegate = g_ptr_array_index (delete_callbacks, n);
+			delegate->callback (graph, resource_buffer->subject, 
+		                            RDF_PREFIX "type", tracker_class_get_uri (class),
+		                            resource_buffer->types, delegate->user_data);
+		}
 	}
+
 }
 
 void
-tracker_data_delete_statement (const gchar            *subject,
-			       const gchar            *predicate,
-			       const gchar            *object,
-			       GError                **error)
+tracker_data_delete_statement (const gchar  *graph,
+                               const gchar  *subject,
+                               const gchar  *predicate,
+                               const gchar  *object,
+                               GError      **error)
 {
 	TrackerClass       *class;
 	TrackerProperty    *field;
@@ -1146,7 +1212,7 @@ tracker_data_delete_statement (const gchar            *subject,
 	if (object && g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
 		class = tracker_ontology_get_class_by_uri (object);
 		if (class != NULL) {
-			cache_delete_resource_type (class);
+			cache_delete_resource_type (class, graph);
 		} else {
 			g_set_error (error, TRACKER_DATA_ERROR, TRACKER_DATA_ERROR_UNKNOWN_CLASS,
 				     "Class '%s' not found in the ontology", object);
@@ -1160,16 +1226,25 @@ tracker_data_delete_statement (const gchar            *subject,
 				     "Property '%s' not found in the ontology", predicate);
 		}
 
-		if (delete_callback) {
-			delete_callback (subject, predicate, object, resource_buffer->types, delete_data);
+		if (delete_callbacks) {
+			guint n;
+			for (n = 0; n < delete_callbacks->len; n++) {
+				TrackerStatementDelegate *delegate;
+
+				delegate = g_ptr_array_index (delete_callbacks, n);
+				delegate->callback (graph, subject, predicate, object, 
+				                    resource_buffer->types, 
+				                    delegate->user_data);
+			}
 		}
 	}
 }
 
 static gboolean
-tracker_data_insert_statement_common (const gchar            *subject,
-				      const gchar            *predicate,
-				      const gchar            *object)
+tracker_data_insert_statement_common (const gchar            *graph,
+                                      const gchar            *subject,
+                                      const gchar            *predicate,
+                                      const gchar            *object)
 {
 	if (g_str_has_prefix (subject, ":")) {
 		/* blank node definition
@@ -1186,10 +1261,13 @@ tracker_data_insert_statement_common (const gchar            *subject,
 
 		if (blank_buffer.subject == NULL) {
 			blank_buffer.subject = g_strdup (subject);
+			blank_buffer.graphs = g_array_sized_new (FALSE, FALSE, sizeof (char*), 4);
 			blank_buffer.predicates = g_array_sized_new (FALSE, FALSE, sizeof (char*), 4);
 			blank_buffer.objects = g_array_sized_new (FALSE, FALSE, sizeof (char*), 4);
 		}
 
+		value = g_strdup (graph);
+		g_array_append_val (blank_buffer.graphs, value);
 		value = g_strdup (predicate);
 		g_array_append_val (blank_buffer.predicates, value);
 		value = g_strdup (object);
@@ -1234,10 +1312,11 @@ tracker_data_insert_statement_common (const gchar            *subject,
 }
 
 void
-tracker_data_insert_statement (const gchar            *subject,
-			       const gchar            *predicate,
-			       const gchar            *object,
-			       GError                **error)
+tracker_data_insert_statement (const gchar            *graph,
+                               const gchar            *subject,
+                               const gchar            *predicate,
+                               const gchar            *object,
+                               GError                **error)
 {
 	TrackerProperty *property;
 
@@ -1249,12 +1328,12 @@ tracker_data_insert_statement (const gchar            *subject,
 	property = tracker_ontology_get_property_by_uri (predicate);
 	if (property != NULL) {
 		if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_RESOURCE) {
-			tracker_data_insert_statement_with_uri (subject, predicate, object, error);
+			tracker_data_insert_statement_with_uri (graph, subject, predicate, object, error);
 		} else {
-			tracker_data_insert_statement_with_string (subject, predicate, object, error);
+			tracker_data_insert_statement_with_string (graph, subject, predicate, object, error);
 		}
 	} else if (strcmp (predicate, TRACKER_PREFIX "uri") == 0) {
-		tracker_data_insert_statement_with_uri (subject, predicate, object, error);
+		tracker_data_insert_statement_with_uri (graph, subject, predicate, object, error);
 	} else {
 		g_set_error (error, TRACKER_DATA_ERROR, TRACKER_DATA_ERROR_UNKNOWN_PROPERTY,
 		             "Property '%s' not found in the ontology", predicate);
@@ -1262,10 +1341,11 @@ tracker_data_insert_statement (const gchar            *subject,
 }
 
 void
-tracker_data_insert_statement_with_uri (const gchar            *subject,
-					const gchar            *predicate,
-					const gchar            *object,
-					GError                **error)
+tracker_data_insert_statement_with_uri (const gchar            *graph,
+                                        const gchar            *subject,
+                                        const gchar            *predicate,
+                                        const gchar            *object,
+                                        GError                **error)
 {
 	GError          *actual_error = NULL;
 	TrackerClass    *class;
@@ -1307,7 +1387,7 @@ tracker_data_insert_statement_with_uri (const gchar            *subject,
 
 		if (blank_uri != NULL) {
 			/* now insert statement referring to blank node */
-			tracker_data_insert_statement (subject, predicate, blank_uri, error);
+			tracker_data_insert_statement (graph, subject, predicate, blank_uri, error);
 
 			g_hash_table_remove (blank_buffer.table, object);
 
@@ -1317,7 +1397,7 @@ tracker_data_insert_statement_with_uri (const gchar            *subject,
 		}
 	}
 
-	if (!tracker_data_insert_statement_common (subject, predicate, object)) {
+	if (!tracker_data_insert_statement_common (graph, subject, predicate, object)) {
 		return;
 	}
 
@@ -1326,7 +1406,7 @@ tracker_data_insert_statement_with_uri (const gchar            *subject,
 		   cope with inference and insert blank rows */
 		class = tracker_ontology_get_class_by_uri (object);
 		if (class != NULL) {
-			cache_create_service_decomposed (class);
+			cache_create_service_decomposed (class, graph);
 		} else {
 			g_set_error (error, TRACKER_DATA_ERROR, TRACKER_DATA_ERROR_UNKNOWN_CLASS,
 				     "Class '%s' not found in the ontology", object);
@@ -1343,17 +1423,26 @@ tracker_data_insert_statement_with_uri (const gchar            *subject,
 			return;
 		}
 
-		if (insert_callback) {
-			insert_callback (subject, predicate, object, resource_buffer->types, insert_data);
+		if (insert_callbacks) {
+			guint n;
+			for (n = 0; n < insert_callbacks->len; n++) {
+				TrackerStatementDelegate *delegate;
+
+				delegate = g_ptr_array_index (insert_callbacks, n);
+				delegate->callback (graph, subject, predicate, object, 
+				                    resource_buffer->types, 
+				                    delegate->user_data);
+			}
 		}
 	}
 }
 
 void
-tracker_data_insert_statement_with_string (const gchar            *subject,
-					   const gchar            *predicate,
-					   const gchar            *object,
-					   GError                **error)
+tracker_data_insert_statement_with_string (const gchar            *graph,
+                                           const gchar            *subject,
+                                           const gchar            *predicate,
+                                           const gchar            *object,
+                                           GError                **error)
 {
 	GError          *actual_error = NULL;
 	TrackerProperty *property;
@@ -1374,7 +1463,7 @@ tracker_data_insert_statement_with_string (const gchar            *subject,
 		return;
 	}
 
-	if (!tracker_data_insert_statement_common (subject, predicate, object)) {
+	if (!tracker_data_insert_statement_common (graph, subject, predicate, object)) {
 		return;
 	}
 
@@ -1386,8 +1475,16 @@ tracker_data_insert_statement_with_string (const gchar            *subject,
 		return;
 	}
 
-	if (insert_callback) {
-		insert_callback (subject, predicate, object, resource_buffer->types, insert_data);
+	if (insert_callbacks) {
+		guint n;
+		for (n = 0; n < insert_callbacks->len; n++) {
+			TrackerStatementDelegate *delegate;
+
+			delegate = g_ptr_array_index (insert_callbacks, n);
+			delegate->callback (graph, subject, predicate, object, 
+					    resource_buffer->types, 
+					    delegate->user_data);
+		}
 	}
 }
 
@@ -1644,8 +1741,13 @@ tracker_data_commit_transaction (void)
 	g_hash_table_unref (update_buffer.resources);
 	g_hash_table_unref (update_buffer.resource_cache);
 
-	if (commit_callback) {
-		commit_callback (commit_data);
+	if (commit_callbacks) {
+		guint n;
+		for (n = 0; n < commit_callbacks->len; n++) {
+			TrackerCommitDelegate *delegate;
+			delegate = g_ptr_array_index (commit_callbacks, n);
+			delegate->callback (delegate->user_data);
+		}
 	}
 }
 
@@ -1678,7 +1780,9 @@ format_sql_value_as_string (GString         *sql,
  * annotations (non-embedded/user metadata) stored about the resource.
  */
 void
-tracker_data_delete_resource_description (const gchar *uri, GError **error)
+tracker_data_delete_resource_description (const gchar *graph, 
+                                          const gchar *uri, 
+                                          GError **error)
 {
 	TrackerDBInterface *iface;
 	TrackerDBStatement *stmt;
@@ -1776,7 +1880,8 @@ tracker_data_delete_resource_description (const gchar *uri, GError **error)
 					tracker_db_result_set_get (single_result, i++, &value, -1);
 
 					if (value) {
-						tracker_data_delete_statement (uri, 
+						
+						tracker_data_delete_statement (graph, uri, 
 						                               tracker_property_get_uri (*property), 
 						                               value, 
 						                               error);
@@ -1806,7 +1911,7 @@ tracker_data_delete_resource_description (const gchar *uri, GError **error)
 
 							tracker_db_result_set_get (multi_result, 0, &value, -1);
 
-							tracker_data_delete_statement (uri, 
+							tracker_data_delete_statement (graph, uri, 
 							                               tracker_property_get_uri (*property), 
 							                               value,
 							                               NULL);
@@ -1854,8 +1959,13 @@ tracker_data_update_sparql (const gchar  *update,
 		tracker_data_update_buffer_clear ();
 		tracker_db_interface_execute_query (iface, NULL, "ROLLBACK TO sparql");
 
-		if (rollback_callback) {
-			rollback_callback (commit_data);
+		if (rollback_callbacks) {
+			guint n;
+			for (n = 0; n < rollback_callbacks->len; n++) {
+				TrackerCommitDelegate *delegate;
+				delegate = g_ptr_array_index (rollback_callbacks, n);
+				delegate->callback (delegate->user_data);
+			}
 		}
 	}
 
diff --git a/src/libtracker-data/tracker-data-update.h b/src/libtracker-data/tracker-data-update.h
index d373709..67c535a 100644
--- a/src/libtracker-data/tracker-data-update.h
+++ b/src/libtracker-data/tracker-data-update.h
@@ -43,34 +43,40 @@ typedef enum  {
 	TRACKER_DATA_ERROR_CONSTRAINT
 } TrackerDataError;
 
-typedef void (*TrackerStatementCallback) (const gchar *subject, 
-					  const gchar *predicate, 
-					  const gchar *object,
-					  GPtrArray   *rdf_types,
-					  gpointer     user_data);
+typedef void (*TrackerStatementCallback) (const gchar *graph,
+                                          const gchar *subject, 
+                                          const gchar *predicate, 
+                                          const gchar *object,
+                                          GPtrArray   *rdf_types,
+                                          gpointer     user_data);
 typedef void (*TrackerCommitCallback)    (gpointer     user_data);
 
 GQuark   tracker_data_error_quark                   (void);
 
 /* Metadata */
-void     tracker_data_delete_resource_description   (const gchar               *uri,
+void     tracker_data_delete_resource_description   (const gchar               *graph,
+                                                     const gchar               *uri,
+                                                     GError                   **error);
+void     tracker_data_delete_statement              (const gchar               *graph,
+                                                     const gchar               *subject,
+                                                     const gchar               *predicate,
+                                                     const gchar               *object,
+                                                     GError                   **error);
+void     tracker_data_insert_statement              (const gchar               *graph,
+                                                     const gchar               *subject,
+                                                     const gchar               *predicate,
+                                                     const gchar               *object,
+                                                     GError                   **error);
+void     tracker_data_insert_statement_with_uri     (const gchar               *graph,
+                                                     const gchar               *subject,
+                                                     const gchar               *predicate,
+                                                     const gchar               *object,
+                                                     GError                   **error);
+void     tracker_data_insert_statement_with_string  (const gchar               *graph,
+                                                     const gchar               *subject,
+                                                     const gchar               *predicate,
+                                                     const gchar               *object,
                                                      GError                   **error);
-void     tracker_data_delete_statement              (const gchar               *subject,
-						     const gchar               *predicate,
-						     const gchar               *object,
-						     GError                   **error);
-void     tracker_data_insert_statement              (const gchar               *subject,
-						     const gchar               *predicate,
-						     const gchar               *object,
-						     GError                   **error);
-void     tracker_data_insert_statement_with_uri     (const gchar               *subject,
-						     const gchar               *predicate,
-						     const gchar               *object,
-						     GError                   **error);
-void     tracker_data_insert_statement_with_string  (const gchar               *subject,
-						     const gchar               *predicate,
-						     const gchar               *object,
-						     GError                   **error);
 void     tracker_data_begin_transaction             (void);
 void     tracker_data_commit_transaction            (void);
 void     tracker_data_update_sparql                 (const gchar               *update,
@@ -85,14 +91,14 @@ void     tracker_data_update_disable_all_volumes    (void);
 void     tracker_data_update_reset_volume           (const gchar               *uri);
 
 /* Calling back */
-void     tracker_data_set_insert_statement_callback (TrackerStatementCallback   callback,
-						     gpointer                   user_data);
-void     tracker_data_set_delete_statement_callback (TrackerStatementCallback   callback,
-						     gpointer                   user_data);
-void     tracker_data_set_commit_statement_callback (TrackerCommitCallback      callback,
-						     gpointer                   user_data);
-void     tracker_data_set_rollback_statement_callback (TrackerCommitCallback      callback,
-						       gpointer                   user_data);
+void     tracker_data_add_insert_statement_callback   (TrackerStatementCallback   callback,
+                                                       gpointer                   user_data);
+void     tracker_data_add_delete_statement_callback   (TrackerStatementCallback   callback,
+                                                       gpointer                   user_data);
+void     tracker_data_add_commit_statement_callback   (TrackerCommitCallback      callback,
+                                                       gpointer                   user_data);
+void     tracker_data_add_rollback_statement_callback (TrackerCommitCallback      callback,
+                                                       gpointer                   user_data);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-sparql-query.vala b/src/libtracker-data/tracker-sparql-query.vala
index 8fa8779..255ecc2 100644
--- a/src/libtracker-data/tracker-sparql-query.vala
+++ b/src/libtracker-data/tracker-sparql-query.vala
@@ -233,6 +233,7 @@ public class Tracker.SparqlQuery : Object {
 	string query_string;
 	bool update_extensions;
 
+	string current_graph;
 	string current_subject;
 	bool current_subject_is_var;
 	string current_predicate;
@@ -784,13 +785,34 @@ public class Tracker.SparqlQuery : Object {
 		return exec_sql (sql.str);
 	}
 
+	private void parse_from_or_into_param () throws Error {
+		if (accept (SparqlTokenType.IRI_REF)) {
+			current_graph = get_last_string (1);
+		} else if (accept (SparqlTokenType.PN_PREFIX)) {
+			string ns = get_last_string ();
+			expect (SparqlTokenType.COLON);
+			current_graph = resolve_prefixed_name (ns, get_last_string ().substring (1));
+		} else {
+			expect (SparqlTokenType.COLON);
+			current_graph = resolve_prefixed_name ("", get_last_string ().substring (1));
+		}
+	}
+
 	void execute_insert () throws Error {
 		expect (SparqlTokenType.INSERT);
+		if (accept (SparqlTokenType.INTO)) {
+			parse_from_or_into_param ();
+		} else
+			current_graph = null;
 		execute_update (false);
 	}
 
 	void execute_delete () throws Error {
 		expect (SparqlTokenType.DELETE);
+		if (accept (SparqlTokenType.FROM)) {
+			parse_from_or_into_param ();
+		} else
+			current_graph = null;
 		execute_update (true);
 	}
 
@@ -871,7 +893,7 @@ public class Tracker.SparqlQuery : Object {
 		bool is_var;
 		string uri = parse_var_or_term (null, out is_var);
 
-		Data.delete_resource_description (uri);
+		Data.delete_resource_description (uri, uri);
 
 		// ensure possible WHERE clause in next part gets the correct results
 		Data.update_buffer_flush ();
@@ -1854,10 +1876,10 @@ public class Tracker.SparqlQuery : Object {
 		string object = parse_construct_var_or_term (var_value_map);
 		if (delete_statements) {
 			// delete triple from database
-			Data.delete_statement (current_subject, current_predicate, object);
+			Data.delete_statement (current_graph, current_subject, current_predicate, object);
 		} else {
 			// insert triple into database
-			Data.insert_statement (current_subject, current_predicate, object);
+			Data.insert_statement (current_graph, current_subject, current_predicate, object);
 		}
 	}
 
diff --git a/src/libtracker-data/tracker-turtle-reader.vala b/src/libtracker-data/tracker-turtle-reader.vala
index f04cca5..d0a52e9 100644
--- a/src/libtracker-data/tracker-turtle-reader.vala
+++ b/src/libtracker-data/tracker-turtle-reader.vala
@@ -45,6 +45,9 @@ public class Tracker.TurtleReader : Object {
 
 	State state;
 
+	// todo: support non-default graph with ntrig files
+	public string from { get; private set; }
+
 	public string subject { get; private set; }
 	public string predicate { get; private set; }
 	public string object { get; private set; }
@@ -366,9 +369,9 @@ public class Tracker.TurtleReader : Object {
 		var reader = new TurtleReader (path);
 		while (reader.next ()) {
 			if (reader.object_is_uri) {
-				Data.insert_statement_with_uri (reader.subject, reader.predicate, reader.object);
+				Data.insert_statement_with_uri (reader.from, reader.subject, reader.predicate, reader.object);
 			} else {
-				Data.insert_statement_with_string (reader.subject, reader.predicate, reader.object);
+				Data.insert_statement_with_string (reader.from, reader.subject, reader.predicate, reader.object);
 			}
 		}
 	}
diff --git a/src/tracker-store/tracker-resources.c b/src/tracker-store/tracker-resources.c
index bbb14c0..3d43c63 100644
--- a/src/tracker-store/tracker-resources.c
+++ b/src/tracker-store/tracker-resources.c
@@ -409,11 +409,12 @@ on_statements_rolled_back (gpointer user_data)
 }
 
 static void
-on_statement_inserted (const gchar *subject,
-		       const gchar *predicate,
-		       const gchar *object,
-		       GPtrArray   *rdf_types,
-		       gpointer user_data)
+on_statement_inserted (const gchar *from,
+                       const gchar *subject,
+                       const gchar *predicate,
+                       const gchar *object,
+                       GPtrArray   *rdf_types,
+                       gpointer user_data)
 {
 	if (g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
 		tracker_events_insert (subject, predicate, object, rdf_types, TRACKER_DBUS_EVENTS_TYPE_ADD);
@@ -423,11 +424,12 @@ on_statement_inserted (const gchar *subject,
 }
 
 static void
-on_statement_deleted (const gchar *subject,
-		      const gchar *predicate,
-		      const gchar *object,
-		      GPtrArray   *rdf_types,
-		      gpointer user_data)
+on_statement_deleted (const gchar *from,
+                      const gchar *subject,
+                      const gchar *predicate,
+                      const gchar *object,
+                      GPtrArray   *rdf_types,
+                      gpointer user_data)
 {
 	if (g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
 		tracker_events_insert (subject, predicate, object, rdf_types, TRACKER_DBUS_EVENTS_TYPE_DELETE);
@@ -447,10 +449,10 @@ tracker_resources_prepare (TrackerResources *object,
 
 	free_event_sources (priv);
 
-	tracker_data_set_insert_statement_callback (on_statement_inserted, object);
-	tracker_data_set_delete_statement_callback (on_statement_deleted, object);
-	tracker_data_set_commit_statement_callback (on_statements_committed, object);
-	tracker_data_set_rollback_statement_callback (on_statements_rolled_back, object);
+	tracker_data_add_insert_statement_callback (on_statement_inserted, object);
+	tracker_data_add_delete_statement_callback (on_statement_deleted, object);
+	tracker_data_add_commit_statement_callback (on_statements_committed, object);
+	tracker_data_add_rollback_statement_callback (on_statements_rolled_back, object);
 
 	priv->event_sources = event_sources;
 }
diff --git a/src/tracker-store/tracker-store.c b/src/tracker-store/tracker-store.c
index c9bb9c7..34327e1 100644
--- a/src/tracker-store/tracker-store.c
+++ b/src/tracker-store/tracker-store.c
@@ -113,12 +113,14 @@ process_turtle_file_part (TrackerTurtleReader *reader, GError **error)
 		/* insert statement */
 		if (tracker_turtle_reader_get_object_is_uri (reader)) {
 			tracker_data_insert_statement_with_uri (
+				tracker_turtle_reader_get_from (reader),
 				tracker_turtle_reader_get_subject (reader),
 				tracker_turtle_reader_get_predicate (reader),
 				tracker_turtle_reader_get_object (reader),
 				&new_error);
 		} else {
 			tracker_data_insert_statement_with_string (
+				tracker_turtle_reader_get_from (reader),
 				tracker_turtle_reader_get_subject (reader),
 				tracker_turtle_reader_get_predicate (reader),
 				tracker_turtle_reader_get_object (reader),
@@ -541,54 +543,6 @@ tracker_store_sparql_query (const gchar *sparql,
 	return tracker_data_query_sparql (sparql, error);
 }
 
-void
-tracker_store_insert_statement (const gchar   *subject,
-                                const gchar   *predicate,
-                                const gchar   *object)
-{
-	TrackerStorePrivate *private;
-
-	g_return_if_fail (subject != NULL);
-	g_return_if_fail (predicate != NULL);
-	g_return_if_fail (object != NULL);
-
-	private = g_static_private_get (&private_key);
-	g_return_if_fail (private != NULL);
-
-	if (private->batch_mode) {
-		/* commit pending batch items */
-		tracker_data_commit_transaction ();
-		private->batch_mode = FALSE;
-		private->batch_count = 0;
-	}
-
-	tracker_data_insert_statement (subject, predicate, object, NULL);
-}
-
-void
-tracker_store_delete_statement (const gchar   *subject,
-                                const gchar   *predicate,
-                                const gchar   *object)
-{
-	TrackerStorePrivate *private;
-
-	g_return_if_fail (subject != NULL);
-	g_return_if_fail (predicate != NULL);
-	g_return_if_fail (object != NULL);
-
-	private = g_static_private_get (&private_key);
-	g_return_if_fail (private != NULL);
-
-	if (private->batch_mode) {
-		/* commit pending batch items */
-		tracker_data_commit_transaction ();
-		private->batch_mode = FALSE;
-		private->batch_count = 0;
-	}
-
-	tracker_data_delete_statement (subject, predicate, object, NULL);
-}
-
 guint
 tracker_store_get_queue_size (void)
 {
diff --git a/src/tracker-store/tracker-store.h b/src/tracker-store/tracker-store.h
index 3ed3e3d..a495800 100644
--- a/src/tracker-store/tracker-store.h
+++ b/src/tracker-store/tracker-store.h
@@ -53,12 +53,6 @@ void         tracker_store_queue_turtle_import    (GFile         *file,
                                                    GDestroyNotify destroy);
 void         tracker_store_sparql_update          (const gchar   *sparql,
                                                    GError       **error);
-void         tracker_store_insert_statement       (const gchar   *subject,
-                                                   const gchar   *predicate,
-                                                   const gchar   *object);
-void         tracker_store_delete_statement       (const gchar   *subject,
-                                                   const gchar   *predicate,
-                                                   const gchar   *object);
 TrackerDBResultSet*
              tracker_store_sparql_query           (const gchar   *sparql,
                                                    GError       **error);



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