Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
colorlabel_repository.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2026 Aurélien PIERRE.
4
5 darktable is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 darktable is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with darktable. If not, see <http://www.gnu.org/licenses/>.
17*/
18
20
21#include "database/database.h"
22#include "database/sql_debug.h"
23#include "system/macros.h"
24
25#include <sqlite3.h>
26
27/* Every statement is prepared and finalised per call. These four were cached "because the
28 * lighttable asks for an image's labels on every thumbnail" -- that stopped being true when
29 * the thumbtable moved to one bulk query computing the label mask inline; the remaining
30 * callers run at import/click frequency, and an unlocked cached statement shared between
31 * the GUI thread and worker jobs is a data race, not an optimisation. */
38
39int dt_colorlabel_repository_get(const int32_t imgid)
40{
41 sqlite3_stmt *stmt = _prepared("SELECT color FROM main.color_labels WHERE imgid = ?1");
42 if(IS_NULL_PTR(stmt)) return 0;
44
45 int colors = 0;
46 // Colors are int between 0 and 5, turn them into octal bitmask
48 colors |= (1 << sqlite3_column_int(stmt, 0));
50
51 return colors;
52}
53
54void dt_colorlabel_repository_set(const int32_t imgid, const int color)
55{
56 sqlite3_stmt *stmt = _prepared("INSERT OR IGNORE INTO main.color_labels (imgid, color) VALUES (?1, ?2)");
57 if(IS_NULL_PTR(stmt)) return;
62}
63
64void dt_colorlabel_repository_remove(const int32_t imgid, const int color)
65{
66 sqlite3_stmt *stmt = _prepared("DELETE FROM main.color_labels WHERE imgid=?1 AND color=?2");
67 if(IS_NULL_PTR(stmt)) return;
72}
73
74void dt_colorlabel_repository_remove_all(const int32_t imgid)
75{
76 sqlite3_stmt *stmt = _prepared("DELETE FROM main.color_labels WHERE imgid=?1");
77 if(IS_NULL_PTR(stmt)) return;
81}
82
83gboolean dt_colorlabel_repository_has(const int32_t imgid, const int color)
84{
85 if(imgid <= 0) return FALSE;
86
87 /* Not cached: this one is asked once per user action, not once per thumbnail. */
89 // clang-format off
91 "SELECT * FROM main.color_labels WHERE imgid=?1 AND color=?2 LIMIT 1",
92 -1, &stmt, NULL);
93 // clang-format on
96
97 const gboolean found = (sqlite3_step(stmt) == SQLITE_ROW);
99 return found;
100}
101
103{
105
106 if(imgid < 0)
107 {
108 /* No ORDER BY on this branch and ORDER BY color on the other. That asymmetry is
109 * inherited from dt_metadata_get(); ordering a selection by colour would group the
110 * same colour from different images together, which is not what the caller counts. */
111 // clang-format off
113 "SELECT color FROM main.color_labels WHERE imgid IN "
114 "(SELECT imgid FROM main.selected_images)",
115 -1, &stmt, NULL);
116 // clang-format on
117 }
118 else
119 {
120 // clang-format off
122 "SELECT color FROM main.color_labels WHERE imgid=?1 ORDER BY color",
123 -1, &stmt, NULL);
124 // clang-format on
126 }
127
128 GList *result = NULL;
129 while(sqlite3_step(stmt) == SQLITE_ROW)
132
133 return g_list_reverse(result);
134}
135
136void dt_colorlabel_repository_foreach(const int32_t imgid, void (*cb)(void *, const int),
137 void *user_data)
138{
139 if(!cb) return;
140
142 DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get_sqlite3_global(), "SELECT color FROM main.color_labels WHERE imgid=?1",
143 -1, &stmt, NULL);
145 while(sqlite3_step(stmt) == SQLITE_ROW)
146 cb(user_data, sqlite3_column_int(stmt, 0));
148}
149
151{
152 /* Nothing cached any more: every statement in this file is prepared and finalised per
153 * call. Kept because the connection's close order calls every repository's cleanup. */
154}
155
156// clang-format off
157// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
158// vim: shiftwidth=2 expandtab tabstop=2 cindent
159// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
160// clang-format on
#define FALSE
Definition ashift_lsd.c:158
gboolean dt_colorlabel_repository_has(const int32_t imgid, const int color)
TRUE when colour color is set on imgid.
void dt_colorlabel_repository_remove_all(const int32_t imgid)
Clear every colour on imgid.
void dt_colorlabel_repository_remove(const int32_t imgid, const int color)
Clear colour color on imgid. Clearing one that is not set does nothing.
void dt_colorlabel_repository_set(const int32_t imgid, const int color)
Set colour color on imgid. Setting one that is already set does nothing.
static sqlite3_stmt * _prepared(const char *query)
GList * dt_colorlabel_repository_get_list(const int32_t imgid)
The colours set on imgid, as a list rather than a bitmask.
int dt_colorlabel_repository_get(const int32_t imgid)
The colours set on imgid, as a bitmask: bit c is set when colour c is.
void dt_colorlabel_repository_foreach(const int32_t imgid, void(*cb)(void *, const int), void *user_data)
Every colour label of imgid, one call per row, in the order the rows come back.
void dt_colorlabel_repository_cleanup(void)
Finalise whatever this repository still caches – today, nothing.
main.color_labels: which of the five colour labels are set on an image.
sqlite3 * dt_database_get_sqlite3_global(void)
Definition database.c:3753
const dt_collection_filter_flag_t colors[6]
Definition filter.c:301
GdkRGBA color[]
Definition geotagging.c:539
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:65
Checked wrappers around the sqlite3_* calls: trace the statement, assert the return code,...
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
Definition sql_debug.h:137
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
Definition sql_debug.h:145