[tracker/ontology-cache: 2/2] libtracker-data: Add ontology cache



commit 6decf65339ffb83fab3d72faecc8dc658b4cc5b2
Author: Jürg Billeter <j bitron ch>
Date:   Wed Dec 1 14:08:06 2010 +0100

    libtracker-data: Add ontology cache

 src/libtracker-data/Makefile.am            |    1 +
 src/libtracker-data/tracker-class.c        |   33 +++-
 src/libtracker-data/tracker-class.h        |    2 +-
 src/libtracker-data/tracker-data-manager.c |   57 ++++-
 src/libtracker-data/tracker-namespace.c    |   16 ++-
 src/libtracker-data/tracker-namespace.h    |    2 +-
 src/libtracker-data/tracker-ontologies.c   |  352 +++++++++++++++++++++++++++-
 src/libtracker-data/tracker-ontologies.h   |   17 ++
 src/libtracker-data/tracker-property.c     |  100 ++++++++-
 src/libtracker-data/tracker-property.h     |    2 +-
 10 files changed, 550 insertions(+), 32 deletions(-)
---
diff --git a/src/libtracker-data/Makefile.am b/src/libtracker-data/Makefile.am
index 4716349..7790e62 100644
--- a/src/libtracker-data/Makefile.am
+++ b/src/libtracker-data/Makefile.am
@@ -46,6 +46,7 @@ libtracker_data_la_SOURCES =                           \
 	tracker-property.c
 
 libtracker_data_la_LIBADD =                            \
+	$(top_builddir)/src/gvdb/libgvdb.la \
 	$(top_builddir)/src/libtracker-common/libtracker-common.la \
 	$(top_builddir)/src/libtracker-sparql/libtracker-sparql- TRACKER_API_VERSION@.la \
 	$(BUILD_LIBS)                                  \
diff --git a/src/libtracker-data/tracker-class.c b/src/libtracker-data/tracker-class.c
index 59d24fb..856f64c 100644
--- a/src/libtracker-data/tracker-class.c
+++ b/src/libtracker-data/tracker-class.c
@@ -41,6 +41,8 @@ struct _TrackerClassPrivate {
 	gboolean db_schema_changed;
 	gboolean notify;
 
+	gboolean use_gvdb;
+
 	GArray *super_classes;
 	GArray *domain_indexes;
 	GArray *last_domain_indexes;
@@ -144,12 +146,18 @@ class_finalize (GObject *object)
 }
 
 TrackerClass *
-tracker_class_new (void)
+tracker_class_new (gboolean use_gvdb)
 {
 	TrackerClass *service;
+	TrackerClassPrivate *priv;
 
 	service = g_object_new (TRACKER_TYPE_CLASS, NULL);
 
+	if (use_gvdb) {
+		priv = GET_PRIV (service);
+		priv->use_gvdb = use_gvdb;
+	}
+
 	return service;
 }
 
@@ -210,6 +218,29 @@ tracker_class_get_super_classes (TrackerClass *service)
 
 	priv = GET_PRIV (service);
 
+	if (priv->use_gvdb) {
+		TrackerClass *super_class;
+		GVariant *variant;
+
+		tracker_class_reset_super_classes (service);
+
+		variant = tracker_ontologies_get_class_value_gvdb (priv->uri, "super-classes");
+		if (variant) {
+			GVariantIter iter;
+			gchar *uri;
+
+			g_variant_iter_init (&iter, variant);
+			while (g_variant_iter_loop (&iter, "s", &uri)) {
+				super_class = tracker_ontologies_get_class_by_uri (uri);
+				g_free (uri);
+
+				tracker_class_add_super_class (service, super_class);
+
+				g_object_unref (super_class);
+			}
+		}
+	}
+
 	return (TrackerClass **) priv->super_classes->data;
 }
 
diff --git a/src/libtracker-data/tracker-class.h b/src/libtracker-data/tracker-class.h
index 118dddf..c3f1c8d 100644
--- a/src/libtracker-data/tracker-class.h
+++ b/src/libtracker-data/tracker-class.h
@@ -57,7 +57,7 @@ typedef void    (*TrackerEventsForeach)                (gint                 gra
                                                         gpointer             user_data);
 
 GType             tracker_class_get_type               (void) G_GNUC_CONST;
-TrackerClass *    tracker_class_new                    (void);
+TrackerClass *    tracker_class_new                    (gboolean             use_gvdb);
 const gchar *     tracker_class_get_uri                (TrackerClass        *service);
 const gchar *     tracker_class_get_name               (TrackerClass        *service);
 gint              tracker_class_get_count              (TrackerClass        *service);
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index ecc9776..f5cf516 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -551,7 +551,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 				subject_id = ++(*max_id);
 			}
 
-			class = tracker_class_new ();
+			class = tracker_class_new (NULL);
 			tracker_class_set_is_new (class, in_update);
 			tracker_class_set_uri (class, subject);
 			tracker_class_set_id (class, subject_id);
@@ -592,7 +592,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 				subject_id = ++(*max_id);
 			}
 
-			property = tracker_property_new ();
+			property = tracker_property_new (NULL);
 			tracker_property_set_is_new (property, in_update);
 			tracker_property_set_uri (property, subject);
 			tracker_property_set_id (property, subject_id);
@@ -627,7 +627,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
 				return;
 			}
 
-			namespace = tracker_namespace_new ();
+			namespace = tracker_namespace_new (NULL);
 			tracker_namespace_set_is_new (namespace, in_update);
 			tracker_namespace_set_uri (namespace, subject);
 			tracker_ontologies_add_namespace (namespace);
@@ -2052,7 +2052,7 @@ db_get_static_data (TrackerDBInterface *iface)
 			TrackerNamespace *namespace;
 			const gchar      *uri, *prefix;
 
-			namespace = tracker_namespace_new ();
+			namespace = tracker_namespace_new (NULL);
 
 			uri = tracker_db_cursor_get_string (cursor, 0, NULL);
 			prefix = tracker_db_cursor_get_string (cursor, 1, NULL);
@@ -2095,7 +2095,7 @@ db_get_static_data (TrackerDBInterface *iface)
 			GValue        value = { 0 };
 			gboolean      notify;
 
-			class = tracker_class_new ();
+			class = tracker_class_new (NULL);
 
 			id = tracker_db_cursor_get_int (cursor, 0);
 			uri = tracker_db_cursor_get_string (cursor, 1, NULL);
@@ -2189,7 +2189,7 @@ db_get_static_data (TrackerDBInterface *iface)
 			gboolean         writeback;
 			gint             id;
 
-			property = tracker_property_new ();
+			property = tracker_property_new (NULL);
 
 			id = tracker_db_cursor_get_int (cursor, 0);
 			uri = tracker_db_cursor_get_string (cursor, 1, NULL);
@@ -3234,6 +3234,36 @@ tracker_data_manager_reload (TrackerBusyCallback  busy_callback,
 	return status;
 }
 
+static void
+write_ontologies_gvdb (GError **error)
+{
+	gchar *filename;
+
+	filename = g_build_filename (g_get_user_cache_dir (),
+	                             "tracker",
+	                             "ontologies.gvdb",
+	                             NULL);
+
+	tracker_ontologies_write_gvdb (filename, error);
+
+	g_free (filename);
+}
+
+static void
+load_ontologies_gvdb (GError **error)
+{
+	gchar *filename;
+
+	filename = g_build_filename (g_get_user_cache_dir (),
+	                             "tracker",
+	                             "ontologies.gvdb",
+	                             NULL);
+
+	tracker_ontologies_load_gvdb (filename, error);
+
+	g_free (filename);
+}
+
 gboolean
 tracker_data_manager_init (TrackerDBManagerFlags  flags,
                            const gchar          **test_schemas,
@@ -3434,6 +3464,8 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 
 		tracker_data_commit_transaction (NULL);
 
+		write_ontologies_gvdb (NULL);
+
 		g_list_foreach (sorted, (GFunc) g_free, NULL);
 		g_list_free (sorted);
 		sorted = NULL;
@@ -3443,12 +3475,15 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 	} else {
 		if (!read_only) {
 			tracker_db_journal_init (NULL, FALSE);
+
+			/* Load ontology from database into memory */
+			db_get_static_data (iface);
+			create_decomposed_transient_metadata_tables (iface);
+			check_ontology = TRUE;
+		} else {
+			load_ontologies_gvdb (NULL);
 		}
 
-		/* Load ontology from database into memory */
-		db_get_static_data (iface);
-		create_decomposed_transient_metadata_tables (iface);
-		check_ontology = TRUE;
 
 		/* This is a no-op when FTS is disabled */
 		tracker_db_interface_sqlite_fts_init (iface, FALSE);
@@ -3767,6 +3802,8 @@ tracker_data_manager_init (TrackerDBManagerFlags  flags,
 			g_list_free (to_reload);
 
 			tracker_data_ontology_process_changes_post_import (seen_classes, seen_properties);
+
+			write_ontologies_gvdb (NULL);
 		}
 
 		tracker_data_ontology_free_seen (seen_classes);
diff --git a/src/libtracker-data/tracker-namespace.c b/src/libtracker-data/tracker-namespace.c
index f296c48..efcd794 100644
--- a/src/libtracker-data/tracker-namespace.c
+++ b/src/libtracker-data/tracker-namespace.c
@@ -25,12 +25,16 @@
 #include <glib.h>
 
 #include "tracker-namespace.h"
+#include "tracker-ontologies.h"
 
 #define GET_PRIV(obj) (((TrackerNamespace*)obj)->priv)
 #define TRACKER_NAMESPACE_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), TRACKER_TYPE_NAMESPACE, TrackerNamespacePrivate))
 
 struct _TrackerNamespacePrivate {
 	gchar *uri;
+
+	gboolean use_gvdb;
+
 	gchar *prefix;
 	gboolean is_new;
 };
@@ -69,12 +73,18 @@ namespace_finalize (GObject *object)
 }
 
 TrackerNamespace *
-tracker_namespace_new (void)
+tracker_namespace_new (gboolean use_gvdb)
 {
 	TrackerNamespace *namespace;
+	TrackerNamespacePrivate *priv;
 
 	namespace = g_object_new (TRACKER_TYPE_NAMESPACE, NULL);
 
+	if (use_gvdb) {
+		priv = GET_PRIV (namespace);
+		priv->use_gvdb = use_gvdb;
+	}
+
 	return namespace;
 }
 
@@ -99,6 +109,10 @@ tracker_namespace_get_prefix (TrackerNamespace *namespace)
 
 	priv = GET_PRIV (namespace);
 
+	if (!priv->prefix && priv->use_gvdb) {
+		priv->prefix = g_strdup (tracker_ontologies_get_namespace_string_gvdb (priv->uri, "prefix"));
+	}
+
 	return priv->prefix;
 }
 
diff --git a/src/libtracker-data/tracker-namespace.h b/src/libtracker-data/tracker-namespace.h
index b097e46..6d1cc7d 100644
--- a/src/libtracker-data/tracker-namespace.h
+++ b/src/libtracker-data/tracker-namespace.h
@@ -50,7 +50,7 @@ struct _TrackerNamespaceClass {
 };
 
 GType             tracker_namespace_get_type      (void) G_GNUC_CONST;
-TrackerNamespace *tracker_namespace_new           (void);
+TrackerNamespace *tracker_namespace_new           (gboolean          use_gvdb);
 const gchar *     tracker_namespace_get_uri       (TrackerNamespace *namespace_);
 const gchar *     tracker_namespace_get_prefix    (TrackerNamespace *namespace_);
 gboolean          tracker_namespace_get_is_new    (TrackerNamespace *namespace_);
diff --git a/src/libtracker-data/tracker-ontologies.c b/src/libtracker-data/tracker-ontologies.c
index cdde80c..f9070fd 100644
--- a/src/libtracker-data/tracker-ontologies.c
+++ b/src/libtracker-data/tracker-ontologies.c
@@ -25,6 +25,8 @@
 
 #include <glib.h>
 
+#include <gvdb/gvdb-builder.h>
+#include <gvdb/gvdb-reader.h>
 #include <libtracker-common/tracker-ontologies.h>
 
 #include "tracker-ontologies.h"
@@ -64,6 +66,11 @@ static GHashTable *id_uri_pairs;
 /* rdf:type */
 static TrackerProperty *rdf_type = NULL;
 
+static GvdbTable *gvdb_table;
+static GvdbTable *gvdb_namespaces_table;
+static GvdbTable *gvdb_classes_table;
+static GvdbTable *gvdb_properties_table;
+
 void
 tracker_ontologies_init (void)
 {
@@ -154,6 +161,20 @@ tracker_ontologies_shutdown (void)
 		rdf_type = NULL;
 	}
 
+	if (gvdb_table) {
+		gvdb_table_unref (gvdb_properties_table);
+		gvdb_properties_table = NULL;
+
+		gvdb_table_unref (gvdb_classes_table);
+		gvdb_classes_table = NULL;
+
+		gvdb_table_unref (gvdb_namespaces_table);
+		gvdb_namespaces_table = NULL;
+
+		gvdb_table_unref (gvdb_table);
+		gvdb_table = NULL;
+	}
+
 	initialized = FALSE;
 }
 
@@ -195,17 +216,42 @@ tracker_ontologies_add_class (TrackerClass *service)
 TrackerClass *
 tracker_ontologies_get_class_by_uri (const gchar *class_uri)
 {
+	TrackerClass *class;
+
 	g_return_val_if_fail (class_uri != NULL, NULL);
 
-	return g_hash_table_lookup (class_uris, class_uri);
+	class = g_hash_table_lookup (class_uris, class_uri);
+
+	if (!class && gvdb_table) {
+		class = tracker_class_new (TRUE);
+		tracker_class_set_uri (class, class_uri);
+
+		g_hash_table_insert (class_uris,
+		                     g_strdup (class_uri),
+		                     class);
+	}
+
+	return class;
 }
 
 TrackerNamespace **
 tracker_ontologies_get_namespaces (guint *length)
 {
-	if (G_UNLIKELY (!namespaces)) {
-		*length = 0;
-		return NULL;
+	if (namespaces->len == 0 && gvdb_table) {
+		gchar **namespace_uris;
+		gint i;
+
+		namespace_uris = gvdb_table_list (gvdb_namespaces_table, "");
+
+		for (i = 0; namespace_uris[i]; i++) {
+			TrackerNamespace *namespace;
+
+			namespace = tracker_ontologies_get_namespace_by_uri (namespace_uris[i]);
+
+			g_ptr_array_add (namespaces, g_object_ref (namespace));
+		}
+
+		g_strfreev (namespace_uris);
 	}
 
 	*length = namespaces->len;
@@ -227,9 +273,21 @@ tracker_ontologies_get_ontologies (guint *length)
 TrackerClass **
 tracker_ontologies_get_classes (guint *length)
 {
-	if (G_UNLIKELY (!classes)) {
-		*length = 0;
-		return NULL;
+	if (properties->len == 0 && gvdb_table) {
+		gchar **class_uris;
+		gint i;
+
+		class_uris = gvdb_table_list (gvdb_classes_table, "");
+
+		for (i = 0; class_uris[i]; i++) {
+			TrackerClass *class;
+
+			class = tracker_ontologies_get_class_by_uri (class_uris[i]);
+
+			g_ptr_array_add (classes, g_object_ref (class));
+		}
+
+		g_strfreev (class_uris);
 	}
 
 	*length = classes->len;
@@ -239,9 +297,21 @@ tracker_ontologies_get_classes (guint *length)
 TrackerProperty **
 tracker_ontologies_get_properties (guint *length)
 {
-	if (G_UNLIKELY (!properties)) {
-		*length = 0;
-		return NULL;
+	if (properties->len == 0 && gvdb_table) {
+		gchar **property_uris;
+		gint i;
+
+		property_uris = gvdb_table_list (gvdb_properties_table, "");
+
+		for (i = 0; property_uris[i]; i++) {
+			TrackerProperty *property;
+
+			property = tracker_ontologies_get_property_by_uri (property_uris[i]);
+
+			g_ptr_array_add (properties, g_object_ref (property));
+		}
+
+		g_strfreev (property_uris);
 	}
 
 	*length = properties->len;
@@ -283,9 +353,22 @@ tracker_ontologies_add_id_uri_pair (gint id, const gchar *uri)
 TrackerProperty *
 tracker_ontologies_get_property_by_uri (const gchar *uri)
 {
+	TrackerProperty *property;
+
 	g_return_val_if_fail (uri != NULL, NULL);
 
-	return g_hash_table_lookup (property_uris, uri);
+	property = g_hash_table_lookup (property_uris, uri);
+
+	if (!property && gvdb_table) {
+		property = tracker_property_new (TRUE);
+		tracker_property_set_uri (property, uri);
+
+		g_hash_table_insert (property_uris,
+		                     g_strdup (uri),
+		                     property);
+	}
+
+	return property;
 }
 
 void
@@ -323,9 +406,22 @@ tracker_ontologies_add_ontology (TrackerOntology *ontology)
 TrackerNamespace *
 tracker_ontologies_get_namespace_by_uri (const gchar *uri)
 {
+	TrackerNamespace *namespace;
+
 	g_return_val_if_fail (uri != NULL, NULL);
 
-	return g_hash_table_lookup (namespace_uris, uri);
+	namespace = g_hash_table_lookup (namespace_uris, uri);
+
+	if (!namespace && gvdb_table) {
+		namespace = tracker_namespace_new (TRUE);
+		tracker_namespace_set_uri (namespace, uri);
+
+		g_hash_table_insert (namespace_uris,
+			             g_strdup (uri),
+			             namespace);
+	}
+
+	return namespace;
 }
 
 
@@ -336,3 +432,235 @@ tracker_ontologies_get_ontology_by_uri (const gchar *uri)
 
 	return g_hash_table_lookup (ontology_uris, uri);
 }
+
+static void
+gvdb_hash_table_insert_variant (GHashTable  *table,
+                                GvdbItem    *parent,
+                                const gchar *uri,
+                                const gchar *predicate,
+                                GVariant    *value)
+{
+	gchar *key;
+	GvdbItem *item;
+
+	key = g_strdup_printf ("%s#%s", uri, predicate);
+	item = gvdb_hash_table_insert (table, key);
+	gvdb_item_set_parent (item, parent);
+	gvdb_item_set_value (item, value);
+	g_free (key);
+}
+
+static GvdbItem *
+gvdb_hash_table_insert_item (GHashTable *table,
+                             GvdbItem   *root,
+                             const gchar *uri)
+{
+	GvdbItem *item;
+
+	item = gvdb_hash_table_insert (table, uri);
+	gvdb_item_set_parent (item, root);
+
+	return item;
+}
+
+static void
+gvdb_hash_table_insert_statement (GHashTable  *table,
+                                  GvdbItem    *parent,
+                                  const gchar *uri,
+                                  const gchar *predicate,
+                                  const gchar *value)
+{
+	gvdb_hash_table_insert_variant (table, parent, uri, predicate, g_variant_new_string (value));
+}
+
+void
+tracker_ontologies_write_gvdb (const gchar  *filename,
+                               GError      **error)
+{
+	GHashTable *gvdb_table, *table;
+	GvdbItem *root, *item;
+	const gchar *uri;
+	gint i;
+
+	gvdb_table = gvdb_hash_table_new (NULL, NULL);
+
+	table = gvdb_hash_table_new (gvdb_table, "namespaces");
+	root = gvdb_hash_table_insert (table, "");
+	for (i = 0; i < namespaces->len; i++) {
+		TrackerNamespace *namespace;
+
+		namespace = namespaces->pdata[i];
+		uri = tracker_namespace_get_uri (namespace);
+
+		item = gvdb_hash_table_insert_item (table, root, uri);
+
+		gvdb_hash_table_insert_statement (table, item, uri, "prefix", tracker_namespace_get_prefix (namespace));
+	}
+
+	table = gvdb_hash_table_new (gvdb_table, "classes");
+	root = gvdb_hash_table_insert (table, "");
+	for (i = 0; i < classes->len; i++) {
+		TrackerClass *class;
+		TrackerClass **super_classes;
+		GVariantBuilder builder;
+
+		class = classes->pdata[i];
+		uri = tracker_class_get_uri (class);
+
+		item = gvdb_hash_table_insert_item (table, root, uri);
+
+		gvdb_hash_table_insert_statement (table, item, uri, "name", tracker_class_get_name (class));
+
+		super_classes = tracker_class_get_super_classes (class);
+		if (super_classes) {
+			g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+
+			while (*super_classes) {
+				g_variant_builder_add (&builder, "s", tracker_class_get_uri (*super_classes));
+				super_classes++;
+			}
+
+			gvdb_hash_table_insert_variant (table, item, uri, "super-classes", g_variant_builder_end (&builder));
+		}
+	}
+
+	table = gvdb_hash_table_new (gvdb_table, "properties");
+	root = gvdb_hash_table_insert (table, "");
+	for (i = 0; i < properties->len; i++) {
+		TrackerProperty *property;
+		TrackerClass **domain_indexes;
+		GVariantBuilder builder;
+
+		property = properties->pdata[i];
+		uri = tracker_property_get_uri (property);
+
+		item = gvdb_hash_table_insert_item (table, root, uri);
+
+		gvdb_hash_table_insert_statement (table, item, uri, "name", tracker_property_get_name (property));
+		gvdb_hash_table_insert_statement (table, item, uri, "domain", tracker_class_get_uri (tracker_property_get_domain (property)));
+		gvdb_hash_table_insert_statement (table, item, uri, "range", tracker_class_get_uri (tracker_property_get_range (property)));
+
+		if (!tracker_property_get_multiple_values (property)) {
+			gvdb_hash_table_insert_variant (table, item, uri, "max-cardinality", g_variant_new_int32 (1));
+		}
+
+		if (tracker_property_get_is_inverse_functional_property (property)) {
+			gvdb_hash_table_insert_variant (table, item, uri, "inverse-functional", g_variant_new_boolean (TRUE));
+		}
+
+		domain_indexes = tracker_property_get_domain_indexes (property);
+		if (domain_indexes) {
+			g_variant_builder_init (&builder, G_VARIANT_TYPE ("as"));
+
+			while (*domain_indexes) {
+				g_variant_builder_add (&builder, "s", tracker_class_get_uri (*domain_indexes));
+				domain_indexes++;
+			}
+
+			gvdb_hash_table_insert_variant (table, item, uri, "domain-indexes", g_variant_builder_end (&builder));
+		}
+	}
+
+	gvdb_table_write_contents (gvdb_table, filename, FALSE, error);
+
+	g_hash_table_unref (gvdb_table);
+}
+
+void
+tracker_ontologies_load_gvdb (const gchar  *filename,
+                              GError      **error)
+{
+	tracker_ontologies_shutdown ();
+
+	tracker_ontologies_init ();
+
+	gvdb_table = gvdb_table_new (filename, TRUE, error);
+
+	gvdb_namespaces_table = gvdb_table_get_table (gvdb_table, "namespaces");
+	gvdb_classes_table = gvdb_table_get_table (gvdb_table, "classes");
+	gvdb_properties_table = gvdb_table_get_table (gvdb_table, "properties");
+}
+
+GVariant *
+tracker_ontologies_get_namespace_value_gvdb (const gchar *uri,
+                                             const gchar *predicate)
+{
+	gchar *key;
+	GVariant *value;
+
+	key = g_strdup_printf ("%s#%s", uri, predicate);
+	value = gvdb_table_get_value (gvdb_namespaces_table, key);
+	g_free (key);
+
+	return value;
+}
+
+const gchar *
+tracker_ontologies_get_namespace_string_gvdb (const gchar *uri,
+                                              const gchar *predicate)
+{
+	GVariant *value;
+	const gchar *result;
+
+	value = tracker_ontologies_get_namespace_value_gvdb (uri, predicate);
+	result = g_variant_get_string (value, NULL);
+	g_variant_unref (value);
+
+	return result;
+}
+
+GVariant *
+tracker_ontologies_get_class_value_gvdb (const gchar *uri,
+                                         const gchar *predicate)
+{
+	gchar *key;
+	GVariant *value;
+
+	key = g_strdup_printf ("%s#%s", uri, predicate);
+	value = gvdb_table_get_value (gvdb_classes_table, key);
+	g_free (key);
+
+	return value;
+}
+
+const gchar *
+tracker_ontologies_get_class_string_gvdb (const gchar *uri,
+                                          const gchar *predicate)
+{
+	GVariant *value;
+	const gchar *result;
+
+	value = tracker_ontologies_get_class_value_gvdb (uri, predicate);
+	result = g_variant_get_string (value, NULL);
+	g_variant_unref (value);
+
+	return result;
+}
+
+GVariant *
+tracker_ontologies_get_property_value_gvdb (const gchar *uri,
+                                            const gchar *predicate)
+{
+	gchar *key;
+	GVariant *value;
+
+	key = g_strdup_printf ("%s#%s", uri, predicate);
+	value = gvdb_table_get_value (gvdb_properties_table, key);
+	g_free (key);
+
+	return value;
+}
+
+const gchar *
+tracker_ontologies_get_property_string_gvdb (const gchar *uri,
+                                             const gchar *predicate)
+{
+	GVariant *value;
+	const gchar *result;
+
+	value = tracker_ontologies_get_property_value_gvdb (uri, predicate);
+	result = g_variant_get_string (value, NULL);
+	g_variant_unref (value);
+
+	return result;
+}
diff --git a/src/libtracker-data/tracker-ontologies.h b/src/libtracker-data/tracker-ontologies.h
index 278a79d..efde10b 100644
--- a/src/libtracker-data/tracker-ontologies.h
+++ b/src/libtracker-data/tracker-ontologies.h
@@ -59,6 +59,23 @@ const gchar*       tracker_ontologies_get_uri_by_id        (gint              id
 void               tracker_ontologies_add_id_uri_pair      (gint              id,
                                                             const gchar      *uri);
 
+void               tracker_ontologies_write_gvdb           (const gchar      *filename,
+                                                            GError          **error);
+void               tracker_ontologies_load_gvdb            (const gchar      *filename,
+                                                            GError          **error);
+GVariant *         tracker_ontologies_get_namespace_value_gvdb  (const gchar      *uri,
+                                                                 const gchar      *predicate);
+const gchar *      tracker_ontologies_get_namespace_string_gvdb (const gchar      *uri,
+                                                                 const gchar      *predicate);
+GVariant *         tracker_ontologies_get_class_value_gvdb      (const gchar      *uri,
+                                                                 const gchar      *predicate);
+const gchar *      tracker_ontologies_get_class_string_gvdb     (const gchar      *uri,
+                                                                 const gchar      *predicate);
+GVariant *         tracker_ontologies_get_property_value_gvdb   (const gchar      *uri,
+                                                                 const gchar      *predicate);
+const gchar *      tracker_ontologies_get_property_string_gvdb  (const gchar      *uri,
+                                                                 const gchar      *predicate);
+
 G_END_DECLS
 
 #endif /* __LIBTRACKER_DATA_ONTOLOGY_H__ */
diff --git a/src/libtracker-data/tracker-property.c b/src/libtracker-data/tracker-property.c
index 9a111a4..9a89345 100644
--- a/src/libtracker-data/tracker-property.c
+++ b/src/libtracker-data/tracker-property.c
@@ -45,6 +45,8 @@ struct _TrackerPropertyPrivate {
 	gchar         *name;
 	gchar         *table_name;
 
+	gboolean       use_gvdb;
+
 	TrackerPropertyType  data_type;
 	TrackerClass   *domain;
 	TrackerClass   *domain_index;
@@ -186,12 +188,18 @@ property_finalize (GObject *object)
  * Returns: The newly created #TrackerProperty
  **/
 TrackerProperty *
-tracker_property_new (void)
+tracker_property_new (gboolean use_gvdb)
 {
 	TrackerProperty *property;
+	TrackerPropertyPrivate *priv;
 
 	property = g_object_new (TRACKER_TYPE_PROPERTY, NULL);
 
+	if (use_gvdb) {
+		priv = GET_PRIV (property);
+		priv->use_gvdb = use_gvdb;
+	}
+
 	return property;
 }
 
@@ -242,12 +250,12 @@ tracker_property_get_table_name (TrackerProperty *property)
 	priv = GET_PRIV (property);
 
 	if (!priv->table_name) {
-		if (priv->multiple_values) {
+		if (tracker_property_get_multiple_values (property)) {
 			priv->table_name = g_strdup_printf ("%s_%s",
-				tracker_class_get_name (priv->domain),
-				priv->name);
+				tracker_class_get_name (tracker_property_get_domain (property)),
+				tracker_property_get_name (property));
 		} else {
-			priv->table_name = g_strdup (tracker_class_get_name (priv->domain));
+			priv->table_name = g_strdup (tracker_class_get_name (tracker_property_get_domain (property)));
 		}
 	}
 
@@ -263,6 +271,27 @@ tracker_property_get_data_type (TrackerProperty *property)
 
 	priv = GET_PRIV (property);
 
+	if (priv->use_gvdb) {
+		const gchar *range_uri;
+
+		range_uri = tracker_ontologies_get_property_string_gvdb (priv->uri, "range");
+		if (strcmp (range_uri, XSD_STRING) == 0) {
+			priv->data_type = TRACKER_PROPERTY_TYPE_STRING;
+		} else if (strcmp (range_uri, XSD_BOOLEAN) == 0) {
+			priv->data_type = TRACKER_PROPERTY_TYPE_BOOLEAN;
+		} else if (strcmp (range_uri, XSD_INTEGER) == 0) {
+			priv->data_type = TRACKER_PROPERTY_TYPE_INTEGER;
+		} else if (strcmp (range_uri, XSD_DOUBLE) == 0) {
+			priv->data_type = TRACKER_PROPERTY_TYPE_DOUBLE;
+		} else if (strcmp (range_uri, XSD_DATE) == 0) {
+			priv->data_type = TRACKER_PROPERTY_TYPE_DATE;
+		} else if (strcmp (range_uri, XSD_DATETIME) == 0) {
+			priv->data_type = TRACKER_PROPERTY_TYPE_DATETIME;
+		} else {
+			priv->data_type = TRACKER_PROPERTY_TYPE_RESOURCE;
+		}
+	}
+
 	return priv->data_type;
 }
 
@@ -278,6 +307,10 @@ tracker_property_get_domain (TrackerProperty *property)
 
 	priv = GET_PRIV (property);
 
+	if (!priv->domain && priv->use_gvdb) {
+		priv->domain = tracker_ontologies_get_class_by_uri (tracker_ontologies_get_property_string_gvdb (priv->uri, "domain"));
+	}
+
 	return priv->domain;
 }
 
@@ -293,6 +326,29 @@ tracker_property_get_domain_indexes (TrackerProperty *property)
 
 	priv = GET_PRIV (property);
 
+	if (priv->use_gvdb) {
+		TrackerClass *domain_index;
+		GVariant *variant;
+
+		tracker_property_reset_domain_indexes (property);
+
+		variant = tracker_ontologies_get_property_value_gvdb (priv->uri, "domain-indexes");
+		if (variant) {
+			GVariantIter iter;
+			gchar *uri;
+
+			g_variant_iter_init (&iter, variant);
+			while (g_variant_iter_loop (&iter, "s", &uri)) {
+				domain_index = tracker_ontologies_get_class_by_uri (uri);
+				g_free (uri);
+
+				tracker_property_add_domain_index (property, domain_index);
+
+				g_object_unref (domain_index);
+			}
+		}
+	}
+
 	return (TrackerClass ** ) priv->domain_indexes->data;
 }
 
@@ -305,6 +361,10 @@ tracker_property_get_range (TrackerProperty *property)
 
 	priv = GET_PRIV (property);
 
+	if (!priv->range && priv->use_gvdb) {
+		priv->range = tracker_ontologies_get_class_by_uri (tracker_ontologies_get_property_string_gvdb (priv->uri, "range"));
+	}
+
 	return priv->range;
 }
 
@@ -465,6 +525,21 @@ tracker_property_get_multiple_values (TrackerProperty *property)
 
 	priv = GET_PRIV (property);
 
+	if (priv->use_gvdb) {
+		GVariant *value;
+		gboolean result;
+
+		value = tracker_ontologies_get_property_value_gvdb (priv->uri, "max-cardinality");
+		if (value != NULL) {
+			result = FALSE;
+			g_variant_unref (value);
+		} else {
+			result = TRUE;
+		}
+
+		return result;
+	}
+
 	return priv->multiple_values;
 }
 
@@ -489,6 +564,21 @@ tracker_property_get_is_inverse_functional_property (TrackerProperty *property)
 
 	priv = GET_PRIV (property);
 
+	if (priv->use_gvdb) {
+		GVariant *value;
+		gboolean result;
+
+		value = tracker_ontologies_get_property_value_gvdb (priv->uri, "inverse-functional");
+		if (value != NULL) {
+			result = g_variant_get_boolean (value);
+			g_variant_unref (value);
+		} else {
+			result = FALSE;
+		}
+
+		return result;
+	}
+
 	return priv->is_inverse_functional_property;
 }
 
diff --git a/src/libtracker-data/tracker-property.h b/src/libtracker-data/tracker-property.h
index d831938..4db4368 100644
--- a/src/libtracker-data/tracker-property.h
+++ b/src/libtracker-data/tracker-property.h
@@ -73,7 +73,7 @@ struct _TrackerPropertyClass {
 };
 
 GType               tracker_property_get_type                (void) G_GNUC_CONST;
-TrackerProperty *   tracker_property_new                     (void);
+TrackerProperty *   tracker_property_new                     (gboolean              use_gvdb);
 const gchar *       tracker_property_get_uri                 (TrackerProperty      *property);
 const gchar *       tracker_property_get_name                (TrackerProperty      *property);
 const gchar *       tracker_property_get_table_name          (TrackerProperty      *property);



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