LCOV - code coverage report
Current view: top level - data/source/storage - data_database_diagram_reader.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.67.0_covts Lines: 91.7 % 339 311
Test Date: 2025-11-06 17:22:08 Functions: 93.8 % 16 15

            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          102 : u8_error_t data_database_diagram_reader_init( data_database_diagram_reader_t *this_, data_database_t *database )
      11              : {
      12          102 :     U8_TRACE_BEGIN();
      13          102 :     assert( NULL != database );
      14          102 :     u8_error_t result = U8_ERROR_NONE;
      15              : 
      16          102 :     (*this_).database = database;
      17              : 
      18          102 :     (*this_).statement_diagram_by_id = NULL;
      19          102 :     (*this_).statement_diagram_by_uuid = NULL;
      20          102 :     (*this_).statement_diagrams_by_parent_id = NULL;
      21          102 :     (*this_).statement_diagrams_by_parent_id_null = NULL;
      22          102 :     (*this_).statement_diagrams_by_classifier_id = NULL;
      23          102 :     (*this_).statement_diagrams_by_relationship_id = NULL;
      24          102 :     (*this_).statement_diagram_ids_by_parent_id = NULL;
      25          102 :     (*this_).statement_diagram_ids_by_parent_id_null = NULL;
      26          102 :     (*this_).statement_diagram_ids_by_classifier_id = NULL;
      27              : 
      28          102 :     (*this_).statement_diagramelement_by_id = NULL;
      29          102 :     (*this_).statement_diagramelement_by_uuid = NULL;
      30          102 :     (*this_).statement_diagramelements_by_diagram_id = NULL;
      31          102 :     (*this_).statement_diagramelements_by_classifier_id = NULL;
      32              : 
      33          102 :     (*this_).statement_visible_classifiers_by_diagram_id = NULL;
      34              : 
      35          102 :     result |= data_database_diagram_reader_private_open( this_ );
      36              : 
      37          102 :     U8_TRACE_END_ERR(result);
      38          102 :     return result;
      39              : }
      40              : 
      41          102 : u8_error_t data_database_diagram_reader_destroy( data_database_diagram_reader_t *this_ )
      42              : {
      43          102 :     U8_TRACE_BEGIN();
      44          102 :     u8_error_t result = U8_ERROR_NONE;
      45              : 
      46          102 :     result |= data_database_diagram_reader_private_close( this_ );
      47              : 
      48          102 :     (*this_).database = NULL;
      49              : 
      50          102 :     U8_TRACE_END_ERR(result);
      51          102 :     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           71 :             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           71 :                                          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            4 :             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            4 :                                          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( &current_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( &current_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( &current_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          102 : u8_error_t data_database_diagram_reader_private_open( data_database_diagram_reader_t *this_ )
     653              : {
     654          102 :     U8_TRACE_BEGIN();
     655          102 :     u8_error_t result = U8_ERROR_NONE;
     656              : 
     657              :     {
     658          102 :         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          102 :         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          102 :         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          102 :         (*this_).statement_diagrams_by_parent_id_borrowed = false;
     676              : 
     677          102 :         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          102 :         (*this_).statement_diagrams_by_parent_id_borrowed = false;
     683              : 
     684          102 :         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          102 :         (*this_).statement_diagrams_by_classifier_id_borrowed = false;
     690              : 
     691          102 :         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          102 :         (*this_).statement_diagrams_by_relationship_id_borrowed = false;
     697              : 
     698          102 :         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          102 :         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          102 :         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          102 :         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          102 :         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          102 :         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          102 :         (*this_).statement_diagramelements_by_diagram_id_borrowed = false;
     734              : 
     735          102 :         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          102 :         (*this_).statement_diagramelements_by_classifier_id_borrowed = false;
     741              : 
     742          102 :         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          102 :         (*this_).statement_visible_classifiers_by_diagram_id_borrowed = false;
     748              : 
     749          102 :         if ( result != U8_ERROR_NONE )
     750              :         {
     751            0 :             U8_LOG_ERROR( "A prepared statement could not be prepared." );
     752              :         }
     753              :     }
     754              : 
     755          102 :     U8_TRACE_END_ERR(result);
     756          102 :     return result;
     757              : }
     758              : 
     759          102 : u8_error_t data_database_diagram_reader_private_close( data_database_diagram_reader_t *this_ )
     760              : {
     761          102 :     U8_TRACE_BEGIN();
     762          102 :     u8_error_t result = U8_ERROR_NONE;
     763              : 
     764              :     {
     765          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_by_id );
     766          102 :         (*this_).statement_diagram_by_id = NULL;
     767              : 
     768          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_by_uuid );
     769          102 :         (*this_).statement_diagram_by_uuid = NULL;
     770              : 
     771          102 :         assert( (*this_).statement_diagrams_by_parent_id_borrowed == false );
     772          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_parent_id );
     773          102 :         (*this_).statement_diagrams_by_parent_id = NULL;
     774              : 
     775          102 :         assert( (*this_).statement_diagrams_by_parent_id_null_borrowed == false );
     776          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_parent_id_null );
     777          102 :         (*this_).statement_diagrams_by_parent_id_null = NULL;
     778              : 
     779          102 :         assert( (*this_).statement_diagrams_by_classifier_id_borrowed == false );
     780          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_classifier_id );
     781          102 :         (*this_).statement_diagrams_by_classifier_id = NULL;
     782              : 
     783          102 :         assert( (*this_).statement_diagrams_by_relationship_id_borrowed == false );
     784          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagrams_by_relationship_id );
     785          102 :         (*this_).statement_diagrams_by_relationship_id = NULL;
     786              : 
     787          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_parent_id );
     788          102 :         (*this_).statement_diagram_ids_by_parent_id = NULL;
     789              : 
     790          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_parent_id_null );
     791          102 :         (*this_).statement_diagram_ids_by_parent_id_null = NULL;
     792              : 
     793          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagram_ids_by_classifier_id );
     794          102 :         (*this_).statement_diagram_ids_by_classifier_id = NULL;
     795              : 
     796          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelement_by_id );
     797          102 :         (*this_).statement_diagramelement_by_id = NULL;
     798              : 
     799          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelement_by_uuid );
     800          102 :         (*this_).statement_diagramelement_by_uuid = NULL;
     801              : 
     802          102 :         assert( (*this_).statement_diagramelements_by_diagram_id_borrowed == false );
     803          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelements_by_diagram_id );
     804          102 :         (*this_).statement_diagramelements_by_diagram_id = NULL;
     805              : 
     806          102 :         assert( (*this_).statement_diagramelements_by_classifier_id_borrowed == false );
     807          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_diagramelements_by_classifier_id );
     808          102 :         (*this_).statement_diagramelements_by_classifier_id = NULL;
     809              : 
     810          102 :         assert( (*this_).statement_visible_classifiers_by_diagram_id_borrowed == false );
     811          102 :         result |= data_database_finalize_statement( (*this_).database, (*this_).statement_visible_classifiers_by_diagram_id );
     812          102 :         (*this_).statement_visible_classifiers_by_diagram_id = NULL;
     813              :     }
     814              : 
     815          102 :     U8_TRACE_END_ERR(result);
     816          102 :     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              : */
        

Generated by: LCOV version 2.0-1