78#include <glib/gstdio.h>
89#define CURRENT_DATABASE_VERSION_LIBRARY 36
90#define CURRENT_DATABASE_VERSION_DATA 9
93#define MAX_NESTED_TRANSACTIONS 0
161#define _db_print(...) \
163 if(_verbose) dt_print(DT_DEBUG_SQL, __VA_ARGS__); \
177#define _SQLITE3_EXEC(a, b, c, d, e) \
178 if(sqlite3_exec(a, b, c, d, e) != SQLITE_OK) \
213 _SQLITE3_EXEC(db->
handle,
"CREATE TABLE main.db_info (key VARCHAR PRIMARY KEY, value VARCHAR)",
215 _SQLITE3_EXEC(db->
handle,
"INSERT OR REPLACE INTO main.db_info (key, value) VALUES ('version', 1)",
218 _SQLITE3_EXEC(db->
handle,
"CREATE INDEX IF NOT EXISTS main.film_rolls_folder_index ON film_rolls (folder)",
234 _SQLITE3_EXEC(db->
handle,
"UPDATE main.images SET focus_distance = -1 WHERE focus_distance IS NULL",
237 _SQLITE3_EXEC(db->
handle,
"UPDATE main.images SET max_version = (SELECT COUNT(*)-1 FROM main.images i WHERE "
238 "i.filename = main.images.filename AND "
239 "i.film_id = main.images.film_id) WHERE max_version IS NULL",
243 "UPDATE main.images SET version = (SELECT COUNT(*) FROM main.images i "
244 "WHERE i.filename = main.images.filename AND "
245 "i.film_id = main.images.film_id AND i.id < main.images.id) WHERE version IS NULL",
253 "CREATE TABLE main.images (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, film_id INTEGER, "
254 "width INTEGER, height INTEGER, filename VARCHAR, maker VARCHAR, model VARCHAR, "
255 "lens VARCHAR, exposure REAL, aperture REAL, iso REAL, focal_length REAL, "
256 "focus_distance REAL, datetime_taken CHAR(20), flags INTEGER, "
257 "output_width INTEGER, output_height INTEGER, crop REAL, "
258 "raw_parameters INTEGER, raw_denoise_threshold REAL, "
259 "raw_auto_bright_threshold REAL, raw_black INTEGER, raw_maximum INTEGER, "
260 "caption VARCHAR, description VARCHAR, license VARCHAR, sha1sum CHAR(40), "
261 "orientation INTEGER, histogram BLOB, lightmap BLOB, longitude REAL, "
262 "latitude REAL, color_matrix BLOB, colorspace INTEGER, version INTEGER, max_version INTEGER)",
268 "INSERT INTO main.images (id, group_id, film_id, width, height, filename, maker, model, "
269 "lens, exposure, aperture, iso, focal_length, focus_distance, datetime_taken, flags, "
270 "output_width, output_height, crop, raw_parameters, raw_denoise_threshold, "
271 "raw_auto_bright_threshold, raw_black, raw_maximum, caption, description, license, sha1sum, "
272 "orientation, histogram, lightmap, longitude, latitude, color_matrix, colorspace, version, "
274 "SELECT id, group_id, film_id, width, height, filename, maker, model, lens, exposure, aperture, iso, "
275 "focal_length, focus_distance, datetime_taken, flags, output_width, output_height, crop, "
276 "raw_parameters, raw_denoise_threshold, raw_auto_bright_threshold, raw_black, raw_maximum, "
277 "caption, description, license, sha1sum, orientation, histogram, lightmap, longitude, "
278 "latitude, color_matrix, colorspace, version, max_version FROM dt_migration_table",
288 _SQLITE3_EXEC(db->
handle,
"INSERT OR IGNORE INTO main.selected_images SELECT imgid FROM dt_migration_table",
304 _SQLITE3_EXEC(db->
handle,
"CREATE TABLE IF NOT EXISTS main.mask (imgid INTEGER, formid INTEGER, form INTEGER, "
305 "name VARCHAR(256), version INTEGER, "
306 "points BLOB, points_count INTEGER, source BLOB)",
311 _SQLITE3_EXEC(db->
handle,
"CREATE INDEX IF NOT EXISTS main.tagged_images_tagid_index ON tagged_images (tagid)",
315 "CREATE TABLE IF NOT EXISTS main.styles (id INTEGER, name VARCHAR, description VARCHAR)",
NULL,
320 _SQLITE3_EXEC(db->
handle,
"CREATE TABLE IF NOT EXISTS main.style_items (styleid INTEGER, num INTEGER, module "
321 "INTEGER, operation VARCHAR(256), op_params BLOB, "
322 "enabled INTEGER, blendop_params BLOB, blendop_version INTEGER, multi_priority "
323 "INTEGER, multi_name VARCHAR(256))",
329 _SQLITE3_EXEC(db->
handle,
"UPDATE main.style_items SET blendop_version = 1 WHERE blendop_version IS NULL",
NULL,
345 _SQLITE3_EXEC(db->
handle,
"INSERT OR IGNORE INTO main.color_labels SELECT imgid, color FROM dt_migration_table",
349 _SQLITE3_EXEC(db->
handle,
"CREATE TABLE IF NOT EXISTS main.meta_data (id INTEGER, key INTEGER, value VARCHAR)",
354 _SQLITE3_EXEC(db->
handle,
"CREATE TABLE IF NOT EXISTS main.presets (name VARCHAR, description VARCHAR, "
355 "operation VARCHAR, op_version INTEGER, op_params BLOB, "
356 "enabled INTEGER, blendop_params BLOB, blendop_version INTEGER, multi_priority "
357 "INTEGER, multi_name VARCHAR(256), "
358 "model VARCHAR, maker VARCHAR, lens VARCHAR, iso_min REAL, iso_max REAL, "
359 "exposure_min REAL, exposure_max REAL, "
360 "aperture_min REAL, aperture_max REAL, focal_length_min REAL, focal_length_max "
361 "REAL, writeprotect INTEGER, "
362 "autoapply INTEGER, filter INTEGER, def INTEGER, isldr INTEGER)",
372 "SELECT p.rowid, p.name, p.operation, p.op_version FROM main.presets p INNER JOIN "
373 "(SELECT * FROM (SELECT rowid, name, operation, op_version, COUNT(*) AS count "
374 "FROM main.presets GROUP BY name, operation, op_version) WHERE count > 1) s "
375 "ON p.name = s.name AND p.operation = s.operation AND p.op_version = s.op_version",
403 "operation = ?3 AND op_version = ?4",
421 const char *
query =
"UPDATE main.presets SET name = name || ' (' || ?1 || ')' WHERE rowid = ?2";
440 "CREATE UNIQUE INDEX IF NOT EXISTS main.presets_idx ON presets (name, operation, op_version)",
478 "UPDATE main.images SET datetime_taken = REPLACE(datetime_taken, '-', ':') WHERE datetime_taken LIKE '%-%'",
497#define TRY_EXEC(_query, _message) \
500 if(sqlite3_exec(db->handle, _query, NULL, NULL, NULL) != SQLITE_OK) \
502 fprintf(stderr, _message); \
503 fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
505 sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
510#define TRY_STEP(_stmt, _expected, _message) \
513 if(sqlite3_step(_stmt) != _expected) \
515 fprintf(stderr, _message); \
516 fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
518 sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
523#define TRY_PREPARE(_stmt, _query, _message) \
526 if(sqlite3_prepare_v2(db->handle, _query, -1, &_stmt, NULL) != SQLITE_OK) \
528 fprintf(stderr, _message); \
529 fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
531 sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
546 else if(version == 0)
553 else if(version == 1)
558 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN write_timestamp INTEGER",
559 "[init] can't add `write_timestamp' column to database\n");
560 TRY_EXEC(
"UPDATE main.images SET write_timestamp = STRFTIME('%s', 'now') WHERE write_timestamp IS NULL",
561 "[init] can't initialize `write_timestamp' with current point in time\n");
566 else if(version == 2)
572 TRY_EXEC(
"UPDATE main.images SET raw_black = 0, raw_maximum = 16384",
573 "[init] can't reset raw_black and raw_maximum\n");
578 else if(version == 3)
582 TRY_EXEC(
"CREATE TRIGGER insert_tag AFTER INSERT ON main.tags"
584 " INSERT INTO tagxtag SELECT id, new.id, 0 FROM TAGS;"
585 " UPDATE tagxtag SET count = 1000000 WHERE id1=new.id AND id2=new.id;"
587 "[init] can't create insert_tag trigger\n");
588 TRY_EXEC(
"CREATE TRIGGER delete_tag BEFORE DELETE ON main.tags"
590 " DELETE FROM tagxtag WHERE id1=old.id OR id2=old.id;"
591 " DELETE FROM tagged_images WHERE tagid=old.id;"
593 "[init] can't create delete_tag trigger\n");
594 TRY_EXEC(
"CREATE TRIGGER attach_tag AFTER INSERT ON main.tagged_images"
597 " SET count = count + 1"
598 " WHERE (id1=new.tagid AND id2 IN (SELECT tagid FROM tagged_images WHERE imgid=new.imgid))"
599 " OR (id2=new.tagid AND id1 IN (SELECT tagid FROM tagged_images WHERE imgid=new.imgid));"
601 "[init] can't create attach_tag trigger\n");
602 TRY_EXEC(
"CREATE TRIGGER detach_tag BEFORE DELETE ON main.tagged_images"
605 " SET count = count - 1"
606 " WHERE (id1=old.tagid AND id2 IN (SELECT tagid FROM tagged_images WHERE imgid=old.imgid))"
607 " OR (id2=old.tagid AND id1 IN (SELECT tagid FROM tagged_images WHERE imgid=old.imgid));"
609 "[init] can't create detach_tag trigger\n");
614 else if(version == 4)
618 TRY_EXEC(
"ALTER TABLE main.presets RENAME TO tmp_presets",
"[init] can't rename table presets\n");
620 TRY_EXEC(
"CREATE TABLE main.presets (name VARCHAR, description VARCHAR, operation VARCHAR, op_params BLOB,"
621 "enabled INTEGER, blendop_params BLOB, model VARCHAR, maker VARCHAR, lens VARCHAR,"
622 "iso_min REAL, iso_max REAL, exposure_min REAL, exposure_max REAL, aperture_min REAL,"
623 "aperture_max REAL, focal_length_min REAL, focal_length_max REAL, writeprotect INTEGER,"
624 "autoapply INTEGER, filter INTEGER, def INTEGER, format INTEGER, op_version INTEGER,"
625 "blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))",
626 "[init] can't create new presets table\n");
628 TRY_EXEC(
"INSERT INTO main.presets (name, description, operation, op_params, enabled, blendop_params, model, "
629 "maker, lens, iso_min, iso_max, exposure_min, exposure_max, aperture_min, aperture_max,"
630 "focal_length_min, focal_length_max, writeprotect, autoapply, filter, def, format, op_version, "
631 "blendop_version, multi_priority, multi_name) SELECT name, description, operation, op_params, "
632 "enabled, blendop_params, model, maker, lens, iso_min, iso_max, exposure_min, exposure_max, "
633 "aperture_min, aperture_max, focal_length_min, focal_length_max, writeprotect, autoapply, filter, "
634 "def, isldr, op_version, blendop_version, multi_priority, multi_name FROM tmp_presets",
635 "[init] can't populate presets table from tmp_presets\n");
637 TRY_EXEC(
"DROP TABLE tmp_presets",
"[init] can't delete table tmp_presets\n");
642 else if(version == 5)
646 TRY_EXEC(
"CREATE INDEX main.images_filename_index ON images (filename)",
647 "[init] can't create index on image filename\n");
652 else if(version == 6)
660 TRY_EXEC(
"ALTER TABLE main.style_items RENAME TO tmp_style_items",
661 "[init] can't rename table style_items\n");
663 TRY_EXEC(
"CREATE TABLE main.style_items (styleid INTEGER, num INTEGER, module INTEGER, "
664 "operation VARCHAR(256), op_params BLOB, enabled INTEGER, "
665 "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))",
666 "[init] can't create new style_items table\n");
668 TRY_EXEC(
"INSERT INTO main.style_items (styleid, num, module, operation, op_params, enabled,"
669 " blendop_params, blendop_version, multi_priority, multi_name)"
670 " SELECT style_id, num, module, operation, op_params, enabled,"
671 " blendop_params, blendop_version, multi_priority, multi_name"
672 " FROM tmp_style_items",
673 "[init] can't populate style_items table from tmp_style_items\n");
675 TRY_EXEC(
"DROP TABLE tmp_style_items",
"[init] can't delete table tmp_style_items\n");
682 else if(version == 7)
687 TRY_EXEC(
"ALTER TABLE main.film_rolls RENAME TO tmp_film_rolls",
"[init] can't rename table film_rolls\n");
689 TRY_EXEC(
"CREATE TABLE main.film_rolls "
690 "(id INTEGER PRIMARY KEY, datetime_accessed CHAR(20), "
691 "folder VARCHAR(1024) NOT NULL)",
692 "[init] can't create new film_rolls table\n");
694 TRY_EXEC(
"INSERT INTO main.film_rolls (id, datetime_accessed, folder) "
695 "SELECT id, datetime_accessed, folder "
696 "FROM tmp_film_rolls "
697 "WHERE folder IS NOT NULL",
698 "[init] can't populate film_rolls table from tmp_film_rolls\n");
700 TRY_EXEC(
"DROP TABLE tmp_film_rolls",
"[init] can't delete table tmp_film_rolls\n");
705 else if(version == 8)
710 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN history_end INTEGER",
711 "[init] can't add `history_end' column to database\n");
713 TRY_EXEC(
"UPDATE main.images SET history_end = (SELECT IFNULL(MAX(num) + 1, 0) FROM main.history "
714 "WHERE imgid = id)",
"[init] can't initialize `history_end' with last history entry\n");
719 else if(version == 9)
724 TRY_EXEC(
"UPDATE main.images SET history_end = (SELECT IFNULL(MAX(num) + 1, 0) FROM main.history "
725 "WHERE imgid = id)",
"[init] can't set `history_end' to 0 where it was NULL\n");
730 else if(version == 10)
735 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN altitude REAL",
736 "[init] can't add `altitude' column to database\n");
738 TRY_EXEC(
"UPDATE main.images SET altitude = NULL",
"[init] can't initialize `altitude' with NULL\n");
743 else if(version == 11)
748 TRY_EXEC(
"DROP TRIGGER main.detach_tag",
"[init] can't drop trigger `detach_tag' from database\n");
750 TRY_EXEC(
"DROP TRIGGER main.attach_tag",
"[init] can't drop trigger `attach_tag' from database\n");
752 TRY_EXEC(
"DROP TRIGGER main.delete_tag",
"[init] can't drop trigger `delete_tag' from database\n");
754 TRY_EXEC(
"DROP TRIGGER main.insert_tag",
"[init] can't drop trigger `insert_tag' from database\n");
756 TRY_EXEC(
"DROP TABLE main.tagxtag",
"[init] can't drop table `tagxtag' from database\n");
761 else if(version == 12)
771 sqlite3_finalize(stmt); \
772 sqlite3_finalize(select_stmt); \
773 sqlite3_finalize(count_clashes_stmt); \
774 sqlite3_finalize(update_name_stmt); \
775 sqlite3_finalize(insert_stmt); \
776 sqlite3_finalize(delete_stmt); \
785 TRY_EXEC(
"DELETE FROM main.presets WHERE rowid IN (SELECT p1.rowid FROM main.presets p1 "
786 "JOIN data.presets p2 ON "
787 "p1.name IS p2.name AND "
788 "p1.description IS p2.description AND "
789 "p1.operation IS p2.operation AND "
790 "p1.op_version IS p2.op_version AND "
791 "p1.op_params IS p2.op_params AND "
792 "p1.enabled IS p2.enabled AND "
793 "p1.blendop_params IS p2.blendop_params AND "
794 "p1.blendop_version IS p2.blendop_version AND "
795 "p1.multi_priority IS p2.multi_priority AND "
796 "p1.multi_name IS p2.multi_name AND "
797 "p1.model IS p2.model AND "
798 "p1.maker IS p2.maker AND "
799 "p1.lens IS p2.lens AND "
800 "p1.iso_min IS p2.iso_min AND "
801 "p1.iso_max IS p2.iso_max AND "
802 "p1.exposure_min IS p2.exposure_min AND "
803 "p1.exposure_max IS p2.exposure_max AND "
804 "p1.aperture_min IS p2.aperture_min AND "
805 "p1.aperture_max IS p2.aperture_max AND "
806 "p1.focal_length_min IS p2.focal_length_min AND "
807 "p1.focal_length_max IS p2.focal_length_max AND "
808 "p1.writeprotect IS p2.writeprotect AND "
809 "p1.autoapply IS p2.autoapply AND "
810 "p1.filter IS p2.filter AND "
811 "p1.def IS p2.def AND "
812 "p1.format IS p2.format "
813 "WHERE p1.writeprotect = 0)",
814 "[init] can't delete already migrated presets from database\n");
818 TRY_PREPARE(
select_stmt,
"SELECT p.rowid, r FROM main.presets AS p, (SELECT rowid AS r, name, operation, "
819 "op_version FROM main.presets GROUP BY name, operation, op_version HAVING "
820 "COUNT(*) > 1) USING (name, operation, op_version) WHERE p.rowid != r",
821 "[init] can't prepare selecting presets with same name, operation, op_version from database\n");
825 "FROM main.presets WHERE rowid = ?1) AS i ON p.name = i.name || \" #\" || ?2 "
826 "AND p.operation = i.operation AND p.op_version = i.op_version",
827 "[init] can't prepare selection of preset count by name from database\n");
831 "[init] can't prepare updating of preset name in database\n");
834 TRY_PREPARE(
stmt,
"SELECT p1.rowid FROM main.presets p1 INNER JOIN data.presets p2 "
835 "USING (name, operation, op_version) WHERE p1.writeprotect = 0",
836 "[init] can't access table `presets' in database\n");
840 "op_params, enabled, blendop_params, blendop_version, multi_priority, multi_name, "
841 "model, maker, lens, iso_min, iso_max, exposure_min, exposure_max, aperture_min, "
842 "aperture_max, focal_length_min, focal_length_max, writeprotect, autoapply, filter, "
844 "SELECT name || \" #\" || ?1, description, operation, op_version, op_params, "
845 "enabled, blendop_params, blendop_version, multi_priority, multi_name, model, maker, "
846 "lens, iso_min, iso_max, exposure_min, exposure_max, aperture_min, aperture_max, "
847 "focal_length_min, focal_length_max, writeprotect, autoapply, filter, def, format "
848 "FROM main.presets p1 WHERE p1.rowid = ?2",
849 "[init] can't prepare insertion statement\n");
851 TRY_PREPARE(
delete_stmt,
"DELETE FROM main.presets WHERE rowid = ?1",
"[init] can't prepare deletion statement\n");
899 TRY_EXEC(
"INSERT OR FAIL INTO data.presets SELECT name, description, operation, "
900 "op_version, op_params, enabled, blendop_params, blendop_version, "
901 "multi_priority, multi_name, model, maker, lens, iso_min, iso_max, "
902 "exposure_min, exposure_max, aperture_min, aperture_max, "
903 "focal_length_min, focal_length_max, writeprotect, autoapply, filter, "
904 "def, format FROM main.presets WHERE writeprotect = 0",
905 "[init] can't copy presets to the data database\n");
907 TRY_EXEC(
"DELETE FROM main.presets WHERE writeprotect = 0",
908 "[init] can't copy presets to the data database\n");
918 sqlite3_finalize(stmt); \
919 sqlite3_finalize(insert_stmt); \
920 sqlite3_finalize(select_stmt); \
921 sqlite3_finalize(delete_stmt); \
922 sqlite3_finalize(update_name_stmt); \
923 sqlite3_finalize(select_new_stmt); \
924 sqlite3_finalize(copy_style_items_stmt); \
925 sqlite3_finalize(delete_style_items_stmt); \
935 TRY_PREPARE(
stmt,
"SELECT id, name FROM main.styles",
"[init] can't prepare style selection from database\n");
937 "[init] can't prepare style item selection from database\n");
939 "[init] can't prepare style name update\n");
941 "SELECT (SELECT COALESCE(MAX(id),0)+1 FROM data.styles), name, description "
942 "FROM main.styles where id = ?1",
943 "[init] can't prepare style insertion for database\n");
945 "[init] can't prepare style deletion for database\n");
947 "[init] can't prepare style selection from data database\n");
949 "(styleid, num, module, operation, op_params, enabled, blendop_params, "
950 "blendop_version, multi_priority, multi_name) "
951 "SELECT ?1, num, module, operation, op_params, enabled, blendop_params, "
952 "blendop_version, multi_priority, multi_name FROM main.style_items "
953 "WHERE styleid = ?2",
954 "[init] can't prepare style item copy into data database\n");
956 "[init] can't prepare style item deletion for database\n");
1032 TRY_EXEC(
"INSERT OR IGNORE INTO data.tags (name, icon, description, flags) "
1033 "SELECT name, icon, description, flags FROM main.tags",
1034 "[init] can't prepare insertion of used tags into data database\n");
1038 TRY_EXEC(
"CREATE TEMPORARY TABLE tagged_images_tmp (imgid INTEGER, tagid INTEGER)",
1039 "[init] can't create temporary table for updating `tagged_images'\n");
1041 TRY_EXEC(
"INSERT INTO tagged_images_tmp (imgid, tagid) "
1042 "SELECT imgid, (SELECT t2.id FROM main.tags t1, data.tags t2 USING (name) WHERE t1.id = tagid) "
1043 "FROM main.tagged_images",
"[init] can't insert into `tagged_images_tmp'\n");
1045 TRY_EXEC(
"DELETE FROM main.tagged_images",
"[init] can't delete tagged images in database\n");
1047 TRY_EXEC(
"INSERT OR IGNORE INTO main.tagged_images (imgid, tagid) SELECT imgid, tagid FROM tagged_images_tmp",
1048 "[init] can't copy updated values back to `tagged_images'\n");
1050 TRY_EXEC(
"DROP TABLE tagged_images_tmp",
"[init] can't drop table `tagged_images_tmp' from database\n");
1053 TRY_EXEC(
"DROP INDEX IF EXISTS main.presets_idx",
"[init] can't drop index `presets_idx' from database\n");
1054 TRY_EXEC(
"DROP TABLE main.presets",
"[init] can't drop table `presets' from database\n");
1055 TRY_EXEC(
"DROP TABLE main.style_items",
"[init] can't drop table `style_items' from database\n");
1056 TRY_EXEC(
"DROP TABLE main.styles",
"[init] can't drop table `styles' from database\n");
1057 TRY_EXEC(
"DROP TABLE main.tags",
"[init] can't drop table `tags' from database\n");
1061 }
else if(version == 13)
1066 TRY_EXEC(
"CREATE TABLE main.used_tags (id INTEGER, name VARCHAR NOT NULL)",
1067 "[init] can't create `used_tags` table\n");
1069 TRY_EXEC(
"CREATE INDEX main.used_tags_idx ON used_tags (id, name)",
1070 "[init] can't create index on table `used_tags' in database\n");
1072 TRY_EXEC(
"INSERT INTO main.used_tags (id, name) SELECT t.id, t.name FROM data.tags AS t, main.tagged_images "
1073 "AS i ON t.id = i.tagid GROUP BY t.id",
1074 "[init] can't insert used tags into `used_tags` table in database\n");
1079 else if(version == 14)
1084 TRY_EXEC(
"DELETE FROM main.used_tags WHERE rowid NOT IN (SELECT rowid FROM used_tags GROUP BY id)",
1085 "[init] can't delete duplicated entries from `used_tags' in database\n");
1087 TRY_EXEC(
"DROP INDEX main.used_tags_idx",
"[init] can't drop index `used_tags_idx' from database\n");
1089 TRY_EXEC(
"CREATE UNIQUE INDEX main.used_tags_idx ON used_tags (id, name)",
1090 "[init] can't create index `used_tags_idx' in database\n");
1092 TRY_EXEC(
"DELETE FROM main.tagged_images WHERE tagid IS NULL",
1093 "[init] can't delete NULL entries from `tagged_images' in database");
1095 TRY_EXEC(
"DELETE FROM main.used_tags WHERE id NOT IN (SELECT DISTINCT tagid FROM main.tagged_images)",
1096 "[init] can't delete unused tags from `used_tags' in database\n");
1101 else if(version == 15)
1106 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN position INTEGER",
1107 "[init] can't add `position' column to images table in database\n");
1108 TRY_EXEC(
"CREATE INDEX main.image_position_index ON images (position)",
1109 "[init] can't create index for custom image order table\n");
1119 TRY_EXEC(
"UPDATE main.images SET position = id << 32",
1120 "[init] can't update positions custom image order table\n");
1125 else if(version == 16)
1130 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN aspect_ratio REAL",
1131 "[init] can't add `aspect_ratio' column to images table in database\n");
1132 TRY_EXEC(
"UPDATE main.images SET aspect_ratio = 0.0",
1133 "[init] can't update aspect_ratio in database\n");
1138 else if(version == 17)
1144 TRY_EXEC(
"CREATE TABLE main.masks_history (imgid INTEGER, num INTEGER, formid INTEGER, form INTEGER, name VARCHAR(256), "
1145 "version INTEGER, points BLOB, points_count INTEGER, source BLOB)",
1146 "[init] can't create `masks_history` table\n");
1148 TRY_EXEC(
"CREATE INDEX main.masks_history_imgid_index ON masks_history (imgid)",
1149 "[init] can't create index `masks_history_imgid_index' in database\n");
1152 TRY_EXEC(
"CREATE INDEX main.mask_imgid_index ON mask (imgid);",
1153 "[init] can't create index `mask_imgid_index' in database\n");
1157 TRY_EXEC(
"UPDATE main.history SET num=num+1 WHERE imgid IN (SELECT imgid FROM main.mask WHERE main.mask.imgid=main.history.imgid)",
1158 "[init] can't update `num' with num+1\n");
1161 TRY_EXEC(
"UPDATE main.images SET history_end = history_end+1 WHERE id IN (SELECT imgid FROM main.mask WHERE main.mask.imgid=main.images.id)",
1162 "[init] can't update `history_end' with history_end+1\n");
1165 TRY_EXEC(
"INSERT INTO main.masks_history (imgid, num, formid, form, name, version, points, points_count, source) SELECT "
1166 "imgid, 0, formid, form, name, version, points, points_count, source FROM main.mask",
1167 "[init] can't insert into masks_history\n");
1170 TRY_EXEC(
"INSERT INTO main.history (imgid, num, operation, op_params, module, enabled, "
1171 "blendop_params, blendop_version, multi_priority, multi_name) "
1172 "SELECT DISTINCT imgid, 0, 'mask_manager', NULL, 1, 0, NULL, 0, 0, '' FROM main.mask "
1174 "[init] can't insert mask manager into history\n");
1176 TRY_EXEC(
"DROP TABLE main.mask",
"[init] can't drop table `mask' from database\n");
1181 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN iop_order_version INTEGER",
1182 "[init] can't add `iop_order_version' column to images table in database\n");
1184 TRY_EXEC(
"UPDATE main.images SET iop_order_version = 0",
1185 "[init] can't update iop_order_version in database\n");
1187 TRY_EXEC(
"UPDATE main.images SET iop_order_version = 1 WHERE "
1188 "EXISTS(SELECT * FROM main.history WHERE main.history.imgid = main.images.id)",
1189 "[init] can't update iop_order_version in database\n");
1191 TRY_EXEC(
"ALTER TABLE main.history ADD COLUMN iop_order REAL",
1192 "[init] can't add `iop_order' column to history table in database\n");
1195 TRY_EXEC(
"CREATE TEMPORARY TABLE iop_order_tmp (iop_order REAL, operation VARCHAR(256))",
1196 "[init] can't create temporary table for updating `main.history'\n");
1206 "INSERT INTO iop_order_tmp (iop_order, operation) VALUES (?1, ?2)",
1224 TRY_EXEC(
"UPDATE main.history SET iop_order = ((("
1225 "SELECT MAX(multi_priority) FROM main.history hist1 WHERE hist1.imgid = main.history.imgid AND hist1.operation = main.history.operation "
1226 ") + 1. - multi_priority) / 1000.) + "
1227 "IFNULL((SELECT iop_order FROM iop_order_tmp WHERE iop_order_tmp.operation = "
1228 "main.history.operation), -999999.) ",
1229 "[init] can't update iop_order in history table\n");
1233 TRY_PREPARE(
sel_stmt,
"SELECT DISTINCT operation FROM main.history WHERE iop_order <= 0 OR iop_order IS NULL",
1234 "[init] can't prepare selecting history iop_order\n");
1239 printf(
"operation %s with no iop_order while upgrading database\n", op_name);
1243 TRY_EXEC(
"DROP TABLE iop_order_tmp",
"[init] can't drop table `iop_order_tmp' from database\n");
1254 else if(version == 18)
1258 TRY_EXEC(
"UPDATE images SET orientation=-2 WHERE orientation=1;",
1259 "[init] can't update images orientation 1 from database\n");
1261 TRY_EXEC(
"UPDATE images SET orientation=1 WHERE orientation=2;",
1262 "[init] can't update images orientation 2 from database\n");
1264 TRY_EXEC(
"UPDATE images SET orientation=-6 WHERE orientation=5;",
1265 "[init] can't update images orientation 5 from database\n");
1267 TRY_EXEC(
"UPDATE images SET orientation=5 WHERE orientation=6;",
1268 "[init] can't update images orientation 6 from database\n");
1270 TRY_EXEC(
"UPDATE images SET orientation=2 WHERE orientation=-2;",
1271 "[init] can't update images orientation -1 from database\n");
1273 TRY_EXEC(
"UPDATE images SET orientation=6 WHERE orientation=-6;",
1274 "[init] can't update images orientation -6 from database\n");
1279 else if(version == 19)
1284 TRY_EXEC(
"CREATE TEMPORARY TABLE m_prio (id INTEGER, operation VARCHAR(256), prio INTEGER)",
1285 "[init] can't create temporary table for updating `history and style_items'\n");
1287 TRY_EXEC(
"CREATE INDEX m_prio_id_index ON m_prio (id)",
1288 "[init] can't create temporary index for updating `history and style_items'\n");
1289 TRY_EXEC(
"CREATE INDEX m_prio_op_index ON m_prio (operation)",
1290 "[init] can't create temporary index for updating `history and style_items'\n");
1292 TRY_EXEC(
"INSERT INTO m_prio SELECT imgid, operation, MAX(multi_priority)"
1293 " FROM main.history GROUP BY imgid, operation",
1294 "[init] can't populate m_prio\n");
1296 TRY_EXEC(
"UPDATE main.history SET multi_priority = "
1297 "(SELECT prio FROM m_prio "
1298 " WHERE main.history.operation = operation AND main.history.imgid = id) - main.history.multi_priority",
1299 "[init] can't update multi_priority for history\n");
1301 TRY_EXEC(
"DROP TABLE m_prio",
"[init] can't drop table `m_prio' from database\n");
1306 else if(version == 20)
1310 TRY_EXEC(
"DROP INDEX IF EXISTS main.used_tags_idx",
"[init] can't drop index `used_tags_idx' from database\n");
1311 TRY_EXEC(
"DROP TABLE used_tags",
"[init] can't delete table used_tags\n");
1317 else if(version == 21)
1322 TRY_EXEC(
"CREATE TABLE module_order (imgid INTEGER PRIMARY KEY, version INTEGER, iop_list VARCHAR)",
1323 "[init] can't create module_order table'\n");
1327 TRY_PREPARE(
mig_stmt,
"SELECT imgid, operation, multi_priority, iop_order, mi.iop_order_version"
1328 " FROM main.history AS hi, main.images AS mi"
1329 " WHERE hi.imgid = mi.id"
1330 " GROUP BY imgid, operation, multi_priority"
1331 " ORDER BY imgid, iop_order",
1332 "[init] can't prepare selecting history for iop_order migration (v21)\n");
1343 char operation[20] = { 0 };
1374 GList *s = iop_order_list;
1412 GList *l = iop_order_list;
1435 "INSERT INTO module_order VALUES (?1, ?2, ?3)", -1,
1448 "INSERT INTO module_order VALUES (?1, ?2, NULL)", -1,
1459 iop_order_list =
NULL;
1478 TRY_EXEC(
"CREATE TABLE h (imgid INTEGER, num INTEGER, module INTEGER, "
1479 "operation VARCHAR(256), op_params BLOB, enabled INTEGER, "
1480 "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))",
1481 "[init] can't create module_order table\n");
1482 TRY_EXEC(
"CREATE INDEX h_imgid_index ON h (imgid)",
1483 "[init] can't create index h_imgid_index\n");
1484 TRY_EXEC(
"INSERT INTO h SELECT imgid, num, module, operation, op_params, enabled, "
1485 "blendop_params, blendop_version, multi_priority, multi_name FROM main.history",
1486 "[init] can't create module_order table\n");
1488 "[init] can't drop table history\n");
1489 TRY_EXEC(
"ALTER TABLE h RENAME TO history",
1490 "[init] can't rename h to history\n");
1491 TRY_EXEC(
"DROP INDEX h_imgid_index",
1492 "[init] can't drop index h_imgid_index\n");
1493 TRY_EXEC(
"CREATE INDEX main.history_imgid_index ON history (imgid)",
1494 "[init] can't create index images_imgid_index\n");
1498 TRY_EXEC(
"CREATE TABLE i (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, film_id INTEGER, "
1499 "width INTEGER, height INTEGER, filename VARCHAR, maker VARCHAR, model VARCHAR, "
1500 "lens VARCHAR, exposure REAL, aperture REAL, iso REAL, focal_length REAL, "
1501 "focus_distance REAL, datetime_taken CHAR(20), flags INTEGER, "
1502 "output_width INTEGER, output_height INTEGER, crop REAL, "
1503 "raw_parameters INTEGER, raw_denoise_threshold REAL, "
1504 "raw_auto_bright_threshold REAL, raw_black INTEGER, raw_maximum INTEGER, "
1505 "caption VARCHAR, description VARCHAR, license VARCHAR, sha1sum CHAR(40), "
1506 "orientation INTEGER, histogram BLOB, lightmap BLOB, longitude REAL, "
1507 "latitude REAL, altitude REAL, color_matrix BLOB, colorspace INTEGER, version INTEGER, "
1508 "max_version INTEGER, write_timestamp INTEGER, history_end INTEGER, position INTEGER, aspect_ratio REAL)",
1509 "[init] can't create table i\n");
1510 TRY_EXEC(
"INSERT INTO i SELECT id, group_id, film_id, width, height, filename, maker, model,"
1511 " lens, exposure, aperture, iso, focal_length, focus_distance, datetime_taken, flags,"
1512 " output_width, output_height, crop, raw_parameters, raw_denoise_threshold,"
1513 " raw_auto_bright_threshold, raw_black, raw_maximum, caption, description, license, sha1sum,"
1514 " orientation, histogram, lightmap, longitude, latitude, altitude, color_matrix, colorspace, version,"
1515 " max_version, write_timestamp, history_end, position, aspect_ratio "
1517 "[init] can't populate table h\n");
1519 "[init] can't drop table images\n");
1520 TRY_EXEC(
"ALTER TABLE i RENAME TO images",
1521 "[init] can't rename i to images\n");
1527 else if(version == 22)
1531 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.images_group_id_index ON images (group_id)",
1532 "[init] can't create group_id index on image\n");
1533 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.images_film_id_index ON images (film_id)",
1534 "[init] can't create film_id index on image\n");
1535 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.images_filename_index ON images (filename)",
1536 "[init] can't create filename index on image\n");
1537 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.image_position_index ON images (position)",
1538 "[init] can't create position index on image\n");
1540 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.film_rolls_folder_index ON film_rolls (folder)",
1541 "[init] can't create folder index on film_rolls\n");
1547 else if(version == 23)
1551 TRY_EXEC(
"CREATE TABLE main.history_hash (imgid INTEGER PRIMARY KEY, "
1552 "basic_hash BLOB, auto_hash BLOB, current_hash BLOB)",
1553 "[init] can't create table history_hash\n");
1562 else if(version == 24)
1565 TRY_EXEC(
"ALTER TABLE main.history_hash ADD COLUMN mipmap_hash BLOB",
1566 "[init] can't add `mipmap_hash' column to history_hash table in database\n");
1571 else if(version == 25)
1574 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN exposure_bias REAL",
1575 "[init] can't add `exposure_bias' column to images table in database\n");
1580 else if(version == 26)
1584 TRY_EXEC(
"CREATE TABLE main.new_film_rolls "
1585 "(id INTEGER PRIMARY KEY, "
1586 "access_timestamp INTEGER, "
1587 "folder VARCHAR(1024) NOT NULL)",
1588 "[init] can't create new_film_rolls table\n");
1590 TRY_EXEC(
"INSERT INTO main.new_film_rolls"
1591 "(id, access_timestamp, folder) "
1593 "strftime('%s', replace(substr(datetime_accessed, 1, 10), ':', '-') || substr(datetime_accessed, 11), 'utc'), "
1596 "WHERE folder IS NOT NULL",
1597 "[init] can't populate new_film_rolls table from film_rolls\n");
1600 "[init] can't delete table film_rolls\n");
1602 TRY_EXEC(
"ALTER TABLE main.new_film_rolls RENAME TO film_rolls",
1603 "[init] can't rename table new_film_rolls to film_rolls\n");
1605 TRY_EXEC(
"CREATE INDEX main.film_rolls_folder_index ON film_rolls (folder)",
1606 "[init] can't create index `film_rolls_folder_index' on table `film_rolls'\n");
1611 else if(version == 27)
1615 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN import_timestamp INTEGER DEFAULT -1",
1616 "[init] can't add `import_timestamp' column to images table in database\n");
1617 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN change_timestamp INTEGER DEFAULT -1",
1618 "[init] can't add `change_timestamp' column to images table in database\n");
1619 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN export_timestamp INTEGER DEFAULT -1",
1620 "[init] can't add `export_timestamp' column to images table in database\n");
1621 TRY_EXEC(
"ALTER TABLE main.images ADD COLUMN print_timestamp INTEGER DEFAULT -1",
1622 "[init] can't add `print_timestamp' column to images table in database\n");
1624 TRY_EXEC(
"UPDATE main.images SET import_timestamp = (SELECT access_timestamp "
1625 "FROM main.film_rolls WHERE film_rolls.id = images.film_id)",
1626 "[init] can't populate import_timestamp column from film_rolls.access_timestamp.\n");
1628 TRY_EXEC(
"UPDATE main.images SET change_timestamp = images.write_timestamp "
1629 "WHERE images.write_timestamp IS NOT NULL "
1630 "AND images.id = (SELECT imgid FROM tagged_images "
1631 "JOIN data.tags ON tags.id = tagged_images.tagid "
1632 "WHERE data.tags.name = 'darktable|changed')",
1633 "[init] can't populate change_timestamp column from images.write_timestamp.\n");
1638 else if(version == 28)
1643 TRY_EXEC(
"UPDATE main.images SET flags = (flags & ~8)",
1644 "[init] can't clear rejected flags");
1647 TRY_EXEC(
"UPDATE main.images SET flags = (flags | 8) & ~7 WHERE (flags & 7) = 6",
1648 "[init] can't set rejected flags");
1653 else if(version == 29)
1658 TRY_EXEC(
"ALTER TABLE main.tagged_images ADD COLUMN position INTEGER",
1659 "[init] can't add `position' column to tagged_images table in database\n");
1661 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.tagged_images_imgid_index ON tagged_images (imgid)",
1662 "[init] can't create image index on tagged_images\n");
1663 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.tagged_images_position_index ON tagged_images (position)",
1664 "[init] can't create position index on tagged_images\n");
1665 TRY_EXEC(
"UPDATE main.tagged_images SET position = (tagid + imgid) << 32",
1666 "[init] can't populate position on tagged_images\n");
1670 TRY_EXEC(
"CREATE TABLE main.i (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, film_id INTEGER, "
1671 "width INTEGER, height INTEGER, filename VARCHAR, maker VARCHAR, model VARCHAR, "
1672 "lens VARCHAR, exposure REAL, aperture REAL, iso REAL, focal_length REAL, "
1673 "focus_distance REAL, datetime_taken CHAR(20), flags INTEGER, "
1674 "output_width INTEGER, output_height INTEGER, crop REAL, "
1675 "raw_parameters INTEGER, raw_denoise_threshold REAL, "
1676 "raw_auto_bright_threshold REAL, raw_black INTEGER, raw_maximum INTEGER, "
1677 "license VARCHAR, sha1sum CHAR(40), "
1678 "orientation INTEGER, histogram BLOB, lightmap BLOB, longitude REAL, "
1679 "latitude REAL, altitude REAL, color_matrix BLOB, colorspace INTEGER, version INTEGER, "
1680 "max_version INTEGER, write_timestamp INTEGER, history_end INTEGER, position INTEGER, "
1681 "aspect_ratio REAL, exposure_bias REAL, "
1682 "import_timestamp INTEGER DEFAULT -1, change_timestamp INTEGER DEFAULT -1, "
1683 "export_timestamp INTEGER DEFAULT -1, print_timestamp INTEGER DEFAULT -1)",
1684 "[init] can't create table i\n");
1686 TRY_EXEC(
"INSERT INTO main.i SELECT id, group_id, film_id, width, height, filename, maker, model,"
1687 " lens, exposure, aperture, iso, focal_length, focus_distance, datetime_taken, flags,"
1688 " output_width, output_height, crop, raw_parameters, raw_denoise_threshold,"
1689 " raw_auto_bright_threshold, raw_black, raw_maximum, license, sha1sum,"
1690 " orientation, histogram, lightmap, longitude, latitude, altitude, color_matrix, colorspace, version,"
1691 " max_version, write_timestamp, history_end, position, aspect_ratio, exposure_bias,"
1692 " import_timestamp, change_timestamp, export_timestamp, print_timestamp "
1694 "[init] can't populate table i\n");
1696 "[init] can't drop table images\n");
1697 TRY_EXEC(
"ALTER TABLE main.i RENAME TO images",
1698 "[init] can't rename i to images\n");
1700 TRY_EXEC(
"CREATE INDEX main.images_group_id_index ON images (group_id)",
1701 "[init] can't create group_id index on images table\n");
1702 TRY_EXEC(
"CREATE INDEX main.images_film_id_index ON images (film_id)",
1703 "[init] can't create film_id index on images table\n");
1704 TRY_EXEC(
"CREATE INDEX main.images_filename_index ON images (filename)",
1705 "[init] can't create filename index on images table\n");
1706 TRY_EXEC(
"CREATE INDEX main.image_position_index ON images (position)",
1707 "[init] can't create position index on images table\n");
1712 else if(version == 30)
1717 TRY_EXEC(
"DROP INDEX IF EXISTS `history_imgid_index`",
1718 "[init] can't drop history_imgid_index\n");
1719 TRY_EXEC(
"CREATE INDEX `history_imgid_index` ON `history` ( `imgid`, `operation` )",
1720 "[init] can't recreate history_imgid_index\n");
1722 TRY_EXEC(
"DROP INDEX IF EXISTS `images_filename_index`",
1723 "[init] can't drop images_filename_index\n");
1724 TRY_EXEC(
"CREATE INDEX `images_filename_index` ON `images` ( `filename`, `version` )",
1725 "[init] can't recreate images_filename_index\n");
1727 TRY_EXEC(
"DROP INDEX IF EXISTS `images_film_id_index`",
1728 "[init] can't drop images_film_id_index\n");
1729 TRY_EXEC(
"CREATE INDEX `images_film_id_index` ON `images` ( `film_id`, `filename` )",
1730 "[init] can't recreate images_film_id_index\n");
1732 TRY_EXEC(
"DROP INDEX IF EXISTS `images_group_id_index`",
1733 "[init] can't drop images_group_id_index\n");
1734 TRY_EXEC(
"CREATE INDEX `images_group_id_index` ON `images` ( `group_id`, `id` )",
1735 "[init] can't recreate images_group_id_index\n");
1737 TRY_EXEC(
"DROP INDEX IF EXISTS `masks_history_imgid_index`",
1738 "[init] can't drop masks_history_imgid_index\n");
1739 TRY_EXEC(
"CREATE INDEX `masks_history_imgid_index` ON `masks_history` ( `imgid`, `num` )",
1740 "[init] can't recreate masks_history_imgid_index\n");
1743 TRY_EXEC(
"CREATE INDEX `images_latlong_index` ON `images` ( `latitude` DESC, `longitude` DESC )",
1744 "[init] can't create images_latlong_index\n");
1749 else if(version == 31)
1754 TRY_EXEC(
"DELETE FROM main.meta_data WHERE rowid NOT IN (SELECT MIN(rowid) "
1755 "FROM main.meta_data GROUP BY id, key)",
1756 "[init] can't remove duplicates from meta_data\n");
1759 TRY_EXEC(
"DROP INDEX IF EXISTS metadata_index",
1760 "[init] can't drop metadata_index\n");
1761 TRY_EXEC(
"CREATE UNIQUE INDEX main.metadata_index ON meta_data (id, key)",
1762 "[init] can't create metadata_index\n");
1767 else if(version == 32)
1777 TRY_EXEC(
"ALTER TABLE `images` RENAME TO `images_old`",
1778 "[init] can't rename images\n");
1780 TRY_EXEC(
"CREATE TABLE `images` (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, film_id INTEGER, "
1781 "width INTEGER, height INTEGER, filename VARCHAR, maker VARCHAR, model VARCHAR, lens VARCHAR, "
1782 "exposure REAL, aperture REAL, iso REAL, focal_length REAL, focus_distance REAL, datetime_taken CHAR(20), "
1783 "flags INTEGER, output_width INTEGER, output_height INTEGER, crop REAL, "
1784 "raw_parameters INTEGER, raw_denoise_threshold REAL, raw_auto_bright_threshold REAL, "
1785 "raw_black INTEGER, raw_maximum INTEGER, license VARCHAR, sha1sum CHAR(40), "
1786 "orientation INTEGER, histogram BLOB, lightmap BLOB, longitude REAL, latitude REAL, altitude REAL, "
1787 "color_matrix BLOB, colorspace INTEGER, version INTEGER, max_version INTEGER, write_timestamp INTEGER, "
1788 "history_end INTEGER, position INTEGER, aspect_ratio REAL, exposure_bias REAL, "
1789 "import_timestamp INTEGER DEFAULT -1, change_timestamp INTEGER DEFAULT -1, export_timestamp INTEGER DEFAULT -1, print_timestamp INTEGER DEFAULT -1, "
1790 "FOREIGN KEY(film_id) REFERENCES film_rolls(id) ON DELETE CASCADE ON UPDATE CASCADE, "
1791 "FOREIGN KEY(group_id) REFERENCES images(id) ON DELETE RESTRICT ON UPDATE CASCADE)",
1792 "[init] can't create new images table\n");
1795 TRY_EXEC(
"DELETE FROM `images_old` WHERE film_id NOT IN (SELECT id FROM `film_rolls`)",
1796 "[init] can't delete images with invalid film id\n");
1798 TRY_EXEC(
"UPDATE `images_old` SET group_id=id WHERE group_id NOT IN (SELECT id from `images_old`)",
1799 "[init] can't fix invalid group ids\n");
1801 TRY_EXEC(
"INSERT INTO `images` SELECT * FROM `images_old`",
1802 "[init] can't copy back from images_old\n");
1805 TRY_EXEC(
"DROP INDEX IF EXISTS `image_position_index`",
1806 "[init] can't drop image_position_index\n");
1807 TRY_EXEC(
"CREATE INDEX `image_position_index` ON `images` (position)",
1808 "[init] can't add image_position_index\n");
1811 TRY_EXEC(
"DROP INDEX IF EXISTS `images_filename_index`",
1812 "[init] can't drop images_filename_index\n");
1813 TRY_EXEC(
"CREATE INDEX `images_filename_index` ON `images` ( `filename`, `version` )",
1814 "[init] can't recreate images_filename_index\n");
1816 TRY_EXEC(
"DROP INDEX IF EXISTS `images_film_id_index`",
1817 "[init] can't drop images_film_id_index\n");
1818 TRY_EXEC(
"CREATE INDEX `images_film_id_index` ON `images` ( `film_id`, `filename` )",
1819 "[init] can't recreate images_film_id_index\n");
1821 TRY_EXEC(
"DROP INDEX IF EXISTS `images_group_id_index`",
1822 "[init] can't drop images_group_id_index\n");
1823 TRY_EXEC(
"CREATE INDEX `images_group_id_index` ON `images` ( `group_id`, `id` )",
1824 "[init] can't recreate images_group_id_index\n");
1826 TRY_EXEC(
"DROP INDEX IF EXISTS `images_latlong_index`",
1827 "[init] can't drop images_latlong_index\n");
1828 TRY_EXEC(
"CREATE INDEX `images_latlong_index` ON `images` ( latitude DESC, longitude DESC )",
1829 "[init] can't add images_latlong_index\n");
1831 TRY_EXEC(
"DROP TABLE `images_old`",
1832 "[init] can't drop table images_old\n");
1835 TRY_EXEC(
"ALTER TABLE `history` RENAME TO `history_old`",
1836 "[init] can't rename history\n");
1838 TRY_EXEC(
"CREATE TABLE `history` (imgid INTEGER, num INTEGER, module INTEGER, "
1839 "operation VARCHAR(256), op_params BLOB, enabled INTEGER, blendop_params BLOB, blendop_version INTEGER, "
1840 "multi_priority INTEGER, multi_name VARCHAR(256), "
1841 "FOREIGN KEY(imgid) REFERENCES images(id) ON DELETE CASCADE ON UPDATE CASCADE)",
1842 "[init] can't create new history table\n");
1844 TRY_EXEC(
"DELETE FROM `history_old` WHERE imgid NOT IN (SELECT id FROM `images`)",
1845 "[init] can't delete orphaned history elements\n");
1847 TRY_EXEC(
"INSERT INTO history SELECT * FROM history_old",
1848 "[init] can't copy back from history_old\n");
1850 TRY_EXEC(
"DROP INDEX IF EXISTS `history_imgid_index`",
1851 "[init] can't drop history_imgid_index\n");
1852 TRY_EXEC(
"CREATE INDEX `history_imgid_op_index` ON `history` ( `imgid`, `operation` )",
1853 "[init] can't recreate history_imgid_index\n");
1854 TRY_EXEC(
"CREATE INDEX `history_imgid_num_index` ON `history` ( `imgid`, `num` DESC )",
1855 "[init] can't recreate history_imgid_index\n");
1857 TRY_EXEC(
"DROP TABLE `history_old`",
1858 "[init] can't drop table history_old\n");
1861 TRY_EXEC(
"ALTER TABLE `history_hash` RENAME TO `history_hash_old`",
1862 "[init] can't rename history_hash\n");
1864 TRY_EXEC(
"CREATE TABLE `history_hash` (imgid INTEGER PRIMARY KEY, basic_hash BLOB, auto_hash BLOB, current_hash BLOB, "
1865 "mipmap_hash BLOB, FOREIGN KEY(imgid) REFERENCES images(id) ON DELETE CASCADE ON UPDATE CASCADE)",
1866 "[init] can't create new history_hash table\n");
1868 TRY_EXEC(
"DELETE FROM `history_hash_old` WHERE imgid NOT IN (SELECT id FROM `images`)",
1869 "[init] can't delete orphaned history_hash elements\n");
1871 TRY_EXEC(
"INSERT INTO `history_hash` SELECT * FROM `history_hash_old`",
1872 "[init] can't copy back from history_hash_old\n");
1874 TRY_EXEC(
"DROP TABLE `history_hash_old`",
1875 "[init] can't drop table history_hash_old\n");
1878 TRY_EXEC(
"ALTER TABLE `tagged_images` RENAME TO `tagged_images_old`",
1879 "[init] can't rename tagged_images\n");
1881 TRY_EXEC(
"CREATE TABLE `tagged_images` (imgid integer, tagid integer, position INTEGER, "
1882 "primary key(imgid, tagid), FOREIGN KEY(imgid) REFERENCES images(id) ON DELETE CASCADE ON UPDATE CASCADE)",
1883 "[init] can't create new tagged_images table\n");
1885 TRY_EXEC(
"DELETE FROM `tagged_images_old` WHERE imgid NOT IN (SELECT id FROM `images`)",
1886 "[init] can't delete orphaned tagged_images elements\n");
1888 TRY_EXEC(
"INSERT INTO `tagged_images` SELECT * FROM `tagged_images_old`",
1889 "[init] can't copy back from tagged_images_old\n");
1892 TRY_EXEC(
"DROP INDEX IF EXISTS tagged_images_imgid_index",
1893 "[init] can't drop tagged_images_imgid_index\n");
1894 TRY_EXEC(
"DROP INDEX IF EXISTS tagged_images_position_index",
1895 "[init] can't drop tagged_images_position_index\n");
1896 TRY_EXEC(
"CREATE INDEX tagged_images_position_index ON tagged_images (position)",
1897 "[init] can't add index tagged_images_position_index\n");
1898 TRY_EXEC(
"DROP INDEX IF EXISTS tagged_images_tagid_index",
1899 "[init] can't drop tagged_images_tagid_index\n");
1900 TRY_EXEC(
"CREATE INDEX tagged_images_tagid_index ON tagged_images (tagid)",
1901 "[init] can't add index tagged_images_tagid_index\n");
1903 TRY_EXEC(
"DROP TABLE `tagged_images_old`",
1904 "[init] can't drop table tagged_images_old\n");
1907 TRY_EXEC(
"ALTER TABLE `masks_history` RENAME TO `masks_history_old`",
1908 "[init] can't rename masks_history\n");
1910 TRY_EXEC(
"CREATE TABLE masks_history (imgid INTEGER, num INTEGER, formid INTEGER, form INTEGER, "
1911 "name VARCHAR(256), version INTEGER, points BLOB, points_count INTEGER, source BLOB, "
1912 "FOREIGN KEY(imgid) REFERENCES images(id) ON DELETE CASCADE ON UPDATE CASCADE)",
1913 "[init] can't create new masks_history table\n");
1915 TRY_EXEC(
"DELETE FROM `masks_history_old` WHERE imgid NOT IN (SELECT id FROM `images`)",
1916 "[init] can't delete orphaned masks_history elements\n");
1918 TRY_EXEC(
"INSERT INTO `masks_history` SELECT * FROM `masks_history_old`",
1919 "[init] can't copy back from masks_history\n");
1921 TRY_EXEC(
"DROP INDEX IF EXISTS `masks_history_imgid_index`",
1922 "[init] can't drop masks_history_imgid_index\n");
1923 TRY_EXEC(
"CREATE INDEX `masks_history_imgid_index` ON `masks_history` ( imgid, num )",
1924 "[init] can't recreate masks_history_imgid_index\n");
1926 TRY_EXEC(
"DROP TABLE masks_history_old",
1927 "[init] can't drop table masks_history_old\n");
1930 TRY_EXEC(
"ALTER TABLE `color_labels` RENAME TO `color_labels_old`",
1931 "[init] can't rename color_labels\n");
1932 TRY_EXEC(
"CREATE TABLE `color_labels` (imgid INTEGER, color INTEGER, "
1933 "FOREIGN KEY(imgid) REFERENCES images(id) ON DELETE CASCADE ON UPDATE CASCADE)",
1934 "[init] can't create new color_labels table\n");
1936 TRY_EXEC(
"DELETE FROM `color_labels_old` WHERE imgid NOT IN (SELECT id FROM `images`)",
1937 "[init] can't delete orphaned color_labels elements\n");
1939 TRY_EXEC(
"INSERT INTO `color_labels` SELECT * FROM `color_labels_old`",
1940 "[init] can't copy back from color_labels\n");
1942 TRY_EXEC(
"DROP TABLE color_labels_old",
1943 "[init] can't drop table color_labels_old\n");
1945 TRY_EXEC(
"CREATE UNIQUE INDEX `color_labels_idx` ON `color_labels` (imgid, color)",
1946 "[init] can't recreate color_labels_idx\n");
1949 TRY_EXEC(
"ALTER TABLE `meta_data` RENAME TO `meta_data_old`",
1950 "[init] can't rename meta_data\n");
1951 TRY_EXEC(
"CREATE TABLE `meta_data` (id integer, key integer, value varchar, "
1952 "FOREIGN KEY(id) REFERENCES images(id) ON DELETE CASCADE ON UPDATE CASCADE)",
1953 "[init] can't create new meta_data table\n");
1955 TRY_EXEC(
"DELETE FROM `meta_data_old` WHERE id NOT IN (SELECT id FROM `images`)",
1956 "[init] can't delete orphaned meta_data elements\n");
1958 TRY_EXEC(
"INSERT INTO `meta_data` SELECT * FROM `meta_data_old`",
1959 "[init] can't copy back from meta_data\n");
1961 TRY_EXEC(
"DROP TABLE meta_data_old",
1962 "[init] can't drop table meta_data_old\n");
1964 TRY_EXEC(
"CREATE UNIQUE INDEX `metadata_index` ON `meta_data` (id, key, value)",
1965 "[init] can't recreate metadata_index\n");
1968 TRY_EXEC(
"ALTER TABLE `selected_images` RENAME TO `selected_images_old`",
1969 "[init] can't rename selected_images\n");
1970 TRY_EXEC(
"CREATE TABLE `selected_images` (imgid INTEGER PRIMARY KEY, "
1971 "FOREIGN KEY(imgid) REFERENCES images(id) ON DELETE CASCADE ON UPDATE CASCADE)",
1972 "[init] can't create new selected_images table\n");
1974 TRY_EXEC(
"DELETE FROM `selected_images_old` WHERE imgid NOT IN (SELECT id FROM `images`)",
1975 "[init] can't delete orphaned selected_images elements\n");
1977 TRY_EXEC(
"INSERT INTO `selected_images` SELECT * FROM `selected_images_old`",
1978 "[init] can't copy back selected_images meta_data\n");
1980 TRY_EXEC(
"DROP TABLE selected_images_old",
1981 "[init] can't drop table selected_images_old\n");
1984 TRY_EXEC(
"ALTER TABLE `module_order` RENAME TO `module_order_old`",
1985 "[init] can't rename module_order\n");
1986 TRY_EXEC(
"CREATE TABLE `module_order` (imgid INTEGER PRIMARY KEY, version INTEGER, iop_list VARCHAR, "
1987 "FOREIGN KEY(imgid) REFERENCES images(id) ON DELETE CASCADE ON UPDATE CASCADE)",
1988 "[init] can't create new module_order table\n");
1990 TRY_EXEC(
"DELETE FROM `module_order_old` WHERE imgid NOT IN (SELECT id FROM `images`)",
1991 "[init] can't delete orphaned module_order elements\n");
1993 TRY_EXEC(
"INSERT INTO `module_order` SELECT * FROM `module_order_old`",
1994 "[init] can't copy back module_order meta_data\n");
1996 TRY_EXEC(
"DROP TABLE module_order_old",
1997 "[init] can't drop table module_order_old\n");
2002 else if(version == 33)
2006 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.images_datetime_taken_nc ON images (datetime_taken COLLATE NOCASE)",
2007 "[init] can't create images_datetime_taken\n");
2008 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS main.metadata_index_key ON meta_data (key)",
2009 "[init] can't create metadata_index_key\n");
2014 else if(version == 34)
2019 TRY_EXEC(
"CREATE TABLE main.images_new (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, film_id INTEGER, "
2020 "width INTEGER, height INTEGER, filename VARCHAR, maker VARCHAR, model VARCHAR, "
2021 "lens VARCHAR, exposure REAL, aperture REAL, iso REAL, focal_length REAL, "
2022 "focus_distance REAL, datetime_taken INTEGER, flags INTEGER, "
2023 "output_width INTEGER, output_height INTEGER, crop REAL, "
2024 "raw_parameters INTEGER, raw_denoise_threshold REAL, "
2025 "raw_auto_bright_threshold REAL, raw_black INTEGER, raw_maximum INTEGER, "
2026 "license VARCHAR, sha1sum CHAR(40), "
2027 "orientation INTEGER, histogram BLOB, lightmap BLOB, longitude REAL, "
2028 "latitude REAL, altitude REAL, color_matrix BLOB, colorspace INTEGER, version INTEGER, "
2029 "max_version INTEGER, write_timestamp INTEGER, history_end INTEGER, position INTEGER, "
2030 "aspect_ratio REAL, exposure_bias REAL, "
2031 "import_timestamp INTEGER, change_timestamp INTEGER, "
2032 "export_timestamp INTEGER, print_timestamp INTEGER, "
2033 "FOREIGN KEY(film_id) REFERENCES film_rolls(id) ON DELETE CASCADE ON UPDATE CASCADE, "
2034 "FOREIGN KEY(group_id) REFERENCES images(id) ON DELETE RESTRICT ON UPDATE CASCADE)",
2035 "[init] can't create new images table\n");
2037 TRY_EXEC(
"INSERT INTO `images_new` SELECT "
2038 "id, group_id, film_id, width, height, filename, maker, model, "
2039 "lens, exposure, aperture, iso, focal_length, focus_distance, NULL AS datetime_taken, flags, "
2040 "output_width, output_height, crop, raw_parameters, raw_denoise_threshold, raw_auto_bright_threshold, raw_black, raw_maximum, "
2041 "license, sha1sum, orientation, histogram, lightmap, longitude, latitude, altitude, color_matrix, colorspace, version, "
2042 "max_version, write_timestamp, history_end, position, aspect_ratio, exposure_bias, "
2043 "NULL AS import_timestamp, NULL AS change_timestamp, NULL AS export_timestamp, NULL AS print_timestamp "
2045 "[init] can't copy back from images\n");
2048 " CASE WHEN datetime_taken = '' THEN NULL ELSE datetime_taken END,"
2049 " CASE WHEN import_timestamp = -1 THEN NULL ELSE import_timestamp END,"
2050 " CASE WHEN change_timestamp = -1 THEN NULL ELSE change_timestamp END,"
2051 " CASE WHEN export_timestamp = -1 THEN NULL ELSE export_timestamp END,"
2052 " CASE WHEN print_timestamp = -1 THEN NULL ELSE print_timestamp END "
2054 "[init] can't get datetime from images\n");
2059 "UPDATE `images_new` SET"
2060 " (datetime_taken, import_timestamp,"
2061 " change_timestamp, export_timestamp, print_timestamp) = "
2062 " (?2, ?3, ?4, ?5, ?6) WHERE id = ?1",
2074 for(
int i = 0;
i < 4;
i++)
2091 TRY_EXEC(
"DROP TABLE `images`",
"[init] can't drop images table\n");
2093 TRY_EXEC(
"ALTER TABLE `images_new` RENAME TO `images`",
"[init] can't rename images_new table to images");
2096 TRY_EXEC(
"CREATE INDEX `image_position_index` ON `images` (position)",
2097 "[init] can't add image_position_index\n");
2098 TRY_EXEC(
"CREATE INDEX `images_filename_index` ON `images` ( `filename`, `version` )",
2099 "[init] can't recreate images_filename_index\n");
2100 TRY_EXEC(
"CREATE INDEX `images_film_id_index` ON `images` ( `film_id`, `filename` )",
2101 "[init] can't recreate images_film_id_index\n");
2102 TRY_EXEC(
"CREATE INDEX `images_group_id_index` ON `images` ( `group_id`, `id` )",
2103 "[init] can't recreate images_group_id_index\n");
2104 TRY_EXEC(
"CREATE INDEX `images_latlong_index` ON `images` ( latitude DESC, longitude DESC )",
2105 "[init] can't add images_latlong_index\n");
2106 TRY_EXEC(
"CREATE INDEX `images_datetime_taken` ON images (datetime_taken)",
2107 "[init] can't create images_datetime_taken\n");
2113 else if(version == 35)
2115 TRY_EXEC(
"CREATE TABLE main.images_new (id INTEGER, filename VARCHAR, flags INTEGER)",
2116 "[init] can't create new images table\n");
2119 "SELECT id, filename, flags"
2121 " WHERE (flags & %d == 0)",
2126 "[init] can't prepare selecting images flags\n");
2132 "UPDATE `images` SET"
2134 " (?2) WHERE id = ?1",
2148 TRY_EXEC(
"DROP TABLE `images_new`",
"[init] can't drop temp images table\n");
2171 else if(version == 0)
2178 else if(version == 1)
2191 TRY_EXEC(
"CREATE TEMPORARY TABLE iop_order_tmp (iop_order REAL, operation VARCHAR(256))",
2192 "[init] can't create temporary table for updating `data.style_items'\n");
2202 "INSERT INTO iop_order_tmp (iop_order, operation) VALUES (?1, ?2)",
2214 TRY_EXEC(
"UPDATE data.style_items SET iop_order = ((("
2215 "SELECT MAX(multi_priority) FROM data.style_items style1 WHERE style1.styleid = data.style_items.styleid AND style1.operation = data.style_items.operation "
2216 ") + 1. - multi_priority) / 1000.) + "
2217 "IFNULL((SELECT iop_order FROM iop_order_tmp WHERE iop_order_tmp.operation = "
2218 "data.style_items.operation), -999999.) ",
2219 "[init] can't update iop_order in style_items table\n");
2221 TRY_PREPARE(
sel_stmt,
"SELECT DISTINCT operation FROM data.style_items WHERE iop_order <= 0 OR iop_order IS NULL",
2222 "[init] can't prepare selecting style_items iop_order\n");
2227 printf(
"operation %s with no iop_order while upgrading style_items in database\n", op_name);
2231 TRY_EXEC(
"DROP TABLE iop_order_tmp",
"[init] can't drop table `iop_order_tmp' from database\n");
2235 else if(version == 2)
2243 TRY_EXEC(
"ALTER TABLE data.tags RENAME TO tmp_tags",
"[init] can't rename table tags\n");
2245 TRY_EXEC(
"CREATE TABLE data.tags (id INTEGER PRIMARY KEY, name VARCHAR, "
2246 "synonyms VARCHAR, flags INTEGER)",
2247 "[init] can't create new tags table\n");
2249 TRY_EXEC(
"INSERT INTO data.tags (id, name, synonyms, flags) SELECT id, name, description, flags "
2251 "[init] can't populate tags table from tmp_tags\n");
2253 TRY_EXEC(
"DROP TABLE tmp_tags",
"[init] can't delete table tmp_tags\n");
2255 TRY_EXEC(
"CREATE UNIQUE INDEX data.tags_name_idx ON tags (name)",
2256 "[init] can't create tags_name_idx on tags table\n");
2262 else if(version == 3)
2267 TRY_EXEC(
"CREATE TEMPORARY TABLE m_prio (id INTEGER, operation VARCHAR(256), prio INTEGER)",
2268 "[init] can't create temporary table for updating `history and style_items'\n");
2270 TRY_EXEC(
"INSERT INTO m_prio SELECT styleid, operation, MAX(multi_priority)"
2271 " FROM data.style_items GROUP BY styleid, operation",
2272 "[init] can't populate m_prio\n");
2275 TRY_EXEC(
"UPDATE data.style_items SET multi_priority = "
2276 "(SELECT prio FROM m_prio "
2277 " WHERE data.style_items.operation = operation AND data.style_items.styleid = id)"
2278 " - data.style_items.multi_priority",
2279 "[init] can't update multi_priority for style_items\n");
2281 TRY_EXEC(
"DROP TABLE m_prio",
"[init] can't drop table `m_prio' from database\n");
2287 else if(version == 4)
2292 TRY_EXEC(
"ALTER TABLE data.style_items RENAME TO s",
2293 "[init] can't rename style_items to s\n");
2294 TRY_EXEC(
"CREATE TABLE data.style_items (styleid INTEGER, num INTEGER, module INTEGER, "
2295 "operation VARCHAR(256), op_params BLOB, enabled INTEGER, "
2296 "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))",
2297 "[init] can't create style_items table'\n");
2298 TRY_EXEC(
"INSERT INTO data.style_items SELECT styleid, num, module, operation, op_params, enabled, "
2299 " blendop_params, blendop_version, multi_priority, multi_name "
2301 "[init] can't populate style_items table'\n");
2303 "[init] can't drop table s'\n");
2309 else if(version == 5)
2314 TRY_EXEC(
"ALTER TABLE data.styles RENAME TO s",
2315 "[init] can't rename styles to s\n");
2316 TRY_EXEC(
"CREATE TABLE data.styles (id INTEGER PRIMARY KEY, name VARCHAR, description VARCHAR, iop_list VARCHAR)",
2317 "[init] can't create styles table\n");
2318 TRY_EXEC(
"INSERT INTO data.styles SELECT id, name, description, NULL FROM s",
2319 "[init] can't populate styles table\n");
2321 "[init] can't drop table s\n");
2323 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS data.styles_name_index ON styles (name)",
2324 "[init] can't create styles_nmae_index\n");
2328 TRY_EXEC(
"CREATE INDEX IF NOT EXISTS data.style_items_styleid_index ON style_items (styleid)",
2329 "[init] can't create style_items_styleid_index\n");
2335 else if(version == 6)
2338 TRY_EXEC(
"CREATE TABLE data.locations "
2339 "(tagid INTEGER PRIMARY KEY, type INTEGER, longitude REAL, latitude REAL, "
2340 "delta1 REAL, delta2 REAL, FOREIGN KEY(tagid) REFERENCES tags(id))",
2341 "[init] can't create new locations table\n");
2345 else if(version == 7)
2348 TRY_EXEC(
"ALTER TABLE data.locations ADD COLUMN ratio FLOAT DEFAULT 1",
2349 "[init] can't add column `ratio' column to locations table\n");
2353 else if(version == 8)
2356 TRY_EXEC(
"ALTER TABLE data.locations ADD COLUMN polygons BLOB",
2357 "[init] can't add column `polygons' column to locations table\n");
2421 db->
handle,
"INSERT OR REPLACE INTO main.db_info (key, value) VALUES ('version', ?1)", -1, &
stmt,
NULL);
2429 "CREATE TABLE main.film_rolls "
2430 "(id INTEGER PRIMARY KEY, access_timestamp INTEGER, "
2434 "folder VARCHAR(1024) NOT NULL)",
2440 "CREATE TABLE main.images (id INTEGER PRIMARY KEY AUTOINCREMENT, group_id INTEGER, film_id INTEGER, "
2441 "width INTEGER, height INTEGER, filename VARCHAR, maker VARCHAR, model VARCHAR, "
2442 "lens VARCHAR, exposure REAL, aperture REAL, iso REAL, focal_length REAL, "
2443 "focus_distance REAL, datetime_taken INTEGER, flags INTEGER, "
2444 "output_width INTEGER, output_height INTEGER, crop REAL, "
2445 "raw_parameters INTEGER, raw_denoise_threshold REAL, "
2446 "raw_auto_bright_threshold REAL, raw_black INTEGER, raw_maximum INTEGER, "
2447 "license VARCHAR, sha1sum CHAR(40), "
2448 "orientation INTEGER, histogram BLOB, lightmap BLOB, longitude REAL, "
2449 "latitude REAL, altitude REAL, color_matrix BLOB, colorspace INTEGER, version INTEGER, "
2450 "max_version INTEGER, write_timestamp INTEGER, history_end INTEGER, position INTEGER, "
2451 "aspect_ratio REAL, exposure_bias REAL, "
2452 "import_timestamp INTEGER DEFAULT -1, change_timestamp INTEGER DEFAULT -1, "
2453 "export_timestamp INTEGER DEFAULT -1, print_timestamp INTEGER DEFAULT -1, "
2454 "FOREIGN KEY(film_id) REFERENCES film_rolls(id) ON DELETE CASCADE ON UPDATE CASCADE, "
2455 "FOREIGN KEY(group_id) REFERENCES images(id) ON DELETE RESTRICT ON UPDATE CASCADE)",
2468 "CREATE TABLE main.history (imgid INTEGER, num INTEGER, module INTEGER, "
2469 "operation VARCHAR(256), op_params BLOB, enabled INTEGER, "
2470 "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256), "
2471 "FOREIGN KEY(imgid) REFERENCES images(id) ON UPDATE CASCADE ON DELETE CASCADE)",
2477 "CREATE TABLE main.masks_history (imgid INTEGER, num INTEGER, formid INTEGER, form INTEGER, name VARCHAR(256), "
2478 "version INTEGER, points BLOB, points_count INTEGER, source BLOB, "
2479 "FOREIGN KEY(imgid) REFERENCES images(id) ON UPDATE CASCADE ON DELETE CASCADE)",
2483 "CREATE INDEX main.masks_history_imgid_index ON masks_history (imgid, num)",
2486 sqlite3_exec(db->
handle,
"CREATE INDEX main.images_latlong_index ON images (latitude DESC, longitude DESC)",
2490 sqlite3_exec(db->
handle,
"CREATE TABLE main.tagged_images (imgid INTEGER, tagid INTEGER, position INTEGER, "
2491 "PRIMARY KEY (imgid, tagid),"
2492 "FOREIGN KEY(imgid) REFERENCES images(id) ON UPDATE CASCADE ON DELETE CASCADE)",
NULL,
NULL,
NULL);
2504 sqlite3_exec(db->
handle,
"CREATE TABLE main.module_order (imgid INTEGER PRIMARY KEY, version INTEGER, iop_list VARCHAR)",
2506 sqlite3_exec(db->
handle,
"CREATE TABLE main.history_hash (imgid INTEGER PRIMARY KEY, "
2507 "basic_hash BLOB, auto_hash BLOB, current_hash BLOB, mipmap_hash BLOB, "
2508 "FOREIGN KEY(imgid) REFERENCES images(id) ON UPDATE CASCADE ON DELETE CASCADE)",
2512 sqlite3_exec(db->
handle,
"CREATE INDEX main.images_datetime_taken_nc ON images (datetime_taken COLLATE NOCASE)",
2527 db->
handle,
"INSERT OR REPLACE INTO data.db_info (key, value) VALUES ('version', ?1)", -1, &
stmt,
NULL);
2532 sqlite3_exec(db->
handle,
"CREATE TABLE data.tags (id INTEGER PRIMARY KEY, name VARCHAR, "
2536 sqlite3_exec(db->
handle,
"CREATE TABLE data.styles (id INTEGER PRIMARY KEY, name VARCHAR, description VARCHAR, iop_list VARCHAR)",
2542 "CREATE TABLE data.style_items (styleid INTEGER, num INTEGER, module INTEGER, "
2543 "operation VARCHAR(256), op_params BLOB, enabled INTEGER, "
2544 "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))",
2548 "CREATE INDEX IF NOT EXISTS data.style_items_styleid_index ON style_items (styleid)",
2551 sqlite3_exec(db->
handle,
"CREATE TABLE data.presets (name VARCHAR, description VARCHAR, operation "
2552 "VARCHAR, op_version INTEGER, op_params BLOB, "
2553 "enabled INTEGER, blendop_params BLOB, blendop_version INTEGER, "
2554 "multi_priority INTEGER, multi_name VARCHAR(256), "
2555 "model VARCHAR, maker VARCHAR, lens VARCHAR, iso_min REAL, iso_max REAL, "
2556 "exposure_min REAL, exposure_max REAL, "
2557 "aperture_min REAL, aperture_max REAL, focal_length_min REAL, "
2558 "focal_length_max REAL, writeprotect INTEGER, "
2559 "autoapply INTEGER, filter INTEGER, def INTEGER, format INTEGER)",
2561 sqlite3_exec(db->
handle,
"CREATE UNIQUE INDEX data.presets_idx ON presets (name, operation, op_version)",
2565 "type INTEGER, longitude REAL, latitude REAL, delta1 REAL, delta2 REAL, ratio FLOAT, polygons BLOB, "
2566 "FOREIGN KEY(tagid) REFERENCES tags(id))",
NULL,
NULL,
NULL);
2578 "CREATE TABLE memory.collected_images (rowid INTEGER PRIMARY KEY AUTOINCREMENT, imgid INTEGER)",
NULL,
2582 "CREATE TABLE memory.collected_backup (rowid INTEGER PRIMARY KEY AUTOINCREMENT, imgid INTEGER)",
NULL,
2587 "(tmpid INTEGER PRIMARY KEY, id INTEGER UNIQUE ON CONFLICT IGNORE, "
2588 "count INTEGER DEFAULT 0, count2 INTEGER DEFAULT 0)",
2594 "CREATE TABLE memory.undo_history (id INTEGER, imgid INTEGER, num INTEGER, module INTEGER, "
2595 "operation VARCHAR(256), op_params BLOB, enabled INTEGER, "
2596 "blendop_params BLOB, blendop_version INTEGER, multi_priority INTEGER, multi_name VARCHAR(256))",
2600 "CREATE TABLE memory.undo_masks_history (id INTEGER, imgid INTEGER, num INTEGER, formid INTEGER,"
2601 " form INTEGER, name VARCHAR(256), version INTEGER, points BLOB, points_count INTEGER, source BLOB)",
2605 "CREATE TABLE memory.undo_module_order (id INTEGER, imgid INTEGER, version INTEGER, iop_list VARCHAR)",
2608 "CREATE TABLE memory.darktable_iop_names (operation VARCHAR(256) PRIMARY KEY, name VARCHAR(256))",
2611 "CREATE TABLE memory.film_folder (id INTEGER PRIMARY KEY, status INTEGER)",
2624 = {
"film_rolls",
"images",
"history",
"masks_history",
"module_order",
2625 "tagged_images",
"color_labels",
"meta_data",
"history_hash" };
2630 " SELECT 0 AS snap_id, 0 AS undo_imgid, * FROM main.%s WHERE 0",
2640 "CREATE TABLE memory.removed_groups (snap_id INTEGER, undo_imgid INTEGER, id INTEGER, group_id INTEGER)",
2677 "UPDATE main.film_rolls SET folder = substr(folder, 1, length(folder) - 1) WHERE folder LIKE '%/'",
2684#define TRY_EXEC(_query, _message) \
2687 if(sqlite3_exec(db->handle, _query, NULL, NULL, NULL) != SQLITE_OK) \
2689 fprintf(stderr, _message); \
2690 fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
2692 sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
2697#define TRY_STEP(_stmt, _expected, _message) \
2700 if(sqlite3_step(_stmt) != _expected) \
2702 fprintf(stderr, _message); \
2703 fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
2705 sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
2710#define TRY_PREPARE(_stmt, _query, _message) \
2713 if(sqlite3_prepare_v2(db->handle, _query, -1, &_stmt, NULL) != SQLITE_OK) \
2715 fprintf(stderr, _message); \
2716 fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
2718 sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
2726 sqlite3_finalize(stmt); stmt = NULL; \
2771 const char *
names[] = {
"/data.db.lock",
"/library.db.lock" };
2772 for(
size_t i = 0;
i <
sizeof(
names) /
sizeof(
names[0]);
i++)
2813 snprintf(filename,
sizeof(filename),
"/proc/%d/cmdline",
pid);
2833 gboolean lock_acquired =
FALSE;
2840 lock_acquired =
TRUE;
2861 memset(buf, 0,
sizeof(buf));
2874 const int bytes_read = read(fd, buf,
sizeof(buf) - 1);
2893 fprintf(
stderr,
"[init] tried several times to acquire the database lock, giving up\n");
2901 fprintf(
stderr,
"[init] the database lock file contains a pid that seems to be alive in your system: %d\n",
2911 fprintf(
stderr,
"[init] the database lock file seems to be empty\n");
2932 return lock_acquired;
2971 fprintf(
stderr,
"[init] we shall not update the database, aborting.\n");
2983 if((version[
k] <
'0' || version[
k] >
'9') && (version[
k] !=
'.'))
3074 fprintf(
stderr,
"[init] cannot ask the user about `%s': no prompt handler registered\n",
3086 const gboolean snapshot_available)
3089 .dbfilename = dbfilename,
3090 .quick_check = quick_check,
3091 .snapshot_available = snapshot_available };
3098 .dbfilename = dbfilename };
3105 .dbfilename = dbfilename };
3111 const char *
const alternative =
params->alternative;
3112 const gboolean load_data =
params->load_data;
3113 const gboolean has_gui =
params->has_gui;
3129 const char *library =
params->library;
3169 else if(
dbname[0] !=
'/')
3176 g_strlcpy(dbfilename_library, alternative,
sizeof(dbfilename_library));
3188 snprintf(dbfilename_data,
sizeof(dbfilename_data),
":memory:");
3201 if(
g_strcmp0(dbfilename_data,
":memory:"))
3208 if(
g_strcmp0(dbfilename_library,
":memory:"))
3216 _db_print(
"[init sql] library: %s, data: %s\n", dbfilename_library, dbfilename_data);
3224 fprintf(
stderr,
"[init] database is locked, probably another process is already using it\n");
3238 fprintf(
stderr,
"[init] maybe your %s/anselrc is corrupt?\n", datadir);
3240 fprintf(
stderr,
"[init] try `cp %s/anselrc %s/anselrc'\n", dbfilename_library, datadir);
3284 fprintf(
stderr,
"[init] database `%s' couldn't be opened. aborting\n", dbfilename_data);
3291 _db_print(
"[sql] Opened database: '%s'\n", dbfilename_data);
3302 _db_print(
"[sql] Configured database\n");
3331 fprintf(
stderr,
"[init] database `%s' couldn't be upgraded from version %d to %d. aborting\n",
3341 fprintf(
stderr,
"[init] database version of `%s' is too new for this build of darktable. aborting\n",
3383 fprintf(
stderr,
"[init] database `%s' is corrupt and can't be opened! either replace it from a backup or "
3384 "delete the file so that darktable can create a new one the next time. aborting\n", dbfilename_data);
3391 fprintf(
stderr,
"[init] deleting `%s' on user request", dbfilename_data);
3433 _db_print(
"[sql] Checked database schema and migrated if needed\n");
3455 fprintf(
stderr,
"[init] database `%s' couldn't be upgraded from version %d to %d. aborting\n",
dbname,
3465 fprintf(
stderr,
"[init] database version of `%s' is too new for this build of darktable. aborting\n",
3507 fprintf(
stderr,
"[init] database `%s' is corrupt and can't be opened! either replace it from a backup or "
3508 "delete the file so that darktable can create a new one the next time. aborting\n", dbfilename_library);
3515 fprintf(
stderr,
"[init] deleting `%s' on user request", dbfilename_library);
3517 if(
g_unlink(dbfilename_library) == 0)
3571 fprintf(
stderr,
"[init] database `%s' couldn't be migrated from the legacy version %d. aborting\n",
3580 fprintf(
stderr,
"[init] database `%s' couldn't be upgraded from version 1 to %d. aborting\n",
dbname,
3599 _db_print(
"[sql] Created in-memory DB\n");
3604 _db_print(
"[sql] Loaded legacy presets\n");
3616 "SELECT icu_load_collation('en_US', 'english')",
3646 fprintf(
stderr,
"[database] a database is already open; close it first\n");
3703 settings->maintenance_freepage_ratio = 0;
3820 const char *homedir =
getenv(
"HOME");
3828 fprintf(
stderr,
"[init] moving database into new XDG directory structure\n");
3834 fprintf(
stderr,
"[init] could not move `%s' to `%s' (%s), keeping the old location\n",
3880 _db_print(
"[db busy stmt] non-finalized nor stepped through statement: '%s'\n",
sql);
3884 _db_print(
"[db busy stmt] non-finalized statement: '%s'\n",
sql);
3890#define ERRCHECK {if (err!=NULL) {_db_print("[db maintenance] maintenance error: '%s'\n",err); sqlite3_free(err); err=NULL;}}
3907 _db_print(
"[db maintenance] maintenance deemed unnecesary, performing only analyze.\n");
3943 _db_print(
"[db maintenance] maintenance problem. if no errors logged, it should work fine next time.\n");
3965 .reclaimable_bytes =
size,
3985 const char *config =
settings.maintenance_check;
3990 _db_print(
"[db maintenance] please consider enabling database maintenance.\n");
4000 if((
strstr(config,
"on both"))
4005 _db_print(
"[db maintenance] checking for maintenance, due to rule: '%s'.\n", config);
4026 _db_print(
"[db maintenance] main: [%d/%d pages], data: [%d/%d pages].\n",
4032 _db_print(
"[db maintenance] page_count <= 0 : main.page_count: %d, data.page_count: %d \n",
4073 _db_print(
"[db backup] %d out of %d done\n", total - remaining, total);
4138 const char *file_pattern =
"%s-snp-%s";
4192 const char *
const config =
settings.create_snapshot;
4199 _db_print(
"[db backup] please consider enabling database snapshots.\n");
4205 _db_print(
"[db backup] performing unconditional snapshot.\n");
4208 else if(!
g_strcmp0(config,
"once a day"))
4213 else if(!
g_strcmp0(config,
"once a week"))
4218 else if(!
g_strcmp0(config,
"once a month"))
4227 _db_print(
"[db backup] invalid timespan requirement expecting never/on close/once a [day/week/month], got %s.\n", config);
4254 _db_print(
"[db backup] checking snapshots existence.\n");
4260 _db_print(
"[db backup] couldn't get library parent!.\n");
4270 _db_print(
"[db backup] couldn't enumerate library parent: %s.\n",
error->message);
4313 _db_print(
"[db backup] problem enumerating library parent: %s.\n",
error->message);
4351 for (
i = 0;
i < length;
i++)
4353 const gchar c = text[
i];
4354 if (c <
'0' || c >
'9')
4356 v =
v * 10 + (c -
'0');
4365 const gchar*
e1 = (gchar *) a;
4366 const gchar*
e2 = (gchar *) b;
4379 int year,month,
day,hour,minute,second;
4432 _db_print(
"[db backup] checking snapshots existence.\n");
4438 _db_print(
"[db backup] couldn't get library parent!.\n");
4448 _db_print(
"[db backup] couldn't get data parent!.\n");
4479 _db_print(
"[db backup] couldn't enumerate library parent: %s.\n",
error->message);
4521 _db_print(
"[db backup] problem enumerating library parent: %s.\n",
error->message);
4546 _db_print(
"[db backup] couldn't enumerate library parent: %s.\n",
error->message);
4564 _db_print(
"[db backup] couldn't enumerate data parent: %s.\n",
error->message);
4602 _db_print(
"[db backup] problem enumerating library parent: %s.\n",
error->message);
4642 _db_print(
"[db backup] problem enumerating data parent: %s.\n",
error->message);
4712 _db_print(
"[db backup] checking snapshots existence.\n");
4718 _db_print(
"[db backup] couldn't get database parent!.\n");
4728 _db_print(
"[db backup] couldn't enumerate database parent: %s.\n",
error->message);
4774 _db_print(
"[db backup] problem enumerating database parent: %s.\n",
error->message);
4852#ifdef USE_NESTED_TRANSACTIONS
4882 fprintf(
stderr,
"[dt_database_release_transaction] COMMIT from non-owner thread\n");
4889 fprintf(
stderr,
"[dt_database_release_transaction] COMMIT outside a transaction\n");
4897#ifdef USE_NESTED_TRANSACTIONS
4914 fprintf(
stderr,
"[dt_database_rollback_transaction] ROLLBACK from non-owner thread\n");
4921 fprintf(
stderr,
"[dt_database_rollback_transaction] ROLLBACK outside a transaction\n");
4932#ifdef USE_NESTED_TRANSACTIONS
4971 _db_print(
"[dt_database_end_transaction_batch] COMMIT from non-owner thread\n");
4978 _db_print(
"[dt_database_end_transaction_batch] COMMIT outside a batch transaction\n");
static void error(char *msg)
void dt_atomic_set_int(dt_atomic_int *var, int value)
int dt_atomic_get_int(dt_atomic_int *var)
int dt_atomic_sub_int(dt_atomic_int *var, int decr)
int dt_atomic_add_int(dt_atomic_int *var, int incr)
typedef void((*dt_cache_allocate_t)(void *userdata, dt_cache_entry_t *entry))
static const dt_adaptation_t kind
dt_image_flags_t dt_image_flags_from_extension(const char *extension)
const char darktable_package_version[]
static dt_pthread_rwlock_t _db_lock
static gboolean _lock_single_database(dt_database_t *db, const char *dbfilename, char **lockfile)
static void _print_backup_progress(int remaining, int total)
void dt_database_set_renamed_handler(dt_database_renamed_handler_t handler)
void dt_database_settings_free(dt_database_settings_t *settings)
void dt_database_backup(const char *filename)
void dt_database_optimize(void)
void dt_database_start_transaction_debug(void)
#define TRY_PREPARE(_stmt, _query, _message)
static dt_database_settings_t _settings
gchar * dt_database_get_most_recent_snap(const char *db_filename)
static gpointer _trx_batch_owner
static gboolean pid_is_alive(int pid)
void dt_database_set_settings(const dt_database_settings_t *settings)
#define MAX_NESTED_TRANSACTIONS
void dt_database_begin_transaction_batch(void)
static gboolean _is_mem_db(void)
void dt_database_release_transaction_debug(void)
void ask_for_upgrade(const gchar *dbname, const gboolean has_gui)
gchar * _get_pragma_string_val(sqlite3 *db, const char *pragma)
static dt_database_response_t _ask_readonly(const char *dbfilename)
static dt_atomic_int _trxid
static dt_database_response_t _ask_user(const dt_database_prompt_context_t *context)
char ** dt_database_snaps_to_remove(void)
static dt_pthread_mutex_t _settings_lock
void dt_database_take_error(dt_database_error_t *error)
void dt_database_error_free(dt_database_error_t *error)
void dt_database_get_settings(dt_database_settings_t *settings)
static gpointer _trx_owner
static void _sanitize_db(dt_database_t *db)
sqlite3 * dt_database_get_sqlite3_global(void)
const char * dt_database_get_last_error(void)
void dt_database_set_prompt_handler(dt_database_prompt_handler_t handler)
void dt_database_close(void)
static gboolean _migrate_schema(dt_database_t *db, int version)
static dt_database_response_t _ask_corrupted(const char *dbfilename, const char *quick_check, const gboolean snapshot_available)
static void _database_delete_mipmaps_files()
static int _upgrade_library_schema_step(dt_database_t *db, int version)
#define TRY_EXEC(_query, _message)
gboolean dt_database_snapshot(void)
const gchar * dt_database_get_path(void)
static gboolean _ask_for_maintenance(const char *maintenance_check, const gboolean closing_time, const guint64 size)
static dt_database_t * _database_init(const dt_database_params_t *params)
static int _upgrade_data_schema_step(dt_database_t *db, int version)
void dt_database_perform_maintenance(void)
void dt_database_cleanup_busy_statements(void)
#define _SQLITE3_EXEC(a, b, c, d, e)
void dt_database_rollback_transaction(void)
static gboolean _db_lock_inited
int _get_pragma_int_val(sqlite3 *db, const char *pragma)
static void _create_library_schema(dt_database_t *db)
static gboolean _snapshot_policy_decides(GTimeSpan *interval, gboolean *answer)
static gboolean _upgrade_library_schema(dt_database_t *db, int version)
static int _backup_db(sqlite3 *src_db, const char *src_db_name, const char *dest_filename, void(*xProgress)(int, int))
static dt_atomic_int _trx_batch_level
static void _database_free(dt_database_t *db)
static dt_database_t * _db
static gboolean _settings_lock_inited
#define CURRENT_DATABASE_VERSION_LIBRARY
static dt_database_renamed_handler_t _renamed_handler
static gboolean _upgrade_data_schema(dt_database_t *db, int version)
static void _create_memory_schema(dt_database_t *db)
#define TRY_STEP(_stmt, _expected, _message)
gboolean dt_database_maybe_maintenance(const gboolean closing_time)
gboolean dt_database_is_open(void)
dt_database_open_result_t dt_database_open(const dt_database_params_t *params)
static gchar * _database_migrate_to_xdg_structure(const char *configured_db)
gboolean dt_database_maybe_snapshot(void)
static dt_database_response_t _ask_upgrade(const char *dbfilename)
int dt_database_delete_lock_files(const char *dbfilename)
static gboolean _lock_databases(dt_database_t *db)
void dt_database_end_transaction_batch(void)
static gboolean _get_iso8601_int(const gchar *text, gsize length, gint *value)
static void _create_data_schema(dt_database_t *db)
static dt_database_prompt_handler_t _prompt_handler
static gint _db_snap_sort(gconstpointer a, gconstpointer b, gpointer user_data)
#define CURRENT_DATABASE_VERSION_DATA
dt_database_response_t(* dt_database_prompt_handler_t)(const dt_database_prompt_context_t *context)
void(* dt_database_renamed_handler_t)(const char *new_library_name)
@ DT_DATABASE_RESPONSE_CLOSE
@ DT_DATABASE_RESPONSE_PROCEED
@ DT_DATABASE_RESPONSE_RESTORE
@ DT_DATABASE_RESPONSE_DELETE
dt_database_open_result_t
@ DT_DATABASE_OPEN_FAILED
@ DT_DATABASE_OPEN_LOCKED
@ DT_DATABASE_PROMPT_UPGRADE
@ DT_DATABASE_PROMPT_MAINTENANCE
@ DT_DATABASE_PROMPT_CORRUPTED
@ DT_DATABASE_PROMPT_READONLY
GDateTime * dt_datetime_exif_to_gdatetime(const char *exif, const GTimeZone *tz)
GTimeZone * dt_datetime_utc_tz(void)
GTimeSpan dt_datetime_gdatetime_to_gtimespan(GDateTime *gdt)
GHashTable * names
GtkWidget* -> the name the application knows it by.
GtkWidget * status
result of the last capture
static int dt_pthread_rwlock_wrlock(dt_pthread_rwlock_t *rwlock) ACQUIRE(rwlock) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_rwlock_unlock(dt_pthread_rwlock_t *rwlock) RELEASE_GENERIC(rwlock) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Initialise a mutex. With mutexattr NULL – which is how 54 of the 56 call sites in this tree spell it ...
static int dt_pthread_rwlock_init(dt_pthread_rwlock_t *lock, const pthread_rwlockattr_t *attr)
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
void dt_loc_get_user_cache_dir(char *cachedir, size_t bufsize)
void dt_loc_get_datadir(char *datadir, size_t bufsize)
void dt_loc_get_user_config_dir(char *configdir, size_t bufsize)
GList * dt_ioppr_get_iop_order_list_version(dt_iop_order_t version)
Return the built-in order list for a given version.
gint dt_sort_iop_list_by_order_f(gconstpointer a, gconstpointer b)
Compare two list nodes holding modules by iop_order.
dt_iop_order_t dt_ioppr_get_iop_order_list_kind(GList *iop_order_list)
Determine the kind of an order list by inspecting its content.
char * dt_ioppr_serialize_text_iop_order_list(GList *iop_order_list)
Serialize an order list to a text representation.
static const dt_iop_drawlayer_params_t * params
void dt_legacy_presets_create(sqlite3 *handle)
float *const restrict const size_t k
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
static void dt_free_gpointer(gpointer ptr)
g_free() one pointer, with the signature GDestroyNotify wants.
#define dt_free(ptr)
g_free() ptr and set it to NULL, skipping both if it is already NULL.
dt_mipmap_buffer_dsc_flags flags
#define DT_PATH_MAX
Buffer size for a filesystem path anywhere in Ansel.
void dt_concat_path_file(char destination[4096], const char path[4096], const char *const file)
Append a constant filename to a variable, stack-based, fixed-sized, directory, and add a / in-between...
static const dt_aligned_pixel_simd_t value
Checked wrappers around the sqlite3_* calls: trace the statement, assert the return code,...
#define DT_DEBUG_SQLITE3_EXEC(a, b, c, d, e)
int sqlite3IcuInit(sqlite3 *db)
static const char *const day[7]
dt_database_prompt_t prompt
int maintenance_freepage_ratio
gchar * dbfilename_library
union dt_iop_order_entry_t::@24 o
gchar * dt_util_foo_to_utf8(const char *string)