[tracker: 11/21] propagate an error if ontology file contains incomplete properties




commit 0a23bcc816ec1ef83f28d137f8b54f2fbbbfb161
Author: Abanoub Ghadban <abanoub gdb gmail com>
Date:   Wed Aug 18 16:13:58 2021 +0200

    propagate an error if ontology file contains incomplete properties
    
    Make the ontology parser propagate an error if it encounters a property that doesn't have range or domain.
    The error also is propagated if the range or domain points to a class that doesn't exist.
    It solves the problem of adding properties with no range or domain to the database which causes tracker 
to crash while the ontology is parsed or when the data is queried.

 src/libtracker-data/tracker-data-manager.c | 62 +++++++++++++++++++++++++++++-
 1 file changed, 60 insertions(+), 2 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 36b6019f8..ffa17aa47 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -1804,6 +1804,45 @@ tracker_data_ontology_process_changes_post_import (GPtrArray *seen_classes,
        return;
 }
 
+static void
+check_properties_completeness (TrackerOntologies  *ontologies,
+                               GError            **error)
+{
+       guint i;
+       guint n_properties;
+       TrackerProperty **properties;
+
+       properties = tracker_ontologies_get_properties (ontologies, &n_properties);
+
+       for (i = 0; i < n_properties; i++) {
+               TrackerProperty *property = properties[i];
+               gchar *missing_definition = NULL;
+
+               if (!tracker_property_get_domain (property))
+                       missing_definition = "domain";
+               else if (!tracker_property_get_range (property))
+                       missing_definition = "range";
+
+               if (missing_definition) {
+                       const gchar *ontology_path = tracker_property_get_ontology_path (property);
+                       goffset line_no = tracker_property_get_definition_line_no (property);
+                       goffset column_no = tracker_property_get_definition_column_no (property);
+                       const gchar *property_name = tracker_property_get_name (property);
+                       gchar *definition_location = g_strdup_printf ("%s:%" G_GOFFSET_FORMAT ":%" 
G_GOFFSET_FORMAT,
+                                                                     ontology_path, line_no, column_no);
+
+                       g_set_error (error,
+                                    TRACKER_SPARQL_ERROR,
+                                    TRACKER_SPARQL_ERROR_OPEN_ERROR,
+                                    "%s: Property %s has no defined %s.",
+                                    definition_location, property_name, missing_definition);
+
+                       g_free (definition_location);
+                       return;
+               }
+       }
+}
+
 static void
 load_ontology_file (TrackerDataManager  *manager,
                     GFile               *file,
@@ -3961,8 +4000,12 @@ tracker_data_manager_initable_init (GInitable     *initable,
                        }
                }
 
-               tracker_data_ontology_setup_db (manager, iface, "main", FALSE,
-                                               &internal_error);
+               check_properties_completeness (manager->ontologies, &internal_error);
+
+               if (!internal_error) {
+                       tracker_data_ontology_setup_db (manager, iface, "main", FALSE,
+                                                       &internal_error);
+               }
 
                if (!internal_error) {
                        tracker_data_ontology_import_into_db (manager, iface,
@@ -4266,6 +4309,21 @@ tracker_data_manager_initable_init (GInitable     *initable,
                        g_object_unref (ontology);
                }
 
+               check_properties_completeness (manager->ontologies, &n_error);
+
+               if (n_error) {
+                       g_propagate_error (error, n_error);
+
+                       g_clear_pointer (&seen_classes, g_ptr_array_unref);
+                       g_clear_pointer (&seen_properties, g_ptr_array_unref);
+
+                       if (ontos) {
+                               g_list_free_full (ontos, g_object_unref);
+                       }
+
+                       goto rollback_db_changes;
+               }
+
                if (to_reload) {
                        GError *ontology_error = NULL;
 


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