Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
history_repository.c File Reference
#include <float.h>
#include <math.h>
#include <string.h>
#include "database/history_repository.h"
#include "database/database.h"
#include "database/sql_debug.h"
#include "system/dtpthread.h"
#include "system/macros.h"
#include "system/mem_alloc.h"
+ Include dependency graph for history_repository.c:

Go to the source code of this file.

Functions

static void _history_stmt_mutex_ensure (void)
 
int32_t dt_history_repository_get_end (const int32_t imgid)
 
gboolean dt_history_repository_set_end (const int32_t imgid, const int32_t history_end)
 
int32_t dt_history_repository_get_next_num (const int32_t imgid)
 
gboolean dt_history_repository_shift_nums (const int32_t imgid, const int delta)
 
gboolean dt_history_repository_write_item (const int32_t imgid, const int num, const char *operation, const void *op_params, const int op_params_size, const int module_version, const gboolean enabled, const void *blendop_params, const int blendop_params_size, const int blendop_version, const int multi_priority, const char *multi_name)
 
gboolean dt_history_repository_delete_history (const int32_t imgid)
 
gboolean dt_history_repository_delete_masks_history (const int32_t imgid)
 
gboolean dt_history_repository_delete_dev_history (const int32_t imgid)
 
void dt_history_repository_foreach_row (const int32_t imgid, dt_history_repository_row_cb cb, void *user_data)
 
void dt_history_repository_foreach_auto_preset_row (const int32_t imgid, const dt_image_t *image, const char *workflow_preset, const int iformat, const int excluded, dt_history_repository_row_cb cb, void *user_data)
 
gboolean dt_history_repository_get_autoapply_ioporder_params (const int32_t imgid, const dt_image_t *image, const int iformat, const int excluded, void **params, int32_t *params_len)
 
int dt_history_repository_count_items (const int32_t imgid)
 
gboolean dt_history_repository_get_last_enabled_params (const int32_t imgid, const char *operation, void **params, int32_t *params_len)
 
gboolean dt_history_repository_module_exists (const int32_t imgid, const char *operation)
 
gboolean dt_history_repository_delete_all_for_image (const int32_t imgid)
 
void dt_history_repository_foreach_last_item (const int32_t imgid, const gboolean enabled, dt_history_repository_item_cb cb, void *user_data)
 
void dt_history_repository_foreach_item (const int32_t imgid, dt_history_repository_item_cb cb, void *user_data)
 
gboolean dt_history_repository_write_mask_item (const int32_t imgid, const int num, const int formid, const int form, const char *name, const int version, const void *points, const int points_len, const int points_count, const void *source, const int source_len)
 
int dt_history_repository_count_mask_items (const int32_t imgid)
 
void dt_history_repository_foreach_mask_item (const int32_t imgid, dt_history_repository_mask_cb cb, void *user_data)
 
int dt_history_repository_find_version_for_params (const char *operation, const void *op_params, const int op_params_size)
 The module version some image's history recorded for this exact parameter blob.
 
void dt_history_repository_foreach_active_module (const int32_t imgid, dt_history_repository_active_module_cb cb, void *user_data)
 Every module an image has enabled, once each, in the order they run.
 
gboolean dt_history_repository_get_module_order_version (const int32_t imgid, int *version)
 imgid's stored order version.
 
gboolean dt_history_repository_has_module_order (const int32_t imgid)
 Whether imgid has a main.module_order row at all, whatever it says.
 
gboolean dt_history_repository_get_module_order (const int32_t imgid, dt_module_order_row_t *row)
 Read imgid's row. FALSE when there is none, and row is then left zeroed.
 
gboolean dt_history_repository_has_custom_module_order (const int32_t imgid)
 Whether imgid's row stores a serialized list, i.e. iop_list IS NOT NULL.
 
void dt_module_order_row_cleanup (dt_module_order_row_t *row)
 Release what dt_history_repository_get_module_order() allocated.
 
gboolean dt_history_repository_set_module_order (const int32_t imgid, const int version, const char *iop_list)
 Store imgid's order: version, and iop_list serialized or NULL.
 
void dt_history_repository_cleanup (void)
 

Variables

static sqlite3_stmt_history_check_module_exists_stmt = NULL
 
static sqlite3_stmt_history_count_items_stmt = NULL
 
static sqlite3_stmt_history_get_end_stmt = NULL
 
static sqlite3_stmt_history_set_end_stmt = NULL
 
static sqlite3_stmt_history_get_next_num_stmt = NULL
 
static sqlite3_stmt_history_delete_history_stmt = NULL
 
static sqlite3_stmt_history_delete_masks_stmt = NULL
 
static sqlite3_stmt_history_shift_history_nums_stmt = NULL
 
static sqlite3_stmt_history_select_history_stmt = NULL
 
static sqlite3_stmt_history_select_num_stmt = NULL
 
static sqlite3_stmt_history_insert_num_stmt = NULL
 
static sqlite3_stmt_history_update_item_stmt = NULL
 
static sqlite3_stmt_history_auto_presets_stmt = NULL
 
static sqlite3_stmt_history_auto_presets_legacy_stmt = NULL
 
static sqlite3_stmt_history_auto_ioporder_stmt = NULL
 
static sqlite3_stmt_module_order_select_stmt = NULL
 
static sqlite3_stmt_module_order_select_version_stmt = NULL
 
static sqlite3_stmt_module_order_insert_stmt = NULL
 
static sqlite3_stmt_module_order_update_list_stmt = NULL
 
static sqlite3_stmt_module_order_update_null_stmt = NULL
 
static dt_pthread_mutex_t _history_stmt_mutex
 
static gsize _history_stmt_mutex_inited = 0
 

Function Documentation

◆ _history_stmt_mutex_ensure()

◆ dt_history_repository_cleanup()

◆ dt_history_repository_count_items()

int dt_history_repository_count_items ( const int32_t  imgid)

how many history items an image has – 0 means "never developed", which is what the "altered" indicator and the embedded-JPEG-vs-raw thumbnail decision both read

Definition at line 470 of file history_repository.c.

References _history_count_items_stmt, _history_stmt_mutex, _history_stmt_mutex_ensure(), dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), IS_NULL_PTR, and L.

Referenced by dt_image_altered(), and test_history_item_cycle().

◆ dt_history_repository_count_mask_items()

int dt_history_repository_count_mask_items ( const int32_t  imgid)

how many mask rows an image has

Definition at line 696 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, and L.

Referenced by dt_exif_xmp_read().

◆ dt_history_repository_delete_all_for_image()

gboolean dt_history_repository_delete_all_for_image ( const int32_t  imgid)

everything an image's development is stored in: history, module_order, masks_history, history_hash, and the history_end / aspect_ratio reset on the image row itself.

Definition at line 562 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, FALSE, L, and TRUE.

Referenced by dt_history_delete_on_image_ext().

◆ dt_history_repository_delete_dev_history()

gboolean dt_history_repository_delete_dev_history ( const int32_t  imgid)

history + masks_history, the pair a development is made of

Definition at line 273 of file history_repository.c.

References dt_history_repository_delete_history(), dt_history_repository_delete_masks_history(), FALSE, and TRUE.

Referenced by _cleanup_history().

◆ dt_history_repository_delete_history()

◆ dt_history_repository_delete_masks_history()

◆ dt_history_repository_find_version_for_params()

int dt_history_repository_find_version_for_params ( const char *  operation,
const void op_params,
const int  op_params_size 
)

The module version some image's history recorded for this exact parameter blob.

A preset with no version of its own can be dated by finding a history entry anywhere in the library that carries byte-identical parameters – that entry knows which version wrote them. Searches every image, so the first match wins arbitrarily; the blobs are equal, which is what makes that acceptable.

Returns
the version, or 0 when no history entry matches.

Definition at line 736 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_BLOB, DT_DEBUG_SQLITE3_BIND_TEXT, DT_DEBUG_SQLITE3_PREPARE_V2, IS_NULL_PTR, and L.

Referenced by _init_presets(), and test_find_version_for_params().

◆ dt_history_repository_foreach_active_module()

void dt_history_repository_foreach_active_module ( const int32_t  imgid,
dt_history_repository_active_module_cb  cb,
void user_data 
)

Every module an image has enabled, once each, in the order they run.

Grouped by (operation, multi_name) and ordered by the lowest num of each group, so a module edited ten times appears once, at the position of its first appearance.

Definition at line 754 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, IS_NULL_PTR, and L.

Referenced by _active_modules_popup(), and test_foreach_active_module().

◆ dt_history_repository_foreach_auto_preset_row()

◆ dt_history_repository_foreach_item()

void dt_history_repository_foreach_item ( const int32_t  imgid,
dt_history_repository_item_cb  cb,
void user_data 
)

every stored item, newest first, duplicates included

Definition at line 645 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, IS_NULL_PTR, and L.

Referenced by dt_history_get_items_as_string().

◆ dt_history_repository_foreach_last_item()

void dt_history_repository_foreach_last_item ( const int32_t  imgid,
const gboolean  enabled,
dt_history_repository_item_cb  cb,
void user_data 
)

the latest item per (operation, multi_priority) – i.e. one row per module instance, carrying its final state. enabled FALSE also returns disabled items.

Definition at line 614 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, IS_NULL_PTR, and L.

Referenced by dt_history_get_items().

◆ dt_history_repository_foreach_mask_item()

void dt_history_repository_foreach_mask_item ( const int32_t  imgid,
dt_history_repository_mask_cb  cb,
void user_data 
)

every mask row of an image, in num order

Definition at line 710 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, IS_NULL_PTR, and L.

Referenced by dt_masks_read_masks_history(), and dt_set_xmp_dt_history().

◆ dt_history_repository_foreach_row()

◆ dt_history_repository_get_autoapply_ioporder_params()

◆ dt_history_repository_get_end()

int32_t dt_history_repository_get_end ( const int32_t  imgid)

The main.history, main.masks_history, main.module_order and main.history_hash tables, plus the two auto-apply queries that read data.presets / main.legacy_presets to seed a new image's history.

The hot statements (the per-image read/write cycle) are prepared once, cached, and used only under this file's statement mutex; dt_history_repository_cleanup() finalises them, which the connection must be able to do before it closes. The rest prepare and finalise per call. Rows never leave as a sqlite3_stmt – the foreach families decode each row into scalars and hand those to a callback.

Warning
dt_history_repository_foreach_row() and dt_history_repository_foreach_auto_preset_row() step a CACHED statement and therefore hold the statement mutex across every callback invocation. The mutex is not recursive: a callback that calls back into this repository deadlocks its own thread. Today's callbacks only decode; keep it that way, or move those two walks to per-call statements first. read history_end for an image; 0 for an invalid imgid or a NULL column

Definition at line 78 of file history_repository.c.

References _history_get_end_stmt, _history_stmt_mutex, _history_stmt_mutex_ensure(), dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), and L.

Referenced by dt_dev_read_history_ext(), dt_history_snapshot_undo_create(), and test_history_item_cycle().

◆ dt_history_repository_get_last_enabled_params()

gboolean dt_history_repository_get_last_enabled_params ( const int32_t  imgid,
const char *  operation,
void **  params,
int32_t *  params_len 
)

the params blob and enabled flag of the LAST history item for operation, or FALSE if the image has none. *params is a copy the caller owns; only written when the item exists AND is enabled, because that is the only case its one consumer acts on.

Definition at line 494 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_BIND_TEXT, DT_DEBUG_SQLITE3_PREPARE_V2, FALSE, IS_NULL_PTR, L, and TRUE.

Referenced by _image_get_history_orientation().

◆ dt_history_repository_get_module_order()

◆ dt_history_repository_get_module_order_version()

gboolean dt_history_repository_get_module_order_version ( const int32_t  imgid,
int *  version 
)

imgid's stored order version.

Returns
FALSE when the image has no row, leaving version untouched. That is the caller's cue to derive a default rather than trust a zero.

Definition at line 780 of file history_repository.c.

References _history_stmt_mutex, _history_stmt_mutex_ensure(), _module_order_select_version_stmt, dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_PREPARE_V2, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, IS_NULL_PTR, and L.

Referenced by dt_history_repository_has_module_order(), dt_ioppr_get_iop_order_version(), and test_module_order_absent_vs_zero().

◆ dt_history_repository_get_next_num()

◆ dt_history_repository_has_custom_module_order()

gboolean dt_history_repository_has_custom_module_order ( const int32_t  imgid)

Whether imgid's row stores a serialized list, i.e. iop_list IS NOT NULL.

Definition at line 849 of file history_repository.c.

References dt_history_repository_get_module_order(), dt_module_order_row_cleanup(), IS_NULL_PTR, L, and row.

Referenced by dt_ioppr_has_iop_order_list(), and test_module_order_absent_vs_zero().

◆ dt_history_repository_has_module_order()

gboolean dt_history_repository_has_module_order ( const int32_t  imgid)

Whether imgid has a main.module_order row at all, whatever it says.

Same table and same predicate as dt_history_repository_get_module_order_version(); it just discards the value.

Definition at line 803 of file history_repository.c.

References dt_history_repository_get_module_order_version().

Referenced by dt_ioppr_set_default_iop_order(), and test_module_order_absent_vs_zero().

◆ dt_history_repository_module_exists()

gboolean dt_history_repository_module_exists ( const int32_t  imgid,
const char *  operation 
)

◆ dt_history_repository_set_end()

◆ dt_history_repository_set_module_order()

gboolean dt_history_repository_set_module_order ( const int32_t  imgid,
const int  version,
const char *  iop_list 
)

Store imgid's order: version, and iop_list serialized or NULL.

Two statements, as the caller's own two-step was: INSERT OR REPLACE a bare row so that one exists, then UPDATE it. Kept that shape rather than collapsed into a single INSERT OR REPLACE carrying the values, because the row this replaces is deleted either way and the cascade that follows is worth leaving exactly where it was.

Definition at line 865 of file history_repository.c.

References _history_stmt_mutex, _history_stmt_mutex_ensure(), _module_order_insert_stmt, _module_order_update_list_stmt, _module_order_update_null_stmt, dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_BIND_TEXT, DT_DEBUG_SQLITE3_PREPARE_V2, dt_pthread_mutex_lock(), dt_pthread_mutex_unlock(), FALSE, IS_NULL_PTR, and L.

Referenced by dt_ioppr_write_iop_order(), and test_module_order_absent_vs_zero().

◆ dt_history_repository_shift_nums()

gboolean dt_history_repository_shift_nums ( const int32_t  imgid,
const int  delta 
)

◆ dt_history_repository_write_item()

gboolean dt_history_repository_write_item ( const int32_t  imgid,
const int  num,
const char *  operation,
const void op_params,
const int  op_params_size,
const int  module_version,
const gboolean  enabled,
const void blendop_params,
const int  blendop_params_size,
const int  blendop_version,
const int  multi_priority,
const char *  multi_name 
)

◆ dt_history_repository_write_mask_item()

gboolean dt_history_repository_write_mask_item ( const int32_t  imgid,
const int  num,
const int  formid,
const int  form,
const char *  name,
const int  version,
const void points,
const int  points_len,
const int  points_count,
const void source,
const int  source_len 
)

append one mask row. TRUE when the INSERT ran to completion.

Both callers act on this: common/exif.cc's add_mask_entry_to_db() marks the entry already-added on success (its "insert once" guard used to test sqlite3_step() against a value an INSERT cannot return, and never fired – fixed alongside the extraction), and develop/masks/masks.c writes each form through it.

Definition at line 667 of file history_repository.c.

References dt_database_get_sqlite3_global(), DT_DEBUG_SQLITE3_BIND_BLOB, DT_DEBUG_SQLITE3_BIND_INT, DT_DEBUG_SQLITE3_BIND_TEXT, DT_DEBUG_SQLITE3_PREPARE_V2, L, and name.

Referenced by add_mask_entry_to_db(), and dt_masks_write_masks_history_item().

◆ dt_module_order_row_cleanup()

Variable Documentation

◆ _history_auto_ioporder_stmt

sqlite3_stmt* _history_auto_ioporder_stmt = NULL
static

◆ _history_auto_presets_legacy_stmt

sqlite3_stmt* _history_auto_presets_legacy_stmt = NULL
static

◆ _history_auto_presets_stmt

sqlite3_stmt* _history_auto_presets_stmt = NULL
static

◆ _history_check_module_exists_stmt

sqlite3_stmt* _history_check_module_exists_stmt = NULL
static

◆ _history_count_items_stmt

sqlite3_stmt* _history_count_items_stmt = NULL
static

◆ _history_delete_history_stmt

sqlite3_stmt* _history_delete_history_stmt = NULL
static

◆ _history_delete_masks_stmt

sqlite3_stmt* _history_delete_masks_stmt = NULL
static

◆ _history_get_end_stmt

sqlite3_stmt* _history_get_end_stmt = NULL
static

◆ _history_get_next_num_stmt

sqlite3_stmt* _history_get_next_num_stmt = NULL
static

◆ _history_insert_num_stmt

sqlite3_stmt* _history_insert_num_stmt = NULL
static

◆ _history_select_history_stmt

sqlite3_stmt* _history_select_history_stmt = NULL
static

◆ _history_select_num_stmt

sqlite3_stmt* _history_select_num_stmt = NULL
static

◆ _history_set_end_stmt

sqlite3_stmt* _history_set_end_stmt = NULL
static

◆ _history_shift_history_nums_stmt

sqlite3_stmt* _history_shift_history_nums_stmt = NULL
static

◆ _history_stmt_mutex

◆ _history_stmt_mutex_inited

gsize _history_stmt_mutex_inited = 0
static

Definition at line 65 of file history_repository.c.

Referenced by _history_stmt_mutex_ensure().

◆ _history_update_item_stmt

sqlite3_stmt* _history_update_item_stmt = NULL
static

◆ _module_order_insert_stmt

sqlite3_stmt* _module_order_insert_stmt = NULL
static

◆ _module_order_select_stmt

sqlite3_stmt* _module_order_select_stmt = NULL
static

◆ _module_order_select_version_stmt

sqlite3_stmt* _module_order_select_version_stmt = NULL
static

◆ _module_order_update_list_stmt

sqlite3_stmt* _module_order_update_list_stmt = NULL
static

◆ _module_order_update_null_stmt

sqlite3_stmt* _module_order_update_null_stmt = NULL
static