[tracker/wip/carlosg/fts-error-propagation: 1/3] libtracker-data: Propagate errors from fts table alterations




commit 0b70358d5fcbae77277594efcb3751509a89a893
Author: Carlos Garnacho <carlosg gnome org>
Date:   Sat Mar 13 12:38:15 2021 +0100

    libtracker-data: Propagate errors from fts table alterations
    
    These might cause errors that are just warned in place and uncaught
    in the larger TrackerDataManager machinery. Propagate these up, so
    that insertions fail properly.

 src/libtracker-data/tracker-data-manager.c        | 90 ++++++++++++++---------
 src/libtracker-data/tracker-db-interface-sqlite.c | 37 ++++++----
 src/libtracker-data/tracker-db-interface-sqlite.h | 15 ++--
 src/libtracker-fts/tracker-fts.c                  | 84 +++++++++++++--------
 src/libtracker-fts/tracker-fts.h                  | 29 ++++----
 5 files changed, 158 insertions(+), 97 deletions(-)
---
diff --git a/src/libtracker-data/tracker-data-manager.c b/src/libtracker-data/tracker-data-manager.c
index 5860b10b0..3e6cc98d8 100644
--- a/src/libtracker-data/tracker-data-manager.c
+++ b/src/libtracker-data/tracker-data-manager.c
@@ -133,9 +133,10 @@ enum {
 };
 
 static gboolean tracker_data_manager_fts_changed (TrackerDataManager *manager);
-static void tracker_data_manager_update_fts (TrackerDataManager *manager,
-                                             TrackerDBInterface *iface,
-                                            const gchar        *database);
+static gboolean tracker_data_manager_update_fts (TrackerDataManager  *manager,
+                                                 TrackerDBInterface  *iface,
+                                                 const gchar         *database,
+                                                 GError             **error);
 
 static void tracker_data_manager_initable_iface_init (GInitableIface *iface);
 
@@ -3554,36 +3555,45 @@ rebuild_fts_tokens (TrackerDataManager *manager,
 }
 
 static gboolean
-tracker_data_manager_init_fts (TrackerDataManager *manager,
-                               TrackerDBInterface *iface,
-                               const gchar        *database,
-                               gboolean            create)
+tracker_data_manager_init_fts (TrackerDataManager  *manager,
+                               TrackerDBInterface  *iface,
+                               const gchar         *database,
+                               gboolean             create,
+                               GError             **error)
 {
        GHashTable *fts_props, *multivalued;
+       gboolean retval;
 
        ontology_get_fts_properties (manager, &fts_props, &multivalued);
-       tracker_db_interface_sqlite_fts_init (iface,
-                                             database,
-                                             fts_props,
-                                             multivalued, create);
+       retval = tracker_db_interface_sqlite_fts_init (iface,
+                                                      database,
+                                                      fts_props,
+                                                      multivalued, create,
+                                                      error);
        g_hash_table_unref (fts_props);
        g_hash_table_unref (multivalued);
-       return TRUE;
+
+       return retval;
 }
 
-static void
-tracker_data_manager_update_fts (TrackerDataManager *manager,
-                                 TrackerDBInterface *iface,
-                                 const gchar        *database)
+static gboolean
+tracker_data_manager_update_fts (TrackerDataManager  *manager,
+                                 TrackerDBInterface  *iface,
+                                 const gchar         *database,
+                                 GError             **error)
 {
        GHashTable *fts_properties, *multivalued;
+       gboolean retval;
 
        ontology_get_fts_properties (manager, &fts_properties, &multivalued);
-       tracker_db_interface_sqlite_fts_alter_table (iface, database,
-                                                    fts_properties,
-                                                    multivalued);
+       retval = tracker_db_interface_sqlite_fts_alter_table (iface, database,
+                                                             fts_properties,
+                                                             multivalued,
+                                                             error);
        g_hash_table_unref (fts_properties);
        g_hash_table_unref (multivalued);
+
+       return retval;
 }
 
 GFile *
@@ -3665,11 +3675,14 @@ tracker_data_manager_initialize_iface (TrackerDataManager  *data_manager,
                                return FALSE;
                        }
 
-                       tracker_data_manager_init_fts (data_manager, iface, value, FALSE);
+                       if (!tracker_data_manager_init_fts (data_manager, iface,
+                                                           value, FALSE, error))
+                               return FALSE;
                }
        }
 
-       tracker_data_manager_init_fts (data_manager, iface, "main", FALSE);
+       if (!tracker_data_manager_init_fts (data_manager, iface, "main", FALSE, error))
+               return FALSE;
 
        return TRUE;
 }
@@ -3803,7 +3816,7 @@ tracker_data_manager_initable_init (GInitable     *initable,
        TrackerDBCursor *cursor;
        TrackerDBStatement *stmt;
        GHashTable *ontos_table;
-       GHashTable *graphs;
+       GHashTable *graphs = NULL;
        GList *sorted = NULL, *l;
        gboolean read_only;
        GError *internal_error = NULL;
@@ -3927,7 +3940,10 @@ tracker_data_manager_initable_init (GInitable     *initable,
                        return FALSE;
                }
 
-               tracker_data_manager_init_fts (manager, iface, "main", TRUE);
+               if (!tracker_data_manager_init_fts (manager, iface, "main", TRUE, &internal_error)) {
+                       g_propagate_error (error, internal_error);
+                       return FALSE;
+               }
 
                tracker_data_manager_initialize_iface (manager, iface, &internal_error);
                if (internal_error) {
@@ -4259,12 +4275,13 @@ tracker_data_manager_initable_init (GInitable     *initable,
                                update_fts = tracker_data_manager_fts_changed (manager);
 
                                if (update_fts)
-                                       tracker_db_interface_sqlite_fts_delete_table (iface, "main");
+                                       tracker_db_interface_sqlite_fts_delete_table (iface, "main", 
&ontology_error);
 
-                               tracker_data_ontology_setup_db (manager, iface, "main", TRUE,
-                                                               &ontology_error);
+                               if (!ontology_error)
+                                       tracker_data_ontology_setup_db (manager, iface, "main", TRUE, 
&ontology_error);
 
-                               graphs = tracker_data_manager_ensure_graphs (manager, iface, &ontology_error);
+                               if (!ontology_error)
+                                       graphs = tracker_data_manager_ensure_graphs (manager, iface, 
&ontology_error);
 
                                if (graphs) {
                                        GHashTableIter iter;
@@ -4274,7 +4291,10 @@ tracker_data_manager_initable_init (GInitable     *initable,
 
                                        while (g_hash_table_iter_next (&iter, &value, NULL)) {
                                                if (update_fts)
-                                                       tracker_db_interface_sqlite_fts_delete_table (iface, 
value);
+                                                       tracker_db_interface_sqlite_fts_delete_table (iface, 
value, &ontology_error);
+
+                                               if (ontology_error)
+                                                       break;
 
                                                tracker_data_ontology_setup_db (manager, iface, value, TRUE,
                                                                                &ontology_error);
@@ -4282,18 +4302,21 @@ tracker_data_manager_initable_init (GInitable     *initable,
                                                        break;
 
                                                if (update_fts) {
-                                                       tracker_data_manager_update_fts (manager, iface, 
value);
+                                                       tracker_data_manager_update_fts (manager, iface, 
value, &ontology_error);
                                                } else {
-                                                       tracker_data_manager_init_fts (manager, iface, value, 
FALSE);
+                                                       tracker_data_manager_init_fts (manager, iface, value, 
FALSE, &ontology_error);
                                                }
+
+                                               if (ontology_error)
+                                                       break;
                                        }
                                }
 
                                if (!ontology_error) {
                                        if (update_fts) {
-                                               tracker_data_manager_update_fts (manager, iface, "main");
+                                               tracker_data_manager_update_fts (manager, iface, "main", 
&ontology_error);
                                        } else {
-                                               tracker_data_manager_init_fts (manager, iface, "main", FALSE);
+                                               tracker_data_manager_init_fts (manager, iface, "main", FALSE, 
&ontology_error);
                                        }
                                }
 
@@ -4643,7 +4666,8 @@ tracker_data_manager_create_graph (TrackerDataManager  *manager,
                                             FALSE, error))
                goto detach;
 
-       tracker_data_manager_init_fts (manager, iface, name, TRUE);
+       if (!tracker_data_manager_init_fts (manager, iface, name, TRUE, error))
+               goto detach;
 
        id = tracker_data_ensure_graph (manager->data_update, name, error);
        if (id == 0)
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.c 
b/src/libtracker-data/tracker-db-interface-sqlite.c
index 0ecfc3535..b8de62afa 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.c
+++ b/src/libtracker-data/tracker-db-interface-sqlite.c
@@ -2243,21 +2243,27 @@ _fts_create_properties (GHashTable *properties)
        return (gchar **) g_ptr_array_free (cols, FALSE);
 }
 
-void
+gboolean
 tracker_db_interface_sqlite_fts_init (TrackerDBInterface  *db_interface,
                                       const gchar         *database,
                                       GHashTable          *properties,
                                       GHashTable          *multivalued,
-                                      gboolean             create)
+                                      gboolean             create,
+                                      GError             **error)
 {
+       GError *inner_error = NULL;
        GStrv fts_columns;
 
        tracker_fts_init_db (db_interface->db, db_interface, db_interface->flags, properties);
 
        if (create &&
            !tracker_fts_create_table (db_interface->db, database, "fts5",
-                                      properties, multivalued)) {
-               g_warning ("FTS tables creation failed");
+                                      properties, multivalued,
+                                      &inner_error)) {
+               g_propagate_prefixed_error (error,
+                                           inner_error,
+                                           "FTS tables creation failed: ");
+               return FALSE;
        }
 
        fts_columns = _fts_create_properties (properties);
@@ -2278,26 +2284,27 @@ tracker_db_interface_sqlite_fts_init (TrackerDBInterface  *db_interface,
                                                              FALSE);
                g_strfreev (fts_columns);
        }
+
+       return TRUE;
 }
 
-void
-tracker_db_interface_sqlite_fts_delete_table (TrackerDBInterface *db_interface,
-                                              const gchar        *database)
+gboolean
+tracker_db_interface_sqlite_fts_delete_table (TrackerDBInterface  *db_interface,
+                                              const gchar         *database,
+                                              GError             **error)
 {
-       if (!tracker_fts_delete_table (db_interface->db, database, "fts5")) {
-               g_critical ("Failed to delete FTS table");
-       }
+       return tracker_fts_delete_table (db_interface->db, database, "fts5", error);
 }
 
-void
+gboolean
 tracker_db_interface_sqlite_fts_alter_table (TrackerDBInterface  *db_interface,
                                              const gchar         *database,
                                              GHashTable          *properties,
-                                             GHashTable          *multivalued)
+                                             GHashTable          *multivalued,
+                                             GError             **error)
 {
-       if (!tracker_fts_alter_table (db_interface->db, database, "fts5", properties, multivalued)) {
-               g_critical ("Failed to update FTS columns");
-       }
+       return tracker_fts_alter_table (db_interface->db, database, "fts5",
+                                       properties, multivalued, error);
 }
 
 static gchar *
diff --git a/src/libtracker-data/tracker-db-interface-sqlite.h 
b/src/libtracker-data/tracker-db-interface-sqlite.h
index 20aa54618..47919447b 100644
--- a/src/libtracker-data/tracker-db-interface-sqlite.h
+++ b/src/libtracker-data/tracker-db-interface-sqlite.h
@@ -49,11 +49,12 @@ TrackerDBInterface *tracker_db_interface_sqlite_new                    (const gc
                                                                         GError                  **error);
 gint64              tracker_db_interface_sqlite_get_last_insert_id     (TrackerDBInterface       *interface);
 void                tracker_db_interface_sqlite_enable_shared_cache    (void);
-void                tracker_db_interface_sqlite_fts_init               (TrackerDBInterface       *interface,
+gboolean            tracker_db_interface_sqlite_fts_init               (TrackerDBInterface       *interface,
                                                                         const gchar              *database,
                                                                         GHashTable               *properties,
                                                                         GHashTable               
*multivalued,
-                                                                        gboolean                  create);
+                                                                        gboolean                  create,
+                                                                        GError                  **error);
 void                tracker_db_interface_sqlite_reset_collator         (TrackerDBInterface       *interface);
 gboolean            tracker_db_interface_sqlite_wal_checkpoint         (TrackerDBInterface       *interface,
                                                                         gboolean                  blocking,
@@ -61,13 +62,15 @@ gboolean            tracker_db_interface_sqlite_wal_checkpoint         (TrackerD
 gboolean            tracker_db_interface_init_vtabs                    (TrackerDBInterface       *interface,
                                                                         gpointer                  vtab_data);
 
-void                tracker_db_interface_sqlite_fts_delete_table       (TrackerDBInterface       *interface,
-                                                                        const gchar              *database);
+gboolean            tracker_db_interface_sqlite_fts_delete_table       (TrackerDBInterface       *interface,
+                                                                        const gchar              *database,
+                                                                        GError                  **error);
 
-void                tracker_db_interface_sqlite_fts_alter_table        (TrackerDBInterface       *interface,
+gboolean            tracker_db_interface_sqlite_fts_alter_table        (TrackerDBInterface       *interface,
                                                                         const gchar              *database,
                                                                         GHashTable               *properties,
-                                                                        GHashTable               
*multivalued);
+                                                                        GHashTable               
*multivalued,
+                                                                        GError                  **error);
 gboolean            tracker_db_interface_sqlite_fts_update_text        (TrackerDBInterface       
*db_interface,
                                                                         const gchar              *database,
                                                                        int                       id,
diff --git a/src/libtracker-fts/tracker-fts.c b/src/libtracker-fts/tracker-fts.c
index 1cb5041fe..e8f474fd9 100644
--- a/src/libtracker-fts/tracker-fts.c
+++ b/src/libtracker-fts/tracker-fts.c
@@ -89,11 +89,12 @@ tracker_fts_init_db (sqlite3               *db,
 }
 
 gboolean
-tracker_fts_create_table (sqlite3     *db,
-                          const gchar *database,
-                          gchar       *table_name,
-                          GHashTable  *tables,
-                          GHashTable  *grouped_columns)
+tracker_fts_create_table (sqlite3      *db,
+                          const gchar  *database,
+                          gchar        *table_name,
+                          GHashTable   *tables,
+                          GHashTable   *grouped_columns,
+                          GError      **error)
 {
        GString *str, *from, *fts;
        gchar *index_table;
@@ -153,17 +154,15 @@ tracker_fts_create_table (sqlite3     *db,
        rc = sqlite3_exec(db, str->str, NULL, NULL, NULL);
        g_string_free (str, TRUE);
 
-       if (rc != SQLITE_OK) {
-               g_assert_not_reached();
-               return FALSE;
-       }
+       if (rc != SQLITE_OK)
+               goto error;
 
        g_string_append (fts, "tokenize=TrackerTokenizer)");
        rc = sqlite3_exec(db, fts->str, NULL, NULL, NULL);
        g_string_free (fts, TRUE);
 
        if (rc != SQLITE_OK)
-               return FALSE;
+               goto error;
 
        str = g_string_new (NULL);
        g_string_append_printf (str,
@@ -172,13 +171,23 @@ tracker_fts_create_table (sqlite3     *db,
        rc = sqlite3_exec (db, str->str, NULL, NULL, NULL);
        g_string_free (str, TRUE);
 
-       return (rc == SQLITE_OK);
+error:
+       if (rc != SQLITE_OK) {
+               g_set_error (error,
+                            TRACKER_DB_INTERFACE_ERROR,
+                            TRACKER_DB_OPEN_ERROR,
+                            "%s", sqlite3_errstr (rc));
+               return FALSE;
+       }
+
+       return TRUE;
 }
 
 gboolean
-tracker_fts_delete_table (sqlite3     *db,
-                         const gchar *database,
-                          gchar       *table_name)
+tracker_fts_delete_table (sqlite3      *db,
+                          const gchar  *database,
+                          gchar        *table_name,
+                          GError      **error)
 {
        gchar *query;
        int rc;
@@ -194,15 +203,24 @@ tracker_fts_delete_table (sqlite3     *db,
                g_free (query);
        }
 
-       return rc == SQLITE_OK;
+       if (rc != SQLITE_OK) {
+               g_set_error (error,
+                            TRACKER_DB_INTERFACE_ERROR,
+                            TRACKER_DB_OPEN_ERROR,
+                            "%s", sqlite3_errstr (rc));
+               return FALSE;
+       }
+
+       return TRUE;
 }
 
 gboolean
-tracker_fts_alter_table (sqlite3     *db,
-                        const gchar *database,
-                        gchar       *table_name,
-                        GHashTable  *tables,
-                        GHashTable  *grouped_columns)
+tracker_fts_alter_table (sqlite3      *db,
+                         const gchar  *database,
+                         gchar        *table_name,
+                         GHashTable   *tables,
+                         GHashTable   *grouped_columns,
+                         GError      **error)
 {
        gchar *query, *tmp_name;
        int rc;
@@ -212,7 +230,7 @@ tracker_fts_alter_table (sqlite3     *db,
 
        tmp_name = g_strdup_printf ("%s_TMP", table_name);
 
-       if (!tracker_fts_create_table (db, database, tmp_name, tables, grouped_columns)) {
+       if (!tracker_fts_create_table (db, database, tmp_name, tables, grouped_columns, error)) {
                g_free (tmp_name);
                return FALSE;
        }
@@ -222,28 +240,34 @@ tracker_fts_alter_table (sqlite3     *db,
        rc = sqlite3_exec (db, query, NULL, NULL, NULL);
        g_free (query);
 
-       if (rc != SQLITE_OK) {
-               g_free (tmp_name);
-               return FALSE;
-       }
+       if (rc != SQLITE_OK)
+               goto error;
 
        query = g_strdup_printf ("INSERT INTO \"%s\".%s(%s) VALUES('rebuild')",
                                 database, tmp_name, tmp_name);
        rc = sqlite3_exec (db, query, NULL, NULL, NULL);
        g_free (query);
 
-       if (rc != SQLITE_OK) {
-               g_free (tmp_name);
-               return FALSE;
-       }
+       if (rc != SQLITE_OK)
+               goto error;
 
        query = g_strdup_printf ("ALTER TABLE \"%s\".%s RENAME TO %s",
                                 database, tmp_name, table_name);
        rc = sqlite3_exec (db, query, NULL, NULL, NULL);
        g_free (query);
+
+error:
        g_free (tmp_name);
 
-       return rc == SQLITE_OK;
+       if (rc != SQLITE_OK) {
+               g_set_error (error,
+                            TRACKER_DB_INTERFACE_ERROR,
+                            TRACKER_DB_OPEN_ERROR,
+                            "%s", sqlite3_errstr (rc));
+               return FALSE;
+       }
+
+       return TRUE;
 }
 
 void
diff --git a/src/libtracker-fts/tracker-fts.h b/src/libtracker-fts/tracker-fts.h
index 059f81823..04074bacf 100644
--- a/src/libtracker-fts/tracker-fts.h
+++ b/src/libtracker-fts/tracker-fts.h
@@ -33,19 +33,22 @@ gboolean    tracker_fts_init_db          (sqlite3               *db,
                                           TrackerDBInterface    *interface,
                                           TrackerDBManagerFlags  flags,
                                           GHashTable            *tables);
-gboolean    tracker_fts_create_table     (sqlite3     *db,
-                                          const gchar *database,
-                                          gchar       *table_name,
-                                          GHashTable  *tables,
-                                          GHashTable  *grouped_columns);
-gboolean    tracker_fts_delete_table     (sqlite3     *db,
-                                          const gchar *database,
-                                          gchar       *table_name);
-gboolean    tracker_fts_alter_table      (sqlite3     *db,
-                                          const gchar *database,
-                                          gchar       *table_name,
-                                          GHashTable  *tables,
-                                          GHashTable  *grouped_columns);
+gboolean    tracker_fts_create_table     (sqlite3      *db,
+                                          const gchar  *database,
+                                          gchar        *table_name,
+                                          GHashTable   *tables,
+                                          GHashTable   *grouped_columns,
+                                          GError      **error);
+gboolean    tracker_fts_delete_table     (sqlite3      *db,
+                                          const gchar  *database,
+                                          gchar        *table_name,
+                                          GError      **error);
+gboolean    tracker_fts_alter_table      (sqlite3      *db,
+                                          const gchar  *database,
+                                          gchar        *table_name,
+                                          GHashTable   *tables,
+                                          GHashTable   *grouped_columns,
+                                          GError      **error);
 void        tracker_fts_rebuild_tokens   (sqlite3     *db,
                                           const gchar *database,
                                           const gchar *table_name);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]