[tracker/ontology-cope: 2/11] libtracker-data: Coping with modest ontology changes in journal replay



commit 16f99fea8d221ab8d93c409bef0ac64d1afa8f76
Author: Philip Van Hoof <philip codeminded be>
Date:   Thu Mar 18 18:33:49 2010 +0100

    libtracker-data: Coping with modest ontology changes in journal replay

 src/libtracker-data/tracker-data-manager.c |  247 +++++++++++++++-------------
 src/libtracker-data/tracker-data-manager.h |   17 ++
 src/libtracker-data/tracker-data-update.c  |  229 ++++++++++++++++++++++++--
 3 files changed, 368 insertions(+), 125 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index e85aa1a..f812e47 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -73,16 +73,16 @@ static gchar              *ontologies_dir;
 static gboolean            initialized;
 static gboolean            in_journal_replay;
 
-static void
-load_ontology_statement (const gchar *ontology_file,
-                         gint         subject_id,
-                         const gchar *subject,
-                         const gchar *predicate,
-                         const gchar *object,
-                         gint        *max_id,
-                         gboolean    is_new,
-                         GHashTable *classes,
-                         GHashTable *properties)
+void
+tracker_data_ontology_load_statement (const gchar *ontology_file,
+                                      gint         subject_id,
+                                      const gchar *subject,
+                                      const gchar *predicate,
+                                      const gchar *object,
+                                      gint        *max_id,
+                                      gboolean    is_new,
+                                      GHashTable *classes,
+                                      GHashTable *properties)
 {
 	if (g_strcmp0 (predicate, RDF_TYPE) == 0) {
 		if (g_strcmp0 (object, RDFS_CLASS) == 0) {
@@ -406,8 +406,8 @@ load_ontology_file_from_path (const gchar        *ontology_file,
 		predicate = tracker_turtle_reader_get_predicate (reader);
 		object = tracker_turtle_reader_get_object (reader);
 
-		load_ontology_statement (ontology_file, 0, subject, predicate, object,
-		                         max_id, is_new, NULL, NULL);
+		tracker_data_ontology_load_statement (ontology_file, 0, subject, predicate, object,
+		                                      max_id, is_new, NULL, NULL);
 	}
 
 	g_object_unref (reader);
@@ -553,8 +553,8 @@ load_ontology_from_journal (GHashTable **classes_out,
 			subject = g_hash_table_lookup (id_uri_map, GINT_TO_POINTER (subject_id));
 			predicate = g_hash_table_lookup (id_uri_map, GINT_TO_POINTER (predicate_id));
 
-			load_ontology_statement ("journal", subject_id, subject, predicate, 
-			                         object, NULL, FALSE, classes, properties);
+			tracker_data_ontology_load_statement ("journal", subject_id, subject, predicate, 
+			                                      object, NULL, FALSE, classes, properties);
 		}
 	}
 
@@ -564,133 +564,149 @@ load_ontology_from_journal (GHashTable **classes_out,
 	g_hash_table_unref (id_uri_map);
 }
 
-
-static void
-load_turtle_file (const gchar* path,
-                  gboolean is_new,
-                  gboolean ignore_nao_last_modified)
+void
+tracker_data_ontology_process_statement (const gchar *graph,
+                                         const gchar *subject,
+                                         const gchar *predicate,
+                                         const gchar *object,
+                                         gboolean     is_uri,
+                                         gboolean     is_new,
+                                         gboolean     ignore_nao_last_modified)
 {
 	GError *error = NULL;
-	TrackerTurtleReader* reader;
-
-	reader = tracker_turtle_reader_new (path, &error);
-
-	if (error != NULL) {
-		g_critical ("%s", error->message);
-		g_error_free (error);
-		return;
-	}
-
-	while (tracker_turtle_reader_next (reader, &error)) {
-
-		const gchar *graph = tracker_turtle_reader_get_graph (reader);
-		const gchar *subject = tracker_turtle_reader_get_subject (reader);
-		const gchar *predicate = tracker_turtle_reader_get_predicate (reader);
-		const gchar *object  = tracker_turtle_reader_get_object (reader);
-
-		if (g_strcmp0 (predicate, RDF_TYPE) == 0) {
-			if (g_strcmp0 (object, RDFS_CLASS) == 0) {
-				TrackerClass *class;
-
-				class = tracker_ontologies_get_class_by_uri (subject);
-
-				if (class && tracker_class_get_is_new (class) != is_new) {
-					continue;
-				}
-			} else if (g_strcmp0 (object, RDF_PROPERTY) == 0) {
-				TrackerProperty *prop;
-
-				prop = tracker_ontologies_get_property_by_uri (subject);
 
-				if (prop && tracker_property_get_is_new (prop) != is_new) {
-					continue;
-				}
-			} else if (g_strcmp0 (object, TRACKER_PREFIX "Namespace") == 0) {
-				TrackerNamespace *namespace;
-
-				namespace = tracker_ontologies_get_namespace_by_uri (subject);
-
-				if (namespace && tracker_namespace_get_is_new (namespace) != is_new) {
-					continue;
-				}
-			} else if (g_strcmp0 (object, TRACKER_PREFIX "Ontology") == 0) {
-				TrackerOntology *ontology;
-
-				ontology = tracker_ontologies_get_ontology_by_uri (subject);
-
-				if (ontology && tracker_ontology_get_is_new (ontology) != is_new) {
-					continue;
-				}
-			}
-		} else if (g_strcmp0 (predicate, RDFS_SUB_CLASS_OF) == 0) {
+	if (g_strcmp0 (predicate, RDF_TYPE) == 0) {
+		if (g_strcmp0 (object, RDFS_CLASS) == 0) {
 			TrackerClass *class;
 
 			class = tracker_ontologies_get_class_by_uri (subject);
 
 			if (class && tracker_class_get_is_new (class) != is_new) {
-				continue;
+				return;
 			}
-		} else if (g_strcmp0 (predicate, RDFS_SUB_PROPERTY_OF) == 0          ||
-		           g_strcmp0 (predicate, RDFS_DOMAIN) == 0                   ||
-		           g_strcmp0 (predicate, RDFS_RANGE) == 0                    ||
-		           g_strcmp0 (predicate, NRL_MAX_CARDINALITY) == 0           ||
-		           g_strcmp0 (predicate, TRACKER_PREFIX "indexed") == 0      ||
-		           g_strcmp0 (predicate, TRACKER_PREFIX "transient") == 0    ||
-		           g_strcmp0 (predicate, TRACKER_PREFIX "isAnnotation") == 0 ||
-		           g_strcmp0 (predicate, TRACKER_PREFIX "fulltextIndexed") == 0) {
+		} else if (g_strcmp0 (object, RDF_PROPERTY) == 0) {
 			TrackerProperty *prop;
 
 			prop = tracker_ontologies_get_property_by_uri (subject);
 
 			if (prop && tracker_property_get_is_new (prop) != is_new) {
-				continue;
+				return;
 			}
-		} else if (g_strcmp0 (predicate, TRACKER_PREFIX "prefix") == 0) {
+		} else if (g_strcmp0 (object, TRACKER_PREFIX "Namespace") == 0) {
 			TrackerNamespace *namespace;
 
 			namespace = tracker_ontologies_get_namespace_by_uri (subject);
 
 			if (namespace && tracker_namespace_get_is_new (namespace) != is_new) {
-				continue;
+				return;
 			}
-		} else if (g_strcmp0 (predicate, NAO_LAST_MODIFIED) == 0) {
+		} else if (g_strcmp0 (object, TRACKER_PREFIX "Ontology") == 0) {
 			TrackerOntology *ontology;
 
 			ontology = tracker_ontologies_get_ontology_by_uri (subject);
 
 			if (ontology && tracker_ontology_get_is_new (ontology) != is_new) {
-				continue;
+				return;
 			}
+		}
+	} else if (g_strcmp0 (predicate, RDFS_SUB_CLASS_OF) == 0) {
+		TrackerClass *class;
 
-			if (ignore_nao_last_modified) {
-				continue;
-			}
+		class = tracker_ontologies_get_class_by_uri (subject);
+
+		if (class && tracker_class_get_is_new (class) != is_new) {
+			return;
 		}
+	} else if (g_strcmp0 (predicate, RDFS_SUB_PROPERTY_OF) == 0          ||
+	           g_strcmp0 (predicate, RDFS_DOMAIN) == 0                   ||
+	           g_strcmp0 (predicate, RDFS_RANGE) == 0                    ||
+	           g_strcmp0 (predicate, NRL_MAX_CARDINALITY) == 0           ||
+	           g_strcmp0 (predicate, TRACKER_PREFIX "indexed") == 0      ||
+	           g_strcmp0 (predicate, TRACKER_PREFIX "transient") == 0    ||
+	           g_strcmp0 (predicate, TRACKER_PREFIX "isAnnotation") == 0 ||
+	           g_strcmp0 (predicate, TRACKER_PREFIX "fulltextIndexed") == 0) {
+		TrackerProperty *prop;
+
+		prop = tracker_ontologies_get_property_by_uri (subject);
+
+		if (prop && tracker_property_get_is_new (prop) != is_new) {
+			return;
+		}
+	} else if (g_strcmp0 (predicate, TRACKER_PREFIX "prefix") == 0) {
+		TrackerNamespace *namespace;
 
-		if (tracker_turtle_reader_get_object_is_uri (reader)) {
-			tracker_data_insert_statement_with_uri (graph, subject,
-			                                        predicate, object,
-			                                        &error);
+		namespace = tracker_ontologies_get_namespace_by_uri (subject);
 
-			if (error != NULL) {
-				g_critical ("%s", error->message);
-				g_error_free (error);
-				return;
-			}
+		if (namespace && tracker_namespace_get_is_new (namespace) != is_new) {
+			return;
+		}
+	} else if (g_strcmp0 (predicate, NAO_LAST_MODIFIED) == 0) {
+		TrackerOntology *ontology;
 
-		} else {
-			tracker_data_insert_statement_with_string (graph, subject,
-			                                           predicate, object,
-			                                           &error);
+		ontology = tracker_ontologies_get_ontology_by_uri (subject);
 
-			if (error != NULL) {
-				g_critical ("%s", error->message);
-				g_error_free (error);
-				return;
-			}
+		if (ontology && tracker_ontology_get_is_new (ontology) != is_new) {
+			return;
+		}
+
+		if (ignore_nao_last_modified) {
+			return;
 		}
 	}
 
+	if (is_uri) {
+		tracker_data_insert_statement_with_uri (graph, subject,
+												predicate, object,
+												&error);
+
+		if (error != NULL) {
+			g_critical ("%s", error->message);
+			g_error_free (error);
+			return;
+		}
+
+	} else {
+		tracker_data_insert_statement_with_string (graph, subject,
+												   predicate, object,
+												   &error);
+
+		if (error != NULL) {
+			g_critical ("%s", error->message);
+			g_error_free (error);
+			return;
+		}
+	}
+}
+
+static void
+load_turtle_file (const gchar* path,
+                  gboolean is_new,
+                  gboolean ignore_nao_last_modified)
+{
+	GError *error = NULL;
+	TrackerTurtleReader* reader;
+
+	reader = tracker_turtle_reader_new (path, &error);
+
+	if (error != NULL) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	while (tracker_turtle_reader_next (reader, &error)) {
+
+		const gchar *graph = tracker_turtle_reader_get_graph (reader);
+		const gchar *subject = tracker_turtle_reader_get_subject (reader);
+		const gchar *predicate = tracker_turtle_reader_get_predicate (reader);
+		const gchar *object  = tracker_turtle_reader_get_object (reader);
+
+		tracker_data_ontology_process_statement (graph, subject, predicate, object,
+		                                         tracker_turtle_reader_get_object_is_uri (reader),
+		                                         is_new, ignore_nao_last_modified);
+
+	}
+
 	g_object_unref (reader);
 }
 
@@ -1330,8 +1346,8 @@ create_decomposed_transient_metadata_tables (TrackerDBInterface *iface)
 	}
 }
 
-static void
-import_ontology_into_db (gboolean is_new)
+void
+tracker_data_ontology_import_into_db (gboolean is_new)
 {
 	TrackerDBInterface *iface;
 
@@ -1350,20 +1366,22 @@ import_ontology_into_db (gboolean is_new)
 		create_decomposed_metadata_tables (iface, classes[i], is_new);
 	}
 
-	/* insert classes into rdfs:Resource table */
+	/* insert classes into rdfs:Resource table and set all classes to not new */
 	for (i = 0; i < n_classes; i++) {
 		if (tracker_class_get_is_new (classes[i]) == is_new) {
 			insert_uri_in_resource_table (iface, tracker_class_get_uri (classes[i]),
 			                              tracker_class_get_id (classes[i]));
 		}
+		tracker_class_set_is_new (classes[i], FALSE);
 	}
 
-	/* insert properties into rdfs:Resource table */
+	/* insert properties into rdfs:Resource table and set all properties to not new */
 	for (i = 0; i < n_props; i++) {
 		if (tracker_property_get_is_new (properties[i]) == is_new) {
 			insert_uri_in_resource_table (iface, tracker_property_get_uri (properties[i]),
 			                              tracker_property_get_id (properties[i]));
 		}
+		tracker_property_set_is_new (properties[i], FALSE);
 	}
 }
 
@@ -1507,7 +1525,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		tracker_data_begin_db_transaction_for_replay (tracker_db_journal_reader_get_time ());
 		tracker_db_interface_sqlite_fts_init (TRACKER_DB_INTERFACE_SQLITE (iface), TRUE);
-		import_ontology_into_db (FALSE);
+		tracker_data_ontology_import_into_db (FALSE);
 		tracker_data_commit_db_transaction ();
 
 		tracker_db_journal_reader_shutdown ();
@@ -1518,6 +1536,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		/* open journal for writing */
 		tracker_db_journal_init (NULL, FALSE);
+
 		check_ontology = TRUE;
 
 		g_hash_table_unref (classes);
@@ -1547,10 +1566,11 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 		}
 
 		tracker_data_begin_db_transaction ();
+		/* Not an ontology transaction: this is the first ontology */
 		tracker_db_journal_start_transaction (time (NULL));
 
 		tracker_db_interface_sqlite_fts_init (TRACKER_DB_INTERFACE_SQLITE (iface), TRUE);
-		import_ontology_into_db (FALSE);
+		tracker_data_ontology_import_into_db (FALSE);
 
 		/* store ontology in database */
 		for (l = sorted; l; l = l->next) {
@@ -1586,6 +1606,8 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		/* check ontology against database */
 		tracker_data_begin_db_transaction ();
+		/* This _is_ an ontology transaction, it represents a change to the ontology */
+		tracker_db_journal_start_ontology_transaction (time (NULL));
 
 		stmt = tracker_db_interface_create_statement (iface,
 		        "SELECT Resource.Uri, \"rdfs:Resource\".\"nao:lastModified\" FROM \"tracker:Ontology\""
@@ -1672,7 +1694,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 		}
 
 		if (to_reload) {
-			import_ontology_into_db (TRUE);
+			tracker_data_ontology_import_into_db (TRUE);
 			for (l = to_reload; l; l = l->next) {
 				const gchar *ontology_file = l->data;
 				import_ontology_file (ontology_file, TRUE, test_schema != NULL);
@@ -1680,6 +1702,7 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 			g_list_free (to_reload);
 		}
 
+		tracker_db_journal_commit_db_transaction ();
 		tracker_data_commit_db_transaction ();
 
 		g_hash_table_unref (ontos_table);
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index 5be4eb2..7b89b4f 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -45,6 +45,23 @@ void     tracker_data_manager_shutdown            (void);
 gint64   tracker_data_manager_get_db_option_int64 (const gchar           *option);
 void     tracker_data_manager_set_db_option_int64 (const gchar           *option,
                                                    gint64                 value);
+void     tracker_data_ontology_load_statement     (const gchar           *ontology_file,
+                                                   gint                   subject_id,
+                                                   const gchar           *subject,
+                                                   const gchar           *predicate,
+                                                   const gchar           *object,
+                                                   gint                  *max_id,
+                                                   gboolean               is_new,
+                                                   GHashTable            *classes,
+                                                   GHashTable            *properties);
+void     tracker_data_ontology_import_into_db     (gboolean               is_new);
+void     tracker_data_ontology_process_statement  (const gchar           *graph,
+                                                   const gchar           *subject,
+                                                   const gchar           *predicate,
+                                                   const gchar           *object,
+                                                   gboolean               is_uri,
+                                                   gboolean               is_new,
+                                                   gboolean               ignore_nao_last_modified);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index cf023f9..3fec0c1 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -46,6 +46,11 @@
 #define RDF_PREFIX TRACKER_RDF_PREFIX
 #define RDFS_PREFIX TRACKER_RDFS_PREFIX
 #define TRACKER_PREFIX TRACKER_TRACKER_PREFIX
+#define NAO_PREFIX TRACKER_NAO_PREFIX
+#define NAO_LAST_MODIFIED NAO_PREFIX "lastModified"
+#define RDF_PREFIX TRACKER_RDF_PREFIX
+#define RDF_PROPERTY RDF_PREFIX "Property"
+#define RDF_TYPE RDF_PREFIX "type"
 
 typedef struct _TrackerDataUpdateBuffer TrackerDataUpdateBuffer;
 typedef struct _TrackerDataUpdateBufferResource TrackerDataUpdateBufferResource;
@@ -124,6 +129,14 @@ struct _TrackerCommitDelegate {
 	gpointer user_data;
 };
 
+typedef struct {
+	gchar *graph;
+	gchar *subject;
+	gchar *predicate;
+	gchar *object;
+	gboolean is_uri;
+} QueuedStatement;
+
 static gboolean in_transaction = FALSE;
 static gboolean in_journal_replay = FALSE;
 static TrackerDataUpdateBuffer update_buffer;
@@ -2220,6 +2233,147 @@ tracker_data_sync (void)
 	tracker_db_journal_fsync ();
 }
 
+static gchar *
+query_resource_by_id (gint id)
+{
+	TrackerDBCursor *cursor;
+	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
+	gchar *uri;
+
+	g_return_val_if_fail (id > 0, NULL);
+
+	iface = tracker_db_manager_get_db_interface ();
+
+	stmt = tracker_db_interface_create_statement (iface,
+	                                              "SELECT Uri FROM Resource WHERE ID = ?");
+	tracker_db_statement_bind_int (stmt, 0, id);
+	cursor = tracker_db_statement_start_cursor (stmt, NULL);
+	g_object_unref (stmt);
+
+	tracker_db_cursor_iter_next (cursor);
+	uri = g_strdup (tracker_db_cursor_get_string (cursor, 0));
+	g_object_unref (cursor);
+
+	return uri;
+}
+static void
+free_queued_statement (QueuedStatement *queued)
+{
+	g_free (queued->subject);
+	g_free (queued->predicate);
+	g_free (queued->object);
+	g_free (queued->graph);
+	g_free (queued);
+}
+
+static GList*
+queue_statement (GList *queue, 
+                 const gchar *graph,
+                 const gchar *subject,
+                 const gchar *predicate,
+                 const gchar *object,
+                 gboolean     is_uri)
+{
+	QueuedStatement *queued = g_new (QueuedStatement, 1);
+
+	queued->subject = g_strdup (subject);
+	queued->predicate = g_strdup (predicate);
+	queued->object = g_strdup (object);
+	queued->is_uri = is_uri;
+	queued->graph = graph ? g_strdup (graph) : NULL;
+
+	queue = g_list_append (queue, queued);
+
+	return queue;
+}
+
+static void
+ontology_transaction_end (GList *ontology_queue)
+{
+	GList *l;
+	const gchar *ontology_uri = NULL;
+
+	tracker_data_ontology_import_into_db (TRUE);
+
+	for (l = ontology_queue; l; l = l->next) {
+		QueuedStatement *queued = ontology_queue->data;
+
+		if (g_strcmp0 (queued->predicate, RDF_TYPE) == 0) {
+			if (g_strcmp0 (queued->object, TRACKER_PREFIX "Ontology") == 0) {
+				ontology_uri = queued->subject;
+			}
+		}
+
+		tracker_data_ontology_process_statement (queued->graph,
+		                                         queued->subject, 
+		                                         queued->predicate, 
+		                                         queued->object, 
+		                                         queued->is_uri, 
+		                                         FALSE, TRUE);
+
+	}
+
+	if (ontology_uri) {
+		TrackerOntology *ontology;
+		ontology = tracker_ontologies_get_ontology_by_uri (ontology_uri);
+		if (ontology) {
+			gint last_mod = 0;
+			TrackerDBInterface *iface;
+			TrackerDBStatement *stmt;
+
+			iface = tracker_db_manager_get_db_interface ();
+
+			/* We can't do better than this cast, it's stored as an int in the
+			 * db. See tracker-data-manager.c for more info. */
+			last_mod = (gint) tracker_ontology_get_last_modified (ontology);
+
+			stmt = tracker_db_interface_create_statement (iface,
+			        "UPDATE \"rdfs:Resource\" SET \"nao:lastModified\"= ? "
+			        "WHERE \"rdfs:Resource\".ID = "
+			        "(SELECT Resource.ID FROM Resource INNER JOIN \"rdfs:Resource\" "
+			        "ON \"rdfs:Resource\".ID = Resource.ID WHERE "
+			        "Resource.Uri = ?)");
+
+			tracker_db_statement_bind_int (stmt, 0, last_mod);
+			tracker_db_statement_bind_text (stmt, 1, ontology_uri);
+			tracker_db_statement_execute (stmt, NULL);
+		}
+	}
+}
+
+static GList*
+ontology_statement_insert (GList       *ontology_queue,
+                           gint         graph_id,
+                           gint         subject_id,
+                           gint         predicate_id,
+                           const gchar *object,
+                           GHashTable  *classes,
+                           GHashTable  *properties)
+{
+	gchar *graph, *subject, *predicate;
+
+	if (graph_id > 0) {
+		graph = query_resource_by_id (graph_id);
+	} else {
+		graph = NULL;
+	}
+
+	subject = query_resource_by_id (subject_id);
+	predicate = query_resource_by_id (predicate_id);
+
+	tracker_data_ontology_load_statement ("journal", subject_id, subject, predicate, 
+	                                      object, NULL, FALSE, classes, properties);
+
+	ontology_queue = queue_statement (ontology_queue, graph, subject, predicate, object, FALSE);
+
+	g_free (graph);
+	g_free (subject);
+	g_free (predicate);
+
+	return ontology_queue;
+}
+
 void
 tracker_data_replay_journal (GHashTable *classes,
                              GHashTable *properties)
@@ -2227,6 +2381,8 @@ tracker_data_replay_journal (GHashTable *classes,
 	GError *journal_error = NULL;
 	static TrackerProperty *rdf_type = NULL;
 	gint last_operation_type = 0;
+	gboolean in_ontology = FALSE;
+	GList *ontology_queue = NULL;
 
 	tracker_data_begin_db_transaction_for_replay (0);
 
@@ -2253,6 +2409,10 @@ tracker_data_replay_journal (GHashTable *classes,
 
 			tracker_db_journal_reader_get_resource (&id, &uri);
 
+			if (in_ontology) {
+				continue;
+			}
+
 			class = g_hash_table_lookup (classes, GINT_TO_POINTER (id));
 			if (!class)
 				property = g_hash_table_lookup (properties, GINT_TO_POINTER (id));
@@ -2276,19 +2436,42 @@ tracker_data_replay_journal (GHashTable *classes,
 				g_error_free (new_error);
 			}
 
+		} else if (type == TRACKER_DB_JOURNAL_START_ONTOLOGY_TRANSACTION) {
+			in_ontology = TRUE;
 		} else if (type == TRACKER_DB_JOURNAL_START_TRANSACTION) {
 			resource_time = tracker_db_journal_reader_get_time ();
 		} else if (type == TRACKER_DB_JOURNAL_END_TRANSACTION) {
-			GError *new_error = NULL;
-			tracker_data_update_buffer_might_flush (&new_error);
-			if (new_error) {
-				g_warning ("Journal replay error: '%s'", new_error->message);
-				g_clear_error (&new_error);
+			if (in_ontology) {
+				ontology_transaction_end (ontology_queue);
+				g_list_foreach (ontology_queue, (GFunc) free_queued_statement, NULL);
+				g_list_free (ontology_queue);
+				ontology_queue = NULL;
+				in_ontology = FALSE;
+			} else {
+				GError *new_error = NULL;
+				tracker_data_update_buffer_might_flush (&new_error);
+				if (new_error) {
+					g_warning ("Journal replay error: '%s'", new_error->message);
+					g_clear_error (&new_error);
+				}
 			}
 		} else if (type == TRACKER_DB_JOURNAL_INSERT_STATEMENT) {
 			GError *new_error = NULL;
 			TrackerProperty *property;
 
+			tracker_db_journal_reader_get_statement (&graph_id, &subject_id, &predicate_id, &object);
+
+			if (in_ontology) {
+				ontology_queue = ontology_statement_insert (ontology_queue,
+				                                            graph_id,
+				                                            subject_id,
+				                                            predicate_id,
+				                                            object,
+				                                            classes,
+				                                            properties);
+				continue;
+			}
+
 			if (last_operation_type == -1) {
 				tracker_data_update_buffer_flush (&new_error);
 				if (new_error) {
@@ -2298,8 +2481,6 @@ tracker_data_replay_journal (GHashTable *classes,
 			}
 			last_operation_type = 1;
 
-			tracker_db_journal_reader_get_statement (&graph_id, &subject_id, &predicate_id, &object);
-
 			property = g_hash_table_lookup (properties, GINT_TO_POINTER (predicate_id));
 
 			if (property) {
@@ -2321,6 +2502,22 @@ tracker_data_replay_journal (GHashTable *classes,
 			TrackerClass *class = NULL;
 			TrackerProperty *property;
 
+			tracker_db_journal_reader_get_statement_id (&graph_id, &subject_id, &predicate_id, &object_id);
+
+			if (in_ontology) {
+				gchar *object_n;
+				object_n = query_resource_by_id (object_id);
+				ontology_queue = ontology_statement_insert (ontology_queue,
+				                                            graph_id,
+				                                            subject_id,
+				                                            predicate_id,
+				                                            object_n,
+				                                            classes,
+				                                            properties);
+				g_free (object_n);
+				continue;
+			}
+
 			if (last_operation_type == -1) {
 				tracker_data_update_buffer_flush (&new_error);
 				if (new_error) {
@@ -2330,8 +2527,6 @@ tracker_data_replay_journal (GHashTable *classes,
 			}
 			last_operation_type = 1;
 
-			tracker_db_journal_reader_get_statement_id (&graph_id, &subject_id, &predicate_id, &object_id);
-
 			property = g_hash_table_lookup (properties, GINT_TO_POINTER (predicate_id));
 
 			if (property) {
@@ -2368,6 +2563,12 @@ tracker_data_replay_journal (GHashTable *classes,
 			GError *new_error = NULL;
 			TrackerProperty *property;
 
+			tracker_db_journal_reader_get_statement (&graph_id, &subject_id, &predicate_id, &object);
+
+			if (in_ontology) {
+				continue;
+			}
+
 			if (last_operation_type == 1) {
 				tracker_data_update_buffer_flush (&new_error);
 				if (new_error) {
@@ -2377,8 +2578,6 @@ tracker_data_replay_journal (GHashTable *classes,
 			}
 			last_operation_type = -1;
 
-			tracker_db_journal_reader_get_statement (&graph_id, &subject_id, &predicate_id, &object);
-
 			resource_buffer_switch (NULL, graph_id, NULL, subject_id);
 
 			property = g_hash_table_lookup (properties, GINT_TO_POINTER (predicate_id));
@@ -2413,6 +2612,12 @@ tracker_data_replay_journal (GHashTable *classes,
 			TrackerClass *class = NULL;
 			TrackerProperty *property;
 
+			tracker_db_journal_reader_get_statement_id (&graph_id, &subject_id, &predicate_id, &object_id);
+
+			if (in_ontology) {
+				continue;
+			}
+
 			if (last_operation_type == 1) {
 				tracker_data_update_buffer_flush (&new_error);
 				if (new_error) {
@@ -2422,8 +2627,6 @@ tracker_data_replay_journal (GHashTable *classes,
 			}
 			last_operation_type = -1;
 
-			tracker_db_journal_reader_get_statement_id (&graph_id, &subject_id, &predicate_id, &object_id);
-
 			property = g_hash_table_lookup (properties, GINT_TO_POINTER (predicate_id));
 
 			if (property) {



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