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.63.2_covts Lines: 94.7 % 320 303
Test Date: 2025-05-01 10:10:14 Functions: 100.0 % 15 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          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( &current_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( &current_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( &current_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-2025 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              : */
        

Generated by: LCOV version 2.0-1