LCOV - code coverage report
Current view: top level - io/source - io_export_flat_traversal.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.62.0_covts Lines: 28 143 19.6 %
Date: 2024-12-21 18:34:41 Functions: 3 7 42.9 %

          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-2024 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 1.16