Line data Source code
1 : /* File: data_database_diagram_reader.c; Copyright and License: see below */
2 :
3 : #include "storage/data_database_diagram_reader.h"
4 : #include "u8/u8_trace.h"
5 : #include "u8/u8_log.h"
6 : #include "utf8stringbuf/utf8stringbuf.h"
7 : #include <sqlite3.h>
8 : #include <assert.h>
9 :
10 103 : u8_error_t data_database_diagram_reader_init( data_database_diagram_reader_t *this_, data_database_t *database )
11 : {
12 103 : U8_TRACE_BEGIN();
13 103 : assert( NULL != database );
14 103 : u8_error_t result = U8_ERROR_NONE;
15 :
16 103 : (*this_).database = database;
17 :
18 103 : (*this_).statement_diagram_by_id = NULL;
19 103 : (*this_).statement_diagram_by_uuid = NULL;
20 103 : (*this_).statement_diagrams_by_parent_id = NULL;
21 103 : (*this_).statement_diagrams_by_parent_id_null = NULL;
22 103 : (*this_).statement_diagrams_by_classifier_id = NULL;
23 103 : (*this_).statement_diagrams_by_relationship_id = NULL;
24 103 : (*this_).statement_diagram_ids_by_parent_id = NULL;
25 103 : (*this_).statement_diagram_ids_by_parent_id_null = NULL;
26 103 : (*this_).statement_diagram_ids_by_classifier_id = NULL;
27 :
28 103 : (*this_).statement_diagramelement_by_id = NULL;
29 103 : (*this_).statement_diagramelement_by_uuid = NULL;
30 103 : (*this_).statement_diagramelements_by_diagram_id = NULL;
31 103 : (*this_).statement_diagramelements_by_classifier_id = NULL;
32 :
33 103 : (*this_).statement_visible_classifiers_by_diagram_id = NULL;
34 :
35 103 : result |= data_database_diagram_reader_private_open( this_ );
36 :
37 103 : U8_TRACE_END_ERR(result);
38 103 : return result;
39 : }
40 :
41 103 : u8_error_t data_database_diagram_reader_destroy( data_database_diagram_reader_t *this_ )
42 : {
43 103 : U8_TRACE_BEGIN();
44 103 : u8_error_t result = U8_ERROR_NONE;
45 :
46 103 : result |= data_database_diagram_reader_private_close( this_ );
47 :
48 103 : (*this_).database = NULL;
49 :
50 103 : U8_TRACE_END_ERR(result);
51 103 : return result;
52 : }
53 :
54 : /* ================================ DIAGRAM ================================ */
55 :
56 : /*!
57 : * \brief predefined search statement to find a diagram by id
58 : */
59 : static const char DATA_DATABASE_READER_SELECT_DIAGRAM_BY_ID[] =
60 : "SELECT id,parent_id,diagram_type,stereotype,name,description,list_order,display_flags,uuid "
61 : "FROM diagrams WHERE id=?;";
62 :
63 : /*!
64 : * \brief predefined search statement to find a diagram by uuid
65 : */
66 : static const char DATA_DATABASE_READER_SELECT_DIAGRAM_BY_UUID[] =
67 : "SELECT id,parent_id,diagram_type,stereotype,name,description,list_order,display_flags,uuid "
68 : "FROM diagrams WHERE uuid=?;";
69 :
70 : /*!
71 : * \brief the column id of the result where this parameter is stored: id
72 : */
73 : static const int RESULT_DIAGRAM_ID_COLUMN = 0;
74 :
75 : /*!
76 : * \brief the column id of the result where this parameter is stored: parent_id
77 : */
78 : static const int RESULT_DIAGRAM_PARENT_ID_COLUMN = 1;
79 :
80 : /*!
81 : * \brief the column id of the result where this parameter is stored: type
82 : */
83 : static const int RESULT_DIAGRAM_TYPE_COLUMN = 2;
84 :
85 : /*!
86 : * \brief the column id of the result where this parameter is stored: stereotype
87 : */
88 : static const int RESULT_DIAGRAM_STEREOTYPE_COLUMN = 3;
89 :
90 : /*!
91 : * \brief the column id of the result where this parameter is stored: name
92 : */
93 : static const int RESULT_DIAGRAM_NAME_COLUMN = 4;
94 :
95 : /*!
96 : * \brief the column id of the result where this parameter is stored: description
97 : */
98 : static const int RESULT_DIAGRAM_DESCRIPTION_COLUMN = 5;
99 :
100 : /*!
101 : * \brief the column id of the result where this parameter is stored: list_order
102 : */
103 : static const int RESULT_DIAGRAM_LIST_ORDER_COLUMN = 6;
104 :
105 : /*!
106 : * \brief the column id of the result where this parameter is stored: display_flags
107 : */
108 : static const int RESULT_DIAGRAM_DISPLAY_FLAGS_COLUMN = 7;
109 :
110 : /*!
111 : * \brief the column id of the result where this parameter is stored: uuid
112 : */
113 : static const int RESULT_DIAGRAM_UUID_COLUMN = 8;
114 :
115 : /*!
116 : * \brief predefined search statement to find diagram ids by parent-id
117 : */
118 : static const char DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_PARENT_ID[] =
119 : "SELECT id "
120 : "FROM diagrams WHERE parent_id=? ORDER BY list_order ASC;";
121 :
122 : /*!
123 : * \brief predefined search statement to find diagram ids by NULL parent-id
124 : */
125 : static const char DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_PARENT_ID_NULL[] =
126 : "SELECT id "
127 : "FROM diagrams WHERE parent_id IS NULL ORDER BY list_order ASC;";
128 :
129 : /*!
130 : * \brief predefined search statement to find diagram ids by classifier-id
131 : */
132 : static const char DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_CLASSIFIER_ID[] =
133 : "SELECT diagrams.id "
134 : "FROM diagrams "
135 : "INNER JOIN diagramelements ON diagramelements.diagram_id=diagrams.id "
136 : "WHERE diagramelements.classifier_id=? "
137 : "GROUP BY diagrams.id " /* filter duplicates if a classifier exists twice in a diagram */
138 : "ORDER BY diagrams.list_order ASC;";
139 :
140 75 : u8_error_t data_database_diagram_reader_get_diagram_by_id( data_database_diagram_reader_t *this_,
141 : data_row_t id,
142 : data_diagram_t *out_diagram )
143 : {
144 75 : U8_TRACE_BEGIN();
145 75 : assert( NULL != out_diagram );
146 75 : u8_error_t result = U8_ERROR_NONE;
147 : int sqlite_err;
148 : sqlite3_stmt *prepared_statement;
149 :
150 : {
151 75 : prepared_statement = (*this_).statement_diagram_by_id;
152 :
153 75 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, prepared_statement, id );
154 :
155 75 : U8_TRACE_INFO( "sqlite3_step()" );
156 75 : sqlite_err = sqlite3_step( prepared_statement );
157 75 : if ( SQLITE_ROW != sqlite_err )
158 : {
159 : /* This may happen e.g. when a diagram is deleted and a window still tries to show it. */
160 4 : U8_TRACE_INFO_INT( "sqlite3_step did not find a row for id", id );
161 4 : result |= U8_ERROR_DB_STRUCTURE;
162 : }
163 :
164 75 : if ( SQLITE_ROW == sqlite_err )
165 : {
166 142 : result |= data_diagram_init( out_diagram,
167 71 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_ID_COLUMN ),
168 71 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ),
169 71 : sqlite3_column_int( prepared_statement, RESULT_DIAGRAM_TYPE_COLUMN ),
170 71 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_STEREOTYPE_COLUMN ),
171 71 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_NAME_COLUMN ),
172 71 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_DESCRIPTION_COLUMN ),
173 : sqlite3_column_int( prepared_statement, RESULT_DIAGRAM_LIST_ORDER_COLUMN ),
174 71 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_DISPLAY_FLAGS_COLUMN ),
175 71 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_UUID_COLUMN )
176 : );
177 71 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ) )
178 : {
179 48 : (*out_diagram).parent_id = DATA_ROW_VOID;
180 : }
181 :
182 71 : data_diagram_trace( out_diagram );
183 :
184 71 : sqlite_err = sqlite3_step( prepared_statement );
185 71 : if ( SQLITE_DONE != sqlite_err )
186 : {
187 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
188 0 : result |= U8_ERROR_DB_STRUCTURE;
189 : }
190 : }
191 : }
192 :
193 75 : U8_TRACE_END_ERR( result );
194 75 : return result;
195 : }
196 :
197 10 : u8_error_t data_database_diagram_reader_get_diagram_by_uuid( data_database_diagram_reader_t *this_,
198 : const char *uuid,
199 : data_diagram_t *out_diagram )
200 : {
201 10 : U8_TRACE_BEGIN();
202 10 : assert( NULL != uuid );
203 10 : assert( NULL != out_diagram );
204 10 : u8_error_t result = U8_ERROR_NONE;
205 : int sqlite_err;
206 : sqlite3_stmt *prepared_statement;
207 :
208 : {
209 10 : prepared_statement = (*this_).statement_diagram_by_uuid;
210 :
211 10 : result |= data_database_diagram_reader_private_bind_text_to_statement( this_, prepared_statement, uuid );
212 :
213 10 : U8_TRACE_INFO( "sqlite3_step()" );
214 10 : sqlite_err = sqlite3_step( prepared_statement );
215 10 : if ( SQLITE_ROW != sqlite_err )
216 : {
217 : /* Do not log this incident, the caller may not expect to find a row. */
218 6 : U8_TRACE_INFO_STR( "sqlite3_step did not find a row for uuid", uuid );
219 6 : result |= U8_ERROR_NOT_FOUND;
220 : }
221 :
222 10 : if ( SQLITE_ROW == sqlite_err )
223 : {
224 8 : result |= data_diagram_init( out_diagram,
225 4 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_ID_COLUMN ),
226 4 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ),
227 4 : sqlite3_column_int( prepared_statement, RESULT_DIAGRAM_TYPE_COLUMN ),
228 4 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_STEREOTYPE_COLUMN ),
229 4 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_NAME_COLUMN ),
230 4 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_DESCRIPTION_COLUMN ),
231 : sqlite3_column_int( prepared_statement, RESULT_DIAGRAM_LIST_ORDER_COLUMN ),
232 4 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_DISPLAY_FLAGS_COLUMN ),
233 4 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_UUID_COLUMN )
234 : );
235 4 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ) )
236 : {
237 3 : (*out_diagram).parent_id = DATA_ROW_VOID;
238 : }
239 :
240 4 : data_diagram_trace( out_diagram );
241 :
242 4 : sqlite_err = sqlite3_step( prepared_statement );
243 4 : if ( SQLITE_DONE != sqlite_err )
244 : {
245 0 : U8_LOG_ERROR_INT( "sqlite3_step not done yet:", sqlite_err );
246 0 : result |= U8_ERROR_DB_STRUCTURE;
247 : }
248 : }
249 : }
250 :
251 10 : U8_TRACE_END_ERR( result );
252 10 : return result;
253 : }
254 :
255 175 : u8_error_t data_database_diagram_reader_get_diagrams_by_parent_id( data_database_diagram_reader_t *this_,
256 : data_row_t parent_id,
257 : data_diagram_iterator_t *io_diagram_iterator )
258 : {
259 175 : U8_TRACE_BEGIN();
260 175 : assert( NULL != io_diagram_iterator );
261 175 : u8_error_t result = U8_ERROR_NONE;
262 : sqlite3_stmt *sqlite3_stmt;
263 : bool * borrow_flag;
264 :
265 175 : if ( DATA_ROW_VOID == parent_id )
266 : {
267 39 : sqlite3_stmt = (*this_).statement_diagrams_by_parent_id_null;
268 39 : result |= data_database_diagram_reader_private_bind_void_to_statement( this_, sqlite3_stmt );
269 39 : borrow_flag = &((*this_).statement_diagrams_by_parent_id_null_borrowed);
270 : }
271 : else
272 : {
273 136 : sqlite3_stmt = (*this_).statement_diagrams_by_parent_id;
274 136 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, parent_id );
275 136 : borrow_flag = &((*this_).statement_diagrams_by_parent_id_borrowed);
276 : }
277 :
278 : data_database_borrowed_stmt_t sql_statement;
279 175 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
280 175 : result |= data_diagram_iterator_reinit( io_diagram_iterator, sql_statement );
281 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
282 :
283 175 : U8_TRACE_END_ERR( result );
284 175 : return result;
285 : }
286 :
287 14 : u8_error_t data_database_diagram_reader_get_diagrams_by_classifier_id( data_database_diagram_reader_t *this_,
288 : data_row_t classifier_id,
289 : data_diagram_iterator_t *io_diagram_iterator )
290 : {
291 14 : U8_TRACE_BEGIN();
292 14 : assert( NULL != io_diagram_iterator );
293 14 : u8_error_t result = U8_ERROR_NONE;
294 :
295 14 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_diagrams_by_classifier_id;
296 14 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, classifier_id );
297 14 : bool *const borrow_flag = &((*this_).statement_diagrams_by_classifier_id_borrowed);
298 :
299 : data_database_borrowed_stmt_t sql_statement;
300 14 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
301 14 : result |= data_diagram_iterator_reinit( io_diagram_iterator, sql_statement );
302 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
303 :
304 14 : U8_TRACE_END_ERR( result );
305 14 : return result;
306 : }
307 :
308 0 : u8_error_t data_database_diagram_reader_get_diagrams_by_relationship_id( data_database_diagram_reader_t *this_,
309 : data_row_t relationship_id,
310 : data_diagram_iterator_t *io_diagram_iterator )
311 : {
312 0 : U8_TRACE_BEGIN();
313 0 : assert( NULL != io_diagram_iterator );
314 0 : u8_error_t result = U8_ERROR_NONE;
315 :
316 0 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_diagrams_by_relationship_id;
317 0 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, relationship_id );
318 0 : bool *const borrow_flag = &((*this_).statement_diagrams_by_relationship_id_borrowed);
319 :
320 : data_database_borrowed_stmt_t sql_statement;
321 0 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
322 0 : result |= data_diagram_iterator_reinit( io_diagram_iterator, sql_statement );
323 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
324 :
325 0 : U8_TRACE_END_ERR( result );
326 0 : return result;
327 : }
328 :
329 23 : u8_error_t data_database_diagram_reader_get_diagram_ids_by_parent_id( data_database_diagram_reader_t *this_,
330 : data_row_t parent_id,
331 : data_small_set_t *out_diagram_ids )
332 : {
333 23 : U8_TRACE_BEGIN();
334 23 : assert( NULL != out_diagram_ids );
335 23 : u8_error_t result = U8_ERROR_NONE;
336 : int sqlite_err;
337 : sqlite3_stmt *prepared_statement;
338 :
339 : {
340 23 : if ( DATA_ROW_VOID == parent_id )
341 : {
342 21 : prepared_statement = (*this_).statement_diagram_ids_by_parent_id_null;
343 21 : result |= data_database_diagram_reader_private_bind_void_to_statement( this_, prepared_statement );
344 : }
345 : else
346 : {
347 2 : prepared_statement = (*this_).statement_diagram_ids_by_parent_id;
348 2 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, prepared_statement, parent_id );
349 : }
350 :
351 23 : data_small_set_clear( out_diagram_ids );
352 23 : sqlite_err = SQLITE_ROW;
353 63 : for ( uint32_t row_index = 0; (SQLITE_ROW == sqlite_err) && (row_index <= DATA_SMALL_SET_MAX_SET_SIZE); row_index ++ )
354 : {
355 40 : U8_TRACE_INFO( "sqlite3_step()" );
356 40 : sqlite_err = sqlite3_step( prepared_statement );
357 40 : if (( SQLITE_ROW != sqlite_err )&&( SQLITE_DONE != sqlite_err ))
358 : {
359 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
360 0 : result |= U8_ERROR_AT_DB;
361 : }
362 40 : if (( SQLITE_ROW == sqlite_err )&&(row_index < DATA_SMALL_SET_MAX_SET_SIZE))
363 : {
364 : data_id_t current_diag_id;
365 17 : data_id_init( ¤t_diag_id, DATA_TABLE_DIAGRAM, sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_ID_COLUMN ) );
366 17 : result |= data_small_set_add_obj( out_diagram_ids, current_diag_id );
367 : }
368 40 : if (( SQLITE_ROW == sqlite_err )&&(row_index >= DATA_SMALL_SET_MAX_SET_SIZE))
369 : {
370 0 : U8_LOG_ANOMALY_INT( "out_diagram_ids[] full:", (row_index+1) );
371 0 : result |= U8_ERROR_ARRAY_BUFFER_EXCEEDED;
372 : }
373 40 : if ( SQLITE_DONE == sqlite_err )
374 : {
375 23 : U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
376 : }
377 : }
378 23 : data_small_set_trace( out_diagram_ids );
379 : }
380 :
381 23 : U8_TRACE_END_ERR( result );
382 23 : return result;
383 : }
384 :
385 1 : u8_error_t data_database_diagram_reader_get_diagram_ids_by_classifier_id( data_database_diagram_reader_t *this_,
386 : data_row_t classifier_id,
387 : data_small_set_t *out_diagram_ids )
388 : {
389 1 : U8_TRACE_BEGIN();
390 1 : assert( NULL != out_diagram_ids );
391 1 : u8_error_t result = U8_ERROR_NONE;
392 : int sqlite_err;
393 : sqlite3_stmt *prepared_statement;
394 :
395 : {
396 1 : prepared_statement = (*this_).statement_diagram_ids_by_classifier_id;
397 :
398 1 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, prepared_statement, classifier_id );
399 :
400 1 : sqlite_err = SQLITE_ROW;
401 4 : for ( uint32_t row_index = 0; (SQLITE_ROW == sqlite_err) && (row_index <= DATA_SMALL_SET_MAX_SET_SIZE); row_index ++ )
402 : {
403 3 : U8_TRACE_INFO( "sqlite3_step()" );
404 3 : sqlite_err = sqlite3_step( prepared_statement );
405 3 : if (( SQLITE_ROW != sqlite_err )&&( SQLITE_DONE != sqlite_err ))
406 : {
407 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
408 0 : result |= U8_ERROR_AT_DB;
409 : }
410 3 : if (( SQLITE_ROW == sqlite_err )&&(row_index < DATA_SMALL_SET_MAX_SET_SIZE))
411 : {
412 : data_id_t current_diag_id;
413 2 : data_id_init( ¤t_diag_id, DATA_TABLE_DIAGRAM, sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_ID_COLUMN ) );
414 2 : result |= data_small_set_add_obj( out_diagram_ids, current_diag_id );
415 2 : data_id_trace( ¤t_diag_id );
416 : }
417 3 : if (( SQLITE_ROW == sqlite_err )&&(row_index >= DATA_SMALL_SET_MAX_SET_SIZE))
418 : {
419 0 : U8_LOG_ANOMALY_INT( "out_diagram_ids[] full:", (row_index+1) );
420 0 : result |= U8_ERROR_ARRAY_BUFFER_EXCEEDED;
421 : }
422 3 : if ( SQLITE_DONE == sqlite_err )
423 : {
424 1 : U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
425 : }
426 : }
427 : }
428 :
429 1 : U8_TRACE_END_ERR( result );
430 1 : return result;
431 : }
432 :
433 : /* ================================ DIAGRAMELEMENT ================================ */
434 :
435 : /*!
436 : * \brief predefined search statement to find a diagramelement by id
437 : */
438 : static const char DATA_DATABASE_READER_SELECT_DIAGRAMELEMENT_BY_ID[] =
439 : "SELECT id,diagram_id,classifier_id,display_flags,focused_feature_id,uuid FROM diagramelements WHERE id=?;";
440 :
441 : /*!
442 : * \brief predefined search statement to find a diagramelement by uuid
443 : */
444 : static const char DATA_DATABASE_READER_SELECT_DIAGRAMELEMENT_BY_UUID[] =
445 : "SELECT id,diagram_id,classifier_id,display_flags,focused_feature_id,uuid FROM diagramelements WHERE uuid=?;";
446 :
447 : /*!
448 : * \brief the column id of the result where this parameter is stored: id
449 : */
450 : static const int RESULT_DIAGRAMELEMENT_ID_COLUMN = 0;
451 :
452 : /*!
453 : * \brief the column id of the result where this parameter is stored: diagram_id
454 : */
455 : static const int RESULT_DIAGRAMELEMENT_DIAGRAM_ID_COLUMN = 1;
456 :
457 : /*!
458 : * \brief the column id of the result where this parameter is stored: classifier_id
459 : */
460 : static const int RESULT_DIAGRAMELEMENT_CLASSIFIER_ID_COLUMN = 2;
461 :
462 : /*!
463 : * \brief the column id of the result where this parameter is stored: display_flags
464 : */
465 : static const int RESULT_DIAGRAMELEMENT_DISPLAY_FLAGS_COLUMN = 3;
466 :
467 : /*!
468 : * \brief the column id of the result where this parameter is stored: focused_feature_id
469 : */
470 : static const int RESULT_DIAGRAMELEMENT_FOCUSED_FEATURE_ID_COLUMN = 4;
471 :
472 : /*!
473 : * \brief the column id of the result where this parameter is stored: uuid
474 : */
475 : static const int RESULT_DIAGRAMELEMENT_UUID_COLUMN = 5;
476 :
477 38 : u8_error_t data_database_diagram_reader_get_diagramelement_by_id( data_database_diagram_reader_t *this_,
478 : data_row_t id,
479 : data_diagramelement_t *out_diagramelement )
480 : {
481 38 : U8_TRACE_BEGIN();
482 38 : assert( NULL != out_diagramelement );
483 38 : u8_error_t result = U8_ERROR_NONE;
484 : int sqlite_err;
485 : sqlite3_stmt *prepared_statement;
486 :
487 : {
488 38 : prepared_statement = (*this_).statement_diagramelement_by_id;
489 :
490 38 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, prepared_statement, id );
491 :
492 38 : U8_TRACE_INFO( "sqlite3_step()" );
493 38 : sqlite_err = sqlite3_step( prepared_statement );
494 38 : if ( SQLITE_ROW != sqlite_err )
495 : {
496 3 : U8_TRACE_INFO_INT( "sqlite3_step did not find a row for id", id );
497 3 : result |= U8_ERROR_DB_STRUCTURE;
498 : }
499 :
500 38 : if ( SQLITE_ROW == sqlite_err )
501 : {
502 35 : result |= data_diagramelement_init( out_diagramelement,
503 35 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_ID_COLUMN ),
504 35 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_DIAGRAM_ID_COLUMN ),
505 35 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_CLASSIFIER_ID_COLUMN ),
506 35 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_DISPLAY_FLAGS_COLUMN ),
507 35 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_FOCUSED_FEATURE_ID_COLUMN ),
508 35 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAMELEMENT_UUID_COLUMN )
509 : );
510 35 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_DIAGRAMELEMENT_FOCUSED_FEATURE_ID_COLUMN ) )
511 : {
512 23 : data_diagramelement_set_focused_feature_row_id ( out_diagramelement, DATA_ROW_VOID );
513 : }
514 :
515 35 : data_diagramelement_trace( out_diagramelement );
516 :
517 35 : sqlite_err = sqlite3_step( prepared_statement );
518 35 : if ( SQLITE_DONE != sqlite_err )
519 : {
520 0 : U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
521 0 : result |= U8_ERROR_DB_STRUCTURE;
522 : }
523 : }
524 : }
525 :
526 38 : U8_TRACE_END_ERR( result );
527 38 : return result;
528 : }
529 :
530 2 : u8_error_t data_database_diagram_reader_get_diagramelement_by_uuid( data_database_diagram_reader_t *this_,
531 : const char *uuid,
532 : data_diagramelement_t *out_diagramelement )
533 : {
534 2 : U8_TRACE_BEGIN();
535 2 : assert( NULL != uuid );
536 2 : assert( NULL != out_diagramelement );
537 2 : u8_error_t result = U8_ERROR_NONE;
538 : int sqlite_err;
539 : sqlite3_stmt *prepared_statement;
540 :
541 : {
542 2 : prepared_statement = (*this_).statement_diagramelement_by_uuid;
543 :
544 2 : result |= data_database_diagram_reader_private_bind_text_to_statement( this_, prepared_statement, uuid );
545 :
546 2 : U8_TRACE_INFO( "sqlite3_step()" );
547 2 : sqlite_err = sqlite3_step( prepared_statement );
548 2 : if ( SQLITE_ROW != sqlite_err )
549 : {
550 : /* Do not log this incident, the caller may not expect to find a row. */
551 1 : U8_TRACE_INFO_STR( "sqlite3_step did not find a row for uuid", uuid );
552 1 : result |= U8_ERROR_NOT_FOUND;
553 : }
554 :
555 2 : if ( SQLITE_ROW == sqlite_err )
556 : {
557 1 : result |= data_diagramelement_init( out_diagramelement,
558 1 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_ID_COLUMN ),
559 1 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_DIAGRAM_ID_COLUMN ),
560 1 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_CLASSIFIER_ID_COLUMN ),
561 1 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_DISPLAY_FLAGS_COLUMN ),
562 1 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_FOCUSED_FEATURE_ID_COLUMN ),
563 1 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAMELEMENT_UUID_COLUMN )
564 : );
565 1 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_DIAGRAMELEMENT_FOCUSED_FEATURE_ID_COLUMN ) )
566 : {
567 1 : data_diagramelement_set_focused_feature_row_id ( out_diagramelement, DATA_ROW_VOID );
568 : }
569 :
570 1 : data_diagramelement_trace( out_diagramelement );
571 :
572 1 : sqlite_err = sqlite3_step( prepared_statement );
573 1 : if ( SQLITE_DONE != sqlite_err )
574 : {
575 0 : U8_LOG_ERROR_INT( "sqlite3_step not done yet:", sqlite_err );
576 0 : result |= U8_ERROR_DB_STRUCTURE;
577 : }
578 : }
579 : }
580 :
581 2 : U8_TRACE_END_ERR( result );
582 2 : return result;
583 : }
584 :
585 139 : u8_error_t data_database_diagram_reader_get_diagramelements_by_diagram_id( data_database_diagram_reader_t *this_,
586 : data_row_t diagram_id,
587 : data_diagramelement_iterator_t *io_diagramelement_iterator )
588 : {
589 139 : U8_TRACE_BEGIN();
590 139 : assert( NULL != io_diagramelement_iterator );
591 139 : u8_error_t result = U8_ERROR_NONE;
592 :
593 139 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_diagramelements_by_diagram_id;
594 139 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, diagram_id );
595 139 : bool *const borrow_flag = &((*this_).statement_diagramelements_by_diagram_id_borrowed);
596 :
597 : data_database_borrowed_stmt_t sql_statement;
598 139 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
599 139 : result |= data_diagramelement_iterator_reinit( io_diagramelement_iterator, sql_statement );
600 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
601 :
602 139 : U8_TRACE_END_ERR( result );
603 139 : return result;
604 : }
605 :
606 10 : u8_error_t data_database_diagram_reader_get_diagramelements_by_classifier_id( data_database_diagram_reader_t *this_,
607 : data_row_t classifier_id,
608 : data_diagramelement_iterator_t *io_diagramelement_iterator )
609 : {
610 10 : U8_TRACE_BEGIN();
611 10 : assert( NULL != io_diagramelement_iterator );
612 10 : u8_error_t result = U8_ERROR_NONE;
613 :
614 10 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_diagramelements_by_classifier_id;
615 10 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, classifier_id );
616 10 : bool *const borrow_flag = &((*this_).statement_diagramelements_by_classifier_id_borrowed);
617 :
618 : data_database_borrowed_stmt_t sql_statement;
619 10 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
620 10 : result |= data_diagramelement_iterator_reinit( io_diagramelement_iterator, sql_statement );
621 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
622 :
623 10 : U8_TRACE_END_ERR( result );
624 10 : return result;
625 : }
626 :
627 : /* ================================ VISIBLE_CLASSIFIER ================================ */
628 :
629 12 : u8_error_t data_database_diagram_reader_get_visible_classifiers_by_diagram_id( data_database_diagram_reader_t *this_,
630 : data_row_t diagram_id,
631 : data_visible_classifier_iterator_t *io_visible_classifier_iterator )
632 : {
633 12 : U8_TRACE_BEGIN();
634 12 : assert( NULL != io_visible_classifier_iterator );
635 12 : u8_error_t result = U8_ERROR_NONE;
636 :
637 12 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_visible_classifiers_by_diagram_id;
638 12 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, diagram_id );
639 12 : bool *const borrow_flag = &((*this_).statement_visible_classifiers_by_diagram_id_borrowed);
640 :
641 : data_database_borrowed_stmt_t sql_statement;
642 12 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
643 12 : result |= data_visible_classifier_iterator_reinit( io_visible_classifier_iterator, sql_statement );
644 : /* do not destroy sql_statement; the object is transferred to the iterator and consumed there. */
645 :
646 12 : U8_TRACE_END_ERR( result );
647 12 : return result;
648 : }
649 :
650 : /* ================================ private ================================ */
651 :
652 103 : u8_error_t data_database_diagram_reader_private_open( data_database_diagram_reader_t *this_ )
653 : {
654 103 : U8_TRACE_BEGIN();
655 103 : u8_error_t result = U8_ERROR_NONE;
656 :
657 : {
658 103 : result |= data_database_prepare_statement( (*this_).database,
659 : DATA_DATABASE_READER_SELECT_DIAGRAM_BY_ID,
660 : sizeof( DATA_DATABASE_READER_SELECT_DIAGRAM_BY_ID ),
661 : &((*this_).statement_diagram_by_id)
662 : );
663 :
664 103 : result |= data_database_prepare_statement( (*this_).database,
665 : DATA_DATABASE_READER_SELECT_DIAGRAM_BY_UUID,
666 : sizeof( DATA_DATABASE_READER_SELECT_DIAGRAM_BY_UUID ),
667 : &((*this_).statement_diagram_by_uuid)
668 : );
669 :
670 103 : result |= data_database_prepare_statement( (*this_).database,
671 : DATA_DIAGRAM_ITERATOR_SELECT_DIAGRAMS_BY_PARENT_ID,
672 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
673 : &((*this_).statement_diagrams_by_parent_id)
674 : );
675 103 : (*this_).statement_diagrams_by_parent_id_borrowed = false;
676 :
677 103 : result |= data_database_prepare_statement( (*this_).database,
678 : DATA_DIAGRAM_ITERATOR_SELECT_DIAGRAMS_BY_PARENT_ID_NULL,
679 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
680 : &((*this_).statement_diagrams_by_parent_id_null)
681 : );
682 103 : (*this_).statement_diagrams_by_parent_id_borrowed = false;
683 :
684 103 : result |= data_database_prepare_statement( (*this_).database,
685 : DATA_DIAGRAM_ITERATOR_SELECT_DIAGRAMS_BY_CLASSIFIER_ID,
686 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
687 : &((*this_).statement_diagrams_by_classifier_id)
688 : );
689 103 : (*this_).statement_diagrams_by_classifier_id_borrowed = false;
690 :
691 103 : result |= data_database_prepare_statement( (*this_).database,
692 : DATA_DIAGRAM_ITERATOR_SELECT_DIAGRAMS_BY_RELATIONSHIP_ID,
693 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
694 : &((*this_).statement_diagrams_by_relationship_id)
695 : );
696 103 : (*this_).statement_diagrams_by_relationship_id_borrowed = false;
697 :
698 103 : result |= data_database_prepare_statement( (*this_).database,
699 : DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_PARENT_ID,
700 : sizeof( DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_PARENT_ID ),
701 : &((*this_).statement_diagram_ids_by_parent_id)
702 : );
703 :
704 103 : result |= data_database_prepare_statement( (*this_).database,
705 : DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_PARENT_ID_NULL,
706 : sizeof( DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_PARENT_ID_NULL ),
707 : &((*this_).statement_diagram_ids_by_parent_id_null)
708 : );
709 :
710 103 : result |= data_database_prepare_statement( (*this_).database,
711 : DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_CLASSIFIER_ID,
712 : sizeof( DATA_DATABASE_READER_SELECT_DIAGRAM_IDS_BY_CLASSIFIER_ID ),
713 : &((*this_).statement_diagram_ids_by_classifier_id)
714 : );
715 :
716 103 : result |= data_database_prepare_statement( (*this_).database,
717 : DATA_DATABASE_READER_SELECT_DIAGRAMELEMENT_BY_ID,
718 : sizeof( DATA_DATABASE_READER_SELECT_DIAGRAMELEMENT_BY_ID ),
719 : &((*this_).statement_diagramelement_by_id)
720 : );
721 :
722 103 : result |= data_database_prepare_statement( (*this_).database,
723 : DATA_DATABASE_READER_SELECT_DIAGRAMELEMENT_BY_UUID,
724 : sizeof( DATA_DATABASE_READER_SELECT_DIAGRAMELEMENT_BY_UUID ),
725 : &((*this_).statement_diagramelement_by_uuid)
726 : );
727 :
728 103 : result |= data_database_prepare_statement( (*this_).database,
729 : DATA_DIAGRAMELEMENT_ITERATOR_SELECT_DIAGRAMELEMENTS_BY_DIAGRAM_ID,
730 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
731 : &((*this_).statement_diagramelements_by_diagram_id)
732 : );
733 103 : (*this_).statement_diagramelements_by_diagram_id_borrowed = false;
734 :
735 103 : result |= data_database_prepare_statement( (*this_).database,
736 : DATA_DIAGRAMELEMENT_ITERATOR_SELECT_DIAGRAMELEMENTS_BY_CLASSIFIER_ID,
737 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
738 : &((*this_).statement_diagramelements_by_classifier_id)
739 : );
740 103 : (*this_).statement_diagramelements_by_classifier_id_borrowed = false;
741 :
742 103 : result |= data_database_prepare_statement( (*this_).database,
743 : DATA_VISIBLE_CLASSIFIER_ITERATOR_SELECT_BY_DIAGRAM_ID,
744 : DATA_DATABASE_SQL_LENGTH_AUTO_DETECT,
745 : &((*this_).statement_visible_classifiers_by_diagram_id)
746 : );
747 103 : (*this_).statement_visible_classifiers_by_diagram_id_borrowed = false;
748 :
749 103 : if ( result != U8_ERROR_NONE )
750 : {
751 0 : U8_LOG_ERROR( "A prepared statement could not be prepared." );
752 : }
753 : }
754 :
755 103 : U8_TRACE_END_ERR(result);
756 103 : return result;
757 : }
758 :
759 103 : u8_error_t data_database_diagram_reader_private_close( data_database_diagram_reader_t *this_ )
760 : {
761 103 : U8_TRACE_BEGIN();
762 103 : u8_error_t result = U8_ERROR_NONE;
763 :
764 : {
765 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_by_id );
766 103 : (*this_).statement_diagram_by_id = NULL;
767 :
768 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_by_uuid );
769 103 : (*this_).statement_diagram_by_uuid = NULL;
770 :
771 103 : assert( (*this_).statement_diagrams_by_parent_id_borrowed == false );
772 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_parent_id );
773 103 : (*this_).statement_diagrams_by_parent_id = NULL;
774 :
775 103 : assert( (*this_).statement_diagrams_by_parent_id_null_borrowed == false );
776 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_parent_id_null );
777 103 : (*this_).statement_diagrams_by_parent_id_null = NULL;
778 :
779 103 : assert( (*this_).statement_diagrams_by_classifier_id_borrowed == false );
780 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_classifier_id );
781 103 : (*this_).statement_diagrams_by_classifier_id = NULL;
782 :
783 103 : assert( (*this_).statement_diagrams_by_relationship_id_borrowed == false );
784 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_relationship_id );
785 103 : (*this_).statement_diagrams_by_relationship_id = NULL;
786 :
787 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_parent_id );
788 103 : (*this_).statement_diagram_ids_by_parent_id = NULL;
789 :
790 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_parent_id_null );
791 103 : (*this_).statement_diagram_ids_by_parent_id_null = NULL;
792 :
793 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_classifier_id );
794 103 : (*this_).statement_diagram_ids_by_classifier_id = NULL;
795 :
796 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelement_by_id );
797 103 : (*this_).statement_diagramelement_by_id = NULL;
798 :
799 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelement_by_uuid );
800 103 : (*this_).statement_diagramelement_by_uuid = NULL;
801 :
802 103 : assert( (*this_).statement_diagramelements_by_diagram_id_borrowed == false );
803 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelements_by_diagram_id );
804 103 : (*this_).statement_diagramelements_by_diagram_id = NULL;
805 :
806 103 : assert( (*this_).statement_diagramelements_by_classifier_id_borrowed == false );
807 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelements_by_classifier_id );
808 103 : (*this_).statement_diagramelements_by_classifier_id = NULL;
809 :
810 103 : assert( (*this_).statement_visible_classifiers_by_diagram_id_borrowed == false );
811 103 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_visible_classifiers_by_diagram_id );
812 103 : (*this_).statement_visible_classifiers_by_diagram_id = NULL;
813 : }
814 :
815 103 : U8_TRACE_END_ERR(result);
816 103 : return result;
817 : }
818 :
819 :
820 : /*
821 : Copyright 2016-2025 Andreas Warnke
822 :
823 : Licensed under the Apache License, Version 2.0 (the "License");
824 : you may not use this file except in compliance with the License.
825 : You may obtain a copy of the License at
826 :
827 : http://www.apache.org/licenses/LICENSE-2.0
828 :
829 : Unless required by applicable law or agreed to in writing, software
830 : distributed under the License is distributed on an "AS IS" BASIS,
831 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
832 : See the License for the specific language governing permissions and
833 : limitations under the License.
834 : */
|