Skip to content

Commit

Permalink
Fix selected_images index
Browse files Browse the repository at this point in the history
1. For a fresh database make sure the index is created correctly
2. In the database migration it seems the unique index creation might fail if non-unique
   data are in the table, to avoid this conflict we drop & recreate both the table and index,
   the only downside being the selection is lost after database upgrade.
  • Loading branch information
jenshannoschwalm committed May 26, 2024
1 parent e3a9aa6 commit a5ba643
Showing 1 changed file with 35 additions and 12 deletions.
47 changes: 35 additions & 12 deletions src/common/database.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This file is part of darktable,
Copyright (C) 2011-2023 darktable developers.
Copyright (C) 2011-2024 darktable developers.
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -48,7 +48,7 @@

// whenever _create_*_schema() gets changed you HAVE to bump this version and add an update path to
// _upgrade_*_schema_step()!
#define CURRENT_DATABASE_VERSION_LIBRARY 51
#define CURRENT_DATABASE_VERSION_LIBRARY 52
#define CURRENT_DATABASE_VERSION_DATA 10

// #define USE_NESTED_TRANSACTIONS
Expand Down Expand Up @@ -2683,30 +2683,30 @@ static int _upgrade_library_schema_step(dt_database_t *db, int version)
TRY_EXEC("CREATE TABLE whitebalance"
" (id INTEGER PRIMARY KEY AUTOINCREMENT,"
" name VARCHAR)",
"[init] can't create table whitebalance\n");
"[init] can't create table whitebalance\n");
TRY_EXEC("CREATE UNIQUE INDEX whitebalance_name ON whitebalance (name)",
"[init] can't create index `whitebalance_name' on table `whitebalance'\n");
"[init] can't create index `whitebalance_name' on table `whitebalance'\n");

TRY_EXEC("CREATE TABLE flash"
" (id INTEGER PRIMARY KEY AUTOINCREMENT,"
" name VARCHAR)",
"[init] can't create table flash\n");
"[init] can't create table flash\n");
TRY_EXEC("CREATE UNIQUE INDEX flash_name ON flash (name)",
"[init] can't create index `flash_name' on table `flash'\n");
"[init] can't create index `flash_name' on table `flash'\n");

TRY_EXEC("CREATE TABLE exposure_program"
" (id INTEGER PRIMARY KEY AUTOINCREMENT,"
" name VARCHAR)",
"[init] can't create table exposure_program\n");
"[init] can't create table exposure_program\n");
TRY_EXEC("CREATE UNIQUE INDEX exposure_program_name ON exposure_program (name)",
"[init] can't create index `exposure_program_name' on table `exposure_program'\n");
"[init] can't create index `exposure_program_name' on table `exposure_program'\n");

TRY_EXEC("CREATE TABLE metering_mode"
" (id INTEGER PRIMARY KEY AUTOINCREMENT,"
" name VARCHAR)",
"[init] can't create table metering_mode\n");
"[init] can't create table metering_mode\n");
TRY_EXEC("CREATE UNIQUE INDEX metering_mode_name ON metering_mode (name)",
"[init] can't create index `metering_mode_name' on table `metering_mode'\n");
"[init] can't create index `metering_mode_name' on table `metering_mode'\n");

TRY_EXEC("CREATE TABLE images_new"
" (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, film_id INTEGER,"
Expand Down Expand Up @@ -2736,7 +2736,7 @@ static int _upgrade_library_schema_step(dt_database_t *db, int version)
"FOREIGN KEY(exposure_program_id) REFERENCES exposure_program(id) ON DELETE CASCADE ON UPDATE CASCADE, "
"FOREIGN KEY(metering_mode_id) REFERENCES metering_mode(id) ON DELETE CASCADE ON UPDATE CASCADE)",
"[init] can't create new table images");

TRY_EXEC("INSERT INTO images_new"
" SELECT id, group_id, film_id, width, height, filename,"
" maker_id, model_id, lens_id, camera_id,"
Expand Down Expand Up @@ -2802,6 +2802,29 @@ static int _upgrade_library_schema_step(dt_database_t *db, int version)

new_version = 51;
}
else if(version == 51)
{
sqlite3_exec(db->handle, "BEGIN TRANSACTION", NULL, NULL, NULL);

// As the selected_images table might have non-unique data the UNIQUE INDEX could fail,
// we avoid this by recreating both the table & index.
// minor downside: selection is lost while updating database sheme.
TRY_EXEC("DROP INDEX selected_images_ni",
"[init] can't drop index selected_images_ni\n");

TRY_EXEC("DROP TABLE selected_images",
"[init] can't drop selected_images\n");

TRY_EXEC("CREATE TABLE selected_images (num INTEGER PRIMARY KEY AUTOINCREMENT, imgid INTEGER)",
"[init] can't create selected_images\n");

TRY_EXEC("CREATE UNIQUE INDEX selected_images_ni"
" ON selected_images (imgid)",
"[init] can't create index selected_images_ni\n");

sqlite3_exec(db->handle, "COMMIT", NULL, NULL, NULL);
new_version = 52;
}
else
new_version = version; // should be the fallback so that calling code sees that we are in an infinite loop

Expand Down Expand Up @@ -3246,7 +3269,7 @@ static void _create_library_schema(dt_database_t *db)

sqlite3_exec(db->handle,
"CREATE UNIQUE INDEX main.selected_images_ni"
" ON main.selected_images (num, imgid)",
" ON selected_images (num, imgid)",
NULL, NULL, NULL);
////////////////////////////// history
sqlite3_exec(
Expand Down

0 comments on commit a5ba643

Please sign in to comment.