LCOV - code coverage report
Current view: top level - ctrl/source - ctrl_classifier_controller.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.70.2_covts Lines: 86.3 % 424 366
Test Date: 2026-05-03 11:56:31 Functions: 92.3 % 26 24

            Line data    Source code
       1              : /* File: ctrl_classifier_controller.c; Copyright and License: see below */
       2              : 
       3              : #include "ctrl_classifier_controller.h"
       4              : #include "u8/u8_trace.h"
       5              : #include "u8/u8_log.h"
       6              : 
       7           47 : void ctrl_classifier_controller_init ( ctrl_classifier_controller_t *this_,
       8              :                                        ctrl_undo_redo_list_t *undo_redo_list,
       9              :                                        ctrl_classifier_trigger_t *policy_enforcer,
      10              :                                        data_database_t *database,
      11              :                                        data_database_reader_t *db_reader,
      12              :                                        data_database_writer_t *db_writer )
      13              : {
      14           47 :     U8_TRACE_BEGIN();
      15              : 
      16           47 :     (*this_).undo_redo_list = undo_redo_list;
      17           47 :     (*this_).policy_enforcer = policy_enforcer;
      18           47 :     (*this_).database = database;
      19           47 :     (*this_).db_reader = db_reader;
      20           47 :     (*this_).db_writer = db_writer;
      21           47 :     consistency_checker_init ( &((*this_).consistency_checker), database, db_reader, db_writer );
      22              : 
      23           47 :     U8_TRACE_END();
      24           47 : }
      25              : 
      26           47 : void ctrl_classifier_controller_destroy ( ctrl_classifier_controller_t *this_ )
      27              : {
      28           47 :     U8_TRACE_BEGIN();
      29              : 
      30           47 :     consistency_checker_destroy ( &((*this_).consistency_checker) );
      31           47 :     (*this_).undo_redo_list = NULL;
      32           47 :     (*this_).policy_enforcer = NULL;
      33           47 :     (*this_).database = NULL;
      34           47 :     (*this_).db_reader = NULL;
      35           47 :     (*this_).db_writer = NULL;
      36              : 
      37           47 :     U8_TRACE_END();
      38           47 : }
      39              : 
      40              : /* ================================ CLASSIFIER ================================ */
      41              : 
      42           47 : u8_error_t ctrl_classifier_controller_create_classifier ( ctrl_classifier_controller_t *this_,
      43              :                                                           const data_classifier_t *new_classifier,
      44              :                                                           ctrl_undo_redo_action_boundary_t add_to_latest_undo_set,
      45              :                                                           data_row_t* out_new_id )
      46              : {
      47           47 :     U8_TRACE_BEGIN();
      48           47 :     assert( NULL != new_classifier );
      49              :     data_classifier_t to_be_created;
      50           47 :     u8_error_t result = U8_ERROR_NONE;
      51              :     data_row_t new_id;
      52              : 
      53           47 :     data_classifier_copy( &to_be_created, new_classifier );
      54              : 
      55           47 :     result = data_database_writer_create_classifier( (*this_).db_writer, &to_be_created, &new_id );
      56           47 :     if ( U8_ERROR_NONE == result )
      57              :     {
      58              :         /* store new id to data_classifier_t object */
      59           40 :         data_classifier_set_row( &to_be_created, new_id );
      60              : 
      61              :         /* if this action shall be stored to the latest set of actions in the undo redo list, remove the boundary: */
      62           40 :         if ( add_to_latest_undo_set == CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND )
      63              :         {
      64              :             u8_error_t internal_err;
      65           11 :             internal_err = ctrl_undo_redo_list_remove_boundary_from_end( (*this_).undo_redo_list );
      66           11 :             if ( U8_ERROR_NONE != internal_err )
      67              :             {
      68            0 :                 U8_LOG_ERROR_HEX( "unexpected internal error", internal_err );
      69              :             }
      70              :         }
      71              : 
      72              :         /* store the new diagram to the undo redo list */
      73           40 :         ctrl_undo_redo_list_add_create_classifier( (*this_).undo_redo_list, &to_be_created );
      74           40 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
      75              : 
      76              :         /* copy new id to out parameter */
      77           40 :         if ( NULL != out_new_id )
      78              :         {
      79           40 :             *out_new_id = new_id;
      80              :         }
      81              :     }
      82              : 
      83           47 :     data_classifier_destroy( &to_be_created );
      84              : 
      85           47 :     U8_TRACE_END_ERR( result );
      86           47 :     return result;
      87              : }
      88              : 
      89           11 : u8_error_t ctrl_classifier_controller_delete_classifier( ctrl_classifier_controller_t *this_,
      90              :                                                          data_row_t obj_id,
      91              :                                                          ctrl_undo_redo_action_boundary_t add_to_latest_undo_set,
      92              :                                                          consistency_stat_t *io_stat )
      93              : {
      94           11 :     U8_TRACE_BEGIN();
      95           11 :     assert( io_stat != NULL );
      96           11 :     u8_error_t result = U8_ERROR_NONE;
      97              :     u8_error_t data_result;
      98              : 
      99              :     /* check if the classifier is still referenced by diagramelements */
     100           11 :     bool is_still_referenced = true;
     101              :     {
     102              :         data_diagram_iterator_t diagram_iterator;
     103           11 :         data_diagram_iterator_init_empty( &diagram_iterator );
     104           11 :         result |= data_database_reader_get_diagrams_by_classifier_id( (*this_).db_reader,
     105              :                                                                       obj_id,
     106              :                                                                       &diagram_iterator
     107              :                                                                     );
     108              : 
     109           11 :         if (( data_diagram_iterator_has_next( &diagram_iterator ) )||( result != U8_ERROR_NONE ))
     110              :         {
     111            7 :             is_still_referenced = true;
     112              :         }
     113              :         else
     114              :         {
     115            4 :             is_still_referenced = false;
     116              :         }
     117           11 :         result |= data_diagram_iterator_destroy( &diagram_iterator );
     118              :     }
     119              : 
     120              :     /* if the classifier is still referenced by diagramelements, do not do anything, report an error */
     121           11 :     if ( is_still_referenced )
     122              :     {
     123            7 :         result |= U8_ERROR_OBJECT_STILL_REFERENCED;
     124              :     }
     125              :     else
     126              :     {
     127              :         /* if this action shall be stored to the latest set of actions in the undo redo list, remove the boundary: */
     128            4 :         if ( add_to_latest_undo_set == CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND )
     129              :         {
     130              :             u8_error_t internal_err;
     131            4 :             internal_err = ctrl_undo_redo_list_remove_boundary_from_end( (*this_).undo_redo_list );
     132            4 :             if ( U8_ERROR_NONE != internal_err )
     133              :             {
     134            0 :                 U8_LOG_ERROR_HEX( "unexpected internal error", internal_err );
     135              :             }
     136              :         }
     137              : 
     138              :         /* delete all features */
     139              :         {
     140              :             data_feature_iterator_t feature_iterator;
     141            4 :             data_feature_iterator_init_empty( &feature_iterator );
     142            4 :             result |= data_database_reader_get_features_by_classifier_id( (*this_).db_reader,
     143              :                                                                           obj_id,
     144              :                                                                           &feature_iterator
     145              :                                                                         );
     146            4 :             while ( data_feature_iterator_has_next( &feature_iterator ) )
     147              :             {
     148            0 :                 result |= data_feature_iterator_next( &feature_iterator, &((*this_).temp_feature) );
     149            0 :                 const data_row_t feat_id = data_feature_get_row( &((*this_).temp_feature) );
     150            0 :                 const bool is_lifeline
     151            0 :                     = ( DATA_FEATURE_TYPE_LIFELINE == data_feature_get_main_type( &((*this_).temp_feature) ) );
     152            0 :                 data_result = data_database_writer_delete_feature( (*this_).db_writer, feat_id, NULL );
     153            0 :                 if ( data_result == U8_ERROR_NONE )
     154              :                 {
     155            0 :                     if ( is_lifeline )
     156              :                     {
     157            0 :                         consistency_stat_decrement_lifelines( io_stat );
     158              :                     }
     159              :                     else
     160              :                     {
     161            0 :                         consistency_stat_decrement_features( io_stat );
     162              :                     }
     163              : 
     164              :                     /* store the deleted feature to the undo redo list */
     165            0 :                     ctrl_undo_redo_list_add_delete_feature( (*this_).undo_redo_list, &((*this_).temp_feature) );
     166              :                 }
     167              :                 else
     168              :                 {
     169              :                     /* report this unexpected error */
     170            0 :                     result |= data_result;
     171              :                 }
     172            0 :                 data_feature_destroy( &((*this_).temp_feature) );
     173              :             }
     174            4 :             result |= data_feature_iterator_destroy( &feature_iterator );
     175              :         }
     176              : 
     177              :         /* delete all relationships */
     178              :         {
     179              :             data_relationship_iterator_t relationship_iterator;
     180            4 :             data_relationship_iterator_init_empty( &relationship_iterator );
     181            4 :             result |= data_database_reader_get_relationships_by_classifier_id( (*this_).db_reader,
     182              :                                                                                obj_id,
     183              :                                                                                &relationship_iterator
     184              :                                                                              );
     185            4 :             while ( data_relationship_iterator_has_next( &relationship_iterator ) )
     186              :             {
     187            0 :                 result |= data_relationship_iterator_next( &relationship_iterator, &((*this_).temp_relationship) );
     188            0 :                 const data_row_t rel_id = data_relationship_get_row( &((*this_).temp_relationship) );
     189            0 :                 data_result = data_database_writer_delete_relationship( (*this_).db_writer, rel_id, NULL );
     190            0 :                 if ( data_result == U8_ERROR_NONE )
     191              :                 {
     192            0 :                     consistency_stat_decrement_relationships( io_stat );
     193              : 
     194              :                     /* store the deleted relationship to the undo redo list */
     195            0 :                     ctrl_undo_redo_list_add_delete_relationship( (*this_).undo_redo_list, &((*this_).temp_relationship) );
     196              :                 }
     197              :                 else
     198              :                 {
     199              :                     /* report this unexpected error */
     200            0 :                     result |= data_result;
     201              :                 }
     202            0 :                 data_relationship_destroy( &((*this_).temp_relationship) );
     203              :             }
     204            4 :             result |= data_relationship_iterator_destroy( &relationship_iterator );
     205              :         }
     206              : 
     207              :         /* delete the classifier */
     208              :         {
     209              :             data_classifier_t old_classifier;
     210            4 :             data_result = data_database_writer_delete_classifier( (*this_).db_writer,
     211              :                                                                   obj_id,
     212              :                                                                   &old_classifier
     213              :                                                                 );
     214              : 
     215            4 :             if ( U8_ERROR_NONE == data_result )
     216              :             {
     217            3 :                 consistency_stat_decrement_classifiers( io_stat );
     218              : 
     219              :                 /* store the deleted classifier to the undo redo list */
     220            3 :                 ctrl_undo_redo_list_add_delete_classifier( (*this_).undo_redo_list, &old_classifier );
     221              : 
     222            3 :                 data_classifier_destroy( &old_classifier );
     223              :             }
     224            1 :             else if ( u8_error_contains( data_result, U8_ERROR_OBJECT_STILL_REFERENCED ) )
     225              :             {
     226              :                 /* report this unexpected error */
     227            0 :                 U8_LOG_ERROR( "The classifier cannot be deleted because it is still referenced." );
     228            0 :                 result |= data_result;
     229              :             }
     230              :             else
     231              :             {
     232              :                 /* report this unexpected error */
     233            1 :                 result |= data_result;
     234              :             }
     235              :         }
     236              : 
     237              :         /* add a boundary to the undo redo list */
     238            4 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     239              :     }
     240              : 
     241           11 :     U8_TRACE_END_ERR( result );
     242           11 :     return result;
     243              : }
     244              : 
     245            1 : u8_error_t ctrl_classifier_controller_update_classifier_main_type ( ctrl_classifier_controller_t *this_,
     246              :                                                                     data_row_t classifier_id,
     247              :                                                                     data_classifier_type_t new_classifier_main_type )
     248              : {
     249            1 :     U8_TRACE_BEGIN();
     250            1 :     u8_error_t result = U8_ERROR_NONE;
     251              :     data_classifier_t old_classifier;
     252              : 
     253            1 :     result = data_database_writer_update_classifier_main_type( (*this_).db_writer, classifier_id, new_classifier_main_type, &old_classifier );
     254            1 :     if ( U8_ERROR_NONE == result )
     255              :     {
     256              :         /* prepare the new classifier */
     257              :         data_classifier_t new_classifier;
     258            1 :         data_classifier_copy( &new_classifier, &old_classifier );
     259            1 :         data_classifier_set_main_type( &new_classifier, new_classifier_main_type );
     260              :         /* store the change of the classifier to the undo redo list */
     261            1 :         ctrl_undo_redo_list_add_update_classifier( (*this_).undo_redo_list, &old_classifier, &new_classifier );
     262            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     263              : 
     264            1 :         data_classifier_destroy( &new_classifier );
     265            1 :         data_classifier_destroy( &old_classifier );
     266              :     }
     267              : 
     268            1 :     U8_TRACE_END_ERR( result );
     269            1 :     return result;
     270              : }
     271              : 
     272            2 : u8_error_t ctrl_classifier_controller_update_classifier_stereotype ( ctrl_classifier_controller_t *this_,
     273              :                                                                      data_row_t classifier_id,
     274              :                                                                      const char* new_classifier_stereotype )
     275              : {
     276            2 :     U8_TRACE_BEGIN();
     277            2 :     u8_error_t result = U8_ERROR_NONE;
     278              :     data_classifier_t old_classifier;
     279              : 
     280            2 :     result = data_database_writer_update_classifier_stereotype( (*this_).db_writer, classifier_id, new_classifier_stereotype, &old_classifier );
     281            2 :     if  (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     282              :     {
     283              :         /* prepare the new classifier */
     284              :         data_classifier_t new_classifier;
     285            2 :         data_classifier_copy( &new_classifier, &old_classifier );
     286            2 :         data_classifier_set_stereotype( &new_classifier, new_classifier_stereotype );
     287              :         /* store the change of the classifier to the undo redo list */
     288            2 :         ctrl_undo_redo_list_add_update_classifier( (*this_).undo_redo_list, &old_classifier, &new_classifier );
     289            2 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     290              : 
     291            2 :         data_classifier_destroy( &new_classifier );
     292            2 :         data_classifier_destroy( &old_classifier );
     293              :     }
     294              : 
     295            2 :     U8_TRACE_END_ERR( result );
     296            2 :     return result;
     297              : }
     298              : 
     299            1 : u8_error_t ctrl_classifier_controller_update_classifier_name ( ctrl_classifier_controller_t *this_,
     300              :                                                                data_row_t classifier_id,
     301              :                                                                const char* new_classifier_name )
     302              : {
     303            1 :     U8_TRACE_BEGIN();
     304            1 :     u8_error_t result = U8_ERROR_NONE;
     305              :     data_classifier_t old_classifier;
     306              : 
     307            1 :     result = data_database_writer_update_classifier_name( (*this_).db_writer, classifier_id, new_classifier_name, &old_classifier );
     308            1 :     if  (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     309              :     {
     310              :         /* prepare the new classifier */
     311              :         data_classifier_t new_classifier;
     312            1 :         data_classifier_copy( &new_classifier, &old_classifier );
     313            1 :         data_classifier_set_name( &new_classifier, new_classifier_name );
     314              :         /* store the change of the classifier to the undo redo list */
     315            1 :         ctrl_undo_redo_list_add_update_classifier( (*this_).undo_redo_list, &old_classifier, &new_classifier );
     316            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     317              : 
     318            1 :         data_classifier_destroy( &new_classifier );
     319            1 :         data_classifier_destroy( &old_classifier );
     320              :     }
     321              : 
     322            1 :     U8_TRACE_END_ERR( result );
     323            1 :     return result;
     324              : }
     325              : 
     326            1 : u8_error_t ctrl_classifier_controller_update_classifier_description ( ctrl_classifier_controller_t *this_,
     327              :                                                                       data_row_t classifier_id,
     328              :                                                                       const char* new_classifier_description )
     329              : {
     330            1 :     U8_TRACE_BEGIN();
     331            1 :     u8_error_t result = U8_ERROR_NONE;
     332              :     data_classifier_t old_classifier;
     333              : 
     334            1 :     result = data_database_writer_update_classifier_description( (*this_).db_writer, classifier_id, new_classifier_description, &old_classifier );
     335            1 :     if (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     336              :     {
     337              :         /* prepare the new classifier */
     338              :         data_classifier_t new_classifier;
     339            1 :         data_classifier_copy( &new_classifier, &old_classifier );
     340            1 :         data_classifier_set_description( &new_classifier, new_classifier_description );
     341              :         /* store the change of the classifier to the undo redo list */
     342            1 :         ctrl_undo_redo_list_add_update_classifier( (*this_).undo_redo_list, &old_classifier, &new_classifier );
     343            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     344              : 
     345            1 :         data_classifier_destroy( &new_classifier );
     346            1 :         data_classifier_destroy( &old_classifier );
     347              :     }
     348              : 
     349            1 :     U8_TRACE_END_ERR( result );
     350            1 :     return result;
     351              : }
     352              : 
     353            1 : u8_error_t ctrl_classifier_controller_update_classifier_x_order ( ctrl_classifier_controller_t *this_,
     354              :                                                                   data_row_t classifier_id,
     355              :                                                                   int32_t new_classifier_x_order )
     356              : {
     357            1 :     U8_TRACE_BEGIN();
     358            1 :     u8_error_t result = U8_ERROR_NONE;
     359              :     data_classifier_t old_classifier;
     360              : 
     361            1 :     result = data_database_writer_update_classifier_x_order( (*this_).db_writer, classifier_id, new_classifier_x_order, &old_classifier );
     362            1 :     if ( U8_ERROR_NONE == result )
     363              :     {
     364              :         /* prepare the new classifier */
     365              :         data_classifier_t new_classifier;
     366            1 :         data_classifier_copy( &new_classifier, &old_classifier );
     367            1 :         data_classifier_set_x_order( &new_classifier, new_classifier_x_order );
     368              :         /* store the change of the classifier to the undo redo list */
     369            1 :         ctrl_undo_redo_list_add_update_classifier( (*this_).undo_redo_list, &old_classifier, &new_classifier );
     370            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     371              : 
     372            1 :         data_classifier_destroy( &new_classifier );
     373            1 :         data_classifier_destroy( &old_classifier );
     374              :     }
     375              : 
     376            1 :     U8_TRACE_END_ERR( result );
     377            1 :     return result;
     378              : }
     379              : 
     380            1 : u8_error_t ctrl_classifier_controller_update_classifier_y_order ( ctrl_classifier_controller_t *this_,
     381              :                                                                   data_row_t classifier_id,
     382              :                                                                   int32_t new_classifier_y_order )
     383              : {
     384            1 :     U8_TRACE_BEGIN();
     385            1 :     u8_error_t result = U8_ERROR_NONE;
     386              :     data_classifier_t old_classifier;
     387              : 
     388            1 :     result = data_database_writer_update_classifier_y_order( (*this_).db_writer, classifier_id, new_classifier_y_order, &old_classifier );
     389            1 :     if ( U8_ERROR_NONE == result )
     390              :     {
     391              :         /* prepare the new classifier */
     392              :         data_classifier_t new_classifier;
     393            1 :         data_classifier_copy( &new_classifier, &old_classifier );
     394            1 :         data_classifier_set_y_order( &new_classifier, new_classifier_y_order );
     395              :         /* store the change of the classifier to the undo redo list */
     396            1 :         ctrl_undo_redo_list_add_update_classifier( (*this_).undo_redo_list, &old_classifier, &new_classifier );
     397            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     398              : 
     399            1 :         data_classifier_destroy( &new_classifier );
     400            1 :         data_classifier_destroy( &old_classifier );
     401              :     }
     402              : 
     403            1 :     U8_TRACE_END_ERR( result );
     404            1 :     return result;
     405              : }
     406              : 
     407            0 : u8_error_t ctrl_classifier_controller_update_classifier_x_order_y_order ( ctrl_classifier_controller_t *this_,
     408              :                                                                           data_row_t classifier_id,
     409              :                                                                           int32_t new_classifier_x_order,
     410              :                                                                           int32_t new_classifier_y_order )
     411              : {
     412            0 :     U8_TRACE_BEGIN();
     413            0 :     u8_error_t result = U8_ERROR_NONE;
     414              :     data_classifier_t old_classifier;
     415              : 
     416            0 :     result = data_database_writer_update_classifier_x_order( (*this_).db_writer, classifier_id, new_classifier_x_order, &old_classifier );
     417            0 :     if ( U8_ERROR_NONE == result )
     418              :     {
     419            0 :         result = data_database_writer_update_classifier_y_order( (*this_).db_writer, classifier_id, new_classifier_y_order, NULL );
     420            0 :         if ( U8_ERROR_NONE == result )
     421              :         {
     422              :             /* prepare the new classifier */
     423              :             data_classifier_t new_classifier;
     424            0 :             data_classifier_copy( &new_classifier, &old_classifier );
     425            0 :             data_classifier_set_x_order( &new_classifier, new_classifier_x_order );
     426            0 :             data_classifier_set_y_order( &new_classifier, new_classifier_y_order );
     427              :             /* store the change of the classifier to the undo redo list */
     428            0 :             ctrl_undo_redo_list_add_update_classifier( (*this_).undo_redo_list, &old_classifier, &new_classifier );
     429            0 :             ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     430              : 
     431            0 :             data_classifier_destroy( &new_classifier );
     432              :         }
     433            0 :         data_classifier_destroy( &old_classifier );
     434              :     }
     435              : 
     436            0 :     U8_TRACE_END_ERR( result );
     437            0 :     return result;
     438              : }
     439              : 
     440            0 : u8_error_t ctrl_classifier_controller_update_classifier_list_order ( ctrl_classifier_controller_t *this_,
     441              :                                                                      data_row_t classifier_id,
     442              :                                                                      int32_t new_classifier_list_order )
     443              : {
     444            0 :     U8_TRACE_BEGIN();
     445            0 :     u8_error_t result = U8_ERROR_NONE;
     446              :     data_classifier_t old_classifier;
     447              : 
     448            0 :     result = data_database_writer_update_classifier_list_order( (*this_).db_writer, classifier_id, new_classifier_list_order, &old_classifier );
     449            0 :     if ( U8_ERROR_NONE == result )
     450              :     {
     451              :         /* prepare the new classifier */
     452              :         data_classifier_t new_classifier;
     453            0 :         data_classifier_copy( &new_classifier, &old_classifier );
     454            0 :         data_classifier_set_list_order( &new_classifier, new_classifier_list_order );
     455              :         /* store the change of the classifier to the undo redo list */
     456            0 :         ctrl_undo_redo_list_add_update_classifier( (*this_).undo_redo_list, &old_classifier, &new_classifier );
     457            0 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     458              : 
     459            0 :         data_classifier_destroy( &new_classifier );
     460            0 :         data_classifier_destroy( &old_classifier );
     461              :     }
     462              : 
     463            0 :     U8_TRACE_END_ERR( result );
     464            0 :     return result;
     465              : }
     466              : 
     467              : /* ================================ FEATURE ================================ */
     468              : 
     469           39 : u8_error_t ctrl_classifier_controller_create_feature ( ctrl_classifier_controller_t *this_,
     470              :                                                        const data_feature_t *new_feature,
     471              :                                                        ctrl_undo_redo_action_boundary_t add_to_latest_undo_set,
     472              :                                                        data_row_t* out_new_id )
     473              : {
     474           39 :     U8_TRACE_BEGIN();
     475           39 :     assert( NULL != new_feature );
     476              :     data_feature_t to_be_created;
     477           39 :     u8_error_t result = U8_ERROR_NONE;
     478              :     data_row_t new_id;
     479              : 
     480           39 :     data_feature_copy( &to_be_created, new_feature );
     481              : 
     482           39 :     result = data_database_writer_create_feature( (*this_).db_writer, &to_be_created, &new_id );
     483           39 :     if ( U8_ERROR_NONE == result )
     484              :     {
     485              :         /* store new id to data_feature_t object */
     486           39 :         data_feature_set_row( &to_be_created, new_id );
     487              : 
     488              :         /* if this action shall be stored to the latest set of actions in the undo redo list, remove the boundary: */
     489           39 :         if ( add_to_latest_undo_set == CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND )
     490              :         {
     491              :             u8_error_t internal_err;
     492           25 :             internal_err = ctrl_undo_redo_list_remove_boundary_from_end( (*this_).undo_redo_list );
     493           25 :             if ( U8_ERROR_NONE != internal_err )
     494              :             {
     495            0 :                 U8_LOG_ERROR_HEX( "unexpected internal error", internal_err );
     496              :             }
     497              :         }
     498              : 
     499              :         /* store the new feature to the undo redo list */
     500           39 :         ctrl_undo_redo_list_add_create_feature( (*this_).undo_redo_list, &to_be_created );
     501           39 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     502              : 
     503              :         /* copy new id to out parameter */
     504           39 :         if ( NULL != out_new_id )
     505              :         {
     506           39 :             *out_new_id = new_id;
     507              :         }
     508              :     }
     509              : 
     510              :     /* apply policy rules */
     511           39 :     if ( U8_ERROR_NONE == result )
     512              :     {
     513           39 :         result |= ctrl_classifier_trigger_post_create_feature ( (*this_).policy_enforcer, &to_be_created );
     514              :     }
     515              : 
     516           39 :     data_feature_destroy( &to_be_created );
     517              : 
     518           39 :     U8_TRACE_END_ERR( result );
     519           39 :     return result;
     520              : }
     521              : 
     522           16 : u8_error_t ctrl_classifier_controller_delete_feature ( ctrl_classifier_controller_t *this_,
     523              :                                                        data_row_t obj_id,
     524              :                                                        ctrl_undo_redo_action_boundary_t add_to_latest_undo_set,
     525              :                                                        consistency_stat_t *io_stat )
     526              : {
     527           16 :     U8_TRACE_BEGIN();
     528           16 :     assert( io_stat != NULL );
     529           16 :     u8_error_t result = U8_ERROR_NONE;
     530              :     u8_error_t data_result;
     531              : 
     532              :     /* if this action shall be stored to the latest set of actions in the undo redo list, remove the boundary: */
     533           16 :     if ( add_to_latest_undo_set == CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND )
     534              :     {
     535              :         u8_error_t internal_err;
     536           13 :         internal_err = ctrl_undo_redo_list_remove_boundary_from_end( (*this_).undo_redo_list );
     537           13 :         if ( U8_ERROR_NONE != internal_err )
     538              :         {
     539            0 :             U8_LOG_ERROR_HEX( "unexpected internal error", internal_err );
     540              :         }
     541              :     }
     542              : 
     543              :     /* delete all relationships to and/or from this feature */
     544              :     {
     545              :         data_relationship_iterator_t relationship_iterator;
     546           16 :         data_relationship_iterator_init_empty( &relationship_iterator );
     547           16 :         result |= data_database_reader_get_relationships_by_feature_id( (*this_).db_reader,
     548              :                                                                         obj_id,
     549              :                                                                         &relationship_iterator
     550              :                                                                       );
     551           18 :         while ( data_relationship_iterator_has_next( &relationship_iterator ) )
     552              :         {
     553            2 :             result |= data_relationship_iterator_next( &relationship_iterator, &((*this_).temp_relationship) );
     554            2 :             const data_row_t rel_id = data_relationship_get_row( &((*this_).temp_relationship) );
     555            2 :             data_result = data_database_writer_delete_relationship( (*this_).db_writer, rel_id, NULL );
     556            2 :             if ( U8_ERROR_NONE == data_result )
     557              :             {
     558            2 :                 consistency_stat_decrement_relationships( io_stat );
     559              : 
     560              :                 /* store the deleted relationship to the undo redo list */
     561            2 :                 ctrl_undo_redo_list_add_delete_relationship( (*this_).undo_redo_list, &((*this_).temp_relationship) );
     562              :             }
     563              :             else
     564              :             {
     565              :                 /* report this unexpected error */
     566            0 :                 result |= data_result;
     567              :             }
     568            2 :             data_relationship_destroy( &((*this_).temp_relationship) );
     569              :         }
     570           16 :         result |= data_relationship_iterator_destroy( &relationship_iterator );
     571              :     }
     572              : 
     573              :     /* delete the feature */
     574              :     data_feature_t old_feature;
     575              :     u8_error_t feature_result;
     576              :     {
     577              :         /* delete feature */
     578           16 :         feature_result = data_database_writer_delete_feature( (*this_).db_writer, obj_id, &old_feature );
     579              : 
     580           16 :         if ( U8_ERROR_NONE == feature_result )
     581              :         {
     582           15 :             const bool is_lifeline
     583           15 :                 = ( DATA_FEATURE_TYPE_LIFELINE == data_feature_get_main_type( &old_feature ) );
     584           15 :             if ( is_lifeline )
     585              :             {
     586            9 :                 consistency_stat_decrement_lifelines( io_stat );
     587              :             }
     588              :             else
     589              :             {
     590            6 :                 consistency_stat_decrement_features( io_stat );
     591              :             }
     592              : 
     593              :             /* store the deleted feature to the undo redo list */
     594           15 :             ctrl_undo_redo_list_add_delete_feature( (*this_).undo_redo_list, &old_feature );
     595              :         }
     596              : 
     597           16 :         result |= feature_result;
     598              :     }
     599              : 
     600              :     /* add boundary to undo-redo-list */
     601           16 :     ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     602              : 
     603              :     /* apply policy rules */
     604           16 :     if ( U8_ERROR_NONE == feature_result )
     605              :     {
     606           15 :         result |= ctrl_classifier_trigger_post_delete_feature ( (*this_).policy_enforcer, &old_feature );
     607           15 :         data_feature_destroy( &old_feature );
     608              :     }
     609              : 
     610           16 :     U8_TRACE_END_ERR( result );
     611           16 :     return result;
     612              : }
     613              : 
     614            2 : u8_error_t ctrl_classifier_controller_update_feature_main_type ( ctrl_classifier_controller_t *this_,
     615              :                                                                  data_row_t feature_id,
     616              :                                                                  data_feature_type_t new_feature_type )
     617              : {
     618            2 :     U8_TRACE_BEGIN();
     619            2 :     u8_error_t result = U8_ERROR_NONE;
     620              :     data_feature_t old_feature;
     621              : 
     622            2 :     result = data_database_writer_update_feature_main_type( (*this_).db_writer, feature_id, new_feature_type, &old_feature );
     623            2 :     if ( U8_ERROR_NONE == result )
     624              :     {
     625              :         /* prepare the new feature */
     626              :         data_feature_t new_feature;
     627            2 :         data_feature_copy( &new_feature, &old_feature );
     628            2 :         data_feature_set_main_type( &new_feature, new_feature_type );
     629              :         /* store the change of the feature to the undo redo list */
     630            2 :         ctrl_undo_redo_list_add_update_feature( (*this_).undo_redo_list, &old_feature, &new_feature );
     631            2 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     632              : 
     633            2 :         data_feature_destroy( &new_feature );
     634            2 :         data_feature_destroy( &old_feature );
     635              :     }
     636              : 
     637            2 :     U8_TRACE_END_ERR( result );
     638            2 :     return result;
     639              : }
     640              : 
     641            1 : u8_error_t ctrl_classifier_controller_update_feature_key ( ctrl_classifier_controller_t *this_,
     642              :                                                            data_row_t feature_id,
     643              :                                                            const char* new_feature_key )
     644              : {
     645            1 :     U8_TRACE_BEGIN();
     646            1 :     u8_error_t result = U8_ERROR_NONE;
     647              :     data_feature_t old_feature;
     648              : 
     649            1 :     result = data_database_writer_update_feature_key( (*this_).db_writer, feature_id, new_feature_key, &old_feature );
     650            1 :     if  (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     651              :     {
     652              :         /* prepare the new feature */
     653              :         data_feature_t new_feature;
     654            1 :         data_feature_copy( &new_feature, &old_feature );
     655            1 :         data_feature_set_key( &new_feature, new_feature_key );
     656              :         /* store the change of the feature to the undo redo list */
     657            1 :         ctrl_undo_redo_list_add_update_feature( (*this_).undo_redo_list, &old_feature, &new_feature );
     658            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     659              : 
     660            1 :         data_feature_destroy( &new_feature );
     661            1 :         data_feature_destroy( &old_feature );
     662              :     }
     663              : 
     664            1 :     U8_TRACE_END_ERR( result );
     665            1 :     return result;
     666              : }
     667              : 
     668            2 : u8_error_t ctrl_classifier_controller_update_feature_value ( ctrl_classifier_controller_t *this_,
     669              :                                                              data_row_t feature_id,
     670              :                                                              const char* new_feature_value )
     671              : {
     672            2 :     U8_TRACE_BEGIN();
     673            2 :     u8_error_t result = U8_ERROR_NONE;
     674              :     data_feature_t old_feature;
     675              : 
     676            2 :     result = data_database_writer_update_feature_value( (*this_).db_writer, feature_id, new_feature_value, &old_feature );
     677            2 :     if  (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     678              :     {
     679              :         /* prepare the new feature */
     680              :         data_feature_t new_feature;
     681            2 :         data_feature_copy( &new_feature, &old_feature );
     682            2 :         data_feature_set_value( &new_feature, new_feature_value );
     683              :         /* store the change of the feature to the undo redo list */
     684            2 :         ctrl_undo_redo_list_add_update_feature( (*this_).undo_redo_list, &old_feature, &new_feature );
     685            2 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     686              : 
     687            2 :         data_feature_destroy( &new_feature );
     688            2 :         data_feature_destroy( &old_feature );
     689              :     }
     690              : 
     691            2 :     U8_TRACE_END_ERR( result );
     692            2 :     return result;
     693              : }
     694              : 
     695            1 : u8_error_t ctrl_classifier_controller_update_feature_description ( ctrl_classifier_controller_t *this_,
     696              :                                                                    data_row_t feature_id,
     697              :                                                                    const char* new_feature_description )
     698              : {
     699            1 :     U8_TRACE_BEGIN();
     700            1 :     u8_error_t result = U8_ERROR_NONE;
     701              :     data_feature_t old_feature;
     702              : 
     703            1 :     result = data_database_writer_update_feature_description( (*this_).db_writer, feature_id, new_feature_description, &old_feature );
     704            1 :     if  (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     705              :     {
     706              :         /* prepare the new feature */
     707              :         data_feature_t new_feature;
     708            1 :         data_feature_copy( &new_feature, &old_feature );
     709            1 :         data_feature_set_description( &new_feature, new_feature_description );
     710              :         /* store the change of the feature to the undo redo list */
     711            1 :         ctrl_undo_redo_list_add_update_feature( (*this_).undo_redo_list, &old_feature, &new_feature );
     712            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     713              : 
     714            1 :         data_feature_destroy( &new_feature );
     715            1 :         data_feature_destroy( &old_feature );
     716              :     }
     717              : 
     718            1 :     U8_TRACE_END_ERR( result );
     719            1 :     return result;
     720              : }
     721              : 
     722            1 : u8_error_t ctrl_classifier_controller_update_feature_list_order ( ctrl_classifier_controller_t *this_,
     723              :                                                                   data_row_t feature_id,
     724              :                                                                   int32_t new_feature_list_order )
     725              : {
     726            1 :     U8_TRACE_BEGIN();
     727            1 :     u8_error_t result = U8_ERROR_NONE;
     728              :     data_feature_t old_feature;
     729              : 
     730            1 :     result = data_database_writer_update_feature_list_order( (*this_).db_writer, feature_id, new_feature_list_order, &old_feature );
     731            1 :     if ( U8_ERROR_NONE == result )
     732              :     {
     733              :         /* prepare the new feature */
     734              :         data_feature_t new_feature;
     735            1 :         data_feature_copy( &new_feature, &old_feature );
     736            1 :         data_feature_set_list_order( &new_feature, new_feature_list_order );
     737              :         /* store the change of the feature to the undo redo list */
     738            1 :         ctrl_undo_redo_list_add_update_feature( (*this_).undo_redo_list, &old_feature, &new_feature );
     739            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     740              : 
     741            1 :         data_feature_destroy( &new_feature );
     742            1 :         data_feature_destroy( &old_feature );
     743              :     }
     744              : 
     745            1 :     U8_TRACE_END_ERR( result );
     746            1 :     return result;
     747              : }
     748              : 
     749              : /* ================================ RELATIONSHIP ================================ */
     750              : 
     751           21 : u8_error_t ctrl_classifier_controller_create_relationship ( ctrl_classifier_controller_t *this_,
     752              :                                                             const data_relationship_t *new_relationship,
     753              :                                                             ctrl_undo_redo_action_boundary_t add_to_latest_undo_set,
     754              :                                                             data_row_t* out_new_id )
     755              : {
     756           21 :     U8_TRACE_BEGIN();
     757           21 :     assert( NULL != new_relationship );
     758              :     data_relationship_t to_be_created;
     759           21 :     u8_error_t result = U8_ERROR_NONE;
     760              :     data_row_t new_id;
     761              : 
     762           21 :     data_relationship_copy( &to_be_created, new_relationship );
     763              : 
     764           21 :     result = data_database_writer_create_relationship( (*this_).db_writer, &to_be_created, &new_id );
     765           21 :     if ( U8_ERROR_NONE == result )
     766              :     {
     767              :         /* store new id to data_relationship_t object */
     768           19 :         data_relationship_set_row( &to_be_created, new_id );
     769              : 
     770              :         /* if this action shall be stored to the latest set of actions in the undo redo list, remove the boundary: */
     771           19 :         if ( add_to_latest_undo_set == CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND )
     772              :         {
     773              :             u8_error_t internal_err;
     774            8 :             internal_err = ctrl_undo_redo_list_remove_boundary_from_end( (*this_).undo_redo_list );
     775            8 :             if ( U8_ERROR_NONE != internal_err )
     776              :             {
     777            0 :                 U8_LOG_ERROR_HEX( "unexpected internal error", internal_err );
     778              :             }
     779              :         }
     780              : 
     781              :         /* store the new relationship to the undo redo list */
     782           19 :         ctrl_undo_redo_list_add_create_relationship( (*this_).undo_redo_list, &to_be_created );
     783           19 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     784              : 
     785              :         /* copy new id to out parameter */
     786           19 :         if ( NULL != out_new_id )
     787              :         {
     788           19 :             *out_new_id = new_id;
     789              :         }
     790              :     }
     791              : 
     792              :     /* apply policy rules */
     793           21 :     if ( U8_ERROR_NONE == result )
     794              :     {
     795           19 :         result |= ctrl_classifier_trigger_post_create_relationship ( (*this_).policy_enforcer, &to_be_created );
     796              :     }
     797              : 
     798           21 :     data_relationship_destroy( &to_be_created );
     799              : 
     800           21 :     U8_TRACE_END_ERR( result );
     801           21 :     return result;
     802              : }
     803              : 
     804            7 : u8_error_t ctrl_classifier_controller_delete_relationship ( ctrl_classifier_controller_t *this_,
     805              :                                                             data_row_t obj_id,
     806              :                                                             ctrl_undo_redo_action_boundary_t add_to_latest_undo_set )
     807              : {
     808            7 :     U8_TRACE_BEGIN();
     809            7 :     u8_error_t result = U8_ERROR_NONE;
     810              : 
     811              :     /* delete relationship */
     812              :     data_relationship_t old_relation;
     813            7 :     result = data_database_writer_delete_relationship( (*this_).db_writer, obj_id, &old_relation );
     814              : 
     815            7 :     if ( U8_ERROR_NONE == result )
     816              :     {
     817              :         /* if this action shall be stored to the latest set of actions in the undo redo list, remove the boundary: */
     818            6 :         if ( add_to_latest_undo_set == CTRL_UNDO_REDO_ACTION_BOUNDARY_APPEND )
     819              :         {
     820              :             u8_error_t internal_err;
     821            3 :             internal_err = ctrl_undo_redo_list_remove_boundary_from_end( (*this_).undo_redo_list );
     822            3 :             if ( U8_ERROR_NONE != internal_err )
     823              :             {
     824            0 :                 U8_LOG_ERROR_HEX( "unexpected internal error", internal_err );
     825              :             }
     826              :         }
     827              : 
     828              :         /* store the deleted relationship to the undo redo list */
     829            6 :         ctrl_undo_redo_list_add_delete_relationship( (*this_).undo_redo_list, &old_relation );
     830            6 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     831              : 
     832            6 :         data_relationship_destroy( &old_relation );
     833              :     }
     834              : 
     835            7 :     U8_TRACE_END_ERR( result );
     836            7 :     return result;
     837              : }
     838              : 
     839            1 : u8_error_t ctrl_classifier_controller_update_relationship_main_type ( ctrl_classifier_controller_t *this_,
     840              :                                                                       data_row_t relationship_id,
     841              :                                                                       data_relationship_type_t new_relationship_type )
     842              : {
     843            1 :     U8_TRACE_BEGIN();
     844            1 :     u8_error_t result = U8_ERROR_NONE;
     845              :     data_relationship_t old_relation;
     846              : 
     847            1 :     result = data_database_writer_update_relationship_main_type( (*this_).db_writer, relationship_id, new_relationship_type, &old_relation );
     848            1 :     if ( U8_ERROR_NONE == result )
     849              :     {
     850              :         /* prepare the new relation */
     851              :         data_relationship_t new_relation;
     852            1 :         data_relationship_copy( &new_relation, &old_relation );
     853            1 :         data_relationship_set_main_type( &new_relation, new_relationship_type );
     854              :         /* store the change of the relation to the undo redo list */
     855            1 :         ctrl_undo_redo_list_add_update_relationship( (*this_).undo_redo_list, &old_relation, &new_relation );
     856            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     857              : 
     858            1 :         data_relationship_destroy( &new_relation );
     859            1 :         data_relationship_destroy( &old_relation );
     860              :     }
     861              : 
     862            1 :     U8_TRACE_END_ERR( result );
     863            1 :     return result;
     864              : }
     865              : 
     866            1 : u8_error_t ctrl_classifier_controller_update_relationship_stereotype ( ctrl_classifier_controller_t *this_,
     867              :                                                                        data_row_t relationship_id,
     868              :                                                                        const char* new_relationship_stereotype )
     869              : {
     870            1 :     U8_TRACE_BEGIN();
     871            1 :     u8_error_t result = U8_ERROR_NONE;
     872              :     data_relationship_t old_relation;
     873              : 
     874            1 :     result = data_database_writer_update_relationship_stereotype( (*this_).db_writer, relationship_id, new_relationship_stereotype, &old_relation );
     875            1 :     if  (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     876              :     {
     877              :         /* prepare the new relation */
     878              :         data_relationship_t new_relation;
     879            1 :         data_relationship_copy( &new_relation, &old_relation );
     880            1 :         data_relationship_set_stereotype( &new_relation, new_relationship_stereotype );
     881              :         /* store the change of the relation to the undo redo list */
     882            1 :         ctrl_undo_redo_list_add_update_relationship( (*this_).undo_redo_list, &old_relation, &new_relation );
     883            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     884              : 
     885            1 :         data_relationship_destroy( &new_relation );
     886            1 :         data_relationship_destroy( &old_relation );
     887              :     }
     888              : 
     889            1 :     U8_TRACE_END_ERR( result );
     890            1 :     return result;
     891              : }
     892              : 
     893            1 : u8_error_t ctrl_classifier_controller_update_relationship_name ( ctrl_classifier_controller_t *this_,
     894              :                                                                  data_row_t relationship_id,
     895              :                                                                  const char* new_relationship_name )
     896              : {
     897            1 :     U8_TRACE_BEGIN();
     898            1 :     u8_error_t result = U8_ERROR_NONE;
     899              :     data_relationship_t old_relation;
     900              : 
     901            1 :     result = data_database_writer_update_relationship_name( (*this_).db_writer, relationship_id, new_relationship_name, &old_relation );
     902            1 :     if  (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     903              :     {
     904              :         /* prepare the new relation */
     905              :         data_relationship_t new_relation;
     906            1 :         data_relationship_copy( &new_relation, &old_relation );
     907            1 :         data_relationship_set_name( &new_relation, new_relationship_name );
     908              :         /* store the change of the relation to the undo redo list */
     909            1 :         ctrl_undo_redo_list_add_update_relationship( (*this_).undo_redo_list, &old_relation, &new_relation );
     910            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     911              : 
     912            1 :         data_relationship_destroy( &new_relation );
     913            1 :         data_relationship_destroy( &old_relation );
     914              :     }
     915              : 
     916            1 :     U8_TRACE_END_ERR( result );
     917            1 :     return result;
     918              : }
     919              : 
     920            2 : u8_error_t ctrl_classifier_controller_update_relationship_description ( ctrl_classifier_controller_t *this_,
     921              :                                                                         data_row_t relationship_id,
     922              :                                                                         const char* new_relationship_description )
     923              : {
     924            2 :     U8_TRACE_BEGIN();
     925            2 :     u8_error_t result = U8_ERROR_NONE;
     926              :     data_relationship_t old_relation;
     927              : 
     928            2 :     result = data_database_writer_update_relationship_description( (*this_).db_writer, relationship_id, new_relationship_description, &old_relation );
     929            2 :     if  (( U8_ERROR_NONE == result ) || ( U8_ERROR_STRING_BUFFER_EXCEEDED == result ))
     930              :     {
     931              :         /* prepare the new relation */
     932              :         data_relationship_t new_relation;
     933            2 :         data_relationship_copy( &new_relation, &old_relation );
     934            2 :         data_relationship_set_description( &new_relation, new_relationship_description );
     935              :         /* store the change of the relation to the undo redo list */
     936            2 :         ctrl_undo_redo_list_add_update_relationship( (*this_).undo_redo_list, &old_relation, &new_relation );
     937            2 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     938              : 
     939            2 :         data_relationship_destroy( &new_relation );
     940            2 :         data_relationship_destroy( &old_relation );
     941              :     }
     942              : 
     943            2 :     U8_TRACE_END_ERR( result );
     944            2 :     return result;
     945              : }
     946              : 
     947            1 : u8_error_t ctrl_classifier_controller_update_relationship_list_order ( ctrl_classifier_controller_t *this_,
     948              :                                                                        data_row_t relationship_id,
     949              :                                                                        int32_t new_relationship_list_order )
     950              : {
     951            1 :     U8_TRACE_BEGIN();
     952            1 :     u8_error_t result = U8_ERROR_NONE;
     953              :     data_relationship_t old_relation;
     954              : 
     955            1 :     result = data_database_writer_update_relationship_list_order( (*this_).db_writer, relationship_id, new_relationship_list_order, &old_relation );
     956            1 :     if ( U8_ERROR_NONE == result )
     957              :     {
     958              :         /* prepare the new relation */
     959              :         data_relationship_t new_relation;
     960            1 :         data_relationship_copy( &new_relation, &old_relation );
     961            1 :         data_relationship_set_list_order( &new_relation, new_relationship_list_order );
     962              :         /* store the change of the relation to the undo redo list */
     963            1 :         ctrl_undo_redo_list_add_update_relationship( (*this_).undo_redo_list, &old_relation, &new_relation );
     964            1 :         ctrl_undo_redo_list_add_boundary( (*this_).undo_redo_list );
     965              : 
     966            1 :         data_relationship_destroy( &new_relation );
     967            1 :         data_relationship_destroy( &old_relation );
     968              :     }
     969              : 
     970            1 :     U8_TRACE_END_ERR( result );
     971            1 :     return result;
     972              : }
     973              : 
     974              : 
     975              : /*
     976              : Copyright 2016-2026 Andreas Warnke
     977              : 
     978              : Licensed under the Apache License, Version 2.0 (the "License");
     979              : you may not use this file except in compliance with the License.
     980              : You may obtain a copy of the License at
     981              : 
     982              :     http://www.apache.org/licenses/LICENSE-2.0
     983              : 
     984              : Unless required by applicable law or agreed to in writing, software
     985              : distributed under the License is distributed on an "AS IS" BASIS,
     986              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     987              : See the License for the specific language governing permissions and
     988              : limitations under the License.
     989              : */
        

Generated by: LCOV version 2.0-1