[tracker/wip/carlosg/transact-graphs: 2/2] libtracker-data: Handle graph updates after commit as a transaction
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [tracker/wip/carlosg/transact-graphs: 2/2] libtracker-data: Handle graph updates after commit as a transaction
- Date: Sun, 23 Aug 2020 20:06:01 +0000 (UTC)
commit bc54d671ed157e16fd45457857a42c99e536ab5d
Author: Carlos Garnacho <carlosg gnome org>
Date: Sun Aug 23 21:47:15 2020 +0200
libtracker-data: Handle graph updates after commit as a transaction
After a graph is created/deleted, we update immediately our graph
accounting. This however didn't take into account that graph operations
may happen within a transaction, so a readonly interface being spawned
at the right time might consider those graphs as existing its query even
though they are not attached yet.
This situation would resolve itself after the last graph is processed,
and the transaction committed, but for that query it would fail like:
In service 'dbus:org.freedesktop.Tracker3.Miner.Files': no such table:
http://tracker.api.gnome.org/ontology/v3/tracker#Audio.nfo:Audio
In order to fix that, handle changes to the known graphs as part of the
transaction, only making it effective after the change is committed, and
database interfaces would correctly find the graph databases when updated.
This makes readonly interfaces aware of the graph changes after the
transaction is committed, not before.
Of course, this means the operation should be rolled back if the
transaction failed. Also do that.
Fixes: https://gitlab.gnome.org/GNOME/tracker/-/issues/231
src/libtracker-data/tracker-data-manager.c | 48 ++++++++++++++++++++++++++----
src/libtracker-data/tracker-data-manager.h | 2 ++
src/libtracker-data/tracker-data-update.c | 4 +++
3 files changed, 49 insertions(+), 5 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 47d721954..ddd6865d5 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -80,6 +80,7 @@ struct _TrackerDataManager {
TrackerOntologies *ontologies;
TrackerData *data_update;
+ GHashTable *transaction_graphs;
GHashTable *graphs;
gchar *status;
@@ -4827,6 +4828,25 @@ tracker_data_manager_get_namespaces (TrackerDataManager *manager)
return ht;
}
+static GHashTable *
+copy_graphs (GHashTable *graphs)
+{
+ GHashTable *copy;
+ GHashTableIter iter;
+ gpointer key, value;
+
+ copy = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free,
+ NULL);
+ g_hash_table_iter_init (&iter, graphs);
+
+ while (g_hash_table_iter_next (&iter, &key, &value))
+ g_hash_table_insert (copy, g_strdup (key), value);
+
+ return copy;
+}
+
gboolean
tracker_data_manager_create_graph (TrackerDataManager *manager,
const gchar *name,
@@ -4852,9 +4872,10 @@ tracker_data_manager_create_graph (TrackerDataManager *manager,
if (id == 0)
goto detach;
- g_hash_table_insert (manager->graphs, g_strdup (name), GINT_TO_POINTER (id));
+ if (!manager->transaction_graphs)
+ manager->transaction_graphs = copy_graphs (manager->graphs);
- manager->generation++;
+ g_hash_table_insert (manager->transaction_graphs, g_strdup (name), GINT_TO_POINTER (id));
return TRUE;
@@ -4887,10 +4908,10 @@ tracker_data_manager_drop_graph (TrackerDataManager *manager,
if (!tracker_data_delete_graph (manager->data_update, name, error))
return FALSE;
- manager->generation++;
+ if (!manager->transaction_graphs)
+ manager->transaction_graphs = copy_graphs (manager->graphs);
- if (manager->graphs)
- g_hash_table_remove (manager->graphs, name);
+ g_hash_table_remove (manager->transaction_graphs, name);
return TRUE;
}
@@ -5053,3 +5074,20 @@ tracker_data_manager_get_generation (TrackerDataManager *manager)
{
return manager->generation;
}
+
+void
+tracker_data_manager_commit_graphs (TrackerDataManager *manager)
+{
+ if (manager->transaction_graphs) {
+ g_clear_pointer (&manager->graphs, g_hash_table_unref);
+ manager->graphs = manager->transaction_graphs;
+ manager->transaction_graphs = NULL;
+ manager->generation++;
+ }
+}
+
+void
+tracker_data_manager_rollback_graphs (TrackerDataManager *manager)
+{
+ g_clear_pointer (&manager->transaction_graphs, g_hash_table_unref);
+}
diff --git a/src/libtracker-data/tracker-data-manager.h b/src/libtracker-data/tracker-data-manager.h
index b7572e6d4..378d058ec 100644
--- a/src/libtracker-data/tracker-data-manager.h
+++ b/src/libtracker-data/tracker-data-manager.h
@@ -100,6 +100,8 @@ gint tracker_data_manager_find_graph (TrackerDataManager *
const gchar *name);
guint tracker_data_manager_get_generation (TrackerDataManager *manager);
+void tracker_data_manager_rollback_graphs (TrackerDataManager *manager);
+void tracker_data_manager_commit_graphs (TrackerDataManager *manager);
G_END_DECLS
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index abc51860a..f7413c948 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -2562,6 +2562,8 @@ tracker_data_commit_transaction (TrackerData *data,
data->update_buffer.fts_ever_updated = FALSE;
}
+ tracker_data_manager_commit_graphs (data->manager);
+
tracker_db_interface_execute_query (iface, NULL, "PRAGMA cache_size = %d",
TRACKER_DB_CACHE_SIZE_DEFAULT);
g_ptr_array_set_size (data->update_buffer.graphs, 0);
@@ -2592,6 +2594,8 @@ tracker_data_rollback_transaction (TrackerData *data)
g_clear_error (&ignorable);
}
+ tracker_data_manager_rollback_graphs (data->manager);
+
tracker_db_interface_execute_query (iface, NULL, "PRAGMA cache_size = %d",
TRACKER_DB_CACHE_SIZE_DEFAULT);
tracker_data_dispatch_rollback_statement_callbacks (data);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]