[tracker/domain-specific-indexes-review: 1/21] libtracker-data: Added tracker:domainIndex property



commit 761df4658b7c7a52a316a6e95e98d2fd985655f4
Author: Philip Van Hoof <philip codeminded be>
Date:   Tue Jun 29 14:22:32 2010 +0200

    libtracker-data: Added tracker:domainIndex property
    
    In this commit the tracker:domainIndex property has no function yet. It'll
    be implemented to represent a setting that will make the storage redundantly
    store a property in the table of its domain, in order to allow placing an
    index on the column for that table.
    
    For example nmm:MusicPiece has a domain-index on nie:title. This will make
    it store a redundent copy of nie:title in nmm:MusicPiece's SQL table,
    while also having a copy in nie:InformationElement's table. The advantage is
    a less complex query and the possibility to set an index on the redundant
    column in nmm:MusicPiece's table.

 data/ontologies/11-rdf.ontology            |    8 ++-
 src/libtracker-data/tracker-class.c        |   31 ++++++++++-
 src/libtracker-data/tracker-class.h        |   53 ++++++++++--------
 src/libtracker-data/tracker-data-manager.c |   84 ++++++++++++++++++++++++++++
 src/libtracker-data/tracker-property.h     |    2 +-
 5 files changed, 150 insertions(+), 28 deletions(-)
---
diff --git a/data/ontologies/11-rdf.ontology b/data/ontologies/11-rdf.ontology
index 5d02162..7a485a9 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-05-18T21:06:00Z" .
+	nao:lastModified "2010-06-29T13:00:00Z" .
 
 rdfs: a tracker:Namespace ;
 	tracker:prefix "rdfs" .
@@ -76,6 +76,10 @@ tracker:prefix a rdf:Property ;
 	rdfs:domain tracker:Namespace ;
 	rdfs:range xsd:string .
 
+tracker:domainIndex a rdf:Property ;
+	rdfs:domain rdfs:Class ;
+	rdfs:range rdf:Property .
+
 tracker:indexed a rdf:Property ;
 	nrl:maxCardinality 1 ;
 	rdfs:domain rdf:Property ;
@@ -102,7 +106,7 @@ tracker:transient a rdf:Property ;
 	rdfs:range xsd:boolean .
 
 tracker:isAnnotation a rdf:Property ;
-        rdfs:comment "The property is never embedded on physical files" ;
+	rdfs:comment "The property is never embedded on physical files" ;
 	nrl:maxCardinality 1 ;
 	rdfs:domain rdf:Property ;
 	rdfs:range xsd:boolean .
diff --git a/src/libtracker-data/tracker-class.c b/src/libtracker-data/tracker-class.c
index 112186e..49a8e6d 100644
--- a/src/libtracker-data/tracker-class.c
+++ b/src/libtracker-data/tracker-class.c
@@ -42,6 +42,7 @@ struct _TrackerClassPrivate {
 	gboolean notify;
 
 	GArray *super_classes;
+	GArray *domain_indexes;
 };
 
 static void class_finalize     (GObject      *object);
@@ -67,6 +68,7 @@ tracker_class_init (TrackerClass *service)
 
 	priv->id = 0;
 	priv->super_classes = g_array_new (TRUE, TRUE, sizeof (TrackerClass *));
+	priv->domain_indexes = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
 
 	/* Make GET_PRIV working */
 	service->priv = priv;
@@ -83,6 +85,7 @@ class_finalize (GObject *object)
 	g_free (priv->name);
 
 	g_array_free (priv->super_classes, TRUE);
+	g_array_free (priv->domain_indexes, TRUE);
 
 	(G_OBJECT_CLASS (tracker_class_parent_class)->finalize) (object);
 }
@@ -157,6 +160,18 @@ tracker_class_get_super_classes (TrackerClass *service)
 	return (TrackerClass **) priv->super_classes->data;
 }
 
+TrackerProperty **
+tracker_class_get_domain_indexes (TrackerClass *service)
+{
+	TrackerClassPrivate *priv;
+
+	g_return_val_if_fail (TRACKER_IS_CLASS (service), NULL);
+
+	priv = GET_PRIV (service);
+
+	return (TrackerProperty **) priv->domain_indexes->data;
+}
+
 gboolean
 tracker_class_get_is_new (TrackerClass *service)
 {
@@ -261,7 +276,6 @@ tracker_class_set_id (TrackerClass *service,
 	priv->id = value;
 }
 
-
 void
 tracker_class_add_super_class (TrackerClass *service,
                                TrackerClass *value)
@@ -277,6 +291,20 @@ tracker_class_add_super_class (TrackerClass *service,
 }
 
 void
+tracker_class_add_domain_index (TrackerClass *service,
+                                TrackerProperty *value)
+{
+	TrackerClassPrivate *priv;
+
+	g_return_if_fail (TRACKER_IS_CLASS (service));
+	g_return_if_fail (TRACKER_IS_PROPERTY (value));
+
+	priv = GET_PRIV (service);
+
+	g_array_append_val (priv->domain_indexes, value);
+}
+
+void
 tracker_class_set_is_new (TrackerClass *service,
                           gboolean      value)
 {
@@ -289,6 +317,7 @@ tracker_class_set_is_new (TrackerClass *service,
 	priv->is_new = value;
 }
 
+
 void
 tracker_class_set_notify (TrackerClass *service,
                           gboolean      value)
diff --git a/src/libtracker-data/tracker-class.h b/src/libtracker-data/tracker-class.h
index ea69b66..d882561 100644
--- a/src/libtracker-data/tracker-class.h
+++ b/src/libtracker-data/tracker-class.h
@@ -36,6 +36,7 @@ G_BEGIN_DECLS
 #define TRACKER_IS_CLASS_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_CLASS))
 #define TRACKER_CLASS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_CLASS, TrackerClassClass))
 
+typedef struct _TrackerProperty TrackerProperty;
 typedef struct _TrackerClass TrackerClass;
 typedef struct _TrackerClassClass TrackerClassClass;
 typedef struct _TrackerClassPrivate TrackerClassPrivate;
@@ -49,32 +50,36 @@ struct _TrackerClassClass {
 	GObjectClass parent_class;
 };
 
-GType           tracker_class_get_type              (void) G_GNUC_CONST;
-TrackerClass *  tracker_class_new                   (void);
-const gchar *   tracker_class_get_uri               (TrackerClass  *service);
-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_db_schema_changed (TrackerClass  *service);
-gboolean        tracker_class_get_notify            (TrackerClass  *service);
+GType             tracker_class_get_type               (void) G_GNUC_CONST;
+TrackerClass *    tracker_class_new                    (void);
+const gchar *     tracker_class_get_uri                (TrackerClass    *service);
+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_db_schema_changed  (TrackerClass    *service);
+gboolean          tracker_class_get_notify             (TrackerClass    *service);
 
-TrackerClass  **tracker_class_get_super_classes     (TrackerClass  *service);
+TrackerClass    **tracker_class_get_super_classes      (TrackerClass    *service);
+TrackerProperty **tracker_class_get_domain_indexes     (TrackerClass    *service);
 
-void            tracker_class_set_uri               (TrackerClass  *service,
-                                                     const gchar   *value);
-void            tracker_class_set_count             (TrackerClass  *service,
-                                                     gint           value);
-void            tracker_class_add_super_class       (TrackerClass  *self,
-                                                     TrackerClass  *value);
-void            tracker_class_set_id                (TrackerClass  *service,
-                                                     gint           id);
-void            tracker_class_set_is_new            (TrackerClass  *service,
-                                                     gboolean       value);
-void            tracker_class_set_db_schema_changed (TrackerClass  *service,
-                                                     gboolean       value);
-void            tracker_class_set_notify            (TrackerClass  *service,
-                                                     gboolean       value);
+void              tracker_class_set_uri                (TrackerClass    *service,
+                                                        const gchar     *value);
+void              tracker_class_set_count              (TrackerClass    *service,
+                                                        gint             value);
+void              tracker_class_add_super_class        (TrackerClass    *self,
+                                                        TrackerClass    *value);
+void              tracker_class_add_domain_index       (TrackerClass    *self,
+                                                        TrackerProperty *value);
+
+void              tracker_class_set_id                 (TrackerClass    *service,
+                                                        gint             id);
+void              tracker_class_set_is_new             (TrackerClass    *service,
+                                                        gboolean         value);
+void              tracker_class_set_db_schema_changed  (TrackerClass    *service,
+                                                        gboolean         value);
+void              tracker_class_set_notify             (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 3e9faf2..7193303 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -516,6 +516,41 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 		}
 
 		tracker_class_set_notify (class, (strcmp (object, "true") == 0));
+	} else if (g_strcmp0 (predicate, TRACKER_PREFIX "domainIndex") == 0) {
+		TrackerClass *class;
+		TrackerProperty *property;
+		TrackerProperty **properties;
+		gboolean ignore = FALSE;
+
+		class = tracker_ontologies_get_class_by_uri (subject);
+
+		if (class == NULL) {
+			g_critical ("%s: Unknown class %s", ontology_path, subject);
+			return;
+		}
+
+		property = tracker_ontologies_get_property_by_uri (object);
+
+		if (property == NULL) {
+			g_critical ("%s: Unknown property %s for tracker:domainIndex in %s",
+			            ontology_path, object, subject);
+			return;
+		}
+
+		properties = tracker_class_get_domain_indexes (class);
+		while (*properties) {
+			if (property == *properties) {
+				g_critical ("%s: property %s already a tracker:domainIndex in %s",
+				            ontology_path, object, subject);
+				ignore = TRUE;
+			}
+			properties++;
+		}
+
+		if (!ignore) {
+			tracker_class_add_domain_index (class, property);
+		}
+
 	} else if (g_strcmp0 (predicate, TRACKER_PREFIX "writeback") == 0) {
 		TrackerProperty *property;
 
@@ -1226,6 +1261,44 @@ class_add_super_classes_from_db (TrackerDBInterface *iface,
 	}
 }
 
+
+static void
+class_add_domain_indexes_from_db (TrackerDBInterface *iface,
+                                  TrackerClass       *class)
+{
+	TrackerDBStatement *stmt;
+	TrackerDBCursor *cursor;
+	GError *error = NULL;
+
+	stmt = tracker_db_interface_create_statement (iface, &error,
+	                                              "SELECT (SELECT Uri FROM Resource WHERE ID = \"tracker:domainIndex\") "
+	                                              "FROM \"rdfs:Class_tracker:domainIndex\" "
+	                                              "WHERE ID = (SELECT ID FROM Resource WHERE Uri = ?)");
+
+	if (!stmt) {
+		g_critical ("%s", error->message);
+		g_error_free (error);
+		return;
+	}
+
+	tracker_db_statement_bind_text (stmt, 0, tracker_class_get_uri (class));
+	cursor = tracker_db_statement_start_cursor (stmt, NULL);
+	g_object_unref (stmt);
+
+	if (cursor) {
+		while (tracker_db_cursor_iter_next (cursor, NULL)) {
+			TrackerProperty *domain_index;
+			const gchar *domain_index_uri;
+
+			domain_index_uri = tracker_db_cursor_get_string (cursor, 0, NULL);
+			domain_index = tracker_ontologies_get_property_by_uri (domain_index_uri);
+			tracker_class_add_domain_index (class, domain_index);
+		}
+
+		g_object_unref (cursor);
+	}
+}
+
 static void
 property_add_super_properties_from_db (TrackerDBInterface *iface,
                                        TrackerProperty *property)
@@ -1269,6 +1342,8 @@ db_get_static_data (TrackerDBInterface *iface)
 	TrackerDBStatement *stmt;
 	TrackerDBCursor *cursor = NULL;
 	TrackerDBResultSet *result_set;
+	TrackerClass **classes;
+	guint n_classes, i;
 	GError *error = NULL;
 
 	stmt = tracker_db_interface_create_statement (iface, &error,
@@ -1389,6 +1464,9 @@ db_get_static_data (TrackerDBInterface *iface)
 
 			class_add_super_classes_from_db (iface, class);
 
+			/* We do this later, we first need to load the properties too
+			   class_add_domain_indexes_from_db (iface, class); */
+
 			tracker_ontologies_add_class (class);
 			tracker_ontologies_add_id_uri_pair (id, uri);
 			tracker_class_set_id (class, id);
@@ -1583,6 +1661,12 @@ db_get_static_data (TrackerDBInterface *iface)
 		cursor = NULL;
 	}
 
+	/* Now that the properties are loaded we can do this foreach class */
+	classes = tracker_ontologies_get_classes (&n_classes);
+	for (i = 0; i < n_classes; i++) {
+		class_add_domain_indexes_from_db (iface, classes[i]);
+	}
+
 	if (error) {
 		g_warning ("%s", error->message);
 		g_error_free (error);
diff --git a/src/libtracker-data/tracker-property.h b/src/libtracker-data/tracker-property.h
index 5ee3561..01ce5f7 100644
--- a/src/libtracker-data/tracker-property.h
+++ b/src/libtracker-data/tracker-property.h
@@ -59,7 +59,7 @@ GType        tracker_property_type_get_type  (void) G_GNUC_CONST;
 #define TRACKER_IS_PROPERTY_CLASS(k)  (G_TYPE_CHECK_CLASS_TYPE ((k), TRACKER_TYPE_PROPERTY))
 #define TRACKER_PROPERTY_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), TRACKER_TYPE_PROPERTY, TrackerPropertyClass))
 
-typedef struct _TrackerProperty         TrackerProperty;
+/* Forward typedef for TrackerProperty in tracker-class.h */
 typedef struct _TrackerPropertyClass TrackerPropertyClass;
 typedef struct _TrackerPropertyPrivate TrackerPropertyPrivate;
 



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