Skip to content

Commit

Permalink
Added explicit primary keys to all entity tables
Browse files Browse the repository at this point in the history
* Without an explicit primary key constraint, SQLite may reassign
  `rowid` columns when records are deleted and a subsequent
  `VACUUM` command is issued. This would break referential
  integrity in the database.
* Prior to this change it worked because the application never
  deletes records, so `rowid` values never changed after
  transactions have been committed. If, however, records were
  deleted manually, the database may become unusable after
  `VACUUM` runs.
* This change instructs SQLite to respect `rowid` values because
  now they are aliased by newly added primary key columns.
* All current SQL will still work because `rowid` may be referenced
  either as such or as the new `id` column. For new records that
  are being inserted, the new `id` column should not be listed in
  the column list of `INSERT INTO` statements and it will be
  populated using the usual `rowid` rules.
* There is no upgrade SQL provided because SQLite does not
  allow changing primary keys on existing tables without copying
  entire tables via temporary tables. The existing schema will keep
  working as long as there are no records deleted from any of the
  entity tables.
  • Loading branch information
StoneStepsInc committed Oct 6, 2024
1 parent cf170f7 commit 11ba594
Showing 1 changed file with 5 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/fit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,7 @@ sqlite3 *open_sqlite_database(const options_t& options, int& schema_version, pri

// files table
if(sqlite3_exec(file_scan_db, "CREATE TABLE files ("
"id INTEGER NOT NULL PRIMARY KEY,"
"name TEXT NOT NULL,"
"ext TEXT NULL,"
"path TEXT NOT NULL);", nullptr, nullptr, &errmsg) != SQLITE_OK)
Expand All @@ -484,6 +485,7 @@ sqlite3 *open_sqlite_database(const options_t& options, int& schema_version, pri

// versions table
if(sqlite3_exec(file_scan_db, "CREATE TABLE versions ("
"id INTEGER NOT NULL PRIMARY KEY,"
"file_id INTEGER NOT NULL,"
"version INTEGER NOT NULL,"
"mod_time INTEGER NOT NULL,"
Expand All @@ -502,6 +504,7 @@ sqlite3 *open_sqlite_database(const options_t& options, int& schema_version, pri

// exif table
if(sqlite3_exec(file_scan_db, "CREATE TABLE exif ("
"id INTEGER NOT NULL PRIMARY KEY,"
"BitsPerSample TEXT NULL,Compression INTEGER NULL,DocumentName TEXT NULL,ImageDescription TEXT NULL,"
"Make TEXT NULL,Model TEXT NULL,Orientation INTEGER NULL,SamplesPerPixel TEXT NULL,"
"Software TEXT NULL,DateTime TEXT NULL,Artist TEXT NULL,Copyright TEXT NULL,"
Expand All @@ -523,6 +526,7 @@ sqlite3 *open_sqlite_database(const options_t& options, int& schema_version, pri

// scans table
if(sqlite3_exec(file_scan_db, "CREATE TABLE scans ("
"id INTEGER NOT NULL PRIMARY KEY,"
"app_version TEXT NOT NULL,"
"scan_time INTEGER NOT NULL,"
"completed_time INTEGER NULL,"
Expand All @@ -536,6 +540,7 @@ sqlite3 *open_sqlite_database(const options_t& options, int& schema_version, pri

// scansets table
if(sqlite3_exec(file_scan_db, "CREATE TABLE scansets ("
"id INTEGER NOT NULL PRIMARY KEY,"
"scan_id INTEGER NOT NULL,"
"version_id INTEGER NOT NULL);", nullptr, nullptr, &errmsg) != SQLITE_OK)
throw std::runtime_error("Cannot create table 'scansets' ("s + std::unique_ptr<char, sqlite_malloc_deleter_t<char>>(errmsg).get() + ")");
Expand Down

0 comments on commit 11ba594

Please sign in to comment.