GCC Code Coverage Report


Directory: src/gate/
File: src/gate/data/sqlite3_adapter.c
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 238 364 65.4%
Functions: 22 23 95.7%
Branches: 67 183 36.6%

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