GCC Code Coverage Report


Directory: src/gate/
File: src/gate/data/adapter_base.h
Date: 2025-09-14 13:10:38
Exec Total Coverage
Lines: 180 250 72.0%
Functions: 20 30 66.7%
Branches: 45 94 47.9%

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
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 4 static gate_bool_t gate_data_reader_base_is_valid(void* This)
77 {
78 4 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
79
1/2
✓ Branch 0 taken 4 times.
✗ Branch 1 not taken.
4 if (self->is_valid)
80 {
81 4 return self->is_valid(self);
82 }
83 return false;
84 }
85
86 3 static gate_result_t gate_data_reader_base_close(void* This)
87 {
88 3 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
89 3 gate_result_t ret = GATE_RESULT_NOTSUPPORTED;
90 gate_size_t ndx;
91 do
92 {
93
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (self->close)
94 {
95 3 ret = self->close(self);
96
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 GATE_BREAK_IF_FAILED(ret);
97 }
98
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 for (ndx = 0; ndx != self->field_count; ++ndx)
99 {
100 3 gate_string_release(&self->names[ndx]);
101 3 gate_value_release(&self->values[ndx]);
102 }
103 3 gate_mem_clear(self->names, sizeof(self->names));
104 3 gate_mem_clear(self->values, sizeof(self->values));
105
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (self->statement)
106 {
107 1 gate_object_release(self->statement);
108 1 self->statement = NULL;
109 }
110 3 ret = GATE_RESULT_OK;
111 } while (0);
112 3 return ret;
113 }
114
115 2 static gate_result_t gate_data_reader_base_next(void* This)
116 {
117 2 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
118
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (self->next)
119 {
120 2 return self->next(self);
121 }
122 return GATE_RESULT_NOTSUPPORTED;
123 }
124
125 static gate_size_t gate_data_reader_base_get_field_count(void* This)
126 {
127 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
128 return self->field_count;
129 }
130 1 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 1 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
133 1 gate_result_t ret = GATE_RESULT_FAILED;
134 do
135 {
136
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 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 1 times.
1 if (field_index >= self->field_count)
142 {
143 ret = GATE_RESULT_OUTOFBOUNDS;
144 break;
145 }
146
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr_type)
147 {
148 1 *ptr_type = self->values[field_index].value_type;
149 }
150 1 ret = GATE_RESULT_OK;
151 } while (0);
152 1 return ret;
153 }
154 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 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
157 gate_result_t ret = GATE_RESULT_FAILED;
158 do
159 {
160 if (!gate_data_reader_base_is_valid(self))
161 {
162 ret = GATE_RESULT_ENDOFSTREAM;
163 break;
164 }
165 if (field_index >= self->field_count)
166 {
167 ret = GATE_RESULT_OUTOFBOUNDS;
168 break;
169 }
170 if (ptr_name)
171 {
172 *ptr_name = &self->names[field_index];
173 }
174 ret = GATE_RESULT_OK;
175 } while (0);
176 return ret;
177 }
178 1 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 1 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
181 1 gate_result_t ret = GATE_RESULT_FAILED;
182 do
183 {
184
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
1 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 1 times.
1 if (field_index >= self->field_count)
190 {
191 ret = GATE_RESULT_OUTOFBOUNDS;
192 break;
193 }
194
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr_value)
195 {
196 1 *ptr_value = &self->values[field_index];
197 }
198 1 ret = GATE_RESULT_OK;
199 } while (0);
200 1 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 1 static void gate_data_reader_base_release(void* This)
210 {
211 1 gate_data_reader_base_t* self = (gate_data_reader_base_t*)This;
212
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
1 if (0 == gate_atomic_int_dec(&self->ref_counter))
213 {
214 1 gate_data_reader_base_close(This);
215 1 gate_mem_dealloc(self);
216 }
217 1 }
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 1 static GATE_INTERFACE_VTBL(gate_data_reader) const* gate_init_data_reader_base_vtbl()
227 {
228 static GATE_INTERFACE_VTBL(gate_data_reader) gate_data_reader_base_vtbl;
229
230
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 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 1 gate_data_reader_base_vtbl = local_vtbl;
248 }
249 1 return &gate_data_reader_base_vtbl;
250 }
251
252 1 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 1 gate_data_reader_t* ret = NULL;
260 1 gate_data_reader_base_t* reader = NULL;
261 gate_result_t res;
262
263 do
264 {
265 1 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 1 times.
1 if (reader == NULL)
267 {
268 break;
269 }
270 1 gate_mem_clear(reader, sizeof(gate_data_reader_base_t));
271 1 reader->vtbl = gate_init_data_reader_base_vtbl();
272 1 gate_atomic_int_init(&reader->ref_counter, 1);
273
274 1 gate_mem_copy(reader->native_handles, handles, sizeof(reader->native_handles));
275 1 reader->statement = statement;
276
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (reader->statement)
277 {
278 1 gate_object_retain(reader->statement);
279 }
280 1 reader->field_count = 0;
281
282 1 reader->init = init;
283 1 reader->is_valid = is_valid;
284 1 reader->next = next;
285 1 reader->close = close;
286
287
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (reader->init)
288 {
289 1 res = reader->init(reader);
290
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (GATE_FAILED(res))
291 {
292 gate_mem_dealloc(reader);
293 break;
294 }
295 }
296
297 1 ret = (gate_data_reader_t*)reader;
298 1 reader = NULL;
299 } while (0);
300 1 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 static char const* gate_data_connection_base_get_interface_name(void* This)
324 {
325 GATE_UNUSED_ARG(This);
326 return GATE_INTERFACE_NAME_DATA_CONNECTION;
327 }
328 3 static void gate_data_connection_base_release(void* This)
329 {
330 3 gate_data_connection_base_t* self = (gate_data_connection_base_t*)This;
331
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2 times.
3 if (0 == gate_atomic_int_dec(&self->ref_counter))
332 {
333
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (self->close)
334 {
335 1 self->close(self);
336 }
337 1 gate_mem_dealloc(self);
338 }
339 3 }
340 2 static int gate_data_connection_base_retain(void* This)
341 {
342 2 gate_data_connection_base_t* self = (gate_data_connection_base_t*)This;
343 2 return (int)gate_atomic_int_inc(&self->ref_counter);
344 }
345
346 2 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 2 gate_data_connection_base_t* self = (gate_data_connection_base_t*)This;
349
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (self->create_statement)
350 {
351 2 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 1 static void gate_init_data_connection_base_vtbl()
358 {
359
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 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 1 gate_data_connection_base_vtbl = local_vtbl;
370 }
371 1 }
372
373 1 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 1 gate_result_t ret = GATE_RESULT_FAILED;
380 1 gate_data_connection_base_t* conn = NULL;
381
382 do
383 {
384 1 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 1 times.
1 if (conn == NULL)
386 {
387 ret = GATE_RESULT_OUTOFMEMORY;
388 break;
389 }
390 1 gate_mem_clear(conn, sizeof(gate_data_connection_base_t));
391 1 gate_init_data_connection_base_vtbl();
392 1 conn->vtbl = &gate_data_connection_base_vtbl;
393 1 gate_atomic_int_init(&conn->ref_counter, 1);
394 1 gate_mem_copy(conn->native_handles, handles, sizeof(conn->native_handles));
395
396 1 conn->init = init;
397 1 conn->close = close;
398 1 conn->create_statement = create_stmt;
399
400
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (conn->init)
401 {
402 1 ret = conn->init(conn);
403
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 GATE_BREAK_IF_FAILED(ret);
404 }
405
406
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (ptr_connection)
407 {
408 1 *ptr_connection = (gate_data_connection_t*)conn;
409 1 conn = NULL;
410 }
411 1 ret = GATE_RESULT_OK;
412 } while (0);
413
414
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (conn != NULL)
415 {
416 gate_object_release(conn);
417 }
418 1 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 2 static void statement_base_close(gate_data_statement_base_t* self)
450 {
451
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (self->close)
452 {
453 2 self->close(self);
454 }
455 2 gate_string_release(&self->sql);
456
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (self->connection)
457 {
458 2 gate_object_release(self->connection);
459 2 self->connection = NULL;
460 }
461 2 }
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 3 static void statement_base_release(void* This)
470 {
471 3 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
472
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
3 if (0 == gate_atomic_int_dec(&self->ref_counter))
473 {
474 2 statement_base_close(self);
475 2 gate_mem_dealloc(self);
476 }
477 3 }
478
479 1 static int statement_base_retain(void* This)
480 {
481 1 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
482 1 return gate_atomic_int_inc(&self->ref_counter);
483 }
484
485 static gate_result_t statement_base_get_param_count(void* This, gate_size_t* ptr_count)
486 {
487 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
488 if (ptr_count)
489 {
490 *ptr_count = self->param_count;
491 return GATE_RESULT_OK;
492 }
493 return GATE_RESULT_INVALIDARG;
494
495 }
496 static gate_result_t statement_base_set_param(void* This, gate_size_t index, gate_value_t const* value)
497 {
498 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
499 if (self->set_param)
500 {
501 return self->set_param(self, index, value);
502 }
503 return GATE_RESULT_NOTSUPPORTED;
504 }
505 static gate_result_t statement_base_set_named_param(void* This, gate_string_t const* name, gate_value_t const* value)
506 {
507 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
508 if (self->set_named_param)
509 {
510 return self->set_named_param(self, name, value);
511 }
512 return GATE_RESULT_NOTSUPPORTED;
513 }
514
515 static gate_result_t statement_base_reset(void* This)
516 {
517 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
518 if (self->reset)
519 {
520 return self->reset(self);
521 }
522 return GATE_RESULT_NOTSUPPORTED;
523 }
524 1 static gate_result_t statement_base_execute(void* This, gate_int32_t* affected_rows)
525 {
526 1 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
527
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (self->execute)
528 {
529 1 return self->execute(self, affected_rows);
530 }
531 return GATE_RESULT_NOTSUPPORTED;
532 }
533 1 static gate_result_t statement_base_query(void* This, gate_data_reader_t** ptr_reader)
534 {
535 1 gate_data_statement_base_t* self = (gate_data_statement_base_t*)This;
536
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (self->query)
537 {
538 1 return self->query(self, ptr_reader);
539 }
540 return GATE_RESULT_NOTSUPPORTED;
541 }
542
543
544 2 static GATE_INTERFACE_VTBL(gate_data_statement) const* statement_base_vtbl()
545 {
546 static GATE_INTERFACE_VTBL(gate_data_statement) vtbl;
547
548
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (vtbl.get_interface_name == NULL)
549 {
550 1 vtbl.get_interface_name = &statement_base_get_interface_name;
551 1 vtbl.release = &statement_base_release;
552 1 vtbl.retain = &statement_base_retain;
553
554 1 vtbl.get_param_count = &statement_base_get_param_count;
555 1 vtbl.set_param = &statement_base_set_param;
556 1 vtbl.set_named_param = &statement_base_set_named_param;
557
558 1 vtbl.reset = &statement_base_reset;
559 1 vtbl.execute = &statement_base_execute;
560 1 vtbl.query = &statement_base_query;
561 }
562 2 return &vtbl;
563 }
564
565 2 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 2 gate_result_t ret = GATE_RESULT_FAILED;
580 2 gate_data_statement_base_t* impl = NULL;
581 do
582 {
583 2 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 2 times.
2 if (impl == NULL)
585 {
586 ret = GATE_RESULT_OUTOFMEMORY;
587 break;
588 }
589
590 2 gate_mem_clear(impl, sizeof(gate_data_statement_base_t));
591 2 impl->vtbl = statement_base_vtbl();
592 2 gate_atomic_int_init(&impl->ref_counter, 1);
593
594 2 impl->connection = (gate_data_connection_t*)connection;
595
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (impl->connection != NULL)
596 {
597 2 gate_object_retain(impl->connection);
598 }
599
600 2 gate_mem_copy(impl->native_handles, handles, sizeof(impl->native_handles));
601
602
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
2 if (NULL == gate_string_clone(&impl->sql, sql))
603 {
604 ret = GATE_RESULT_OUTOFMEMORY;
605 break;
606 }
607
608 2 impl->close = close;
609 2 impl->set_param = set_param;
610 2 impl->set_named_param = set_named_param;
611 2 impl->reset = reset;
612 2 impl->execute = execute;
613 2 impl->query = query;
614
615
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (init)
616 {
617 2 ret = init(impl);
618
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 GATE_BREAK_IF_FAILED(ret);
619 }
620
621
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 if (ptr_output)
622 {
623 2 *ptr_output = impl;
624 2 impl = NULL;
625 }
626
627 /* success case */
628 2 ret = GATE_RESULT_OK;
629 } while (0);
630
631
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (impl)
632 {
633 statement_base_release(impl);
634 }
635
636 2 return ret;
637 }
638
639
640 #if defined(__cplusplus)
641 }
642 #endif
643
644 #endif
645