diff --git a/tracker-sqlte-3.25-rename-tables.patch b/tracker-sqlte-3.25-rename-tables.patch new file mode 100644 index 0000000..ebe55ab --- /dev/null +++ b/tracker-sqlte-3.25-rename-tables.patch @@ -0,0 +1,338 @@ +From 29d3bab2ef1d826c29bc5b54e9558a5521bf6bcd Mon Sep 17 00:00:00 2001 +From: Carlos Garnacho +Date: Thu, 8 Nov 2018 12:40:36 +0100 +Subject: [PATCH] libtracker-data: Drop FTS table/view before ontology updates + +Sqlite >= 3.25.0 got stricter 'alter table ... rename ...' behavior +where the renaming affects all references to the table across the +database. This is at odds with our fts_view view on schema updates +due to ontology changes, as we first migrate (rename current table, +create new one, insert previous content, drop old table) all resource +tables before doing the FTS table/view updates. This causes rename +failures due to the fts_view referencing the renamed and dropped +tables. + +Change the ontology update code so we delete the FTS table/view +before changing resource tables in case of FTS updates. This makes +the behavior correct both before and after the Sqlite change. + +https://gitlab.gnome.org/GNOME/tracker/issues/40 +--- + src/libtracker-data/tracker-data-manager.c | 105 +++++++++++++----- + .../tracker-db-interface-sqlite.c | 8 ++ + .../tracker-db-interface-sqlite.h | 2 + + src/libtracker-fts/tracker-fts.c | 32 ++++-- + src/libtracker-fts/tracker-fts.h | 2 + + 5 files changed, 107 insertions(+), 42 deletions(-) + +diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c +index 4fab66824..87c9b486f 100644 +--- a/src/libtracker-data/tracker-data-manager.c ++++ b/src/libtracker-data/tracker-data-manager.c +@@ -135,6 +135,12 @@ enum { + N_PROPS + }; + ++#if HAVE_TRACKER_FTS ++static gboolean tracker_data_manager_fts_changed (TrackerDataManager *manager); ++static void tracker_data_manager_update_fts (TrackerDataManager *manager, ++ TrackerDBInterface *iface); ++#endif ++ + static void tracker_data_manager_initable_iface_init (GInitableIface *iface); + + G_DEFINE_TYPE_WITH_CODE (TrackerDataManager, tracker_data_manager, G_TYPE_OBJECT, +@@ -3681,6 +3687,9 @@ tracker_data_ontology_import_into_db (TrackerDataManager *manager, + TrackerProperty **properties; + guint i, n_props, n_classes; + gboolean base_tables_altered = FALSE; ++#if HAVE_TRACKER_FTS ++ gboolean update_fts = FALSE; ++#endif + + iface = tracker_db_manager_get_writable_db_interface (manager->db_manager); + +@@ -3691,6 +3700,15 @@ tracker_data_ontology_import_into_db (TrackerDataManager *manager, + return; + } + ++#if HAVE_TRACKER_FTS ++ if (in_update) { ++ update_fts = tracker_data_manager_fts_changed (manager); ++ ++ if (update_fts) ++ tracker_db_interface_sqlite_fts_delete_table (iface); ++ } ++#endif ++ + /* create tables */ + for (i = 0; i < n_classes; i++) { + GError *internal_error = NULL; +@@ -3740,6 +3758,14 @@ tracker_data_ontology_import_into_db (TrackerDataManager *manager, + } + } + } ++ ++#if HAVE_TRACKER_FTS ++ if (update_fts) { ++ tracker_data_manager_update_fts (manager, iface); ++ } else { ++ tracker_data_manager_init_fts (iface, !in_update); ++ } ++#endif + } + + static gint +@@ -3942,13 +3968,44 @@ load_ontologies_gvdb (TrackerDataManager *manager, + + #if HAVE_TRACKER_FTS + static gboolean ++tracker_data_manager_fts_changed (TrackerDataManager *manager) ++{ ++ TrackerProperty **properties; ++ gboolean has_changed = FALSE; ++ guint i, len; ++ ++ properties = tracker_ontologies_get_properties (manager->ontologies, &len); ++ ++ for (i = 0; i < len; i++) { ++ TrackerClass *class; ++ ++ if (tracker_property_get_fulltext_indexed (properties[i]) != ++ tracker_property_get_orig_fulltext_indexed (properties[i])) { ++ has_changed |= TRUE; ++ } ++ ++ if (!tracker_property_get_fulltext_indexed (properties[i])) { ++ continue; ++ } ++ ++ has_changed |= tracker_property_get_is_new (properties[i]); ++ ++ /* We must also regenerate FTS if any table in the view ++ * updated its schema. ++ */ ++ class = tracker_property_get_domain (properties[i]); ++ has_changed |= tracker_class_get_db_schema_changed (class); ++ } ++ ++ return has_changed; ++} ++ ++static void + ontology_get_fts_properties (TrackerDataManager *manager, +- gboolean only_new, + GHashTable **fts_properties, + GHashTable **multivalued) + { + TrackerProperty **properties; +- gboolean has_changed = FALSE; + guint i, len; + + properties = tracker_ontologies_get_properties (manager->ontologies, &len); +@@ -3960,16 +4017,10 @@ ontology_get_fts_properties (TrackerDataManager *manager, + const gchar *name, *table_name; + GList *list; + +- if (tracker_property_get_fulltext_indexed (properties[i]) != +- tracker_property_get_orig_fulltext_indexed (properties[i])) { +- has_changed |= TRUE; +- } +- + if (!tracker_property_get_fulltext_indexed (properties[i])) { + continue; + } + +- has_changed |= tracker_property_get_is_new (properties[i]); + table_name = tracker_property_get_table_name (properties[i]); + name = tracker_property_get_name (properties[i]); + list = g_hash_table_lookup (*fts_properties, table_name); +@@ -3986,8 +4037,6 @@ ontology_get_fts_properties (TrackerDataManager *manager, + list = g_list_append (list, (gpointer) name); + } + } +- +- return has_changed; + } + + static void +@@ -4001,29 +4050,36 @@ rebuild_fts_tokens (TrackerDataManager *manager, + /* Update the stamp file */ + tracker_db_manager_tokenizer_update (manager->db_manager); + } +-#endif + + gboolean + tracker_data_manager_init_fts (TrackerDBInterface *iface, + gboolean create) + { +-#if HAVE_TRACKER_FTS + GHashTable *fts_props, *multivalued; + TrackerDataManager *manager; + + manager = tracker_db_interface_get_user_data (iface); +- ontology_get_fts_properties (manager, FALSE, &fts_props, &multivalued); ++ ontology_get_fts_properties (manager, &fts_props, &multivalued); + tracker_db_interface_sqlite_fts_init (iface, fts_props, + multivalued, create); + g_hash_table_unref (fts_props); + g_hash_table_unref (multivalued); + return TRUE; +-#else +- g_info ("FTS support is disabled"); +- return FALSE; +-#endif + } + ++static void ++tracker_data_manager_update_fts (TrackerDataManager *manager, ++ TrackerDBInterface *iface) ++{ ++ GHashTable *fts_properties, *multivalued; ++ ++ ontology_get_fts_properties (manager, &fts_properties, &multivalued); ++ tracker_db_interface_sqlite_fts_alter_table (iface, fts_properties, multivalued); ++ g_hash_table_unref (fts_properties); ++ g_hash_table_unref (multivalued); ++} ++#endif ++ + GFile * + tracker_data_manager_get_cache_location (TrackerDataManager *manager) + { +@@ -4279,8 +4335,6 @@ tracker_data_manager_initable_init (GInitable *initable, + tracker_data_ontology_import_into_db (manager, FALSE, + &internal_error); + +- tracker_data_manager_init_fts (iface, TRUE); +- + if (internal_error) { + g_propagate_error (error, internal_error); + return FALSE; +@@ -4371,7 +4425,9 @@ tracker_data_manager_initable_init (GInitable *initable, + } + } + ++#if HAVE_TRACKER_FTS + tracker_data_manager_init_fts (iface, FALSE); ++#endif + } + + if (!read_only) { +@@ -4630,17 +4686,6 @@ tracker_data_manager_initable_init (GInitable *initable, + } + + if (update_nao) { +-#if HAVE_TRACKER_FTS +- GHashTable *fts_properties, *multivalued; +- +- if (ontology_get_fts_properties (manager, TRUE, &fts_properties, &multivalued)) { +- tracker_db_interface_sqlite_fts_alter_table (iface, fts_properties, multivalued); +- } +- +- g_hash_table_unref (fts_properties); +- g_hash_table_unref (multivalued); +-#endif +- + update_ontology_last_modified (manager, iface, ontology, &n_error); + + if (n_error) { +diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c b/src/libtracker-data/tracker-db-interface-sqlite.c +index dbecce9e5..9a8a5c302 100644 +--- a/src/libtracker-data/tracker-db-interface-sqlite.c ++++ b/src/libtracker-data/tracker-db-interface-sqlite.c +@@ -1656,6 +1656,14 @@ tracker_db_interface_sqlite_fts_init (TrackerDBInterface *db_interface, + + #if HAVE_TRACKER_FTS + ++void ++tracker_db_interface_sqlite_fts_delete_table (TrackerDBInterface *db_interface) ++{ ++ if (!tracker_fts_delete_table (db_interface->db, "fts5")) { ++ g_critical ("Failed to delete FTS table"); ++ } ++} ++ + void + tracker_db_interface_sqlite_fts_alter_table (TrackerDBInterface *db_interface, + GHashTable *properties, +diff --git a/src/libtracker-data/tracker-db-interface-sqlite.h b/src/libtracker-data/tracker-db-interface-sqlite.h +index 8ae70fd42..45eb5fd7c 100644 +--- a/src/libtracker-data/tracker-db-interface-sqlite.h ++++ b/src/libtracker-data/tracker-db-interface-sqlite.h +@@ -61,6 +61,8 @@ gboolean tracker_db_interface_sqlite_wal_checkpoint (TrackerD + + + #if HAVE_TRACKER_FTS ++void tracker_db_interface_sqlite_fts_delete_table (TrackerDBInterface *interface); ++ + void tracker_db_interface_sqlite_fts_alter_table (TrackerDBInterface *interface, + GHashTable *properties, + GHashTable *multivalued); +diff --git a/src/libtracker-fts/tracker-fts.c b/src/libtracker-fts/tracker-fts.c +index 3c550ca41..49ba4d362 100644 +--- a/src/libtracker-fts/tracker-fts.c ++++ b/src/libtracker-fts/tracker-fts.c +@@ -157,6 +157,26 @@ tracker_fts_create_table (sqlite3 *db, + return (rc == SQLITE_OK); + } + ++gboolean ++tracker_fts_delete_table (sqlite3 *db, ++ gchar *table_name) ++{ ++ gchar *query; ++ int rc; ++ ++ query = g_strdup_printf ("DROP VIEW fts_view"); ++ rc = sqlite3_exec (db, query, NULL, NULL, NULL); ++ g_free (query); ++ ++ if (rc == SQLITE_OK) { ++ query = g_strdup_printf ("DROP TABLE %s", table_name); ++ sqlite3_exec (db, query, NULL, NULL, NULL); ++ g_free (query); ++ } ++ ++ return rc == SQLITE_OK; ++} ++ + gboolean + tracker_fts_alter_table (sqlite3 *db, + gchar *table_name, +@@ -168,18 +188,6 @@ tracker_fts_alter_table (sqlite3 *db, + + tmp_name = g_strdup_printf ("%s_TMP", table_name); + +- query = g_strdup_printf ("DROP VIEW fts_view"); +- rc = sqlite3_exec (db, query, NULL, NULL, NULL); +- g_free (query); +- +- query = g_strdup_printf ("DROP TABLE %s", tmp_name); +- rc = sqlite3_exec (db, query, NULL, NULL, NULL); +- g_free (query); +- +- query = g_strdup_printf ("DROP TABLE %s", table_name); +- rc = sqlite3_exec (db, query, NULL, NULL, NULL); +- g_free (query); +- + if (!tracker_fts_create_table (db, tmp_name, tables, grouped_columns)) { + g_free (tmp_name); + return FALSE; +diff --git a/src/libtracker-fts/tracker-fts.h b/src/libtracker-fts/tracker-fts.h +index 751014f38..3bda8cf98 100644 +--- a/src/libtracker-fts/tracker-fts.h ++++ b/src/libtracker-fts/tracker-fts.h +@@ -36,6 +36,8 @@ gboolean tracker_fts_create_table (sqlite3 *db, + gchar *table_name, + GHashTable *tables, + GHashTable *grouped_columns); ++gboolean tracker_fts_delete_table (sqlite3 *db, ++ gchar *table_name); + gboolean tracker_fts_alter_table (sqlite3 *db, + gchar *table_name, + GHashTable *tables, +-- +2.18.1 + + diff --git a/tracker.changes b/tracker.changes index 5554cb7..460667b 100644 --- a/tracker.changes +++ b/tracker.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Nov 8 14:13:28 UTC 2018 - Dominique Leuenberger + +- Add tracker-sqlte-3.25-rename-tables.patch: drop FTS table/view + before ontology update (glgo#GNOME/tracker#40, boo#1110090) + ------------------------------------------------------------------- Wed Nov 7 06:52:58 UTC 2018 - bjorn.lie@gmail.com diff --git a/tracker.spec b/tracker.spec index b21f3b4..efef5ca 100644 --- a/tracker.spec +++ b/tracker.spec @@ -31,6 +31,8 @@ URL: https://wiki.gnome.org/Projects/Tracker Source0: http://download.gnome.org/sources/tracker/2.1/%{name}-%{version}.tar.xz # PATCH-FIX-UPSTREAM tracker-extract-private.patch bgo#725689 dimstar@opensuse.org -- Do not maintain LT versioning for private libs Patch0: tracker-extract-private.patch +# PATCH-FIX-UPSTREAM tracker-sqlte-3.25-rename-tables.patch glgo#GNOME/tracker#40 boo#1110090 dimstar@opensuse.org -- drop FTS table/view before ontology update +Patch1: tracker-sqlte-3.25-rename-tables.patch BuildRequires: fdupes BuildRequires: gcc-c++ BuildRequires: glib2-devel >= 2.44.0