GCC Code Coverage Report


Directory: src/gate/
File: src/gate/data/sqlite3_adapter.c
Date: 2026-03-20 22:56:14
Exec Total Coverage
Lines: 279 364 76.6%
Functions: 23 23 100.0%
Branches: 87 183 47.5%

Line Branch Exec Source
1 /* GATE PROJECT LICENSE:
2 +----------------------------------------------------------------------------+
3 | Copyright(c) 2018-2026, Stefan Meislinger |
4 | All rights reserved. |
5 | |
6 | Redistribution and use in source and binary forms, with or without |
7 | modification, are permitted provided that the following conditions are met:|
8 | |
9 | 1. Redistributions of source code must retain the above copyright notice, |
10 | this list of conditions and the following disclaimer. |
11 | 2. Redistributions in binary form must reproduce the above copyright |
12 | notice, this list of conditions and the following disclaimer in the |
13 | documentation and/or other materials provided with the distribution. |
14 | |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"|
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 | ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
25 | THE POSSIBILITY OF SUCH DAMAGE. |
26 +----------------------------------------------------------------------------+
27 */
28 #include "gate/data/sqlite3_adapter.h"
29 #include "gate/results.h"
30 #include "gate/arrays.h"
31 #include "gate/debugging.h"
32 #include "gate/data/adapter_base.h"
33
34 #if defined(GATE_DATA_SQLITE3_ENABLED)
35 # define GATE_DATA_SQLITE3_LIB_IMPL 1
36 #else
37 # if defined(GATE_SYS_WIN) || defined(GATE_SYS_POSIX)
38 # if !defined(GATE_DATA_SQLITE3_SHAREDLIB)
39 # define GATE_DATA_SQLITE3_SHAREDLIB 1
40 # endif
41 # define GATE_DATA_SQLITE3_LIB_IMPL 1
42 # else
43 # define GATE_DATA_SQLITE3_NO_IMPL 1
44 # endif
45 #endif
46
47
48 #if defined(GATE_DATA_SQLITE3_LIB_IMPL)
49
50
51 #if !defined(GATE_DATA_SQLITE3_SHAREDLIB)
52
53 # include "sqlite3.h"
54
55 #else
56
57 # include "gate/libraries.h"
58
59 typedef struct gate_sqlite3_stmt_impl sqlite3_stmt;
60 typedef struct gate_sqlite3_impl sqlite3;
61 typedef gate_int64_t sqlite_int64;
62
63 #define SQLITE_INTEGER 1
64 #define SQLITE_FLOAT 2
65 #define SQLITE_BLOB 4
66 #define SQLITE_NULL 5
67 #ifdef SQLITE_TEXT
68 # undef SQLITE_TEXT
69 #else
70 # define SQLITE_TEXT 3
71 #endif
72 #define SQLITE3_TEXT 3
73
74 #define SQLITE_OK 0
75 #define SQLITE_ERROR 1
76 #define SQLITE_INTERNAL 2
77 #define SQLITE_PERM 3
78 #define SQLITE_ABORT 4
79 #define SQLITE_BUSY 5
80 #define SQLITE_LOCKED 6
81 #define SQLITE_NOMEM 7
82 #define SQLITE_READONLY 8
83 #define SQLITE_INTERRUPT 9
84 #define SQLITE_IOERR 10
85 #define SQLITE_CORRUPT 11
86 #define SQLITE_NOTFOUND 12
87 #define SQLITE_FULL 13
88 #define SQLITE_CANTOPEN 14
89 #define SQLITE_PROTOCOL 15
90 #define SQLITE_EMPTY 16
91 #define SQLITE_SCHEMA 17
92 #define SQLITE_TOOBIG 18
93 #define SQLITE_CONSTRAINT 19
94 #define SQLITE_MISMATCH 20
95 #define SQLITE_MISUSE 21
96 #define SQLITE_NOLFS 22
97 #define SQLITE_AUTH 23
98 #define SQLITE_FORMAT 24
99 #define SQLITE_RANGE 25
100 #define SQLITE_NOTADB 26
101 #define SQLITE_NOTICE 27
102 #define SQLITE_WARNING 28
103 #define SQLITE_ROW 100
104 #define SQLITE_DONE 101
105
106 #define SQLITE_OPEN_READONLY 0x00000001
107 #define SQLITE_OPEN_READWRITE 0x00000002
108 #define SQLITE_OPEN_CREATE 0x00000004
109 #define SQLITE_OPEN_DELETEONCLOSE 0x00000008
110 #define SQLITE_OPEN_EXCLUSIVE 0x00000010
111 #define SQLITE_OPEN_AUTOPROXY 0x00000020
112 #define SQLITE_OPEN_URI 0x00000040
113 #define SQLITE_OPEN_MEMORY 0x00000080
114 #define SQLITE_OPEN_MAIN_DB 0x00000100
115 #define SQLITE_OPEN_TEMP_DB 0x00000200
116 #define SQLITE_OPEN_TRANSIENT_DB 0x00000400
117 #define SQLITE_OPEN_MAIN_JOURNAL 0x00000800
118 #define SQLITE_OPEN_TEMP_JOURNAL 0x00001000
119 #define SQLITE_OPEN_SUBJOURNAL 0x00002000
120 #define SQLITE_OPEN_SUPER_JOURNAL 0x00004000
121 #define SQLITE_OPEN_NOMUTEX 0x00008000
122 #define SQLITE_OPEN_FULLMUTEX 0x00010000
123 #define SQLITE_OPEN_SHAREDCACHE 0x00020000
124 #define SQLITE_OPEN_PRIVATECACHE 0x00040000
125 #define SQLITE_OPEN_WAL 0x00080000
126 #define SQLITE_OPEN_NOFOLLOW 0x01000000
127 #define SQLITE_OPEN_EXRESCODE 0x02000000
128
129 #endif
130
131 #if defined(GATE_SYS_WIN16)
132 # define SQLITE3_CALL GATE_CALL
133 #else
134 # define SQLITE3_CALL
135 #endif
136
137 typedef struct gate_sqlite3_api_class
138 {
139 int (SQLITE3_CALL *column_type) (sqlite3_stmt* pStmt, int i);
140 int (SQLITE3_CALL *column_count) (sqlite3_stmt* pStmt);
141 const char* (SQLITE3_CALL *column_name) (sqlite3_stmt* pStmt, int N);
142 sqlite_int64 (SQLITE3_CALL *column_int64) (sqlite3_stmt* pStmt, int i);
143 double (SQLITE3_CALL *column_double) (sqlite3_stmt* pStmt, int i);
144 int (SQLITE3_CALL *column_bytes) (sqlite3_stmt* pStmt, int i);
145 const void* (SQLITE3_CALL *column_blob) (sqlite3_stmt* pStmt, int i);
146 const unsigned char*(SQLITE3_CALL *column_text) (sqlite3_stmt* pStmt, int i);
147
148 int (SQLITE3_CALL *bind_parameter_count) (sqlite3_stmt* pStmt);
149 int (SQLITE3_CALL *bind_parameter_index) (sqlite3_stmt* pStmt, const char* zName);
150 const char* (SQLITE3_CALL *bind_parameter_name) (sqlite3_stmt* pStmt, int i);
151 int (SQLITE3_CALL *bind_blob) (sqlite3_stmt* pStmt, int i, const void* value, int len, void(SQLITE3_CALL *dtor)(void*));
152 int (SQLITE3_CALL *bind_double) (sqlite3_stmt* pStmt, int i, double value);
153 int (SQLITE3_CALL *bind_int64) (sqlite3_stmt* pStmt, int i, sqlite_int64 value);
154 int (SQLITE3_CALL *bind_null) (sqlite3_stmt* pStmt, int i);
155 int (SQLITE3_CALL *bind_text) (sqlite3_stmt* pStmt, int i, const char* text, int len, void(SQLITE3_CALL *dtor)(void*));
156
157 int (SQLITE3_CALL *prepare) (sqlite3* db, const char* zSql, int nBytes, sqlite3_stmt** ppStmt, const char** pzTail);
158 int (SQLITE3_CALL *clear_bindings) (sqlite3_stmt*);
159 int (SQLITE3_CALL *reset) (sqlite3_stmt* pStmt);
160 int (SQLITE3_CALL *changes) (sqlite3* db);
161 int (SQLITE3_CALL *close) (sqlite3* db);
162 int (SQLITE3_CALL *open) (const char* zFilename, sqlite3** ppDb);
163 int (SQLITE3_CALL *open_v2) (const char* zFilename, sqlite3** ppDb, int flags, const char* zVfs);
164 int (SQLITE3_CALL *finalize) (sqlite3_stmt* pStmt);
165 int (SQLITE3_CALL *step) (sqlite3_stmt* pStmt);
166 const char* (SQLITE3_CALL *errmsg) (sqlite3* db);
167 } gate_sqlite3_api_t;
168
169 static gate_sqlite3_api_t sqlite3_api = GATE_INIT_EMPTY;
170
171
172 #if !defined(GATE_DATA_SQLITE3_SHAREDLIB)
173
174 #if defined(GATE_DEBUG_MODE)
175 # /* define GATE_DATA_SQLITE3_DEBUGGING 1 */
176 #endif
177
178 #if defined(GATE_DATA_SQLITE3_DEBUGGING)
179 void errorLogCallback(void* pArg, int iErrCode, const char* zMsg)
180 {
181 printf("SQLITE (%d): %s\n", iErrCode, zMsg);
182 }
183 #endif
184
185 3 static gate_result_t gate_data_sqlite3_api_init()
186 {
187 static gate_atomic_flag_t sqlite3_api_initialized = GATE_ATOMIC_FLAG_INIT;
188
189
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
3 if (gate_atomic_flag_set(&sqlite3_api_initialized) == 0)
190 {
191 2 sqlite3_api.column_type = &sqlite3_column_type;
192 2 sqlite3_api.column_count = &sqlite3_column_count;
193 2 sqlite3_api.column_name = &sqlite3_column_name;
194 2 sqlite3_api.column_int64 = &sqlite3_column_int64;
195 2 sqlite3_api.column_double = &sqlite3_column_double;
196 2 sqlite3_api.column_bytes = &sqlite3_column_bytes;
197 2 sqlite3_api.column_blob = &sqlite3_column_blob;
198 2 sqlite3_api.column_text = &sqlite3_column_text;
199
200 2 sqlite3_api.bind_parameter_count = &sqlite3_bind_parameter_count;
201 2 sqlite3_api.bind_parameter_index = &sqlite3_bind_parameter_index;
202 2 sqlite3_api.bind_parameter_name = &sqlite3_bind_parameter_name;
203 2 sqlite3_api.bind_blob = &sqlite3_bind_blob;
204 2 sqlite3_api.bind_double = &sqlite3_bind_double;
205 2 sqlite3_api.bind_int64 = &sqlite3_bind_int64;
206 2 sqlite3_api.bind_null = &sqlite3_bind_null;
207 2 sqlite3_api.bind_text = &sqlite3_bind_text;
208
209 2 sqlite3_api.prepare = &sqlite3_prepare;
210 2 sqlite3_api.clear_bindings = &sqlite3_clear_bindings;
211 2 sqlite3_api.reset = &sqlite3_reset;
212 2 sqlite3_api.changes = &sqlite3_changes;
213 2 sqlite3_api.close = &sqlite3_close;
214 2 sqlite3_api.open = &sqlite3_open;
215 2 sqlite3_api.open_v2 = &sqlite3_open_v2;
216 2 sqlite3_api.finalize = &sqlite3_finalize;
217 2 sqlite3_api.step = &sqlite3_step;
218 2 sqlite3_api.errmsg = &sqlite3_errmsg;
219 #if defined(GATE_DATA_SQLITE3_DEBUGGING)
220 sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
221 #endif
222 }
223 3 return GATE_RESULT_OK;
224 }
225
226 #else
227
228
229 static char const* gate_data_sqlite3_lib_names[] = {
230 #if defined(GATE_SYS_WIN)
231 "sqlite3.dll"
232 #else
233 "libsqlite3.so.0"
234 #endif
235 #if defined(GATE_DATA_SQLITE3_LIB_ALTERNATIVES)
236 ,
237 GATE_DATA_SQLITE3_LIB_ALTERNATIVES
238 #endif
239 };
240
241 static gate_size_t const gate_data_sqlite3_lib_names_count
242 = sizeof(gate_data_sqlite3_lib_names) / sizeof(gate_data_sqlite3_lib_names[0]);
243
244
245 static gate_result_t gate_data_sqlite3_api_load(gate_library_t lib)
246 {
247 #define SQL3_LOAD_FUNC(name, func_ptr) \
248 ret = gate_library_get_function_name(lib, name, func_ptr); \
249 if(GATE_FAILED(ret)) return ret;
250
251 gate_result_t ret;
252 SQL3_LOAD_FUNC("sqlite3_column_type", &sqlite3_api.column_type);
253 SQL3_LOAD_FUNC("sqlite3_column_count", &sqlite3_api.column_count);
254 SQL3_LOAD_FUNC("sqlite3_column_name", &sqlite3_api.column_name);
255 SQL3_LOAD_FUNC("sqlite3_column_int64", &sqlite3_api.column_int64);
256 SQL3_LOAD_FUNC("sqlite3_column_double", &sqlite3_api.column_double);
257 SQL3_LOAD_FUNC("sqlite3_column_bytes", &sqlite3_api.column_bytes);
258 SQL3_LOAD_FUNC("sqlite3_column_blob", &sqlite3_api.column_blob);
259 SQL3_LOAD_FUNC("sqlite3_column_text", &sqlite3_api.column_text);
260
261 SQL3_LOAD_FUNC("sqlite3_bind_parameter_count", &sqlite3_api.bind_parameter_count);
262 SQL3_LOAD_FUNC("sqlite3_bind_parameter_index", &sqlite3_api.bind_parameter_index);
263 SQL3_LOAD_FUNC("sqlite3_bind_parameter_name", &sqlite3_api.bind_parameter_name);
264 SQL3_LOAD_FUNC("sqlite3_bind_blob", &sqlite3_api.bind_blob);
265 SQL3_LOAD_FUNC("sqlite3_bind_double", &sqlite3_api.bind_double);
266 SQL3_LOAD_FUNC("sqlite3_bind_int64", &sqlite3_api.bind_int64);
267 SQL3_LOAD_FUNC("sqlite3_bind_null", &sqlite3_api.bind_null);
268 SQL3_LOAD_FUNC("sqlite3_bind_text", &sqlite3_api.bind_text);
269
270 SQL3_LOAD_FUNC("sqlite3_prepare", &sqlite3_api.prepare);
271 SQL3_LOAD_FUNC("sqlite3_clear_bindings", &sqlite3_api.clear_bindings);
272 SQL3_LOAD_FUNC("sqlite3_reset", &sqlite3_api.reset);
273 SQL3_LOAD_FUNC("sqlite3_changes", &sqlite3_api.changes);
274 SQL3_LOAD_FUNC("sqlite3_close", &sqlite3_api.close);
275 SQL3_LOAD_FUNC("sqlite3_open", &sqlite3_api.open);
276 SQL3_LOAD_FUNC("sqlite3_open_v2", &sqlite3_api.open_v2);
277 SQL3_LOAD_FUNC("sqlite3_finalize", &sqlite3_api.finalize);
278 SQL3_LOAD_FUNC("sqlite3_step", &sqlite3_api.step);
279 SQL3_LOAD_FUNC("sqlite3_errmsg", &sqlite3_api.errmsg);
280 return GATE_RESULT_OK;
281 }
282
283 static gate_result_t gate_data_sqlite3_api_init()
284 {
285 static gate_atomic_flag_t sqlite3_api_initialized = GATE_ATOMIC_FLAG_INIT;
286 gate_string_t libname = GATE_STRING_INIT_EMPTY;
287 gate_size_t index;
288 gate_library_t lib = NULL;
289 gate_result_t result;
290
291 if (gate_atomic_flag_set(&sqlite3_api_initialized) == true)
292 {
293 /* already loaded */
294 return GATE_RESULT_OK;
295 }
296
297 for (index = 0; index != gate_data_sqlite3_lib_names_count; ++index)
298 {
299 gate_string_create_static(&libname, gate_data_sqlite3_lib_names[index]);
300 result = gate_library_open(&libname, &lib, GATE_LIBRARY_FLAG_DEFAULT);
301 if (GATE_FAILED(result))
302 {
303 continue;
304 }
305 result = gate_data_sqlite3_api_load(lib);
306 if (GATE_SUCCEEDED(result))
307 {
308 /* library loaded -> OK */
309 return GATE_RESULT_OK;
310 }
311 gate_library_close(lib);
312 }
313 /* no library loaded -> reset */
314 gate_atomic_flag_clear(&sqlite3_api_initialized);
315 return GATE_RESULT_NOTAVAILABLE;
316 }
317
318 #endif
319
320
321 17 static gate_result_t sqlite3_error_to_gate_result(int sql3_error)
322 {
323
1/28
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
17 switch (sql3_error)
324 {
325 17 case SQLITE_OK: return GATE_RESULT_OK;
326 case SQLITE_ROW: return GATE_RESULT_OK_PARTIAL;
327 case SQLITE_ERROR: return GATE_RESULT_FAILED;
328 case SQLITE_INTERNAL: return GATE_RESULT_UNKNOWNERROR;
329 case SQLITE_PERM: return GATE_RESULT_PERMISSIONDENIED;
330 case SQLITE_ABORT: return GATE_RESULT_CANCELED;
331 case SQLITE_BUSY: return GATE_RESULT_BLOCKED;
332 case SQLITE_LOCKED: return GATE_RESULT_LOCKED;
333 case SQLITE_NOMEM: return GATE_RESULT_OUTOFMEMORY;
334 case SQLITE_READONLY: return GATE_RESULT_ACCESSDENIED;
335 case SQLITE_INTERRUPT: return GATE_RESULT_EXECUTIONINTERRUPTED;
336 case SQLITE_IOERR: return GATE_RESULT_DEVICEERROR;
337 case SQLITE_CORRUPT: return GATE_RESULT_INVALIDDATA;
338 case SQLITE_NOTFOUND: return GATE_RESULT_INVALIDARG;
339 case SQLITE_FULL: return GATE_RESULT_OUTOFRESOURCES;
340 case SQLITE_CANTOPEN: return GATE_RESULT_NOTAVAILABLE;
341 case SQLITE_PROTOCOL: return GATE_RESULT_NOTREADY;
342 case SQLITE_SCHEMA: return GATE_RESULT_PRECONDITIONFAILED;
343 case SQLITE_TOOBIG: return GATE_RESULT_OVERFLOW;
344 case SQLITE_CONSTRAINT: return GATE_RESULT_EXECUTIONFAILED;
345 case SQLITE_MISMATCH: return GATE_RESULT_INCORRECTTYPE;
346 case SQLITE_MISUSE: return GATE_RESULT_INVALIDSTATE;
347 case SQLITE_NOLFS: return GATE_RESULT_NOTSUPPORTED;
348 case SQLITE_AUTH: return GATE_RESULT_SECURITYBREACH;
349 case SQLITE_RANGE: return GATE_RESULT_OUTOFBOUNDS;
350 case SQLITE_NOTADB: return GATE_RESULT_INVALIDCONTENT;
351 case SQLITE_DONE: return GATE_RESULT_ENDOFSTREAM;
352 default: return GATE_RESULT_FAILED;
353 }
354 }
355
356 72 static gate_bool_t gate_data_reader_sqlite3_is_valid(gate_data_reader_base_t* reader)
357 {
358 72 sqlite3_stmt* stmt = (sqlite3_stmt*)reader->native_handles[0];
359 72 return stmt != NULL;
360 }
361
362 9 static gate_result_t gate_data_reader_sqlite3_close(gate_data_reader_base_t* reader)
363 {
364 9 gate_result_t ret = GATE_RESULT_OK;
365 do
366 {
367 /* notice: statement object owns native statement resource, reader has weak pointer to it */
368 9 gate_mem_clear(reader->native_handles, sizeof(reader->native_handles));
369 9 ret = GATE_RESULT_OK;
370 } while (0);
371 9 return ret;
372 }
373
374 7 static gate_result_t gate_data_reader_sqlite3_next(gate_data_reader_base_t* reader)
375 {
376 7 gate_result_t ret = GATE_RESULT_FAILED;
377
378 do
379 {
380 7 sqlite3_stmt* stmt = (sqlite3_stmt*)reader->native_handles[0];
381 int sql3_result;
382 gate_size_t ndx;
383
384
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 7 times.
7 if (!gate_data_reader_base_is_valid(reader))
385 {
386 ret = GATE_RESULT_ENDOFSTREAM;
387 break;
388 }
389
390 7 sql3_result = sqlite3_api.step(stmt);
391
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (SQLITE_DONE == sql3_result)
392 {
393 /* end of data stream reached */
394 3 ret = GATE_RESULT_ENDOFSTREAM;
395 3 gate_data_reader_base_close(reader);
396 3 break;
397 }
398
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (SQLITE_ROW != sql3_result)
399 {
400 /* data read error occured */
401 ret = GATE_RESULT_FAILED;
402 GATE_DEBUG_TRACE_MSG_VALUE("sqlite3_step() failed", sql3_result);
403 break;
404 }
405
406 /* succeeded: */
407
2/2
✓ Branch 0 taken 21 times.
✓ Branch 1 taken 4 times.
25 for (ndx = 0; ndx != reader->field_count; ++ndx)
408 {
409 21 gate_value_t* ptr_value = &reader->values[ndx];
410 int sql3_type;
411
412 21 gate_string_t str = GATE_STRING_INIT_EMPTY;
413
414 21 gate_value_release(ptr_value);
415
416 21 sql3_type = sqlite3_api.column_type(stmt, (int)ndx);
417
4/5
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
21 switch (sql3_type)
418 {
419 9 case SQLITE_INTEGER:
420 {
421 9 gate_int64_t i64 = (gate_int64_t)sqlite3_api.column_int64(stmt, (int)ndx);
422 9 gate_value_create(GATE_TYPE_I64, &i64, ptr_value);
423 9 break;
424 }
425 2 case SQLITE_FLOAT:
426 {
427 2 gate_real64_t r64 = (gate_real64_t)sqlite3_api.column_double(stmt, (int)ndx);
428 2 gate_value_create(GATE_TYPE_R64, &r64, ptr_value);
429 2 break;
430 }
431 2 case SQLITE_BLOB:
432 {
433 2 int byte_count = sqlite3_api.column_bytes(stmt, (int)ndx);
434 2 gate_uint8_t const* byte_ptr = (gate_uint8_t const*)sqlite3_api.column_blob(stmt, (int)ndx);
435 2 gate_arraylist_t arraylist = gate_arraylist_create(1, byte_ptr, (gate_size_t)byte_count, NULL, NULL);
436 2 gate_array_t arr = GATE_INIT_EMPTY;
437 2 gate_array_create(&arr, arraylist);
438 2 gate_value_create(GATE_TYPE_ARRAY, &arr, ptr_value);
439 2 gate_array_release(&arr);
440 2 gate_arraylist_release(arraylist);
441 2 break;
442 }
443 8 case SQLITE_TEXT:
444 {
445 8 int byte_count = sqlite3_api.column_bytes(stmt, (int)ndx);
446 8 char const* text_ptr = (char const*)sqlite3_api.column_text(stmt, (int)ndx);
447 8 gate_string_create(&str, text_ptr, (gate_size_t)byte_count);
448 8 gate_value_create(GATE_TYPE_STRING, &str, ptr_value);
449 8 gate_string_release(&str);
450 8 break;
451 }
452 default:
453 case SQLITE_NULL:
454 {
455 /* already released */
456 break;
457 }
458 }
459 }
460 4 ret = GATE_RESULT_OK;
461 } while (0);
462
463 7 return ret;
464 }
465
466
467 3 static gate_result_t gate_data_reader_sqlite3_init(gate_data_reader_base_t* reader)
468 {
469 3 gate_result_t ret = GATE_RESULT_OK;
470 sqlite3_stmt* stmt;
471 gate_size_t ndx;
472
473
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_DEBUG_ASSERT(reader != NULL);
474
475 3 stmt = (sqlite3_stmt*)reader->native_handles[0];
476 3 reader->field_count = (gate_size_t)sqlite3_api.column_count(stmt);
477
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (reader->field_count > sizeof(reader->names) / sizeof(reader->names[0]))
478 {
479 reader->field_count = sizeof(reader->names) / sizeof(reader->names[0]);
480 }
481
482
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 3 times.
17 for (ndx = 0; ndx != reader->field_count; ++ndx)
483 {
484 14 char const* ptr_name = sqlite3_api.column_name(stmt, (int)ndx);
485
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 14 times.
14 if (NULL == gate_string_create(&reader->names[ndx], ptr_name, gate_str_length(ptr_name)))
486 {
487 ret = GATE_RESULT_OUTOFMEMORY;
488 break;
489 }
490 }
491
492 3 return ret;
493 }
494
495
496 6 static gate_result_t sqlite3_execute_statement(sqlite3* db, sqlite3_stmt* stmt, gate_int32_t* affected_rows)
497 {
498 6 int sql3_result = 0;
499
500 do
501 {
502 6 sql3_result = sqlite3_api.step(stmt);
503
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 } while (sql3_result == SQLITE_ROW);
504
505
1/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
6 switch (sql3_result)
506 {
507 6 case SQLITE_DONE:
508 {
509
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (affected_rows != NULL)
510 {
511 6 *affected_rows = (gate_int32_t)sqlite3_api.changes(db);
512 }
513 6 return GATE_RESULT_OK;
514 }
515 case SQLITE_BUSY:
516 {
517 GATE_DEBUG_TRACE("sqlite DB is busy");
518 return GATE_RESULT_LOCKED;
519 }
520 case SQLITE_ERROR:
521 {
522 GATE_DEBUG_TRACE(sqlite3_api.errmsg(db));
523 return GATE_RESULT_FAILED;
524 }
525 default:
526 {
527 GATE_DEBUG_TRACE_MSG_VALUE("Unknown sqlite3_step() result", sql3_result);
528 return GATE_RESULT_UNKNOWNERROR;
529 }
530 }
531 }
532
533
534 3 static gate_result_t sqlite3_query_statement(gate_data_statement_t* ptr_statement, sqlite3_stmt* stmt, gate_data_reader_t** ptr_reader)
535 {
536 3 gate_data_reader_t* reader = NULL;
537 3 gate_data_handles_t handles = GATE_INIT_EMPTY;
538
539 3 handles[0] = (void*)stmt;
540
541 3 reader = gate_data_reader_base_create(
542 ptr_statement, handles,
543 &gate_data_reader_sqlite3_init,
544 &gate_data_reader_sqlite3_is_valid,
545 &gate_data_reader_sqlite3_next,
546 &gate_data_reader_sqlite3_close);
547
548
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (reader == NULL)
549 {
550 return GATE_RESULT_OUTOFMEMORY;
551 }
552
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (ptr_reader)
553 {
554 3 *ptr_reader = reader;
555 3 reader = NULL;
556 }
557 else
558 {
559 gate_object_release(reader);
560 }
561
562 3 return GATE_RESULT_OK;
563 }
564
565
566 9 static gate_result_t sqlite3stmt_init(gate_data_statement_base_t* impl)
567 {
568 9 gate_result_t ret = GATE_RESULT_FAILED;
569
570
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 GATE_DEBUG_ASSERT(impl != NULL);
571
572 do
573 {
574 9 sqlite3_stmt* stmt = impl->native_handles[1];
575 9 int cnt = sqlite3_api.bind_parameter_count(stmt);
576
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (cnt >= 0)
577 {
578 9 impl->param_count = (gate_size_t)cnt;
579 }
580 9 ret = GATE_RESULT_OK;
581 } while (0);
582
583 9 return ret;
584 }
585
586 9 static void sqlite3stmt_close(gate_data_statement_base_t* impl)
587 {
588 sqlite3_stmt* sql3_statement;
589
590
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 GATE_DEBUG_ASSERT(impl != NULL);
591
592 9 sql3_statement = (sqlite3_stmt*)impl->native_handles[1];
593 9 impl->native_handles[1] = NULL;
594
595
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (sql3_statement != NULL)
596 {
597 9 sqlite3_api.finalize(sql3_statement);
598 }
599 9 }
600
601 6 static gate_result_t sql3_bind_int(sqlite3_stmt* stmt, int index, gate_int64_t value)
602 {
603 6 int sql3_result = sqlite3_api.bind_int64(stmt, index, value);
604 6 return sqlite3_error_to_gate_result(sql3_result);
605 }
606
607 2 static gate_result_t sql3_bind_real(sqlite3_stmt* stmt, int index, gate_real64_t value)
608 {
609 2 int sql3_result = sqlite3_api.bind_double(stmt, index, value);
610 2 return sqlite3_error_to_gate_result(sql3_result);
611 }
612
613 2 static gate_result_t sql3_bind_blob(sqlite3_stmt* stmt, int index, void const* data, gate_size_t len)
614 {
615 int sql3_result;
616 2 char* buffer = NULL;
617
618
2/4
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
2 if ((len == 0) || (data == NULL))
619 {
620 sql3_result = sqlite3_api.bind_blob(stmt, index, NULL, 0, NULL);
621 }
622 else
623 {
624 2 buffer = gate_mem_alloc(len);
625
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (buffer == NULL)
626 {
627 return GATE_RESULT_OUTOFMEMORY;
628 }
629 2 gate_mem_copy(buffer, data, len);
630 2 sql3_result = sqlite3_api.bind_blob(stmt, index, buffer, (int)len, &gate_mem_dealloc);
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (sql3_result != SQLITE_OK)
632 {
633 gate_mem_dealloc(buffer);
634 }
635 }
636 2 return sqlite3_error_to_gate_result(sql3_result);
637 }
638
639 7 static gate_result_t sql3_bind_text(sqlite3_stmt* stmt, int index, char const* text, gate_size_t len)
640 {
641 int sql3_result;
642 7 char* buffer = NULL;
643
644
2/4
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 7 times.
7 if ((len == 0) || (text == NULL))
645 {
646 sql3_result = sqlite3_api.bind_text(stmt, index, NULL, 0, NULL);
647 }
648 else
649 {
650 7 buffer = gate_mem_alloc(len + 1);
651
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (buffer == NULL)
652 {
653 return GATE_RESULT_OUTOFMEMORY;
654 }
655 7 gate_mem_copy(buffer, text, len);
656 7 buffer[len] = 0;
657 7 sql3_result = sqlite3_api.bind_text(stmt, index, buffer, (int)len, &gate_mem_dealloc);
658
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (sql3_result != SQLITE_OK)
659 {
660 gate_mem_dealloc(buffer);
661 }
662 }
663 7 return sqlite3_error_to_gate_result(sql3_result);
664 }
665
666 17 static gate_result_t sqlite3stmt_set_param(gate_data_statement_base_t* self, gate_size_t param_index, gate_value_t const* value)
667 {
668 17 gate_result_t ret = GATE_RESULT_FAILED;
669 sqlite3_stmt* stmt;
670 int param_count;
671 17 int index = (int)param_index;
672
673
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
17 GATE_DEBUG_ASSERT(self != NULL);
674
675 17 stmt = (sqlite3_stmt*)self->native_handles[1];
676 17 param_count = sqlite3_api.bind_parameter_count(stmt);
677
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
17 if ((index == 0) || (index > param_count))
678 {
679 return GATE_RESULT_OUTOFBOUNDS;
680 }
681
682
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 17 times.
17 if ((value == NULL) || (value->value_type == GATE_TYPE_EMPTY))
683 {
684 int sql3_result = sqlite3_api.bind_null(stmt, index);
685 return sqlite3_error_to_gate_result(sql3_result);
686 }
687 else
688 {
689 gate_cstrbuffer8_t buffer;
690 17 gate_datetime_t dt = GATE_INIT_EMPTY;
691 gate_size_t len;
692
693
14/20
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 1 times.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✓ Branch 10 taken 1 times.
✓ Branch 11 taken 2 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2 times.
✓ Branch 14 taken 1 times.
✓ Branch 15 taken 1 times.
✓ Branch 16 taken 1 times.
✓ Branch 17 taken 1 times.
✓ Branch 18 taken 1 times.
✗ Branch 19 not taken.
17 switch (value->value_type)
694 {
695 case GATE_TYPE_BOOL: return sql3_bind_int(stmt, index, value->content.bool_value);
696 2 case GATE_TYPE_I8: return sql3_bind_int(stmt, index, value->content.i8_value);
697 case GATE_TYPE_UI8: return sql3_bind_int(stmt, index, value->content.ui8_value);
698 1 case GATE_TYPE_I16: return sql3_bind_int(stmt, index, value->content.i16_value);
699 1 case GATE_TYPE_UI16: return sql3_bind_int(stmt, index, value->content.ui16_value);
700 1 case GATE_TYPE_I32: return sql3_bind_int(stmt, index, value->content.i32_value);
701 1 case GATE_TYPE_UI32: return sql3_bind_int(stmt, index, value->content.ui32_value);
702 case GATE_TYPE_I64: return sql3_bind_int(stmt, index, value->content.i64_value);
703 case GATE_TYPE_UI64: return sql3_bind_int(stmt, index, value->content.ui64_value);
704
705 1 case GATE_TYPE_R32: return sql3_bind_real(stmt, index, value->content.r32_value);
706 1 case GATE_TYPE_R64: return sql3_bind_real(stmt, index, value->content.r64_value);
707
708 2 case GATE_TYPE_BLOB: return sql3_bind_blob(stmt, index, value->content.blob_value.data, value->content.blob_value.length);
709
710 case GATE_TYPE_CSTR: return sql3_bind_text(stmt, index, value->content.cstring_value, gate_str_length(value->content.cstring_value));
711 2 case GATE_TYPE_STRING: return sql3_bind_text(stmt, index, value->content.string_value.str, value->content.string_value.length);
712 1 case GATE_TYPE_WSTR:
713 {
714
1/2
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (NULL == gate_cstrbuffer_create_wstr(&buffer, value->content.wstring_value, gate_wstr_length(value->content.wstring_value)))
715 {
716 return GATE_RESULT_OUTOFMEMORY;
717 }
718 1 ret = sql3_bind_text(stmt, index, gate_cstrbuffer_get(&buffer), gate_cstrbuffer_length(&buffer));
719 1 gate_cstrbuffer_destroy(&buffer);
720 1 return ret;
721 }
722 1 case GATE_TYPE_GUID:
723 {
724 1 ret = gate_guid_to_string(&value->content.guid_value, buffer.local_buffer);
725
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_RETURN_IF_FAILED(ret);
726 1 return sql3_bind_text(stmt, index, buffer.local_buffer, gate_str_length(buffer.local_buffer));
727 }
728 1 case GATE_TYPE_DATE:
729 {
730 1 dt.date = value->content.date_value;
731 1 len = sizeof(buffer.local_buffer);
732 1 ret = gate_date_to_string(&dt, 0, "{YYYY}-{MM}-{DD}", buffer.local_buffer, &len);
733
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_RETURN_IF_FAILED(ret);
734 1 return sql3_bind_text(stmt, index, buffer.local_buffer, len);
735 }
736 1 case GATE_TYPE_DATETIME:
737 {
738 1 len = sizeof(buffer.local_buffer);
739 1 ret = gate_date_to_string(&value->content.datetime_value, 0, "{YYYY}-{MM}-{DD} {hh}:{mm}:{ss}", buffer.local_buffer, &len);
740
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_RETURN_IF_FAILED(ret);
741 1 return sql3_bind_text(stmt, index, buffer.local_buffer, len);
742 }
743 1 case GATE_TYPE_TIME:
744 {
745 1 ret = gate_time_to_datetime(&value->content.time_value, &dt);
746
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_RETURN_IF_FAILED(ret);
747 1 len = sizeof(buffer.local_buffer);
748 1 ret = gate_date_to_string(&dt, 0, "{YYYY}-{MM}-{DD} {hh}:{mm}:{ss}", buffer.local_buffer, &len);
749
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_RETURN_IF_FAILED(ret);
750 1 return sql3_bind_text(stmt, index, buffer.local_buffer, len);
751 }
752
753 case GATE_TYPE_PROPERTY:
754 default:
755 return GATE_RESULT_INCORRECTTYPE;
756 }
757 }
758 return ret;
759 }
760 6 static gate_result_t sqlite3stmt_set_named_param(gate_data_statement_base_t* self, gate_string_t const* name, gate_value_t const* value)
761 {
762 6 gate_result_t ret = GATE_RESULT_FAILED;
763 sqlite3_stmt* sql3_statement;
764 int param_count;
765 int param_ndx;
766
767
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 GATE_DEBUG_ASSERT(self != NULL);
768
769 6 sql3_statement = (sqlite3_stmt*)self->native_handles[1];
770 6 param_count = sqlite3_api.bind_parameter_count(sql3_statement);
771
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 for (param_ndx = 1; param_ndx <= param_count; ++param_ndx)
772 {
773 21 char const* param_name = sqlite3_api.bind_parameter_name(sql3_statement, param_ndx);
774
2/2
✓ Branch 1 taken 6 times.
✓ Branch 2 taken 15 times.
21 if (gate_string_equals_str(name, param_name))
775 {
776 /* named parameter found, access it by index */
777 6 return sqlite3stmt_set_param(self, (gate_size_t)param_ndx, value);
778 }
779 }
780 /* no parameter was found */
781 return GATE_RESULT_NOMATCH;
782 }
783 3 static gate_result_t sqlite3stmt_reset(gate_data_statement_base_t* self)
784 {
785 sqlite3_stmt* sql3_statement;
786 int sql3_result;
787
788
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_DEBUG_ASSERT(self != NULL);
789
790 3 sql3_statement = (sqlite3_stmt*)self->native_handles[1];
791 3 sql3_result = sqlite3_api.clear_bindings(sql3_statement);
792
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sql3_result != SQLITE_OK)
793 {
794 return sqlite3_error_to_gate_result(sql3_result);
795 }
796
797 3 sql3_result = sqlite3_api.reset(sql3_statement);
798
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sql3_result != SQLITE_OK)
799 {
800 return sqlite3_error_to_gate_result(sql3_result);
801 }
802
803 3 return GATE_RESULT_OK;
804 }
805 6 static gate_result_t sqlite3stmt_execute(gate_data_statement_base_t* self, gate_int32_t* affected_rows)
806 {
807 6 gate_result_t ret = GATE_RESULT_FAILED;
808 sqlite3* db;
809 sqlite3_stmt* stmt;
810
811
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 GATE_DEBUG_ASSERT(self != NULL);
812
813 6 db = (sqlite3*)self->native_handles[0];
814 6 stmt = (sqlite3_stmt*)self->native_handles[1];
815 6 return sqlite3_execute_statement(db, stmt, affected_rows);
816 }
817 3 static gate_result_t sqlite3stmt_query(gate_data_statement_base_t* self, gate_data_reader_t** ptr_reader)
818 {
819 sqlite3_stmt* sql3_statement;
820
821
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_DEBUG_ASSERT(self != NULL);
822 3 sql3_statement = (sqlite3_stmt*)self->native_handles[1];
823 3 return sqlite3_query_statement((gate_data_statement_t*)self, sql3_statement, ptr_reader);
824 }
825
826 9 static gate_result_t gate_data_connection_sqlite3_create_statement(
827 gate_data_connection_base_t* self,
828 gate_string_t const* sql,
829 gate_data_statement_t** ptr_statement)
830 {
831 9 gate_result_t ret = GATE_RESULT_FAILED;
832 9 gate_data_statement_base_t* ptr_stmt_base = NULL;
833 9 gate_string_t cmd = GATE_STRING_INIT_EMPTY;
834
835
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 GATE_DEBUG_ASSERT(self != NULL);
836
837 do
838 {
839 gate_data_handles_t handles;
840 9 sqlite3* db = self->native_handles[0];
841 9 sqlite3_stmt* sql3_statement = NULL;
842 int sql3_result;
843
844
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 9 times.
9 if (gate_string_is_empty(sql))
845 {
846 ret = GATE_RESULT_INVALIDARG;
847 break;
848 }
849
850
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (sql->str[sql->length] == '\0')
851 {
852 9 gate_string_duplicate(&cmd, sql);
853 }
854 else
855 {
856 if (NULL == gate_string_create(&cmd, gate_string_ptr(sql, 0), gate_string_length(sql)))
857 {
858 ret = GATE_RESULT_OUTOFMEMORY;
859 break;
860 }
861 }
862
863 9 gate_mem_clear(&handles[0], sizeof(handles));
864
865 9 sql3_result = sqlite3_api.prepare(db, cmd.str, (int)cmd.length, &sql3_statement, NULL);
866
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (sql3_result != SQLITE_OK)
867 {
868 ret = GATE_RESULT_FAILED;
869 GATE_DEBUG_TRACE_MSG_VALUE("sqlite3_prepare() failed", sql3_result);
870 break;
871 }
872
873 9 handles[0] = (void*)db;
874 9 handles[1] = (void*)sql3_statement;
875
876 9 ret = gate_data_statement_base_create(
877 self, handles, sql,
878 &sqlite3stmt_init,
879 &sqlite3stmt_close,
880 &sqlite3stmt_set_param,
881 &sqlite3stmt_set_named_param,
882 &sqlite3stmt_reset,
883 &sqlite3stmt_execute,
884 &sqlite3stmt_query,
885 &ptr_stmt_base);
886
887
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (GATE_FAILED(ret))
888 {
889 sqlite3_api.finalize(sql3_statement);
890 break;
891 }
892
893 /* success case: */
894
1/2
✓ Branch 0 taken 9 times.
✗ Branch 1 not taken.
9 if (ptr_statement)
895 {
896 9 *ptr_statement = (gate_data_statement_t*)ptr_stmt_base;
897 9 ptr_stmt_base = NULL;
898 }
899 } while (0);
900
901
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (ptr_stmt_base != NULL)
902 {
903 gate_object_release(ptr_stmt_base);
904 ptr_stmt_base = NULL;
905 }
906
907 9 gate_string_release(&cmd);
908 9 return ret;
909 }
910
911
912 3 static gate_result_t gate_data_connection_sqlite3_init(gate_data_connection_base_t* self)
913 {
914 //static gate_string_t const init_commands = GATE_STRING_INIT_STATIC("PRAGMA foreign_keys = ON");
915 //gate_data_connection_execute(self, &init_commands, NULL);
916 3 return GATE_RESULT_OK;
917 }
918
919 3 static void gate_data_connection_sqlite3_close(gate_data_connection_base_t* self)
920 {
921 sqlite3* db;
922
923
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_DEBUG_ASSERT(self != NULL);
924
925 3 db = (sqlite3*)self->native_handles[0];
926
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (db != NULL)
927 {
928 3 sqlite3_api.close(db);
929 }
930 3 gate_mem_clear(self->native_handles, sizeof(self->native_handles));
931 3 }
932
933
934
935 3 gate_result_t gate_data_adapter_sqlite3_create(gate_string_t const* path, gate_enumint_t flags, gate_data_connection_t** ptr_connection)
936 {
937 gate_result_t ret;
938 3 sqlite3* db = NULL;
939
940 do
941 {
942 char file_path[GATE_MAX_FILEPATH_LENGTH];
943 int sql3_result;
944 3 int sql3_flags = 0;
945 3 gate_data_handles_t handles = GATE_INIT_EMPTY;
946
947 3 ret = gate_data_sqlite3_api_init();
948
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_BREAK_IF_FAILED(ret);
949
950
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (GATE_FLAG_ENABLED(flags, GATE_DATA_SQLITE3_FLAG_READONLY))
951 {
952 sql3_flags = SQLITE_OPEN_READONLY;
953 }
954 else
955 {
956 3 sql3_flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
957 }
958
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 GATE_FLAG_SET(sql3_flags, SQLITE_OPEN_NOMUTEX, !(GATE_FLAG_ENABLED(flags, GATE_DATA_SQLITE3_FLAG_SERIALIZED)));
959
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_FLAG_SET(sql3_flags, SQLITE_OPEN_FULLMUTEX, GATE_FLAG_ENABLED(flags, GATE_DATA_SQLITE3_FLAG_SERIALIZED));
960
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_FLAG_SET(sql3_flags, SQLITE_OPEN_SHAREDCACHE, GATE_FLAG_ENABLED(flags, GATE_DATA_SQLITE3_FLAG_SHAREDCACHE));
961
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 GATE_FLAG_SET(sql3_flags, SQLITE_OPEN_MEMORY, GATE_FLAG_ENABLED(flags, GATE_DATA_SQLITE3_FLAG_INMEMORY));
962
963 3 gate_string_to_buffer(path, file_path, sizeof(file_path));
964 3 sql3_result = sqlite3_api.open_v2(file_path, &db, sql3_flags, NULL);
965
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (sql3_result != SQLITE_OK)
966 {
967 GATE_DEBUG_TRACE_MSG_VALUE("sqlite3_open() failed", sql3_result);
968 ret = GATE_RESULT_FAILED;
969 break;
970 }
971
972 3 handles[0] = (void*)db;
973
974 3 ret = gate_data_connection_base_create(handles,
975 &gate_data_connection_sqlite3_init,
976 &gate_data_connection_sqlite3_close,
977 //&gate_data_connection_sqlite3_execute,
978 //&gate_data_connection_sqlite3_query,
979 &gate_data_connection_sqlite3_create_statement,
980 ptr_connection);
981
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_BREAK_IF_FAILED(ret);
982
983 /* success case*/
984 3 db = NULL;
985 } while (0);
986
987
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (db != NULL)
988 {
989 sqlite3_api.close(db);
990 }
991
992 3 return ret;
993 }
994
995 #endif /* GATE_DATA_SQLITE3_LIB_IMPL */
996
997 #if defined(GATE_DATA_SQLITE3_NO_IMPL)
998
999 gate_result_t gate_data_adapter_sqlite3_create(
1000 gate_string_t const* path, gate_enumint_t flags,
1001 gate_data_connection_t** ptr_connection)
1002 {
1003 (void)path;
1004 (void)flags;
1005 (void)ptr_connection;
1006 return GATE_RESULT_NOTIMPLEMENTED;
1007 }
1008
1009 #endif /* GATE_DATA_SQLITE3_NO_IMPL */
1010
1011