[tracker/property-changes-for-review: 2/5] libtracker-data: Support for ontology change tracker:notify, tracker:writeback and tracker:indexed
- From: Philip Van Hoof <pvanhoof src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/property-changes-for-review: 2/5] libtracker-data: Support for ontology change tracker:notify, tracker:writeback and tracker:indexed
- Date: Mon, 5 Apr 2010 14:31:48 +0000 (UTC)
commit 1b365e489ed9275c99ccd458a7cf5fafd9340354
Author: Philip Van Hoof <philip codeminded be>
Date: Wed Mar 31 11:40:57 2010 +0200
libtracker-data: Support for ontology change tracker:notify, tracker:writeback and tracker:indexed
src/libtracker-data/tracker-class.c | 53 +++
src/libtracker-data/tracker-class.h | 8 +-
src/libtracker-data/tracker-data-manager.c | 351 +++++++++++++++++---
src/libtracker-data/tracker-data-manager.h | 7 +-
src/libtracker-data/tracker-data-update.c | 41 ++-
src/libtracker-data/tracker-property.c | 52 +++
src/libtracker-data/tracker-property.h | 6 +
.../change/source/99-example.ontology.v2 | 3 +-
.../change/source/99-example.ontology.v3 | 3 +-
.../change/source/99-example.ontology.v4 | 7 +
.../change/updates/99-example.queries.v3 | 2 +-
11 files changed, 472 insertions(+), 61 deletions(-)
---
diff --git a/src/libtracker-data/tracker-class.c b/src/libtracker-data/tracker-class.c
index b2375e6..0fc2599 100644
--- a/src/libtracker-data/tracker-class.c
+++ b/src/libtracker-data/tracker-class.c
@@ -39,6 +39,8 @@ struct _TrackerClassPriv {
gint count;
gint id;
gboolean is_new;
+ gboolean need_recreate;
+ gboolean notify;
GArray *super_classes;
};
@@ -165,6 +167,30 @@ tracker_class_get_is_new (TrackerClass *service)
return priv->is_new;
}
+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;
+
+ g_return_val_if_fail (TRACKER_IS_CLASS (service), FALSE);
+
+ priv = GET_PRIV (service);
+
+ return priv->need_recreate;
+}
+
void
tracker_class_set_uri (TrackerClass *service,
const gchar *value)
@@ -260,3 +286,30 @@ tracker_class_set_is_new (TrackerClass *service,
priv->is_new = value;
}
+
+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)
+{
+ TrackerClassPriv *priv;
+
+ g_return_if_fail (TRACKER_IS_CLASS (service));
+
+ priv = GET_PRIV (service);
+
+ priv->need_recreate = value;
+}
+
diff --git a/src/libtracker-data/tracker-class.h b/src/libtracker-data/tracker-class.h
index c6c0acd..0b1725b 100644
--- a/src/libtracker-data/tracker-class.h
+++ b/src/libtracker-data/tracker-class.h
@@ -54,8 +54,10 @@ 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_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,
@@ -66,6 +68,10 @@ void tracker_class_set_id (TrackerClass *service,
gint id);
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 ef29b66..7573b47 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -46,6 +46,7 @@
#include "tracker-ontology.h"
#include "tracker-property.h"
#include "tracker-sparql-query.h"
+#include "tracker-data-query.h"
#define RDF_PREFIX TRACKER_RDF_PREFIX
#define RDF_PROPERTY RDF_PREFIX "Property"
@@ -69,9 +70,147 @@
#define ZLIBBUFSIZ 8192
-static gchar *ontologies_dir;
-static gboolean initialized;
-static gboolean in_journal_replay;
+static gchar *ontologies_dir;
+static gboolean initialized;
+static gboolean in_journal_replay;
+
+static void
+set_index_for_single_value_property (TrackerDBInterface *iface,
+ const gchar *service_name,
+ const gchar *field_name,
+ gboolean enabled)
+{
+ if (enabled) {
+ tracker_db_interface_execute_query (iface, NULL,
+ "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\")",
+ service_name,
+ field_name,
+ service_name,
+ field_name);
+ } else {
+ tracker_db_interface_execute_query (iface, NULL,
+ "DROP INDEX IF EXISTS \"%s_%s\"",
+ service_name,
+ field_name);
+ }
+}
+
+static void
+set_index_for_multi_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_ID_ID\"",
+ service_name,
+ field_name);
+
+ if (enabled) {
+ tracker_db_interface_execute_query (iface, NULL,
+ "CREATE INDEX \"%s_%s_ID\" ON \"%s_%s\" (ID)",
+ service_name,
+ field_name,
+ service_name,
+ field_name);
+ tracker_db_interface_execute_query (iface, NULL,
+ "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (\"%s\", ID)",
+ service_name,
+ field_name,
+ service_name,
+ field_name,
+ field_name);
+ } else {
+ tracker_db_interface_execute_query (iface, NULL,
+ "DROP INDEX IF EXISTS \"%s_%s_ID\"",
+ service_name,
+ field_name);
+ tracker_db_interface_execute_query (iface, NULL,
+ "CREATE UNIQUE INDEX \"%s_%s_ID_ID\" ON \"%s_%s\" (ID, \"%s\")",
+ service_name,
+ field_name,
+ service_name,
+ field_name,
+ field_name);
+ }
+}
+
+static gboolean
+update_property_value (const gchar *kind,
+ const gchar *subject,
+ const gchar *predicate,
+ const gchar *object)
+{
+ GError *error = NULL;
+ TrackerDBResultSet *result_set;
+ gchar *query;
+ gboolean needed = TRUE;
+
+ query = g_strdup_printf ("SELECT ?old_value WHERE { "
+ "<%s> %s ?old_value "
+ "}", subject, kind);
+
+ result_set = tracker_data_query_sparql (query, &error);
+
+ g_free (query);
+
+ if (!error && result_set) {
+ gchar *str = NULL;
+
+ tracker_db_result_set_get (result_set, 0, &str, -1);
+
+ if (g_strcmp0 (object, str) == 0) {
+ needed = FALSE;
+ } else {
+ tracker_data_delete_statement (NULL, subject, predicate, str, &error);
+ if (!error)
+ tracker_data_update_buffer_flush (&error);
+ }
+
+ g_free (str);
+ }
+
+ if (result_set) {
+ g_object_unref (result_set);
+ }
+
+ if (!error && needed) {
+ tracker_data_insert_statement (NULL, subject,
+ predicate, object,
+ &error);
+ if (!error)
+ tracker_data_update_buffer_flush (&error);
+ }
+
+ if (error) {
+ g_critical ("Ontology change: %s", error->message);
+ g_clear_error (&error);
+ }
+
+ 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,
@@ -82,15 +221,24 @@ 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 (!in_update)
+ 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);
+ } else {
+ /* Reset for a correct post-check */
+ tracker_class_set_notify (class, FALSE);
+ }
return;
}
@@ -105,6 +253,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 {
@@ -114,9 +265,17 @@ 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) {
- if (!in_update)
+ 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);
+ } else {
+ /* Reset for a correct post-check */
+ tracker_property_set_indexed (property, FALSE);
+ tracker_property_set_writeback (property, FALSE);
+ }
return;
}
@@ -131,6 +290,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 {
@@ -198,6 +360,29 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
}
tracker_class_add_super_class (class, super_class);
+ } else if (g_strcmp0 (predicate, TRACKER_PREFIX "notify") == 0) {
+ TrackerClass *class;
+
+ class = tracker_ontologies_get_class_by_uri (subject);
+
+ if (class == NULL) {
+ g_critical ("%s: Unknown class %s", ontology_path, subject);
+ return;
+ }
+
+ tracker_class_set_notify (class, (strcmp (object, "true") == 0));
+
+ } else if (g_strcmp0 (predicate, TRACKER_PREFIX "writeback") == 0) {
+ TrackerProperty *property;
+
+ property = tracker_ontologies_get_property_by_uri (subject);
+
+ if (property == NULL) {
+ g_critical ("%s: Unknown property %s", ontology_path, subject);
+ return;
+ }
+
+ tracker_property_set_writeback (property, (strcmp (object, "true") == 0));
} else if (g_strcmp0 (predicate, RDFS_SUB_PROPERTY_OF) == 0) {
TrackerProperty *property, *super_property;
@@ -285,13 +470,7 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
return;
}
- if (tracker_property_get_is_new (property) != in_update) {
- return;
- }
-
- if (strcmp (object, "true") == 0) {
- tracker_property_set_indexed (property, TRUE);
- }
+ tracker_property_set_indexed (property, (strcmp (object, "true") == 0));
} else if (g_strcmp0 (predicate, TRACKER_PREFIX "transient") == 0) {
TrackerProperty *property;
@@ -349,6 +528,10 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
return;
}
+ if (tracker_property_get_is_new (property) != in_update) {
+ return;
+ }
+
if (strcmp (object, "true") == 0) {
tracker_property_set_fulltext_no_limit (property, TRUE);
}
@@ -381,13 +564,82 @@ tracker_data_ontology_load_statement (const gchar *ontology_path,
tracker_ontology_set_last_modified (ontology, tracker_string_to_date (object, NULL, NULL));
}
+}
+
+void
+tracker_data_ontology_post_check (GPtrArray *seen_classes,
+ GPtrArray *seen_properties)
+{
+ gint i;
+
+ /* This checks for properties of classes being removed from the ontology.
+ * For example when going from: prefix:A rdfs:Class ; tracker:notify true .
+ * to prefix:A rdfs:Class . */
+
+ for (i = 0; i < seen_classes->len; i++) {
+ TrackerClass *class = g_ptr_array_index (seen_classes, i);
+ const gchar *subject;
+ subject = tracker_class_get_uri (class);
+ if (tracker_class_get_notify (class)) {
+ update_property_value ("tracker:notify",
+ subject,
+ TRACKER_PREFIX "notify",
+ "true");
+ } else {
+ update_property_value ("tracker:notify",
+ subject,
+ TRACKER_PREFIX "notify",
+ "false");
+ }
+ }
+
+ for (i = 0; i < seen_properties->len; i++) {
+ TrackerProperty *property = g_ptr_array_index (seen_properties, i);
+ const gchar *subject;
+ subject = tracker_property_get_uri (property);
+ if (tracker_property_get_writeback (property)) {
+ update_property_value ("tracker:writeback",
+ subject,
+ TRACKER_PREFIX "writeback",
+ "true");
+ } else {
+ update_property_value ("tracker:writeback",
+ subject,
+ TRACKER_PREFIX "writeback",
+ "false");
+ }
+
+ if (tracker_property_get_indexed (property)) {
+ if (update_property_value ("tracker:indexed",
+ subject,
+ TRACKER_PREFIX "indexed",
+ "true")) {
+ fix_indexed (property, TRUE);
+ }
+ } else {
+ if (update_property_value ("tracker:indexed",
+ subject,
+ TRACKER_PREFIX "indexed",
+ "false")) {
+ fix_indexed (property, FALSE);
+ }
+ }
+ }
+}
+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,
- gboolean in_update)
+ gboolean in_update,
+ GPtrArray *seen_classes,
+ GPtrArray *seen_properties)
{
TrackerTurtleReader *reader;
GError *error = NULL;
@@ -399,6 +651,9 @@ load_ontology_file_from_path (const gchar *ontology_path,
return;
}
+ /* Post checks are only needed for ontology updates, not the initial
+ * ontology */
+
while (error == NULL && tracker_turtle_reader_next (reader, &error)) {
const gchar *subject, *predicate, *object;
@@ -407,7 +662,8 @@ 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);
@@ -505,7 +761,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;
@@ -535,8 +790,12 @@ load_ontology_from_journal (GHashTable **classes_out,
subject = g_hash_table_lookup (id_uri_map, GINT_TO_POINTER (subject_id));
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);
+ /* Post checks are only needed for ontology updates, not the initial
+ * ontology */
+
+ tracker_data_ontology_load_statement ("journal", subject_id, subject, predicate,
+ object, NULL, FALSE, classes, properties,
+ NULL, NULL);
}
}
@@ -1094,30 +1353,18 @@ create_decomposed_metadata_property_table (TrackerDBInterface *iface,
tracker_property_get_name (property));
}
+ tracker_db_interface_execute_query (iface, NULL,
+ "%s)", sql->str);
+
/* 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,
- "%s, "
- "UNIQUE (\"%s\", ID))",
- sql->str,
- 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);
+ set_index_for_multi_value_property (iface, service_name, field_name, TRUE);
} else {
+ set_index_for_multi_value_property (iface, service_name, field_name, FALSE);
/* we still have to include the property value in
* the unique index for proper constraints */
- tracker_db_interface_execute_query (iface, NULL,
- "%s, "
- "UNIQUE (ID, \"%s\"))",
- sql->str,
- field_name);
}
g_string_free (sql, TRUE);
@@ -1271,12 +1518,7 @@ 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);
- tracker_db_interface_execute_query (iface, NULL,
- "CREATE INDEX \"%s_%s\" ON \"%s\" (\"%s\")",
- service_name,
- field_name,
- service_name,
- field_name);
+ set_index_for_single_value_property (iface, service_name, field_name, TRUE);
}
}
@@ -1546,7 +1788,7 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
gchar *ontology_path;
g_debug ("Loading ontology %s", (char *) l->data);
ontology_path = g_build_filename (ontologies_dir, l->data, NULL);
- load_ontology_file_from_path (ontology_path, &max_id, FALSE);
+ load_ontology_file_from_path (ontology_path, &max_id, FALSE, NULL, NULL);
g_free (ontology_path);
}
@@ -1558,7 +1800,7 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
g_debug ("Loading ontology:'%s' (TEST ONTOLOGY)", test_schema_path);
- load_ontology_file_from_path (test_schema_path, &max_id, FALSE);
+ load_ontology_file_from_path (test_schema_path, &max_id, FALSE, NULL, NULL);
g_free (test_schema_path);
}
}
@@ -1613,6 +1855,11 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
GList *to_reload = NULL;
GList *ontos = NULL;
guint p;
+ GPtrArray *seen_classes;
+ GPtrArray *seen_properties;
+
+ seen_classes = g_ptr_array_new ();
+ seen_properties = g_ptr_array_new ();
/* Get all the ontology files from ontologies_dir */
sorted = get_ontologies (test_schemas != NULL, ontologies_dir);
@@ -1711,9 +1958,10 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
/* In case of first-time, this wont start at zero */
max_id = get_new_service_id (iface);
}
- /* load ontology from files into memory, set all new's
+ /* load ontology from files into memory, set all new's
* is_new to TRUE */
- load_ontology_file_from_path (ontology_path, &max_id, TRUE);
+ load_ontology_file_from_path (ontology_path, &max_id, TRUE,
+ seen_classes, seen_properties);
to_reload = g_list_prepend (to_reload, l->data);
update_nao = TRUE;
}
@@ -1723,9 +1971,10 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
/* In case of first-time, this wont start at zero */
max_id = get_new_service_id (iface);
}
- /* load ontology from files into memory, set all new's
+ /* load ontology from files into memory, set all new's
* is_new to TRUE */
- load_ontology_file_from_path (ontology_path, &max_id, TRUE);
+ load_ontology_file_from_path (ontology_path, &max_id, TRUE,
+ seen_classes, seen_properties);
to_reload = g_list_prepend (to_reload, l->data);
update_nao = TRUE;
}
@@ -1760,6 +2009,10 @@ tracker_data_manager_init (TrackerDBManagerFlags flags,
g_list_free (to_reload);
}
+ tracker_data_ontology_post_check (seen_classes, seen_properties);
+ tracker_data_ontology_free_seen (seen_classes);
+ tracker_data_ontology_free_seen (seen_properties);
+
/* Reset the is_new flag for all classes and properties */
tracker_data_ontology_import_finished ();
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..0d766cc 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;
@@ -2458,8 +2462,9 @@ ontology_statement_insert (GList *ontology_queue,
predicate = g_hash_table_lookup (id_uri_map, GINT_TO_POINTER (predicate_id));
/* 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);
+ tracker_data_ontology_load_statement ("journal", subject_id, subject, predicate,
+ 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 b59d1e6..cbe178e 100644
--- a/src/libtracker-data/tracker-property.c
+++ b/src/libtracker-data/tracker-property.c
@@ -59,6 +59,8 @@ struct _TrackerPropertyPriv {
gboolean transient;
gboolean is_inverse_functional_property;
gboolean is_new;
+ gboolean need_recreate;
+ gboolean writeback;
GArray *super_properties;
};
@@ -341,6 +343,30 @@ 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;
+
+ g_return_val_if_fail (TRACKER_IS_PROPERTY (field), FALSE);
+
+ priv = GET_PRIV (field);
+
+ return priv->need_recreate;
+}
+
+gboolean
tracker_property_get_embedded (TrackerProperty *field)
{
TrackerPropertyPriv *priv;
@@ -551,6 +577,32 @@ 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)
+{
+ TrackerPropertyPriv *priv;
+
+ g_return_if_fail (TRACKER_IS_PROPERTY (field));
+
+ priv = GET_PRIV (field);
+
+ priv->need_recreate = value;
+}
+
+void
tracker_property_set_fulltext_indexed (TrackerProperty *field,
gboolean value)
{
diff --git a/src/libtracker-data/tracker-property.h b/src/libtracker-data/tracker-property.h
index ab4e532..7eb4baa 100644
--- a/src/libtracker-data/tracker-property.h
+++ b/src/libtracker-data/tracker-property.h
@@ -87,6 +87,8 @@ 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);
TrackerProperty ** tracker_property_get_super_properties (TrackerProperty *property);
@@ -114,6 +116,10 @@ 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
(TrackerProperty *property,
gboolean value);
diff --git a/tests/libtracker-data/change/source/99-example.ontology.v2 b/tests/libtracker-data/change/source/99-example.ontology.v2
index fefb68f..10bdbb2 100644
--- a/tests/libtracker-data/change/source/99-example.ontology.v2
+++ b/tests/libtracker-data/change/source/99-example.ontology.v2
@@ -17,5 +17,6 @@ example:B a rdfs:Class ;
example:b a rdf:Property ;
rdfs:domain example:A ;
- rdfs:range example:B .
+ rdfs:range example:B ;
+ tracker:indexed true .
diff --git a/tests/libtracker-data/change/source/99-example.ontology.v3 b/tests/libtracker-data/change/source/99-example.ontology.v3
index 4c626bc..5048df1 100644
--- a/tests/libtracker-data/change/source/99-example.ontology.v3
+++ b/tests/libtracker-data/change/source/99-example.ontology.v3
@@ -31,4 +31,5 @@ example:i2 a rdf:Property ;
example:single1 a rdf:Property ;
rdfs:domain example:A ;
rdfs:range xsd:integer ;
- nrl:maxCardinality 1 .
+ nrl:maxCardinality 1 ;
+ tracker:indexed true .
diff --git a/tests/libtracker-data/change/source/99-example.ontology.v4 b/tests/libtracker-data/change/source/99-example.ontology.v4
index 706d77c..08b0a28 100644
--- a/tests/libtracker-data/change/source/99-example.ontology.v4
+++ b/tests/libtracker-data/change/source/99-example.ontology.v4
@@ -4,6 +4,7 @@
@prefix tracker: <http://www.tracker-project.org/ontologies/tracker#> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix nao: <http://www.semanticdesktop.org/ontologies/2007/08/15/nao#> .
+ prefix nrl: <http://www.semanticdesktop.org/ontologies/2007/08/15/nrl#> .
example: a tracker:Namespace, tracker:Ontology ;
nao:lastModified "2010-03-23T11:00:04Z" ;
@@ -27,6 +28,12 @@ example:i2 a rdf:Property ;
rdfs:domain example:A ;
rdfs:range xsd:integer .
+example:single1 a rdf:Property ;
+ rdfs:domain example:A ;
+ rdfs:range xsd:integer ;
+ nrl:maxCardinality 1 ;
+ tracker:indexed false .
+
example:ib a rdf:Property ;
rdfs:domain example:B ;
rdfs:range xsd:integer .
diff --git a/tests/libtracker-data/change/updates/99-example.queries.v3 b/tests/libtracker-data/change/updates/99-example.queries.v3
index 62d1b07..45b4a55 100644
--- a/tests/libtracker-data/change/updates/99-example.queries.v3
+++ b/tests/libtracker-data/change/updates/99-example.queries.v3
@@ -4,6 +4,6 @@ insert { <a01> example:i1 2 }
insert { <a01> example:i2 1 }
delete { <a01> example:i2 1 }
insert { <a01> example:i2 2 }
-insert { <a01> example:single1 1 }
+insert { <a01> example:single1 2 }
delete { <a01> example:single1 1 }
insert { <a01> example:single1 2 }
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]