[tracker/wip/carlosg/resource-leak-fix: 6/8] libtracker-data: Add resource element triggers
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/resource-leak-fix: 6/8] libtracker-data: Add resource element triggers
- Date: Sat, 15 Jul 2017 15:54:11 +0000 (UTC)
commit 6edb4fddea6ac69f1595ac16bfcccb4a168290fe
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Jul 5 10:56:46 2017 +0200
libtracker-data: Add resource element triggers
Those will control the Refcount column in the Resource table,
whenever a resource is added/removed from a resource or multivalued
property table, or whenever a single or multivalued property points
or stops pointing to a given resource, its refcount will be changed.
This adds automatic refcounting on elements, so we can tell those
with a refcount=0 are not referenced anywhere so thus can be dropped.
src/libtracker-data/tracker-data-manager.c | 116 ++++++++++++++++++++++++++++
1 files changed, 116 insertions(+), 0 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 05d8947..c7bea50 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -2901,6 +2901,118 @@ schedule_copy (GPtrArray *schedule,
}
static void
+create_triggers_on_rowid (TrackerDBInterface *iface,
+ TrackerClass *klass,
+ TrackerProperty *property,
+ GError **error)
+{
+ GError *internal_error = NULL;
+ gchar *table_name;
+
+ 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));
+ }
+
+ tracker_db_interface_execute_query (iface, &internal_error,
+ "CREATE TRIGGER \"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);
+ if (internal_error) {
+ g_propagate_error (error, internal_error);
+ g_free (table_name);
+ return;
+ }
+
+ tracker_db_interface_execute_query (iface, &internal_error,
+ "CREATE TRIGGER \"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);
+ if (internal_error) {
+ g_propagate_error (error, internal_error);
+ g_free (table_name);
+ return;
+ }
+
+ g_free (table_name);
+}
+
+static void
+create_table_triggers (TrackerDataManager *manager,
+ TrackerDBInterface *iface,
+ TrackerClass *klass,
+ GError **error)
+{
+ const gchar *property_name;
+ TrackerProperty **properties, *property;
+ GError *internal_error = NULL;
+ guint i, n_props;
+
+ create_triggers_on_rowid (iface, klass, NULL, &internal_error);
+ if (internal_error) {
+ g_propagate_error (error, internal_error);
+ return;
+ }
+
+ properties = tracker_ontologies_get_properties (manager->ontologies, &n_props);
+
+ for (i = 0; i < n_props; i++) {
+ gboolean multivalued;
+ gchar *table_name;
+
+ property = properties[i];
+
+ if (tracker_property_get_domain (property) != klass ||
+ tracker_property_get_data_type (property) != TRACKER_PROPERTY_TYPE_RESOURCE)
+ continue;
+
+ property_name = tracker_property_get_name (property);
+ 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;
+ }
+
+ table_name = g_strdup_printf ("%s_%s",
+ tracker_class_get_name (klass),
+ property_name);
+ } else {
+ table_name = g_strdup (tracker_class_get_name (klass));
+ }
+
+ 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\";"
+ "UPDATE Resource SET Refcount = Refcount - 1 WHERE
Resource.rowid = OLD.\"%s\";"
+ "END",
+ tracker_class_get_name (klass),
+ property_name,
+ property_name, table_name,
+ property_name, property_name);
+ g_free (table_name);
+
+ if (internal_error) {
+ g_propagate_error (error, internal_error);
+ return;
+ }
+ }
+}
+
+static void
create_decomposed_metadata_tables (TrackerDataManager *manager,
TrackerDBInterface *iface,
TrackerClass *service,
@@ -2912,6 +3024,7 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
GString *create_sql = NULL;
GString *in_col_sql = NULL;
GString *sel_col_sql = NULL;
+ GString *trigger_sql = NULL;
TrackerProperty **properties, *property, **domain_indexes;
GSList *class_properties = NULL, *field_it;
gboolean main_class;
@@ -3203,6 +3316,9 @@ create_decomposed_metadata_tables (TrackerDataManager *manager,
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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]