[tracker/ontology-cope: 4/5] libtracker-common, libtracker-data: Added ontology validation check



commit e827442b8ce59944403fef7064f1f3af6f4886a9
Author: Philip Van Hoof <philip codeminded be>
Date:   Tue Feb 16 17:31:11 2010 +0100

    libtracker-common, libtracker-data: Added ontology validation check

 src/libtracker-common/tracker-ontology.c   |   30 ++--
 src/libtracker-common/tracker-ontology.h   |    4 +-
 src/libtracker-data/tracker-data-manager.c |  252 +++++++++++++++++++++++-----
 3 files changed, 221 insertions(+), 65 deletions(-)
---
diff --git a/src/libtracker-common/tracker-ontology.c b/src/libtracker-common/tracker-ontology.c
index e388fdf..d7c9f28 100644
--- a/src/libtracker-common/tracker-ontology.c
+++ b/src/libtracker-common/tracker-ontology.c
@@ -34,7 +34,7 @@ typedef struct _TrackerOntologyPriv TrackerOntologyPriv;
 
 struct _TrackerOntologyPriv {
 	gchar *uri;
-	gchar *last_modified;
+	time_t last_modified;
 };
 
 static void ontology_finalize     (GObject      *object);
@@ -71,12 +71,15 @@ tracker_ontology_class_init (TrackerOntologyClass *klass)
 	                                                      "URI",
 	                                                      NULL,
 	                                                      G_PARAM_READWRITE));
+
 	g_object_class_install_property (object_class,
 	                                 PROP_LAST_MODIFIED,
-	                                 g_param_spec_string ("last-modified",
+	                                 g_param_spec_int64  ("last-modified",
 	                                                      "last-modified",
 	                                                      "Last modified",
-	                                                      NULL,
+	                                                      G_MININT64,
+	                                                      G_MAXINT64,
+	                                                      0,
 	                                                      G_PARAM_READWRITE));
 
 	g_type_class_add_private (object_class, sizeof (TrackerOntologyPriv));
@@ -95,7 +98,6 @@ ontology_finalize (GObject *object)
 	priv = GET_PRIV (object);
 
 	g_free (priv->uri);
-	g_free (priv->last_modified);
 
 	(G_OBJECT_CLASS (tracker_ontology_parent_class)->finalize) (object);
 }
@@ -115,7 +117,7 @@ ontology_get_property (GObject    *object,
 		g_value_set_string (value, priv->uri);
 		break;
 	case PROP_LAST_MODIFIED:
-		g_value_set_string (value, priv->last_modified);
+		g_value_set_int64 (value, priv->last_modified);
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -140,7 +142,7 @@ ontology_set_property (GObject      *object,
 		break;
 	case PROP_LAST_MODIFIED:
 		tracker_ontology_set_last_modified (TRACKER_ONTOLOGY (object),
-		                                    g_value_get_string (value));
+		                                    g_value_get_int64 (value));
 		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
@@ -158,22 +160,22 @@ tracker_ontology_new (void)
 	return ontology;
 }
 
-const gchar *
+time_t
 tracker_ontology_get_last_modified (TrackerOntology *ontology)
 {
 	TrackerOntologyPriv *priv;
 
-	g_return_val_if_fail (TRACKER_IS_ONTOLOGY (ontology), NULL);
+	g_return_val_if_fail (TRACKER_IS_ONTOLOGY (ontology), 0);
 
 	priv = GET_PRIV (ontology);
 
-	return priv->last_modified;
+	return (gint64) priv->last_modified;
 }
 
 
 void
 tracker_ontology_set_last_modified (TrackerOntology *ontology,
-                                    const gchar    *value)
+                                    time_t           value)
 {
 	TrackerOntologyPriv *priv;
 
@@ -181,13 +183,7 @@ tracker_ontology_set_last_modified (TrackerOntology *ontology,
 
 	priv = GET_PRIV (ontology);
 
-	g_free (priv->last_modified);
-
-	if (value) {
-		priv->last_modified = g_strdup (value);
-	} else {
-		priv->last_modified = NULL;
-	}
+	priv->last_modified = (gint64) value;
 
 	g_object_notify (G_OBJECT (ontology), "last-modified");
 }
diff --git a/src/libtracker-common/tracker-ontology.h b/src/libtracker-common/tracker-ontology.h
index 29c00be..a81ee8c 100644
--- a/src/libtracker-common/tracker-ontology.h
+++ b/src/libtracker-common/tracker-ontology.h
@@ -50,9 +50,9 @@ struct _TrackerOntologyClass {
 
 GType             tracker_ontology_get_type          (void) G_GNUC_CONST;
 TrackerOntology  *tracker_ontology_new               (void);
-const gchar *     tracker_ontology_get_last_modified (TrackerOntology *ontology);
+time_t            tracker_ontology_get_last_modified (TrackerOntology *ontology);
 void              tracker_ontology_set_last_modified (TrackerOntology *ontology,
-                                                      const gchar      *value);
+                                                      time_t           value);
 const gchar *     tracker_ontology_get_uri           (TrackerOntology *ontology);
 void              tracker_ontology_set_uri           (TrackerOntology *ontology,
                                                       const gchar      *value);
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index c16c396..8c27cbe 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -293,7 +293,7 @@ load_ontology_statement (const gchar *ontology_file,
 			return;
 		}
 
-		tracker_ontology_set_last_modified (ontology, object);
+		tracker_ontology_set_last_modified (ontology, tracker_string_to_date (object));
 	}
 
 }
@@ -330,6 +330,78 @@ load_ontology_file_from_path (const gchar        *ontology_file,
 	}
 }
 
+
+static TrackerOntology*
+get_ontology_from_file (const gchar *ontology_file)
+{
+	TrackerTurtleReader *reader;
+	GError              *error = NULL;
+	GHashTable          *ontology_uris;
+	TrackerOntology     *ret = NULL;
+
+	reader = tracker_turtle_reader_new (ontology_file, &error);
+	if (error) {
+		g_critical ("Turtle parse error: %s", error->message);
+		g_error_free (error);
+		return NULL;
+	}
+
+	ontology_uris = g_hash_table_new_full (g_str_hash,
+	                                       g_str_equal,
+	                                       g_free,
+	                                       g_object_unref);
+
+	while (error == NULL && tracker_turtle_reader_next (reader, &error)) {
+		const gchar *subject, *predicate, *object;
+
+		subject = tracker_turtle_reader_get_subject (reader);
+		predicate = tracker_turtle_reader_get_predicate (reader);
+		object = tracker_turtle_reader_get_object (reader);
+
+		if (g_strcmp0 (predicate, RDF_TYPE) == 0) {
+			if (g_strcmp0 (object, TRACKER_PREFIX "Ontology") == 0) {
+				TrackerOntology *ontology;
+
+				if (tracker_ontologies_get_ontology_by_uri (subject) != NULL) {
+					g_critical ("%s: Duplicate definition of ontology %s", ontology_file, subject);
+					return NULL;
+				}
+
+				ontology = tracker_ontology_new ();
+				tracker_ontology_set_uri (ontology, subject);
+
+				g_hash_table_insert (ontology_uris,
+				                     g_strdup (subject),
+				                     g_object_ref (ontology));
+
+				g_object_unref (ontology);
+			}
+		} else if (g_strcmp0 (predicate, NAO_LAST_MODIFIED) == 0) {
+			TrackerOntology *ontology;
+
+			ontology = g_hash_table_lookup (ontology_uris, subject);
+			if (ontology == NULL) {
+				g_critical ("%s: Unknown ontology %s", ontology_file, subject);
+				return NULL;
+			}
+
+			tracker_ontology_set_last_modified (ontology, tracker_string_to_date (object));
+			ret = g_object_ref (ontology);
+			break;
+		}
+	}
+
+	g_hash_table_unref (ontology_uris);
+	g_object_unref (reader);
+
+	if (error) {
+		g_critical ("Turtle parse error: %s", error->message);
+		g_error_free (error);
+	}
+
+	return ret;
+}
+
 static void
 load_ontology_file (const gchar               *filename,
                     gint                      *max_id)
@@ -1031,13 +1103,52 @@ import_ontology_into_db (void)
 	}
 }
 
+static GList*
+get_ontologies (gboolean test_schema, const gchar *ontologies_dir)
+{
+	GList *sorted = NULL;
+
+	if (test_schema) {
+		sorted = g_list_prepend (sorted, g_strdup ("12-nrl.ontology"));
+		sorted = g_list_prepend (sorted, g_strdup ("11-rdf.ontology"));
+		sorted = g_list_prepend (sorted, g_strdup ("10-xsd.ontology"));
+	} else {
+		GDir        *ontologies;
+		const gchar *conf_file;
+
+		ontologies = g_dir_open (ontologies_dir, 0, NULL);
+
+		conf_file = g_dir_read_name (ontologies);
+
+		/* .ontology files */
+		while (conf_file) {
+			if (g_str_has_suffix (conf_file, ".ontology")) {
+				sorted = g_list_insert_sorted (sorted,
+				                               g_strdup (conf_file),
+				                               (GCompareFunc) strcmp);
+			}
+			conf_file = g_dir_read_name (ontologies);
+		}
+
+		g_dir_close (ontologies);
+	}
+
+	return sorted;
+}
+
+
 gboolean
 tracker_data_manager_init (TrackerDBManagerFlags  flags,
                            const gchar           *test_schema,
                            gboolean              *first_time)
 {
 	TrackerDBInterface *iface;
-	gboolean is_first_time_index, read_journal;
+	gboolean is_first_time_index, read_journal, check_ontology;
+	TrackerDBCursor *cursor;
+	TrackerDBStatement *stmt;
+	GHashTable *ontos_table;
+	GList *sorted = NULL, *l;
+	const gchar *env_path;
 
 	/* First set defaults for return values */
 	if (first_time) {
@@ -1070,6 +1181,17 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 		}
 	}
 
+	env_path = g_getenv ("TRACKER_DB_ONTOLOGIES_DIR");
+
+	if (G_LIKELY (!env_path)) {
+		ontologies_dir = g_build_filename (SHAREDIR,
+		                                   "tracker",
+		                                   "ontologies",
+		                                   NULL);
+	} else {
+		ontologies_dir = g_strdup (env_path);
+	}
+
 	if (read_journal) {
 		in_journal_replay = TRUE;
 
@@ -1088,51 +1210,13 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		/* open journal for writing */
 		tracker_db_journal_init (NULL);
+		check_ontology = TRUE;
 	} else if (is_first_time_index) {
 		gint max_id = 0;
-		GList *sorted = NULL, *l;
-		gchar *test_schema_path = NULL;
-		const gchar *env_path;
 		GError *error = NULL;
+		gchar *test_schema_path = NULL;
 
-		env_path = g_getenv ("TRACKER_DB_ONTOLOGIES_DIR");
-
-		if (G_LIKELY (!env_path)) {
-			ontologies_dir = g_build_filename (SHAREDIR,
-			                                   "tracker",
-			                                   "ontologies",
-			                                   NULL);
-		} else {
-			ontologies_dir = g_strdup (env_path);
-		}
-
-		if (test_schema) {
-			/* load test schema, not used in normal operation */
-			test_schema_path = g_strconcat (test_schema, ".ontology", NULL);
-
-			sorted = g_list_prepend (sorted, g_strdup ("12-nrl.ontology"));
-			sorted = g_list_prepend (sorted, g_strdup ("11-rdf.ontology"));
-			sorted = g_list_prepend (sorted, g_strdup ("10-xsd.ontology"));
-		} else {
-			GDir        *ontologies;
-			const gchar *conf_file;
-
-			ontologies = g_dir_open (ontologies_dir, 0, NULL);
-
-			conf_file = g_dir_read_name (ontologies);
-
-			/* .ontology files */
-			while (conf_file) {
-				if (g_str_has_suffix (conf_file, ".ontology")) {
-					sorted = g_list_insert_sorted (sorted,
-					                               g_strdup (conf_file),
-					                               (GCompareFunc) strcmp);
-				}
-				conf_file = g_dir_read_name (ontologies);
-			}
-
-			g_dir_close (ontologies);
-		}
+		sorted = get_ontologies (test_schema != NULL, ontologies_dir);
 
 		tracker_db_journal_init (NULL);
 
@@ -1172,15 +1256,89 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		g_list_foreach (sorted, (GFunc) g_free, NULL);
 		g_list_free (sorted);
-
-		g_free (ontologies_dir);
-		ontologies_dir = NULL;
+		sorted = NULL;
+		check_ontology = FALSE;
 	} else {
 		tracker_db_journal_init (NULL);
 
 		/* load ontology from database into memory */
 		db_get_static_data (iface);
 		create_decomposed_transient_metadata_tables (iface);
+		check_ontology = TRUE;
+	}
+
+	if (check_ontology) {
+		sorted = get_ontologies (test_schema != NULL, ontologies_dir);
+
+		/* check ontology against database */
+		tracker_data_begin_transaction ();
+
+		stmt = tracker_db_interface_create_statement (iface,
+		        "SELECT Resource.Uri, \"rdfs:Resource\".\"nao:lastModified\" FROM \"tracker:Ontology\""
+		        "INNER JOIN Resource ON Resource.ID = \"tracker:Ontology\".ID "
+		        "INNER JOIN \"rdfs:Resource\" ON \"tracker:Ontology\".ID = \"rdfs:Resource\".ID");
+
+		cursor = tracker_db_statement_start_cursor (stmt, NULL);
+		g_object_unref (stmt);
+
+
+		ontos_table = g_hash_table_new_full (g_str_hash,
+		                                     g_str_equal,
+		                                     g_free,
+		                                     NULL);
+
+		while (tracker_db_cursor_iter_next (cursor)) {
+			const gchar *onto_uri = tracker_db_cursor_get_string (cursor, 0);
+			/* It's stored as an int in the db anyway. This is caused by 
+			 * string_to_gvalue in tracker-data-update.c */
+			gint value = tracker_db_cursor_get_int (cursor, 1);
+
+			g_hash_table_insert (ontos_table, g_strdup (onto_uri), 
+			                     GINT_TO_POINTER (value));
+		}
+
+		g_object_unref (cursor);
+
+		for (l = sorted; l; l = l->next) {
+			TrackerOntology *ontology;
+			gchar *ontology_file;
+			gboolean found;
+			gpointer value;
+
+			ontology_file = g_build_filename (ontologies_dir, l->data, NULL);
+			ontology = get_ontology_from_file (ontology_file);
+
+			if (!ontology) {
+				g_critical ("Can't get ontology from file: %s", ontology_file);
+				g_free (l->data);
+				g_free (ontology_file);
+				continue;
+			}
+
+			found = g_hash_table_lookup_extended (ontos_table, 
+			                                      tracker_ontology_get_uri (ontology),
+			                                      NULL, &value);
+
+			if (found) {
+				gint val = GPOINTER_TO_INT (value);
+				/* We can't do better than this cast, it's stored as an int in the
+				 * db. See above comment for more info. */
+				if (val != (gint) tracker_ontology_get_last_modified (ontology)) {
+					g_print ("%s NOT up to date\n", ontology_file);
+				} else {
+					g_print ("%s up to date\n", ontology_file);
+				}
+			}
+
+			g_free (ontology_file);
+			g_object_unref (ontology);
+			g_free (l->data);
+		}
+
+		tracker_data_commit_transaction ();
+
+		g_hash_table_unref (ontos_table);
+		g_list_free (sorted);
 	}
 
 	/* ensure FTS is fully initialized */
@@ -1188,6 +1346,8 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 	initialized = TRUE;
 
+	g_free (ontologies_dir);
+
 	return TRUE;
 }
 



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