36 "SELECT name FROM data.tags t JOIN main.tagged_images i ON "
37 "i.tagid = t.id WHERE imgid IN "
38 "(SELECT imgid FROM main.selected_images)",
46 "SELECT name FROM data.tags t JOIN main.tagged_images i ON "
47 "i.tagid = t.id WHERE imgid = ?1",
74 "SELECT t.id, t.name, ti.count"
75 " FROM data.tags AS t"
76 " LEFT JOIN (SELECT tagid,"
77 " COUNT(DISTINCT imgid) AS count"
78 " FROM main.tagged_images"
79 " GROUP BY tagid) AS ti"
81 " WHERE name = ?1 OR SUBSTR(name, 1, LENGTH(?2)) = ?2",
147 "WHERE LOWER(T.name) = LOWER(?1)",
name);
158 "INSERT INTO data.tags (id, name) VALUES (NULL, ?1)", -1, &
stmt,
NULL);
175 "SELECT name FROM data.tags WHERE id= ?1", -1, &
stmt,
NULL);
190 "UPDATE data.tags SET name = ?2 WHERE id = ?1", -1, &
stmt,
NULL);
203 "SELECT COUNT(*) FROM main.tagged_images WHERE tagid=?1", -1, &
stmt,
NULL);
215 _run_for_id(
"DELETE FROM data.tags WHERE id=?1", tagid);
216 _run_for_id(
"DELETE FROM main.tagged_images WHERE tagid=?1", tagid);
217 _run_for_id(
"DELETE FROM memory.darktable_tags WHERE tagid=?1", tagid);
240 _run_for_id(
"INSERT INTO memory.darktable_tags (tagid) VALUES (?1)", tagid);
253 "INSERT INTO memory.darktable_tags (tagid)"
254 " SELECT DISTINCT id"
256 " WHERE name LIKE 'darktable|%%'",
271 "SELECT flags FROM data.tags WHERE id = ?1", -1, &
stmt,
NULL);
284 "UPDATE data.tags SET flags = ?2 WHERE id = ?1", -1, &
stmt,
NULL);
296 "UPDATE data.tags SET flags = (IFNULL(flags, 0) & ?3) | ?2 WHERE id = ?1",
310 "SELECT synonyms FROM data.tags WHERE id = ?1", -1, &
stmt,
NULL);
313 gchar *synonyms =
NULL;
324 "UPDATE data.tags SET synonyms = ?2 WHERE id = ?1", -1, &
stmt,
NULL);
340 "SELECT imgid FROM main.tagged_images WHERE imgid = ?1 AND tagid = ?2",
366 "SELECT imgid FROM main.tagged_images WHERE tagid = ?1", -1, &
stmt,
NULL);
378 " WHERE tagid = %d AND imgid IN (%s)", tagid,
imgid_list);
390 "SELECT COUNT(DISTINCT imgid) AS imgnb FROM main.tagged_images WHERE tagid = ?1",
407 gchar *
query =
g_strdup_printf(
"DELETE FROM main.tagged_images WHERE imgid = %d AND tagid IN (%s)",
422 gchar *
query =
g_strdup_printf(
"INSERT INTO main.tagged_images (imgid, tagid, position) VALUES %s",
444 {
"SELECT DISTINCT I.tagid, T.name, T.flags, T.synonyms,"
445 " COUNT(DISTINCT I.imgid) AS inb"
446 " FROM main.tagged_images AS I"
447 " JOIN data.tags AS T ON T.id = I.tagid"
448 " WHERE I.imgid = ?1"
451 "SELECT DISTINCT I.tagid, T.name, T.flags, T.synonyms,"
452 " COUNT(DISTINCT I.imgid) AS inb"
453 " FROM main.tagged_images AS I"
454 " JOIN data.tags AS T ON T.id = I.tagid"
455 " WHERE I.imgid = ?1 AND T.id NOT IN memory.darktable_tags"
457 " ORDER by T.name" },
459 {
"SELECT DISTINCT I.tagid, T.name, T.flags, T.synonyms,"
460 " COUNT(DISTINCT I.imgid) AS inb"
461 " FROM main.tagged_images AS I"
462 " JOIN data.tags AS T ON T.id = I.tagid"
463 " JOIN main.selected_images AS S ON S.imgid = I.imgid"
466 "SELECT DISTINCT I.tagid, T.name, T.flags, T.synonyms,"
467 " COUNT(DISTINCT I.imgid) AS inb"
468 " FROM main.tagged_images AS I"
469 " JOIN data.tags AS T ON T.id = I.tagid"
470 " JOIN main.selected_images AS S ON S.imgid = I.imgid"
471 " WHERE T.id NOT IN memory.darktable_tags"
473 " ORDER by T.name" },
492 const int sel = (imgid > 0) ? 0 : 1;
514 if(!(imgid > 0))
return NULL;
519 "SELECT DISTINCT T.id, T.name, T.flags, T.synonyms"
520 " FROM data.tags AS T"
522 " JOIN (SELECT DISTINCT I.tagid, T.name"
523 " FROM main.tagged_images AS I"
524 " JOIN data.tags AS T ON T.id = I.tagid"
525 " WHERE I.imgid = ?1 AND T.id NOT IN memory.darktable_tags"
526 " ORDER by T.name) AS T1"
528 " ON T.id = T1.tagid"
529 " OR (T.name = SUBSTR(T1.name, 1, LENGTH(T.name))"
530 " AND SUBSTR(T1.name, LENGTH(T.name) + 1, 1) = '|')",
551 char query[256] = { 0 };
557 " FROM main.tagged_images AS I"
558 " JOIN data.tags T on T.id = I.tagid"
559 " WHERE I.imgid IN (%s) %s",
562 "AND NOT T.id IN memory.darktable_tags");
581 "INSERT INTO memory.taglist (id, count)"
582 " SELECT tagid, COUNT(*)"
583 " FROM main.tagged_images"
593 "SELECT T.name, T.id, MT.count, CT.imgnb, T.flags, T.synonyms"
595 " LEFT JOIN memory.taglist MT ON MT.id = T.id "
596 " LEFT JOIN (SELECT tagid, COUNT(DISTINCT imgid) AS imgnb"
597 " FROM main.tagged_images "
598 " WHERE imgid IN (SELECT imgid FROM main.selected_images) GROUP BY tagid) AS CT "
599 " ON CT.tagid = T.id"
600 " WHERE T.id NOT IN memory.darktable_tags "
638 "SELECT DISTINCT T.name, T.id"
640 " JOIN main.tagged_images TI ON TI.tagid = T.id"
641 " WHERE TI.imgid IN (SELECT imgid FROM memory.collected_images)"
642 " AND T.id NOT IN memory.darktable_tags"
670 "SELECT DISTINCT T.name FROM main.tagged_images AS I "
671 "INNER JOIN data.tags AS T "
672 "ON T.id = I.tagid AND SUBSTR(T.name, 1, LENGTH(?2)) = ?2 "
673 "WHERE I.imgid = ?1",
695 "INSERT INTO memory.similar_tags (tagid)"
698 " WHERE name = ?1 OR SUBSTR(name, 1, LENGTH(?2)) = ?2",
735 *
tag_count =
_scalar(
"SELECT COUNT(DISTINCT tagid) FROM memory.similar_tags");
738 " FROM main.tagged_images AS ti "
739 " JOIN memory.similar_tags AS st"
740 " ON st.tagid = ti.tagid");
755 "SELECT ST.tagid, T.name"
756 " FROM memory.similar_tags ST"
758 " ON T.id = ST.tagid ",
775 "SELECT DISTINCT ti.imgid"
776 " FROM main.tagged_images AS ti"
777 " JOIN memory.similar_tags AS st"
778 " ON st.tagid = ti.tagid",
797 "INSERT INTO memory.taglist (id, count, count2)"
798 " SELECT S.tagid, COUNT(imgid) AS count,"
799 " CASE WHEN count2 IS NULL THEN 0 ELSE count2 END AS count2"
800 " FROM main.tagged_images AS S"
802 " SELECT tagid, COUNT(imgid) AS count2"
803 " FROM main.tagged_images"
804 " WHERE imgid IN main.selected_images"
805 " GROUP BY tagid) AS at"
806 " ON at.tagid = S.tagid"
807 " WHERE S.tagid NOT IN memory.darktable_tags"
817 " td.flags, td.synonyms FROM ("
819 " SELECT DISTINCT tagid2 FROM ("
820 " SELECT tagid2 FROM ("
822 " SELECT tagid1, tagid2, count(*) AS c12"
824 " SELECT DISTINCT tagid AS tagid1, imgid FROM main.tagged_images"
825 " JOIN memory.taglist AS t00"
826 " ON t00.id = tagid1 AND t00.count2 > 0) AS t1"
828 " SELECT DISTINCT tagid AS tagid2, imgid FROM main.tagged_images"
829 " WHERE tagid NOT IN memory.darktable_tags) AS t2"
830 " ON t2.imgid = t1.imgid AND tagid1 != tagid2"
831 " GROUP BY tagid1, tagid2)"
832 " JOIN memory.taglist AS t01"
833 " ON t01.id = tagid1"
834 " JOIN memory.taglist AS t02"
835 " ON t02.id = tagid2"
837 " WHERE (t01.count-t01.count2) != 0"
838 " AND (100 * c12 / (t01.count-t01.count2) >= %d)"
839 " AND t02.count2 != %d) "
843 " SELECT tn.id AS tagid2 FROM data.tags AS tn"
844 " JOIN memory.taglist AS t02"
846 " WHERE tn.name IN (\'%s\')"
848 " AND t02.count2 != %d LIMIT %d)) "
849 "LEFT JOIN memory.taglist AS t21 "
850 "ON t21.id = tagid2 "
851 "LEFT JOIN data.tags as td ON td.id = tagid2 ",
856 " tn.flags, tn.synonyms "
858 "FROM data.tags AS tn "
859 "JOIN memory.taglist AS t02 "
861 "WHERE tn.name IN (\'%s\')"
863 " AND t02.count2 != %d LIMIT %d",
901 "INSERT INTO main.tagged_images (tagid, imgid, position)"
903 " (SELECT (IFNULL(MAX(position),0) & 0xFFFFFFFF00000000) + (1 << 32)"
904 " FROM main.tagged_images))",
936 "FROM main.tagged_images "
938 "ON data.tags.id = main.tagged_images.tagid AND name NOT LIKE 'darktable|%%' "
939 "WHERE imgid in (%s) GROUP BY tagid", set);
static const dt_adaptation_t kind
sqlite3 * dt_database_get_sqlite3_global(void)
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
dt_mipmap_buffer_dsc_flags flags
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)
#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)
gboolean dt_tag_repository_attach(const guint tagid, const int32_t imgid)
Attach tagid to imgid, at the end of the tag order.
void dt_tag_repository_delete_batch(const char *id_list)
Delete every tag in id_list and its attachments.
void dt_tag_repository_rename(const guint tagid, const char *new_name)
Rename tagid. The caller checks first that the new name is free.
GList * dt_tag_repository_get_with_usage(const uint32_t nb_selected)
Every user tag with how often it is used and how much of the selection carries it.
GList * dt_tag_repository_get_collection_tags(void)
User tags attached to at least one image of the current collection, by name.
static guint _first_id_for_text(const char *query, const char *value)
void dt_tag_repository_get_agreement(GList *imgids, gboolean *same_tags, gboolean *same_categories)
Do all of imgids carry exactly the same tags? The same categories?
gchar * dt_tag_repository_get_name(const guint tagid)
The name of tagid, newly allocated, or NULL.
int dt_tag_repository_count_attachments(const guint tagid)
How many attachment ROWS tagid has, or -1 if the count could not be read. See dt_tag_repository_count...
GList * dt_tag_repository_get_images(const guint tagid)
Images carrying tagid, GINT_TO_POINTER. Free with g_list_free().
static void _run_for_id(const char *query, const guint id)
GList * dt_tag_repository_get_suggestions(const uint32_t nb_selected, const int confidence, const char *recent_tags, const int nb_recent)
Tags worth suggesting for the current selection.
static void _clear_similar_tags(void)
GList * dt_tag_repository_get_by_path_with_counts(const char *path, const char *path_prefix)
Tags at path or below it, each with the number of distinct images carrying it.
static GList * _collect_imgids(sqlite3_stmt *stmt)
GList * dt_tag_repository_get_ids_for_images(const char *imgid_list, const dt_tag_kind_t kind)
Ids of the tags on a set of images, optionally restricted by kind.
void dt_tag_repository_mark_internal(const guint tagid)
Record tagid as an internal tag.
void dt_tag_repository_get_similar(const char *keyword, GList **tags, GList **imgids)
The tags matching keyword and the images carrying any of them.
guint dt_tag_repository_find_by_name(const char *name)
The id of the tag named name, or 0 when there is none.
GList * dt_tag_repository_get_attached_for_export(const int32_t imgid)
Tags attached to imgid for export, plus every ancestor on their paths.
GList * dt_tag_repository_get_names_under(const int32_t imgid, const char *category)
Names of the tags on imgid that start with category.
guint dt_tag_repository_find_by_name_nocase(const char *name)
The id of the tag whose name matches name case-INSENSITIVELY, or 0.
gint dt_tag_repository_get_flags(const guint tagid)
The flags word of tagid, or 0.
void dt_tag_repository_update_flags(const guint tagid, const gint set, const gint keep_mask)
Set the bits in set and clear those absent from keep_mask: flags = (IFNULL(flags,0) & keep_mask) | se...
void dt_tag_repository_count_similar(const char *keyword, int *tag_count, int *img_count)
How many tags match keyword, and how many images carry any of them.
GList * dt_tag_repository_get_images_in_list(const guint tagid, const char *imgid_list)
Images carrying tagid, restricted to imgid_list – a comma-separated list of decimal image ids compose...
void dt_tag_repository_delete(const guint tagid)
Delete tagid, its attachments, and its memory.darktable_tags entry.
void dt_tag_repository_cleanup(void)
Finalise whatever this repository still caches – today, nothing. See dt_colorlabel_repository_cleanup...
void dt_tag_repository_attach_batch(const char *values)
Attach rows given as the VALUES clause of the insert – "(imgid,tagid,pos),…". The position expression...
gchar * dt_tag_repository_get_synonyms(const guint tagid)
The synonyms of tagid, newly allocated, or NULL.
void dt_tag_repository_set_synonyms(const guint tagid, const char *synonyms)
Replace the synonyms of tagid.
static const char *const _attached_query[2][2]
void dt_tag_repository_rebuild_internal(void)
Rebuild the whole internal-tag cache from data.tags.
uint32_t dt_tag_repository_count_distinct_images(const guint tagid)
Distinct images carrying tagid.
static dt_tag_t * _tag_from_row(sqlite3_stmt *stmt, const gboolean with_count)
void dt_tag_repository_set_flags(const guint tagid, const gint flags)
Replace the flags word of tagid.
static int _scalar(const char *query)
static void _fill_similar_tags(const char *keyword)
void dt_tag_count_free(gpointer data)
Release one dt_tag_count_t, name included. Suits g_list_free_full().
gboolean dt_tag_repository_is_attached(const guint tagid, const int32_t imgid)
TRUE when tagid is attached to imgid.
void dt_tag_repository_detach_batch(const int32_t imgid, const char *tagid_list)
Detach every tag in tagid_list from imgid.
GList * dt_tag_repository_get_attached(const int32_t imgid, const gboolean ignore_internal)
Tags attached to one image or to the current selection, ordered by name.
GList * dt_tag_repository_get_attached_names(const int32_t imgid)
Names of the tags attached to an image.
guint dt_tag_repository_insert(const char *name)
Insert a tag named name and return its new id, or 0 on failure.
data.tags and main.tagged_images.