]> git.ipfire.org Git - people/stevee/pakfire.git/commitdiff
db: Check for compatible architecture
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 8 May 2022 16:34:44 +0000 (16:34 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 8 May 2022 16:34:44 +0000 (16:34 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/libpakfire/db.c

index 8f24e0f587b37795377e5ad3ba37fed4814827bc..9b21a8b15377b1275f1f94b6e7ebd57c795245e1 100644 (file)
@@ -108,6 +108,75 @@ ERROR:
        return val;
 }
 
+static char* pakfire_db_get_string(struct pakfire_db* db, const char* key) {
+       char* s = NULL;
+
+       // Fetch the value from the database
+       sqlite3_value* value = pakfire_db_get(db, key);
+       if (!value)
+               return NULL;
+
+       // Extract the value as string
+       const char* p = (const char*)sqlite3_value_text(value);
+       if (!p)
+               goto ERROR;
+
+       // Copy string to heap
+       s = strdup(p);
+
+ERROR:
+       if (value)
+               sqlite3_value_free(value);
+
+       return s;
+}
+
+static int pakfire_db_set_string(struct pakfire_db* db, const char* key, const char* val) {
+       sqlite3_stmt* stmt = NULL;
+       int r;
+
+       DEBUG(db->pakfire, "Setting %s to '%s'\n", key, val);
+
+       const char* sql = "INSERT INTO settings(key, val) VALUES(?, ?) \
+               ON CONFLICT (key) DO UPDATE SET val = excluded.val";
+
+       // Prepare statement
+       r = sqlite3_prepare_v2(db->handle, sql, strlen(sql), &stmt, NULL);
+       if (r != SQLITE_OK) {
+               ERROR(db->pakfire, "Could not prepare SQL statement: %s: %s\n",
+                       sql, sqlite3_errmsg(db->handle));
+               return 1;
+       }
+
+       // Bind key
+       r = sqlite3_bind_text(stmt, 1, key, strlen(key), NULL);
+       if (r != SQLITE_OK) {
+               ERROR(db->pakfire, "Could not bind key: %s\n", sqlite3_errmsg(db->handle));
+               goto ERROR;
+       }
+
+       // Bind val
+       r = sqlite3_bind_text(stmt, 2, val, strlen(val), NULL);
+       if (r != SQLITE_OK) {
+               ERROR(db->pakfire, "Could not bind val: %s\n", sqlite3_errmsg(db->handle));
+               goto ERROR;
+       }
+
+       // Execute the statement
+       do {
+               r = sqlite3_step(stmt);
+       } while (r == SQLITE_BUSY);
+
+       // Set return code
+       r = (r == SQLITE_OK);
+
+ERROR:
+       if (stmt)
+               sqlite3_finalize(stmt);
+
+       return r;
+}
+
 static int pakfire_db_set_int(struct pakfire_db* db, const char* key, int val) {
        sqlite3_stmt* stmt = NULL;
        int r;
@@ -377,6 +446,15 @@ static int pakfire_db_create_schema(struct pakfire_db* db) {
        if (r)
                return 1;
 
+       const char* arch = pakfire_get_arch(db->pakfire);
+
+       // Set architecture
+       r = pakfire_db_set_string(db, "arch", arch);
+       if (r) {
+               ERROR(db->pakfire, "Could not set architecture\n");
+               return r;
+       }
+
        return 0;
 }
 
@@ -441,6 +519,32 @@ ROLLBACK:
        return 1;
 }
 
+static int pakfire_db_check_arch(struct pakfire_db* db) {
+       int r = 1;
+
+       // Fetch database architecture
+       char* db_arch = pakfire_db_get_string(db, "arch");
+       if (!db_arch) {
+               ERROR(db->pakfire, "Database is of an unknown architecture\n");
+               goto ERROR;
+       }
+
+       // Fetch the running architecture
+       const char* arch = pakfire_get_arch(db->pakfire);
+       if (!arch)
+               goto ERROR;
+
+       // They should match
+       if (strcmp(db_arch, arch) == 0)
+               r = 0;
+
+ERROR:
+       if (db_arch)
+               free(db_arch);
+
+       return r;
+}
+
 static int pakfire_db_setup(struct pakfire_db* db) {
        int r;
 
@@ -540,6 +644,11 @@ int pakfire_db_open(struct pakfire_db** db, struct pakfire* pakfire, int flags)
        if (r)
                goto END;
 
+       // Check for compatible architecture
+       r = pakfire_db_check_arch(o);
+       if (r)
+               goto END;
+
        *db = o;
        r = 0;