LCOV - code coverage report
Current view: top level - ctrl/source - ctrl_consistency_checker.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.56.1_covts Lines: 335 368 91.0 %
Date: 2024-03-23 04:33:35 Functions: 11 11 100.0 %

          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 "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 err_result = U8_ERROR_NONE;
     137          30 :     u8_error_t data_err;
     138             : 
     139             :     /* write report title */
     140          30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure a single root diagram\n" );
     141             : 
     142             :     /* get all root diagrams */
     143          30 :     uint32_t out_diagram_count;
     144          60 :     data_err = data_database_reader_get_diagrams_by_parent_id ( (*this_).db_reader,
     145             :                                                                 DATA_ROW_ID_VOID,
     146             :                                                                 CTRL_CONSISTENCY_CHECKER_MAX_DIAG_BUFFER,
     147          30 :                                                                 &((*this_).temp_diagram_buffer),
     148             :                                                                 &out_diagram_count
     149             :                                                               );
     150             : 
     151          30 :     if ( U8_ERROR_NONE == data_err )
     152             :     {
     153          30 :         utf8stream_writer_write_str( out_english_report, "    ROOT DIAGRAM COUNT: " );
     154          30 :         utf8stream_writer_write_int( out_english_report, out_diagram_count );
     155          30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     156          62 :         for ( int list_pos = 0; list_pos < out_diagram_count; list_pos ++ )
     157             :         {
     158          32 :             utf8stream_writer_write_str( out_english_report, "    INFO: Root diagram: " );
     159          32 :             utf8stream_writer_write_int( out_english_report, data_diagram_get_row_id( &((*this_).temp_diagram_buffer[list_pos]) ) );
     160          32 :             utf8stream_writer_write_str( out_english_report, ": " );
     161          32 :             utf8stream_writer_write_str( out_english_report, data_diagram_get_name_const( &((*this_).temp_diagram_buffer[list_pos]) ) );
     162          32 :             utf8stream_writer_write_str( out_english_report, "\n" );
     163             :         }
     164          30 :         if ( out_diagram_count == 0 )
     165             :         {
     166           0 :             (*io_err) ++;
     167           0 :             utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Create a diagram via the GUI.\n" );
     168             :         }
     169          30 :         else if ( out_diagram_count > 1 )
     170             :         {
     171           2 :             (*io_err) += (out_diagram_count-1) ;
     172           2 :             data_row_id_t proposed_root_diagram_id = data_diagram_get_row_id( &((*this_).temp_diagram_buffer[0]) );
     173           2 :             if ( ! modify_db )
     174             :             {
     175           1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Attach additional root diagrams below the first: " );
     176           1 :                 utf8stream_writer_write_int( out_english_report, proposed_root_diagram_id );
     177           1 :                 utf8stream_writer_write_str( out_english_report, "\n" );
     178             :             }
     179             :             else
     180             :             {
     181           2 :                 for ( int list_pos = 1; list_pos < out_diagram_count; list_pos ++ )
     182             :                 {
     183           2 :                     data_err = data_database_writer_update_diagram_parent_id ( (*this_).db_writer,
     184           1 :                                                                                data_diagram_get_row_id( &((*this_).temp_diagram_buffer[list_pos]) ),
     185             :                                                                                proposed_root_diagram_id,
     186             :                                                                                NULL
     187             :                                                                              );
     188           1 :                     if ( U8_ERROR_NONE == data_err )
     189             :                     {
     190           1 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Diagram " );
     191           1 :                         utf8stream_writer_write_int( out_english_report, data_diagram_get_row_id( &((*this_).temp_diagram_buffer[list_pos]) ) );
     192           1 :                         utf8stream_writer_write_str( out_english_report, " attached to " );
     193           1 :                         utf8stream_writer_write_int( out_english_report, proposed_root_diagram_id);
     194           1 :                         utf8stream_writer_write_str( out_english_report, "\n" );
     195           1 :                         (*io_fix) ++;
     196             :                     }
     197             :                     else
     198             :                     {
     199           0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     200           0 :                         err_result |= data_err;
     201             :                     }
     202             :                 }
     203             :             }
     204             :         }
     205             :     }
     206             :     else
     207             :     {
     208           0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     209           0 :         err_result |= data_err;
     210             :     }
     211             : 
     212          30 :     U8_TRACE_END_ERR( err_result );
     213          30 :     return err_result;
     214             : }
     215             : 
     216          30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_diagram_parents ( ctrl_consistency_checker_t *this_,
     217             :                                                                            bool modify_db,
     218             :                                                                            uint32_t *io_err,
     219             :                                                                            uint32_t *io_fix,
     220             :                                                                            utf8stream_writer_t *out_english_report )
     221             : {
     222          30 :     U8_TRACE_BEGIN();
     223          30 :     assert ( NULL != io_err );
     224          30 :     assert ( NULL != out_english_report );
     225          30 :     u8_error_t err_result = U8_ERROR_NONE;
     226          30 :     u8_error_t data_err;
     227             : 
     228             :     /* write report title */
     229          30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that no circular/invalid references of diagram parents exist\n" );
     230             : 
     231          30 :     data_small_set_t circ_ref;
     232          30 :     data_small_set_init( &circ_ref );
     233          30 :     data_err = data_database_consistency_checker_find_circular_diagram_parents ( &((*this_).db_checker), &circ_ref );
     234          30 :     if ( U8_ERROR_NONE == data_err )
     235             :     {
     236          30 :         uint32_t circ_ref_count = data_small_set_get_count( &circ_ref );
     237             : 
     238          30 :         utf8stream_writer_write_str( out_english_report, "    DIAGRAMS WITH CIRCLUAR OR INVALID PARENT REFERENCES: " );
     239          30 :         utf8stream_writer_write_int( out_english_report, circ_ref_count );
     240          30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     241             : 
     242          30 :         if ( circ_ref_count != 0 )
     243             :         {
     244           4 :             (*io_err) += circ_ref_count;
     245             : 
     246             :             /* get the root diagram */
     247           4 :             data_row_id_t root_diag_id = DATA_ROW_ID_VOID;
     248             :             {
     249           4 :                 uint32_t out_diagram_count;
     250           8 :                 data_err = data_database_reader_get_diagrams_by_parent_id ( (*this_).db_reader,
     251             :                                                                             DATA_ROW_ID_VOID,
     252             :                                                                             CTRL_CONSISTENCY_CHECKER_MAX_DIAG_BUFFER,
     253           4 :                                                                             &((*this_).temp_diagram_buffer),
     254             :                                                                             &out_diagram_count
     255             :                                                                           );
     256           4 :                 if (( U8_ERROR_NONE == data_err )&&( out_diagram_count > 0 ))
     257             :                 {
     258           4 :                     root_diag_id = data_diagram_get_row_id( &((*this_).temp_diagram_buffer[0]) );
     259             :                 }
     260             :             }
     261             : 
     262           4 :             if ( ! modify_db )
     263             :             {
     264           2 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Move " );
     265           2 :                 utf8stream_writer_write_int( out_english_report, circ_ref_count );
     266           2 :                 utf8stream_writer_write_str( out_english_report, " diagrams below root diagram " );
     267           2 :                 utf8stream_writer_write_int( out_english_report, root_diag_id );
     268           2 :                 utf8stream_writer_write_str( out_english_report, ".\n" );
     269             :             }
     270             :             else
     271             :             {
     272           6 :                 for ( int list_pos = 0; list_pos < circ_ref_count; list_pos ++ )
     273             :                 {
     274           4 :                     data_id_t diagram_id = data_small_set_get_id( &circ_ref, list_pos );
     275           4 :                     data_row_id_t diagram_row_id = data_id_get_row_id( &diagram_id );
     276             : 
     277           4 :                     data_err = data_database_writer_update_diagram_parent_id ( (*this_).db_writer,
     278             :                                                                                diagram_row_id,
     279             :                                                                                root_diag_id,
     280             :                                                                                NULL /*out_old_diagram*/
     281             :                                                                              );
     282           4 :                     if ( U8_ERROR_NONE == data_err )
     283             :                     {
     284           4 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Diagram " );
     285           4 :                         utf8stream_writer_write_int( out_english_report, diagram_row_id );
     286           4 :                         utf8stream_writer_write_str( out_english_report, " moved below root diagram " );
     287           4 :                         utf8stream_writer_write_int( out_english_report, root_diag_id );
     288           4 :                         utf8stream_writer_write_str( out_english_report, ".\n" );
     289           4 :                         (*io_fix) ++;
     290             :                     }
     291             :                     else
     292             :                     {
     293           0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     294           0 :                         err_result |= data_err;
     295             :                     }
     296             :                 }
     297             :             }
     298             :         }
     299             :     }
     300             :     else
     301             :     {
     302           0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     303           0 :         err_result |= data_err;
     304             :     }
     305             : 
     306          30 :     U8_TRACE_END_ERR( err_result );
     307          30 :     return err_result;
     308             : }
     309             : 
     310          30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_diagramelements ( ctrl_consistency_checker_t *this_,
     311             :                                                                            bool modify_db,
     312             :                                                                            uint32_t *io_err,
     313             :                                                                            uint32_t *io_fix,
     314             :                                                                            utf8stream_writer_t *out_english_report )
     315             : {
     316          30 :     U8_TRACE_BEGIN();
     317          30 :     assert ( NULL != io_err );
     318          30 :     assert ( NULL != io_fix );
     319          30 :     assert ( NULL != out_english_report );
     320          30 :     u8_error_t err_result = U8_ERROR_NONE;
     321          30 :     u8_error_t data_err;
     322             : 
     323             :     /* write report title */
     324          30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that diagramelements reference valid diagrams and classifiers\n" );
     325             : 
     326          30 :     data_small_set_t unref;
     327          30 :     data_small_set_init( &unref );
     328          30 :     data_err = data_database_consistency_checker_find_nonreferencing_diagramelements ( &((*this_).db_checker), &unref );
     329          30 :     if ( U8_ERROR_NONE == data_err )
     330             :     {
     331          30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     332             : 
     333          30 :         utf8stream_writer_write_str( out_english_report, "    NONREFERENCING DIAGRAMELEMENTS COUNT: " );
     334          30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     335          30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     336             : 
     337          30 :         if ( unref_count != 0 )
     338             :         {
     339           2 :             (*io_err) += unref_count;
     340             : 
     341           2 :             if ( ! modify_db )
     342             :             {
     343           1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     344           1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     345           1 :                 utf8stream_writer_write_str( out_english_report, " diagramelements.\n" );
     346             :             }
     347             :             else
     348             :             {
     349           4 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     350             :                 {
     351           3 :                     data_id_t diagramelement_id = data_small_set_get_id( &unref, list_pos );
     352           3 :                     data_row_id_t diagramelement_row_id = data_id_get_row_id( &diagramelement_id );
     353           3 :                     data_err = data_database_writer_delete_diagramelement ( (*this_).db_writer, diagramelement_row_id, NULL );
     354           3 :                     if ( U8_ERROR_NONE == data_err )
     355             :                     {
     356           3 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Diagramelement " );
     357           3 :                         utf8stream_writer_write_int( out_english_report, diagramelement_row_id );
     358           3 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     359           3 :                         (*io_fix) ++;
     360             :                     }
     361             :                     else
     362             :                     {
     363           0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     364           0 :                         err_result |= data_err;
     365             :                     }
     366             :                 }
     367             :             }
     368             :         }
     369             :     }
     370             :     else
     371             :     {
     372           0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     373           0 :         err_result |= data_err;
     374             :     }
     375             : 
     376          30 :     U8_TRACE_END_ERR( err_result );
     377          30 :     return err_result;
     378             : }
     379             : 
     380          30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_diagele_features ( ctrl_consistency_checker_t *this_,
     381             :                                                                             bool modify_db,
     382             :                                                                             uint32_t *io_err,
     383             :                                                                             uint32_t *io_fix,
     384             :                                                                             utf8stream_writer_t *out_english_report )
     385             : {
     386          30 :     U8_TRACE_BEGIN();
     387          30 :     assert ( NULL != io_err );
     388          30 :     assert ( NULL != io_fix );
     389          30 :     assert ( NULL != out_english_report );
     390          30 :     u8_error_t err_result = U8_ERROR_NONE;
     391          30 :     u8_error_t data_err;
     392             : 
     393             :     /* write report title */
     394          30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that diagramelements reference NULL or valid features\n" );
     395             : 
     396          30 :     data_small_set_t unref;
     397          30 :     data_small_set_init( &unref );
     398          30 :     data_err = data_database_consistency_checker_find_invalid_focused_features ( &((*this_).db_checker), &unref );
     399          30 :     if ( U8_ERROR_NONE == data_err )
     400             :     {
     401          30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     402             : 
     403          30 :         utf8stream_writer_write_str( out_english_report, "    ILLREFERENCING DIAGRAMELEMENTS COUNT: " );
     404          30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     405          30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     406             : 
     407          30 :         if ( unref_count != 0 )
     408             :         {
     409           2 :             (*io_err) += unref_count;
     410             : 
     411           2 :             if ( ! modify_db )
     412             :             {
     413           1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Unlink focused features from " );
     414           1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     415           1 :                 utf8stream_writer_write_str( out_english_report, " diagramelements.\n" );
     416             :             }
     417             :             else
     418             :             {
     419           3 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     420             :                 {
     421           2 :                     data_id_t diagramelement_id = data_small_set_get_id( &unref, list_pos );
     422           2 :                     data_row_id_t diagramelement_row_id = data_id_get_row_id( &diagramelement_id );
     423           2 :                     data_err = data_database_writer_update_diagramelement_focused_feature_id ( (*this_).db_writer, diagramelement_row_id, DATA_ROW_ID_VOID, NULL );
     424           2 :                     if ( U8_ERROR_NONE == data_err )
     425             :                     {
     426           2 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Focused features unlinked from " );
     427           2 :                         utf8stream_writer_write_int( out_english_report, diagramelement_row_id );
     428           2 :                         utf8stream_writer_write_str( out_english_report, " diagramelements.\n" );
     429           2 :                         (*io_fix) ++;
     430             :                     }
     431             :                     else
     432             :                     {
     433           0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     434           0 :                         err_result |= data_err;
     435             :                     }
     436             :                 }
     437             :             }
     438             :         }
     439             :     }
     440             :     else
     441             :     {
     442           0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     443           0 :         err_result |= data_err;
     444             :     }
     445             : 
     446          30 :     U8_TRACE_END_ERR( err_result );
     447          30 :     return err_result;
     448             : }
     449             : 
     450          30 : u8_error_t ctrl_consistency_checker_private_ensure_referenced_classifiers ( ctrl_consistency_checker_t *this_,
     451             :                                                                             bool modify_db,
     452             :                                                                             uint32_t *io_err,
     453             :                                                                             uint32_t *io_fix,
     454             :                                                                             utf8stream_writer_t *out_english_report )
     455             : {
     456          30 :     U8_TRACE_BEGIN();
     457          30 :     assert ( NULL != io_err );
     458          30 :     assert ( NULL != io_fix );
     459          30 :     assert ( NULL != out_english_report );
     460          30 :     u8_error_t err_result = U8_ERROR_NONE;
     461          30 :     u8_error_t data_err;
     462             : 
     463             :     /* write report title */
     464          30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that classifiers are referenced\n" );
     465             : 
     466          30 :     data_small_set_t unref;
     467          30 :     data_small_set_init( &unref );
     468          30 :     data_err = data_database_consistency_checker_find_unreferenced_classifiers ( &((*this_).db_checker), &unref );
     469          30 :     if ( U8_ERROR_NONE == data_err )
     470             :     {
     471          30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     472             : 
     473          30 :         utf8stream_writer_write_str( out_english_report, "    UNREFERENCED CLASSIFIER COUNT: " );
     474          30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     475          30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     476             : 
     477          30 :         if ( unref_count != 0 )
     478             :         {
     479           4 :             (*io_err) += unref_count;
     480             : 
     481           4 :             if ( ! modify_db )
     482             :             {
     483           2 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     484           2 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     485           2 :                 utf8stream_writer_write_str( out_english_report, " classifiers.\n" );
     486             :             }
     487             :             else
     488             :             {
     489           4 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     490             :                 {
     491           2 :                     data_id_t classifier_id = data_small_set_get_id( &unref, list_pos );
     492           2 :                     data_row_id_t classifier_row_id = data_id_get_row_id( &classifier_id );
     493           2 :                     err_result |= data_database_consistency_checker_kill_classifier ( &((*this_).db_checker), classifier_row_id );
     494           2 :                     if ( U8_ERROR_NONE == err_result )
     495             :                     {
     496           2 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Classifier " );
     497           2 :                         utf8stream_writer_write_int( out_english_report, classifier_row_id );
     498           2 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     499           2 :                         (*io_fix) ++;
     500             :                     }
     501             :                     else
     502             :                     {
     503           0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     504             :                     }
     505             :                 }
     506             :             }
     507             :         }
     508             :     }
     509             :     else
     510             :     {
     511           0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     512           0 :         err_result |= data_err;
     513             :     }
     514             : 
     515          30 :     U8_TRACE_END_ERR( err_result );
     516          30 :     return err_result;
     517             : }
     518             : 
     519          30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_feature_parents ( ctrl_consistency_checker_t *this_,
     520             :                                                                            bool modify_db,
     521             :                                                                            uint32_t *io_err,
     522             :                                                                            uint32_t *io_fix,
     523             :                                                                            utf8stream_writer_t *out_english_report )
     524             : {
     525          30 :     U8_TRACE_BEGIN();
     526          30 :     assert ( NULL != io_err );
     527          30 :     assert ( NULL != io_fix );
     528          30 :     assert ( NULL != out_english_report );
     529          30 :     u8_error_t err_result = U8_ERROR_NONE;
     530          30 :     u8_error_t data_err;
     531             : 
     532             :     /* write report title */
     533          30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that features have valid classifiers\n" );
     534             : 
     535          30 :     data_small_set_t unref;
     536          30 :     data_small_set_init( &unref );
     537          30 :     data_err = data_database_consistency_checker_find_unreferenced_features ( &((*this_).db_checker), &unref );
     538          30 :     if ( U8_ERROR_NONE == data_err )
     539             :     {
     540          30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     541             : 
     542          30 :         utf8stream_writer_write_str( out_english_report, "    NONREFERENCING FEATURES COUNT: " );
     543          30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     544          30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     545             : 
     546          30 :         if ( unref_count != 0 )
     547             :         {
     548           3 :             (*io_err) += unref_count;
     549             : 
     550           3 :             if ( ! modify_db )
     551             :             {
     552           1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     553           1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     554           1 :                 utf8stream_writer_write_str( out_english_report, " features.\n" );
     555             :             }
     556             :             else
     557             :             {
     558           4 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     559             :                 {
     560           2 :                     data_id_t feature_id = data_small_set_get_id( &unref, list_pos );
     561           2 :                     data_row_id_t feature_row_id = data_id_get_row_id( &feature_id );
     562           2 :                     data_err = data_database_writer_delete_feature ( (*this_).db_writer, feature_row_id, NULL );
     563           2 :                     if ( U8_ERROR_NONE == data_err )
     564             :                     {
     565           2 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Feature " );
     566           2 :                         utf8stream_writer_write_int( out_english_report, feature_row_id );
     567           2 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     568           2 :                         (*io_fix) ++;
     569             :                     }
     570             :                     else
     571             :                     {
     572           0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     573           0 :                         err_result |= data_err;
     574             :                     }
     575             :                 }
     576             :             }
     577             :         }
     578             :     }
     579             :     else
     580             :     {
     581           0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     582           0 :         err_result |= data_err;
     583             :     }
     584             : 
     585          30 :     U8_TRACE_END_ERR( err_result );
     586          30 :     return err_result;
     587             : }
     588             : 
     589          30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_relationship_classifiers ( ctrl_consistency_checker_t *this_,
     590             :                                                                                     bool modify_db,
     591             :                                                                                     uint32_t *io_err,
     592             :                                                                                     uint32_t *io_fix,
     593             :                                                                                     utf8stream_writer_t *out_english_report )
     594             : {
     595          30 :     U8_TRACE_BEGIN();
     596          30 :     assert ( NULL != io_err );
     597          30 :     assert ( NULL != io_fix );
     598          30 :     assert ( NULL != out_english_report );
     599          30 :     u8_error_t err_result = U8_ERROR_NONE;
     600          30 :     u8_error_t data_err;
     601             : 
     602             :     /* write report title */
     603          30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that relationships link valid classifiers\n" );
     604             : 
     605          30 :     data_small_set_t unref;
     606          30 :     data_small_set_init( &unref );
     607          30 :     data_err = data_database_consistency_checker_find_unreferenced_relationships ( &((*this_).db_checker), &unref );
     608          30 :     if ( U8_ERROR_NONE == data_err )
     609             :     {
     610          30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     611             : 
     612          30 :         utf8stream_writer_write_str( out_english_report, "    NONREFERENCING RELATIONSHIPS COUNT: " );
     613          30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     614          30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     615             : 
     616          30 :         if ( unref_count != 0 )
     617             :         {
     618           3 :             (*io_err) += unref_count;
     619             : 
     620           3 :             if ( ! modify_db )
     621             :             {
     622           1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     623           1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     624           1 :                 utf8stream_writer_write_str( out_english_report, " relationships.\n" );
     625             :             }
     626             :             else
     627             :             {
     628           6 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     629             :                 {
     630           4 :                     data_id_t relationship_id = data_small_set_get_id( &unref, list_pos );
     631           4 :                     data_row_id_t relation_row_id = data_id_get_row_id( &relationship_id );
     632           4 :                     data_err = data_database_writer_delete_relationship ( (*this_).db_writer, relation_row_id, NULL );
     633           4 :                     if ( U8_ERROR_NONE == data_err )
     634             :                     {
     635           4 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Relationship " );
     636           4 :                         utf8stream_writer_write_int( out_english_report, relation_row_id );
     637           4 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     638           4 :                         (*io_fix) ++;
     639             :                     }
     640             :                     else
     641             :                     {
     642           0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     643           0 :                         err_result |= data_err;
     644             :                     }
     645             :                 }
     646             :             }
     647             :         }
     648             :     }
     649             :     else
     650             :     {
     651           0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     652           0 :         err_result |= data_err;
     653             :     }
     654             : 
     655          30 :     U8_TRACE_END_ERR( err_result );
     656          30 :     return err_result;
     657             : }
     658             : 
     659          30 : u8_error_t ctrl_consistency_checker_private_ensure_valid_relationship_features ( ctrl_consistency_checker_t *this_,
     660             :                                                                                  bool modify_db,
     661             :                                                                                  uint32_t *io_err,
     662             :                                                                                  uint32_t *io_fix,
     663             :                                                                                  utf8stream_writer_t *out_english_report )
     664             : {
     665          30 :     U8_TRACE_BEGIN();
     666          30 :     assert ( NULL != io_err );
     667          30 :     assert ( NULL != io_fix );
     668          30 :     assert ( NULL != out_english_report );
     669          30 :     u8_error_t err_result = U8_ERROR_NONE;
     670          30 :     u8_error_t data_err;
     671             : 
     672             :     /* write report title */
     673          30 :     utf8stream_writer_write_str( out_english_report, "STEP: Ensure that relationships link NULL or valid features\n" );
     674             : 
     675          30 :     data_small_set_t unref;
     676          30 :     data_small_set_init( &unref );
     677          30 :     data_err = data_database_consistency_checker_find_invalid_relationship_features ( &((*this_).db_checker), &unref );
     678          30 :     if ( U8_ERROR_NONE == data_err )
     679             :     {
     680          30 :         uint32_t unref_count = data_small_set_get_count( &unref );
     681             : 
     682          30 :         utf8stream_writer_write_str( out_english_report, "    ILLREFERENCING RELATIONSHIPS COUNT: " );
     683          30 :         utf8stream_writer_write_int( out_english_report, unref_count );
     684          30 :         utf8stream_writer_write_str( out_english_report, "\n" );
     685             : 
     686          30 :         if ( unref_count != 0 )
     687             :         {
     688           2 :             (*io_err) += unref_count;
     689             : 
     690           2 :             if ( ! modify_db )
     691             :             {
     692           1 :                 utf8stream_writer_write_str( out_english_report, "    PROPOSED FIX: Delete " );
     693           1 :                 utf8stream_writer_write_int( out_english_report, unref_count );
     694           1 :                 utf8stream_writer_write_str( out_english_report, " relationships.\n" );
     695             :             }
     696             :             else
     697             :             {
     698           4 :                 for ( int list_pos = 0; list_pos < unref_count; list_pos ++ )
     699             :                 {
     700           3 :                     data_id_t relationship_id = data_small_set_get_id( &unref, list_pos );
     701           3 :                     data_row_id_t relation_row_id = data_id_get_row_id( &relationship_id );
     702           3 :                     data_err = data_database_writer_delete_relationship ( (*this_).db_writer, relation_row_id, NULL );
     703           3 :                     if ( U8_ERROR_NONE == data_err )
     704             :                     {
     705           3 :                         utf8stream_writer_write_str( out_english_report, "    FIX: Relationship " );
     706           3 :                         utf8stream_writer_write_int( out_english_report, relation_row_id );
     707           3 :                         utf8stream_writer_write_str( out_english_report, " deleted.\n" );
     708           3 :                         (*io_fix) ++;
     709             :                     }
     710             :                     else
     711             :                     {
     712           0 :                         utf8stream_writer_write_str( out_english_report, "ERROR WRITING DATABASE.\n" );
     713           0 :                         err_result |= data_err;
     714             :                     }
     715             :                 }
     716             :             }
     717             :         }
     718             :     }
     719             :     else
     720             :     {
     721           0 :         utf8stream_writer_write_str( out_english_report, "ERROR READING DATABASE.\n" );
     722           0 :         err_result |= data_err;
     723             :     }
     724             : 
     725          30 :     U8_TRACE_END_ERR( err_result );
     726          30 :     return err_result;
     727             : }
     728             : 
     729             : 
     730             : /*
     731             : Copyright 2016-2024 Andreas Warnke
     732             : 
     733             : Licensed under the Apache License, Version 2.0 (the "License");
     734             : you may not use this file except in compliance with the License.
     735             : You may obtain a copy of the License at
     736             : 
     737             :     http://www.apache.org/licenses/LICENSE-2.0
     738             : 
     739             : Unless required by applicable law or agreed to in writing, software
     740             : distributed under the License is distributed on an "AS IS" BASIS,
     741             : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     742             : See the License for the specific language governing permissions and
     743             : limitations under the License.
     744             : */

Generated by: LCOV version 1.16