From f773a547dbc267474f9b52276e94998a84e202f0 Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Fri, 14 Mar 2025 10:56:31 +0000 Subject: [PATCH] db: Fail graciously when we could not open the database This mainly changes the return code and does some minor code cleanups Signed-off-by: Michael Tremer --- src/pakfire/db.c | 96 +++++++++++++++++++++++++++--------------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/src/pakfire/db.c b/src/pakfire/db.c index 545f8b96..b280a876 100644 --- a/src/pakfire/db.c +++ b/src/pakfire/db.c @@ -594,23 +594,31 @@ ROLLBACK: } static int pakfire_db_check_arch(struct pakfire_db* db) { - int r = 1; + const char* arch = NULL; + char* db_arch = NULL; + int r = 0; // Fetch database architecture - char* db_arch = pakfire_db_get_string(db, "arch"); + db_arch = pakfire_db_get_string(db, "arch"); if (!db_arch) { - ERROR(db->ctx, "Database is of an unknown architecture\n"); + ERROR(db->ctx, "Database is of an unknown format\n"); + r = -EINVAL; goto ERROR; } // Fetch the running architecture - const char* arch = pakfire_get_effective_arch(db->pakfire); - if (!arch) + arch = pakfire_get_effective_arch(db->pakfire); + if (!arch) { + r = -EINVAL; goto ERROR; + } // They should match - if (strcmp(db_arch, arch) == 0) - r = 0; + if (!pakfire_string_equals(db_arch, arch)) { + ERROR(db->ctx, "Database architecture does not match, got %s\n", db_arch); + r = -EINVAL; + goto ERROR; + } ERROR: if (db_arch) @@ -638,7 +646,7 @@ static int pakfire_db_setup(struct pakfire_db* db) { if (db->schema && db->schema < SCHEMA_MIN_SUP) { ERROR(db->ctx, "Database schema %d is not supported by this version of Pakfire\n", db->schema); - return 1; + return -ENOTSUP; } // Read modification timestamp @@ -658,7 +666,7 @@ static int pakfire_db_setup(struct pakfire_db* db) { if (r != SQLITE_OK) { ERROR(db->ctx, "Could not set journal mode to WAL: %s\n", sqlite3_errmsg(db->handle)); - return 1; + return -ENOTSUP; } // Disable autocheckpoint @@ -666,77 +674,81 @@ static int pakfire_db_setup(struct pakfire_db* db) { if (r != SQLITE_OK) { ERROR(db->ctx, "Could not disable autocheckpoint: %s\n", sqlite3_errmsg(db->handle)); - return 1; + return -ENOTSUP; } // Create or migrate schema r = pakfire_db_migrate_schema(db); - if (r) + if (r < 0) return r; return 0; } int pakfire_db_open(struct pakfire_db** db, struct pakfire* pakfire, int flags) { - int r = 1; + struct pakfire_db* self = NULL; + int sqlite3_flags = 0; + int r; - struct pakfire_db* o = calloc(1, sizeof(*o)); - if (!o) - return -ENOMEM; + // Allocate some memory + self = calloc(1, sizeof(*self)); + if (!self) + return -errno; // Store a reference to the context - o->ctx = pakfire_ctx(pakfire); + self->ctx = pakfire_ctx(pakfire); - o->pakfire = pakfire_ref(pakfire); - o->nrefs = 1; + // Store a reference to pakfire + self->pakfire = pakfire_ref(pakfire); - int sqlite3_flags = 0; + // Initialize the reference counter + self->nrefs = 1; // Store mode & forward it to sqlite3 if (flags & PAKFIRE_DB_READWRITE) { - o->mode = PAKFIRE_DB_READWRITE; + self->mode = PAKFIRE_DB_READWRITE; sqlite3_flags |= SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; } else { - o->mode = PAKFIRE_DB_READONLY; + self->mode = PAKFIRE_DB_READONLY; sqlite3_flags |= SQLITE_OPEN_READONLY; } // Make the filename - r = pakfire_path(o->pakfire, o->path, "%s", DATABASE_PATH); - if (r) - goto END; + r = pakfire_path(self->pakfire, self->path, "%s", DATABASE_PATH); + if (r < 0) + goto ERROR; // Create the parent directory - r = pakfire_mkparentdir(o->path, 0755); + r = pakfire_mkparentdir(self->path, 0755); if (r < 0) - goto END; + goto ERROR; // Try to open the sqlite3 database file - r = sqlite3_open_v2(o->path, &o->handle, sqlite3_flags, NULL); + r = sqlite3_open_v2(self->path, &self->handle, sqlite3_flags, NULL); if (r != SQLITE_OK) { - ERROR(o->ctx, "Could not open database %s: %s\n", - o->path, sqlite3_errmsg(o->handle)); + ERROR(self->ctx, "Could not open database %s: %s\n", + self->path, sqlite3_errmsg(self->handle)); - r = 1; - goto END; + r = -errno; + goto ERROR; } // Setup the database - r = pakfire_db_setup(o); - if (r) - goto END; + r = pakfire_db_setup(self); + if (r < 0) + goto ERROR; // Check for compatible architecture - r = pakfire_db_check_arch(o); - if (r) - goto END; + r = pakfire_db_check_arch(self); + if (r < 0) + goto ERROR; - *db = o; - r = 0; + // Return the pointer + *db = self; + return 0; -END: - if (r) - pakfire_db_free(o); +ERROR: + pakfire_db_free(self); return r; } -- 2.39.5