53#define LIMIT_QUERY "LIMIT ?1, ?2"
57#define and_operator_initial() (0)
74#define or_operator_initial() (0)
124 const gboolean recursive)
145 query =
g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s%%'))",
166 query =
g_strdup_printf(
"(film_id IN (SELECT id FROM main.film_rolls WHERE folder LIKE '%s' OR folder LIKE '%s"
195 query =
g_strdup_printf(
"(id IN (SELECT imgid FROM main.color_labels WHERE color IS NOT NULL))");
221 query =
g_strdup(
"EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = id)");
225 query =
g_strdup(
"NOT EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = id)");
253 "WHERE (longitude IS NOT NULL AND latitude IS NOT NULL))) ",
259 "WHERE (longitude IS NOT NULL AND latitude IS NOT NULL))"
260 "AND id %s IN (SELECT imgid FROM main.tagged_images AS ti"
261 " JOIN data.tags AS t"
262 " ON t.id = ti.tagid"
305 "WHERE tagid NOT IN memory.darktable_tags))");
317 "(SELECT id FROM data.tags "
318 "WHERE LOWER(name) = LOWER('%s')"
319 " OR SUBSTR(LOWER(name), 1, LENGTH('%s') + 1) = LOWER('%s|'))))",
329 "(SELECT id FROM data.tags WHERE SUBSTR(LOWER(name), 1, LENGTH('%s')) = LOWER('%s'))))",
338 "(SELECT id FROM data.tags WHERE LOWER(name) = LOWER('%s'))))",
355 if(
operator &&
strcmp(
operator,
"[]") == 0)
380 if(
operator &&
strcmp(
operator,
"[]") == 0)
403 if(
operator &&
strcmp(
operator,
"[]") == 0)
429 if(
operator &&
strcmp(
operator,
"[]") == 0)
441 query =
g_strdup_printf(
"(CASE WHEN exposure < 0.4 THEN ((exposure >= %s - 1.0/100000) AND (exposure <= %s + 1.0/100000)) "
442 "ELSE (ROUND(exposure,2) >= %s - 1.0/100000) AND (ROUND(exposure,2) <= %s + 1.0/100000) END)",
460 char *
name = (
char*)l->data;
499 if(
strcmp(
operator,
"[]") == 0)
529 "JOIN memory.darktable_iop_names AS m ON m.operation = h.operation "
530 "WHERE h.enabled = 1 AND m.name LIKE '%s'))",
escaped_text);
556 if(
operator &&
strcmp(
operator,
"[]") == 0)
691 const uint32_t tagid =
_tagid;
692 char tag[16] = { 0 };
693 snprintf(tag,
sizeof(tag),
"%u", tagid);
697 "SELECT DISTINCT mi.id FROM (SELECT"
698 " id, group_id, film_id, filename, datetime_taken, "
699 " flags, version, aspect_ratio,"
700 " maker, model, lens, aperture, exposure, focal_length,"
701 " iso, import_timestamp, change_timestamp,"
702 " export_timestamp, print_timestamp"
703 " FROM main.images AS mi %s%s WHERE ",
704 tagid ?
" LEFT JOIN main.tagged_images AS ti"
705 " ON ti.imgid = mi.id AND ti.tagid = " :
"",
742 sq =
g_strdup_printf(
"ORDER BY CASE WHEN flags & 8 = 8 THEN -1 ELSE flags & 7 END %s", order);
793 sq =
dt_util_dstrcat(
sq,
", group_id ASC, mi.id-group_id != 0, filename ASC, version ASC, mi.id ASC");
893 " UNION SELECT imgid AS id FROM main.tagged_images AS ti, data.tags AS t"
894 " WHERE t.id=ti.tagid AND (t.name LIKE '%s' OR t.synonyms LIKE '%s')"
895 " UNION SELECT id FROM main.images"
896 " WHERE filename LIKE '%s'"
897 " UNION SELECT i.id FROM main.images AS i, main.film_rolls AS fr"
898 " WHERE fr.id=i.film_id AND fr.folder LIKE '%s')",
934 " (SELECT imgid AS id, SUM(1 << color) AS mask FROM main.color_labels GROUP BY imgid)"
935 " WHERE ((mask & %i) > 0))",
940 " (SELECT imgid AS id, SUM(1 << color) AS mask FROM main.color_labels GROUP BY imgid)"
941 " WHERE ((mask & 31) > 0))",
981 ") AS mi JOIN (SELECT id AS film_rolls_id, folder FROM main.film_rolls) ON film_id = film_rolls_id");
996 const uint32_t tagid =
_tagid;
997 char tag[16] = { 0 };
998 snprintf(tag,
sizeof(tag),
"%u", tagid);
1001 "SELECT DISTINCT mi.id FROM (SELECT"
1002 " id, group_id, film_id, filename, datetime_taken, "
1003 " flags, version, %s position, aspect_ratio,"
1004 " maker, model, lens, aperture, exposure, focal_length,"
1005 " iso, import_timestamp, change_timestamp,"
1006 " export_timestamp, print_timestamp"
1007 " FROM main.images AS mi %s%s ) AS mi ",
1008 tagid ?
"CASE WHEN ti.position IS NULL THEN 0 ELSE ti.position END AS" :
"",
1009 tagid ?
" LEFT JOIN main.tagged_images AS ti"
1010 " ON ti.imgid = mi.id AND ti.tagid = " :
"",
1016 const uint32_t tagid =
_tagid;
1017 char tag[16] = { 0 };
1018 snprintf(tag,
sizeof(tag),
"%u", tagid);
1021 "SELECT DISTINCT mi.id FROM (SELECT"
1022 " id, group_id, film_id, filename, datetime_taken, "
1023 " flags, version, %s position, aspect_ratio,"
1024 " maker, model, lens, aperture, exposure, focal_length,"
1025 " iso, import_timestamp, change_timestamp,"
1026 " export_timestamp, print_timestamp"
1027 " FROM main.images AS mi %s%s ) AS mi WHERE ",
1028 tagid ?
"CASE WHEN ti.position IS NULL THEN 0 ELSE ti.position END AS" :
"",
1029 tagid ?
" LEFT JOIN main.tagged_images AS ti"
1030 " ON ti.imgid = mi.id AND ti.tagid = " :
"",
1064 "SELECT COUNT(DISTINCT imgid) from memory.collected_images",
1087 static const char *
const conj[] = {
"AND",
"OR",
"AND NOT" };
1090 for(
int i = 0;
i < n_rules;
i++)
1093 const int mode =
CLAMP(
r->mode, 0, 2);
1111 const uint32_t tagid)
1144 "INSERT INTO memory.darktable_iop_names (operation, name) VALUES (?1, ?2)",
1149 for(
size_t i = 0;
i < count;
i++)
1177 " WHERE group_id = %d AND id IN (%s)",
1204 gchar *
q =
g_strdup_printf(
"SELECT maker, model, COUNT(*) AS count FROM main.images AS mi"
1205 " WHERE %s GROUP BY maker, model",
where_ext);
1235 " FROM main.images AS mi"
1236 " JOIN (SELECT fr.id AS film_rolls_id, folder, status"
1237 " FROM main.film_rolls AS fr"
1238 " JOIN memory.film_folder AS ff ON fr.id = ff.id)"
1239 " ON film_id = film_rolls_id"
1240 " WHERE %s GROUP BY folder, film_rolls_id",
where_ext);
1245 " FROM (SELECT tagid, COUNT(*) as count"
1246 " FROM main.images AS mi JOIN main.tagged_images ON id = imgid"
1247 " WHERE %s GROUP BY tagid)"
1248 " JOIN (SELECT name, id AS tag_id FROM data.tags)"
1249 " ON tagid = tag_id GROUP BY name",
where_ext);
1251 "SELECT '%s' AS name, 0 as id, COUNT(*) AS count "
1252 "FROM main.images AS mi WHERE mi.id NOT IN"
1253 " (SELECT DISTINCT imgid FROM main.tagged_images AS ti"
1254 " WHERE ti.tagid NOT IN memory.darktable_tags)",
1259 query =
g_strdup_printf(
"SELECT CASE WHEN mi.longitude IS NULL OR mi.latitude IS null THEN '%s'"
1260 " ELSE CASE WHEN ta.imgid IS NULL THEN '%s' ELSE '%s' || ta.tagname END"
1261 " END AS name, ta.tagid AS tag_id, COUNT(*) AS count"
1262 " FROM main.images AS mi"
1263 " LEFT JOIN (SELECT imgid, t.id AS tagid, SUBSTR(t.name, %d) AS tagname"
1264 " FROM main.tagged_images AS ti JOIN data.tags AS t ON ti.tagid = t.id"
1265 " JOIN data.locations AS l ON l.tagid = t.id) AS ta ON ta.imgid = mi.id"
1266 " WHERE %s GROUP BY name, tag_id",
1267 _(
"not tagged"),
_(
"tagged"),
_(
"tagged"),
1272 query =
g_strdup_printf(
"SELECT (datetime_taken / 86400000000) * 86400000000 AS date, 1, COUNT(*) AS count"
1273 " FROM main.images AS mi"
1274 " WHERE datetime_taken IS NOT NULL AND datetime_taken <> 0 AND %s"
1295 " WHERE %s IS NOT NULL AND %s <> 0 AND %s GROUP BY date",
1301 query =
g_strdup_printf(
"SELECT CASE WHEN EXISTS (SELECT 1 FROM main.history h WHERE h.imgid = mi.id)"
1302 " THEN '%s' ELSE '%s' END as altered, 1, COUNT(*) AS count"
1303 " FROM main.images AS mi WHERE %s GROUP BY altered ORDER BY altered ASC",
1308 query =
g_strdup_printf(
"SELECT CASE WHEN (flags & %d) THEN '%s' ELSE '%s' END as lcp, 1, COUNT(*) AS count"
1309 " FROM main.images AS mi WHERE %s GROUP BY lcp ORDER BY lcp ASC",
1315 " WHEN 3 THEN '%s' WHEN 4 THEN '%s' ELSE '' END, color, COUNT(*) AS count"
1316 " FROM main.images AS mi"
1317 " JOIN (SELECT imgid AS color_labels_id, color FROM main.color_labels)"
1318 " ON id = color_labels_id WHERE %s GROUP BY color ORDER BY color DESC",
1319 _(
"red"),
_(
"yellow"),
_(
"green"),
_(
"blue"),
_(
"purple"),
where_ext);
1324 " GROUP BY lens ORDER BY lens",
where_ext);
1328 query =
g_strdup_printf(
"SELECT CAST(focal_length AS INTEGER) AS focal_length, 1, COUNT(*) AS count"
1329 " FROM main.images AS mi WHERE %s GROUP BY CAST(focal_length AS INTEGER)"
1330 " ORDER BY CAST(focal_length AS INTEGER)",
where_ext);
1335 " FROM main.images AS mi WHERE %s GROUP BY iso ORDER BY iso",
where_ext);
1340 " FROM main.images AS mi WHERE %s GROUP BY aperture ORDER BY aperture",
where_ext);
1344 query =
g_strdup_printf(
"SELECT CASE WHEN (exposure < 0.4) THEN '1/' || CAST(1/exposure + 0.9 AS INTEGER)"
1345 " ELSE ROUND(exposure,2) || '\"' END as _exposure, 1, COUNT(*) AS count"
1346 " FROM main.images AS mi WHERE %s GROUP BY _exposure ORDER BY exposure",
where_ext);
1350 query =
g_strdup_printf(
"SELECT filename, 1, COUNT(*) AS count FROM main.images AS mi WHERE %s"
1351 " GROUP BY filename ORDER BY filename",
where_ext);
1355 query =
g_strdup_printf(
"SELECT CASE WHEN id = group_id THEN '%s' ELSE '%s' END as group_leader, 1,"
1356 " COUNT(*) AS count FROM main.images AS mi WHERE %s"
1357 " GROUP BY group_leader ORDER BY group_leader ASC",
1358 _(
"group leaders"),
_(
"group followers"),
where_ext);
1362 query =
g_strdup_printf(
"SELECT m.name AS module_name, 1, COUNT(*) AS count FROM main.images AS mi"
1363 " JOIN (SELECT DISTINCT imgid, operation FROM main.history WHERE enabled = 1) AS h"
1364 " ON h.imgid = mi.id JOIN memory.darktable_iop_names AS m"
1365 " ON m.operation = h.operation WHERE %s GROUP BY module_name ORDER BY module_name",
1375 query =
g_strdup_printf(
"SELECT CASE %s END as ver, 1, COUNT(*) AS count FROM main.images AS mi"
1376 " LEFT JOIN (SELECT imgid, version FROM main.module_order) mo ON mo.imgid = mi.id"
1383 query =
g_strdup_printf(
"SELECT CASE WHEN (flags & 8) == 8 THEN -1 ELSE (flags & 7) END AS rating, 1,"
1384 " COUNT(*) AS count FROM main.images AS mi WHERE %s GROUP BY rating ORDER BY rating",
1393 if(!
req->metadata_hidden)
1395 " COUNT(*) AS count, CASE WHEN value IS NULL THEN 0 ELSE 1 END AS force_order"
1396 " FROM main.images AS mi"
1397 " LEFT JOIN (SELECT id AS meta_data_id, value FROM main.meta_data WHERE key = %d)"
1398 " ON id = meta_data_id WHERE %s GROUP BY value ORDER BY force_order, value",
1405 query =
g_strdup_printf(
"SELECT folder, film_rolls_id, COUNT(*) AS count, status FROM main.images AS mi"
1406 " JOIN (SELECT fr.id AS film_rolls_id, folder, status FROM main.film_rolls AS fr"
1407 " JOIN memory.film_folder AS ff ON ff.id = fr.id) ON film_id = film_rolls_id"
1451 if (filter && filter[0] !=
'\0')
1461 "SELECT maker, model FROM main.images GROUP BY maker, model",
1552 " FROM memory.collected_images"
1553 " WHERE imgid NOT IN (%s)"
1554 " AND rowid > (SELECT rowid"
1555 " FROM memory.collected_images"
1556 " WHERE imgid IN (%s)"
1557 " ORDER BY rowid LIMIT 1)"
1558 " ORDER BY rowid LIMIT 1",
1574 " FROM memory.collected_images"
1575 " WHERE imgid NOT IN (%s)"
1576 " AND rowid < (SELECT rowid"
1577 " FROM memory.collected_images"
1578 " WHERE imgid IN (%s)"
1579 " ORDER BY rowid LIMIT 1)"
1580 " ORDER BY rowid DESC LIMIT 1",
1622 "DELETE FROM memory.collected_images",
1626 "DELETE FROM memory.sqlite_sequence"
1627 " WHERE name='collected_images'",
1656 use_limit ?
"SELECT imgid FROM memory.collected_images LIMIT -1, ?1"
1657 :
"SELECT imgid FROM memory.collected_images",
1699 "SELECT imgid FROM memory.collected_images",
1703 gboolean found =
FALSE;
1718 if(!found) offset = 0;
1727 "INSERT INTO memory.collected_images"
1728 " SELECT * FROM memory.collected_backup",
1736 "INSERT INTO memory.collected_backup"
1737 " SELECT * FROM memory.collected_images",
1747 "DELETE FROM memory.collected_images"
1748 " WHERE imgid NOT IN "
1749 " (SELECT imgid FROM main.selected_images)",
void dt_collection_split_operator_exposure(const gchar *input, char **number1, char **number2, char **operator)
void dt_collection_split_operator_number(const gchar *input, char **number1, char **number2, char **operator)
void dt_collection_get_makermodels(const gchar *filter, GList **sanitized, GList **exif)
gchar * dt_collection_get_makermodel(const char *exif_maker, const char *exif_model)
void dt_collection_split_operator_datetime(const gchar *input, char **number1, char **number2, char **operator)
dt_collection_t * dt_collection_get_global(void)
dt_collection_properties_t
@ DT_COLLECTION_PROP_EXPOSURE
@ DT_COLLECTION_PROP_MODULE
@ DT_COLLECTION_PROP_RATING
@ DT_COLLECTION_PROP_QUERY
@ DT_COLLECTION_PROP_TIME
@ DT_COLLECTION_PROP_METADATA
@ DT_COLLECTION_PROP_GROUPING
@ DT_COLLECTION_PROP_FILMROLL
@ DT_COLLECTION_PROP_LENS
@ DT_COLLECTION_PROP_CAMERA
@ DT_COLLECTION_PROP_LOCAL_COPY
@ DT_COLLECTION_PROP_GEOTAGGING
@ DT_COLLECTION_PROP_FILENAME
@ DT_COLLECTION_PROP_COLORLABEL
@ DT_COLLECTION_PROP_ORDER
@ DT_COLLECTION_PROP_FOLDERS
@ DT_COLLECTION_PROP_APERTURE
@ DT_COLLECTION_PROP_IMPORT_TIMESTAMP
@ DT_COLLECTION_PROP_FOCAL_LENGTH
@ DT_COLLECTION_PROP_EXPORT_TIMESTAMP
@ DT_COLLECTION_PROP_CHANGE_TIMESTAMP
@ DT_COLLECTION_PROP_HISTORY
@ DT_COLLECTION_PROP_PRINT_TIMESTAMP
@ COLLECTION_QUERY_USE_ONLY_WHERE_EXT
@ COLLECTION_QUERY_USE_WHERE_EXT
@ COLLECTION_QUERY_USE_SORT
@ COLLECTION_QUERY_USE_LIMIT
@ COLLECTION_FILTER_ALTERED
@ COLLECTION_FILTER_UNALTERED
@ COLLECTION_FILTER_GREEN
@ COLLECTION_FILTER_2_STAR
@ COLLECTION_FILTER_MAGENTA
@ COLLECTION_FILTER_0_STAR
@ COLLECTION_FILTER_1_STAR
@ COLLECTION_FILTER_5_STAR
@ COLLECTION_FILTER_YELLOW
@ COLLECTION_FILTER_REJECTED
@ COLLECTION_FILTER_4_STAR
@ COLLECTION_FILTER_3_STAR
@ COLLECTION_FILTER_WHITE
@ DT_COLLECTION_SORT_EXPORT_TIMESTAMP
@ DT_COLLECTION_SORT_IMPORT_TIMESTAMP
@ DT_COLLECTION_SORT_DATETIME
@ DT_COLLECTION_SORT_GROUP
@ DT_COLLECTION_SORT_FILENAME
@ DT_COLLECTION_SORT_RATING
@ DT_COLLECTION_SORT_PATH
@ DT_COLLECTION_SORT_TITLE
@ DT_COLLECTION_SORT_CHANGE_TIMESTAMP
@ DT_COLLECTION_SORT_NONE
@ DT_COLLECTION_SORT_PRINT_TIMESTAMP
@ DT_COLLECTION_SORT_COLOR
static const char *const * _order_names
static int _order_names_count
static int _recompose(void)
static uint64_t _generation
uint64_t dt_collection_query_get_generation(void)
void dt_collection_query_set_order_names(const char *const *names, const int count)
static gchar ** _where_ext
void dt_collection_query_pop(void)
static gchar * _sort_query(void)
static const gchar * _ensure_query(void)
int dt_collection_query_set_rules(const dt_collection_params_t *params, const dt_collection_rule_t *rules, const int n_rules, const uint32_t tagid)
GList * dt_collection_query_get_group_members(const int32_t group_id, const int32_t exclude_imgid)
void dt_collection_query_set_order_resolver(dt_collection_query_order_resolver_t fn)
GList * dt_collection_query_get_property_values(const dt_collection_values_request_t *req)
void dt_collection_query_cleanup(void)
static dt_collection_name_value_t * _name_value_new(char *name, int id, int count, int status)
void dt_collection_query_set_iop_names(const dt_iop_name_row_t *rows, const size_t count)
Fill memory.darktable_iop_names, the table the module-name rules join against.
static gchar * _extended_where(void)
static char * or_operator(int *term)
void dt_collection_query_push(void)
static gchar * _extended_where_excluding(const int exclude, const gboolean apply_exclude)
void dt_collection_query_get_makermodels(const gchar *filter, GList **sanitized, GList **exif)
static uint32_t _compute_count(void)
static dt_collection_params_t _params
int dt_collection_query_recompose(void)
void dt_collection_query_refresh_memory_table(void)
GList * dt_collection_query_get_images_for_rule(const dt_collection_properties_t property, const char *text, gboolean recursive)
static void _set_selq_pre_sort(char **selq_pre)
#define or_operator_initial()
uint32_t dt_collection_query_count(void)
static char * and_operator(int *term)
int32_t dt_collection_query_find_neighbour(GList *imgids)
static int _store(gchar *query)
static dt_collection_query_order_resolver_t _order_resolver
static gchar * get_query_string(const dt_collection_properties_t property, const gchar *text, const gboolean recursive)
int32_t dt_collection_query_get_nth(const int nth)
GList * dt_collection_query_get_images(const uint32_t limit)
static gchar ** _compose_where_ext(const dt_collection_rule_t *rules, const int n_rules)
int dt_collection_query_image_offset(const int32_t imgid)
void dt_collection_query_restrict_to_selection(void)
int(* dt_collection_query_order_resolver_t)(const char *text)
const dt_colormatrix_t dt_aligned_pixel_t out
sqlite3 * dt_database_get_sqlite3_global(void)
gboolean dt_database_is_open(void)
#define dt_database_start_transaction()
#define dt_database_release_transaction()
GTimeSpan dt_datetime_exif_to_gtimespan(const char *sdt)
gboolean dt_datetime_gtimespan_to_exif(char *sdt, const size_t sdt_size, const GTimeSpan gts)
#define DT_DATETIME_EXIF_LENGTH
static const dt_iop_order_entry_t * orders[5]
#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)
Checked wrappers around the sqlite3_* calls: trace the statement, assert the return code,...
#define DT_DEBUG_SQLITE3_EXEC(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e)
#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c)
unsigned __int64 uint64_t
dt_collection_query_flags_t query_flags
dt_collection_sort_t sort
dt_collection_filter_flag_t filter_flags
One module's identity, for the rule that searches by module name.
GList * dt_util_str_to_glist(const gchar *separator, const gchar *text)
gchar * dt_util_glist_to_str(const gchar *separator, GList *items)
gchar * dt_util_dstrcat(gchar *str, const gchar *format,...)