LCOV - code coverage report
Current view: top level - ctrl/source - ctrl_classifier_controller.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.62.0_covts Lines: 371 427 86.9 %
Date: 2024-12-21 18:34:41 Functions: 24 26 92.3 %

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