[tracker/secondary-index-for-master: 1/2] libtracker-data: Add support for tracker:secondaryIndex



commit 2f7db4dc39659fb64da7963c4acbdc8ead09eb40
Author: Philip Van Hoof <philip codeminded be>
Date:   Wed May 19 13:50:34 2010 +0200

    libtracker-data: Add support for tracker:secondaryIndex
    
    This will create a two-column index in SQLite.

 data/ontologies/11-rdf.ontology            |    7 +-
 src/libtracker-data/tracker-data-manager.c |  137 ++++++++++++++++++++++++----
 src/libtracker-data/tracker-data-update.c  |    4 +-
 src/libtracker-data/tracker-property.c     |   37 ++++++++
 src/libtracker-data/tracker-property.h     |    3 +
 5 files changed, 165 insertions(+), 23 deletions(-)
---
diff --git a/data/ontologies/11-rdf.ontology b/data/ontologies/11-rdf.ontology
index 2077c8c..b9e03a2 100644
--- a/data/ontologies/11-rdf.ontology
+++ b/data/ontologies/11-rdf.ontology
@@ -7,7 +7,7 @@
 
 rdf: a tracker:Namespace, tracker:Ontology ;
 	tracker:prefix "rdf" ;
-	nao:lastModified "2010-02-16T11:00:00Z" .
+	nao:lastModified "2010-05-18T21:06:00Z" .
 
 rdfs: a tracker:Namespace ;
 	tracker:prefix "rdfs" .
@@ -81,6 +81,11 @@ tracker:indexed a rdf:Property ;
 	rdfs:domain rdf:Property ;
 	rdfs:range xsd:boolean .
 
+tracker:secondaryIndex a rdf:Property ;
+	nrl:maxCardinality 1 ;
+	rdfs:domain rdf:Property ;
+	rdfs:range rdf:Property .
+
 tracker:fulltextIndexed a rdf:Property ;
 	nrl:maxCardinality 1 ;
 	rdfs:domain rdf:Property ;
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index c82deeb..21ad9f4 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -104,11 +104,39 @@ static Conversion allowed_range_conversions[] = {
 };
 
 static void
+set_secondary_index_for_single_value_property (TrackerDBInterface *iface,
+                                               const gchar        *service_name,
+                                               const gchar        *field_name,
+                                               const gchar        *second_field_name,
+                                               gboolean            enabled)
+{
+	tracker_db_interface_execute_query (iface, NULL,
+	                                    "DROP INDEX IF EXISTS \"%s_%s\"",
+	                                    service_name,
+	                                    field_name);
+
+	if (enabled) {
+		tracker_db_interface_execute_query (iface, NULL,
+		                                    "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\", \"%s\")",
+		                                    service_name,
+		                                    field_name,
+		                                    service_name,
+		                                    field_name,
+		                                    second_field_name);
+	}
+}
+
+static void
 set_index_for_single_value_property (TrackerDBInterface *iface,
                                      const gchar        *service_name,
                                      const gchar        *field_name,
                                      gboolean            enabled)
 {
+	tracker_db_interface_execute_query (iface, NULL,
+	                                    "DROP INDEX IF EXISTS \"%s_%s\"",
+	                                    service_name,
+	                                    field_name);
+
 	if (enabled) {
 		tracker_db_interface_execute_query (iface, NULL,
 		                                    "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\")",
@@ -116,11 +144,6 @@ set_index_for_single_value_property (TrackerDBInterface *iface,
 		                                    field_name,
 		                                    service_name,
 		                                    field_name);
-	} else {
-		tracker_db_interface_execute_query (iface, NULL,
-		                                    "DROP INDEX IF EXISTS \"%s_%s\"",
-		                                    service_name,
-		                                    field_name);
 	}
 }
 
@@ -220,7 +243,7 @@ update_property_value (const gchar     *kind,
 				needed = FALSE;
 			} else {
 
-				if (!is_allowed_conversion (str, object, allowed)) {
+				if (allowed && !is_allowed_conversion (str, object, allowed)) {
 					g_error ("Ontology change conversion not allowed '%s' -> '%s' in '%s' of '%s'",
 					         str, object, predicate, subject);
 				}
@@ -232,7 +255,11 @@ update_property_value (const gchar     *kind,
 
 			g_free (str);
 		} else {
-			needed = (g_strcmp0 (object, "true") == 0);
+			if (object && (g_strcmp0 (object, "false") == 0)) {
+				needed = FALSE;
+			} else {
+				needed = (object != NULL);
+			}
 		}
 		g_free (query);
 		if (result_set) {
@@ -312,8 +339,17 @@ fix_indexed (TrackerProperty *property)
 		set_index_for_multi_value_property (iface, service_name, field_name,
 		                                    tracker_property_get_indexed (property));
 	} else {
-		set_index_for_single_value_property (iface, service_name, field_name,
-		                                     tracker_property_get_indexed (property));
+		TrackerProperty *secondary_index;
+
+		secondary_index = tracker_property_get_secondary_index (property);
+		if (secondary_index == NULL) {
+			set_index_for_single_value_property (iface, service_name, field_name,
+			                                     tracker_property_get_indexed (property));
+		} else {
+			set_secondary_index_for_single_value_property (iface, service_name, field_name,
+			                                               tracker_property_get_name (secondary_index),
+			                                               tracker_property_get_indexed (property));
+		}
 	}
 }
 
@@ -379,6 +415,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 				} else {
 					/* Reset for a correct post-check */
 					tracker_property_set_indexed (property, FALSE);
+					tracker_property_set_secondary_index (property, NULL);
 					tracker_property_set_writeback (property, FALSE);
 				}
 				return;
@@ -575,6 +612,22 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 		}
 
 		tracker_property_set_indexed (property, (strcmp (object, "true") == 0));
+	} else if (g_strcmp0 (predicate, TRACKER_PREFIX "secondaryIndex") == 0) {
+		TrackerProperty *property, *secondary_index;
+
+		property = tracker_ontologies_get_property_by_uri (subject);
+		if (property == NULL) {
+			g_critical ("%s: Unknown property %s", ontology_path, subject);
+			return;
+		}
+
+		secondary_index = tracker_ontologies_get_property_by_uri (object);
+		if (secondary_index == NULL) {
+			g_critical ("%s: Unknown property %s", ontology_path, object);
+			return;
+		}
+
+		tracker_property_set_secondary_index (property, secondary_index);
 	} else if (g_strcmp0 (predicate, TRACKER_PREFIX "transient") == 0) {
 		TrackerProperty *property;
 
@@ -707,6 +760,8 @@ tracker_data_ontology_process_changes (GPtrArray *seen_classes,
 		for (i = 0; i < seen_properties->len; i++) {
 			TrackerProperty *property = g_ptr_array_index (seen_properties, i);
 			const gchar *subject;
+			TrackerProperty *secondary_index;
+			gboolean indexed_set = FALSE;
 
 			subject = tracker_property_get_uri (property);
 
@@ -731,6 +786,7 @@ tracker_data_ontology_process_changes (GPtrArray *seen_classes,
 				                           "true", allowed_boolean_conversions,
 				                           NULL, property)) {
 					fix_indexed (property);
+					indexed_set = TRUE;
 				}
 			} else {
 				if (update_property_value ("tracker:indexed",
@@ -739,6 +795,29 @@ tracker_data_ontology_process_changes (GPtrArray *seen_classes,
 				                           "false", allowed_boolean_conversions,
 				                           NULL, property)) {
 					fix_indexed (property);
+					indexed_set = TRUE;
+				}
+			}
+
+			secondary_index = tracker_property_get_secondary_index (property);
+
+			if (secondary_index) {
+				if (update_property_value ("tracker:secondaryIndex",
+				                           subject,
+				                           TRACKER_PREFIX "secondaryIndex",
+				                           tracker_property_get_uri (secondary_index), NULL,
+				                           NULL, property)) {
+					if (!indexed_set)
+						fix_indexed (property);
+				}
+			} else {
+				if (update_property_value ("tracker:secondaryIndex",
+				                           subject,
+				                           TRACKER_PREFIX "secondaryIndex",
+				                           NULL, NULL,
+				                           NULL, property)) {
+					if (!indexed_set)
+						fix_indexed (property);
 				}
 			}
 
@@ -1276,6 +1355,7 @@ db_get_static_data (TrackerDBInterface *iface)
 	                                              "(SELECT Uri FROM Resource WHERE ID = \"rdfs:range\"), "
 	                                              "\"nrl:maxCardinality\", "
 	                                              "\"tracker:indexed\", "
+	                                              "(SELECT Uri FROM Resource WHERE ID = \"tracker:secondaryIndex\"), "
 	                                              "\"tracker:fulltextIndexed\", "
 	                                              "\"tracker:fulltextNoLimit\", "
 	                                              "\"tracker:transient\", "
@@ -1291,7 +1371,7 @@ db_get_static_data (TrackerDBInterface *iface)
 		while (tracker_db_cursor_iter_next (cursor, NULL)) {
 			GValue value = { 0 };
 			TrackerProperty *property;
-			const gchar     *uri, *domain_uri, *range_uri;
+			const gchar     *uri, *domain_uri, *range_uri, *secondary_index_uri;
 			gboolean         multi_valued, indexed, fulltext_indexed, fulltext_no_limit;
 			gboolean         transient, annotation, is_inverse_functional_property;
 			gboolean         writeback;
@@ -1325,7 +1405,9 @@ db_get_static_data (TrackerDBInterface *iface)
 				indexed = FALSE;
 			}
 
-			tracker_db_cursor_get_value (cursor, 6, &value);
+			secondary_index_uri = tracker_db_cursor_get_string (cursor, 6);
+
+			tracker_db_cursor_get_value (cursor, 7, &value);
 
 			if (G_VALUE_TYPE (&value) != 0) {
 				fulltext_indexed = (g_value_get_int (&value) == 1);
@@ -1335,7 +1417,7 @@ db_get_static_data (TrackerDBInterface *iface)
 				fulltext_indexed = FALSE;
 			}
 
-			tracker_db_cursor_get_value (cursor, 7, &value);
+			tracker_db_cursor_get_value (cursor, 8, &value);
 
 			if (G_VALUE_TYPE (&value) != 0) {
 				fulltext_no_limit = (g_value_get_int (&value) == 1);
@@ -1345,7 +1427,7 @@ db_get_static_data (TrackerDBInterface *iface)
 				fulltext_no_limit = FALSE;
 			}
 
-			tracker_db_cursor_get_value (cursor, 8, &value);
+			tracker_db_cursor_get_value (cursor, 9, &value);
 
 			if (G_VALUE_TYPE (&value) != 0) {
 				transient = (g_value_get_int (&value) == 1);
@@ -1355,7 +1437,7 @@ db_get_static_data (TrackerDBInterface *iface)
 				transient = FALSE;
 			}
 
-			tracker_db_cursor_get_value (cursor, 9, &value);
+			tracker_db_cursor_get_value (cursor, 10, &value);
 
 			if (G_VALUE_TYPE (&value) != 0) {
 				annotation = (g_value_get_int (&value) == 1);
@@ -1365,8 +1447,9 @@ db_get_static_data (TrackerDBInterface *iface)
 				annotation = FALSE;
 			}
 
+
 			/* tracker:writeback column */
-			tracker_db_cursor_get_value (cursor, 10, &value);
+			tracker_db_cursor_get_value (cursor, 11, &value);
 
 			if (G_VALUE_TYPE (&value) != 0) {
 				writeback = (g_value_get_int (&value) == 1);
@@ -1377,7 +1460,7 @@ db_get_static_data (TrackerDBInterface *iface)
 			}
 
 			/* NRL_INVERSE_FUNCTIONAL_PROPERTY column */
-			tracker_db_cursor_get_value (cursor, 11, &value);
+			tracker_db_cursor_get_value (cursor, 12, &value);
 
 			if (G_VALUE_TYPE (&value) != 0) {
 				is_inverse_functional_property = TRUE;
@@ -1395,8 +1478,14 @@ db_get_static_data (TrackerDBInterface *iface)
 			tracker_property_set_range (property, tracker_ontologies_get_class_by_uri (range_uri));
 			tracker_property_set_multiple_values (property, multi_valued);
 			tracker_property_set_indexed (property, indexed);
+
 			tracker_property_set_db_schema_changed (property, FALSE);
 			tracker_property_set_writeback (property, writeback);
+
+			if (secondary_index_uri) {
+				tracker_property_set_secondary_index (property, tracker_ontologies_get_property_by_uri (secondary_index_uri));
+			}
+
 			tracker_property_set_fulltext_indexed (property, fulltext_indexed);
 			tracker_property_set_fulltext_no_limit (property, fulltext_no_limit);
 			tracker_property_set_embedded (property, !annotation);
@@ -1833,7 +1922,7 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
 
 	/* create index for single-valued fields */
 	for (field_it = class_properties; field_it != NULL; field_it = field_it->next) {
-		TrackerProperty *field;
+		TrackerProperty *field, *secondary_index;
 		const char   *field_name;
 
 		field = field_it->data;
@@ -1841,7 +1930,15 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
 		if (!tracker_property_get_multiple_values (field)
 		    && tracker_property_get_indexed (field)) {
 			field_name = tracker_property_get_name (field);
-			set_index_for_single_value_property (iface, service_name, field_name, TRUE);
+
+			secondary_index = tracker_property_get_secondary_index (field);
+			if (secondary_index == NULL) {
+				set_index_for_single_value_property (iface, service_name, field_name, TRUE);
+			} else {
+				set_secondary_index_for_single_value_property (iface, service_name, field_name,
+				                                               tracker_property_get_name (secondary_index),
+				                                               TRUE);
+			}
 		}
 	}
 
@@ -2351,10 +2448,10 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		if (to_reload) {
 			/* Perform ALTER-TABLE and CREATE-TABLE calls for all that are is_new */
-			tracker_data_ontology_process_changes (seen_classes, seen_properties);
-
 			tracker_data_ontology_import_into_db (TRUE);
 
+			tracker_data_ontology_process_changes (seen_classes, seen_properties);
+
 			for (l = to_reload; l; l = l->next) {
 				const gchar *ontology_path = l->data;
 				/* store ontology in database */
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 3cdc383..98d2074 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -2388,11 +2388,11 @@ ontology_transaction_end (GList *ontology_queue,
 	GList *l;
 	const gchar *ontology_uri = NULL;
 
-	tracker_data_ontology_process_changes (seen_classes, seen_properties);
-
 	/* Perform ALTER-TABLE and CREATE-TABLE calls for all that are is_new */
 	tracker_data_ontology_import_into_db (TRUE);
 
+	tracker_data_ontology_process_changes (seen_classes, seen_properties);
+
 	for (l = ontology_queue; l; l = l->next) {
 		QueuedStatement *queued = ontology_queue->data;
 
diff --git a/src/libtracker-data/tracker-property.c b/src/libtracker-data/tracker-property.c
index 254edc9..bcb715f 100644
--- a/src/libtracker-data/tracker-property.c
+++ b/src/libtracker-data/tracker-property.c
@@ -51,6 +51,7 @@ struct _TrackerPropertyPrivate {
 	gint           weight;
 	gint           id;
 	gboolean       indexed;
+	TrackerProperty *secondary_index;
 	gboolean       fulltext_indexed;
 	gboolean       fulltext_no_limit;
 	gboolean       embedded;
@@ -155,6 +156,10 @@ property_finalize (GObject *object)
 		g_object_unref (priv->range);
 	}
 
+	if (priv->secondary_index) {
+		g_object_unref (priv->secondary_index);
+	}
+
 	g_array_free (priv->super_properties, TRUE);
 
 	(G_OBJECT_CLASS (tracker_property_parent_class)->finalize) (object);
@@ -311,6 +316,18 @@ tracker_property_get_indexed (TrackerProperty *property)
 	return priv->indexed;
 }
 
+TrackerProperty *
+tracker_property_get_secondary_index (TrackerProperty *property)
+{
+	TrackerPropertyPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_PROPERTY (property), NULL);
+
+	priv = GET_PRIV (property);
+
+	return priv->secondary_index;
+}
+
 gboolean
 tracker_property_get_fulltext_indexed (TrackerProperty *property)
 {
@@ -498,6 +515,26 @@ tracker_property_set_domain (TrackerProperty *property,
 }
 
 void
+tracker_property_set_secondary_index (TrackerProperty *property,
+                                      TrackerProperty *value)
+{
+	TrackerPropertyPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_PROPERTY (property));
+
+	priv = GET_PRIV (property);
+
+	if (priv->secondary_index) {
+		g_object_unref (priv->secondary_index);
+		priv->secondary_index = NULL;
+	}
+
+	if (value) {
+		priv->secondary_index = g_object_ref (value);
+	}
+}
+
+void
 tracker_property_set_range (TrackerProperty *property,
                             TrackerClass     *value)
 {
diff --git a/src/libtracker-data/tracker-property.h b/src/libtracker-data/tracker-property.h
index 4dd5a6e..c3a2c16 100644
--- a/src/libtracker-data/tracker-property.h
+++ b/src/libtracker-data/tracker-property.h
@@ -83,6 +83,7 @@ TrackerClass *      tracker_property_get_range             (TrackerProperty
 gint                tracker_property_get_weight            (TrackerProperty      *property);
 gint                tracker_property_get_id                (TrackerProperty      *property);
 gboolean            tracker_property_get_indexed           (TrackerProperty      *property);
+TrackerProperty *   tracker_property_get_secondary_index   (TrackerProperty      *property);
 gboolean            tracker_property_get_fulltext_indexed  (TrackerProperty      *property);
 gboolean            tracker_property_get_fulltext_no_limit (TrackerProperty      *property);
 gboolean            tracker_property_get_embedded          (TrackerProperty      *property);
@@ -106,6 +107,8 @@ void                tracker_property_set_id                (TrackerProperty
                                                             gint                  value);
 void                tracker_property_set_indexed           (TrackerProperty      *property,
                                                             gboolean              value);
+void                tracker_property_set_secondary_index   (TrackerProperty      *property,
+                                                            TrackerProperty      *value);
 void                tracker_property_set_fulltext_indexed  (TrackerProperty      *property,
                                                             gboolean              value);
 void                tracker_property_set_fulltext_no_limit (TrackerProperty      *property,



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