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

Generated by: LCOV version 2.0-1