Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
sql_debug.h
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2011 Bruce Guenter.
4 Copyright (C) 2011 Henrik Andersson.
5 Copyright (C) 2011 johannes hanika.
6 Copyright (C) 2011, 2014, 2016-2017 Tobias Ellinghaus.
7 Copyright (C) 2012 Richard Wonka.
8 Copyright (C) 2016 Roman Lebedev.
9 Copyright (C) 2018 Mario Lueder.
10 Copyright (C) 2020 Pascal Obry.
11 Copyright (C) 2022, 2026 Aurélien PIERRE.
12 Copyright (C) 2022 Martin Bařinka.
13 Copyright (C) 2023, 2025 Alynx Zhou.
14
15 darktable is free software: you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation, either version 3 of the License, or
18 (at your option) any later version.
19
20 darktable is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with darktable. If not, see <http://www.gnu.org/licenses/>.
27*/
28
50#ifndef DT_DATABASE_SQL_DEBUG_H
51#define DT_DATABASE_SQL_DEBUG_H
52
53/* Self-containment: the macros below expand to dt_database_get_sqlite3_global()
54 * (database/database.h), dt_print()/DT_DEBUG_SQL (common/logging.h) and fprintf()
55 * (<stdio.h>). Include them here rather than making every consumer of the macros do it. */
56
57#include "common/logging.h"
58#include "database/database.h"
59
60#include <sqlite3.h>
61#include <stdio.h>
62
63#ifdef __cplusplus
64extern "C" {
65#endif
66
67// define this to see all sql queries passed to prepare and exec at compile time, or a variable name
68// warning:
69// there are some direct calls to sqlite3_exec and sqlite3_prepare_v2 which are missing here. grep manually.
70// #define DEBUG_SQL_QUERIES
71
72#ifdef DEBUG_SQL_QUERIES
73 #define __STRINGIFY(TEXT) #TEXT
74 #define MESSAGE(VALUE) __STRINGIFY(message __STRINGIFY(SQLDEBUG: VALUE))
75 #define __DT_DEBUG_SQL_QUERY__(value) _Pragma(MESSAGE(value))
76#else
77 #define __DT_DEBUG_SQL_QUERY__(value)
78#endif
79
80
81#ifdef _DEBUG
82#include <assert.h> // conditional-ok: assert() is used only in this arm; the release arm below reports and continues
83#define __DT_DEBUG_ASSERT__(xin) \
84 { \
85 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin; \
86 if(x != SQLITE_OK) \
87 { \
88 fprintf(stderr, "sqlite3 error: %s:%d, function %s(): %s\n", __FILE__, __LINE__, __FUNCTION__, \
89 sqlite3_errmsg(dt_database_get_sqlite3_global())); \
90 } \
91 assert(x == SQLITE_OK); \
92 _Pragma("GCC diagnostic pop") \
93 }
94#define __DT_DEBUG_ASSERT_WITH_QUERY__(xin, query) \
95 { \
96 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin; \
97 if(x != SQLITE_OK) \
98 { \
99 fprintf(stderr, "sqlite3 error: %s:%d, function %s(), query \"%s\": %s\n", __FILE__, __LINE__, __FUNCTION__,\
100 (query), sqlite3_errmsg(dt_database_get_sqlite3_global())); \
101 } \
102 assert(x == SQLITE_OK); \
103 _Pragma("GCC diagnostic pop") \
104 }
105#else
106#define __DT_DEBUG_ASSERT__(xin) \
107 { \
108 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin; \
109 if(x != SQLITE_OK) \
110 { \
111 fprintf(stderr, "sqlite3 error: %s:%d, function %s(): %s\n", __FILE__, __LINE__, __FUNCTION__, \
112 sqlite3_errmsg(dt_database_get_sqlite3_global())); \
113 } \
114 _Pragma("GCC diagnostic pop") \
115 }
116#define __DT_DEBUG_ASSERT_WITH_QUERY__(xin, query) \
117 { \
118 _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin; \
119 if(x != SQLITE_OK) \
120 { \
121 fprintf(stderr, "sqlite3 error: %s:%d, function %s(), query \"%s\": %s\n", __FILE__, __LINE__, __FUNCTION__,\
122 (query), sqlite3_errmsg(dt_database_get_sqlite3_global())); \
123 } \
124 _Pragma("GCC diagnostic pop") \
125 }
126
127#endif
128
129#define DT_DEBUG_SQLITE3_EXEC(a, b, c, d, e) \
130 do \
131 { \
132 dt_print(DT_DEBUG_SQL, "[sql] %s:%d, function %s(): exec \"%s\"\n", __FILE__, __LINE__, __FUNCTION__, (b)); \
133 __DT_DEBUG_ASSERT_WITH_QUERY__(sqlite3_exec(a, b, c, d, e), (b)); \
134 __DT_DEBUG_SQL_QUERY__(b) \
135 } while(0)
136
137#define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e) \
138 do \
139 { \
140 dt_print(DT_DEBUG_SQL, "[sql] %s:%d, function %s(): prepare \"%s\"\n", __FILE__, __LINE__, __FUNCTION__, (b));\
141 __DT_DEBUG_ASSERT_WITH_QUERY__(sqlite3_prepare_v2(a, b, c, d, e), (b)); \
142 __DT_DEBUG_SQL_QUERY__(b) \
143 } while(0)
144
145#define DT_DEBUG_SQLITE3_BIND_INT(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_int(a, b, c))
146#define DT_DEBUG_SQLITE3_BIND_INT64(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_int64(a, b, c))
147#define DT_DEBUG_SQLITE3_BIND_DOUBLE(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_double(a, b, c))
148#define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e) __DT_DEBUG_ASSERT__(sqlite3_bind_text(a, b, c, d, e))
149#define DT_DEBUG_SQLITE3_BIND_BLOB(a, b, c, d, e) __DT_DEBUG_ASSERT__(sqlite3_bind_blob(a, b, c, d, e))
150#define DT_DEBUG_SQLITE3_CLEAR_BINDINGS(a) __DT_DEBUG_ASSERT__(sqlite3_clear_bindings(a))
151#define DT_DEBUG_SQLITE3_RESET(a) __DT_DEBUG_ASSERT__(sqlite3_reset(a))
152
153#ifdef __cplusplus
154}
155#endif
156
157#endif // DT_DATABASE_SQL_DEBUG_H
158
159// clang-format off
160// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
161// vim: shiftwidth=2 expandtab tabstop=2 cindent
162// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
163// clang-format on