Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
database.c File Reference
#include "system/atomic.h"
#include "common/paths.h"
#include "system/dtpthread.h"
#include "common/image.h"
#include "database/database.h"
#include "database/sql_debug.h"
#include "common/datetime.h"
#include "common/file_location.h"
#include "develop/iop_order.h"
#include "database/legacy_presets.h"
#include <gio/gio.h>
#include <glib.h>
#include <glib/gstdio.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/stat.h>
#include <sys/types.h>
#include "common/utility.h"
+ Include dependency graph for database.c:

Go to the source code of this file.

Data Structures

struct  dt_database_t
 

Macros

#define CURRENT_DATABASE_VERSION_LIBRARY   36
 
#define CURRENT_DATABASE_VERSION_DATA   9
 
#define MAX_NESTED_TRANSACTIONS   0
 
#define _db_print(...)
 
#define _SQLITE3_EXEC(a, b, c, d, e)
 
#define TRY_EXEC(_query, _message)
 
#define TRY_STEP(_stmt, _expected, _message)
 
#define TRY_PREPARE(_stmt, _query, _message)
 
#define FINALIZE
 
#define FINALIZE
 
#define FINALIZE
 
#define FINALIZE
 
#define TRY_EXEC(_query, _message)
 
#define TRY_STEP(_stmt, _expected, _message)
 
#define TRY_PREPARE(_stmt, _query, _message)
 
#define FINALIZE
 
#define ERRCHECK   {if (err!=NULL) {_db_print("[db maintenance] maintenance error: '%s'\n",err); sqlite3_free(err); err=NULL;}}
 

Typedefs

typedef struct dt_database_t dt_database_t
 

Functions

static gchar * _database_migrate_to_xdg_structure (const char *configured_db)
 
static void _database_delete_mipmaps_files ()
 
static void _database_free (dt_database_t *db)
 
static gboolean _migrate_schema (dt_database_t *db, int version)
 
static int _upgrade_library_schema_step (dt_database_t *db, int version)
 
static int _upgrade_data_schema_step (dt_database_t *db, int version)
 
static gboolean _upgrade_library_schema (dt_database_t *db, int version)
 
static gboolean _upgrade_data_schema (dt_database_t *db, int version)
 
static void _create_library_schema (dt_database_t *db)
 
static void _create_data_schema (dt_database_t *db)
 
static void _create_memory_schema (dt_database_t *db)
 
static void _sanitize_db (dt_database_t *db)
 
void dt_database_take_error (dt_database_error_t *error)
 
void dt_database_error_free (dt_database_error_t *error)
 
int dt_database_delete_lock_files (const char *dbfilename)
 
static gboolean pid_is_alive (int pid)
 
static gboolean _lock_single_database (dt_database_t *db, const char *dbfilename, char **lockfile)
 
static gboolean _lock_databases (dt_database_t *db)
 
static dt_database_response_t _ask_upgrade (const char *dbfilename)
 
void ask_for_upgrade (const gchar *dbname, const gboolean has_gui)
 
void dt_database_backup (const char *filename)
 
int _get_pragma_int_val (sqlite3 *db, const char *pragma)
 
gchar * _get_pragma_string_val (sqlite3 *db, const char *pragma)
 
void dt_database_set_prompt_handler (dt_database_prompt_handler_t handler)
 
static dt_database_response_t _ask_user (const dt_database_prompt_context_t *context)
 
static dt_database_response_t _ask_corrupted (const char *dbfilename, const char *quick_check, const gboolean snapshot_available)
 
static dt_database_response_t _ask_readonly (const char *dbfilename)
 
static dt_database_t_database_init (const dt_database_params_t *params)
 
void dt_database_set_renamed_handler (dt_database_renamed_handler_t handler)
 
dt_database_open_result_t dt_database_open (const dt_database_params_t *params)
 
void dt_database_set_settings (const dt_database_settings_t *settings)
 
void dt_database_get_settings (dt_database_settings_t *settings)
 
void dt_database_settings_free (dt_database_settings_t *settings)
 
void dt_database_close (void)
 
gboolean dt_database_is_open (void)
 
const char * dt_database_get_last_error (void)
 
sqlite3 * dt_database_get_sqlite3_global (void)
 
const gchar * dt_database_get_path (void)
 
void dt_database_cleanup_busy_statements (void)
 
void dt_database_perform_maintenance (void)
 
static gboolean _ask_for_maintenance (const char *maintenance_check, const gboolean closing_time, const guint64 size)
 
static gboolean _is_mem_db (void)
 
gboolean dt_database_maybe_maintenance (const gboolean closing_time)
 
void dt_database_optimize (void)
 
static void _print_backup_progress (int remaining, int total)
 
static int _backup_db (sqlite3 *src_db, const char *src_db_name, const char *dest_filename, void(*xProgress)(int, int))
 
gboolean dt_database_snapshot (void)
 
static gboolean _snapshot_policy_decides (GTimeSpan *interval, gboolean *answer)
 
gboolean dt_database_maybe_snapshot (void)
 
static gboolean _get_iso8601_int (const gchar *text, gsize length, gint *value)
 
static gint _db_snap_sort (gconstpointer a, gconstpointer b, gpointer user_data)
 
char ** dt_database_snaps_to_remove (void)
 
gchar * dt_database_get_most_recent_snap (const char *db_filename)
 
void dt_database_start_transaction_debug (void)
 
void dt_database_release_transaction_debug (void)
 
void dt_database_rollback_transaction (void)
 
void dt_database_begin_transaction_batch (void)
 
void dt_database_end_transaction_batch (void)
 

Variables

static dt_atomic_int _trxid
 
static dt_atomic_int _trx_batch_level
 
static gpointer _trx_owner = NULL
 
static gpointer _trx_batch_owner = NULL
 
static dt_database_t_db = NULL
 
static dt_pthread_rwlock_t _db_lock
 
static gboolean _db_lock_inited = FALSE
 
static dt_database_settings_t _settings = { NULL, 0, NULL, 0 }
 
static dt_pthread_mutex_t _settings_lock
 
static gboolean _settings_lock_inited = FALSE
 
static gboolean _has_gui = FALSE
 
static gboolean _verbose = FALSE
 
static dt_database_renamed_handler_t _renamed_handler = NULL
 
static dt_database_prompt_handler_t _prompt_handler = NULL
 

Macro Definition Documentation

◆ _db_print

#define _db_print (   ...)
Value:
do { \
if(_verbose) dt_print(DT_DEBUG_SQL, __VA_ARGS__); \
} while(0)
static gboolean _verbose
Definition database.c:153
@ DT_DEBUG_SQL
Definition logging.h:58
void dt_print(dt_debug_thread_t thread, const char *msg,...) __attribute__((format(printf
Print to stdout when thread is enabled, prefixed with seconds since startup.

Trace gate. A statement, so that a bare if(_verbose) dt_print(...) cannot swallow a following else – which is exactly what happened in caches/image_cache.c and was only caught by -Wdangling-else in the Debug builds.

Definition at line 161 of file database.c.

◆ _SQLITE3_EXEC

#define _SQLITE3_EXEC (   a,
  b,
  c,
  d,
 
)
Value:
if(sqlite3_exec(a, b, c, d, e) != SQLITE_OK) \
{ \
all_ok = FALSE; \
failing_query = b; \
goto end; \
}
#define FALSE
Definition ashift_lsd.c:158

Definition at line 177 of file database.c.

◆ CURRENT_DATABASE_VERSION_DATA

#define CURRENT_DATABASE_VERSION_DATA   9

Definition at line 90 of file database.c.

◆ CURRENT_DATABASE_VERSION_LIBRARY

#define CURRENT_DATABASE_VERSION_LIBRARY   36

Definition at line 89 of file database.c.

◆ ERRCHECK

#define ERRCHECK   {if (err!=NULL) {_db_print("[db maintenance] maintenance error: '%s'\n",err); sqlite3_free(err); err=NULL;}}

Definition at line 3882 of file database.c.

◆ FINALIZE [1/5]

#define FINALIZE

Definition at line 537 of file database.c.

◆ FINALIZE [2/5]

#define FINALIZE
Value:
do \
{ \
sqlite3_finalize(stmt); \
sqlite3_finalize(select_stmt); \
sqlite3_finalize(count_clashes_stmt); \
sqlite3_finalize(update_name_stmt); \
sqlite3_finalize(insert_stmt); \
sqlite3_finalize(delete_stmt); \
} while(0)

Definition at line 537 of file database.c.

◆ FINALIZE [3/5]

#define FINALIZE
Value:
do \
{ \
sqlite3_finalize(stmt); \
sqlite3_finalize(insert_stmt); \
sqlite3_finalize(select_stmt); \
sqlite3_finalize(delete_stmt); \
sqlite3_finalize(update_name_stmt); \
sqlite3_finalize(select_new_stmt); \
sqlite3_finalize(copy_style_items_stmt); \
sqlite3_finalize(delete_style_items_stmt); \
} while(0)

Definition at line 537 of file database.c.

◆ FINALIZE [4/5]

#define FINALIZE

Definition at line 537 of file database.c.

◆ FINALIZE [5/5]

#define FINALIZE
Value:
do \
{ \
sqlite3_finalize(stmt); stmt = NULL; /* NULL so that finalize becomes a NOP */ \
} while(0)

Definition at line 537 of file database.c.

◆ MAX_NESTED_TRANSACTIONS

#define MAX_NESTED_TRANSACTIONS   0

Definition at line 93 of file database.c.

◆ TRY_EXEC [1/2]

#define TRY_EXEC (   _query,
  _message 
)
Value:
do \
{ \
if(sqlite3_exec(db->handle, _query, NULL, NULL, NULL) != SQLITE_OK) \
{ \
fprintf(stderr, _message); \
fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
return version; \
} \
} while(0)
static gchar * _query
#define FINALIZE
Definition database.c:537

Definition at line 497 of file database.c.

◆ TRY_EXEC [2/2]

#define TRY_EXEC (   _query,
  _message 
)
Value:
do \
{ \
if(sqlite3_exec(db->handle, _query, NULL, NULL, NULL) != SQLITE_OK) \
{ \
fprintf(stderr, _message); \
fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
return FALSE; \
} \
} while(0)

Definition at line 497 of file database.c.

◆ TRY_PREPARE [1/2]

#define TRY_PREPARE (   _stmt,
  _query,
  _message 
)
Value:
do \
{ \
if(sqlite3_prepare_v2(db->handle, _query, -1, &_stmt, NULL) != SQLITE_OK) \
{ \
fprintf(stderr, _message); \
fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
return version; \
} \
} while(0)

Definition at line 523 of file database.c.

◆ TRY_PREPARE [2/2]

#define TRY_PREPARE (   _stmt,
  _query,
  _message 
)
Value:
do \
{ \
if(sqlite3_prepare_v2(db->handle, _query, -1, &_stmt, NULL) != SQLITE_OK) \
{ \
fprintf(stderr, _message); \
fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
return FALSE; \
} \
} while(0)

Definition at line 523 of file database.c.

◆ TRY_STEP [1/2]

#define TRY_STEP (   _stmt,
  _expected,
  _message 
)
Value:
do \
{ \
if(sqlite3_step(_stmt) != _expected) \
{ \
fprintf(stderr, _message); \
fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
return version; \
} \
} while(0)

Definition at line 510 of file database.c.

◆ TRY_STEP [2/2]

#define TRY_STEP (   _stmt,
  _expected,
  _message 
)
Value:
do \
{ \
if(sqlite3_step(_stmt) != _expected) \
{ \
fprintf(stderr, _message); \
fprintf(stderr, "[init] %s\n", sqlite3_errmsg(db->handle)); \
sqlite3_exec(db->handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL); \
return FALSE; \
} \
} while(0)

Definition at line 510 of file database.c.

Typedef Documentation

◆ dt_database_t

typedef struct dt_database_t dt_database_t

Function Documentation

◆ _ask_corrupted()

static dt_database_response_t _ask_corrupted ( const char *  dbfilename,
const char *  quick_check,
const gboolean  snapshot_available 
)
static

◆ _ask_for_maintenance()

static gboolean _ask_for_maintenance ( const char *  maintenance_check,
const gboolean  closing_time,
const guint64  size 
)
static

◆ _ask_readonly()

static dt_database_response_t _ask_readonly ( const char *  dbfilename)
static

◆ _ask_upgrade()

static dt_database_response_t _ask_upgrade ( const char *  dbfilename)
static

◆ _ask_user()

◆ _backup_db()

static int _backup_db ( sqlite3 *  src_db,
const char *  src_db_name,
const char *  dest_filename,
void(*)(int, int)  xProgress 
)
static

Definition at line 4068 of file database.c.

References _db_print, _get_pragma_int_val(), dt_free, MAX, MIN, and void().

Referenced by dt_database_snapshot().

◆ _create_data_schema()

static void _create_data_schema ( dt_database_t db)
static

Definition at line 2519 of file database.c.

References CURRENT_DATABASE_VERSION_DATA, and dt_database_t::handle.

Referenced by _database_init().

◆ _create_library_schema()

static void _create_library_schema ( dt_database_t db)
static
Todo:
: make sure to bump CURRENT_DATABASE_VERSION_LIBRARY and add a

Definition at line 2413 of file database.c.

References CURRENT_DATABASE_VERSION_LIBRARY, and dt_database_t::handle.

Referenced by _database_init().

◆ _create_memory_schema()

static void _create_memory_schema ( dt_database_t db)
static

Definition at line 2572 of file database.c.

References dt_database_t::handle, and i.

Referenced by _database_init().

◆ _database_delete_mipmaps_files()

static void _database_delete_mipmaps_files ( )
static

Definition at line 3840 of file database.c.

References dt_concat_path_file(), dt_loc_get_user_cache_dir(), and DT_PATH_MAX.

Referenced by _database_init().

◆ _database_free()

◆ _database_init()

◆ _database_migrate_to_xdg_structure()

static gchar * _database_migrate_to_xdg_structure ( const char *  configured_db)
static

◆ _db_snap_sort()

static gint _db_snap_sort ( gconstpointer  a,
gconstpointer  b,
gpointer  user_data 
)
static

Definition at line 4355 of file database.c.

References _get_iso8601_int(), day, and IS_NULL_PTR.

Referenced by dt_database_snaps_to_remove().

◆ _get_iso8601_int()

static gboolean _get_iso8601_int ( const gchar *  text,
gsize  length,
gint *  value 
)
static

Definition at line 4335 of file database.c.

References FALSE, i, TRUE, v, and value.

Referenced by _db_snap_sort().

◆ _get_pragma_int_val()

int _get_pragma_int_val ( sqlite3 *  db,
const char *  pragma 
)

Definition at line 3020 of file database.c.

References dt_free.

Referenced by _backup_db(), dt_database_maybe_maintenance(), and dt_database_perform_maintenance().

◆ _get_pragma_string_val()

gchar * _get_pragma_string_val ( sqlite3 *  db,
const char *  pragma 
)

Definition at line 3036 of file database.c.

References dt_free.

Referenced by _database_init().

◆ _is_mem_db()

◆ _lock_databases()

◆ _lock_single_database()

static gboolean _lock_single_database ( dt_database_t db,
const char *  dbfilename,
char **  lockfile 
)
static

◆ _migrate_schema()

static gboolean _migrate_schema ( dt_database_t db,
int  version 
)
static

Definition at line 186 of file database.c.

References _SQLITE3_EXEC, dt_free, FALSE, dt_database_t::handle, i, IS_NULL_PTR, name, and TRUE.

Referenced by _database_init().

◆ _print_backup_progress()

static void _print_backup_progress ( int  remaining,
int  total 
)
static
Todo:
if we have closing splashpage - this can be used to advance progressbar :)

Definition at line 4062 of file database.c.

References _db_print.

Referenced by dt_database_snapshot().

◆ _sanitize_db()

static void _sanitize_db ( dt_database_t db)
static

Definition at line 2644 of file database.c.

References dt_free, dt_util_foo_to_utf8(), and dt_database_t::handle.

Referenced by _database_init().

◆ _snapshot_policy_decides()

static gboolean _snapshot_policy_decides ( GTimeSpan *  interval,
gboolean *  answer 
)
static

◆ _upgrade_data_schema()

static gboolean _upgrade_data_schema ( dt_database_t db,
int  version 
)
static

Definition at line 2399 of file database.c.

References _upgrade_data_schema_step(), CURRENT_DATABASE_VERSION_DATA, FALSE, and TRUE.

Referenced by _database_init().

◆ _upgrade_data_schema_step()

◆ _upgrade_library_schema()

static gboolean _upgrade_library_schema ( dt_database_t db,
int  version 
)
static

Definition at line 2384 of file database.c.

References _upgrade_library_schema_step(), CURRENT_DATABASE_VERSION_LIBRARY, FALSE, and TRUE.

Referenced by _database_init().

◆ _upgrade_library_schema_step()

◆ ask_for_upgrade()

void ask_for_upgrade ( const gchar *  dbname,
const gboolean  has_gui 
)

Definition at line 2957 of file database.c.

References _ask_upgrade(), and DT_DATABASE_RESPONSE_PROCEED.

Referenced by _database_init().

◆ dt_database_backup()

void dt_database_backup ( const char *  filename)

Definition at line 2976 of file database.c.

References darktable_package_version, dt_free, FALSE, k, and TRUE.

Referenced by _database_init().

◆ dt_database_begin_transaction_batch()

void dt_database_begin_transaction_batch ( void  )

◆ dt_database_cleanup_busy_statements()

void dt_database_cleanup_busy_statements ( void  )

cleanup busy statements on closing dt, just before performing maintenance

Definition at line 3861 of file database.c.

References _db, _db_print, dt_database_t::handle, and IS_NULL_PTR.

Referenced by dt_cleanup().

◆ dt_database_close()

void dt_database_close ( void  )

Close the connection and release the lock files. Safe to call when nothing is open.

Warning
Every statement must be finalised before this returns, which is why the repositories under src/database expose a *_cleanup() each. A connection cannot be closed out from under a sqlite3_stmt still held elsewhere – and that is the reason this pair is not yet a dt_database_swap(). See src/database/README.md.

Definition at line 3749 of file database.c.

References _database_free(), _db, _db_lock, _db_lock_inited, dt_pthread_rwlock_unlock(), dt_pthread_rwlock_wrlock(), and IS_NULL_PTR.

Referenced by dt_cleanup(), dt_init(), and testdb_teardown().

◆ dt_database_delete_lock_files()

int dt_database_delete_lock_files ( const char *  dbfilename)

Delete data.db.lock and library.db.lock beside dbfilename. Returns 0 when every lock file that existed was removed. Call only once the user has agreed.

Definition at line 2760 of file database.c.

References dt_free, i, IS_NULL_PTR, names, and status.

Referenced by dt_database_show_error().

◆ dt_database_end_transaction_batch()

◆ dt_database_error_free()

void dt_database_error_free ( dt_database_error_t error)

Release the strings owned by error.

Definition at line 2751 of file database.c.

References dt_free, error(), and IS_NULL_PTR.

Referenced by dt_database_show_error().

◆ dt_database_get_last_error()

const char * dt_database_get_last_error ( void  )

The message for the most recent failed call on the connection.

Exists so that reporting an error does not require the handle. Valid until the next call into the database from any thread – copy it if you keep it.

Definition at line 3776 of file database.c.

References _db, dt_database_t::handle, and IS_NULL_PTR.

Referenced by dt_exif_xmp_read(), and dt_film_new().

◆ dt_database_get_most_recent_snap()

gchar * dt_database_get_most_recent_snap ( const char *  db_filename)

get possibly the freshest snapshot to restore

Definition at line 4699 of file database.c.

References _db_print, dt_free, error(), and IS_NULL_PTR.

Referenced by _database_init().

◆ dt_database_get_path()

const gchar * dt_database_get_path ( void  )

Absolute path of the library file currently open, or NULL. Valid until the next dt_database_close(); copy it if you need to outlive that.

Definition at line 3787 of file database.c.

References _db, and dt_database_t::dbfilename_library.

Referenced by dt_mipmap_cache_get_filename().

◆ dt_database_get_settings()

void dt_database_get_settings ( dt_database_settings_t settings)

Take a copy of the policy. Strings are newly allocated – release with dt_database_settings_free(). Read as one snapshot under the module's lock: the GUI thread can replace these while a maintenance decision is being made, and four fields read one at a time can be a mix of old and new.

Definition at line 3685 of file database.c.

References _settings, _settings_lock, _settings_lock_inited, dt_database_settings_t::create_snapshot, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), IS_NULL_PTR, dt_database_settings_t::keep_snapshots, dt_database_settings_t::maintenance_check, and dt_database_settings_t::maintenance_freepage_ratio.

Referenced by _snapshot_policy_decides(), dt_database_maybe_maintenance(), and dt_database_snaps_to_remove().

◆ dt_database_get_sqlite3_global()

sqlite3 * dt_database_get_sqlite3_global ( void  )

The connection itself.

Warning
This is the escape hatch, and it is counted. Every caller of this holds a raw sqlite3 * that the module cannot account for, cannot serialise against a close, and cannot trace. tools/check_module_boundaries.sh ratchets the number of call sites downwards and it is deleted at zero – at which point the private lock below actually guarantees something and swapping workspaces at runtime becomes implementable.

Do not call it from new code: put the query in a repository under src/database and give it a name. See src/database/README.md.

Definition at line 3782 of file database.c.

References _db, and dt_database_t::handle.

Referenced by _clear_similar_tags(), _columns_of(), _compute_count(), _fill_similar_tags(), _first_id_for_text(), _image_get_stmt(), _image_write_history_hash(), _next_id(), _prepared(), _run(), _run_for_id(), _run_snap_imgid(), _scalar(), dt_collection_query_find_neighbour(), dt_collection_query_get_group_members(), dt_collection_query_get_images(), dt_collection_query_get_images_for_rule(), dt_collection_query_get_makermodels(), dt_collection_query_get_nth(), dt_collection_query_get_property_values(), dt_collection_query_image_offset(), dt_collection_query_pop(), dt_collection_query_push(), dt_collection_query_refresh_memory_table(), dt_collection_query_restrict_to_selection(), dt_collection_query_set_iop_names(), dt_colorlabel_repository_foreach(), dt_colorlabel_repository_get_list(), dt_colorlabel_repository_has(), dt_film_repository_delete(), dt_film_repository_find_by_folder(), dt_film_repository_folder_status_clear(), dt_film_repository_folder_status_set(), dt_film_repository_foreach(), dt_film_repository_foreach_empty(), dt_film_repository_foreach_under(), dt_film_repository_get_folder(), dt_film_repository_get_image_ids(), dt_film_repository_has_images(), dt_film_repository_insert(), dt_film_repository_set_folder(), dt_film_repository_touch_access(), dt_history_repository_count_items(), dt_history_repository_count_mask_items(), dt_history_repository_delete_all_for_image(), dt_history_repository_delete_history(), dt_history_repository_delete_masks_history(), dt_history_repository_find_version_for_params(), dt_history_repository_foreach_active_module(), dt_history_repository_foreach_auto_preset_row(), dt_history_repository_foreach_item(), dt_history_repository_foreach_last_item(), dt_history_repository_foreach_mask_item(), dt_history_repository_foreach_row(), dt_history_repository_get_autoapply_ioporder_params(), dt_history_repository_get_end(), dt_history_repository_get_last_enabled_params(), dt_history_repository_get_module_order(), dt_history_repository_get_module_order_version(), dt_history_repository_get_next_num(), dt_history_repository_module_exists(), dt_history_repository_set_end(), dt_history_repository_set_module_order(), dt_history_repository_shift_nums(), dt_history_repository_write_item(), dt_history_repository_write_mask_item(), dt_history_snapshot_repository_next_id(), dt_image_repository_clear_flag_among(), dt_image_repository_copy_to_film(), dt_image_repository_count_distinct_fields(), dt_image_repository_count_in_id_range(), dt_image_repository_count_others_with_flag(), dt_image_repository_delete(), dt_image_repository_duplicate(), dt_image_repository_find_by_film_and_filename(), dt_image_repository_find_by_folder_and_filename(), dt_image_repository_find_group_for_pattern(), dt_image_repository_foreach_collected(), dt_image_repository_foreach_in_id_range(), dt_image_repository_foreach_with_path(), dt_image_repository_get_collected_geo_bounds(), dt_image_repository_get_collected_geo_points(), dt_image_repository_get_duplicate_ids(), dt_image_repository_get_full_paths(), dt_image_repository_get_group_member_rows(), dt_image_repository_get_group_members(), dt_image_repository_get_ids_with_flag(), dt_image_repository_get_ids_with_flag_among(), dt_image_repository_get_ratings(), dt_image_repository_get_timestamps(), dt_image_repository_get_version(), dt_image_repository_get_versions(), dt_image_repository_get_write_timestamp(), dt_image_repository_get_xmp_row(), dt_image_repository_insert_import(), dt_image_repository_load(), dt_image_repository_reassign_group(), dt_image_repository_set_flag_among(), dt_image_repository_set_flags(), dt_image_repository_set_flags_masked(), dt_image_repository_set_group(), dt_image_repository_set_version(), dt_image_repository_set_write_timestamp(), dt_image_repository_store(), dt_image_repository_touch_write_timestamp(), dt_location_repository_delete(), dt_location_repository_find_images_for_location(), dt_location_repository_find_locations_for_image(), dt_location_repository_get_data(), dt_location_repository_get_image_locations(), dt_location_repository_get_in_bbox(), dt_location_repository_get_polygon(), dt_location_repository_set_data(), dt_metadata_repository_add(), dt_metadata_repository_find_image_by_value(), dt_metadata_repository_foreach(), dt_metadata_repository_foreach_selected(), dt_metadata_repository_get_all(), dt_metadata_repository_get_values(), dt_metadata_repository_remove(), dt_preset_repository_add_iop_preset(), dt_preset_repository_add_module_preset(), dt_preset_repository_add_shipped_preset(), dt_preset_repository_delete_all_for_module(), dt_preset_repository_delete_by_rowid(), dt_preset_repository_delete_by_rowid_unprotected(), dt_preset_repository_delete_module_preset(), dt_preset_repository_delete_shipped(), dt_preset_repository_duplicate_module_preset(), dt_preset_repository_find_autoapply(), dt_preset_repository_find_rowid(), dt_preset_repository_get_by_rowid(), dt_preset_repository_get_conditions(), dt_preset_repository_get_identity(), dt_preset_repository_get_iop_preset(), dt_preset_repository_get_module_preset(), dt_preset_repository_insert(), dt_preset_repository_insert_with_conditions(), dt_preset_repository_list_all(), dt_preset_repository_list_all_versions(), dt_preset_repository_list_editable(), dt_preset_repository_list_for_iop(), dt_preset_repository_list_for_menu(), dt_preset_repository_list_for_module(), dt_preset_repository_list_for_upgrade(), dt_preset_repository_list_for_version(), dt_preset_repository_module_preset_exists(), dt_preset_repository_rename_module_preset(), dt_preset_repository_set_blend_params(), dt_preset_repository_set_module_version(), dt_preset_repository_update_camera(), dt_preset_repository_update_conditions(), dt_preset_repository_update_flag(), dt_preset_repository_update_iop_params(), dt_preset_repository_update_module_params(), dt_preset_repository_update_params_by_rowid(), dt_preset_repository_update_range(), dt_removed_image_repository_restore(), dt_selection_repository_clear(), dt_selection_repository_deselect(), dt_selection_repository_deselect_list(), dt_selection_repository_drop_uncollected(), dt_selection_repository_get_all(), dt_selection_repository_get_lowest_id(), dt_selection_repository_pop(), dt_selection_repository_push(), dt_selection_repository_select(), dt_selection_repository_select_list(), dt_style_repository_append_item_from_history(), dt_style_repository_copy_items_from_history(), dt_style_repository_copy_items_from_style(), dt_style_repository_delete(), dt_style_repository_delete_items_except(), dt_style_repository_foreach_apply_item(), dt_style_repository_foreach_item(), dt_style_repository_foreach_item_against_image(), dt_style_repository_foreach_item_for_export(), dt_style_repository_foreach_item_with_params(), dt_style_repository_foreach_style(), dt_style_repository_get_description(), dt_style_repository_get_id_by_name(), dt_style_repository_get_iop_list(), dt_style_repository_get_style(), dt_style_repository_insert_header(), dt_style_repository_insert_item(), dt_style_repository_normalize_multi_priority(), dt_style_repository_set_iop_list(), dt_style_repository_update_header(), dt_style_repository_update_item_from_history(), dt_tag_repository_attach(), dt_tag_repository_attach_batch(), dt_tag_repository_count_attachments(), dt_tag_repository_count_distinct_images(), dt_tag_repository_delete_batch(), dt_tag_repository_detach_batch(), dt_tag_repository_get_agreement(), dt_tag_repository_get_attached(), dt_tag_repository_get_attached_for_export(), dt_tag_repository_get_attached_names(), dt_tag_repository_get_by_path_with_counts(), dt_tag_repository_get_collection_tags(), dt_tag_repository_get_flags(), dt_tag_repository_get_ids_for_images(), dt_tag_repository_get_images(), dt_tag_repository_get_images_in_list(), dt_tag_repository_get_name(), dt_tag_repository_get_names_under(), dt_tag_repository_get_similar(), dt_tag_repository_get_suggestions(), dt_tag_repository_get_synonyms(), dt_tag_repository_get_with_usage(), dt_tag_repository_insert(), dt_tag_repository_is_attached(), dt_tag_repository_rebuild_internal(), dt_tag_repository_rename(), dt_tag_repository_set_flags(), dt_tag_repository_set_synonyms(), dt_tag_repository_update_flags(), imported_style_name(), max_style_id(), print_enabled_state_summary(), print_module_order_summary(), and sql_int_for_bound_images().

◆ dt_database_is_open()

gboolean dt_database_is_open ( void  )

TRUE between a successful dt_database_open() and dt_database_close().

Definition at line 3771 of file database.c.

References _db, and IS_NULL_PTR.

Referenced by _remove_undo_data_free(), and dt_collection_query_refresh_memory_table().

◆ dt_database_maybe_maintenance()

gboolean dt_database_maybe_maintenance ( const gboolean  closing_time)

Ask the user whether to VACUUM, if the policy and the free-page ratio both say it is worth it. closing_time distinguishes the startup check from the shutdown one.

Definition at line 3970 of file database.c.

References _ask_for_maintenance(), _db, _db_print, _get_pragma_int_val(), _is_mem_db(), dt_database_get_settings(), dt_database_settings_free(), FALSE, dt_database_t::handle, IS_NULL_PTR, dt_database_settings_t::maintenance_check, dt_database_settings_t::maintenance_freepage_ratio, and TRUE.

Referenced by dt_cleanup(), and dt_init().

◆ dt_database_maybe_snapshot()

gboolean dt_database_maybe_snapshot ( void  )

check if creating database snapshot is recommended

Definition at line 4227 of file database.c.

References _db, _db_print, _is_mem_db(), _snapshot_policy_decides(), dt_database_t::dbfilename_library, dt_free, error(), FALSE, and IS_NULL_PTR.

Referenced by dt_cleanup().

◆ dt_database_open()

◆ dt_database_optimize()

void dt_database_optimize ( void  )

perform pre-db-close optimizations (always call when quiting darktable)

Definition at line 4050 of file database.c.

References _db, _is_mem_db(), DT_DEBUG_SQLITE3_EXEC, dt_database_t::handle, and IS_NULL_PTR.

Referenced by dt_cleanup().

◆ dt_database_perform_maintenance()

void dt_database_perform_maintenance ( void  )

◆ dt_database_release_transaction_debug()

◆ dt_database_rollback_transaction()

◆ dt_database_set_prompt_handler()

void dt_database_set_prompt_handler ( dt_database_prompt_handler_t  handler)

Install the handler the module asks through. NULL removes it.

Must be registered BEFORE dt_database_open() runs – which is before dt_gui_gtk_init(), so this one cannot go where the film/collection/folder-survey handlers go. darktable.c registers it, being the only thing that knows this early whether there will be a GUI.

With no handler, every prompt answers CLOSE: a corrupt database is not deleted or restored, and a schema is not migrated, on the strength of a question nobody was asked. That is also what makes a headless run safe – these dialogs used to be built unconditionally, with no has_gui guard, on a GTK that ansel-cli never initialises.

Definition at line 3062 of file database.c.

References _prompt_handler.

Referenced by dt_database_gui_register_handlers().

◆ dt_database_set_renamed_handler()

void dt_database_set_renamed_handler ( dt_database_renamed_handler_t  handler)

Definition at line 3627 of file database.c.

References _renamed_handler.

Referenced by dt_init().

◆ dt_database_set_settings()

◆ dt_database_settings_free()

void dt_database_settings_free ( dt_database_settings_t settings)

Release the strings owned by settings (not settings itself).

Definition at line 3711 of file database.c.

References dt_database_settings_t::create_snapshot, dt_free, IS_NULL_PTR, and dt_database_settings_t::maintenance_check.

Referenced by _snapshot_policy_decides(), dt_database_maybe_maintenance(), and dt_database_snaps_to_remove().

◆ dt_database_snaps_to_remove()

char ** dt_database_snaps_to_remove ( void  )

◆ dt_database_snapshot()

gboolean dt_database_snapshot ( void  )

◆ dt_database_start_transaction_debug()

◆ dt_database_take_error()

void dt_database_take_error ( dt_database_error_t error)

Move the pending error out of the module into error, clearing it. Consumes it: a second call reports no error.

Definition at line 2734 of file database.c.

References _db, error(), dt_database_t::error_dbfilename, dt_database_t::error_message, dt_database_t::error_other_pid, IS_NULL_PTR, and dt_database_t::lock_acquired.

Referenced by dt_database_show_error().

◆ pid_is_alive()

static gboolean pid_is_alive ( int  pid)
static

Definition at line 2784 of file database.c.

References dt_free, FALSE, pid_is_alive(), and TRUE.

Referenced by _lock_single_database(), and pid_is_alive().

Variable Documentation

◆ _db

◆ _db_lock

dt_pthread_rwlock_t _db_lock
static

Serialises the module's own work against dt_database_close().

It is a reader/writer lock rather than a mutex because that is the shape the workspace swap needs: every query takes it for reading and they proceed concurrently (sqlite is opened SERIALIZED and does its own internal locking), while closing takes it for writing and therefore waits for every in-flight query to finish.

Warning
It does NOT yet make dt_database_close() safe, and the module does not pretend otherwise. dt_database_get_sqlite3_global() hands the connection out to call sites that keep using it long after they returned, entirely outside this lock; until that count reaches zero the lock covers the module's own statements and nothing else. This is exactly why there is no dt_database_swap() yet – see src/database/README.md.

It used to live on darktable_t as database_threadsafe, reachable through common/global_mutexes.h by anything that cared to take it. Two functions in this file were its only users.

Definition at line 141 of file database.c.

Referenced by dt_database_begin_transaction_batch(), dt_database_close(), dt_database_end_transaction_batch(), dt_database_open(), dt_database_release_transaction_debug(), dt_database_rollback_transaction(), and dt_database_start_transaction_debug().

◆ _db_lock_inited

gboolean _db_lock_inited = FALSE
static

Definition at line 142 of file database.c.

Referenced by dt_database_close(), and dt_database_open().

◆ _has_gui

gboolean _has_gui = FALSE
static

Session constants, read once by the orchestrator and handed to dt_database_open().

Definition at line 152 of file database.c.

Referenced by _ask_for_maintenance(), and dt_database_open().

◆ _prompt_handler

dt_database_prompt_handler_t _prompt_handler = NULL
static

Definition at line 3060 of file database.c.

Referenced by _ask_user(), and dt_database_set_prompt_handler().

◆ _renamed_handler

dt_database_renamed_handler_t _renamed_handler = NULL
static

Told when the XDG migration renames the library out from under the configured name.

Definition at line 156 of file database.c.

Referenced by _database_migrate_to_xdg_structure(), and dt_database_set_renamed_handler().

◆ _settings

dt_database_settings_t _settings = { NULL, 0, NULL, 0 }
static

Maintenance and snapshot policy, told to us by the orchestrator. Guarded by _settings_lock, because the GUI thread replaces it while a maintenance decision may be reading it.

Definition at line 147 of file database.c.

Referenced by dt_database_get_settings(), and dt_database_set_settings().

◆ _settings_lock

dt_pthread_mutex_t _settings_lock
static

◆ _settings_lock_inited

gboolean _settings_lock_inited = FALSE
static

◆ _trx_batch_level

◆ _trx_batch_owner

◆ _trx_owner

◆ _trxid

◆ _verbose

gboolean _verbose = FALSE
static

Definition at line 153 of file database.c.

Referenced by dt_database_open().