1 /*
2     This file is part of darktable,
3     Copyright (C) 2011-2020 darktable developers.
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 
19 #pragma once
20 
21 #include <sqlite3.h>
22 
23 // define this to see all sql queries passed to prepare and exec at compile time, or a variable name
24 // warning:
25 // there are some direct calls to sqlite3_exec and sqlite3_prepare_v2 which are missing here. grep manually.
26 // #define DEBUG_SQL_QUERIES
27 
28 #ifdef DEBUG_SQL_QUERIES
29   #define __STRINGIFY(TEXT) #TEXT
30   #define MESSAGE(VALUE) __STRINGIFY(message __STRINGIFY(SQLDEBUG: VALUE))
31   #define __DT_DEBUG_SQL_QUERY__(value) _Pragma(MESSAGE(value))
32 #else
33   #define __DT_DEBUG_SQL_QUERY__(value)
34 #endif
35 
36 
37 #ifdef _DEBUG
38 #include <assert.h>
39 #define __DT_DEBUG_ASSERT__(xin)                                                                                  \
40   {                                                                                                               \
41     _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin;              \
42     if(x != SQLITE_OK)                                                                                            \
43     {                                                                                                             \
44       fprintf(stderr, "sqlite3 error: %s:%d, function %s(): %s\n", __FILE__, __LINE__, __FUNCTION__,              \
45               sqlite3_errmsg(dt_database_get(darktable.db)));                                                     \
46     }                                                                                                             \
47     assert(x == SQLITE_OK);                                                                                       \
48     _Pragma("GCC diagnostic pop")                                                                                 \
49   }
50 #define __DT_DEBUG_ASSERT_WITH_QUERY__(xin, query)                                                                \
51   {                                                                                                               \
52     _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin;              \
53     if(x != SQLITE_OK)                                                                                            \
54     {                                                                                                             \
55       fprintf(stderr, "sqlite3 error: %s:%d, function %s(), query \"%s\": %s\n", __FILE__, __LINE__, __FUNCTION__,\
56               (query), sqlite3_errmsg(dt_database_get(darktable.db)));                                            \
57     }                                                                                                             \
58     assert(x == SQLITE_OK);                                                                                       \
59     _Pragma("GCC diagnostic pop")                                                                                 \
60   }
61 #else
62 #define __DT_DEBUG_ASSERT__(xin)                                                                                  \
63   {                                                                                                               \
64     _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin;              \
65     if(x != SQLITE_OK)                                                                                            \
66     {                                                                                                             \
67       fprintf(stderr, "sqlite3 error: %s:%d, function %s(): %s\n", __FILE__, __LINE__, __FUNCTION__,              \
68               sqlite3_errmsg(dt_database_get(darktable.db)));                                                     \
69     }                                                                                                             \
70     _Pragma("GCC diagnostic pop")                                                                                 \
71   }
72 #define __DT_DEBUG_ASSERT_WITH_QUERY__(xin, query)                                                                \
73   {                                                                                                               \
74     _Pragma("GCC diagnostic push") _Pragma("GCC diagnostic ignored \"-Wshadow\"") const int x = xin;              \
75     if(x != SQLITE_OK)                                                                                            \
76     {                                                                                                             \
77       fprintf(stderr, "sqlite3 error: %s:%d, function %s(), query \"%s\": %s\n", __FILE__, __LINE__, __FUNCTION__,\
78               (query), sqlite3_errmsg(dt_database_get(darktable.db)));                                            \
79     }                                                                                                             \
80     _Pragma("GCC diagnostic pop")                                                                                 \
81   }
82 
83 #endif
84 
85 #define DT_DEBUG_SQLITE3_EXEC(a, b, c, d, e)                                                                      \
86   do                                                                                                              \
87   {                                                                                                               \
88     dt_print(DT_DEBUG_SQL, "[sql] %s:%d, function %s(): exec \"%s\"\n", __FILE__, __LINE__, __FUNCTION__, (b));   \
89     __DT_DEBUG_ASSERT_WITH_QUERY__(sqlite3_exec(a, b, c, d, e), (b));                                             \
90     __DT_DEBUG_SQL_QUERY__(b)                                                                                     \
91   } while(0)
92 
93 #define DT_DEBUG_SQLITE3_PREPARE_V2(a, b, c, d, e)                                                                \
94   do                                                                                                              \
95   {                                                                                                               \
96     dt_print(DT_DEBUG_SQL, "[sql] %s:%d, function %s(): prepare \"%s\"\n", __FILE__, __LINE__, __FUNCTION__, (b));\
97     __DT_DEBUG_ASSERT_WITH_QUERY__(sqlite3_prepare_v2(a, b, c, d, e), (b));                                       \
98     __DT_DEBUG_SQL_QUERY__(b)                                                                                     \
99   } while(0)
100 
101 #define DT_DEBUG_SQLITE3_BIND_INT(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_int(a, b, c))
102 #define DT_DEBUG_SQLITE3_BIND_INT64(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_int64(a, b, c))
103 #define DT_DEBUG_SQLITE3_BIND_DOUBLE(a, b, c) __DT_DEBUG_ASSERT__(sqlite3_bind_double(a, b, c))
104 #define DT_DEBUG_SQLITE3_BIND_TEXT(a, b, c, d, e) __DT_DEBUG_ASSERT__(sqlite3_bind_text(a, b, c, d, e))
105 #define DT_DEBUG_SQLITE3_BIND_BLOB(a, b, c, d, e) __DT_DEBUG_ASSERT__(sqlite3_bind_blob(a, b, c, d, e))
106 #define DT_DEBUG_SQLITE3_CLEAR_BINDINGS(a) __DT_DEBUG_ASSERT__(sqlite3_clear_bindings(a))
107 #define DT_DEBUG_SQLITE3_RESET(a) __DT_DEBUG_ASSERT__(sqlite3_reset(a))
108 
109 // modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
110 // vim: shiftwidth=2 expandtab tabstop=2 cindent
111 // kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
112