[tracker/rss-enclosures] libtracker-data: Detect removal of a rdfs:subClassOf in ontology and cope



commit af132d28e714e553e268359bffef71a1dd0b6b33
Author: Philip Van Hoof <philip codeminded be>
Date:   Thu Nov 11 10:51:48 2010 +0100

    libtracker-data: Detect removal of a rdfs:subClassOf in ontology and cope
    
    Fixes NB#203632

 src/libtracker-data/tracker-class.c        |   33 ++++++++++-
 src/libtracker-data/tracker-class.h        |    2 +
 src/libtracker-data/tracker-data-manager.c |   85 ++++++++++++++++++++++++++-
 3 files changed, 115 insertions(+), 5 deletions(-)
---
diff --git a/src/libtracker-data/tracker-class.c b/src/libtracker-data/tracker-class.c
index 7486032..59d24fb 100644
--- a/src/libtracker-data/tracker-class.c
+++ b/src/libtracker-data/tracker-class.c
@@ -44,6 +44,7 @@ struct _TrackerClassPrivate {
 	GArray *super_classes;
 	GArray *domain_indexes;
 	GArray *last_domain_indexes;
+	GArray *last_super_classes;
 
 	struct {
 		struct {
@@ -92,6 +93,7 @@ tracker_class_init (TrackerClass *service)
 	priv->super_classes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
 	priv->domain_indexes = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
 	priv->last_domain_indexes = NULL;
+	priv->last_super_classes = NULL;
 
 	priv->deletes.pending.sub_pred_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
 	priv->deletes.pending.obj_graph_ids = g_array_new (FALSE, FALSE, sizeof (gint64));
@@ -130,9 +132,13 @@ class_finalize (GObject *object)
 	g_array_free (priv->inserts.ready.sub_pred_ids, TRUE);
 	g_array_free (priv->inserts.ready.obj_graph_ids, TRUE);
 
-	if (priv->last_domain_indexes)
+	if (priv->last_domain_indexes) {
 		g_array_free (priv->last_domain_indexes, TRUE);
+	}
 
+	if (priv->last_super_classes) {
+		g_array_free (priv->last_super_classes, TRUE);
+	}
 
 	(G_OBJECT_CLASS (tracker_class_parent_class)->finalize) (object);
 }
@@ -232,6 +238,18 @@ tracker_class_get_last_domain_indexes (TrackerClass *service)
 	return (TrackerProperty **) (priv->last_domain_indexes ? priv->last_domain_indexes->data : NULL);
 }
 
+TrackerClass **
+tracker_class_get_last_super_classes (TrackerClass *service)
+{
+	TrackerClassPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CLASS (service), NULL);
+
+	priv = GET_PRIV (service);
+
+	return (TrackerClass **) (priv->last_super_classes ? priv->last_super_classes->data : NULL);
+}
+
 gboolean
 tracker_class_get_is_new (TrackerClass *service)
 {
@@ -351,6 +369,19 @@ tracker_class_add_super_class (TrackerClass *service,
 }
 
 void
+tracker_class_reset_super_classes (TrackerClass *service)
+{
+	TrackerClassPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_CLASS (service));
+
+	priv = GET_PRIV (service);
+
+	priv->last_super_classes = priv->super_classes;
+	priv->super_classes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
+}
+
+void
 tracker_class_add_domain_index (TrackerClass *service,
                                 TrackerProperty *value)
 {
diff --git a/src/libtracker-data/tracker-class.h b/src/libtracker-data/tracker-class.h
index 2b4d5c1..118dddf 100644
--- a/src/libtracker-data/tracker-class.h
+++ b/src/libtracker-data/tracker-class.h
@@ -69,6 +69,7 @@ gboolean          tracker_class_get_notify             (TrackerClass        *ser
 TrackerClass    **tracker_class_get_super_classes      (TrackerClass        *service);
 TrackerProperty **tracker_class_get_domain_indexes     (TrackerClass        *service);
 TrackerProperty **tracker_class_get_last_domain_indexes(TrackerClass        *service);
+TrackerClass    **tracker_class_get_last_super_classes (TrackerClass        *service);
 
 void              tracker_class_set_uri                (TrackerClass        *service,
                                                         const gchar         *value);
@@ -81,6 +82,7 @@ void              tracker_class_add_domain_index       (TrackerClass        *ser
 void              tracker_class_del_domain_index       (TrackerClass        *service,
                                                         TrackerProperty     *value);
 void              tracker_class_reset_domain_indexes   (TrackerClass        *service);
+void              tracker_class_reset_super_classes   (TrackerClass        *service);
 void              tracker_class_set_id                 (TrackerClass        *service,
                                                         gint                 id);
 void              tracker_class_set_is_new             (TrackerClass        *service,
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 9fc7da8..07d6f73 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -551,6 +551,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 						}
 					}
 					tracker_class_reset_domain_indexes (class);
+					tracker_class_reset_super_classes (class);
 					tracker_class_set_notify (class, FALSE);
 				}
 				return;
@@ -669,10 +670,11 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 
 		is_new = tracker_class_get_is_new (class);
 		if (is_new != in_update) {
+			gboolean ignore = FALSE;
 			/* Detect unsupported ontology change (this needs a journal replay) */
-			if (in_update == TRUE && is_new == FALSE) {
+			if (in_update == TRUE && is_new == FALSE && g_strcmp0 (object, RDFS_PREFIX "Resource") != 0) {
 				TrackerClass **super_classes = tracker_class_get_super_classes (class);
-				gboolean found = FALSE;
+				gboolean had = FALSE;
 
 				super_class = tracker_ontologies_get_class_by_uri (object);
 				if (super_class == NULL) {
@@ -682,19 +684,31 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 
 				while (*super_classes) {
 					if (*super_classes == super_class) {
-						found = TRUE;
+						ignore = TRUE;
+						g_debug ("%s: Class %s already has rdfs:subClassOf in %s",
+						         ontology_path, object, subject);
 						break;
 					}
 					super_classes++;
 				}
 
+				super_classes = tracker_class_get_last_super_classes (class);
+				if (super_classes) {
+					while (*super_classes) {
+						if (super_class == *super_classes) {
+							had = TRUE;
+						}
+						super_classes++;
+					}
+				}
+
 				/* This doesn't detect removed rdfs:subClassOf situations, it
 				 * only checks whether no new ones are being added. For 
 				 * detecting the removal of a rdfs:subClassOf, please check the
 				 * tracker_data_ontology_process_changes_pre_db stuff */
 
 
-				if (found == FALSE) {
+				if (!ignore && !had) {
 					handle_unsupported_ontology_change (ontology_path,
 					                                    tracker_class_get_name (class),
 					                                    "rdfs:subClassOf",
@@ -704,6 +718,11 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 				}
 			}
 
+			if (!ignore) {
+				super_class = tracker_ontologies_get_class_by_uri (object);
+				tracker_class_add_super_class (class, super_class);
+			}
+
 			return;
 		}
 
@@ -714,6 +733,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 		}
 
 		tracker_class_add_super_class (class, super_class);
+
 	} else if (g_strcmp0 (predicate, TRACKER_PREFIX "notify") == 0) {
 		TrackerClass *class;
 
@@ -1278,6 +1298,55 @@ check_for_deleted_domain_index (TrackerClass *class)
 }
 
 static void
+check_for_deleted_super_classes (TrackerClass  *class,
+                                 GError       **error)
+{
+	TrackerClass **last_super_classes;
+
+	last_super_classes = tracker_class_get_last_super_classes (class);
+
+	if (!last_super_classes) {
+		return;
+	}
+
+	while (*last_super_classes) {
+		TrackerClass *last_super_class = *last_super_classes;
+		gboolean found = FALSE;
+		TrackerClass **super_classes;
+
+		if (g_strcmp0 (tracker_class_get_uri (last_super_class), RDFS_PREFIX "Resource") == 0) {
+			last_super_classes++;
+			continue;
+		}
+
+		super_classes = tracker_class_get_super_classes (class);
+
+		while (*super_classes) {
+			TrackerClass *super_class = *super_classes;
+
+			if (last_super_class == super_class) {
+				found = TRUE;
+				break;
+			}
+			super_classes++;
+		}
+
+		if (!found) {
+			const gchar *ontology_path = "Unknown";
+			const gchar *subject = tracker_class_get_uri (class);
+
+			handle_unsupported_ontology_change (ontology_path,
+			                                    subject,
+			                                    "rdfs:subClassOf", "-", "-",
+			                                    error);
+			return;
+		}
+
+		last_super_classes++;
+	}
+}
+
+static void
 tracker_data_ontology_process_changes_pre_db (GPtrArray  *seen_classes,
                                               GPtrArray  *seen_properties,
                                               GError    **error)
@@ -1285,8 +1354,16 @@ tracker_data_ontology_process_changes_pre_db (GPtrArray  *seen_classes,
 	gint i;
 	if (seen_classes) {
 		for (i = 0; i < seen_classes->len; i++) {
+			GError *n_error = NULL;
 			TrackerClass *class = g_ptr_array_index (seen_classes, i);
+
 			check_for_deleted_domain_index (class);
+			check_for_deleted_super_classes (class, &n_error);
+
+			if (n_error) {
+				g_propagate_error (error, n_error);
+				return;
+			}
 		}
 	}
 



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