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