[tracker/property-changes] libtracker-data: Initial infrastructure for support for range ontology changes



commit e6f894a000a662b6b082da548fdcffcf98382458
Author: Philip Van Hoof <philip codeminded be>
Date:   Thu Apr 1 16:44:00 2010 +0200

    libtracker-data: Initial infrastructure for support for range ontology changes

 src/libtracker-data/tracker-class.c        |   26 ++++++
 src/libtracker-data/tracker-class.h        |    3 +
 src/libtracker-data/tracker-data-manager.c |  136 +++++++++++++++++++++++++---
 src/libtracker-data/tracker-property.c     |   26 ++++++
 src/libtracker-data/tracker-property.h     |    3 +
 5 files changed, 179 insertions(+), 15 deletions(-)
---
diff --git a/src/libtracker-data/tracker-class.c b/src/libtracker-data/tracker-class.c
index b2375e6..7b39c96 100644
--- a/src/libtracker-data/tracker-class.c
+++ b/src/libtracker-data/tracker-class.c
@@ -39,6 +39,7 @@ struct _TrackerClassPriv {
 	gint count;
 	gint id;
 	gboolean is_new;
+	gboolean need_recreate;
 
 	GArray *super_classes;
 };
@@ -165,6 +166,18 @@ tracker_class_get_is_new (TrackerClass *service)
 	return priv->is_new;
 }
 
+gboolean
+tracker_class_get_need_recreate (TrackerClass *service)
+{
+	TrackerClassPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
+
+	priv = GET_PRIV (service);
+
+	return priv->need_recreate;
+}
+
 void
 tracker_class_set_uri (TrackerClass *service,
                        const gchar  *value)
@@ -260,3 +273,16 @@ tracker_class_set_is_new (TrackerClass *service,
 
 	priv->is_new = value;
 }
+
+void
+tracker_class_set_need_recreate (TrackerClass *service,
+                                 gboolean         value)
+{
+	TrackerClassPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_CLASS (service));
+
+	priv = GET_PRIV (service);
+
+	priv->need_recreate = value;
+}
diff --git a/src/libtracker-data/tracker-class.h b/src/libtracker-data/tracker-class.h
index c6c0acd..8282606 100644
--- a/src/libtracker-data/tracker-class.h
+++ b/src/libtracker-data/tracker-class.h
@@ -54,6 +54,7 @@ const gchar *   tracker_class_get_name          (TrackerClass  *service);
 gint            tracker_class_get_count         (TrackerClass  *service);
 gint            tracker_class_get_id            (TrackerClass  *service);
 gboolean        tracker_class_get_is_new        (TrackerClass  *service);
+gboolean        tracker_class_get_need_recreate (TrackerClass  *service);
 
 TrackerClass  **tracker_class_get_super_classes (TrackerClass  *service);
 void            tracker_class_set_uri           (TrackerClass  *service,
@@ -66,6 +67,8 @@ void            tracker_class_set_id            (TrackerClass  *service,
                                                  gint           id);
 void            tracker_class_set_is_new        (TrackerClass  *service,
                                                  gboolean       value);
+void            tracker_class_set_need_recreate (TrackerClass  *service,
+                                                 gboolean       value);
 
 G_END_DECLS
 
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 0aa2516..19281f9 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -48,6 +48,7 @@
 #include "tracker-sparql-query.h"
 #include "tracker-data-query.h"
 
+#define XSD_PREFIX TRACKER_XSD_PREFIX
 #define RDF_PREFIX TRACKER_RDF_PREFIX
 #define RDF_PROPERTY RDF_PREFIX "Property"
 #define RDF_TYPE RDF_PREFIX "type"
@@ -154,9 +155,9 @@ update_property_value (const gchar *kind,
 	}
 
 	if (!error && needed) {
-		tracker_data_insert_statement_with_string (NULL, subject,
-		                                           predicate, object,
-		                                           &error);
+		tracker_data_insert_statement (NULL, subject,
+		                               predicate, object,
+		                               &error);
 	}
 
 	if (error) {
@@ -371,16 +372,21 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 			return;
 		}
 
-		if (tracker_property_get_is_new (property) != in_update) {
-			return;
-		}
-
 		range = tracker_ontologies_get_class_by_uri (object);
 		if (range == NULL) {
 			g_critical ("%s: Unknown class %s", ontology_path, object);
 			return;
 		}
 
+		if (tracker_property_get_is_new (property) != in_update) {
+			TrackerClass *class;
+			if (update_property_value ("rdfs:range", subject, predicate, object)) {
+				class = tracker_property_get_domain (property);
+				tracker_class_set_need_recreate (class, TRUE);
+				tracker_property_set_need_recreate (property, TRUE);
+			}
+		}
+
 		tracker_property_set_range (property, range);
 	} else if (g_strcmp0 (predicate, NRL_MAX_CARDINALITY) == 0) {
 		TrackerProperty *property;
@@ -1172,7 +1178,8 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
                                            TrackerProperty    *property,
                                            const gchar        *service_name,
                                            const gchar       **sql_type_for_single_value,
-                                           gboolean            in_update)
+                                           gboolean            in_update,
+                                           gboolean            in_change)
 {
 	const char *field_name;
 	const char *sql_type;
@@ -1205,9 +1212,11 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
 		break;
 	}
 
-	if (!in_update || (in_update && (tracker_property_get_is_new (property)))) {
+	if (!in_update || (in_update && (tracker_property_get_is_new (property) ||
+	                                 tracker_property_get_need_recreate (property)))) {
 		if (transient || tracker_property_get_multiple_values (property)) {
 			GString *sql;
+			GString *col_sql = NULL;
 
 			/* multiple values */
 
@@ -1216,7 +1225,10 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
 				         service_name, field_name);
 			}
 
-
+			if (in_change && !tracker_property_get_is_new (property)) {
+				tracker_db_interface_execute_query (iface, NULL, "ALTER TABLE \"%s_%s\" RENAME TO \"%s_%s_TEMP\"", 
+				                                    service_name, field_name, service_name, field_name);
+			}
 
 			sql = g_string_new ("");
 			g_string_append_printf (sql, "CREATE %sTABLE \"%s_%s\" ("
@@ -1230,6 +1242,12 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
 			                             sql_type,
 			                             field_name);
 
+			if (in_change && !tracker_property_get_is_new (property)) {
+				col_sql = g_string_new ("ID");
+				g_string_append_printf (col_sql, ", \"%s\", \"%s:graph\"", 
+				                        field_name, field_name);
+			}
+
 			if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME) {
 				/* xsd:dateTime is stored in three columns:
 				 * universal time, local date, local time of day */
@@ -1238,6 +1256,12 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
 				                        ", \"%s:localTime\" INTEGER NOT NULL",
 				                        tracker_property_get_name (property),
 				                        tracker_property_get_name (property));
+
+				if (in_change && !tracker_property_get_is_new (property)) {
+					g_string_append_printf (col_sql, "\"%s:localDate\", \"%s:localTime\"", 
+					                        tracker_property_get_name (property),
+					                        tracker_property_get_name (property));
+				}
 			}
 
 			/* multiple values */
@@ -1264,19 +1288,43 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
 
 			g_string_free (sql, TRUE);
 
+
+			if (in_change && !tracker_property_get_is_new (property) && col_sql) {
+				gchar *query;
+
+				query = g_strdup_printf ("INSERT INTO \"%s_%s\"(%s) "
+				                         "SELECT %s FROM \"%s_%s_TEMP\"",
+				                         service_name, field_name, col_sql->str,
+				                         col_sql->str, field_name, service_name);
+
+				tracker_db_interface_execute_query (iface, NULL, "%s", query);
+				g_free (query);
+				tracker_db_interface_execute_query (iface, NULL, "DROP TABLE \"%s_%s_TEMP\"",
+				                                    service_name, field_name);
+			}
+
+			if (col_sql) {
+				g_string_free (col_sql, TRUE);
+			}
+
 		} else if (sql_type_for_single_value) {
 			*sql_type_for_single_value = sql_type;
 		}
 	}
+
+
+
 }
 
 static void
 create_decomposed_metadata_tables (TrackerDBInterface *iface,
                                    TrackerClass       *service,
-                                   gboolean            in_update)
+                                   gboolean            in_update,
+                                   gboolean            in_change)
 {
 	const char       *service_name;
 	GString          *create_sql = NULL;
+	GString          *col_sql = NULL;
 	TrackerProperty **properties, *property;
 	GSList           *class_properties, *field_it;
 	gboolean          main_class;
@@ -1291,8 +1339,17 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
 		return;
 	}
 
+	if (in_change) {
+		GError *error = NULL;
+		tracker_db_interface_execute_query (iface, &error, "ALTER TABLE \"%s\" RENAME TO \"%s_TEMP\"", service_name, service_name);
+		col_sql = g_string_new ("ID");
+		if (error) {
+			g_critical ("Ontology change: %s", error->message);
+			g_error_free (error);
+		}
+	}
 
-	if (!in_update || (in_update && tracker_class_get_is_new (service))) {
+	if (in_change || !in_update || (in_update && tracker_class_get_is_new (service))) {
 		if (in_update)
 			g_debug ("Altering database with new class '%s' (create)", service_name);
 		in_alter = FALSE;
@@ -1311,13 +1368,15 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
 		property = properties[i];
 
 		if (tracker_property_get_domain (property) == service) {
+			gboolean put_change;
 			const gchar *sql_type_for_single_value = NULL;
 			const gchar *field_name;
 
 			create_decomposed_metadata_property_table (iface, property,
 			                                           service_name,
 			                                           &sql_type_for_single_value,
-			                                           in_update);
+			                                           in_update,
+			                                           in_change);
 
 			field_name = tracker_property_get_name (property);
 
@@ -1333,6 +1392,7 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
 				}
 
 				if (!in_alter) {
+					put_change = TRUE;
 					class_properties = g_slist_prepend (class_properties, property);
 
 					g_string_append_printf (create_sql, ", \"%s\" %s",
@@ -1356,6 +1416,7 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
 				} else if (tracker_property_get_is_new (property)) {
 					GString *alter_sql = NULL;
 
+					put_change = FALSE;
 					class_properties = g_slist_prepend (class_properties, property);
 
 					alter_sql = g_string_new ("ALTER TABLE ");
@@ -1392,7 +1453,20 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
 						g_string_free (alter_sql, TRUE);
 
 					}
+				} else {
+					put_change = TRUE;
+				}
+
+				if (in_change && put_change) {
+					g_string_append_printf (col_sql, ", \"%s\", \"%s:graph\"", 
+					                        field_name, field_name);
+					if (tracker_property_get_data_type (property) == TRACKER_PROPERTY_TYPE_DATETIME) {
+						g_string_append_printf (col_sql, ", \"%s:localDate\", \"%s:localTime\"", 
+						                        tracker_property_get_name (property),
+						                        tracker_property_get_name (property));
+					}
 				}
+
 			}
 		}
 	}
@@ -1419,6 +1493,34 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
 
 	g_slist_free (class_properties);
 
+
+	if (in_change && col_sql) {
+		gchar *query;
+		GError *error = NULL;
+
+		query = g_strdup_printf ("INSERT INTO \"%s\"(%s) "
+		                         "SELECT %s FROM \"%s_TEMP\"",
+		                         service_name, col_sql->str,
+		                         col_sql->str, service_name);
+
+		tracker_db_interface_execute_query (iface, &error, "%s", query);
+		if (error) {
+			g_critical ("Ontology change: %s", error->message);
+			g_clear_error (&error);
+		}
+
+		g_free (query);
+		tracker_db_interface_execute_query (iface, &error, "DROP TABLE \"%s_TEMP\"", service_name);
+		if (error) {
+			g_critical ("Ontology change: %s", error->message);
+			g_error_free (error);
+		}
+
+	}
+
+	if (col_sql) {
+		g_string_free (col_sql, TRUE);
+	}
 }
 
 static void
@@ -1447,7 +1549,8 @@ create_decomposed_transient_metadata_tables (TrackerDBInterface *iface)
 			/* create the TEMPORARY table */
 			create_decomposed_metadata_property_table (iface, property,
 			                                           service_name,
-			                                           NULL, FALSE);
+			                                           NULL, FALSE,
+			                                           FALSE);
 		}
 	}
 }
@@ -1464,10 +1567,12 @@ tracker_data_ontology_import_finished (void)
 
 	for (i = 0; i < n_classes; i++) {
 		tracker_class_set_is_new (classes[i], FALSE);
+		tracker_class_set_need_recreate (classes[i], FALSE);
 	}
 
 	for (i = 0; i < n_props; i++) {
 		tracker_property_set_is_new (properties[i], FALSE);
+		tracker_property_set_need_recreate (properties[i], FALSE);
 	}
 }
 
@@ -1488,7 +1593,8 @@ tracker_data_ontology_import_into_db (gboolean in_update)
 	/* create tables */
 	for (i = 0; i < n_classes; i++) {
 		/* Also !is_new classes are processed, they might have new properties */
-		create_decomposed_metadata_tables (iface, classes[i], in_update);
+		create_decomposed_metadata_tables (iface, classes[i], in_update,
+		                                   tracker_class_get_need_recreate (classes[i]));
 	}
 
 	/* insert classes into rdfs:Resource table */
diff --git a/src/libtracker-data/tracker-property.c b/src/libtracker-data/tracker-property.c
index b59d1e6..692ab74 100644
--- a/src/libtracker-data/tracker-property.c
+++ b/src/libtracker-data/tracker-property.c
@@ -59,6 +59,7 @@ struct _TrackerPropertyPriv {
 	gboolean       transient;
 	gboolean       is_inverse_functional_property;
 	gboolean       is_new;
+	gboolean       need_recreate;
 
 	GArray        *super_properties;
 };
@@ -341,6 +342,18 @@ tracker_property_get_is_new (TrackerProperty *field)
 }
 
 gboolean
+tracker_property_get_need_recreate (TrackerProperty *field)
+{
+	TrackerPropertyPriv *priv;
+
+	g_return_val_if_fail (TRACKER_IS_PROPERTY (field), FALSE);
+
+	priv = GET_PRIV (field);
+
+	return priv->need_recreate;
+}
+
+gboolean
 tracker_property_get_embedded (TrackerProperty *field)
 {
 	TrackerPropertyPriv *priv;
@@ -551,6 +564,19 @@ tracker_property_set_is_new (TrackerProperty *field,
 }
 
 void
+tracker_property_set_need_recreate (TrackerProperty *field,
+                                    gboolean         value)
+{
+	TrackerPropertyPriv *priv;
+
+	g_return_if_fail (TRACKER_IS_PROPERTY (field));
+
+	priv = GET_PRIV (field);
+
+	priv->need_recreate = value;
+}
+
+void
 tracker_property_set_fulltext_indexed (TrackerProperty *field,
                                        gboolean                 value)
 {
diff --git a/src/libtracker-data/tracker-property.h b/src/libtracker-data/tracker-property.h
index ab4e532..5851566 100644
--- a/src/libtracker-data/tracker-property.h
+++ b/src/libtracker-data/tracker-property.h
@@ -87,6 +87,7 @@ gboolean            tracker_property_get_embedded         (TrackerProperty
 gboolean            tracker_property_get_multiple_values  (TrackerProperty      *property);
 gboolean            tracker_property_get_transient        (TrackerProperty      *property);
 gboolean            tracker_property_get_is_new           (TrackerProperty      *property);
+gboolean            tracker_property_get_need_recreate    (TrackerProperty      *property);
 gboolean            tracker_property_get_is_inverse_functional_property
 (TrackerProperty      *property);
 TrackerProperty **  tracker_property_get_super_properties (TrackerProperty      *property);
@@ -114,6 +115,8 @@ void                tracker_property_set_transient        (TrackerProperty
                                                            gboolean              value);
 void                tracker_property_set_is_new           (TrackerProperty      *property,
                                                            gboolean              value);
+void                tracker_property_set_need_recreate    (TrackerProperty      *property,
+                                                           gboolean              value);
 void                tracker_property_set_is_inverse_functional_property
 (TrackerProperty      *property,
  gboolean              value);



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