LCOV - code coverage report
Current view: top level - ctrl/source - ctrl_consistency_checker.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 91.1 % 361 329
Test Date: 2025-05-01 10:10:14 Functions: 100.0 % 11 11

            Line data    Source code
       1              : /* File: ctrl_consistency_checker.c; Copyright and License: see below */
       2              : 
       3              : #include "ctrl_consistency_checker.h"
       4              : #include "storage/data_database_consistency_checker.h"
       5              : #include "entity/data_id.h"
       6              : #include "u8/u8_trace.h"
       7              : #include "u8/u8_log.h"
       8              : #include <assert.h>
       9              : 
      10           84 : void ctrl_consistency_checker_init ( ctrl_consistency_checker_t *this_,
      11              :                                      data_database_t *database,
      12              :                                      data_database_reader_t *db_reader,
      13              :                                      data_database_writer_t *db_writer )
      14              : {
      15           84 :     U8_TRACE_BEGIN();
      16           84 :     assert( NULL != database );
      17           84 :     assert( NULL != db_reader );
      18           84 :     assert( NULL != db_writer );
      19              : 
      20           84 :     (*this_).database = database;
      21           84 :     (*this_).db_reader = db_reader;
      22           84 :     (*this_).db_writer = db_writer;
      23              : 
      24           84 :     data_database_consistency_checker_init( &((*this_).db_checker), database );
      25              : 
      26           84 :     U8_TRACE_END();
      27           84 : }
      28              : 
      29           84 : void ctrl_consistency_checker_destroy ( ctrl_consistency_checker_t *this_ )
      30              : {
      31           84 :     U8_TRACE_BEGIN();
      32              : 
      33           84 :     data_database_consistency_checker_destroy( &((*this_).db_checker) );
      34              : 
      35           84 :     (*this_).database = NULL;
      36           84 :     (*this_).db_reader = NULL;
      37           84 :     (*this_).db_writer = NULL;
      38              : 
      39           84 :     U8_TRACE_END();
      40           84 : }
      41              : 
      42           30 : u8_error_t ctrl_consistency_checker_repair_database ( ctrl_consistency_checker_t *this_,
      43              :                                                       bool modify_db,
      44              :                                                       uint32_t *out_err,
      45              :                                                       uint32_t *out_fix,
      46              :                                                       utf8stream_writer_t *out_english_report )
      47              : {
      48           30 :     U8_TRACE_BEGIN();
      49           30 :     assert ( NULL != out_english_report );
      50           30 :     u8_error_t err_result = U8_ERROR_NONE;
      51           30 :     uint32_t error_count = 0;
      52           30 :     uint32_t fix_count = 0;
      53              : 
      54              :     /* write report title */
      55           30 :     if ( modify_db )
      56              :     {
      57           10 :         utf8stream_writer_write_str( out_english_report, "TITLE: Repair database\n" );
      58              :     }
      59              :     else
      60              :     {
      61           20 :         utf8stream_writer_write_str( out_english_report, "TITLE: Check database\n" );
      62              :     }
      63              : 
      64              :     /* == find inconsistencies in drawings == */
      65              : 
      66              :     /* get all root diagrams */
      67           30 :     err_result |= ctrl_consistency_checker_private_ensure_single_root_diagram( this_, modify_db, &error_count, &fix_count, out_english_report );
      68              : 
      69              :     /* find invalid and circular diagram parent links */
      70           30 :     err_result |= ctrl_consistency_checker_private_ensure_valid_diagram_parents( this_, modify_db, &error_count, &fix_count, out_english_report );
      71              : 
      72              :     /* find nonreferencing diagramelements */
      73           30 :     err_result |= ctrl_consistency_checker_private_ensure_valid_diagramelements( this_, modify_db, &error_count, &fix_count, out_english_report );
      74              : 
      75              :     /* find illreferencing diagramelements */
      76           30 :     err_result |= ctrl_consistency_checker_private_ensure_valid_diagele_features( this_, modify_db, &error_count, &fix_count, out_english_report );
      77              : 
      78              :     /* find unreferenced, invisible classifiers */
      79           30 :     err_result |= ctrl_consistency_checker_private_ensure_referenced_classifiers( this_, modify_db, &error_count, &fix_count, out_english_report );
      80              : 
      81              :     /* == find inconsistencies in meta model == */
      82              : 
      83              :     /* find nonreferencing features */
      84           30 :     err_result |= ctrl_consistency_checker_private_ensure_valid_feature_parents( this_, modify_db, &error_count, &fix_count, out_english_report );
      85              : 
      86              :     /* find nonreferencing relationships */
      87           30 :     err_result |= ctrl_consistency_checker_private_ensure_valid_relationship_classifiers( this_, modify_db, &error_count, &fix_count, out_english_report );
      88              : 
      89              :     /* find illreferencing relationships */
      90           30 :     err_result |= ctrl_consistency_checker_private_ensure_valid_relationship_features( this_, modify_db, &error_count, &fix_count, out_english_report );
      91              : 
      92              :     /* prepare results and return */
      93           30 :     if ( NULL != out_err )
      94              :     {
      95           30 :         (*out_err) = error_count;
      96              :     }
      97           30 :     if ( NULL != out_fix )
      98              :     {
      99           30 :         (*out_fix) = fix_count;
     100              :     }
     101              : 
     102              :     /* write report summary */
     103           30 :     const char *db_filename = data_database_get_filename_ptr ( (*this_).database );
     104           30 :     utf8stream_writer_write_str( out_english_report, "SUMMARY: " );
     105           30 :     if ( db_filename != NULL )
     106              :     {
     107           30 :         utf8stream_writer_write_str( out_english_report, "\n    File: " );
     108           30 :         utf8stream_writer_write_str( out_english_report, db_filename );
     109              :     }
     110           30 :     utf8stream_writer_write_str( out_english_report, "\n    Errors found: " );
     111           30 :     utf8stream_writer_write_int( out_english_report, error_count );
     112           30 :     utf8stream_writer_write_str( out_english_report, "\n    Errors fixed: " );
     113           30 :     utf8stream_writer_write_int( out_english_report, fix_count );
     114           30 :     utf8stream_writer_write_str( out_english_report, "\n" );
     115              : 
     116              :     /* if not all errors fixed, set result to U8_ERROR_DB_STRUCTURE */
     117           30 :     if ( error_count > fix_count )
     118              :     {
     119           10 :         err_result |= U8_ERROR_DB_STRUCTURE;
     120              :     }
     121              : 
     122           30 :     U8_TRACE_END_ERR( err_result );
     123           30 :     return err_result;
     124              : }
     125              : 
     126           30 : u8_error_t ctrl_consistency_checker_private_ensure_single_root_diagram ( ctrl_consistency_checker_t *this_,
     127              :                                                                          bool modify_db,
     128              :                                                                          uint32_t *io_err,
     129              :                                                                          uint32_t *io_fix,
     130              :                                                                          utf8stream_writer_t *out_english_report )
     131              : {
     132           30 :     U8_TRACE_BEGIN();
     133           30 :     assert ( NULL != io_err );
     134           30 :     assert ( NULL != io_fix );
     135           30 :     assert ( NULL != out_english_report );
     136           30 :     u8_error_t result = U8_ERROR_NONE;
     137              : 
     138              :     /* write report title */
     139           30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure a single root diagram\n" );
     140              : 
     141              :     /* get all root diagrams */
     142              :     data_small_set_t all_roots;
     143           30 :     data_small_set_init( &all_roots );
     144              :     data_diagram_iterator_t diagram_iterator;
     145           30 :     result |= data_diagram_iterator_init_empty( &diagram_iterator );
     146              : 
     147           30 :     result |= data_database_reader_get_diagrams_by_parent_id( (*this_).db_reader,
     148              :                                                               DATA_ROW_VOID,
     149              :                                                               &diagram_iterator
     150              :                                                             );
     151              : 
     152           30 :     if ( U8_ERROR_NONE != result )
     153              :     {
     154            0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     155              :     }
     156              : 
     157           62 :     while ( data_diagram_iterator_has_next( &diagram_iterator ) )
     158              :     {
     159           32 :         result |= data_diagram_iterator_next( &diagram_iterator, &((*this_).temp_diagram) );
     160           32 :         result |= data_small_set_add_obj( &all_roots, data_diagram_get_data_id( &((*this_).temp_diagram) ) );
     161              : 
     162           32 :         utf8stream_writer_write_str( out_english_report, "    INFO: Root diagram: " );
     163           32 :         utf8stream_writer_write_int( out_english_report, data_diagram_get_row_id( &((*this_).temp_diagram) ) );
     164           32 :         utf8stream_writer_write_str( out_english_report, ": " );
     165           32 :         utf8stream_writer_write_str( out_english_report, data_diagram_get_name_const( &((*this_).temp_diagram) ) );
     166           32 :         utf8stream_writer_write_str( out_english_report, "\n" );
     167              :     }
     168           30 :     const uint_fast32_t root_diagram_count = data_small_set_get_count( &all_roots );
     169           30 :     utf8stream_writer_write_str( out_english_report, "    ROOT DIAGRAM COUNT: " );
     170           30 :     utf8stream_writer_write_int( out_english_report, root_diagram_count );
     171           30 :     utf8stream_writer_write_str( out_english_report, "\n" );
     172           30 :     result |= data_diagram_iterator_destroy( &diagram_iterator );
     173              : 
     174           30 :     if ( root_diagram_count == 0 )
     175              :     {
     176            0 :         (*io_err) ++;
     177            0 :         utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Create a diagram via the GUI.\n" );
     178              :     }
     179           30 :     else if ( root_diagram_count > 1 )
     180              :     {
     181            2 :         (*io_err) += (root_diagram_count-1) ;
     182            2 :         const data_id_t proposed_root_diagram = data_small_set_get_id( &all_roots, 0 );
     183            2 :         const data_row_t proposed_root_diagram_id = data_id_get_row_id( &proposed_root_diagram );
     184            2 :         if ( ! modify_db )
     185              :         {
     186            1 :             utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Attach additional root diagrams below the first: " );
     187            1 :             utf8stream_writer_write_int( out_english_report, proposed_root_diagram_id );
     188            1 :             utf8stream_writer_write_str( out_english_report, "\n" );
     189              :         }
     190              :         else
     191              :         {
     192            2 :             for ( int list_pos = 1; list_pos < root_diagram_count; list_pos ++ )
     193              :             {
     194            1 :                 const data_id_t proposed_child_diagram = data_small_set_get_id( &all_roots, list_pos );
     195            1 :                 const data_row_t proposed_child_diagram_id = data_id_get_row_id( &proposed_child_diagram );
     196              :                 const u8_error_t data_err
     197            1 :                     = data_database_writer_update_diagram_parent_id( (*this_).db_writer,
     198              :                                                                      proposed_child_diagram_id,
     199              :                                                                      proposed_root_diagram_id,
     200              :                                                                      NULL
     201              :                                                                    );
     202            1 :                 if ( U8_ERROR_NONE == data_err )
     203              :                 {
     204            1 :                     utf8stream_writer_write_str( out_english_report, "    FIX: Diagram " );
     205            1 :                     utf8stream_writer_write_int( out_english_report, proposed_child_diagram_id );
     206            1 :                     utf8stream_writer_write_str( out_english_report, " attached to " );
     207            1 :                     utf8stream_writer_write_int( out_english_report, proposed_root_diagram_id);
     208            1 :                     utf8stream_writer_write_str( out_english_report, "\n" );
     209            1 :                     (*io_fix) ++;
     210              :                 }
     211              :                 else
     212              :                 {
     213            0 :                     utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     214            0 :                     result |= data_err;
     215              :                 }
     216              :             }
     217              :         }
     218              :     }
     219           30 :     data_small_set_destroy( &all_roots );
     220              : 
     221           30 :     U8_TRACE_END_ERR( result );
     222           30 :     return result;
     223              : }
     224              : 
     225           30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_diagram_parents ( ctrl_consistency_checker_t *this_,
     226              :                                                                            bool modify_db,
     227              :                                                                            uint32_t *io_err,
     228              :                                                                            uint32_t *io_fix,
     229              :                                                                            utf8stream_writer_t *out_english_report )
     230              : {
     231           30 :     U8_TRACE_BEGIN();
     232           30 :     assert ( NULL != io_err );
     233           30 :     assert ( NULL != out_english_report );
     234           30 :     u8_error_t err_result = U8_ERROR_NONE;
     235              :     u8_error_t data_err;
     236              : 
     237              :     /* write report title */
     238           30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that no circular/invalid references of diagram parents exist\n" );
     239              : 
     240              :     data_small_set_t circ_ref;
     241           30 :     data_small_set_init( &circ_ref );
     242           30 :     data_err = data_database_consistency_checker_find_circular_diagram_parents ( &((*this_).db_checker), &circ_ref );
     243           30 :     if ( U8_ERROR_NONE == data_err )
     244              :     {
     245           30 :         uint32_t circ_ref_count = data_small_set_get_count( &circ_ref );
     246              : 
     247           30 :         utf8stream_writer_write_str( out_english_report, "    DIAGRAMS WITH CIRCLUAR OR INVALID PARENT REFERENCES: " );
     248           30 :         utf8stream_writer_write_int( out_english_report, circ_ref_count );
     249           30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     250              : 
     251           30 :         if ( circ_ref_count != 0 )
     252              :         {
     253            4 :             (*io_err) += circ_ref_count;
     254              : 
     255              :             /* get the root diagram */
     256            4 :             data_row_t root_diag_id = DATA_ROW_VOID;
     257              :             {
     258              :                 data_diagram_iterator_t diagram_iterator;
     259            4 :                 err_result |= data_diagram_iterator_init_empty( &diagram_iterator );
     260            4 :                 err_result |= data_database_reader_get_diagrams_by_parent_id( (*this_).db_reader,
     261              :                                                                               DATA_ROW_VOID,
     262              :                                                                               &diagram_iterator
     263              :                                                                             );
     264            4 :                 if (( U8_ERROR_NONE == err_result )&& data_diagram_iterator_has_next( &diagram_iterator ) )
     265              :                 {
     266            4 :                     err_result |= data_diagram_iterator_next( &diagram_iterator, &((*this_).temp_diagram) );
     267            4 :                     root_diag_id = data_diagram_get_row_id( &((*this_).temp_diagram) );
     268              :                 }
     269            4 :                 err_result |= data_diagram_iterator_destroy( &diagram_iterator );
     270              :             }
     271              : 
     272            4 :             if ( ! modify_db )
     273              :             {
     274            2 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Move " );
     275            2 :                 utf8stream_writer_write_int( out_english_report, circ_ref_count );
     276            2 :                 utf8stream_writer_write_str( out_english_report, " diagrams below root diagram " );
     277            2 :                 utf8stream_writer_write_int( out_english_report, root_diag_id );
     278            2 :                 utf8stream_writer_write_str( out_english_report, ".\n" );
     279              :             }
     280              :             else
     281              :             {
     282            6 :                 for ( int list_pos = 0; list_pos < circ_ref_count; list_pos ++ )
     283              :                 {
     284            4 :                     data_id_t diagram_id = data_small_set_get_id( &circ_ref, list_pos );
     285            4 :                     data_row_t diagram_row_id = data_id_get_row_id( &diagram_id );
     286              : 
     287            4 :                     data_err = data_database_writer_update_diagram_parent_id ( (*this_).db_writer,
     288              :                                                                                diagram_row_id,
     289              :                                                                                root_diag_id,
     290              :                                                                                NULL /*out_old_diagram*/
     291              :                                                                              );
     292            4 :                     if ( U8_ERROR_NONE == data_err )
     293              :                     {
     294            4 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Diagram " );
     295            4 :                         utf8stream_writer_write_int( out_english_report, diagram_row_id );
     296            4 :                         utf8stream_writer_write_str( out_english_report, " moved below root diagram " );
     297            4 :                         utf8stream_writer_write_int( out_english_report, root_diag_id );
     298            4 :                         utf8stream_writer_write_str( out_english_report, ".\n" );
     299            4 :                         (*io_fix) ++;
     300              :                     }
     301              :                     else
     302              :                     {
     303            0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     304            0 :                         err_result |= data_err;
     305              :                     }
     306              :                 }
     307              :             }
     308              :         }
     309              :     }
     310              :     else
     311              :     {
     312            0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     313            0 :         err_result |= data_err;
     314              :     }
     315           30 :     data_small_set_destroy( &circ_ref );
     316              : 
     317           30 :     U8_TRACE_END_ERR( err_result );
     318           30 :     return err_result;
     319              : }
     320              : 
     321           30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_diagramelements ( ctrl_consistency_checker_t *this_,
     322              :                                                                            bool modify_db,
     323              :                                                                            uint32_t *io_err,
     324              :                                                                            uint32_t *io_fix,
     325              :                                                                            utf8stream_writer_t *out_english_report )
     326              : {
     327           30 :     U8_TRACE_BEGIN();
     328           30 :     assert ( NULL != io_err );
     329           30 :     assert ( NULL != io_fix );
     330           30 :     assert ( NULL != out_english_report );
     331           30 :     u8_error_t err_result = U8_ERROR_NONE;
     332              :     u8_error_t data_err;
     333              : 
     334              :     /* write report title */
     335           30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that diagramelements reference valid diagrams and classifiers\n" );
     336              : 
     337              :     data_small_set_t unref;
     338           30 :     data_small_set_init( &unref );
     339           30 :     data_err = data_database_consistency_checker_find_nonreferencing_diagramelements ( &((*this_).db_checker), &unref );
     340           30 :     if ( U8_ERROR_NONE == data_err )
     341              :     {
     342           30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     343              : 
     344           30 :         utf8stream_writer_write_str( out_english_report, "    NONREFERENCING DIAGRAMELEMENTS COUNT: " );
     345           30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     346           30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     347              : 
     348           30 :         if ( unref_count != 0 )
     349              :         {
     350            2 :             (*io_err) += unref_count;
     351              : 
     352            2 :             if ( ! modify_db )
     353              :             {
     354            1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     355            1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     356            1 :                 utf8stream_writer_write_str( out_english_report, " diagramelements.\n" );
     357              :             }
     358              :             else
     359              :             {
     360            4 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     361              :                 {
     362            3 :                     data_id_t diagramelement_id = data_small_set_get_id( &unref, list_pos );
     363            3 :                     data_row_t diagramelement_row_id = data_id_get_row_id( &diagramelement_id );
     364            3 :                     data_err = data_database_writer_delete_diagramelement ( (*this_).db_writer, diagramelement_row_id, NULL );
     365            3 :                     if ( U8_ERROR_NONE == data_err )
     366              :                     {
     367            3 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Diagramelement " );
     368            3 :                         utf8stream_writer_write_int( out_english_report, diagramelement_row_id );
     369            3 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     370            3 :                         (*io_fix) ++;
     371              :                     }
     372              :                     else
     373              :                     {
     374            0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     375            0 :                         err_result |= data_err;
     376              :                     }
     377              :                 }
     378              :             }
     379              :         }
     380              :     }
     381              :     else
     382              :     {
     383            0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     384            0 :         err_result |= data_err;
     385              :     }
     386              : 
     387           30 :     U8_TRACE_END_ERR( err_result );
     388           30 :     return err_result;
     389              : }
     390              : 
     391           30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_diagele_features ( ctrl_consistency_checker_t *this_,
     392              :                                                                             bool modify_db,
     393              :                                                                             uint32_t *io_err,
     394              :                                                                             uint32_t *io_fix,
     395              :                                                                             utf8stream_writer_t *out_english_report )
     396              : {
     397           30 :     U8_TRACE_BEGIN();
     398           30 :     assert ( NULL != io_err );
     399           30 :     assert ( NULL != io_fix );
     400           30 :     assert ( NULL != out_english_report );
     401           30 :     u8_error_t err_result = U8_ERROR_NONE;
     402              :     u8_error_t data_err;
     403              : 
     404              :     /* write report title */
     405           30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that diagramelements reference NULL or valid features\n" );
     406              : 
     407              :     data_small_set_t unref;
     408           30 :     data_small_set_init( &unref );
     409           30 :     data_err = data_database_consistency_checker_find_invalid_focused_features ( &((*this_).db_checker), &unref );
     410           30 :     if ( U8_ERROR_NONE == data_err )
     411              :     {
     412           30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     413              : 
     414           30 :         utf8stream_writer_write_str( out_english_report, "    ILLREFERENCING DIAGRAMELEMENTS COUNT: " );
     415           30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     416           30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     417              : 
     418           30 :         if ( unref_count != 0 )
     419              :         {
     420            2 :             (*io_err) += unref_count;
     421              : 
     422            2 :             if ( ! modify_db )
     423              :             {
     424            1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Unlink focused features from " );
     425            1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     426            1 :                 utf8stream_writer_write_str( out_english_report, " diagramelements.\n" );
     427              :             }
     428              :             else
     429              :             {
     430            3 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     431              :                 {
     432            2 :                     data_id_t diagramelement_id = data_small_set_get_id( &unref, list_pos );
     433            2 :                     data_row_t diagramelement_row_id = data_id_get_row_id( &diagramelement_id );
     434            2 :                     data_err = data_database_writer_update_diagramelement_focused_feature_id ( (*this_).db_writer, diagramelement_row_id, DATA_ROW_VOID, NULL );
     435            2 :                     if ( U8_ERROR_NONE == data_err )
     436              :                     {
     437            2 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Focused features unlinked from " );
     438            2 :                         utf8stream_writer_write_int( out_english_report, diagramelement_row_id );
     439            2 :                         utf8stream_writer_write_str( out_english_report, " diagramelements.\n" );
     440            2 :                         (*io_fix) ++;
     441              :                     }
     442              :                     else
     443              :                     {
     444            0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     445            0 :                         err_result |= data_err;
     446              :                     }
     447              :                 }
     448              :             }
     449              :         }
     450              :     }
     451              :     else
     452              :     {
     453            0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     454            0 :         err_result |= data_err;
     455              :     }
     456              : 
     457           30 :     U8_TRACE_END_ERR( err_result );
     458           30 :     return err_result;
     459              : }
     460              : 
     461           30 : u8_error_t ctrl_consistency_checker_private_ensure_referenced_classifiers ( ctrl_consistency_checker_t *this_,
     462              :                                                                             bool modify_db,
     463              :                                                                             uint32_t *io_err,
     464              :                                                                             uint32_t *io_fix,
     465              :                                                                             utf8stream_writer_t *out_english_report )
     466              : {
     467           30 :     U8_TRACE_BEGIN();
     468           30 :     assert ( NULL != io_err );
     469           30 :     assert ( NULL != io_fix );
     470           30 :     assert ( NULL != out_english_report );
     471           30 :     u8_error_t err_result = U8_ERROR_NONE;
     472              :     u8_error_t data_err;
     473              : 
     474              :     /* write report title */
     475           30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that classifiers are referenced\n" );
     476              : 
     477              :     data_small_set_t unref;
     478           30 :     data_small_set_init( &unref );
     479           30 :     data_err = data_database_consistency_checker_find_unreferenced_classifiers ( &((*this_).db_checker), &unref );
     480           30 :     if ( U8_ERROR_NONE == data_err )
     481              :     {
     482           30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     483              : 
     484           30 :         utf8stream_writer_write_str( out_english_report, "    UNREFERENCED CLASSIFIER COUNT: " );
     485           30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     486           30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     487              : 
     488           30 :         if ( unref_count != 0 )
     489              :         {
     490            4 :             (*io_err) += unref_count;
     491              : 
     492            4 :             if ( ! modify_db )
     493              :             {
     494            2 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     495            2 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     496            2 :                 utf8stream_writer_write_str( out_english_report, " classifiers.\n" );
     497              :             }
     498              :             else
     499              :             {
     500            4 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     501              :                 {
     502            2 :                     data_id_t classifier_id = data_small_set_get_id( &unref, list_pos );
     503            2 :                     data_row_t classifier_row_id = data_id_get_row_id( &classifier_id );
     504            2 :                     err_result |= data_database_consistency_checker_kill_classifier ( &((*this_).db_checker), classifier_row_id );
     505            2 :                     if ( U8_ERROR_NONE == err_result )
     506              :                     {
     507            2 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Classifier " );
     508            2 :                         utf8stream_writer_write_int( out_english_report, classifier_row_id );
     509            2 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     510            2 :                         (*io_fix) ++;
     511              :                     }
     512              :                     else
     513              :                     {
     514            0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     515              :                     }
     516              :                 }
     517              :             }
     518              :         }
     519              :     }
     520              :     else
     521              :     {
     522            0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     523            0 :         err_result |= data_err;
     524              :     }
     525              : 
     526           30 :     U8_TRACE_END_ERR( err_result );
     527           30 :     return err_result;
     528              : }
     529              : 
     530           30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_feature_parents ( ctrl_consistency_checker_t *this_,
     531              :                                                                            bool modify_db,
     532              :                                                                            uint32_t *io_err,
     533              :                                                                            uint32_t *io_fix,
     534              :                                                                            utf8stream_writer_t *out_english_report )
     535              : {
     536           30 :     U8_TRACE_BEGIN();
     537           30 :     assert ( NULL != io_err );
     538           30 :     assert ( NULL != io_fix );
     539           30 :     assert ( NULL != out_english_report );
     540           30 :     u8_error_t err_result = U8_ERROR_NONE;
     541              :     u8_error_t data_err;
     542              : 
     543              :     /* write report title */
     544           30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that features have valid classifiers\n" );
     545              : 
     546              :     data_small_set_t unref;
     547           30 :     data_small_set_init( &unref );
     548           30 :     data_err = data_database_consistency_checker_find_unreferenced_features ( &((*this_).db_checker), &unref );
     549           30 :     if ( U8_ERROR_NONE == data_err )
     550              :     {
     551           30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     552              : 
     553           30 :         utf8stream_writer_write_str( out_english_report, "    NONREFERENCING FEATURES COUNT: " );
     554           30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     555           30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     556              : 
     557           30 :         if ( unref_count != 0 )
     558              :         {
     559            3 :             (*io_err) += unref_count;
     560              : 
     561            3 :             if ( ! modify_db )
     562              :             {
     563            1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     564            1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     565            1 :                 utf8stream_writer_write_str( out_english_report, " features.\n" );
     566              :             }
     567              :             else
     568              :             {
     569            4 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     570              :                 {
     571            2 :                     data_id_t feature_id = data_small_set_get_id( &unref, list_pos );
     572            2 :                     data_row_t feature_row_id = data_id_get_row_id( &feature_id );
     573            2 :                     data_err = data_database_writer_delete_feature ( (*this_).db_writer, feature_row_id, NULL );
     574            2 :                     if ( U8_ERROR_NONE == data_err )
     575              :                     {
     576            2 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Feature " );
     577            2 :                         utf8stream_writer_write_int( out_english_report, feature_row_id );
     578            2 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     579            2 :                         (*io_fix) ++;
     580              :                     }
     581              :                     else
     582              :                     {
     583            0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     584            0 :                         err_result |= data_err;
     585              :                     }
     586              :                 }
     587              :             }
     588              :         }
     589              :     }
     590              :     else
     591              :     {
     592            0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     593            0 :         err_result |= data_err;
     594              :     }
     595              : 
     596           30 :     U8_TRACE_END_ERR( err_result );
     597           30 :     return err_result;
     598              : }
     599              : 
     600           30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_relationship_classifiers ( ctrl_consistency_checker_t *this_,
     601              :                                                                                     bool modify_db,
     602              :                                                                                     uint32_t *io_err,
     603              :                                                                                     uint32_t *io_fix,
     604              :                                                                                     utf8stream_writer_t *out_english_report )
     605              : {
     606           30 :     U8_TRACE_BEGIN();
     607           30 :     assert ( NULL != io_err );
     608           30 :     assert ( NULL != io_fix );
     609           30 :     assert ( NULL != out_english_report );
     610           30 :     u8_error_t err_result = U8_ERROR_NONE;
     611              :     u8_error_t data_err;
     612              : 
     613              :     /* write report title */
     614           30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that relationships link valid classifiers\n" );
     615              : 
     616              :     data_small_set_t unref;
     617           30 :     data_small_set_init( &unref );
     618           30 :     data_err = data_database_consistency_checker_find_unreferenced_relationships ( &((*this_).db_checker), &unref );
     619           30 :     if ( U8_ERROR_NONE == data_err )
     620              :     {
     621           30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     622              : 
     623           30 :         utf8stream_writer_write_str( out_english_report, "    NONREFERENCING RELATIONSHIPS COUNT: " );
     624           30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     625           30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     626              : 
     627           30 :         if ( unref_count != 0 )
     628              :         {
     629            3 :             (*io_err) += unref_count;
     630              : 
     631            3 :             if ( ! modify_db )
     632              :             {
     633            1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     634            1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     635            1 :                 utf8stream_writer_write_str( out_english_report, " relationships.\n" );
     636              :             }
     637              :             else
     638              :             {
     639            6 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     640              :                 {
     641            4 :                     data_id_t relationship_id = data_small_set_get_id( &unref, list_pos );
     642            4 :                     data_row_t relation_row_id = data_id_get_row_id( &relationship_id );
     643            4 :                     data_err = data_database_writer_delete_relationship ( (*this_).db_writer, relation_row_id, NULL );
     644            4 :                     if ( U8_ERROR_NONE == data_err )
     645              :                     {
     646            4 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Relationship " );
     647            4 :                         utf8stream_writer_write_int( out_english_report, relation_row_id );
     648            4 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     649            4 :                         (*io_fix) ++;
     650              :                     }
     651              :                     else
     652              :                     {
     653            0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     654            0 :                         err_result |= data_err;
     655              :                     }
     656              :                 }
     657              :             }
     658              :         }
     659              :     }
     660              :     else
     661              :     {
     662            0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     663            0 :         err_result |= data_err;
     664              :     }
     665              : 
     666           30 :     U8_TRACE_END_ERR( err_result );
     667           30 :     return err_result;
     668              : }
     669              : 
     670           30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_relationship_features ( ctrl_consistency_checker_t *this_,
     671              :                                                                                  bool modify_db,
     672              :                                                                                  uint32_t *io_err,
     673              :                                                                                  uint32_t *io_fix,
     674              :                                                                                  utf8stream_writer_t *out_english_report )
     675              : {
     676           30 :     U8_TRACE_BEGIN();
     677           30 :     assert ( NULL != io_err );
     678           30 :     assert ( NULL != io_fix );
     679           30 :     assert ( NULL != out_english_report );
     680           30 :     u8_error_t err_result = U8_ERROR_NONE;
     681              :     u8_error_t data_err;
     682              : 
     683              :     /* write report title */
     684           30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that relationships link NULL or valid features\n" );
     685              : 
     686              :     data_small_set_t unref;
     687           30 :     data_small_set_init( &unref );
     688           30 :     data_err = data_database_consistency_checker_find_invalid_relationship_features ( &((*this_).db_checker), &unref );
     689           30 :     if ( U8_ERROR_NONE == data_err )
     690              :     {
     691           30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     692              : 
     693           30 :         utf8stream_writer_write_str( out_english_report, "    ILLREFERENCING RELATIONSHIPS COUNT: " );
     694           30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     695           30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     696              : 
     697           30 :         if ( unref_count != 0 )
     698              :         {
     699            2 :             (*io_err) += unref_count;
     700              : 
     701            2 :             if ( ! modify_db )
     702              :             {
     703            1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     704            1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     705            1 :                 utf8stream_writer_write_str( out_english_report, " relationships.\n" );
     706              :             }
     707              :             else
     708              :             {
     709            4 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     710              :                 {
     711            3 :                     data_id_t relationship_id = data_small_set_get_id( &unref, list_pos );
     712            3 :                     data_row_t relation_row_id = data_id_get_row_id( &relationship_id );
     713            3 :                     data_err = data_database_writer_delete_relationship ( (*this_).db_writer, relation_row_id, NULL );
     714            3 :                     if ( U8_ERROR_NONE == data_err )
     715              :                     {
     716            3 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Relationship " );
     717            3 :                         utf8stream_writer_write_int( out_english_report, relation_row_id );
     718            3 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     719            3 :                         (*io_fix) ++;
     720              :                     }
     721              :                     else
     722              :                     {
     723            0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     724            0 :                         err_result |= data_err;
     725              :                     }
     726              :                 }
     727              :             }
     728              :         }
     729              :     }
     730              :     else
     731              :     {
     732            0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     733            0 :         err_result |= data_err;
     734              :     }
     735              : 
     736           30 :     U8_TRACE_END_ERR( err_result );
     737           30 :     return err_result;
     738              : }
     739              : 
     740              : 
     741              : /*
     742              : Copyright 2016-2025 Andreas Warnke
     743              : 
     744              : Licensed under the Apache License, Version 2.0 (the "License");
     745              : you may not use this file except in compliance with the License.
     746              : You may obtain a copy of the License at
     747              : 
     748              :     http://www.apache.org/licenses/LICENSE-2.0
     749              : 
     750              : Unless required by applicable law or agreed to in writing, software
     751              : distributed under the License is distributed on an "AS IS" BASIS,
     752              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     753              : See the License for the specific language governing permissions and
     754              : limitations under the License.
     755              : */
        

Generated by: LCOV version 2.0-1