LCOV - code coverage report
Current view: top level - io/source - io_export_flat_traversal.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 19.6 % 143 28
Test Date: 2025-05-01 10:10:14 Functions: 42.9 % 7 3

            Line data    Source code
       1              : /* File: io_export_flat_traversal.c; Copyright and License: see below */
       2              : 
       3              : #include "io_export_flat_traversal.h"
       4              : #include "u8/u8_trace.h"
       5              : #include "entity/data_diagram.h"
       6              : #include "entity/data_classifier.h"
       7              : #include <stdint.h>
       8              : #include <stdio.h>
       9              : #include <stdlib.h>
      10              : 
      11            2 : void io_export_flat_traversal_init( io_export_flat_traversal_t *this_,
      12              :                                      data_database_reader_t *db_reader,
      13              :                                      data_stat_t *io_export_stat,
      14              :                                      io_element_writer_t *out_element_writer )
      15              : {
      16            2 :     U8_TRACE_BEGIN();
      17            2 :     assert( NULL != db_reader );
      18            2 :     assert( NULL != io_export_stat );
      19            2 :     assert( NULL != out_element_writer );
      20              : 
      21            2 :     (*this_).db_reader = db_reader;
      22            2 :     (*this_).export_stat = io_export_stat;
      23            2 :     (*this_).element_writer = out_element_writer;
      24              : 
      25            2 :     U8_TRACE_END();
      26            2 : }
      27              : 
      28            2 : void io_export_flat_traversal_destroy( io_export_flat_traversal_t *this_ )
      29              : {
      30            2 :     U8_TRACE_BEGIN();
      31              : 
      32            2 :     (*this_).db_reader = NULL;
      33            2 :     (*this_).export_stat = NULL;
      34            2 :     (*this_).element_writer = NULL;
      35              : 
      36            2 :     U8_TRACE_END();
      37            2 : }
      38              : 
      39            4 : u8_error_t io_export_flat_traversal_iterate_classifiers( io_export_flat_traversal_t *this_, bool hierarchical  )
      40              : {
      41            4 :     U8_TRACE_BEGIN();
      42            4 :     u8_error_t write_err = U8_ERROR_NONE;
      43              : 
      44              :     {
      45              :         u8_error_t data_err;
      46              :         data_classifier_iterator_t classifier_iterator;
      47              : 
      48              :         /* init the iterator */
      49            4 :         data_classifier_iterator_init_empty( &classifier_iterator );
      50            4 :         data_err = data_database_reader_get_all_classifiers ( (*this_).db_reader, hierarchical, &classifier_iterator );
      51            4 :         if ( data_err != U8_ERROR_NONE )
      52              :         {
      53            0 :             write_err |= data_err;
      54              :         }
      55              :         else
      56              :         {
      57            4 :             while( data_classifier_iterator_has_next( &classifier_iterator ) && ( write_err == U8_ERROR_NONE ) )
      58              :             {
      59            0 :                 data_err = data_classifier_iterator_next( &classifier_iterator, &((*this_).temp_classifier) );
      60            0 :                 if ( data_err != U8_ERROR_NONE )
      61              :                 {
      62            0 :                     write_err |= data_err;
      63              :                 }
      64              :                 else
      65              :                 {
      66            0 :                     write_err |= io_export_flat_traversal_private_traverse_classifier( this_, &((*this_).temp_classifier) );
      67              : 
      68            0 :                     data_classifier_destroy( &((*this_).temp_classifier) );
      69              :                 }
      70              :             }
      71              :         }
      72            4 :         data_err = data_classifier_iterator_destroy( &classifier_iterator );
      73            4 :         if ( data_err != U8_ERROR_NONE )
      74              :         {
      75            0 :             write_err |= data_err;
      76              :         }
      77              :     }
      78              : 
      79            4 :     U8_TRACE_END_ERR( write_err );
      80            4 :     return write_err;
      81              : }
      82              : 
      83            0 : u8_error_t io_export_flat_traversal_private_traverse_classifier( io_export_flat_traversal_t *this_,
      84              :                                                                  const data_classifier_t *classifier )
      85              : {
      86            0 :     U8_TRACE_BEGIN();
      87            0 :     assert( NULL != classifier );
      88            0 :     assert( data_classifier_is_valid( classifier ) );
      89            0 :     u8_error_t write_err = U8_ERROR_NONE;
      90              : 
      91              :     /* start classifier */
      92              :     {
      93            0 :         const data_classifier_type_t host_type = DATA_CLASSIFIER_TYPE_VOID;
      94            0 :         write_err |= io_element_writer_start_classifier( (*this_).element_writer, host_type, classifier );
      95            0 :         write_err |= io_element_writer_assemble_classifier( (*this_).element_writer, host_type, classifier );
      96              :     }
      97              : 
      98              :     /* start features and relationships */
      99              :     {
     100            0 :         u8_error_t data_err_3 = U8_ERROR_NONE;
     101              : 
     102              :         /* write the features */
     103              :         data_feature_iterator_t feature_iterator;
     104            0 :         data_err_3 |= data_feature_iterator_init_empty( &feature_iterator );
     105            0 :         data_err_3 |= data_database_reader_get_features_by_classifier_id( (*this_).db_reader,
     106              :                                                                           data_classifier_get_row_id( classifier ),
     107              :                                                                           &feature_iterator
     108              :                                                                         );
     109            0 :         write_err |= io_export_flat_traversal_private_iterate_features( this_, classifier, &feature_iterator );
     110            0 :         data_err_3 |= data_feature_iterator_destroy( &feature_iterator );
     111              : 
     112              :         /* write the relationships */
     113              :         data_relationship_iterator_t rel_iterator;
     114            0 :         data_err_3 |= data_relationship_iterator_init_empty( &rel_iterator );
     115            0 :         data_err_3 |= data_database_reader_get_relationships_by_classifier_id( (*this_).db_reader,
     116              :                                                                                data_classifier_get_row_id( classifier ),
     117              :                                                                                &rel_iterator
     118              :                                                                              );
     119            0 :         write_err |= io_export_flat_traversal_private_iterate_relationships( this_, classifier, &rel_iterator );
     120            0 :         data_err_3 |= data_relationship_iterator_destroy( &rel_iterator );
     121              : 
     122              :         /* if errors at reading the database, add these to the result */
     123            0 :         if ( data_err_3 != U8_ERROR_NONE )
     124              :         {
     125            0 :             write_err |= data_err_3;
     126              :         }
     127              :     }
     128              : 
     129              :     /* end classifier */
     130              :     {
     131            0 :         const data_classifier_type_t host_type = DATA_CLASSIFIER_TYPE_VOID;
     132            0 :         write_err |= io_element_writer_end_classifier( (*this_).element_writer, host_type, classifier );
     133              :     }
     134              : 
     135            0 :     U8_TRACE_END_ERR( write_err );
     136            0 :     return write_err;
     137              : }
     138              : 
     139            0 : u8_error_t io_export_flat_traversal_private_iterate_features( io_export_flat_traversal_t *this_,
     140              :                                                               const data_classifier_t *classifier,
     141              :                                                               data_feature_iterator_t *feature_iterator )
     142              : {
     143            0 :     U8_TRACE_BEGIN();
     144            0 :     assert( classifier != NULL );
     145            0 :     assert( data_classifier_is_valid( classifier ) );
     146            0 :     assert( feature_iterator != NULL );
     147            0 :     u8_error_t write_err = U8_ERROR_NONE;
     148            0 :     u8_error_t data_err = U8_ERROR_NONE;
     149              : 
     150              :     /* iterate over all features */
     151            0 :     while ( data_feature_iterator_has_next( feature_iterator ) )
     152              :     {
     153              :         /* get feature */
     154            0 :         data_err |= data_feature_iterator_next( feature_iterator, &((*this_).temp_from_feature) );
     155            0 :         if ( data_feature_is_valid( &((*this_).temp_from_feature) ) )
     156              :         {
     157            0 :             const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
     158            0 :             write_err |= io_element_writer_start_feature( (*this_).element_writer, classifier_type, &((*this_).temp_from_feature) );
     159            0 :             write_err |= io_element_writer_assemble_feature( (*this_).element_writer, classifier, &((*this_).temp_from_feature) );
     160            0 :             write_err |= io_element_writer_end_feature( (*this_).element_writer, classifier_type, &((*this_).temp_from_feature) );
     161              :         }
     162              :         else
     163              :         {
     164            0 :             assert( false );
     165              :         }
     166              :     }
     167              : 
     168            0 :     write_err |= data_err;  /* result is the combination of writing errors and reading errors */
     169            0 :     U8_TRACE_END_ERR( write_err );
     170            0 :     return write_err;
     171              : }
     172              : 
     173            0 : u8_error_t io_export_flat_traversal_private_iterate_relationships( io_export_flat_traversal_t *this_,
     174              :                                                                    const data_classifier_t *classifier,
     175              :                                                                    data_relationship_iterator_t *relationship_iterator )
     176              : {
     177            0 :     U8_TRACE_BEGIN();
     178            0 :     assert( classifier != NULL );
     179            0 :     assert( relationship_iterator != NULL );
     180            0 :     assert( data_classifier_is_valid( classifier ) );
     181            0 :     assert( relationship_iterator != NULL );
     182            0 :     u8_error_t write_err = U8_ERROR_NONE;
     183            0 :     u8_error_t data_err = U8_ERROR_NONE;
     184              : 
     185            0 :     const data_classifier_type_t host_type = data_classifier_get_main_type( classifier );
     186              : 
     187              :     /* iterate over all relationships */
     188            0 :     while ( data_relationship_iterator_has_next( relationship_iterator ) )
     189              :     {
     190              :         /* get relationship */
     191            0 :         data_err |= data_relationship_iterator_next( relationship_iterator, &((*this_).temp_relationship) );
     192            0 :         const data_relationship_t *const relation = &((*this_).temp_relationship);
     193            0 :         if ( data_relationship_is_valid( relation ) )
     194              :         {
     195              :             /* determine if the relationship is outgoing */
     196            0 :             const bool is_outgoing
     197            0 :                 = ( data_relationship_get_from_classifier_row_id( relation ) == data_classifier_get_row_id( classifier ) );
     198            0 :             if ( is_outgoing )
     199              :             {
     200              :                 /* get the element types at both ends of the relationship */
     201            0 :                 data_classifier_init_empty( &((*this_).temp_from_classifier) );
     202            0 :                 data_feature_init_empty( &((*this_).temp_from_feature) );
     203            0 :                 data_classifier_init_empty( &((*this_).temp_to_classifier) );
     204            0 :                 data_feature_init_empty( &((*this_).temp_to_feature) );
     205              : 
     206              :                 const u8_error_t d_err
     207            0 :                     = io_export_flat_traversal_private_get_relationship_ends( this_,
     208              :                                                                               classifier,
     209              :                                                                               relation,
     210              :                                                                               &((*this_).temp_from_classifier),
     211              :                                                                               &((*this_).temp_from_feature),
     212              :                                                                               &((*this_).temp_to_classifier),
     213              :                                                                               &((*this_).temp_to_feature)
     214              :                                                                             );
     215              : 
     216            0 :                 if ( d_err == U8_ERROR_NONE )
     217              :                 {
     218              :                     /* all classifiers found, print the relation */
     219            0 :                     write_err |= io_element_writer_start_relationship( (*this_).element_writer, host_type, relation );
     220            0 :                     write_err |= io_element_writer_assemble_relationship( (*this_).element_writer,
     221              :                                                                           classifier,
     222              :                                                                           relation,
     223            0 :                                                                           &((*this_).temp_from_classifier),
     224            0 :                                                                           &((*this_).temp_from_feature),
     225            0 :                                                                           &((*this_).temp_to_classifier),
     226            0 :                                                                           &((*this_).temp_to_feature)
     227              :                                                                         );
     228            0 :                     write_err |= io_element_writer_end_relationship( (*this_).element_writer, host_type, relation );
     229              :                 }
     230              :                 else
     231              :                 {
     232            0 :                     write_err |= d_err;
     233              :                 }
     234              : 
     235            0 :                 data_classifier_destroy( &((*this_).temp_from_classifier) );
     236            0 :                 data_feature_destroy( &((*this_).temp_from_feature) );
     237            0 :                 data_classifier_destroy( &((*this_).temp_to_classifier) );
     238            0 :                 data_feature_destroy( &((*this_).temp_to_feature) );
     239              :             }
     240              :         }
     241              :         else
     242              :         {
     243            0 :             assert( false );
     244              :         }
     245              :     }
     246              : 
     247            0 :     write_err |= data_err;  /* result is the combination of writing errors and reading errors */
     248            0 :     U8_TRACE_END_ERR( write_err );
     249            0 :     return write_err;
     250              : }
     251              : 
     252            0 : u8_error_t io_export_flat_traversal_private_get_relationship_ends( io_export_flat_traversal_t *this_,
     253              :                                                                    const data_classifier_t *classifier,
     254              :                                                                    const data_relationship_t *relation,
     255              :                                                                    data_classifier_t *out_from_c,
     256              :                                                                    data_feature_t *out_from_f,
     257              :                                                                    data_classifier_t *out_to_c,
     258              :                                                                    data_feature_t *out_to_f )
     259              : {
     260            0 :     U8_TRACE_BEGIN();
     261            0 :     assert( classifier != NULL );
     262            0 :     assert( relation != NULL );
     263            0 :     assert( out_from_c != NULL );
     264            0 :     assert( out_from_f != NULL );
     265            0 :     assert( out_to_c != NULL );
     266            0 :     assert( out_to_f != NULL );
     267            0 :     u8_error_t data_err = U8_ERROR_NONE;
     268              : 
     269              :     {
     270              :         /* get from classifier */
     271            0 :         const data_row_t from_classifier_row_id = data_relationship_get_from_classifier_row_id( relation );
     272            0 :         if ( from_classifier_row_id == data_classifier_get_row_id ( classifier ) )
     273              :         {
     274            0 :             data_classifier_replace( out_from_c, classifier );
     275              :         }
     276              :         else
     277              :         {
     278            0 :             data_err |= data_database_reader_get_classifier_by_id( (*this_).db_reader,
     279              :                                                                    from_classifier_row_id,
     280              :                                                                    out_from_c
     281              :                                                                  );
     282              :         }
     283              : 
     284              :         /* get from feature */
     285            0 :         const data_row_t from_feature_row_id = data_relationship_get_from_feature_row_id( relation );
     286            0 :         if ( from_feature_row_id != DATA_ROW_VOID )
     287              :         {
     288            0 :             data_err |=  data_database_reader_get_feature_by_id( (*this_).db_reader,
     289              :                                                                  from_feature_row_id,
     290              :                                                                  out_from_f
     291              :                                                                );
     292              :         }
     293              :         else
     294              :         {
     295            0 :             data_feature_init_empty( out_from_f );
     296              :         }
     297              : 
     298              :         /* get to classifier */
     299            0 :         const data_row_t to_classifier_row_id = data_relationship_get_to_classifier_row_id( relation );
     300            0 :         if ( to_classifier_row_id == data_classifier_get_row_id ( classifier ) )
     301              :         {
     302            0 :             data_classifier_replace( out_to_c, classifier );
     303              :         }
     304              :         else
     305              :         {
     306            0 :             data_err |= data_database_reader_get_classifier_by_id( (*this_).db_reader,
     307              :                                                                    to_classifier_row_id,
     308              :                                                                    out_to_c
     309              :                                                                  );
     310              :         }
     311              : 
     312              :         /* get to feature */
     313            0 :         const data_row_t to_feature_row_id = data_relationship_get_to_feature_row_id( relation );
     314            0 :         if ( to_feature_row_id != DATA_ROW_VOID )
     315              :         {
     316            0 :             data_err |= data_database_reader_get_feature_by_id( (*this_).db_reader,
     317              :                                                                 to_feature_row_id,
     318              :                                                                 out_to_f
     319              :                                                               );
     320              :         }
     321              :         else
     322              :         {
     323            0 :             data_feature_init_empty( out_to_f );
     324              :         }
     325              :     }
     326              : 
     327            0 :     if ( data_err != U8_ERROR_NONE )
     328              :     {
     329            0 :         U8_LOG_ERROR_INT( "A relationship references classifier(s) and/or feature(s) that do not exist:",
     330              :                           data_relationship_get_row_id ( relation )
     331              :                         );
     332              :     }
     333            0 :     U8_TRACE_END_ERR( data_err );
     334            0 :     return data_err;
     335              : }
     336              : 
     337              : 
     338              : /*
     339              : Copyright 2021-2025 Andreas Warnke
     340              : 
     341              : Licensed under the Apache License, Version 2.0 (the "License");
     342              : you may not use this file except in compliance with the License.
     343              : You may obtain a copy of the License at
     344              : 
     345              :     http://www.apache.org/licenses/LICENSE-2.0
     346              : 
     347              : Unless required by applicable law or agreed to in writing, software
     348              : distributed under the License is distributed on an "AS IS" BASIS,
     349              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     350              : See the License for the specific language governing permissions and
     351              : limitations under the License.
     352              : */
        

Generated by: LCOV version 2.0-1