[tracker/property-changes] libtracker-data: Ontology change coping for property changes
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/property-changes] libtracker-data: Ontology change coping for property changes
- Date: Fri, 2 Apr 2010 12:16:12 +0000 (UTC)
commit 820a92eafeb5e9b77e814be6e052968c33000af1
Author: Philip Van Hoof <philip codeminded be>
Date: Fri Apr 2 14:13:43 2010 +0200
libtracker-data: Ontology change coping for property changes
This post-check checks for property properties being removed from a class.
Just checking for tracker:indexed is, for example, not sufficient: It's
possible that the line got removed from the TTL file. So a post check is
needed to compare the old situation with the new situation, on top of the
already added checks comparing values.
src/libtracker-data/tracker-class.c | 26 ++++
src/libtracker-data/tracker-class.h | 5 +-
src/libtracker-data/tracker-data-manager.c | 215 +++++++++++++++++++++++++---
src/libtracker-data/tracker-data-manager.h | 7 +-
src/libtracker-data/tracker-data-update.c | 39 +++++-
src/libtracker-data/tracker-property.c | 26 ++++
src/libtracker-data/tracker-property.h | 3 +
7 files changed, 290 insertions(+), 31 deletions(-)
---
diff --git a/src/libtracker-data/tracker-class.c b/src/libtracker-data/tracker-class.c
index 7b39c96..501dd9b 100644
--- a/src/libtracker-data/tracker-class.c
+++ b/src/libtracker-data/tracker-class.c
@@ -40,6 +40,7 @@ struct _TrackerClassPriv {
gint id;
gboolean is_new;
gboolean need_recreate;
+ gboolean notify;
GArray *super_classes;
};
@@ -167,6 +168,18 @@ tracker_class_get_is_new (TrackerClass *service)
}
gboolean
+tracker_class_get_notify (TrackerClass *service)
+{
+ TrackerClassPriv *priv;
+
+ g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
+
+ priv = GET_PRIV (service);
+
+ return priv->notify;
+}
+
+gboolean
tracker_class_get_need_recreate (TrackerClass *service)
{
TrackerClassPriv *priv;
@@ -275,6 +288,19 @@ tracker_class_set_is_new (TrackerClass *service,
}
void
+tracker_class_set_notify (TrackerClass *service,
+ gboolean value)
+{
+ TrackerClassPriv *priv;
+
+ g_return_if_fail (TRACKER_IS_CLASS (service));
+
+ priv = GET_PRIV (service);
+
+ priv->notify = value;
+}
+
+void
tracker_class_set_need_recreate (TrackerClass *service,
gboolean value)
{
diff --git a/src/libtracker-data/tracker-class.h b/src/libtracker-data/tracker-class.h
index 8282606..0b1725b 100644
--- a/src/libtracker-data/tracker-class.h
+++ b/src/libtracker-data/tracker-class.h
@@ -55,8 +55,9 @@ 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);
-
+gboolean tracker_class_get_notify (TrackerClass *service);
TrackerClass **tracker_class_get_super_classes (TrackerClass *service);
+
void tracker_class_set_uri (TrackerClass *service,
const gchar *value);
void tracker_class_set_count (TrackerClass *service,
@@ -69,6 +70,8 @@ void tracker_class_set_is_new (TrackerClass *service,
gboolean value);
void tracker_class_set_need_recreate (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 b75785a..7b4030a 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -188,6 +188,28 @@ update_property_value (const gchar *kind,
return needed;
}
+
+static void
+fix_indexed (TrackerProperty *property, gboolean enabled)
+{
+ TrackerDBInterface *iface;
+ TrackerClass *class;
+ const gchar *service_name;
+ const gchar *field_name;
+
+ iface = tracker_db_manager_get_db_interface ();
+
+ class = tracker_property_get_domain (property);
+ field_name = tracker_property_get_name (property);
+ service_name = tracker_class_get_name (class);
+
+ if (tracker_property_get_multiple_values (property)) {
+ set_index_for_multi_value_property (iface, service_name, field_name, enabled);
+ } else {
+ set_index_for_single_value_property (iface, service_name, field_name, enabled);
+ }
+}
+
void
tracker_data_ontology_load_statement (const gchar *ontology_path,
gint subject_id,
@@ -197,13 +219,18 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
gint *max_id,
gboolean in_update,
GHashTable *classes,
- GHashTable *properties)
+ GHashTable *properties,
+ GPtrArray *seen_classes,
+ GPtrArray *seen_properties)
{
if (g_strcmp0 (predicate, RDF_TYPE) == 0) {
if (g_strcmp0 (object, RDFS_CLASS) == 0) {
TrackerClass *class;
+ class = tracker_ontologies_get_class_by_uri (subject);
- if (tracker_ontologies_get_class_by_uri (subject) != NULL) {
+ if (class != NULL) {
+ if (seen_classes)
+ g_ptr_array_add (seen_classes, g_object_ref (class));
if (!in_update)
g_critical ("%s: Duplicate definition of class %s", ontology_path, subject);
return;
@@ -220,6 +247,9 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
tracker_ontologies_add_class (class);
tracker_ontologies_add_id_uri_pair (subject_id, subject);
+ if (seen_classes)
+ g_ptr_array_add (seen_classes, g_object_ref (class));
+
if (classes) {
g_hash_table_insert (classes, GINT_TO_POINTER (subject_id), class);
} else {
@@ -229,7 +259,10 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
} else if (g_strcmp0 (object, RDF_PROPERTY) == 0) {
TrackerProperty *property;
- if (tracker_ontologies_get_property_by_uri (subject) != NULL) {
+ property = tracker_ontologies_get_property_by_uri (subject);
+ if (property != NULL) {
+ if (seen_properties)
+ g_ptr_array_add (seen_properties, g_object_ref (property));
if (!in_update)
g_critical ("%s: Duplicate definition of property %s", ontology_path, subject);
return;
@@ -246,6 +279,9 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
tracker_ontologies_add_property (property);
tracker_ontologies_add_id_uri_pair (subject_id, subject);
+ if (seen_properties)
+ g_ptr_array_add (seen_properties, g_object_ref (property));
+
if (properties) {
g_hash_table_insert (properties, GINT_TO_POINTER (subject_id), property);
} else {
@@ -326,6 +362,8 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
update_property_value ("tracker:notify", subject, predicate, object);
}
+ tracker_class_set_notify (class, (strcmp (object, "true") == 0));
+
} else if (g_strcmp0 (predicate, TRACKER_PREFIX "writeback") == 0) {
TrackerProperty *property;
@@ -436,24 +474,8 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
enabled = (strcmp (object, "true") == 0);
if (tracker_property_get_is_new (property) != in_update) {
-
if (update_property_value ("tracker:indexed", subject, predicate, object)) {
- TrackerDBInterface *iface;
- TrackerClass *class;
- const gchar *service_name;
- const gchar *field_name;
-
- iface = tracker_db_manager_get_db_interface ();
-
- class = tracker_property_get_domain (property);
- field_name = tracker_property_get_name (property);
- service_name = tracker_class_get_name (class);
-
- if (tracker_property_get_multiple_values (property)) {
- set_index_for_multi_value_property (iface, service_name, field_name, enabled);
- } else {
- set_index_for_single_value_property (iface, service_name, field_name, enabled);
- }
+ fix_indexed (property, enabled);
}
}
@@ -555,6 +577,139 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
}
}
+void
+tracker_data_ontology_post_check (GPtrArray *seen_classes,
+ GPtrArray *seen_properties)
+{
+ gint i;
+
+ for (i = 0; i < seen_classes->len; i++) {
+ TrackerClass *class = g_ptr_array_index (seen_classes, i);
+ GError *error = NULL;
+ TrackerDBResultSet *result_set;
+ const gchar *subject;
+ gchar *query;
+
+ subject = tracker_class_get_uri (class);
+ query = g_strdup_printf ("SELECT ?predicate ?object WHERE { <%s> ?predicate ?object }",
+ subject);
+
+ result_set = tracker_data_query_sparql (query, &error);
+ g_free (query);
+
+ if (!error && result_set) {
+ gboolean saw_notify = FALSE, is_notify;
+
+ do {
+ gchar *predicate, *old_object;
+ TrackerProperty *property;
+
+ tracker_db_result_set_get (result_set, 0, &predicate, -1);
+ tracker_db_result_set_get (result_set, 1, &old_object, -1);
+
+ property = tracker_ontologies_get_property_by_uri (predicate);
+
+ if (property != NULL) {
+ if (g_strcmp0 (predicate, TRACKER_PREFIX "notify") == 0) {
+ saw_notify = TRUE;
+ is_notify = (strcmp (old_object, "true") == 0);
+ }
+ }
+
+ g_free (old_object);
+ g_free (predicate);
+
+ } while (tracker_db_result_set_iter_next (result_set) && !saw_notify);
+
+ if (!saw_notify && tracker_class_get_notify (class)) {
+ update_property_value ("tracker:notify",
+ subject,
+ TRACKER_PREFIX "notify",
+ is_notify ? "true" : "false");
+ }
+
+ } else {
+ if (error) {
+ g_critical ("Ontology change: %s", error->message);
+ g_clear_error (&error);
+ }
+ }
+
+ if (result_set)
+ g_object_unref (result_set);
+ }
+
+ for (i = 0; i < seen_properties->len; i++) {
+ TrackerProperty *property = g_ptr_array_index (seen_properties, i);
+ GError *error = NULL;
+ TrackerDBResultSet *result_set;
+ const gchar *subject;
+ gboolean saw_writeback = FALSE, saw_indexed = FALSE;
+ gboolean is_writeback, is_indexed;
+ gchar *query;
+
+ subject = tracker_property_get_uri (property);
+ query = g_strdup_printf ("SELECT ?predicate ?object WHERE { <%s> ?predicate ?object }",
+ subject);
+ result_set = tracker_data_query_sparql (query, &error);
+ g_free (query);
+
+ if (!error && result_set) {
+ do {
+ gchar *predicate, *old_object;
+
+ tracker_db_result_set_get (result_set, 0, &predicate, -1);
+ tracker_db_result_set_get (result_set, 1, &old_object, -1);
+
+ if (!saw_writeback && g_strcmp0 (predicate, TRACKER_PREFIX "writeback") == 0) {
+ saw_writeback = TRUE;
+ is_writeback = (strcmp (old_object, "true") == 0);
+ }
+
+ if (!saw_indexed && g_strcmp0 (predicate, TRACKER_PREFIX "indexed") == 0) {
+ saw_indexed = TRUE;
+ is_indexed = (strcmp (old_object, "true") == 0);
+ }
+
+ g_free (predicate);
+ g_free (old_object);
+ } while (tracker_db_result_set_iter_next (result_set));
+
+ if (!saw_writeback && tracker_property_get_writeback (property)) {
+ update_property_value ("tracker:writeback",
+ subject,
+ TRACKER_PREFIX "writeback",
+ is_writeback ? "true" : "false");
+ }
+
+ if (!saw_indexed && tracker_property_get_indexed (property)) {
+ if (update_property_value ("tracker:indexed",
+ subject,
+ TRACKER_PREFIX "indexed",
+ is_indexed ? "true" : "false")) {
+ fix_indexed (property, is_indexed);
+ }
+ }
+
+ } else {
+ if (error) {
+ g_critical ("Ontology change: %s", error->message);
+ g_clear_error (&error);
+ }
+ }
+
+ if (result_set)
+ g_object_unref (result_set);
+ }
+}
+
+void
+tracker_data_ontology_free_seen (GPtrArray *seen)
+{
+ g_ptr_array_foreach (seen, (GFunc) g_object_unref, NULL);
+ g_ptr_array_free (seen, TRUE);
+}
+
static void
load_ontology_file_from_path (const gchar *ontology_path,
gint *max_id,
@@ -562,6 +717,8 @@ load_ontology_file_from_path (const gchar *ontology_path,
{
TrackerTurtleReader *reader;
GError *error = NULL;
+ GPtrArray *seen_classes = NULL;
+ GPtrArray *seen_properties = NULL;
reader = tracker_turtle_reader_new (ontology_path, &error);
if (error) {
@@ -570,6 +727,11 @@ load_ontology_file_from_path (const gchar *ontology_path,
return;
}
+ if (in_update) {
+ seen_classes = g_ptr_array_new ();
+ seen_properties = g_ptr_array_new ();
+ }
+
while (error == NULL && tracker_turtle_reader_next (reader, &error)) {
const gchar *subject, *predicate, *object;
@@ -578,11 +740,18 @@ load_ontology_file_from_path (const gchar *ontology_path,
object = tracker_turtle_reader_get_object (reader);
tracker_data_ontology_load_statement (ontology_path, 0, subject, predicate, object,
- max_id, in_update, NULL, NULL);
+ max_id, in_update, NULL, NULL,
+ seen_classes, seen_properties);
}
g_object_unref (reader);
+ if (in_update) {
+ tracker_data_ontology_post_check (seen_classes, seen_properties);
+ tracker_data_ontology_free_seen (seen_classes);
+ tracker_data_ontology_free_seen (seen_properties);
+ }
+
if (error) {
g_critical ("Turtle parse error: %s", error->message);
g_error_free (error);
@@ -676,7 +845,6 @@ load_ontology_from_journal (GHashTable **classes_out,
id_uri_map = g_hash_table_new (g_direct_hash, g_direct_equal);
-
while (tracker_db_journal_reader_next (NULL)) {
TrackerDBJournalEntryType type;
@@ -707,7 +875,8 @@ load_ontology_from_journal (GHashTable **classes_out,
predicate = g_hash_table_lookup (id_uri_map, GINT_TO_POINTER (predicate_id));
tracker_data_ontology_load_statement ("journal", subject_id, subject, predicate,
- object, NULL, FALSE, classes, properties);
+ object, NULL, FALSE, classes, properties,
+ NULL, NULL);
}
}
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index cb41391..38a5f2c 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -58,7 +58,9 @@ void tracker_data_ontology_load_statement (const gchar *ontolo
gint *max_id,
gboolean in_update,
GHashTable *classes,
- GHashTable *properties);
+ GHashTable *properties,
+ GPtrArray *seen_classes,
+ GPtrArray *seen_properties);
void tracker_data_ontology_import_into_db (gboolean is_new);
void tracker_data_ontology_process_statement (const gchar *graph,
const gchar *subject,
@@ -68,6 +70,9 @@ void tracker_data_ontology_process_statement (const gchar *graph,
gboolean in_update,
gboolean ignore_nao_last_modified);
void tracker_data_ontology_import_finished (void);
+void tracker_data_ontology_post_check (GPtrArray *seen_classes,
+ GPtrArray *seen_properties);
+void tracker_data_ontology_free_seen (GPtrArray *seen);
G_END_DECLS
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 37bb4b4..1190e05 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -2376,11 +2376,13 @@ queue_statement (GList *queue,
}
static void
-ontology_transaction_end (GList *ontology_queue)
+ontology_transaction_end (GList *ontology_queue, GPtrArray *seen_classes, GPtrArray *seen_properties)
{
GList *l;
const gchar *ontology_uri = NULL;
+ tracker_data_ontology_post_check (seen_classes, seen_properties);
+
/* Perform ALTER-TABLE and CREATE-TABLE calls for all that are is_new */
tracker_data_ontology_import_into_db (TRUE);
@@ -2444,7 +2446,9 @@ ontology_statement_insert (GList *ontology_queue,
GHashTable *classes,
GHashTable *properties,
GHashTable *id_uri_map,
- gboolean is_uri)
+ gboolean is_uri,
+ GPtrArray *seen_classes,
+ GPtrArray *seen_properties)
{
const gchar *graph, *subject, *predicate;
@@ -2459,7 +2463,8 @@ ontology_statement_insert (GList *ontology_queue,
/* load ontology from journal into memory, set all new's is_new to TRUE */
tracker_data_ontology_load_statement ("journal", subject_id, subject, predicate,
- object, NULL, TRUE, classes, properties);
+ object, NULL, TRUE, classes, properties,
+ seen_classes, seen_properties);
/* Queue the statement for processing after ALTER in ontology_transaction_end */
ontology_queue = queue_statement (ontology_queue, graph, subject, predicate, object, is_uri);
@@ -2480,6 +2485,8 @@ tracker_data_replay_journal (GHashTable *classes,
gint last_operation_type = 0;
gboolean in_ontology = FALSE;
GList *ontology_queue = NULL;
+ GPtrArray *seen_classes = NULL;
+ GPtrArray *seen_properties = NULL;
tracker_data_begin_db_transaction_for_replay (0);
@@ -2538,11 +2545,15 @@ tracker_data_replay_journal (GHashTable *classes,
resource_time = tracker_db_journal_reader_get_time ();
} else if (type == TRACKER_DB_JOURNAL_END_TRANSACTION) {
if (in_ontology) {
- ontology_transaction_end (ontology_queue);
+ ontology_transaction_end (ontology_queue, seen_classes, seen_properties);
g_list_foreach (ontology_queue, (GFunc) free_queued_statement, NULL);
g_list_free (ontology_queue);
ontology_queue = NULL;
in_ontology = FALSE;
+ tracker_data_ontology_free_seen (seen_classes);
+ seen_classes = NULL;
+ tracker_data_ontology_free_seen (seen_properties);
+ seen_properties = NULL;
} else {
GError *new_error = NULL;
tracker_data_update_buffer_might_flush (&new_error);
@@ -2558,6 +2569,12 @@ tracker_data_replay_journal (GHashTable *classes,
tracker_db_journal_reader_get_statement (&graph_id, &subject_id, &predicate_id, &object);
if (in_ontology) {
+
+ if (!seen_classes)
+ seen_classes = g_ptr_array_new ();
+ if (!seen_properties)
+ seen_properties = g_ptr_array_new ();
+
ontology_queue = ontology_statement_insert (ontology_queue,
graph_id,
subject_id,
@@ -2566,7 +2583,9 @@ tracker_data_replay_journal (GHashTable *classes,
classes,
properties,
id_uri_map,
- FALSE);
+ FALSE,
+ seen_classes,
+ seen_properties);
continue;
}
@@ -2605,6 +2624,12 @@ tracker_data_replay_journal (GHashTable *classes,
if (in_ontology) {
const gchar *object_n;
object_n = g_hash_table_lookup (id_uri_map, GINT_TO_POINTER (object_id));
+
+ if (!seen_classes)
+ seen_classes = g_ptr_array_new ();
+ if (!seen_properties)
+ seen_properties = g_ptr_array_new ();
+
ontology_queue = ontology_statement_insert (ontology_queue,
graph_id,
subject_id,
@@ -2613,7 +2638,9 @@ tracker_data_replay_journal (GHashTable *classes,
classes,
properties,
id_uri_map,
- TRUE);
+ TRUE,
+ seen_classes,
+ seen_properties);
continue;
}
diff --git a/src/libtracker-data/tracker-property.c b/src/libtracker-data/tracker-property.c
index 692ab74..cbe178e 100644
--- a/src/libtracker-data/tracker-property.c
+++ b/src/libtracker-data/tracker-property.c
@@ -60,6 +60,7 @@ struct _TrackerPropertyPriv {
gboolean is_inverse_functional_property;
gboolean is_new;
gboolean need_recreate;
+ gboolean writeback;
GArray *super_properties;
};
@@ -342,6 +343,18 @@ tracker_property_get_is_new (TrackerProperty *field)
}
gboolean
+tracker_property_get_writeback (TrackerProperty *field)
+{
+ TrackerPropertyPriv *priv;
+
+ g_return_val_if_fail (TRACKER_IS_PROPERTY (field), FALSE);
+
+ priv = GET_PRIV (field);
+
+ return priv->writeback;
+}
+
+gboolean
tracker_property_get_need_recreate (TrackerProperty *field)
{
TrackerPropertyPriv *priv;
@@ -564,6 +577,19 @@ tracker_property_set_is_new (TrackerProperty *field,
}
void
+tracker_property_set_writeback (TrackerProperty *field,
+ gboolean value)
+{
+ TrackerPropertyPriv *priv;
+
+ g_return_if_fail (TRACKER_IS_PROPERTY (field));
+
+ priv = GET_PRIV (field);
+
+ priv->writeback = value;
+}
+
+void
tracker_property_set_need_recreate (TrackerProperty *field,
gboolean value)
{
diff --git a/src/libtracker-data/tracker-property.h b/src/libtracker-data/tracker-property.h
index 5851566..7eb4baa 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_writeback (TrackerProperty *property);
gboolean tracker_property_get_need_recreate (TrackerProperty *property);
gboolean tracker_property_get_is_inverse_functional_property
(TrackerProperty *property);
@@ -115,6 +116,8 @@ void tracker_property_set_transient (TrackerProperty
gboolean value);
void tracker_property_set_is_new (TrackerProperty *property,
gboolean value);
+void tracker_property_set_writeback (TrackerProperty *property,
+ gboolean value);
void tracker_property_set_need_recreate (TrackerProperty *property,
gboolean value);
void tracker_property_set_is_inverse_functional_property
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]