Commit 8cefe799 authored by Carlos Garnacho's avatar Carlos Garnacho

Merge branch 'wip/carlosg/insert-delete-triggers'

parents d33a5286 053154dc
Pipeline #27491 passed with stage
in 4 minutes and 39 seconds
......@@ -2899,49 +2899,81 @@ schedule_copy (GPtrArray *schedule,
}
static void
create_triggers_on_rowid (TrackerDBInterface *iface,
TrackerClass *klass,
TrackerProperty *property,
GError **error)
create_insert_delete_triggers (TrackerDBInterface *iface,
const gchar *table_name,
const gchar * const *properties,
gint n_properties,
GError **error)
{
GError *internal_error = NULL;
gchar *table_name;
GString *trigger_query;
gint i;
if (property) {
table_name = g_strdup_printf ("%s_%s",
tracker_class_get_name (klass),
tracker_property_get_name (property));
} else {
table_name = g_strdup (tracker_class_get_name (klass));
/* Insert trigger */
tracker_db_interface_execute_query (iface, &internal_error,
"DROP TRIGGER IF EXISTS \"trigger_insert_%s\" ",
table_name);
if (internal_error) {
g_propagate_error (error, internal_error);
return;
}
trigger_query = g_string_new (NULL);
g_string_append_printf (trigger_query,
"CREATE TRIGGER \"trigger_insert_%s\" "
"AFTER INSERT ON \"%s\" "
"FOR EACH ROW BEGIN ",
table_name, table_name);
for (i = 0; i < n_properties; i++) {
g_string_append_printf (trigger_query,
"UPDATE Resource "
"SET Refcount = Refcount + 1 "
"WHERE Resource.rowid = NEW.\"%s\"; ",
properties[i]);
}
g_string_append (trigger_query, "END; ");
tracker_db_interface_execute_query (iface, &internal_error,
"CREATE TRIGGER IF NOT EXISTS \"trigger_insert_%s\" "
"AFTER INSERT ON \"%s\" "
"FOR EACH ROW BEGIN "
"UPDATE Resource SET Refcount = Refcount + 1 WHERE Resource.rowid = NEW.ID;"
"END",
table_name, table_name);
trigger_query->str);
g_string_free (trigger_query, TRUE);
if (internal_error) {
g_propagate_error (error, internal_error);
g_free (table_name);
return;
}
/* Delete trigger */
tracker_db_interface_execute_query (iface, &internal_error,
"CREATE TRIGGER IF NOT EXISTS \"trigger_delete_%s\" "
"AFTER DELETE ON \"%s\" "
"FOR EACH ROW BEGIN "
"UPDATE Resource SET Refcount = Refcount - 1 WHERE Resource.rowid = OLD.ID;"
"END",
table_name, table_name);
"DROP TRIGGER IF EXISTS \"trigger_delete_%s\" ",
table_name);
if (internal_error) {
g_propagate_error (error, internal_error);
g_free (table_name);
return;
}
g_free (table_name);
trigger_query = g_string_new (NULL);
g_string_append_printf (trigger_query,
"CREATE TRIGGER \"trigger_delete_%s\" "
"AFTER DELETE ON \"%s\" "
"FOR EACH ROW BEGIN ",
table_name, table_name);
for (i = 0; i < n_properties; i++) {
g_string_append_printf (trigger_query,
"UPDATE Resource "
"SET Refcount = Refcount - 1 "
"WHERE Resource.rowid = OLD.\"%s\"; ",
properties[i]);
}
g_string_append (trigger_query, "END; ");
tracker_db_interface_execute_query (iface, &internal_error,
trigger_query->str);
g_string_free (trigger_query, TRUE);
if (internal_error) {
g_propagate_error (error, internal_error);
return;
}
}
static void
......@@ -2953,13 +2985,11 @@ create_table_triggers (TrackerDataManager *manager,
const gchar *property_name;
TrackerProperty **properties, *property;
GError *internal_error = NULL;
GPtrArray *trigger_properties;
guint i, n_props;
create_triggers_on_rowid (iface, klass, NULL, &internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
return;
}
trigger_properties = g_ptr_array_new ();
g_ptr_array_add (trigger_properties, "ROWID");
properties = tracker_ontologies_get_properties (manager->ontologies, &n_props);
......@@ -2977,21 +3007,39 @@ create_table_triggers (TrackerDataManager *manager,
multivalued = tracker_property_get_multiple_values (property);
if (multivalued) {
create_triggers_on_rowid (iface, klass, property, &internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
return;
}
const gchar * const properties[] = { "ID", property_name };
table_name = g_strdup_printf ("%s_%s",
tracker_class_get_name (klass),
property_name);
create_insert_delete_triggers (iface, table_name, properties,
G_N_ELEMENTS (properties),
&internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
g_ptr_array_unref (trigger_properties);
g_free (table_name);
return;
}
} else {
table_name = g_strdup (tracker_class_get_name (klass));
g_ptr_array_add (trigger_properties, (gchar *) property_name);
}
tracker_db_interface_execute_query (iface, &internal_error,
"CREATE TRIGGER IF NOT EXISTS \"trigger_update_%s_%s\" "
"DROP TRIGGER IF EXISTS \"trigger_update_%s_%s\"",
tracker_class_get_name (klass),
property_name);
if (internal_error) {
g_propagate_error (error, internal_error);
g_ptr_array_unref (trigger_properties);
g_free (table_name);
return;
}
tracker_db_interface_execute_query (iface, &internal_error,
"CREATE TRIGGER \"trigger_update_%s_%s\" "
"AFTER UPDATE OF \"%s\" ON \"%s\" "
"FOR EACH ROW BEGIN "
"UPDATE Resource SET Refcount = Refcount + 1 WHERE Resource.rowid = NEW.\"%s\";"
......@@ -3005,9 +3053,22 @@ create_table_triggers (TrackerDataManager *manager,
if (internal_error) {
g_propagate_error (error, internal_error);
g_ptr_array_unref (trigger_properties);
return;
}
}
create_insert_delete_triggers (iface,
tracker_class_get_name (klass),
(const gchar * const *) trigger_properties->pdata,
trigger_properties->len,
&internal_error);
g_ptr_array_unref (trigger_properties);
if (internal_error) {
g_propagate_error (error, internal_error);
return;
}
}
static void
......@@ -3312,10 +3373,6 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
g_debug ("Creating: '%s'", create_sql->str);
tracker_db_interface_execute_query (iface, &internal_error,
"%s", create_sql->str);
if (!internal_error)
create_table_triggers (manager, iface, service, &internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
goto error_out;
......@@ -3427,6 +3484,19 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
}
}
if (!in_update || in_change || tracker_class_get_is_new (service)) {
/* FIXME: We are trusting object refcount will stay intact across
* ontology changes. One situation where this is not true are
* removal or properties with rdfs:Resource range.
*/
create_table_triggers (manager, iface, service, &internal_error);
if (internal_error) {
g_propagate_error (error, internal_error);
goto error_out;
}
}
if (copy_schedule) {
guint i;
for (i = 0; i < copy_schedule->len; i++) {
......@@ -4803,7 +4873,8 @@ data_manager_check_perform_cleanup (TrackerDataManager *manager)
count = 0;
stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_NONE, NULL,
"SELECT COUNT(*) FROM Resource WHERE Refcount <= 0 "
"AND Resource.ID NOT IN (SELECT ID FROM Graph)");
"AND Resource.ID > %d AND Resource.ID NOT IN (SELECT ID FROM Graph)",
TRACKER_ONTOLOGIES_MAX_ID);
if (stmt) {
cursor = tracker_db_statement_start_cursor (stmt, NULL);
g_object_unref (stmt);
......@@ -4837,7 +4908,8 @@ tracker_data_manager_dispose (GObject *object)
stmt = tracker_db_interface_create_statement (iface, TRACKER_DB_STATEMENT_CACHE_TYPE_UPDATE,
&error,
"DELETE FROM Resource WHERE Refcount <= 0 "
"AND Resource.ID NOT IN (SELECT ID FROM Graph)");
"AND Resource.ID > %d AND Resource.ID NOT IN (SELECT ID FROM Graph)",
TRACKER_ONTOLOGIES_MAX_ID);
if (stmt) {
tracker_db_statement_execute (stmt, &error);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment