[tracker/tracker-0.10] libtracker-data: Detect unsupported ontology change rdfs:subPropertyOf



commit b9b9ecfa9cf63756098971fcde645af301dc4a4a
Author: Philip Van Hoof <philip codeminded be>
Date:   Tue Sep 13 11:46:18 2011 +0200

    libtracker-data: Detect unsupported ontology change rdfs:subPropertyOf

 src/libtracker-data/tracker-data-manager.c |   84 ++++++++++++++++++++++++++-
 src/libtracker-data/tracker-property.c     |   37 ++++++++++++
 src/libtracker-data/tracker-property.h     |    7 ++-
 3 files changed, 122 insertions(+), 6 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 8ac0eaf..020c56c 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -624,6 +624,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 					/* Reset for a correct post and pre-check */
 					tracker_property_set_last_multiple_values (property, TRUE);
 					tracker_property_reset_domain_indexes (property);
+					tracker_property_reset_super_properties (property);
 					tracker_property_set_indexed (property, FALSE);
 					tracker_property_set_secondary_index (property, NULL);
 					tracker_property_set_writeback (property, FALSE);
@@ -901,10 +902,11 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 
 		is_new = tracker_property_get_is_new (property);
 		if (is_new != in_update) {
+			gboolean ignore = FALSE;
 			/* Detect unsupported ontology change (this needs a journal replay) */
 			if (in_update == TRUE && is_new == FALSE) {
 				TrackerProperty **super_properties = tracker_property_get_super_properties (property);
-				gboolean found = FALSE;
+				gboolean had = FALSE;
 
 				super_property = tracker_ontologies_get_property_by_uri (object);
 				if (super_property == NULL) {
@@ -914,16 +916,30 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 
 				while (*super_properties) {
 					if (*super_properties == super_property) {
-						found = TRUE;
+						ignore = TRUE;
+						g_debug ("%s: Property %s already has rdfs:subPropertyOf in %s",
+						         ontology_path, object, subject);
 						break;
 					}
 					super_properties++;
 				}
 
+				super_properties = tracker_property_get_last_super_properties (property);
+				if (super_properties) {
+					while (*super_properties) {
+						if (super_property == *super_properties) {
+							had = TRUE;
+						}
+						super_properties++;
+					}
+				}
+
 				/* This doesn't detect removed rdfs:subPropertyOf situations, it
-				 * only checks whether no new ones are being added */
+				 * only checks whether no new ones are being added. For
+				 * detecting the removal of a rdfs:subPropertyOf, please check the
+				 * tracker_data_ontology_process_changes_pre_db stuff */
 
-				if (found == FALSE) {
+				if (!ignore && !had) {
 					handle_unsupported_ontology_change (ontology_path,
 					                                    tracker_property_get_name (property),
 					                                    "rdfs:subPropertyOf",
@@ -932,6 +948,12 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 					                                    error);
 				}
 			}
+
+			if (!ignore) {
+				super_property = tracker_ontologies_get_property_by_uri (object);
+				tracker_property_add_super_property (property, super_property);
+			}
+
 			return;
 		}
 
@@ -1365,6 +1387,51 @@ check_for_deleted_super_classes (TrackerClass  *class,
 	}
 }
 
+
+static void
+check_for_deleted_super_properties (TrackerProperty  *property,
+                                    GError          **error)
+{
+	TrackerProperty **last_super_properties;
+
+	last_super_properties = tracker_property_get_last_super_properties (property);
+
+	if (!last_super_properties) {
+		return;
+	}
+
+	while (*last_super_properties) {
+		TrackerProperty *last_super_property = *last_super_properties;
+		gboolean found = FALSE;
+		TrackerProperty **super_properties;
+
+		super_properties = tracker_property_get_super_properties (property);
+
+		while (*super_properties) {
+			TrackerProperty *super_property = *super_properties;
+
+			if (last_super_property == super_property) {
+				found = TRUE;
+				break;
+			}
+			super_properties++;
+		}
+
+		if (!found) {
+			const gchar *ontology_path = "Unknown";
+			const gchar *subject = tracker_property_get_uri (property);
+
+			handle_unsupported_ontology_change (ontology_path,
+			                                    subject,
+			                                    "rdfs:subPropertyOf", "-", "-",
+			                                    error);
+			return;
+		}
+
+		last_super_properties++;
+	}
+}
+
 static void
 tracker_data_ontology_process_changes_pre_db (GPtrArray  *seen_classes,
                                               GPtrArray  *seen_properties,
@@ -1388,9 +1455,18 @@ tracker_data_ontology_process_changes_pre_db (GPtrArray  *seen_classes,
 
 	if (seen_properties) {
 		for (i = 0; i < seen_properties->len; i++) {
+			GError *n_error = NULL;
+
 			TrackerProperty *property = g_ptr_array_index (seen_properties, i);
 			gboolean last_multiple_values = tracker_property_get_last_multiple_values (property);
 
+			check_for_deleted_super_properties (property, &n_error);
+
+			if (n_error) {
+				g_propagate_error (error, n_error);
+				return;
+			}
+
 			if (tracker_property_get_is_new (property) == FALSE &&
 			    last_multiple_values != tracker_property_get_multiple_values (property)) {
 				const gchar *ontology_path = "Unknown";
diff --git a/src/libtracker-data/tracker-property.c b/src/libtracker-data/tracker-property.c
index 7bf2c2f..0b1ade7 100644
--- a/src/libtracker-data/tracker-property.c
+++ b/src/libtracker-data/tracker-property.c
@@ -70,6 +70,7 @@ struct _TrackerPropertyPrivate {
 
 	GArray        *super_properties;
 	GArray        *domain_indexes;
+	GArray        *last_super_properties;
 };
 
 static void property_finalize     (GObject      *object);
@@ -140,6 +141,7 @@ tracker_property_init (TrackerProperty *property)
 	priv->force_journal = TRUE;
 	priv->super_properties = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
 	priv->domain_indexes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
+	priv->last_super_properties = NULL;
 
 	/* Make GET_PRIV working */
 	property->priv = priv;
@@ -172,6 +174,10 @@ property_finalize (GObject *object)
 		g_object_unref (priv->secondary_index);
 	}
 
+	if (priv->last_super_properties) {
+		g_array_free (priv->last_super_properties, TRUE);
+	}
+
 	g_array_free (priv->super_properties, TRUE);
 	g_array_free (priv->domain_indexes, TRUE);
 
@@ -354,6 +360,37 @@ tracker_property_get_domain_indexes (TrackerProperty *property)
 	return (TrackerClass ** ) priv->domain_indexes->data;
 }
 
+TrackerProperty **
+tracker_property_get_last_super_properties (TrackerProperty *property)
+{
+	TrackerPropertyPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
+	g_return_val_if_fail (property != NULL, NULL);
+
+	priv = GET_PRIV (property);
+
+	return (TrackerProperty **) (priv->last_super_properties ? priv->last_super_properties->data : NULL);
+}
+
+void
+tracker_property_reset_super_properties (TrackerProperty *property)
+{
+	TrackerPropertyPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_PROPERTY (property));
+
+	priv = GET_PRIV (property);
+
+	if (priv->last_super_properties) {
+		g_array_free (priv->last_super_properties, TRUE);
+	}
+
+	priv->last_super_properties = priv->super_properties;
+	priv->super_properties = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
+}
+
+
 TrackerClass *
 tracker_property_get_range (TrackerProperty *property)
 {
diff --git a/src/libtracker-data/tracker-property.h b/src/libtracker-data/tracker-property.h
index 68623f6..e6bac49 100644
--- a/src/libtracker-data/tracker-property.h
+++ b/src/libtracker-data/tracker-property.h
@@ -145,8 +145,11 @@ void                tracker_property_set_is_inverse_functional_property
                                                               gboolean              value);
 void                tracker_property_set_force_journal       (TrackerProperty      *property,
                                                               gboolean              value);
-void                tracker_property_add_super_property    (TrackerProperty      *property,
-                                                            TrackerProperty      *value);
+void                tracker_property_add_super_property      (TrackerProperty      *property,
+                                                              TrackerProperty      *value);
+TrackerProperty   **tracker_property_get_last_super_properties
+                                                             (TrackerProperty      *property);
+void                tracker_property_reset_super_properties  (TrackerProperty      *property);
 
 G_END_DECLS
 



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