[tracker] Transient properties
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: svn-commits-list gnome org
- Subject: [tracker] Transient properties
- Date: Mon, 20 Apr 2009 07:00:04 -0400 (EDT)
commit 577a178dbae40783e5c1bf39b099dba509e57db5
Author: Philip Van Hoof <philip codeminded be>
Date: Mon Apr 20 12:56:38 2009 +0200
Transient properties
Added support for transient properties. Right now the support for these
properties still stores physically. This is done that way because if we'd use
TEMPORARY tables in sqlite, the table wouldn't be shared between the processes
of trackerd and tracker-indexer. When we refactor to letting trackerd do both
writes and reads, we can instead start using TEMPORARY tables. I have added
the code for this, but commented out in this commit.
---
data/ontologies/11-rdf.ontology | 4 +
src/libtracker-common/tracker-property.c | 55 +++++++-
src/libtracker-common/tracker-property.h | 3 +
src/libtracker-data/tracker-data-manager.c | 220 ++++++++++++++++++++--------
4 files changed, 218 insertions(+), 64 deletions(-)
diff --git a/data/ontologies/11-rdf.ontology b/data/ontologies/11-rdf.ontology
index ae3069c..f67957d 100644
--- a/data/ontologies/11-rdf.ontology
+++ b/data/ontologies/11-rdf.ontology
@@ -80,3 +80,7 @@ tracker:fulltextIndexed a rdf:Property ;
rdfs:domain rdf:Property ;
rdfs:range xsd:boolean .
+tracker:transient a rdf:Property ;
+ nrl:maxCardinality 1 ;
+ rdfs:domain rdf:Property ;
+ rdfs:range xsd:boolean .
diff --git a/src/libtracker-common/tracker-property.c b/src/libtracker-common/tracker-property.c
index 83f6b69..7138859 100644
--- a/src/libtracker-common/tracker-property.c
+++ b/src/libtracker-common/tracker-property.c
@@ -52,6 +52,7 @@ struct _TrackerPropertyPriv {
gboolean embedded;
gboolean multiple_values;
gboolean filtered;
+ gboolean transient;
GArray *super_properties;
};
@@ -78,7 +79,8 @@ enum {
PROP_FULLTEXT_INDEXED,
PROP_EMBEDDED,
PROP_MULTIPLE_VALUES,
- PROP_FILTERED
+ PROP_FILTERED,
+ PROP_TRANSIENT
};
GType
@@ -236,6 +238,13 @@ tracker_property_class_init (TrackerPropertyClass *klass)
"Filtered",
TRUE,
G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_TRANSIENT,
+ g_param_spec_boolean ("transient",
+ "transient",
+ "Transient",
+ FALSE,
+ G_PARAM_READWRITE));
g_type_class_add_private (object_class, sizeof (TrackerPropertyPriv));
}
@@ -250,6 +259,7 @@ tracker_property_init (TrackerProperty *field)
priv->weight = 1;
priv->embedded = TRUE;
priv->filtered = TRUE;
+ priv->transient = FALSE;
priv->multiple_values = TRUE;
priv->super_properties = g_array_new (TRUE, TRUE, sizeof (TrackerProperty *));
}
@@ -313,6 +323,9 @@ property_get_property (GObject *object,
case PROP_FILTERED:
g_value_set_boolean (value, priv->filtered);
break;
+ case PROP_TRANSIENT:
+ g_value_set_boolean (value, priv->transient);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -366,6 +379,10 @@ property_set_property (GObject *object,
tracker_property_set_filtered (TRACKER_PROPERTY (object),
g_value_get_boolean (value));
break;
+ case PROP_TRANSIENT:
+ tracker_property_set_transient (TRACKER_PROPERTY (object),
+ g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
break;
@@ -425,6 +442,19 @@ tracker_property_get_uri (TrackerProperty *field)
return priv->uri;
}
+gboolean
+tracker_property_get_transient (TrackerProperty *field)
+{
+ TrackerPropertyPriv *priv;
+
+ g_return_val_if_fail (TRACKER_IS_PROPERTY (field), FALSE);
+
+ priv = GET_PRIV (field);
+
+ return priv->transient;
+}
+
+
const gchar *
tracker_property_get_name (TrackerProperty *field)
{
@@ -605,6 +635,22 @@ tracker_property_set_uri (TrackerProperty *field,
}
void
+tracker_property_set_transient (TrackerProperty *field,
+ gboolean value)
+{
+ TrackerPropertyPriv *priv;
+
+ g_return_if_fail (TRACKER_IS_PROPERTY (field));
+
+ priv = GET_PRIV (field);
+
+ priv->transient = value;
+ priv->multiple_values = TRUE;
+
+ g_object_notify (G_OBJECT (field), "transient");
+}
+
+void
tracker_property_set_data_type (TrackerProperty *field,
TrackerPropertyType value)
{
@@ -747,7 +793,12 @@ tracker_property_set_multiple_values (TrackerProperty *field,
priv = GET_PRIV (field);
- priv->multiple_values = value;
+ if (priv->transient) {
+ priv->multiple_values = TRUE;
+ } else {
+ priv->multiple_values = value;
+ }
+
g_object_notify (G_OBJECT (field), "multiple-values");
}
diff --git a/src/libtracker-common/tracker-property.h b/src/libtracker-common/tracker-property.h
index 82a3230..8534851 100644
--- a/src/libtracker-common/tracker-property.h
+++ b/src/libtracker-common/tracker-property.h
@@ -88,6 +88,7 @@ gboolean tracker_property_get_fulltext_indexed(TrackerProperty *property);
gboolean tracker_property_get_embedded (TrackerProperty *property);
gboolean tracker_property_get_multiple_values (TrackerProperty *property);
gboolean tracker_property_get_filtered (TrackerProperty *property);
+gboolean tracker_property_get_transient (TrackerProperty *property);
TrackerProperty **tracker_property_get_super_properties (TrackerProperty *property);
void tracker_property_set_uri (TrackerProperty *property,
@@ -110,6 +111,8 @@ void tracker_property_set_multiple_values (TrackerProperty *property,
gboolean value);
void tracker_property_set_filtered (TrackerProperty *property,
gboolean value);
+void tracker_property_set_transient (TrackerProperty *property,
+ gboolean value);
void tracker_property_set_super_properties (TrackerProperty *property,
TrackerProperty **super_properties);
void tracker_property_add_super_property (TrackerProperty *property,
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index d8d1eae..008fd2d 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -232,6 +232,18 @@ load_ontology_file_from_path (const gchar *ontology_file)
if (strcmp (object, "true") == 0) {
tracker_property_set_indexed (property, TRUE);
}
+ } else if (strcmp (predicate, TRACKER_PREFIX "transient") == 0) {
+ TrackerProperty *property;
+
+ property = tracker_ontology_get_property_by_uri (subject);
+ if (property == NULL) {
+ g_critical ("%s: Unknown property %s", ontology_file, subject);
+ continue;
+ }
+
+ if (strcmp (object, "true") == 0) {
+ tracker_property_set_transient (property, TRUE);
+ }
} else if (strcmp (predicate, TRACKER_PREFIX "fulltextIndexed") == 0) {
TrackerProperty *property;
@@ -437,7 +449,8 @@ db_get_static_data (TrackerDBInterface *iface)
"(SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:range\"), "
"\"nrl:maxCardinality\", "
"\"tracker:indexed\", "
- "\"tracker:fulltextIndexed\" "
+ "\"tracker:fulltextIndexed\", "
+ "\"tracker:transient\" "
"FROM \"rdf:Property\" ORDER BY ID");
result_set = tracker_db_statement_execute (stmt, NULL);
g_object_unref (stmt);
@@ -450,6 +463,7 @@ db_get_static_data (TrackerDBInterface *iface)
TrackerProperty *property;
gchar *uri, *domain_uri, *range_uri;
gboolean multi_valued, indexed, fulltext_indexed;
+ gboolean transient = FALSE;
property = tracker_property_new ();
@@ -487,6 +501,16 @@ db_get_static_data (TrackerDBInterface *iface)
fulltext_indexed = FALSE;
}
+ _tracker_db_result_set_get_value (result_set, 6, &value);
+ if (G_VALUE_TYPE (&value) != 0) {
+ transient = (g_value_get_int (&value) == 1);
+ g_value_unset (&value);
+ } else {
+ /* NULL */
+ transient = FALSE;
+ }
+
+ tracker_property_set_transient (property, transient);
tracker_property_set_uri (property, uri);
tracker_property_set_domain (property, tracker_ontology_get_class_by_uri (domain_uri));
tracker_property_set_range (property, tracker_ontology_get_class_by_uri (range_uri));
@@ -509,6 +533,90 @@ db_get_static_data (TrackerDBInterface *iface)
}
static void
+create_decomposed_metadata_property_table (TrackerDBInterface *iface,
+ TrackerProperty **property,
+ const gchar *service_name,
+ const gchar **sql_type_for_single_value)
+{
+ const char *field_name;
+ const char *sql_type;
+ gboolean transient;
+
+ field_name = tracker_property_get_name (*property);
+
+ transient = !sql_type_for_single_value;
+
+ if (!transient) {
+ transient = tracker_property_get_transient (*property);
+ }
+
+ switch (tracker_property_get_data_type (*property)) {
+ case TRACKER_PROPERTY_TYPE_STRING:
+ sql_type = "TEXT";
+ break;
+ case TRACKER_PROPERTY_TYPE_INTEGER:
+ case TRACKER_PROPERTY_TYPE_BOOLEAN:
+ case TRACKER_PROPERTY_TYPE_DATE:
+ case TRACKER_PROPERTY_TYPE_DATETIME:
+ case TRACKER_PROPERTY_TYPE_RESOURCE:
+ sql_type = "INTEGER";
+ break;
+ case TRACKER_PROPERTY_TYPE_DOUBLE:
+ sql_type = "REAL";
+ break;
+ default:
+ sql_type = "";
+ break;
+ }
+
+ /* TODO: When we refactor to having writes in trackerd, we can use
+ * TEMPORARY tables instead of deleting and storing physically */
+
+ if (transient || tracker_property_get_multiple_values (*property)) {
+ /* multiple values */
+ if (tracker_property_get_indexed (*property)) {
+ /* use different UNIQUE index for properties whose
+ * value should be indexed to minimize index size */
+ tracker_db_interface_execute_query (iface, NULL,
+ "CREATE %sTABLE \"%s_%s\" ("
+ "ID INTEGER NOT NULL, "
+ "\"%s\" %s NOT NULL, "
+ "UNIQUE (\"%s\", ID))",
+ transient ? "" /*"TEMPORARY "*/ : "",
+ service_name,
+ field_name,
+ field_name,
+ sql_type,
+ field_name);
+
+ tracker_db_interface_execute_query (iface, NULL,
+ "CREATE INDEX \"%s_%s_ID\" ON \"%s_%s\" (ID)",
+ service_name,
+ field_name,
+ service_name,
+ field_name);
+ } else {
+ /* we still have to include the property value in
+ * the unique index for proper constraints */
+ tracker_db_interface_execute_query (iface, NULL,
+ "CREATE %sTABLE \"%s_%s\" ("
+ "ID INTEGER NOT NULL, "
+ "\"%s\" %s NOT NULL, "
+ "UNIQUE (ID, \"%s\"))",
+ transient ? "" /*"TEMPORARY "*/ : "",
+ service_name,
+ field_name,
+ field_name,
+ sql_type,
+ field_name);
+ }
+ } else if (sql_type_for_single_value) {
+ *sql_type_for_single_value = sql_type;
+ }
+
+}
+
+static void
create_decomposed_metadata_tables (TrackerDBInterface *iface,
TrackerClass *service,
gint *max_id)
@@ -536,72 +644,21 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
properties = tracker_ontology_get_properties ();
class_properties = NULL;
for (property = properties; *property; property++) {
- const char *field_name;
-
- field_name = tracker_property_get_name (*property);
if (tracker_property_get_domain (*property) == service) {
- const char *sql_type;
-
- switch (tracker_property_get_data_type (*property)) {
- case TRACKER_PROPERTY_TYPE_STRING:
- sql_type = "TEXT";
- break;
- case TRACKER_PROPERTY_TYPE_INTEGER:
- case TRACKER_PROPERTY_TYPE_BOOLEAN:
- case TRACKER_PROPERTY_TYPE_DATE:
- case TRACKER_PROPERTY_TYPE_DATETIME:
- case TRACKER_PROPERTY_TYPE_RESOURCE:
- sql_type = "INTEGER";
- break;
- case TRACKER_PROPERTY_TYPE_DOUBLE:
- sql_type = "REAL";
- break;
- default:
- sql_type = "";
- break;
- }
+ const gchar *sql_type_for_single_value = NULL;
- if (tracker_property_get_multiple_values (*property)) {
- /* multiple values */
- if (tracker_property_get_indexed (*property)) {
- /* use different UNIQUE index for properties whose
- * value should be indexed to minimize index size */
- tracker_db_interface_execute_query (iface, NULL,
- "CREATE TABLE \"%s_%s\" ("
- "ID INTEGER NOT NULL, "
- "\"%s\" %s NOT NULL, "
- "UNIQUE (\"%s\", ID))",
- service_name,
- field_name,
- field_name,
- sql_type,
- field_name);
-
- tracker_db_interface_execute_query (iface, NULL,
- "CREATE INDEX \"%s_%s_ID\" ON \"%s_%s\" (ID)",
- service_name,
- field_name,
- service_name,
- field_name);
- } else {
- /* we still have to include the property value in
- * the unique index for proper constraints */
- tracker_db_interface_execute_query (iface, NULL,
- "CREATE TABLE \"%s_%s\" ("
- "ID INTEGER NOT NULL, "
- "\"%s\" %s NOT NULL, "
- "UNIQUE (ID, \"%s\"))",
- service_name,
- field_name,
- field_name,
- sql_type,
- field_name);
- }
- } else {
+ create_decomposed_metadata_property_table (iface, property,
+ service_name,
+ &sql_type_for_single_value);
+
+ if (sql_type_for_single_value) {
/* single value */
class_properties = g_slist_prepend (class_properties, *property);
- g_string_append_printf (sql, ", \"%s\" %s", field_name, sql_type);
+
+ g_string_append_printf (sql, ", \"%s\" %s",
+ tracker_property_get_name (*property),
+ sql_type_for_single_value);
}
}
}
@@ -650,6 +707,44 @@ create_decomposed_metadata_tables (TrackerDBInterface *iface,
}
}
+static void
+create_decomposed_transient_metadata_tables (TrackerDBInterface *iface)
+{
+ TrackerProperty **properties;
+ TrackerProperty **property;
+
+ properties = tracker_ontology_get_properties ();
+
+ for (property = properties; *property; property++) {
+ if (tracker_property_get_transient (*property)) {
+
+ TrackerClass *domain;
+ const gchar *service_name;
+ const char *field_name;
+
+ field_name = tracker_property_get_name (*property);
+
+ domain = tracker_property_get_domain (*property);
+ service_name = tracker_class_get_name (domain);
+
+ /* TODO: When we refactor to having writes in trackerd, we can use
+ * TEMPORARY tables instead of deleting and storing physically
+
+ * create_decomposed_metadata_property_table (iface, property,
+ * service_name,
+ * NULL);
+ */
+
+ tracker_db_interface_execute_query (iface, NULL,
+ "DELETE FROM \"%s_%s\"",
+ service_name,
+ field_name);
+ }
+ }
+
+ g_free (properties);
+}
+
gboolean
tracker_data_manager_init (TrackerConfig *config,
TrackerLanguage *language,
@@ -781,6 +876,7 @@ tracker_data_manager_init (TrackerConfig *config,
} else {
/* load ontology from database into memory */
db_get_static_data (iface);
+ create_decomposed_transient_metadata_tables (iface);
}
return TRUE;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]