GCC Code Coverage Report


Directory: src/gate/
File: src/gate/data/adapter_base.h
Date: 2026-08-06 22:46:24
Exec Total Coverage
Lines: 211 250 84.4%
Functions: 27 30 90.0%
Branches: 54 94 57.4%

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
29 /** @file
30 * @brief Data adapter generator utilities
31 * @ingroup gatedata
32 */
33
34 #ifndef GATE_DATA_ADAPTER_BASE_H_INCLUDED
35 #define GATE_DATA_ADAPTER_BASE_H_INCLUDED
36
37 #include "gate/data/adapter.h"
38 #include "gate/results.h"
39
40 #if defined(__cplusplus)
41 extern "C" {
42 #endif
43
44
45 /***********************************
46 * data reader base implementation *
47 ***********************************/
48
49 #define GATE_DATA_ADAPTER_BASE_READER_MAX_FIELDS 64
50 typedef void* gate_data_handles_t[4];
51
52 typedef struct gate_data_reader_base_class gate_data_reader_base_t;
53
54 struct gate_data_reader_base_class
55 {
56 GATE_INTERFACE_VTBL(gate_data_reader) const* vtbl;
57
58 gate_atomic_int_t ref_counter;
59
60 gate_data_statement_t* statement;
61 gate_data_handles_t native_handles; /* DB native query handles */
62 gate_size_t field_count; /* amount of data fields (columns) in query result */
63
64 gate_string_t names[GATE_DATA_ADAPTER_BASE_READER_MAX_FIELDS]; /* column names */
65 gate_type_id_t types[GATE_DATA_ADAPTER_BASE_READER_MAX_FIELDS]; /* column field data types */
66 gate_value_t values[GATE_DATA_ADAPTER_BASE_READER_MAX_FIELDS]; /* currently loaded column field values */
67 void* params[GATE_DATA_ADAPTER_BASE_READER_MAX_FIELDS]; /* additional column parameters */
68
69 gate_result_t(*init)(gate_data_reader_base_t* reader); /* prepares names, types and params fields*/
70 gate_bool_t(*is_valid)(gate_data_reader_base_t* reader); /* returns true if data row is loaded and valid */
71 gate_result_t(*next)(gate_data_reader_base_t* reader); /* discards current data row and loads next one int values */
72 gate_result_t(*close)(gate_data_reader_base_t* reader); /* closes DB query resources and releases field values */
73 };
74
75
76 113 static gate_bool_t gate_data_reader_base_is_valid(void* This)
77 {
78 113 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
79
1/2
✓ Branch 0 taken 113 times.
✗ Branch 1 not taken.
113 if (self->is_valid)
80 {
81 113 return self->is_valid(self);
82 }
83 return false;
84 }
85
86 15 static gate_result_t gate_data_reader_base_close(void* This)
87 {
88 15 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
89 15 gate_result_t ret = GATE_RESULT_NOTSUPPORTED;
90 gate_size_t ndx;
91 do
92 {
93
1/2
✓ Branch 0 taken 15 times.
✗ Branch 1 not taken.
15 if (self->close)
94 {
95 15 ret = self->close(self);
96
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 GATE_BREAK_IF_FAILED(ret);
97 }
98
2/2
✓ Branch 0 taken 81 times.
✓ Branch 1 taken 15 times.
96 for (ndx = 0; ndx != self->field_count; ++ndx)
99 {
100 81 gate_string_release(&self->names[ndx]);
101 81 gate_value_release(&self->values[ndx]);
102 }
103 15 gate_mem_clear(self->names, sizeof(self->names));
104 15 gate_mem_clear(self->values, sizeof(self->values));
105
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 10 times.
15 if (self->statement)
106 {
107 5 gate_object_release(self->statement);
108 5 self->statement = NULL;
109 }
110 15 ret = GATE_RESULT_OK;
111 } while (0);
112 15 return ret;
113 }
114
115 11 static gate_result_t gate_data_reader_base_next(void* This)
116 {
117 11 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
118
1/2
✓ Branch 0 taken 11 times.
✗ Branch 1 not taken.
11 if (self->next)
119 {
120 11 return self->next(self);
121 }
122 return GATE_RESULT_NOTSUPPORTED;
123 }
124
125 5 static gate_size_t gate_data_reader_base_get_field_count(void* This)
126 {
127 5 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
128 5 return self->field_count;
129 }
130 34 static gate_result_t gate_data_reader_base_get_field_type(void* This, gate_size_t field_index, gate_type_id_t* ptr_type)
131 {
132 34 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
133 34 gate_result_t ret = GATE_RESULT_FAILED;
134 do
135 {
136
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
34 if (!gate_data_reader_base_is_valid(self))
137 {
138 ret = GATE_RESULT_ENDOFSTREAM;
139 break;
140 }
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if (field_index >= self->field_count)
142 {
143 ret = GATE_RESULT_OUTOFBOUNDS;
144 break;
145 }
146
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 if (ptr_type)
147 {
148 34 *ptr_type = self->values[field_index].value_type;
149 }
150 34 ret = GATE_RESULT_OK;
151 } while (0);
152 34 return ret;
153 }
154 33 static gate_result_t gate_data_reader_base_get_field_name(void* This, gate_size_t field_index, gate_string_t const** ptr_name)
155 {
156 33 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
157 33 gate_result_t ret = GATE_RESULT_FAILED;
158 do
159 {
160
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 33 times.
33 if (!gate_data_reader_base_is_valid(self))
161 {
162 ret = GATE_RESULT_ENDOFSTREAM;
163 break;
164 }
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 33 times.
33 if (field_index >= self->field_count)
166 {
167 ret = GATE_RESULT_OUTOFBOUNDS;
168 break;
169 }
170
1/2
✓ Branch 0 taken 33 times.
✗ Branch 1 not taken.
33 if (ptr_name)
171 {
172 33 *ptr_name = &self->names[field_index];
173 }
174 33 ret = GATE_RESULT_OK;
175 } while (0);
176 33 return ret;
177 }
178 34 static gate_result_t gate_data_reader_base_get_field_value(void* This, gate_size_t field_index, gate_value_t const** ptr_value)
179 {
180 34 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
181 34 gate_result_t ret = GATE_RESULT_FAILED;
182 do
183 {
184
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 34 times.
34 if (!gate_data_reader_base_is_valid(self))
185 {
186 ret = GATE_RESULT_ENDOFSTREAM;
187 break;
188 }
189
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
34 if (field_index >= self->field_count)
190 {
191 ret = GATE_RESULT_OUTOFBOUNDS;
192 break;
193 }
194
1/2
✓ Branch 0 taken 34 times.
✗ Branch 1 not taken.
34 if (ptr_value)
195 {
196 34 *ptr_value = &self->values[field_index];
197 }
198 34 ret = GATE_RESULT_OK;
199 } while (0);
200 34 return ret;
201 }
202
203 static char const* gate_data_reader_base_get_interface_name(void* This)
204 {
205 GATE_UNUSED_ARG(This);
206 return GATE_INTERFACE_NAME_DATA_READER;
207 }
208
209 5 static void gate_data_reader_base_release(void* This)
210 {
211 5 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
212
1/2
✓ Branch 1 taken 5 times.
✗ Branch 2 not taken.
5 if (0 == gate_atomic_int_dec(&self->ref_counter))
213 {
214 5 gate_data_reader_base_close(This);
215 5 gate_mem_dealloc(self);
216 }
217 5 }
218
219 static int gate_data_reader_base_retain(void* This)
220 {
221 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
222 return gate_atomic_int_inc(&self->ref_counter);
223 }
224
225
226 5 static GATE_INTERFACE_VTBL(gate_data_reader) const* gate_init_data_reader_base_vtbl(void)
227 {
228 static GATE_INTERFACE_VTBL(gate_data_reader) gate_data_reader_base_vtbl;
229
230
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (!gate_data_reader_base_vtbl.get_interface_name)
231 {
232 GATE_INTERFACE_VTBL(gate_data_reader) const local_vtbl =
233 {
234 &gate_data_reader_base_get_interface_name,
235 &gate_data_reader_base_release,
236 &gate_data_reader_base_retain,
237
238 &gate_data_reader_base_is_valid,
239 &gate_data_reader_base_next,
240 &gate_data_reader_base_close,
241 &gate_data_reader_base_get_field_count,
242 &gate_data_reader_base_get_field_type,
243 &gate_data_reader_base_get_field_name,
244 &gate_data_reader_base_get_field_value
245 };
246
247 3 gate_data_reader_base_vtbl = local_vtbl;
248 }
249 5 return &gate_data_reader_base_vtbl;
250 }
251
252 5 static gate_data_reader_t* gate_data_reader_base_create(gate_data_statement_t* statement,
253 gate_data_handles_t handles,
254 gate_result_t(*init)(gate_data_reader_base_t* reader),
255 gate_bool_t(*is_valid)(gate_data_reader_base_t* reader),
256 gate_result_t(*next)(gate_data_reader_base_t* reader),
257 gate_result_t(*close)(gate_data_reader_base_t* reader))
258 {
259 5 gate_data_reader_t* ret = NULL;
260 5 gate_data_reader_base_t* reader = NULL;
261 gate_result_t res;
262
263 do
264 {
265 5 reader = (gate_data_reader_base_t*)gate_mem_alloc(sizeof(gate_data_reader_base_t));
266
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (reader == NULL)
267 {
268 break;
269 }
270 5 gate_mem_clear(reader, sizeof(gate_data_reader_base_t));
271 5 reader->vtbl = gate_init_data_reader_base_vtbl();
272 5 gate_atomic_int_init(&reader->ref_counter, 1);
273
274 5 gate_mem_copy(reader->native_handles, handles, sizeof(reader->native_handles));
275 5 reader->statement = statement;
276
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (reader->statement)
277 {
278 5 gate_object_retain(reader->statement);
279 }
280 5 reader->field_count = 0;
281
282 5 reader->init = init;
283 5 reader->is_valid = is_valid;
284 5 reader->next = next;
285 5 reader->close = close;
286
287
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (reader->init)
288 {
289 5 res = reader->init(reader);
290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (GATE_FAILED(res))
291 {
292 gate_mem_dealloc(reader);
293 break;
294 }
295 }
296
297 5 ret = (gate_data_reader_t*)reader;
298 5 reader = NULL;
299 } while (0);
300 5 return ret;
301 }
302
303
304
305 /***************************************
306 * data connection base implementation *
307 ***************************************/
308
309 typedef struct gate_data_connection_base_class gate_data_connection_base_t;
310
311 struct gate_data_connection_base_class
312 {
313 GATE_INTERFACE_VTBL(gate_data_connection) const* vtbl;
314
315 gate_atomic_int_t ref_counter;
316 gate_data_handles_t native_handles;
317
318 gate_result_t(*init)(gate_data_connection_base_t* self);
319 void(*close)(gate_data_connection_base_t* self);
320 gate_result_t(*create_statement)(gate_data_connection_base_t* self, gate_string_t const* sql, gate_data_statement_t** ptr_stmt);
321 };
322
323 2 static char const* gate_data_connection_base_get_interface_name(void* This)
324 {
325 GATE_UNUSED_ARG(This);
326 2 return GATE_INTERFACE_NAME_DATA_CONNECTION;
327 }
328 39 static void gate_data_connection_base_release(void* This)
329 {
330 39 gate_data_connection_base_t* self = (gate_data_connection_base_t*)This;
331
2/2
✓ Branch 1 taken 7 times.
✓ Branch 2 taken 32 times.
39 if (0 == gate_atomic_int_dec(&self->ref_counter))
332 {
333
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (self->close)
334 {
335 7 self->close(self);
336 }
337 7 gate_mem_dealloc(self);
338 }
339 39 }
340 32 static int gate_data_connection_base_retain(void* This)
341 {
342 32 gate_data_connection_base_t* self = (gate_data_connection_base_t*)This;
343 32 return (int)gate_atomic_int_inc(&self->ref_counter);
344 }
345
346 25 static gate_result_t gate_data_connection_base_create_statement(void* This, gate_string_t const* sql, gate_data_statement_t** ptr_stmt)
347 {
348 25 gate_data_connection_base_t* self = (gate_data_connection_base_t*)This;
349
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (self->create_statement)
350 {
351 25 return self->create_statement(self, sql, ptr_stmt);
352 }
353 return GATE_RESULT_NOTSUPPORTED;
354 }
355
356 static GATE_INTERFACE_VTBL(gate_data_connection) gate_data_connection_base_vtbl;
357 7 static void gate_init_data_connection_base_vtbl(void)
358 {
359
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (!gate_data_connection_base_vtbl.get_interface_name)
360 {
361 GATE_INTERFACE_VTBL(gate_data_connection) const local_vtbl =
362 {
363 &gate_data_connection_base_get_interface_name,
364 &gate_data_connection_base_release,
365 &gate_data_connection_base_retain,
366
367 &gate_data_connection_base_create_statement
368 };
369 3 gate_data_connection_base_vtbl = local_vtbl;
370 }
371 7 }
372
373 7 static gate_result_t gate_data_connection_base_create(gate_data_handles_t handles,
374 gate_result_t(*init)(gate_data_connection_base_t* self),
375 void(*close)(gate_data_connection_base_t* self),
376 gate_result_t(*create_stmt)(gate_data_connection_base_t* self, gate_string_t const* sql, gate_data_statement_t** ptr_stmt),
377 gate_data_connection_t** ptr_connection)
378 {
379 7 gate_result_t ret = GATE_RESULT_FAILED;
380 7 gate_data_connection_base_t* conn = NULL;
381
382 do
383 {
384 7 conn = (gate_data_connection_base_t*)gate_mem_alloc(sizeof(gate_data_connection_base_t));
385
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (conn == NULL)
386 {
387 ret = GATE_RESULT_OUTOFMEMORY;
388 break;
389 }
390 7 gate_mem_clear(conn, sizeof(gate_data_connection_base_t));
391 7 gate_init_data_connection_base_vtbl();
392 7 conn->vtbl = &gate_data_connection_base_vtbl;
393 7 gate_atomic_int_init(&conn->ref_counter, 1);
394 7 gate_mem_copy(conn->native_handles, handles, sizeof(conn->native_handles));
395
396 7 conn->init = init;
397 7 conn->close = close;
398 7 conn->create_statement = create_stmt;
399
400
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (conn->init)
401 {
402 7 ret = conn->init(conn);
403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 GATE_BREAK_IF_FAILED(ret);
404 }
405
406
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (ptr_connection)
407 {
408 7 *ptr_connection = (gate_data_connection_t*)conn;
409 7 conn = NULL;
410 }
411 7 ret = GATE_RESULT_OK;
412 } while (0);
413
414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
7 if (conn != NULL)
415 {
416 gate_object_release(conn);
417 }
418 7 return ret;
419 }
420
421
422
423 /**************************************
424 * data statement base implementation *
425 **************************************/
426
427 typedef struct gate_data_statement_base_class gate_data_statement_base_t;
428
429 struct gate_data_statement_base_class
430 {
431 GATE_INTERFACE_VTBL(gate_data_statement) const* vtbl;
432
433 gate_atomic_int_t ref_counter;
434 gate_data_handles_t native_handles;
435 gate_data_connection_t* connection;
436 gate_string_t sql;
437 gate_size_t param_count;
438
439 void(*close)(gate_data_statement_base_t* self);
440
441 gate_result_t(*set_param)(gate_data_statement_base_t* self, gate_size_t index, gate_value_t const* value);
442 gate_result_t(*set_named_param)(gate_data_statement_base_t* self, gate_string_t const* name, gate_value_t const* value);
443
444 gate_result_t(*reset)(gate_data_statement_base_t* self);
445 gate_result_t(*execute)(gate_data_statement_base_t* self, gate_int32_t* affected_rows);
446 gate_result_t(*query)(gate_data_statement_base_t* self, gate_data_reader_t** ptr_reader);
447 };
448
449 25 static void statement_base_close(gate_data_statement_base_t* self)
450 {
451
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (self->close)
452 {
453 25 self->close(self);
454 }
455 25 gate_string_release(&self->sql);
456
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (self->connection)
457 {
458 25 gate_object_release(self->connection);
459 25 self->connection = NULL;
460 }
461 25 }
462
463 static char const* statement_base_get_interface_name(void* This)
464 {
465 GATE_UNUSED_ARG(This);
466 return GATE_INTERFACE_NAME_DATA_STATEMENT;
467 }
468
469 30 static void statement_base_release(void* This)
470 {
471 30 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
472
2/2
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 5 times.
30 if (0 == gate_atomic_int_dec(&self->ref_counter))
473 {
474 25 statement_base_close(self);
475 25 gate_mem_dealloc(self);
476 }
477 30 }
478
479 5 static int statement_base_retain(void* This)
480 {
481 5 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
482 5 return gate_atomic_int_inc(&self->ref_counter);
483 }
484
485 7 static gate_result_t statement_base_get_param_count(void* This, gate_size_t* ptr_count)
486 {
487 7 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
488
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (ptr_count)
489 {
490 7 *ptr_count = self->param_count;
491 7 return GATE_RESULT_OK;
492 }
493 return GATE_RESULT_INVALIDARG;
494
495 }
496 24 static gate_result_t statement_base_set_param(void* This, gate_size_t index, gate_value_t const* value)
497 {
498 24 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
499
1/2
✓ Branch 0 taken 24 times.
✗ Branch 1 not taken.
24 if (self->set_param)
500 {
501 24 return self->set_param(self, index, value);
502 }
503 return GATE_RESULT_NOTSUPPORTED;
504 }
505 6 static gate_result_t statement_base_set_named_param(void* This, gate_string_t const* name, gate_value_t const* value)
506 {
507 6 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
508
1/2
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
6 if (self->set_named_param)
509 {
510 6 return self->set_named_param(self, name, value);
511 }
512 return GATE_RESULT_NOTSUPPORTED;
513 }
514
515 7 static gate_result_t statement_base_reset(void* This)
516 {
517 7 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
518
1/2
✓ Branch 0 taken 7 times.
✗ Branch 1 not taken.
7 if (self->reset)
519 {
520 7 return self->reset(self);
521 }
522 return GATE_RESULT_NOTSUPPORTED;
523 }
524 20 static gate_result_t statement_base_execute(void* This, gate_int32_t* affected_rows)
525 {
526 20 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
527
1/2
✓ Branch 0 taken 20 times.
✗ Branch 1 not taken.
20 if (self->execute)
528 {
529 20 return self->execute(self, affected_rows);
530 }
531 return GATE_RESULT_NOTSUPPORTED;
532 }
533 5 static gate_result_t statement_base_query(void* This, gate_data_reader_t** ptr_reader)
534 {
535 5 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
536
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 if (self->query)
537 {
538 5 return self->query(self, ptr_reader);
539 }
540 return GATE_RESULT_NOTSUPPORTED;
541 }
542
543
544 25 static GATE_INTERFACE_VTBL(gate_data_statement) const* statement_base_vtbl(void)
545 {
546 static GATE_INTERFACE_VTBL(gate_data_statement) vtbl;
547
548
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 22 times.
25 if (vtbl.get_interface_name == NULL)
549 {
550 3 vtbl.get_interface_name = &statement_base_get_interface_name;
551 3 vtbl.release = &statement_base_release;
552 3 vtbl.retain = &statement_base_retain;
553
554 3 vtbl.get_param_count = &statement_base_get_param_count;
555 3 vtbl.set_param = &statement_base_set_param;
556 3 vtbl.set_named_param = &statement_base_set_named_param;
557
558 3 vtbl.reset = &statement_base_reset;
559 3 vtbl.execute = &statement_base_execute;
560 3 vtbl.query = &statement_base_query;
561 }
562 25 return &vtbl;
563 }
564
565 25 static gate_result_t gate_data_statement_base_create(
566 gate_data_connection_base_t* connection,
567 gate_data_handles_t handles,
568 gate_string_t const* sql,
569 gate_result_t(*init)(gate_data_statement_base_t* self),
570 void(*close)(gate_data_statement_base_t* self),
571 gate_result_t(*set_param)(gate_data_statement_base_t* self, gate_size_t index, gate_value_t const* value),
572 gate_result_t(*set_named_param)(gate_data_statement_base_t* self, gate_string_t const* name, gate_value_t const* value),
573 gate_result_t(*reset)(gate_data_statement_base_t* self),
574 gate_result_t(*execute)(gate_data_statement_base_t* self, gate_int32_t* affected_rows),
575 gate_result_t(*query)(gate_data_statement_base_t* self, gate_data_reader_t** ptr_reader),
576 gate_data_statement_base_t** ptr_output
577 )
578 {
579 25 gate_result_t ret = GATE_RESULT_FAILED;
580 25 gate_data_statement_base_t* impl = NULL;
581 do
582 {
583 25 impl = (gate_data_statement_base_t*)gate_mem_alloc(sizeof(gate_data_statement_base_t));
584
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (impl == NULL)
585 {
586 ret = GATE_RESULT_OUTOFMEMORY;
587 break;
588 }
589
590 25 gate_mem_clear(impl, sizeof(gate_data_statement_base_t));
591 25 impl->vtbl = statement_base_vtbl();
592 25 gate_atomic_int_init(&impl->ref_counter, 1);
593
594 25 impl->connection = (gate_data_connection_t*)connection;
595
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (impl->connection != NULL)
596 {
597 25 gate_object_retain(impl->connection);
598 }
599
600 25 gate_mem_copy(impl->native_handles, handles, sizeof(impl->native_handles));
601
602
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25 times.
25 if (NULL == gate_string_clone(&impl->sql, sql))
603 {
604 ret = GATE_RESULT_OUTOFMEMORY;
605 break;
606 }
607
608 25 impl->close = close;
609 25 impl->set_param = set_param;
610 25 impl->set_named_param = set_named_param;
611 25 impl->reset = reset;
612 25 impl->execute = execute;
613 25 impl->query = query;
614
615
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (init)
616 {
617 25 ret = init(impl);
618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 GATE_BREAK_IF_FAILED(ret);
619 }
620
621
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (ptr_output)
622 {
623 25 *ptr_output = impl;
624 25 impl = NULL;
625 }
626
627 /* success case */
628 25 ret = GATE_RESULT_OK;
629 } while (0);
630
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
25 if (impl)
632 {
633 statement_base_release(impl);
634 }
635
636 25 return ret;
637 }
638
639
640 #if defined(__cplusplus)
641 }
642 #endif
643
644 #endif
645