-
Notifications
You must be signed in to change notification settings - Fork 6.5k
Expand file tree
/
Copy pathsqlite_functions.h
More file actions
173 lines (145 loc) · 11.2 KB
/
Copy pathsqlite_functions.h
File metadata and controls
173 lines (145 loc) · 11.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
// SPDX-License-Identifier: GPL-3.0-or-later
#ifndef NETDATA_SQLITE_FUNCTIONS_H
#define NETDATA_SQLITE_FUNCTIONS_H
#include "database/rrd.h"
#include "sqlite3.h"
void analytics_set_data_str(char **name, const char *value);
#define SQLITE_BIND_FAIL(label, rc) \
do { \
if ((rc) != SQLITE_OK) \
goto label; \
} while (0)
#define REPORT_BIND_FAIL(res, param) \
do { \
if (unlikely((param))) { \
const char *failed_param = sqlite3_bind_parameter_name((res), (param)); \
nd_log( \
NDLS_DAEMON, \
NDLP_ERR, \
"Failed to bind parameter %d (%s) in %s", \
(param), \
failed_param ? failed_param : "?", \
__FUNCTION__); \
} \
} while (0)
#define SQLITE_FINALIZE(res) \
do { \
if ((res)) { \
int _rc = sqlite3_finalize((res)); \
if (_rc != SQLITE_OK) { \
nd_log(NDLS_DAEMON, NDLP_ERR, "Failed to finalize statement rc=%d in %s", _rc, __FUNCTION__); \
} \
} \
} while (0)
#define SQLITE_RESET(res) \
do { \
if ((res)) { \
int _rc = sqlite3_reset((res)); \
if (_rc != SQLITE_OK) { \
nd_log(NDLS_DAEMON, NDLP_ERR, "Failed to reset statement rc=%d in %s", _rc, __FUNCTION__); \
} \
} \
} while (0)
#define REQUIRE_DB(db) \
({ \
if (unlikely(!(db))) { \
if (default_rrd_memory_mode == RRD_DB_MODE_DBENGINE) \
error_report("Database has not been initialized in %s", __FUNCTION__); \
} \
(db) != NULL; \
})
extern bool sqlite_databases_closed;
#define REQUIRE_HEALTH_DB_OPEN() \
(!__atomic_load_n(&sqlite_databases_closed, __ATOMIC_ACQUIRE))
#define PREPARE_COMPILED_STATEMENT(db, sql, stmt_ptr) \
({ \
bool _ret = true; \
if ((!*(stmt_ptr))) { \
int _rc = prepare_statement((db), (sql), stmt_ptr); \
if (_rc != SQLITE_OK) { \
internal_error(true, "Failed to prepare statement \"%s\", rc=%d in %s", (sql), _rc, __FUNCTION__); \
nd_log(NDLS_DAEMON, NDLP_ERR, "Failed to prepare statement, rc=%d in %s", _rc, __FUNCTION__); \
} \
_ret = (_rc == SQLITE_OK); \
} \
_ret; \
})
#define PREPARE_STATEMENT(db, sql, stmt_ptr) \
({ \
int _rc = simple_prepare_statement((db), (sql), stmt_ptr); \
if (_rc != SQLITE_OK) { \
internal_error(true, "Failed to prepare statement \"%s\", rc=%d in %s", (sql), _rc, __FUNCTION__); \
nd_log(NDLS_DAEMON, NDLP_ERR, "Failed to prepare statement, rc=%d in %s", _rc, __FUNCTION__); \
} \
_rc == SQLITE_OK; \
})
#define SQL_MAX_RETRY (100)
#define SQLITE_INSERT_DELAY (10) // Insert delay in case of lock
#define SQLITE_BUSY_DELAY_MS (30) // Busy timeout delay
SQLITE_API int sqlite3_step_monitored(sqlite3_stmt *stmt);
SQLITE_API int sqlite3_exec_monitored(
sqlite3 *db, /* An open database */
const char *sql, /* SQL to be evaluated */
int (*callback)(void*,int,char**,char**), /* Callback function */
void *data, /* 1st argument to callback */
char **errmsg /* Error msg written here */
);
// Initialization and shutdown
int init_database_batch(sqlite3 *database, const char *batch[], const char *description);
int configure_sqlite_database(sqlite3 *database, int target_version, const char *description);
// Helpers
int bind_text_null(sqlite3_stmt *res, int position, const char *text, bool can_be_null);
int prepare_statement(sqlite3 *database, const char *query, sqlite3_stmt **statement);
int simple_prepare_statement(sqlite3 *database, const char *query, sqlite3_stmt **statement);
void finalize_self_prepared_sql_statements();
void finalize_all_prepared_sql_statements();
int execute_insert(sqlite3_stmt *res);
int db_execute(sqlite3 *database, const char *cmd, int *sqlite_rc);
char *get_database_extented_error(sqlite3 *database, int i, const char *description);
void sql_drop_table(const char *table);
void sqlite_now_usec(sqlite3_context *context, int argc, sqlite3_value **argv);
uint64_t sqlite_get_db_space(sqlite3 *db);
int get_free_page_count(sqlite3 *database);
int get_database_page_count(sqlite3 *database);
// Return a pointer to the UUID blob stored in column iCol when the current row
// contains a BLOB with exactly sizeof(nd_uuid_t) bytes. The caller must pass a
// valid statement positioned on a row. The returned pointer refers to
// SQLite-owned memory and is only valid until the statement is stepped, reset,
// or finalized. Returns NULL for NULL, non-BLOB, or malformed values.
static inline const nd_uuid_t *sqlite3_column_uuid_ptr(sqlite3_stmt *res, int iCol) {
if (sqlite3_column_type(res, iCol) != SQLITE_BLOB)
return NULL;
const void *uuid = sqlite3_column_blob(res, iCol);
if (!uuid || sqlite3_column_bytes(res, iCol) != sizeof(nd_uuid_t))
return NULL;
return (const nd_uuid_t *)uuid;
}
// Copy the UUID stored in column iCol into dst. The caller must pass a valid
// statement positioned on a row and a writable destination UUID buffer.
// Returns true on success, false when the column does not contain a valid UUID blob.
static inline bool sqlite3_column_uuid_copy(sqlite3_stmt *res, int iCol, nd_uuid_t dst) {
const nd_uuid_t *uuid = sqlite3_column_uuid_ptr(res, iCol);
if (!uuid)
return false;
uuid_copy(dst, *uuid);
return true;
}
// Convert the UUID stored in column iCol to lowercase text in out. The caller
// must pass a valid statement positioned on a row and a writable buffer large
// enough for UUID_STR_LEN bytes. Returns true on success, false when the column
// does not contain a valid UUID blob.
static inline bool sqlite3_column_uuid_unparse_lower(sqlite3_stmt *res, int iCol, char *out) {
const nd_uuid_t *uuid = sqlite3_column_uuid_ptr(res, iCol);
if (!uuid)
return false;
uuid_unparse_lower(*uuid, out);
return true;
}
int sqlite_library_init(void);
void sqlite_library_shutdown(void);
void sql_close_database(sqlite3 *database, const char *database_name);
void sql_close_thread_db_safe(sqlite3 **database);
void sqlite_close_databases(void);
uint64_t get_total_database_space(void);
int sqlite_release_memory(int bytes);
#endif //NETDATA_SQLITE_FUNCTIONS_H