LCOV - code coverage report
Current view: top level - data/source/storage - data_diagram_iterator.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.65.6_covts Lines: 64 68 94.1 %
Date: 2025-09-25 21:07:53 Functions: 6 6 100.0 %

          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         189 : u8_error_t data_diagram_iterator_init_empty ( data_diagram_iterator_t *this_ )
      93             : {
      94         189 :     U8_TRACE_BEGIN();
      95         189 :     u8_error_t result = U8_ERROR_NONE;
      96             : 
      97         189 :     data_database_borrowed_stmt_init_void( &((*this_).statement) );
      98         189 :     (*this_).is_at_end = true;
      99             : 
     100         189 :     U8_TRACE_END_ERR(result);
     101         189 :     return result;
     102             : }
     103             : 
     104         189 : u8_error_t data_diagram_iterator_reinit ( data_diagram_iterator_t *this_,
     105             :                                           data_database_borrowed_stmt_t statement )
     106             : {
     107         189 :     U8_TRACE_BEGIN();
     108         189 :     assert( data_database_borrowed_stmt_is_valid( &statement ) );
     109         189 :     u8_error_t result = U8_ERROR_NONE;
     110             : 
     111             :     /* destroy old state */
     112         189 :     result = data_diagram_iterator_destroy( this_ );
     113             : 
     114             :     /* init new state */
     115         189 :     (*this_).statement = statement;
     116         189 :     (*this_).is_at_end = false;
     117         189 :     result |= data_diagram_iterator_private_step_to_next( this_ );
     118             : 
     119         189 :     U8_TRACE_END_ERR(result);
     120         189 :     return result;
     121             : }
     122             : 
     123         378 : u8_error_t data_diagram_iterator_destroy ( data_diagram_iterator_t *this_ )
     124             : {
     125         378 :     U8_TRACE_BEGIN();
     126         378 :     u8_error_t result = U8_ERROR_NONE;
     127             : 
     128         378 :     result |= data_database_borrowed_stmt_destroy( &((*this_).statement) );
     129         378 :     (*this_).is_at_end = true;
     130             : 
     131         378 :     U8_TRACE_END_ERR(result);
     132         378 :     return result;
     133             : }
     134             : 
     135         221 : bool data_diagram_iterator_has_next ( const data_diagram_iterator_t *this_ )
     136             : {
     137         221 :     return ( ! (*this_).is_at_end );
     138             : }
     139             : 
     140          43 : u8_error_t data_diagram_iterator_next ( data_diagram_iterator_t *this_, data_diagram_t *out_diagram )
     141             : {
     142          43 :     U8_TRACE_BEGIN();
     143          43 :     assert( NULL != out_diagram );
     144          43 :     assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
     145          43 :     u8_error_t result = U8_ERROR_NONE;
     146             : 
     147          43 :     if ( ! (*this_).is_at_end )
     148             :     {
     149          41 :         sqlite3_stmt *const sql_statement = data_database_borrowed_stmt_get_statement( &((*this_).statement) );
     150          82 :         result |= data_diagram_init( out_diagram,
     151          41 :                                      sqlite3_column_int64( sql_statement, RESULT_DIAGRAM_ID_COLUMN ),
     152          41 :                                      sqlite3_column_int64( sql_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ),
     153          41 :                                      sqlite3_column_int( sql_statement, RESULT_DIAGRAM_TYPE_COLUMN ),
     154          41 :                                      (const char*) sqlite3_column_text( sql_statement, RESULT_DIAGRAM_STEREOTYPE_COLUMN ),
     155          41 :                                      (const char*) sqlite3_column_text( sql_statement, RESULT_DIAGRAM_NAME_COLUMN ),
     156          41 :                                      (const char*) sqlite3_column_text( sql_statement, RESULT_DIAGRAM_DESCRIPTION_COLUMN ),
     157             :                                      sqlite3_column_int( sql_statement, RESULT_DIAGRAM_LIST_ORDER_COLUMN ),
     158          41 :                                      sqlite3_column_int64( sql_statement, RESULT_DIAGRAM_DISPLAY_FLAGS_COLUMN ),
     159          41 :                                      (const char*) sqlite3_column_text( sql_statement, RESULT_DIAGRAM_UUID_COLUMN )
     160             :                                    );
     161          41 :         if ( SQLITE_NULL == sqlite3_column_type( sql_statement, RESULT_DIAGRAM_PARENT_ID_COLUMN ) )
     162             :         {
     163          38 :             data_diagram_set_parent_row_id( out_diagram, DATA_ROW_VOID );
     164             :         }
     165          41 :         data_diagram_trace( out_diagram );
     166             : 
     167             :         /* step to next */
     168          41 :         result |= data_diagram_iterator_private_step_to_next( this_ );
     169             :     }
     170             :     else
     171             :     {
     172           2 :         U8_TRACE_INFO( "iterator already at end" );
     173           2 :         (*this_).is_at_end = true;
     174           2 :         result |= U8_ERROR_INVALID_REQUEST;
     175             :     }
     176             : 
     177          43 :     U8_TRACE_END_ERR( result );
     178          43 :     return result;
     179             : }
     180             : 
     181         230 : u8_error_t data_diagram_iterator_private_step_to_next ( data_diagram_iterator_t *this_ )
     182             : {
     183         230 :     U8_TRACE_BEGIN();
     184         230 :     assert( data_database_borrowed_stmt_is_valid( &((*this_).statement) ) );
     185         230 :     u8_error_t result = U8_ERROR_NONE;
     186             : 
     187             :     /* do one step, check if is_at_end */
     188             :     {
     189             :         int sqlite_err;
     190         230 :         U8_TRACE_INFO( "sqlite3_step()" );
     191         230 :         sqlite_err = sqlite3_step( data_database_borrowed_stmt_get_statement( &((*this_).statement) ) );
     192         230 :         if ( SQLITE_DONE == sqlite_err )
     193             :         {
     194         184 :             U8_TRACE_INFO( "sqlite3_step finished: SQLITE_DONE" );
     195         184 :             (*this_).is_at_end = true;
     196             :         }
     197          46 :         else if ( SQLITE_ROW == sqlite_err )
     198             :         {
     199          46 :             (*this_).is_at_end = false;
     200             :         }
     201             :         else
     202             :         {
     203           0 :             U8_LOG_ERROR_INT( "sqlite3_step failed:", sqlite_err );
     204           0 :             (*this_).is_at_end = true;
     205           0 :             result |= data_diagram_iterator_destroy( this_ );
     206           0 :             result |= U8_ERROR_AT_DB;
     207             :         }
     208             :     }
     209             : 
     210         230 :     U8_TRACE_END_ERR(result);
     211         230 :     return result;
     212             : }
     213             : 
     214             : 
     215             : /*
     216             : Copyright 2024-2025 Andreas Warnke
     217             : 
     218             : Licensed under the Apache License, Version 2.0 (the "License");
     219             : you may not use this file except in compliance with the License.
     220             : You may obtain a copy of the License at
     221             : 
     222             :     http://www.apache.org/licenses/LICENSE-2.0
     223             : 
     224             : Unless required by applicable law or agreed to in writing, software
     225             : distributed under the License is distributed on an "AS IS" BASIS,
     226             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     227             : See the License for the specific language governing permissions and
     228             : limitations under the License.
     229             : */

Generated by: LCOV version 1.16