[tracker] libtracker-data: Use update buffer for deletes as well



commit a18235987333fc427b3a775fbdb9753f5d1a154a
Author: Jürg Billeter <j bitron ch>
Date:   Mon Oct 26 17:01:05 2009 +0100

    libtracker-data: Use update buffer for deletes as well
    
    This fixes handling of FTS updates when deleting or updating property
    values by reusing the logic written for inserts.

 src/libtracker-data/tracker-data-update.c |  495 ++++++++++++++---------------
 1 files changed, 243 insertions(+), 252 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index ced18a4..8dc2497 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -79,7 +79,10 @@ struct _TrackerDataUpdateBufferProperty {
 
 struct _TrackerDataUpdateBufferTable {
 	gboolean insert;
+	gboolean delete_row;
+	gboolean delete_value;
 	gboolean multiple_values;
+	TrackerClass *class;
 	GArray *properties;
 };
 
@@ -246,11 +249,12 @@ cache_ensure_table (const gchar            *table_name,
 }
 
 static void
-cache_insert_row (const gchar            *table_name)
+cache_insert_row (TrackerClass *class)
 {
 	TrackerDataUpdateBufferTable    *table;
 
-	table = cache_ensure_table (table_name, FALSE);
+	table = cache_ensure_table (tracker_class_get_name (class), FALSE);
+	table->class = class;
 	table->insert = TRUE;
 }
 
@@ -272,6 +276,35 @@ cache_insert_value (const gchar            *table_name,
 	g_array_append_val (table->properties, property);
 }
 
+static void
+cache_delete_row (TrackerClass *class)
+{
+	TrackerDataUpdateBufferTable    *table;
+
+	table = cache_ensure_table (tracker_class_get_name (class), FALSE);
+	table->class = class;
+	table->delete_row = TRUE;
+}
+
+static void
+cache_delete_value (const gchar            *table_name,
+		    const gchar            *field_name,
+		    GValue                 *value,
+		    gboolean                multiple_values,
+		    gboolean                fts)
+{
+	TrackerDataUpdateBufferTable    *table;
+	TrackerDataUpdateBufferProperty  property;
+
+	property.name = g_strdup (field_name);
+	property.value = *value;
+	property.fts = fts;
+
+	table = cache_ensure_table (table_name, multiple_values);
+	table->delete_value = TRUE;
+	g_array_append_val (table->properties, property);
+}
+
 static guint32
 query_resource_id (const gchar *uri)
 {
@@ -377,16 +410,42 @@ tracker_data_resource_buffer_flush (void)
 			for (i = 0; i < table->properties->len; i++) {
 				property = &g_array_index (table->properties, TrackerDataUpdateBufferProperty, i);
 
-				stmt = tracker_db_interface_create_statement (iface,
-					"INSERT OR IGNORE INTO \"%s\" (ID, \"%s\") VALUES (?, ?)",
-					table_name,
-					property->name);
+				if (table->delete_value) {
+					/* delete rows for multiple value properties */
+					stmt = tracker_db_interface_create_statement (iface,
+						"DELETE FROM \"%s\" WHERE ID = ? AND \"%s\" = ?",
+						table_name,
+						property->name);
+				} else {
+					stmt = tracker_db_interface_create_statement (iface,
+						"INSERT OR IGNORE INTO \"%s\" (ID, \"%s\") VALUES (?, ?)",
+						table_name,
+						property->name);
+				}
+
 				tracker_db_statement_bind_int (stmt, 0, resource_buffer->id);
 				statement_bind_gvalue (stmt, 1, &property->value);
 				tracker_db_statement_execute (stmt, NULL);
 				g_object_unref (stmt);
 			}
 		} else {
+			if (table->delete_row) {
+				/* remove entry from rdf:type table */
+				stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"rdfs:Resource_rdf:type\" WHERE ID = ? AND \"rdf:type\" = ?");
+				tracker_db_statement_bind_int (stmt, 0, resource_buffer->id);
+				tracker_db_statement_bind_int (stmt, 1, ensure_resource_id (tracker_class_get_uri (table->class)));
+				tracker_db_statement_execute (stmt, NULL);
+				g_object_unref (stmt);
+
+				/* remove row from class table */
+				stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"%s\" WHERE ID = ?", table_name);
+				tracker_db_statement_bind_int (stmt, 0, resource_buffer->id);
+				tracker_db_statement_execute (stmt, NULL);
+				g_object_unref (stmt);
+
+				continue;
+			}
+
 			if (table->insert) {
 				/* ensure we have a row for the subject id */
 				stmt = tracker_db_interface_create_statement (iface,
@@ -419,7 +478,12 @@ tracker_data_resource_buffer_flush (void)
 
 			for (i = 0; i < table->properties->len; i++) {
 				property = &g_array_index (table->properties, TrackerDataUpdateBufferProperty, i);
-				statement_bind_gvalue (stmt, i, &property->value);
+				if (table->delete_value) {
+					/* just set value to NULL for single value properties */
+					tracker_db_statement_bind_null (stmt, i);
+				} else {
+					statement_bind_gvalue (stmt, i, &property->value);
+				}
 			}
 
 			tracker_db_statement_execute (stmt, NULL);
@@ -571,17 +635,16 @@ cache_create_service_decomposed (TrackerClass           *cl)
 		}
 	}
 
-	tracker_class_set_count (cl, tracker_class_get_count (cl) + 1);
-
 	g_ptr_array_add (resource_buffer->types, g_strdup (class_uri));
 
 	g_value_init (&gvalue, G_TYPE_INT);
 
-	cache_insert_row (tracker_class_get_name (cl));
+	cache_insert_row (cl);
 
 	g_value_set_int (&gvalue, ensure_resource_id (tracker_class_get_uri (cl)));
 	cache_insert_value ("rdfs:Resource_rdf:type", "rdf:type", &gvalue, TRUE, FALSE);
 
+	tracker_class_set_count (cl, tracker_class_get_count (cl) + 1);
 	if (insert_callback) {
 		insert_callback (resource_buffer->subject, RDF_PREFIX "type", class_uri, 
 		                 resource_buffer->types, insert_data);
@@ -632,6 +695,28 @@ value_set_add_value (GValueArray *value_set,
 }
 
 static gboolean
+value_set_remove_value (GValueArray *value_set,
+                        GValue      *value)
+{
+	gint i;
+
+	g_return_val_if_fail (G_VALUE_TYPE (value), FALSE);
+
+	for (i = 0; i < value_set->n_values; i++) {
+		if (value_equal (g_value_array_get_nth (value_set, i), value)) {
+			/* value found, remove from set */
+
+			g_value_array_remove (value_set, i);
+
+			return TRUE;
+		}
+	}
+
+	/* no change, value not found */
+	return FALSE;
+}
+
+static gboolean
 check_property_domain (TrackerProperty *property)
 {
 	gint type_index;
@@ -861,280 +946,198 @@ cache_set_metadata_decomposed (TrackerProperty	*property,
 }
 
 static void
-delete_resource_type (gint resource_id,
-		      TrackerClass           *cl)
+delete_metadata_decomposed (TrackerProperty  *property,
+			    const gchar	     *value,
+			    GError          **error)
 {
-	TrackerDBInterface  *iface;
-	TrackerDBStatement  *stmt;
-
-	iface = tracker_db_manager_get_db_interface ();
-
-	/* remove entry from rdf:type table */
-	stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"rdfs:Resource_rdf:type\" WHERE ID = ? AND \"rdf:type\" = ?");
-	tracker_db_statement_bind_int (stmt, 0, resource_id);
-	tracker_db_statement_bind_int (stmt, 1, ensure_resource_id (tracker_class_get_uri (cl)));
-	tracker_db_statement_execute (stmt, NULL);
-	g_object_unref (stmt);
-
-	/* remove row from class table */
-	stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"%s\" WHERE ID = ?", tracker_class_get_name (cl));
-	tracker_db_statement_bind_int (stmt, 0, resource_id);
-	tracker_db_statement_execute (stmt, NULL);
-	g_object_unref (stmt);
-}
-
-static void
-delete_metadata_decomposed (gint resource_id,
-			    TrackerProperty	*property,
-			    const gchar	*value)
-{
-	TrackerDBInterface  *iface;
-	TrackerDBStatement  *stmt;
-	guint32		    object_id;
-	gboolean            multiple_values;
-	const gchar *class_name, *property_name;
+	gboolean            multiple_values, fts;
+	gchar              *table_name;
+	const gchar        *field_name;
 	TrackerProperty   **super_properties;
-
-	iface = tracker_db_manager_get_db_interface ();
+	GValue gvalue = { 0 };
+	GValueArray        *old_values;
 
 	multiple_values = tracker_property_get_multiple_values (property);
-	class_name = tracker_class_get_name (tracker_property_get_domain (property));
-	property_name = tracker_property_get_name (property);
 	if (multiple_values) {
-		/* delete rows for multiple value properties */
-		stmt = tracker_db_interface_create_statement (iface,
-			"DELETE FROM \"%s_%s\" WHERE ID = ? AND \"%s\" = ?",
-			class_name, property_name, property_name);
+		table_name = g_strdup_printf ("%s_%s",
+			tracker_class_get_name (tracker_property_get_domain (property)),
+			tracker_property_get_name (property));
 	} else {
-		/* just set value to NULL for single value properties */
-		stmt = tracker_db_interface_create_statement (iface,
-			"UPDATE \"%s\" SET \"%s\" = NULL WHERE ID = ? AND \"%s\" = ?",
-			class_name, property_name, property_name);
+		table_name = g_strdup (tracker_class_get_name (tracker_property_get_domain (property)));
 	}
+	field_name = tracker_property_get_name (property);
 
-	tracker_db_statement_bind_int (stmt, 0, resource_id);
+	fts = tracker_property_get_fulltext_indexed (property);
 
-	switch (tracker_property_get_data_type (property)) {
-	case TRACKER_PROPERTY_TYPE_STRING:
-		tracker_db_statement_bind_text (stmt, 1, value);
-		break;
-	case TRACKER_PROPERTY_TYPE_INTEGER:
-		tracker_db_statement_bind_int (stmt, 1, atoi (value));
-		break;
-	case TRACKER_PROPERTY_TYPE_BOOLEAN:
-		tracker_db_statement_bind_int (stmt, 1, strcmp (value, "true") == 0);
-		break;
-	case TRACKER_PROPERTY_TYPE_DOUBLE:
-		tracker_db_statement_bind_double (stmt, 1, atof (value));
-		break;
-	case TRACKER_PROPERTY_TYPE_DATE:
-	case TRACKER_PROPERTY_TYPE_DATETIME:
-		tracker_db_statement_bind_int (stmt, 1, tracker_string_to_date (value));
-		break;
-	case TRACKER_PROPERTY_TYPE_RESOURCE:
-		object_id = ensure_resource_id (value);
-		tracker_db_statement_bind_int (stmt, 1, object_id);
-		break;
-	default:
-		g_assert_not_reached ();
+	/* read existing property values */
+	old_values = get_old_property_values (property, error);
+	if (*error) {
+		g_free (table_name);
+		return;
 	}
 
-	tracker_db_statement_execute (stmt, NULL);
-	g_object_unref (stmt);
+	string_to_gvalue (value, tracker_property_get_data_type (property), &gvalue);
+
+	if (!value_set_remove_value (old_values, &gvalue)) {
+		/* value not found */
+		g_value_unset (&gvalue);
+	} else {
+		cache_delete_value (table_name, field_name, &gvalue, multiple_values, fts);
+	}
+
+	g_free (table_name);
 
 	/* also delete super property values */
 	super_properties = tracker_property_get_super_properties (property);
 	while (*super_properties) {
-		delete_metadata_decomposed (resource_id, *super_properties, value);
+		delete_metadata_decomposed (*super_properties, value, error);
 		super_properties++;
 	}
 }
 
-
-void
-tracker_data_delete_statement (const gchar            *subject,
-			       const gchar            *predicate,
-			       const gchar            *object,
-			       GError                **error)
+static void
+cache_delete_resource_type (TrackerClass *class)
 {
-	TrackerClass       *class;
-	TrackerProperty    *field;
-	gint		    subject_id;
-	GPtrArray          *types;
+	TrackerDBInterface *iface;
+	TrackerDBStatement *stmt;
+	TrackerDBResultSet *result_set;
+	TrackerProperty   **properties, **prop;
+	gboolean            found;
+	gint                i;
 
-	g_return_if_fail (subject != NULL);
-	g_return_if_fail (predicate != NULL);
-	g_return_if_fail (object != NULL);
-	g_return_if_fail (in_transaction);
+	iface = tracker_db_manager_get_db_interface ();
 
-	subject_id = query_resource_id (subject);
-	
-	if (subject_id == 0) {
-		/* subject not in database */
-		return;
+	found = FALSE;
+	for (i = 0; i < resource_buffer->types->len; i++) {
+		if (strcmp (g_ptr_array_index (resource_buffer->types, i), tracker_class_get_uri (class)) == 0) {
+			found = TRUE;
+		}
 	}
 
-	/* delete does not use update buffer, flush it */
-	tracker_data_update_buffer_flush ();
-
-	types = tracker_data_query_rdf_type (subject_id);
-
-	/* TODO we need to retrieve all existing (FTS indexed) property values for
-	 * this resource to properly support incremental FTS updates
-	 * (like calling deleteTerms and then calling insertTerms)
-	 */
-	tracker_fts_update_init (subject_id);
-
-	if (object && g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
-		class = tracker_ontology_get_class_by_uri (object);
-		if (class != NULL) {
-			TrackerDBInterface *iface;
-			TrackerDBStatement *stmt;
-			TrackerDBResultSet *result_set;
-			TrackerProperty   **properties, **prop;
-			GString *projection = NULL;
-
-			iface = tracker_db_manager_get_db_interface ();
-
-			/* retrieve all subclasses we need to remove from the subject
-			 * before we can remove the class specified as object of the statement */
-			stmt = tracker_db_interface_create_statement (iface,
-				"SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:Class_rdfs:subClassOf\".ID) "
-				"FROM \"rdfs:Resource_rdf:type\" INNER JOIN \"rdfs:Class_rdfs:subClassOf\" ON (\"rdf:type\" = \"rdfs:Class_rdfs:subClassOf\".ID) "
-				"WHERE \"rdfs:Resource_rdf:type\".ID = ? AND \"rdfs:subClassOf\" = (SELECT ID FROM \"rdfs:Resource\" WHERE Uri = ?)");
-			tracker_db_statement_bind_int (stmt, 0, subject_id);
-			tracker_db_statement_bind_text (stmt, 1, object);
-			result_set = tracker_db_statement_execute (stmt, NULL);
-			g_object_unref (stmt);
-
-			if (result_set) {
-				do {
-					gchar *class_uri;
-
-					tracker_db_result_set_get (result_set, 0, &class_uri, -1);
-					tracker_data_delete_statement (subject, predicate, class_uri, NULL);
-					g_free (class_uri);
-				} while (tracker_db_result_set_iter_next (result_set));
-
-				g_object_unref (result_set);
-			}
+	if (!found) {
+		/* type not found, nothing to do */
+		return;
+	}
 
-			properties = tracker_ontology_get_properties ();
+	/* retrieve all subclasses we need to remove from the subject
+	 * before we can remove the class specified as object of the statement */
+	stmt = tracker_db_interface_create_statement (iface,
+		"SELECT (SELECT Uri FROM \"rdfs:Resource\" WHERE ID = \"rdfs:Class_rdfs:subClassOf\".ID) "
+		"FROM \"rdfs:Resource_rdf:type\" INNER JOIN \"rdfs:Class_rdfs:subClassOf\" ON (\"rdf:type\" = \"rdfs:Class_rdfs:subClassOf\".ID) "
+		"WHERE \"rdfs:Resource_rdf:type\".ID = ? AND \"rdfs:subClassOf\" = (SELECT ID FROM \"rdfs:Resource\" WHERE Uri = ?)");
+	tracker_db_statement_bind_int (stmt, 0, resource_buffer->id);
+	tracker_db_statement_bind_text (stmt, 1, tracker_class_get_uri (class));
+	result_set = tracker_db_statement_execute (stmt, NULL);
+	g_object_unref (stmt);
 
-			for (prop = properties; *prop; prop++) {
+	if (result_set) {
+		do {
+			gchar *class_uri;
 
-				if (tracker_property_get_domain (*prop) != class) {
-					continue;
-				}
+			tracker_db_result_set_get (result_set, 0, &class_uri, -1);
+			cache_delete_resource_type (tracker_ontology_get_class_by_uri (class_uri));
+			g_free (class_uri);
+		} while (tracker_db_result_set_iter_next (result_set));
 
-				if (!tracker_property_get_multiple_values (*prop)) {
+		g_object_unref (result_set);
+	}
 
-					if (tracker_property_get_fulltext_indexed (*prop)) {
-						if (!projection) {
-							projection = g_string_new ("");
-						} else {
-							g_string_append_c (projection, ',');
-						}
+	/* delete all property values */
 
-						g_string_append_c (projection, '\'');
-						g_string_append (projection, tracker_property_get_name (*prop));
-						g_string_append (projection, "',");
-						g_string_append_c (projection, '"');
-						g_string_append (projection, tracker_property_get_name (*prop));
-						g_string_append_c (projection, '"');
-					}
-				} else {
+	properties = tracker_ontology_get_properties ();
 
-					if (tracker_property_get_fulltext_indexed (*prop)) {
+	for (prop = properties; *prop; prop++) {
+		gboolean            multiple_values, fts;
+		gchar              *table_name;
+		const gchar        *field_name;
+		GValueArray        *old_values;
+		gint                i;
 
-						/* Removing all fulltext properties from fts for 
-						 * none nrl:maxCardinality */
+		if (tracker_property_get_domain (*prop) != class) {
+			continue;
+		}
 
-						stmt = tracker_db_interface_create_statement (iface, "SELECT \"%s\" FROM \"%s_%s\" WHERE ID = ?",
-								tracker_property_get_name (*prop),
-								tracker_class_get_name (class),
-								tracker_property_get_name (*prop));
-						tracker_db_statement_bind_int (stmt, 0, subject_id);
-						result_set = tracker_db_statement_execute (stmt, NULL);
-						g_object_unref (stmt);
+		multiple_values = tracker_property_get_multiple_values (*prop);
+		if (multiple_values) {
+			table_name = g_strdup_printf ("%s_%s",
+				tracker_class_get_name (class),
+				tracker_property_get_name (*prop));
+		} else {
+			table_name = g_strdup (tracker_class_get_name (class));
+		}
+		field_name = tracker_property_get_name (*prop);
 
-						if (result_set) {
-							gchar *prop_object = NULL;
+		fts = tracker_property_get_fulltext_indexed (*prop);
 
-							tracker_db_result_set_get (result_set, 0, &prop_object, -1);
-							g_object_unref (result_set);
+		old_values = get_old_property_values (*prop, NULL);
 
-							if (prop_object) {
-								tracker_fts_update_text (subject_id, -1, prop_object);
+		for (i = old_values->n_values - 1; i >= 0 ; i--) {
+			GValue *old_gvalue;
+			GValue  gvalue = { 0 };
 
-								g_free (prop_object);
-							}
-						}
-					}
+			old_gvalue = g_value_array_get_nth (old_values, i);
+			g_value_init (&gvalue, G_VALUE_TYPE (old_gvalue));
+			g_value_copy (old_gvalue, &gvalue);
 
-					/* multi-valued property, delete values from DB */
-					stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"%s_%s\" WHERE ID = ?",
-								tracker_class_get_name (class),
-								tracker_property_get_name (*prop));
-					tracker_db_statement_bind_int (stmt, 0, subject_id);
-					tracker_db_statement_execute (stmt, NULL);
-					g_object_unref (stmt);
-				}
-			}
-
-			/* delete single-valued properties for current class */
-
-			if (projection) {
-
-				/* Removing all fulltext properties from fts for
-				 * nrl:maxCardinality 1 */
+			value_set_remove_value (old_values, &gvalue);
+			cache_delete_value (table_name, field_name, &gvalue, multiple_values, fts);
+		}
 
-				stmt = tracker_db_interface_create_statement (iface, "SELECT %s FROM \"%s\" WHERE ID = ?",
-						projection->str,
-						tracker_class_get_name (class));
-				g_string_free (projection, TRUE);
+		g_free (table_name);
+	}
 
-				tracker_db_statement_bind_int (stmt, 0, subject_id);
-				result_set = tracker_db_statement_execute (stmt, NULL);
-				g_object_unref (stmt);
+	cache_delete_row (class);
 
-				if (result_set) {
-					gchar *prop_object = NULL;
-					gchar *prop_name = NULL;
-					guint columns, c;
+	tracker_class_set_count (class, tracker_class_get_count (class) - 1);
+	if (delete_callback) {
+		delete_callback (resource_buffer->subject, RDF_PREFIX "type", tracker_class_get_uri (class), resource_buffer->types, delete_data);
+	}
+}
 
-					do {
-						columns = tracker_db_result_set_get_n_columns (result_set);
-						for (c = 0; c < columns; c += 2) {
-							tracker_db_result_set_get (result_set, c, &prop_name, -1);
-							tracker_db_result_set_get (result_set, c + 1, &prop_object, -1);
+void
+tracker_data_delete_statement (const gchar            *subject,
+			       const gchar            *predicate,
+			       const gchar            *object,
+			       GError                **error)
+{
+	TrackerClass       *class;
+	TrackerProperty    *field;
+	gint		    subject_id;
 
-							if (prop_object && prop_name) {
-								tracker_fts_update_text (subject_id, -1, prop_object);
-							}
+	g_return_if_fail (subject != NULL);
+	g_return_if_fail (predicate != NULL);
+	g_return_if_fail (object != NULL);
+	g_return_if_fail (in_transaction);
 
-							g_free (prop_object);
-							prop_object = NULL;
-							g_free (prop_name);
-							prop_name = NULL;
+	subject_id = query_resource_id (subject);
 
-						}
-					} while (tracker_db_result_set_iter_next (result_set));
+	if (subject_id == 0) {
+		/* subject not in database */
+		return;
+	}
 
-					g_object_unref (result_set);
-				}
-			}
+	if (resource_buffer == NULL || strcmp (resource_buffer->subject, subject) != 0) {
+		/* switch subject */
+		resource_buffer = g_hash_table_lookup (update_buffer.resources, subject);
+	}
 
-			stmt = tracker_db_interface_create_statement (iface, "DELETE FROM \"%s\" WHERE ID = ?",
-			                                              tracker_class_get_name (class));
-			tracker_db_statement_bind_int (stmt, 0, subject_id);
-			tracker_db_statement_execute (stmt, NULL);
-			g_object_unref (stmt);
+	if (resource_buffer == NULL) {
+		/* subject not yet in cache, retrieve or create ID */
+		resource_buffer = g_slice_new0 (TrackerDataUpdateBufferResource);
+		resource_buffer->subject = g_strdup (subject);
+		resource_buffer->id = query_resource_id (resource_buffer->subject);
+		resource_buffer->fts_updated = FALSE;
+		resource_buffer->types = tracker_data_query_rdf_type (resource_buffer->id);
+		resource_buffer->predicates = g_hash_table_new_full (g_direct_hash, g_direct_equal, g_object_unref, (GDestroyNotify) g_value_array_free);
+		resource_buffer->tables = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) cache_table_free);
 
-			/* delete rows from class tables */
-			delete_resource_type (subject_id, class);
+		g_hash_table_insert (update_buffer.resources, g_strdup (subject), resource_buffer);
+	}
 
-			tracker_class_set_count (class, tracker_class_get_count (class) - 1);
+	if (object && g_strcmp0 (predicate, RDF_PREFIX "type") == 0) {
+		class = tracker_ontology_get_class_by_uri (object);
+		if (class != NULL) {
+			cache_delete_resource_type (class);
 		} else {
 			g_set_error (error, TRACKER_DATA_ERROR, TRACKER_DATA_ERROR_UNKNOWN_CLASS,
 				     "Class '%s' not found in the ontology", object);
@@ -1142,27 +1145,15 @@ tracker_data_delete_statement (const gchar            *subject,
 	} else {
 		field = tracker_ontology_get_property_by_uri (predicate);
 		if (field != NULL) {
-
-			delete_metadata_decomposed (subject_id, field, object);
-
-			if (object && tracker_property_get_fulltext_indexed (field)) {
-				tracker_fts_update_text (subject_id, -1, object);
-			}
+			delete_metadata_decomposed (field, object, error);
 		} else {
 			g_set_error (error, TRACKER_DATA_ERROR, TRACKER_DATA_ERROR_UNKNOWN_PROPERTY,
 				     "Property '%s' not found in the ontology", predicate);
 		}
-	}
 
-	update_buffer.fts_ever_updated = TRUE;
-
-	if (delete_callback) {
-		delete_callback (subject, predicate, object, types, delete_data);
-	}
-
-	if (types) {
-		g_ptr_array_foreach (types, (GFunc) g_free, NULL);
-		g_ptr_array_free (types, TRUE);
+		if (delete_callback) {
+			delete_callback (subject, predicate, object, resource_buffer->types, delete_data);
+		}
 	}
 }
 



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