LCOV - code coverage report
Current view: top level - data/source/storage - data_diagram_iterator.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.70.5_covts Lines: 94.1 % 68 64
Test Date: 2026-05-28 21:31:40 Functions: 100.0 % 6 6

            Line data    Source code
       1              : /* File: data_diagram_iterator.c; Copyright and License: see below */
       2              : 
       3              : #include "storage/data_diagram_iterator.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              : #include <stdint.h>
      10              : 
      11              : const char *const DATA_DIAGRAM_ITERATOR_SELECT_DIAGRAMS_BY_PARENT_ID =
      12              :     "SELECT id,parent_id,diagram_type,stereotype,name,description,list_order,display_flags,uuid "
      13              :     "FROM diagrams WHERE parent_id=? ORDER BY list_order ASC;";
      14              : 
      15              : const char *const DATA_DIAGRAM_ITERATOR_SELECT_DIAGRAMS_BY_PARENT_ID_NULL =
      16              :     "SELECT id,parent_id,diagram_type,stereotype,name,description,list_order,display_flags,uuid "
      17              :     "FROM diagrams WHERE parent_id IS NULL ORDER BY list_order ASC,diagrams.id ASC;";  /* ensure always the same order */
      18              : 
      19              : const char *const DATA_DIAGRAM_ITERATOR_SELECT_DIAGRAMS_BY_CLASSIFIER_ID =
      20              :     "SELECT diagrams.id,diagrams.parent_id,diagrams.diagram_type,diagrams.stereotype,"
      21              :     "diagrams.name,diagrams.description,diagrams.list_order,diagrams.display_flags,diagrams.uuid "
      22              :     "FROM diagrams "
      23              :     "INNER JOIN diagramelements ON diagramelements.diagram_id=diagrams.id "
      24              :     "WHERE diagramelements.classifier_id=? "
      25              :     "GROUP BY diagrams.id "  /* filter duplicates if a classifier exists twice in a diagram */
      26              :     "ORDER BY diagrams.list_order ASC,diagrams.id ASC;";  /* ensure always the same order */
      27              : 
      28              : const char *const DATA_DIAGRAM_ITERATOR_SELECT_DIAGRAMS_BY_RELATIONSHIP_ID =
      29              :     "SELECT diagrams.id,diagrams.parent_id,diagrams.diagram_type,diagrams.stereotype,"
      30              :     "diagrams.name,diagrams.description,diagrams.list_order,diagrams.display_flags,diagrams.uuid "
      31              :     "FROM relationships "
      32              :     "INNER JOIN diagramelements AS source ON source.classifier_id=relationships.from_classifier_id "
      33              :     "INNER JOIN diagramelements AS dest ON (dest.classifier_id=relationships.to_classifier_id) AND (dest.diagram_id=source.diagram_id) "
      34              :     "INNER JOIN diagrams ON diagrams.id=source.diagram_id "
      35              :     "WHERE relationships.id=? "
      36              :     "AND ( (source.focused_feature_id=relationships.from_feature_id) OR (source.focused_feature_id ISNULL) ) "
      37              :     "AND ( (dest.focused_feature_id=relationships.to_feature_id) OR (dest.focused_feature_id ISNULL) ) "
      38              :     "GROUP BY diagrams.id " /* filter duplicates if a relationship exists twice in a diagram */
      39              :     "ORDER BY ( (source.focused_feature_id ISNULL) AND (dest.focused_feature_id ISNULL) ) ASC,"  /* start with interactions/scenarios */
      40              :     "diagrams.list_order ASC,diagrams.id ASC;";  /* ensure always the same order */
      41              : 
      42              :     /* Note: This query omits scenario/interaction diagrams */
      43              :     /* which either contain the searched relationship as invariant/non-scenario relationship */
      44              :     /* or which show another lifeline than the one of the searched relationship. */
      45              :     /* It does not filter any invariant/non-scenario diagram even if the relationship is not visible there. */
      46              : 
      47              : /*!
      48              :  *  \brief the column id of the result where this parameter is stored: id
      49              :  */
      50              : static const int RESULT_DIAGRAM_ID_COLUMN = 0;
      51              : 
      52              : /*!
      53              :  *  \brief the column id of the result where this parameter is stored: parent_id
      54              :  */
      55              : static const int RESULT_DIAGRAM_PARENT_ID_COLUMN = 1;
      56              : 
      57              : /*!
      58              :  *  \brief the column id of the result where this parameter is stored: type
      59              :  */
      60              : static const int RESULT_DIAGRAM_TYPE_COLUMN = 2;
      61              : 
      62              : /*!
      63              :  *  \brief the column id of the result where this parameter is stored: stereotype
      64              :  */
      65              : static const int RESULT_DIAGRAM_STEREOTYPE_COLUMN = 3;
      66              : 
      67              : /*!
      68              :  *  \brief the column id of the result where this parameter is stored: name
      69              :  */
      70              : static const int RESULT_DIAGRAM_NAME_COLUMN = 4;
      71              : 
      72              : /*!
      73              :  *  \brief the column id of the result where this parameter is stored: description
      74              :  */
      75              : static const int RESULT_DIAGRAM_DESCRIPTION_COLUMN = 5;
      76              : 
      77              : /*!
      78              :  *  \brief the column id of the result where this parameter is stored: list_order
      79              :  */
      80              : static const int RESULT_DIAGRAM_LIST_ORDER_COLUMN = 6;
      81              : 
      82              : /*!
      83              :  *  \brief the column id of the result where this parameter is stored: display_flags
      84              :  */
      85              : static const int RESULT_DIAGRAM_DISPLAY_FLAGS_COLUMN = 7;
      86              : 
      87              : /*!
      88              :  *  \brief the column id of the result where this parameter is stored: uuid
      89              :  */
      90              : static const int RESULT_DIAGRAM_UUID_COLUMN = 8;
      91              : 
      92          264 : void data_diagram_iterator_init_empty ( data_diagram_iterator_t *this_ )
      93              : {
      94          264 :     U8_TRACE_BEGIN();
      95              : 
      96          264 :     data_database_borrowed_stmt_init_void( &((*this_).statement) );
      97          264 :     (*this_).is_at_end = true;
      98              : 
      99          264 :     U8_TRACE_END();
     100          264 : }
     101              : 
     102          264 : u8_error_t data_diagram_iterator_reinit ( data_diagram_iterator_t *this_,
     103              :                                           data_database_borrowed_stmt_t statement )
     104              : {
     105          264 :     U8_TRACE_BEGIN();
     106          264 :     assert( data_database_borrowed_stmt_is_valid( &statement ) );
     107          264 :     u8_error_t result = U8_ERROR_NONE;
     108              : 
     109              :     /* destroy old state */
     110          264 :     result = data_diagram_iterator_destroy( this_ );
     111              : 
     112              :     /* init new state */
     113          264 :     (*this_).statement = statement;
     114          264 :     (*this_).is_at_end = false;
     115          264 :     result |= data_diagram_iterator_private_step_to_next( this_ );
     116              : 
     117          264 :     U8_TRACE_END_ERR(result);
     118          264 :     return result;
     119              : }
     120              : 
     121          528 : u8_error_t data_diagram_iterator_destroy ( data_diagram_iterator_t *this_ )
     122              : {
     123          528 :     U8_TRACE_BEGIN();
     124          528 :     u8_error_t result = U8_ERROR_NONE;
     125              : 
     126          528 :     result |= data_database_borrowed_stmt_destroy( &((*this_).statement) );
     127          528 :     (*this_).is_at_end = true;
     128              : 
     129          528 :     U8_TRACE_END_ERR(result);
     130          528 :     return result;
     131              : }
     132              : 
     133          393 : bool data_diagram_iterator_has_next ( const data_diagram_iterator_t *this_ )
     134              : {
     135          393 :     return ( ! (*this_).is_at_end );
     136              : }
     137              : 
     138          140 : u8_error_t data_diagram_iterator_next ( data_diagram_iterator_t *this_, data_diagram_t *out_diagram )
     139              : {
     140          140 :     U8_TRACE_BEGIN();
     141          140 :     assert( NULL != out_diagram );
     142          140 :     assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
     143          140 :     u8_error_t result = U8_ERROR_NONE;
     144              : 
     145          140 :     if ( ! (*this_).is_at_end )
     146              :     {
     147          138 :         sqlite3_stmt *const sql_statement = data_database_borrowed_stmt_get_statement( &((*this_).statement) );
     148          138 :         result |= data_diagram_init( out_diagram,
     149          138 :                                      sqlite3_column_int64( sql_statement, RESULT_DIAGRAM_ID_COLUMN ),
     150          138 :                                      sqlite3_column_int64( sql_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ),
     151          138 :                                      sqlite3_column_int( sql_statement, RESULT_DIAGRAM_TYPE_COLUMN ),
     152          138 :                                      (const char*) sqlite3_column_text( sql_statement, RESULT_DIAGRAM_STEREOTYPE_COLUMN ),
     153          138 :                                      (const char*) sqlite3_column_text( sql_statement, RESULT_DIAGRAM_NAME_COLUMN ),
     154          138 :                                      (const char*) sqlite3_column_text( sql_statement, RESULT_DIAGRAM_DESCRIPTION_COLUMN ),
     155          138 :                                      sqlite3_column_int( sql_statement, RESULT_DIAGRAM_LIST_ORDER_COLUMN ),
     156          138 :                                      sqlite3_column_int64( sql_statement, RESULT_DIAGRAM_DISPLAY_FLAGS_COLUMN ),
     157          138 :                                      (const char*) sqlite3_column_text( sql_statement, RESULT_DIAGRAM_UUID_COLUMN )
     158              :                                    );
     159          138 :         if ( SQLITE_NULL == sqlite3_column_type( sql_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ) )
     160              :         {
     161           87 :             data_diagram_set_parent_row( out_diagram, DATA_ROW_VOID );
     162              :         }
     163          138 :         data_diagram_trace( out_diagram );
     164              : 
     165              :         /* step to next */
     166          138 :         result |= data_diagram_iterator_private_step_to_next( this_ );
     167              :     }
     168              :     else
     169              :     {
     170            2 :         U8_TRACE_INFO( "iterator already at end" );
     171            2 :         (*this_).is_at_end = true;
     172            2 :         result |= U8_ERROR_INVALID_REQUEST;
     173              :     }
     174              : 
     175          140 :     U8_TRACE_END_ERR( result );
     176          140 :     return result;
     177              : }
     178              : 
     179          402 : u8_error_t data_diagram_iterator_private_step_to_next ( data_diagram_iterator_t *this_ )
     180              : {
     181          402 :     U8_TRACE_BEGIN();
     182          402 :     assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
     183          402 :     u8_error_t result = U8_ERROR_NONE;
     184              : 
     185              :     /* do one step, check if is_at_end */
     186              :     {
     187              :         int sqlite_err;
     188          402 :         U8_TRACE_INFO( "sqlite3_step()" );
     189          402 :         sqlite_err = sqlite3_step( data_database_borrowed_stmt_get_statement( &((*this_).statement) ) );
     190          402 :         if ( SQLITE_DONE == sqlite_err )
     191              :         {
     192          256 :             U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
     193          256 :             (*this_).is_at_end = true;
     194              :         }
     195          146 :         else if ( SQLITE_ROW == sqlite_err )
     196              :         {
     197          146 :             (*this_).is_at_end = false;
     198              :         }
     199              :         else
     200              :         {
     201            0 :             U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
     202            0 :             (*this_).is_at_end = true;
     203            0 :             result |= data_diagram_iterator_destroy( this_ );
     204            0 :             result |= U8_ERROR_AT_DB;
     205              :         }
     206              :     }
     207              : 
     208          402 :     U8_TRACE_END_ERR(result);
     209          402 :     return result;
     210              : }
     211              : 
     212              : 
     213              : /*
     214              : Copyright 2024-2026 Andreas Warnke
     215              : 
     216              : Licensed under the Apache License, Version 2.0 (the "License");
     217              : you may not use this file except in compliance with the License.
     218              : You may obtain a copy of the License at
     219              : 
     220              :     http://www.apache.org/licenses/LICENSE-2.0
     221              : 
     222              : Unless required by applicable law or agreed to in writing, software
     223              : distributed under the License is distributed on an "AS IS" BASIS,
     224              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     225              : See the License for the specific language governing permissions and
     226              : limitations under the License.
     227              : */
        

Generated by: LCOV version 2.0-1