From 69db1874b52587442d29d1a5585540e3f87e8b5f Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 22 Jan 2023 17:33:37 +0100 Subject: core: Check and repair FTS integrity during integrity check Extend the integrity check so it covers FTS index integrity in all graph databases. If FTS is still corrupt after rebuild, an error will be indirectly risen. --- src/libtracker-sparql/core/tracker-data-manager.c | 34 ++++++++++++++++++++++ .../core/tracker-db-interface-sqlite.c | 7 +++++ .../core/tracker-db-interface-sqlite.h | 3 ++ src/libtracker-sparql/core/tracker-fts.c | 17 +++++++++++ src/libtracker-sparql/core/tracker-fts.h | 4 +++ 5 files changed, 65 insertions(+) (limited to 'src/libtracker-sparql') diff --git a/src/libtracker-sparql/core/tracker-data-manager.c b/src/libtracker-sparql/core/tracker-data-manager.c index daa8dfffb..4cd917e2b 100644 --- a/src/libtracker-sparql/core/tracker-data-manager.c +++ b/src/libtracker-sparql/core/tracker-data-manager.c @@ -4166,6 +4166,11 @@ integrity_check_cb (TrackerDBManager *db_manager, { GError *internal_error = NULL; TrackerDBStatement *stmt; + GHashTableIter iter; + const gchar *graph; + TrackerProperty **properties; + guint len, i; + gboolean has_fts = FALSE; /* Ensure that database has been initialized earlier * by checking whether Resource table exists. @@ -4185,6 +4190,35 @@ integrity_check_cb (TrackerDBManager *db_manager, g_clear_object (&stmt); + properties = tracker_ontologies_get_properties (data_manager->ontologies, &len); + + for (i = 0; i < len; i++) { + has_fts |= tracker_property_get_fulltext_indexed (properties[i]); + if (has_fts) + break; + } + + if (has_fts) { + g_hash_table_iter_init (&iter, data_manager->graphs); + while (g_hash_table_iter_next (&iter, (gpointer*) &graph, NULL)) { + if (!tracker_db_interface_sqlite_fts_integrity_check (iface, graph)) { + tracker_db_interface_sqlite_fts_rebuild_tokens (iface, graph, NULL); + if (!tracker_db_interface_sqlite_fts_integrity_check (iface, graph)) { + g_message ("Corrupt database: FTS index on graph %s is corrupt", graph); + return TRUE; + } + } + } + + if (!tracker_db_interface_sqlite_fts_integrity_check (iface, "main")) { + tracker_db_interface_sqlite_fts_rebuild_tokens (iface, "main", NULL); + if (!tracker_db_interface_sqlite_fts_integrity_check (iface, "main")) { + g_message ("Corrupt database: FTS index on main database is corrupt"); + return TRUE; + } + } + } + return FALSE; } diff --git a/src/libtracker-sparql/core/tracker-db-interface-sqlite.c b/src/libtracker-sparql/core/tracker-db-interface-sqlite.c index 385b59f4f..e4959ce2e 100644 --- a/src/libtracker-sparql/core/tracker-db-interface-sqlite.c +++ b/src/libtracker-sparql/core/tracker-db-interface-sqlite.c @@ -2378,6 +2378,13 @@ tracker_db_interface_sqlite_fts_delete_text_stmt (TrackerDBInterface *db_interf return stmt; } +gboolean +tracker_db_interface_sqlite_fts_integrity_check (TrackerDBInterface *interface, + const gchar *database) +{ + return tracker_fts_integrity_check (interface->db, database, "fts5"); +} + gboolean tracker_db_interface_sqlite_fts_rebuild_tokens (TrackerDBInterface *interface, const gchar *database, diff --git a/src/libtracker-sparql/core/tracker-db-interface-sqlite.h b/src/libtracker-sparql/core/tracker-db-interface-sqlite.h index 9848df6e9..d1889881a 100644 --- a/src/libtracker-sparql/core/tracker-db-interface-sqlite.h +++ b/src/libtracker-sparql/core/tracker-db-interface-sqlite.h @@ -78,6 +78,9 @@ TrackerDBStatement * tracker_db_interface_sqlite_fts_delete_text_stmt (TrackerDB const gchar **properties, GError **error); +gboolean tracker_db_interface_sqlite_fts_integrity_check (TrackerDBInterface *interface, + const gchar *database); + gboolean tracker_db_interface_sqlite_fts_rebuild_tokens (TrackerDBInterface *interface, const gchar *database, GError **error); diff --git a/src/libtracker-sparql/core/tracker-fts.c b/src/libtracker-sparql/core/tracker-fts.c index 8b0a9052c..50f4c0e55 100644 --- a/src/libtracker-sparql/core/tracker-fts.c +++ b/src/libtracker-sparql/core/tracker-fts.c @@ -263,6 +263,23 @@ error: return TRUE; } +gboolean +tracker_fts_integrity_check (sqlite3 *db, + const gchar *database, + const gchar *table_name) +{ + gchar *query; + gint rc; + + /* This special query rebuilds the tokens in the given FTS table */ + query = g_strdup_printf ("INSERT INTO \"%s\".%s(%s, rank) VALUES('integrity-check', 1)", + database, table_name, table_name); + rc = sqlite3_exec (db, query, NULL, NULL, NULL); + g_free (query); + + return rc == SQLITE_OK; +} + gboolean tracker_fts_rebuild_tokens (sqlite3 *db, const gchar *database, diff --git a/src/libtracker-sparql/core/tracker-fts.h b/src/libtracker-sparql/core/tracker-fts.h index 1c3aebbdc..56c157a8f 100644 --- a/src/libtracker-sparql/core/tracker-fts.h +++ b/src/libtracker-sparql/core/tracker-fts.h @@ -56,6 +56,10 @@ gboolean tracker_fts_rebuild_tokens (sqlite3 *db, const gchar *table_name, GError **error); +gboolean tracker_fts_integrity_check (sqlite3 *db, + const gchar *database, + const gchar *table_name); + G_END_DECLS #endif /* __LIBTRACKER_FTS_FTS_H__ */ -- cgit v1.2.1