diff options
author | Ross Burton <ross.burton@intel.com> | 2020-03-26 15:43:39 +0000 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2020-03-28 13:25:58 +0000 |
commit | 4135af505695b98b6eed85f5f49195b961136c26 (patch) | |
tree | 42b9de20843a5f0a5fdecf1eb0892985eef0379d | |
parent | 9be580a689d1e01e2c061b0a1da6c749d83c0c2c (diff) | |
download | colord-4135af505695b98b6eed85f5f49195b961136c26.tar.gz |
Refactor opening of mapping database and try again if fails
Extract the actual opening of the mapping database to a static function,
once it is open do a quick verification of the database, and if that
fails (corrupted database, typically) then try to delete the file and
try again.
Closes #111.
-rw-r--r-- | src/cd-mapping-db.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/src/cd-mapping-db.c b/src/cd-mapping-db.c index f62e267..7a3df35 100644 --- a/src/cd-mapping-db.c +++ b/src/cd-mapping-db.c @@ -21,8 +21,10 @@ #include "config.h" +#include <errno.h> #include <gio/gio.h> #include <glib-object.h> +#include <glib/gstdio.h> #include <sqlite3.h> #include "cd-common.h" @@ -58,13 +60,13 @@ cd_mapping_db_convert_cb (void *data, gint argc, gchar **argv, gchar **col_name) return rc; } -gboolean -cd_mapping_db_load (CdMappingDb *mdb, +static gboolean +cd_mapping_db_open (CdMappingDb *mdb, const gchar *filename, + gboolean retry, GError **error) { CdMappingDbPrivate *priv = GET_PRIVATE (mdb); - const gchar *statement; gchar *error_msg = NULL; gint rc; g_autofree gchar *path = NULL; @@ -90,6 +92,55 @@ cd_mapping_db_load (CdMappingDb *mdb, return FALSE; } + /* sanity check of the database */ + rc = sqlite3_exec (priv->db, "PRAGMA quick_check", NULL, NULL, &error_msg); + if (rc != SQLITE_OK) { + /* Database appears to be mangled, so wipe it and try again */ + sqlite3_close (priv->db); + priv->db = NULL; + + if (retry) { + if (g_unlink (filename) != 0) { + g_set_error (error, + CD_CLIENT_ERROR, + CD_CLIENT_ERROR_INTERNAL, + "Cannot remove damaged database: %s", + g_strerror (errno)); + return FALSE; + } + + return cd_mapping_db_open (mdb, filename, FALSE, error); + } else { + g_set_error (error, + CD_CLIENT_ERROR, + CD_CLIENT_ERROR_INTERNAL, + "Cannot open mapping database: %s", + error_msg); + sqlite3_free (error_msg); + return FALSE; + } + } + + return TRUE; +} + +gboolean +cd_mapping_db_load (CdMappingDb *mdb, + const gchar *filename, + GError **error) +{ + CdMappingDbPrivate *priv = GET_PRIVATE (mdb); + const gchar *statement; + gchar *error_msg = NULL; + gint rc; + g_autofree gchar *path = NULL; + + g_return_val_if_fail (CD_IS_MAPPING_DB (mdb), FALSE); + g_return_val_if_fail (priv->db == NULL, FALSE); + + if (!cd_mapping_db_open (mdb, filename, TRUE, error)) + return FALSE; + /* we don't need to keep doing fsync */ rc = sqlite3_exec (priv->db, "PRAGMA synchronous=OFF", NULL, NULL, &error_msg); |