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 112 : u8_error_t data_database_diagram_reader_init( data_database_diagram_reader_t *this_, data_database_t *database )
11 : {
12 112 : U8_TRACE_BEGIN();
13 112 : assert( NULL != database );
14 112 : u8_error_t result = U8_ERROR_NONE;
15 :
16 112 : (*this_).database = database;
17 :
18 112 : (*this_).statement_diagram_by_id = NULL;
19 112 : (*this_).statement_diagram_by_uuid = NULL;
20 112 : (*this_).statement_diagrams_by_parent_id = NULL;
21 112 : (*this_).statement_diagrams_by_parent_id_null = NULL;
22 112 : (*this_).statement_diagrams_by_classifier_id = NULL;
23 112 : (*this_).statement_diagrams_by_relationship_id = NULL;
24 112 : (*this_).statement_diagram_ids_by_parent_id = NULL;
25 112 : (*this_).statement_diagram_ids_by_parent_id_null = NULL;
26 112 : (*this_).statement_diagram_ids_by_classifier_id = NULL;
27 :
28 112 : (*this_).statement_diagramelement_by_id = NULL;
29 112 : (*this_).statement_diagramelement_by_uuid = NULL;
30 112 : (*this_).statement_diagramelements_by_diagram_id = NULL;
31 112 : (*this_).statement_diagramelements_by_classifier_id = NULL;
32 :
33 112 : (*this_).statement_visible_classifiers_by_diagram_id = NULL;
34 :
35 112 : result |= data_database_diagram_reader_private_open( this_ );
36 :
37 112 : U8_TRACE_END_ERR(result);
38 112 : return result;
39 : }
40 :
41 112 : u8_error_t data_database_diagram_reader_destroy( data_database_diagram_reader_t *this_ )
42 : {
43 112 : U8_TRACE_BEGIN();
44 112 : u8_error_t result = U8_ERROR_NONE;
45 :
46 112 : result |= data_database_diagram_reader_private_close( this_ );
47 :
48 112 : (*this_).database = NULL;
49 :
50 112 : U8_TRACE_END_ERR(result);
51 112 : 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 108 : 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 108 : U8_TRACE_BEGIN();
145 108 : assert( NULL != out_diagram );
146 108 : u8_error_t result = U8_ERROR_NONE;
147 : int sqlite_err;
148 : sqlite3_stmt *prepared_statement;
149 :
150 : {
151 108 : prepared_statement = (*this_).statement_diagram_by_id;
152 :
153 108 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, prepared_statement, id );
154 :
155 108 : U8_TRACE_INFO( "sqlite3_step()" );
156 108 : sqlite_err = sqlite3_step( prepared_statement );
157 108 : 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 108 : if ( SQLITE_ROW == sqlite_err )
165 : {
166 104 : result |= data_diagram_init( out_diagram,
167 104 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_ID_COLUMN ),
168 104 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ),
169 104 : sqlite3_column_int( prepared_statement, RESULT_DIAGRAM_TYPE_COLUMN ),
170 104 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_STEREOTYPE_COLUMN ),
171 104 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_NAME_COLUMN ),
172 104 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_DESCRIPTION_COLUMN ),
173 104 : sqlite3_column_int( prepared_statement, RESULT_DIAGRAM_LIST_ORDER_COLUMN ),
174 104 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_DISPLAY_FLAGS_COLUMN ),
175 104 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_UUID_COLUMN )
176 : );
177 104 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ) )
178 : {
179 63 : (*out_diagram).parent_id = DATA_ROW_VOID;
180 : }
181 :
182 104 : data_diagram_trace( out_diagram );
183 :
184 104 : sqlite_err = sqlite3_step( prepared_statement );
185 104 : 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 108 : U8_TRACE_END_ERR( result );
194 108 : return result;
195 : }
196 :
197 9 : 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 9 : U8_TRACE_BEGIN();
202 9 : assert( NULL != uuid );
203 9 : assert( NULL != out_diagram );
204 9 : u8_error_t result = U8_ERROR_NONE;
205 : int sqlite_err;
206 : sqlite3_stmt *prepared_statement;
207 :
208 : {
209 9 : prepared_statement = (*this_).statement_diagram_by_uuid;
210 :
211 9 : result |= data_database_diagram_reader_private_bind_text_to_statement( this_, prepared_statement, uuid );
212 :
213 9 : U8_TRACE_INFO( "sqlite3_step()" );
214 9 : sqlite_err = sqlite3_step( prepared_statement );
215 9 : if ( SQLITE_ROW != sqlite_err )
216 : {
217 : /* Do not log this incident, the caller may not expect to find a row. */
218 4 : U8_TRACE_INFO_STR( "sqlite3_step did not find a row for uuid", uuid );
219 4 : result |= U8_ERROR_NOT_FOUND;
220 : }
221 :
222 9 : if ( SQLITE_ROW == sqlite_err )
223 : {
224 5 : result |= data_diagram_init( out_diagram,
225 5 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_ID_COLUMN ),
226 5 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ),
227 5 : sqlite3_column_int( prepared_statement, RESULT_DIAGRAM_TYPE_COLUMN ),
228 5 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_STEREOTYPE_COLUMN ),
229 5 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_NAME_COLUMN ),
230 5 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_DESCRIPTION_COLUMN ),
231 5 : sqlite3_column_int( prepared_statement, RESULT_DIAGRAM_LIST_ORDER_COLUMN ),
232 5 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_DISPLAY_FLAGS_COLUMN ),
233 5 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAM_UUID_COLUMN )
234 : );
235 5 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ) )
236 : {
237 2 : (*out_diagram).parent_id = DATA_ROW_VOID;
238 : }
239 :
240 5 : data_diagram_trace( out_diagram );
241 :
242 5 : sqlite_err = sqlite3_step( prepared_statement );
243 5 : 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 9 : U8_TRACE_END_ERR( result );
252 9 : 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 58 : 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 58 : U8_TRACE_BEGIN();
292 58 : assert( NULL != io_diagram_iterator );
293 58 : u8_error_t result = U8_ERROR_NONE;
294 :
295 58 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_diagrams_by_classifier_id;
296 58 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, classifier_id );
297 58 : bool *const borrow_flag = &((*this_).statement_diagrams_by_classifier_id_borrowed);
298 :
299 : data_database_borrowed_stmt_t sql_statement;
300 58 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
301 58 : 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 58 : U8_TRACE_END_ERR( result );
305 58 : return result;
306 : }
307 :
308 31 : 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 31 : U8_TRACE_BEGIN();
313 31 : assert( NULL != io_diagram_iterator );
314 31 : u8_error_t result = U8_ERROR_NONE;
315 :
316 31 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_diagrams_by_relationship_id;
317 31 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, relationship_id );
318 31 : bool *const borrow_flag = &((*this_).statement_diagrams_by_relationship_id_borrowed);
319 :
320 : data_database_borrowed_stmt_t sql_statement;
321 31 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
322 31 : 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 31 : U8_TRACE_END_ERR( result );
326 31 : return result;
327 : }
328 :
329 24 : 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 24 : U8_TRACE_BEGIN();
334 24 : assert( NULL != out_diagram_ids );
335 24 : u8_error_t result = U8_ERROR_NONE;
336 : int sqlite_err;
337 : sqlite3_stmt *prepared_statement;
338 :
339 : {
340 24 : if ( DATA_ROW_VOID == parent_id )
341 : {
342 22 : prepared_statement = (*this_).statement_diagram_ids_by_parent_id_null;
343 22 : 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 24 : data_small_set_clear( out_diagram_ids );
352 24 : sqlite_err = SQLITE_ROW;
353 66 : for ( uint32_t row_index = 0; (SQLITE_ROW == sqlite_err) && (row_index <= DATA_SMALL_SET_MAX_SET_SIZE); row_index ++ )
354 : {
355 42 : U8_TRACE_INFO( "sqlite3_step()" );
356 42 : sqlite_err = sqlite3_step( prepared_statement );
357 42 : 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 42 : if (( SQLITE_ROW == sqlite_err )&&(row_index < DATA_SMALL_SET_MAX_SET_SIZE))
363 : {
364 : data_id_t current_diag_id;
365 18 : data_id_init( ¤t_diag_id, DATA_TABLE_DIAGRAM, sqlite3_column_int64( prepared_statement, RESULT_DIAGRAM_ID_COLUMN ) );
366 18 : result |= data_small_set_add_obj( out_diagram_ids, current_diag_id );
367 : }
368 42 : 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 42 : if ( SQLITE_DONE == sqlite_err )
374 : {
375 24 : U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
376 : }
377 : }
378 24 : data_small_set_trace( out_diagram_ids );
379 : }
380 :
381 24 : U8_TRACE_END_ERR( result );
382 24 : 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 43 : 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 43 : U8_TRACE_BEGIN();
482 43 : assert( NULL != out_diagramelement );
483 43 : u8_error_t result = U8_ERROR_NONE;
484 : int sqlite_err;
485 : sqlite3_stmt *prepared_statement;
486 :
487 : {
488 43 : prepared_statement = (*this_).statement_diagramelement_by_id;
489 :
490 43 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, prepared_statement, id );
491 :
492 43 : U8_TRACE_INFO( "sqlite3_step()" );
493 43 : sqlite_err = sqlite3_step( prepared_statement );
494 43 : 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 43 : if ( SQLITE_ROW == sqlite_err )
501 : {
502 40 : result |= data_diagramelement_init( out_diagramelement,
503 40 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_ID_COLUMN ),
504 40 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_DIAGRAM_ID_COLUMN ),
505 40 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_CLASSIFIER_ID_COLUMN ),
506 40 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_DISPLAY_FLAGS_COLUMN ),
507 40 : sqlite3_column_int64( prepared_statement, RESULT_DIAGRAMELEMENT_FOCUSED_FEATURE_ID_COLUMN ),
508 40 : (const char*) sqlite3_column_text( prepared_statement, RESULT_DIAGRAMELEMENT_UUID_COLUMN )
509 : );
510 40 : if ( SQLITE_NULL == sqlite3_column_type( prepared_statement, RESULT_DIAGRAMELEMENT_FOCUSED_FEATURE_ID_COLUMN ) )
511 : {
512 25 : data_diagramelement_set_focused_feature_row ( out_diagramelement, DATA_ROW_VOID );
513 : }
514 :
515 40 : data_diagramelement_trace( out_diagramelement );
516 :
517 40 : sqlite_err = sqlite3_step( prepared_statement );
518 40 : 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 43 : U8_TRACE_END_ERR( result );
527 43 : return result;
528 : }
529 :
530 3 : 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 3 : U8_TRACE_BEGIN();
535 3 : assert( NULL != uuid );
536 3 : assert( NULL != out_diagramelement );
537 3 : u8_error_t result = U8_ERROR_NONE;
538 : int sqlite_err;
539 : sqlite3_stmt *prepared_statement;
540 :
541 : {
542 3 : prepared_statement = (*this_).statement_diagramelement_by_uuid;
543 :
544 3 : result |= data_database_diagram_reader_private_bind_text_to_statement( this_, prepared_statement, uuid );
545 :
546 3 : U8_TRACE_INFO( "sqlite3_step()" );
547 3 : sqlite_err = sqlite3_step( prepared_statement );
548 3 : if ( SQLITE_ROW != sqlite_err )
549 : {
550 : /* Do not log this incident, the caller may not expect to find a row. */
551 2 : U8_TRACE_INFO_STR( "sqlite3_step did not find a row for uuid", uuid );
552 2 : result |= U8_ERROR_NOT_FOUND;
553 : }
554 :
555 3 : 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 ( 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 3 : U8_TRACE_END_ERR( result );
582 3 : return result;
583 : }
584 :
585 155 : 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 155 : U8_TRACE_BEGIN();
590 155 : assert( NULL != io_diagramelement_iterator );
591 155 : u8_error_t result = U8_ERROR_NONE;
592 :
593 155 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_diagramelements_by_diagram_id;
594 155 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, diagram_id );
595 155 : bool *const borrow_flag = &((*this_).statement_diagramelements_by_diagram_id_borrowed);
596 :
597 : data_database_borrowed_stmt_t sql_statement;
598 155 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
599 155 : 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 155 : U8_TRACE_END_ERR( result );
603 155 : return result;
604 : }
605 :
606 9 : 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 9 : U8_TRACE_BEGIN();
611 9 : assert( NULL != io_diagramelement_iterator );
612 9 : u8_error_t result = U8_ERROR_NONE;
613 :
614 9 : sqlite3_stmt *const sqlite3_stmt = (*this_).statement_diagramelements_by_classifier_id;
615 9 : result |= data_database_diagram_reader_private_bind_id_to_statement( this_, sqlite3_stmt, classifier_id );
616 9 : bool *const borrow_flag = &((*this_).statement_diagramelements_by_classifier_id_borrowed);
617 :
618 : data_database_borrowed_stmt_t sql_statement;
619 9 : data_database_borrowed_stmt_init( &sql_statement, (*this_).database, sqlite3_stmt, borrow_flag );
620 9 : 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 9 : U8_TRACE_END_ERR( result );
624 9 : 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 112 : u8_error_t data_database_diagram_reader_private_open( data_database_diagram_reader_t *this_ )
653 : {
654 112 : U8_TRACE_BEGIN();
655 112 : u8_error_t result = U8_ERROR_NONE;
656 :
657 : {
658 112 : 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 112 : 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 112 : 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 112 : (*this_).statement_diagrams_by_parent_id_borrowed = false;
676 :
677 112 : 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 112 : (*this_).statement_diagrams_by_parent_id_borrowed = false;
683 :
684 112 : 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 112 : (*this_).statement_diagrams_by_classifier_id_borrowed = false;
690 :
691 112 : 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 112 : (*this_).statement_diagrams_by_relationship_id_borrowed = false;
697 :
698 112 : 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 112 : 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 112 : 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 112 : 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 112 : 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 112 : 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 112 : (*this_).statement_diagramelements_by_diagram_id_borrowed = false;
734 :
735 112 : 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 112 : (*this_).statement_diagramelements_by_classifier_id_borrowed = false;
741 :
742 112 : 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 112 : (*this_).statement_visible_classifiers_by_diagram_id_borrowed = false;
748 :
749 112 : if ( result != U8_ERROR_NONE )
750 : {
751 0 : U8_LOG_ERROR( "A prepared statement could not be prepared." );
752 : }
753 : }
754 :
755 112 : U8_TRACE_END_ERR(result);
756 112 : return result;
757 : }
758 :
759 112 : u8_error_t data_database_diagram_reader_private_close( data_database_diagram_reader_t *this_ )
760 : {
761 112 : U8_TRACE_BEGIN();
762 112 : u8_error_t result = U8_ERROR_NONE;
763 :
764 : {
765 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_by_id );
766 112 : (*this_).statement_diagram_by_id = NULL;
767 :
768 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_by_uuid );
769 112 : (*this_).statement_diagram_by_uuid = NULL;
770 :
771 112 : assert( (*this_).statement_diagrams_by_parent_id_borrowed == false );
772 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_parent_id );
773 112 : (*this_).statement_diagrams_by_parent_id = NULL;
774 :
775 112 : assert( (*this_).statement_diagrams_by_parent_id_null_borrowed == false );
776 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_parent_id_null );
777 112 : (*this_).statement_diagrams_by_parent_id_null = NULL;
778 :
779 112 : assert( (*this_).statement_diagrams_by_classifier_id_borrowed == false );
780 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_classifier_id );
781 112 : (*this_).statement_diagrams_by_classifier_id = NULL;
782 :
783 112 : assert( (*this_).statement_diagrams_by_relationship_id_borrowed == false );
784 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_relationship_id );
785 112 : (*this_).statement_diagrams_by_relationship_id = NULL;
786 :
787 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_parent_id );
788 112 : (*this_).statement_diagram_ids_by_parent_id = NULL;
789 :
790 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_parent_id_null );
791 112 : (*this_).statement_diagram_ids_by_parent_id_null = NULL;
792 :
793 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_classifier_id );
794 112 : (*this_).statement_diagram_ids_by_classifier_id = NULL;
795 :
796 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelement_by_id );
797 112 : (*this_).statement_diagramelement_by_id = NULL;
798 :
799 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelement_by_uuid );
800 112 : (*this_).statement_diagramelement_by_uuid = NULL;
801 :
802 112 : assert( (*this_).statement_diagramelements_by_diagram_id_borrowed == false );
803 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelements_by_diagram_id );
804 112 : (*this_).statement_diagramelements_by_diagram_id = NULL;
805 :
806 112 : assert( (*this_).statement_diagramelements_by_classifier_id_borrowed == false );
807 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelements_by_classifier_id );
808 112 : (*this_).statement_diagramelements_by_classifier_id = NULL;
809 :
810 112 : assert( (*this_).statement_visible_classifiers_by_diagram_id_borrowed == false );
811 112 : result |= data_database_finalize_statement( (*this_).database, (*this_).statement_visible_classifiers_by_diagram_id );
812 112 : (*this_).statement_visible_classifiers_by_diagram_id = NULL;
813 : }
814 :
815 112 : U8_TRACE_END_ERR(result);
816 112 : return result;
817 : }
818 :
819 :
820 : /*
821 : Copyright 2016-2026 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 : */
|