LCOV - code coverage report
Current view: top level - data/source/storage - data_database_writer.c (source / functions) Coverage Total Hit
Test: crystal-facet-uml_v1.63.2_covts Lines: 98.4 % 570 561
Test Date: 2025-05-01 10:10:14 Functions: 100.0 % 38 38

            Line data    Source code
       1              : /* File: data_database_writer.c; Copyright and License: see below */
       2              : 
       3              : #include "storage/data_database_writer.h"
       4              : #include "entity/data_id.h"
       5              : #include "u8/u8_trace.h"
       6              : #include "u8/u8_log.h"
       7              : #include <sqlite3.h>
       8              : #include <assert.h>
       9              : 
      10           70 : void data_database_writer_init ( data_database_writer_t *this_, data_database_reader_t *db_reader, data_database_t *database )
      11              : {
      12           70 :     U8_TRACE_BEGIN();
      13           70 :     assert( NULL != db_reader );
      14           70 :     assert( NULL != database );
      15              : 
      16           70 :     (*this_).database = database;
      17           70 :     (*this_).db_reader = db_reader;
      18              : 
      19           70 :     data_database_sql_builder_init( &((*this_).sql_builder) );
      20              : 
      21           70 :     data_database_listener_init ( &((*this_).me_as_listener), this_, (void (*)(void*,data_database_listener_signal_t)) &data_database_writer_db_change_callback );
      22           70 :     data_database_add_db_listener( database, &((*this_).me_as_listener) );
      23              : 
      24           70 :     U8_TRACE_END();
      25           70 : }
      26              : 
      27           70 : void data_database_writer_destroy ( data_database_writer_t *this_ )
      28              : {
      29           70 :     U8_TRACE_BEGIN();
      30              : 
      31           70 :     data_database_remove_db_listener( (*this_).database, &((*this_).me_as_listener) );
      32              : 
      33           70 :     data_database_sql_builder_destroy( &((*this_).sql_builder) );
      34              : 
      35           70 :     (*this_).db_reader = NULL;
      36           70 :     (*this_).database = NULL;
      37              : 
      38           70 :     U8_TRACE_END();
      39           70 : }
      40              : 
      41            9 : void data_database_writer_db_change_callback ( data_database_writer_t *this_, data_database_listener_signal_t signal_id )
      42              : {
      43            9 :     U8_TRACE_BEGIN();
      44              : 
      45            9 :     switch ( signal_id )
      46              :     {
      47            4 :         case DATA_DATABASE_LISTENER_SIGNAL_PREPARE_CLOSE:
      48              :         {
      49            4 :             U8_TRACE_INFO( "DATA_DATABASE_LISTENER_SIGNAL_PREPARE_CLOSE" );
      50              :         }
      51            4 :         break;
      52              : 
      53            5 :         case DATA_DATABASE_LISTENER_SIGNAL_DB_OPENED:
      54              :         {
      55            5 :             U8_TRACE_INFO( "DATA_DATABASE_LISTENER_SIGNAL_DB_OPENED" );
      56              :         }
      57            5 :         break;
      58              : 
      59            0 :         default:
      60              :         {
      61            0 :             U8_LOG_ERROR( "unexpected data_database_listener_signal_t" );
      62              :         }
      63              :     }
      64              : 
      65            9 :     U8_TRACE_END();
      66            9 : }
      67              : 
      68              : /* ================================ DIAGRAM ================================ */
      69              : 
      70          200 : u8_error_t data_database_writer_create_diagram ( data_database_writer_t *this_,
      71              :                                                  const data_diagram_t *diagram,
      72              :                                                  data_row_t* out_new_id )
      73              : {
      74          200 :     U8_TRACE_BEGIN();
      75          200 :     assert( NULL != diagram );
      76          200 :     u8_error_t result = U8_ERROR_NONE;
      77          200 :     data_row_t new_id = DATA_ROW_VOID;
      78              : 
      79          200 :     result |= data_database_sql_builder_build_create_diagram_command( &((*this_).sql_builder), diagram );
      80          200 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
      81              : 
      82          200 :     result |= data_database_transaction_begin ( (*this_).database );
      83          200 :     result |= data_database_in_transaction_create( (*this_).database, sql_cmd, &new_id );
      84          200 :     result |= data_database_transaction_commit ( (*this_).database );
      85              : 
      86          200 :     U8_LOG_EVENT_INT( "sqlite3_exec: INSERT INTO diagrams ... ->", new_id );  /* do not log confidential information, only id */
      87              : 
      88              :     /* notify listeners */
      89              :     data_row_t parent_id;
      90          200 :     parent_id = data_diagram_get_parent_row_id( diagram );
      91          200 :     data_change_notifier_emit_signal( data_database_get_notifier_ptr( (*this_).database ),
      92              :                                       DATA_CHANGE_EVENT_TYPE_CREATE,
      93              :                                       DATA_TABLE_DIAGRAM,
      94              :                                       new_id,
      95              :                                       DATA_TABLE_DIAGRAM,
      96              :                                       parent_id
      97              :                                     );
      98              : 
      99          200 :     if ( NULL != out_new_id )
     100              :     {
     101          170 :         *out_new_id = new_id;
     102              :     }
     103              : 
     104          200 :     U8_TRACE_END_ERR( result );
     105          200 :     return result;
     106              : }
     107              : 
     108          134 : u8_error_t data_database_writer_delete_diagram( data_database_writer_t *this_,
     109              :                                                 data_row_t obj_id,
     110              :                                                 data_diagram_t *out_old_diagram )
     111              : {
     112          134 :     U8_TRACE_BEGIN();
     113          134 :     u8_error_t result = U8_ERROR_NONE;
     114          134 :     result |= data_database_transaction_begin ( (*this_).database );
     115              : 
     116              :     /* Note: out_old_diagram is NULL if old data shall not be returned */
     117          134 :     if ( NULL != out_old_diagram )
     118              :     {
     119            3 :         result |= data_database_reader_get_diagram_by_id ( (*this_).db_reader, obj_id, out_old_diagram );
     120              :     }
     121              : 
     122              :     /* Note: This function fails if the diagram is still referenced. */
     123              :     data_diagram_iterator_t diagram_iterator;
     124          134 :     result |= data_diagram_iterator_init_empty( &diagram_iterator );
     125          134 :     result |= data_database_reader_get_diagrams_by_parent_id( (*this_).db_reader, obj_id, &diagram_iterator );
     126          134 :     const bool has_child_diagrams = data_diagram_iterator_has_next( &diagram_iterator );
     127          134 :     result |= data_diagram_iterator_destroy( &diagram_iterator );
     128              : 
     129              :     data_diagramelement_iterator_t diagramelement_iterator;
     130          134 :     result |= data_diagramelement_iterator_init_empty( &diagramelement_iterator );
     131          134 :     result |= data_database_reader_get_diagramelements_by_diagram_id( (*this_).db_reader,
     132              :                                                                       obj_id,
     133              :                                                                       &diagramelement_iterator
     134              :                                                                     );
     135          134 :     const bool has_elements = data_diagramelement_iterator_has_next( &diagramelement_iterator );
     136          134 :     result |= data_diagramelement_iterator_destroy( &diagramelement_iterator );
     137              : 
     138          134 :     if ( has_child_diagrams || has_elements )
     139              :     {
     140            1 :         result |= U8_ERROR_OBJECT_STILL_REFERENCED;
     141              :     }
     142              :     else
     143              :     {
     144          133 :         result |= data_database_sql_builder_build_delete_diagram_command ( &((*this_).sql_builder), obj_id );
     145          133 :         char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     146          133 :         result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     147          133 :         U8_LOG_EVENT_INT( "sqlite3_exec: DELETE FROM diagrams ... ->", obj_id );  /* do not log confidential information, only id */
     148              :     }
     149              : 
     150          134 :     result |= data_database_transaction_commit ( (*this_).database );
     151              : 
     152              :     /* notify listeners */
     153          134 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     154              :                                                      DATA_CHANGE_EVENT_TYPE_DELETE,
     155              :                                                      DATA_TABLE_DIAGRAM,
     156              :                                                      obj_id
     157              :                                                    );
     158              : 
     159          134 :     U8_TRACE_END_ERR( result );
     160          134 :     return result;
     161              : }
     162              : 
     163            9 : u8_error_t data_database_writer_update_diagram_type ( data_database_writer_t *this_,
     164              :                                                       data_row_t diagram_id,
     165              :                                                       data_diagram_type_t new_diagram_type,
     166              :                                                       data_diagram_t *out_old_diagram )
     167              : {
     168            9 :     U8_TRACE_BEGIN();
     169            9 :     u8_error_t result = U8_ERROR_NONE;
     170              : 
     171            9 :     result |= data_database_transaction_begin ( (*this_).database );
     172              : 
     173              :     /* Note: out_old_diagram is NULL if old data shall not be returned */
     174            9 :     if ( NULL != out_old_diagram )
     175              :     {
     176            5 :         result |= data_database_reader_get_diagram_by_id ( (*this_).db_reader, diagram_id, out_old_diagram );
     177              :     }
     178              : 
     179            9 :     result |= data_database_sql_builder_build_update_diagram_type_cmd( &((*this_).sql_builder), diagram_id, new_diagram_type );
     180            9 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     181              : 
     182            9 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     183            9 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE diagrams SET diagram_type ... ->", diagram_id );  /* do not log confidential information, only id */
     184              : 
     185            9 :     result |= data_database_transaction_commit ( (*this_).database );
     186              : 
     187              :     /* notify listeners */
     188            9 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     189              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     190              :                                                      DATA_TABLE_DIAGRAM,
     191              :                                                      diagram_id
     192              :                                                    );
     193              : 
     194            9 :     U8_TRACE_END_ERR( result );
     195            9 :     return result;
     196              : }
     197              : 
     198            4 : u8_error_t data_database_writer_update_diagram_stereotype ( data_database_writer_t *this_,
     199              :                                                             data_row_t diagram_id,
     200              :                                                             const char* new_diagram_stereotype,
     201              :                                                             data_diagram_t *out_old_diagram )
     202              : {
     203            4 :     U8_TRACE_BEGIN();
     204            4 :     assert( NULL != new_diagram_stereotype );
     205            4 :     u8_error_t result = U8_ERROR_NONE;
     206              : 
     207            4 :     result |= data_database_transaction_begin ( (*this_).database );
     208              : 
     209              :     /* Note: out_old_diagram is NULL if old data shall not be returned */
     210            4 :     if ( NULL != out_old_diagram )
     211              :     {
     212            0 :         result |= data_database_reader_get_diagram_by_id ( (*this_).db_reader, diagram_id, out_old_diagram );
     213              :     }
     214              : 
     215            4 :     result |= data_database_sql_builder_build_update_diagram_stereotype_cmd( &((*this_).sql_builder), diagram_id, new_diagram_stereotype );
     216            4 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     217              : 
     218            4 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     219            4 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE diagrams SET stereotype ... ->", diagram_id );  /* do not log confidential information, only id */
     220              : 
     221            4 :     result |= data_database_transaction_commit ( (*this_).database );
     222              : 
     223              :     /* notify listeners */
     224            4 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     225              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     226              :                                                      DATA_TABLE_DIAGRAM,
     227              :                                                      diagram_id
     228              :                                                    );
     229              : 
     230            4 :     U8_TRACE_END_ERR( result );
     231            4 :     return result;
     232              : }
     233              : 
     234            6 : u8_error_t data_database_writer_update_diagram_name ( data_database_writer_t *this_,
     235              :                                                       data_row_t diagram_id,
     236              :                                                       const char* new_diagram_name,
     237              :                                                       data_diagram_t *out_old_diagram )
     238              : {
     239            6 :     U8_TRACE_BEGIN();
     240            6 :     assert( NULL != new_diagram_name );
     241            6 :     u8_error_t result = U8_ERROR_NONE;
     242              : 
     243            6 :     result |= data_database_transaction_begin ( (*this_).database );
     244              : 
     245              :     /* Note: out_old_diagram is NULL if old data shall not be returned */
     246            6 :     if ( NULL != out_old_diagram )
     247              :     {
     248            2 :         result |= data_database_reader_get_diagram_by_id ( (*this_).db_reader, diagram_id, out_old_diagram );
     249              :     }
     250              : 
     251            6 :     result |= data_database_sql_builder_build_update_diagram_name_cmd( &((*this_).sql_builder), diagram_id, new_diagram_name );
     252            6 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     253              : 
     254            6 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     255            6 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE diagrams SET name ... ->", diagram_id );  /* do not log confidential information, only id */
     256              : 
     257            6 :     result |= data_database_transaction_commit ( (*this_).database );
     258              : 
     259              :     /* notify listeners */
     260            6 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     261              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     262              :                                                      DATA_TABLE_DIAGRAM,
     263              :                                                      diagram_id
     264              :                                                    );
     265              : 
     266            6 :     U8_TRACE_END_ERR( result );
     267            6 :     return result;
     268              : }
     269              : 
     270            5 : u8_error_t data_database_writer_update_diagram_description ( data_database_writer_t *this_,
     271              :                                                              data_row_t diagram_id,
     272              :                                                              const char* new_diagram_description,
     273              :                                                              data_diagram_t *out_old_diagram )
     274              : {
     275            5 :     U8_TRACE_BEGIN();
     276            5 :     assert( NULL != new_diagram_description );
     277            5 :     u8_error_t result = U8_ERROR_NONE;
     278              : 
     279            5 :     result |= data_database_transaction_begin ( (*this_).database );
     280              : 
     281              :     /* Note: out_old_diagram is NULL if old data shall not be returned */
     282            5 :     if ( NULL != out_old_diagram )
     283              :     {
     284            1 :         result |= data_database_reader_get_diagram_by_id ( (*this_).db_reader, diagram_id, out_old_diagram );
     285              :     }
     286              : 
     287            5 :     result |= data_database_sql_builder_build_update_diagram_description_cmd( &((*this_).sql_builder), diagram_id, new_diagram_description );
     288            5 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     289              : 
     290            5 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     291            5 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE diagrams SET description ... ->", diagram_id );  /* do not log confidential information, only id */
     292              : 
     293            5 :     result |= data_database_transaction_commit ( (*this_).database );
     294              : 
     295              :     /* notify listeners */
     296            5 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     297              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     298              :                                                      DATA_TABLE_DIAGRAM,
     299              :                                                      diagram_id
     300              :                                                    );
     301              : 
     302            5 :     U8_TRACE_END_ERR( result );
     303            5 :     return result;
     304              : }
     305              : 
     306            5 : u8_error_t data_database_writer_update_diagram_list_order ( data_database_writer_t *this_,
     307              :                                                             data_row_t diagram_id,
     308              :                                                             int32_t new_diagram_list_order,
     309              :                                                             data_diagram_t *out_old_diagram )
     310              : {
     311            5 :     U8_TRACE_BEGIN();
     312            5 :     u8_error_t result = U8_ERROR_NONE;
     313              : 
     314            5 :     result |= data_database_transaction_begin ( (*this_).database );
     315              : 
     316              :     /* Note: out_old_diagram is NULL if old data shall not be returned */
     317            5 :     if ( NULL != out_old_diagram )
     318              :     {
     319            1 :         result |= data_database_reader_get_diagram_by_id ( (*this_).db_reader, diagram_id, out_old_diagram );
     320              :     }
     321              : 
     322            5 :     result |= data_database_sql_builder_build_update_diagram_list_order_cmd( &((*this_).sql_builder), diagram_id, new_diagram_list_order );
     323            5 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     324              : 
     325            5 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     326            5 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE diagrams SET list_order ... ->", diagram_id );  /* do not log confidential information, only id */
     327              : 
     328            5 :     result |= data_database_transaction_commit ( (*this_).database );
     329              : 
     330              :     /* notify listeners */
     331            5 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     332              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     333              :                                                      DATA_TABLE_DIAGRAM,
     334              :                                                      diagram_id
     335              :                                                    );
     336              : 
     337            5 :     U8_TRACE_END_ERR( result );
     338            5 :     return result;
     339              : }
     340              : 
     341            9 : u8_error_t data_database_writer_update_diagram_parent_id ( data_database_writer_t *this_,
     342              :                                                            data_row_t diagram_id,
     343              :                                                            data_row_t new_diagram_parent_id,
     344              :                                                            data_diagram_t *out_old_diagram )
     345              : {
     346            9 :     U8_TRACE_BEGIN();
     347            9 :     u8_error_t result = U8_ERROR_NONE;
     348              : 
     349            9 :     result |= data_database_transaction_begin ( (*this_).database );
     350              : 
     351              :     /* Note: out_old_diagram is NULL if old data shall not be returned */
     352            9 :     if ( NULL != out_old_diagram )
     353              :     {
     354            0 :         result |= data_database_reader_get_diagram_by_id ( (*this_).db_reader, diagram_id, out_old_diagram );
     355              :     }
     356              : 
     357            9 :     result |= data_database_sql_builder_build_update_diagram_parent_id_cmd( &((*this_).sql_builder), diagram_id, new_diagram_parent_id );
     358            9 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     359              : 
     360            9 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     361            9 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE diagrams SET parent_id ... ->", diagram_id );  /* do not log confidential information, only id */
     362              : 
     363            9 :     result |= data_database_transaction_commit ( (*this_).database );
     364              : 
     365              :     /* notify listeners */
     366            9 :     data_change_notifier_emit_signal( data_database_get_notifier_ptr( (*this_).database ),
     367              :                                       DATA_CHANGE_EVENT_TYPE_UPDATE,
     368              :                                       DATA_TABLE_DIAGRAM,
     369              :                                       diagram_id,
     370              :                                       DATA_TABLE_DIAGRAM,
     371              :                                       new_diagram_parent_id
     372              :                                     );
     373              : 
     374            9 :     U8_TRACE_END_ERR( result );
     375            9 :     return result;
     376              : }
     377              : 
     378              : /* ================================ CLASSIFIER ================================ */
     379              : 
     380          246 : u8_error_t data_database_writer_create_classifier( data_database_writer_t *this_,
     381              :                                                    const data_classifier_t *classifier,
     382              :                                                    data_row_t* out_new_id )
     383              : {
     384          246 :     U8_TRACE_BEGIN();
     385          246 :     assert( NULL != classifier );
     386          246 :     u8_error_t result = U8_ERROR_NONE;
     387          246 :     data_row_t new_id = DATA_ROW_VOID;
     388              : 
     389          246 :     result |= data_database_sql_builder_build_create_classifier_command( &((*this_).sql_builder), classifier );
     390          246 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     391              : 
     392          246 :     result |= data_database_transaction_begin ( (*this_).database );
     393          246 :     result |= data_database_in_transaction_create( (*this_).database, sql_cmd, &new_id );
     394          246 :     result |= data_database_transaction_commit ( (*this_).database );
     395          246 :     U8_LOG_EVENT_INT( "sqlite3_exec: INSERT INTO classifiers ... ->", new_id );  /* do not log confidential information, only id */
     396              : 
     397              :     /* notify listeners */
     398          246 :     data_change_notifier_emit_signal( data_database_get_notifier_ptr( (*this_).database ),
     399              :                                       DATA_CHANGE_EVENT_TYPE_CREATE,
     400              :                                       DATA_TABLE_CLASSIFIER,
     401              :                                       new_id,
     402              :                                       DATA_TABLE_VOID,  /* classifiers have no parent */
     403              :                                       DATA_ROW_VOID  /* classifiers have no parent */
     404              :                                     );
     405              : 
     406          246 :     if ( NULL != out_new_id )
     407              :     {
     408          219 :         *out_new_id = new_id;
     409              :     }
     410              : 
     411          246 :     U8_TRACE_END_ERR( result );
     412          246 :     return result;
     413              : }
     414              : 
     415            4 : u8_error_t data_database_writer_delete_classifier( data_database_writer_t *this_,
     416              :                                                    data_row_t obj_id,
     417              :                                                    data_classifier_t *out_old_classifier )
     418              : {
     419            4 :     U8_TRACE_BEGIN();
     420            4 :     u8_error_t result = U8_ERROR_NONE;
     421              :     bool object_still_referenced;
     422              : 
     423            4 :     result |= data_database_transaction_begin ( (*this_).database );
     424              : 
     425              :     /* Note: out_old_classifier is NULL if old data shall not be returned */
     426            4 :     if ( NULL != out_old_classifier )
     427              :     {
     428            3 :         result |= data_database_reader_get_classifier_by_id ( (*this_).db_reader, obj_id, out_old_classifier );
     429              :     }
     430              : 
     431              :     /* Note: This function fails if the classifier is still referenced. */
     432              :     data_diagram_iterator_t diagram_iterator;
     433            4 :     result |= data_diagram_iterator_init_empty( &diagram_iterator );
     434            4 :     result |= data_database_reader_get_diagrams_by_classifier_id ( (*this_).db_reader, obj_id, &diagram_iterator );
     435            4 :     const bool has_occurrences = data_diagram_iterator_has_next( &diagram_iterator );
     436            4 :     result |= data_diagram_iterator_destroy( &diagram_iterator );
     437              : 
     438            4 :     if ( has_occurrences )
     439              :     {
     440            0 :         object_still_referenced = true;
     441              :     }
     442              :     else
     443              :     {
     444              :         data_feature_iterator_t feature_iterator;
     445            4 :         result |= data_feature_iterator_init_empty( &feature_iterator );
     446            4 :         result |= data_database_reader_get_features_by_classifier_id ( (*this_).db_reader, obj_id, &feature_iterator );
     447            4 :         const bool has_next_feature = data_feature_iterator_has_next( &feature_iterator );
     448            4 :         result |= data_feature_iterator_destroy( &feature_iterator );
     449            4 :         if ( has_next_feature )
     450              :         {
     451            0 :             object_still_referenced = true;
     452              :         }
     453              :         else
     454              :         {
     455              :             data_relationship_iterator_t rel_iterator;
     456            4 :             result |= data_relationship_iterator_init_empty( &rel_iterator );
     457            4 :             result |= data_database_reader_get_relationships_by_classifier_id ( (*this_).db_reader, obj_id, &rel_iterator );
     458            4 :             const bool has_next_rel = data_relationship_iterator_has_next( &rel_iterator );
     459            4 :             result |= data_relationship_iterator_destroy( &rel_iterator );
     460            4 :             if ( has_next_rel )
     461              :             {
     462            0 :                 object_still_referenced = true;
     463              :             }
     464              :             else
     465              :             {
     466            4 :                 object_still_referenced = false;
     467              :             }
     468              :         }
     469              :     }
     470              : 
     471            4 :     if ( object_still_referenced )
     472              :     {
     473            0 :         result |= U8_ERROR_OBJECT_STILL_REFERENCED;
     474              :     }
     475              :     else
     476              :     {
     477            4 :         result |= data_database_sql_builder_build_delete_classifier_command ( &((*this_).sql_builder), obj_id );
     478            4 :         char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     479            4 :         result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     480            4 :         U8_LOG_EVENT_INT( "sqlite3_exec: DELETE FROM classifiers ... ->", obj_id );  /* do not log confidential information, only id */
     481              :     }
     482              : 
     483            4 :     result |= data_database_transaction_commit ( (*this_).database );
     484              : 
     485              :     /* notify listeners */
     486            4 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     487              :                                                      DATA_CHANGE_EVENT_TYPE_DELETE,
     488              :                                                      DATA_TABLE_CLASSIFIER,
     489              :                                                      obj_id
     490              :                                                    );
     491              : 
     492            4 :     U8_TRACE_END_ERR( result );
     493            4 :     return result;
     494              : }
     495              : 
     496            3 : u8_error_t data_database_writer_update_classifier_main_type ( data_database_writer_t *this_,
     497              :                                                               data_row_t classifier_id,
     498              :                                                               data_classifier_type_t new_classifier_main_type,
     499              :                                                               data_classifier_t *out_old_classifier )
     500              : {
     501            3 :     U8_TRACE_BEGIN();
     502            3 :     u8_error_t result = U8_ERROR_NONE;
     503              : 
     504            3 :     result |= data_database_transaction_begin ( (*this_).database );
     505              : 
     506              :     /* Note: out_old_classifier is NULL if old data shall not be returned */
     507            3 :     if ( NULL != out_old_classifier )
     508              :     {
     509            1 :         result |= data_database_reader_get_classifier_by_id ( (*this_).db_reader, classifier_id, out_old_classifier );
     510              :     }
     511              : 
     512            3 :     result |= data_database_sql_builder_build_update_classifier_main_type_cmd( &((*this_).sql_builder), classifier_id, new_classifier_main_type );
     513            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     514              : 
     515            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     516            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE classifiers SET main_type ... ->", classifier_id );  /* do not log confidential information, only id */
     517              : 
     518            3 :     result |= data_database_transaction_commit ( (*this_).database );
     519              : 
     520              :     /* notify listeners */
     521            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     522              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     523              :                                                      DATA_TABLE_CLASSIFIER,
     524              :                                                      classifier_id
     525              :                                                    );
     526              : 
     527            3 :     U8_TRACE_END_ERR( result );
     528            3 :     return result;
     529              : }
     530              : 
     531            4 : u8_error_t data_database_writer_update_classifier_stereotype ( data_database_writer_t *this_,
     532              :                                                                data_row_t classifier_id,
     533              :                                                                const char* new_classifier_stereotype,
     534              :                                                                data_classifier_t *out_old_classifier )
     535              : {
     536            4 :     U8_TRACE_BEGIN();
     537            4 :     u8_error_t result = U8_ERROR_NONE;
     538              : 
     539            4 :     result |= data_database_transaction_begin ( (*this_).database );
     540              : 
     541              :     /* Note: out_old_classifier is NULL if old data shall not be returned */
     542            4 :     if ( NULL != out_old_classifier )
     543              :     {
     544            2 :         result |= data_database_reader_get_classifier_by_id ( (*this_).db_reader, classifier_id, out_old_classifier );
     545              :     }
     546              : 
     547            4 :     result |= data_database_sql_builder_build_update_classifier_stereotype_cmd( &((*this_).sql_builder), classifier_id, new_classifier_stereotype );
     548            4 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     549              : 
     550            4 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     551            4 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE classifiers SET stereotype ... ->", classifier_id );  /* do not log confidential information, only id */
     552              : 
     553            4 :     result |= data_database_transaction_commit ( (*this_).database );
     554              : 
     555              :     /* notify listeners */
     556            4 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     557              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     558              :                                                      DATA_TABLE_CLASSIFIER,
     559              :                                                      classifier_id
     560              :                                                    );
     561              : 
     562            4 :     U8_TRACE_END_ERR( result );
     563            4 :     return result;
     564              : }
     565              : 
     566            3 : u8_error_t data_database_writer_update_classifier_name ( data_database_writer_t *this_,
     567              :                                                          data_row_t classifier_id,
     568              :                                                          const char* new_classifier_name,
     569              :                                                          data_classifier_t *out_old_classifier )
     570              : {
     571            3 :     U8_TRACE_BEGIN();
     572            3 :     u8_error_t result = U8_ERROR_NONE;
     573              : 
     574            3 :     result |= data_database_transaction_begin ( (*this_).database );
     575              : 
     576              :     /* Note: out_old_classifier is NULL if old data shall not be returned */
     577            3 :     if ( NULL != out_old_classifier )
     578              :     {
     579            1 :         result |= data_database_reader_get_classifier_by_id ( (*this_).db_reader, classifier_id, out_old_classifier );
     580              :     }
     581              : 
     582            3 :     result |= data_database_sql_builder_build_update_classifier_name_cmd( &((*this_).sql_builder), classifier_id, new_classifier_name );
     583            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     584              : 
     585            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     586            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE classifiers SET name ... ->", classifier_id );  /* do not log confidential information, only id */
     587              : 
     588            3 :     result |= data_database_transaction_commit ( (*this_).database );
     589              : 
     590              :     /* notify listeners */
     591            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     592              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     593              :                                                      DATA_TABLE_CLASSIFIER,
     594              :                                                      classifier_id
     595              :                                                    );
     596              : 
     597            3 :     U8_TRACE_END_ERR( result );
     598            3 :     return result;
     599              : }
     600              : 
     601            3 : u8_error_t data_database_writer_update_classifier_description ( data_database_writer_t *this_,
     602              :                                                                 data_row_t classifier_id,
     603              :                                                                 const char* new_classifier_description,
     604              :                                                                 data_classifier_t *out_old_classifier )
     605              : {
     606            3 :     U8_TRACE_BEGIN();
     607            3 :     u8_error_t result = U8_ERROR_NONE;
     608              : 
     609            3 :     result |= data_database_transaction_begin ( (*this_).database );
     610              : 
     611              :     /* Note: out_old_classifier is NULL if old data shall not be returned */
     612            3 :     if ( NULL != out_old_classifier )
     613              :     {
     614            1 :         result |= data_database_reader_get_classifier_by_id ( (*this_).db_reader, classifier_id, out_old_classifier );
     615              :     }
     616              : 
     617            3 :     result |= data_database_sql_builder_build_update_classifier_description_cmd( &((*this_).sql_builder), classifier_id, new_classifier_description );
     618            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     619              : 
     620            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     621            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE classifiers SET description ... ->", classifier_id );  /* do not log confidential information, only id */
     622              : 
     623            3 :     result |= data_database_transaction_commit ( (*this_).database );
     624              : 
     625              :     /* notify listeners */
     626            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     627              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     628              :                                                      DATA_TABLE_CLASSIFIER,
     629              :                                                      classifier_id
     630              :                                                    );
     631              : 
     632            3 :     U8_TRACE_END_ERR( result );
     633            3 :     return result;
     634              : }
     635              : 
     636            3 : u8_error_t data_database_writer_update_classifier_x_order ( data_database_writer_t *this_,
     637              :                                                             data_row_t classifier_id,
     638              :                                                             int32_t new_classifier_x_order,
     639              :                                                             data_classifier_t *out_old_classifier )
     640              : {
     641            3 :     U8_TRACE_BEGIN();
     642            3 :     u8_error_t result = U8_ERROR_NONE;
     643              : 
     644            3 :     result |= data_database_transaction_begin ( (*this_).database );
     645              : 
     646              :     /* Note: out_old_classifier is NULL if old data shall not be returned */
     647            3 :     if ( NULL != out_old_classifier )
     648              :     {
     649            1 :         result |= data_database_reader_get_classifier_by_id ( (*this_).db_reader, classifier_id, out_old_classifier );
     650              :     }
     651              : 
     652            3 :     result |= data_database_sql_builder_build_update_classifier_x_order_cmd( &((*this_).sql_builder), classifier_id, new_classifier_x_order );
     653            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     654              : 
     655            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     656            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE classifiers SET x_order ... ->", classifier_id );  /* do not log confidential information, only id */
     657              : 
     658            3 :     result |= data_database_transaction_commit ( (*this_).database );
     659              : 
     660              :     /* notify listeners */
     661            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     662              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     663              :                                                      DATA_TABLE_CLASSIFIER,
     664              :                                                      classifier_id
     665              :                                                    );
     666              : 
     667            3 :     U8_TRACE_END_ERR( result );
     668            3 :     return result;
     669              : }
     670              : 
     671            3 : u8_error_t data_database_writer_update_classifier_y_order ( data_database_writer_t *this_,
     672              :                                                             data_row_t classifier_id,
     673              :                                                             int32_t new_classifier_y_order,
     674              :                                                             data_classifier_t *out_old_classifier )
     675              : {
     676            3 :     U8_TRACE_BEGIN();
     677            3 :     u8_error_t result = U8_ERROR_NONE;
     678              : 
     679            3 :     result |= data_database_transaction_begin ( (*this_).database );
     680              : 
     681              :     /* Note: out_old_classifier is NULL if old data shall not be returned */
     682            3 :     if ( NULL != out_old_classifier )
     683              :     {
     684            1 :         result |= data_database_reader_get_classifier_by_id ( (*this_).db_reader, classifier_id, out_old_classifier );
     685              :     }
     686              : 
     687            3 :     result |= data_database_sql_builder_build_update_classifier_y_order_cmd( &((*this_).sql_builder), classifier_id, new_classifier_y_order );
     688            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     689              : 
     690            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     691            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE classifiers SET y_order ... ->", classifier_id );  /* do not log confidential information, only id */
     692              : 
     693            3 :     result |= data_database_transaction_commit ( (*this_).database );
     694              : 
     695              :     /* notify listeners */
     696            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     697              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     698              :                                                      DATA_TABLE_CLASSIFIER,
     699              :                                                      classifier_id
     700              :                                                    );
     701              : 
     702            3 :     U8_TRACE_END_ERR( result );
     703            3 :     return result;
     704              : }
     705              : 
     706            2 : u8_error_t data_database_writer_update_classifier_list_order ( data_database_writer_t *this_,
     707              :                                                                data_row_t classifier_id,
     708              :                                                                int32_t new_classifier_list_order,
     709              :                                                                data_classifier_t *out_old_classifier )
     710              : {
     711            2 :     U8_TRACE_BEGIN();
     712            2 :     u8_error_t result = U8_ERROR_NONE;
     713              : 
     714            2 :     result |= data_database_transaction_begin ( (*this_).database );
     715              : 
     716              :     /* Note: out_old_classifier is NULL if old data shall not be returned */
     717            2 :     if ( NULL != out_old_classifier )
     718              :     {
     719            0 :         result |= data_database_reader_get_classifier_by_id ( (*this_).db_reader, classifier_id, out_old_classifier );
     720              :     }
     721              : 
     722            2 :     result |= data_database_sql_builder_build_update_classifier_list_order_cmd( &((*this_).sql_builder), classifier_id, new_classifier_list_order );
     723            2 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     724              : 
     725            2 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     726            2 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE classifiers SET list_order ... ->", classifier_id );  /* do not log confidential information, only id */
     727              : 
     728            2 :     result |= data_database_transaction_commit ( (*this_).database );
     729              : 
     730              :     /* notify listeners */
     731            2 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     732              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     733              :                                                      DATA_TABLE_CLASSIFIER,
     734              :                                                      classifier_id
     735              :     );
     736              : 
     737            2 :     U8_TRACE_END_ERR( result );
     738            2 :     return result;
     739              : }
     740              : 
     741              : /* ================================ DIAGRAMELEMENT ================================ */
     742              : 
     743          262 : u8_error_t data_database_writer_create_diagramelement( data_database_writer_t *this_,
     744              :                                                        const data_diagramelement_t *diagramelement,
     745              :                                                        data_row_t* out_new_id )
     746              : {
     747          262 :     U8_TRACE_BEGIN();
     748          262 :     assert( NULL != diagramelement );
     749          262 :     u8_error_t result = U8_ERROR_NONE;
     750          262 :     data_row_t new_id = DATA_ROW_VOID;
     751              : 
     752          262 :     result |= data_database_sql_builder_build_create_diagramelement_command( &((*this_).sql_builder), diagramelement );
     753          262 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     754              : 
     755          262 :     result |= data_database_transaction_begin ( (*this_).database );
     756          262 :     result |= data_database_in_transaction_create( (*this_).database, sql_cmd, &new_id );
     757          262 :     result |= data_database_transaction_commit ( (*this_).database );
     758          262 :     U8_LOG_EVENT_INT( "sqlite3_exec: INSERT INTO diagramelements ... ->", new_id );  /* do not log confidential information, only id */
     759              : 
     760              :     /* notify listeners */
     761              :     data_row_t diagram_id;
     762          262 :     diagram_id = data_diagramelement_get_diagram_row_id( diagramelement );
     763          262 :     data_change_notifier_emit_signal( data_database_get_notifier_ptr( (*this_).database ),
     764              :                                       DATA_CHANGE_EVENT_TYPE_CREATE,
     765              :                                       DATA_TABLE_DIAGRAMELEMENT,
     766              :                                       new_id,
     767              :                                       DATA_TABLE_DIAGRAM,
     768              :                                       diagram_id
     769              :                                     );
     770              : 
     771          262 :     if ( NULL != out_new_id )
     772              :     {
     773          221 :         *out_new_id = new_id;
     774              :     }
     775              : 
     776          262 :     U8_TRACE_END_ERR( result );
     777          262 :     return result;
     778              : }
     779              : 
     780           10 : u8_error_t data_database_writer_delete_diagramelement( data_database_writer_t *this_,
     781              :                                                        data_row_t obj_id,
     782              :                                                        data_diagramelement_t *out_old_diagramelement )
     783              : {
     784           10 :     U8_TRACE_BEGIN();
     785           10 :     u8_error_t result = U8_ERROR_NONE;
     786              : 
     787           10 :     result |= data_database_transaction_begin ( (*this_).database );
     788              : 
     789              :     /* Note: out_old_diagramelement is NULL if old data shall not be returned */
     790           10 :     if ( NULL != out_old_diagramelement )
     791              :     {
     792            6 :         result |= data_database_reader_get_diagramelement_by_id ( (*this_).db_reader, obj_id, out_old_diagramelement );
     793              :     }
     794              : 
     795           10 :     result |= data_database_sql_builder_build_delete_diagramelement_command ( &((*this_).sql_builder), obj_id );
     796           10 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     797              : 
     798           10 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     799           10 :     U8_LOG_EVENT_INT( "sqlite3_exec: DELETE FROM diagramelements ... ->", obj_id );  /* do not log confidential information, only id */
     800              : 
     801           10 :     result |= data_database_transaction_commit ( (*this_).database );
     802              : 
     803              :     /* notify listeners */
     804           10 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     805              :                                                      DATA_CHANGE_EVENT_TYPE_DELETE,
     806              :                                                      DATA_TABLE_DIAGRAMELEMENT,
     807              :                                                      obj_id
     808              :                                                    );
     809              : 
     810           10 :     U8_TRACE_END_ERR( result );
     811           10 :     return result;
     812              : }
     813              : 
     814            6 : u8_error_t data_database_writer_update_diagramelement_display_flags ( data_database_writer_t *this_,
     815              :                                                                       data_row_t diagramelement_id,
     816              :                                                                       data_diagramelement_flag_t new_display_flags,
     817              :                                                                       data_diagramelement_t *out_old_diagramelement )
     818              : {
     819            6 :     U8_TRACE_BEGIN();
     820            6 :     u8_error_t result = U8_ERROR_NONE;
     821              : 
     822            6 :     result |= data_database_transaction_begin ( (*this_).database );
     823              : 
     824              :     /* Note: out_old_diagramelement is NULL if old data shall not be returned */
     825            6 :     if ( NULL != out_old_diagramelement )
     826              :     {
     827            1 :         result |= data_database_reader_get_diagramelement_by_id ( (*this_).db_reader, diagramelement_id, out_old_diagramelement );
     828              :     }
     829              : 
     830            6 :     result |= data_database_sql_builder_build_update_diagramelement_display_flags_cmd( &((*this_).sql_builder), diagramelement_id, new_display_flags );
     831            6 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     832              : 
     833            6 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     834            6 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE diagramelements SET display_flags ... ->", diagramelement_id );  /* do not log confidential information, only id */
     835              : 
     836            6 :     result |= data_database_transaction_commit ( (*this_).database );
     837              : 
     838              :     /* notify listeners */
     839            6 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     840              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     841              :                                                      DATA_TABLE_DIAGRAMELEMENT,
     842              :                                                      diagramelement_id
     843              :                                                    );
     844              : 
     845            6 :     U8_TRACE_END_ERR( result );
     846            6 :     return result;
     847              : }
     848              : 
     849           28 : u8_error_t data_database_writer_update_diagramelement_focused_feature_id ( data_database_writer_t *this_,
     850              :                                                                            data_row_t diagramelement_id,
     851              :                                                                            data_row_t new_focused_feature_id,
     852              :                                                                            data_diagramelement_t *out_old_diagramelement )
     853              : {
     854           28 :     U8_TRACE_BEGIN();
     855           28 :     u8_error_t result = U8_ERROR_NONE;
     856              : 
     857           28 :     result |= data_database_transaction_begin ( (*this_).database );
     858              : 
     859              :     /* Note: out_old_diagramelement is NULL if old data shall not be returned */
     860           28 :     if ( NULL != out_old_diagramelement )
     861              :     {
     862           21 :         result |= data_database_reader_get_diagramelement_by_id ( (*this_).db_reader, diagramelement_id, out_old_diagramelement );
     863              :     }
     864              : 
     865           28 :     result |= data_database_sql_builder_build_update_diagramelement_focused_feature_id_cmd( &((*this_).sql_builder), diagramelement_id, new_focused_feature_id );
     866           28 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     867              : 
     868           28 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     869           28 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE diagramelements SET focused_feature_id ... ->", diagramelement_id );  /* do not log confidential information, only id */
     870              : 
     871           28 :     result |= data_database_transaction_commit ( (*this_).database );
     872              : 
     873              :     /* notify listeners */
     874           28 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     875              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     876              :                                                      DATA_TABLE_DIAGRAMELEMENT,
     877              :                                                      diagramelement_id
     878              :                                                    );
     879              : 
     880           28 :     U8_TRACE_END_ERR( result );
     881           28 :     return result;
     882              : }
     883              : 
     884              : /* ================================ FEATURE ================================ */
     885              : 
     886          325 : u8_error_t data_database_writer_create_feature ( data_database_writer_t *this_, const data_feature_t *feature, data_row_t* out_new_id )
     887              : {
     888          325 :     U8_TRACE_BEGIN();
     889          325 :     assert( NULL != feature );
     890          325 :     u8_error_t result = U8_ERROR_NONE;
     891          325 :     data_row_t new_id = DATA_ROW_VOID;
     892              : 
     893          325 :     result |= data_database_sql_builder_build_create_feature_command( &((*this_).sql_builder), feature );
     894          325 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     895              : 
     896          325 :     result |= data_database_transaction_begin ( (*this_).database );
     897          325 :     result |= data_database_in_transaction_create( (*this_).database, sql_cmd, &new_id );
     898          325 :     result |= data_database_transaction_commit ( (*this_).database );
     899          325 :     U8_LOG_EVENT_INT( "sqlite3_exec: INSERT INTO features ... ->", new_id );  /* do not log confidential information, only id */
     900              : 
     901              :     /* notify listeners */
     902              :     data_row_t classifier_id;
     903          325 :     classifier_id = data_feature_get_classifier_row_id( feature );
     904          325 :     data_change_notifier_emit_signal( data_database_get_notifier_ptr( (*this_).database ),
     905              :                                       DATA_CHANGE_EVENT_TYPE_CREATE,
     906              :                                       DATA_TABLE_FEATURE,
     907              :                                       new_id,
     908              :                                       DATA_TABLE_CLASSIFIER,
     909              :                                       classifier_id
     910              :                                     );
     911              : 
     912          325 :     if ( NULL != out_new_id )
     913              :     {
     914          298 :         *out_new_id = new_id;
     915              :     }
     916              : 
     917          325 :     U8_TRACE_END_ERR( result );
     918          325 :     return result;
     919              : }
     920              : 
     921           14 : u8_error_t data_database_writer_delete_feature ( data_database_writer_t *this_, data_row_t obj_id, data_feature_t *out_old_feature )
     922              : {
     923           14 :     U8_TRACE_BEGIN();
     924           14 :     u8_error_t result = U8_ERROR_NONE;
     925              : 
     926           14 :     result |= data_database_transaction_begin ( (*this_).database );
     927              : 
     928              :     /* Note: out_old_feature is NULL if old data shall not be returned */
     929           14 :     if ( NULL != out_old_feature )
     930              :     {
     931           10 :         result |= data_database_reader_get_feature_by_id ( (*this_).db_reader, obj_id, out_old_feature );
     932              :     }
     933              : 
     934           14 :     result |= data_database_sql_builder_build_delete_feature_command ( &((*this_).sql_builder), obj_id );
     935           14 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     936              : 
     937           14 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     938           14 :     U8_LOG_EVENT_INT( "sqlite3_exec: DELETE FROM features ... ->", obj_id );  /* do not log confidential information, only id */
     939              : 
     940           14 :     result |= data_database_transaction_commit ( (*this_).database );
     941              : 
     942              :     /* notify listeners */
     943           14 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     944              :                                                      DATA_CHANGE_EVENT_TYPE_DELETE,
     945              :                                                      DATA_TABLE_FEATURE,
     946              :                                                      obj_id
     947              :                                                    );
     948              : 
     949           14 :     U8_TRACE_END_ERR( result );
     950           14 :     return result;
     951              : }
     952              : 
     953            6 : u8_error_t data_database_writer_update_feature_main_type ( data_database_writer_t *this_, data_row_t feature_id, data_feature_type_t new_feature_type, data_feature_t *out_old_feature )
     954              : {
     955            6 :     U8_TRACE_BEGIN();
     956            6 :     u8_error_t result = U8_ERROR_NONE;
     957              : 
     958            6 :     result |= data_database_transaction_begin ( (*this_).database );
     959              : 
     960              :     /* Note: out_old_feature is NULL if old data shall not be returned */
     961            6 :     if ( NULL != out_old_feature )
     962              :     {
     963            2 :         result |= data_database_reader_get_feature_by_id ( (*this_).db_reader, feature_id, out_old_feature );
     964              :     }
     965              : 
     966            6 :     result |= data_database_sql_builder_build_update_feature_main_type_cmd( &((*this_).sql_builder), feature_id, new_feature_type );
     967            6 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
     968              : 
     969            6 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
     970            6 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE features SET main_type ... ->", feature_id );  /* do not log confidential information, only id */
     971              : 
     972            6 :     result |= data_database_transaction_commit ( (*this_).database );
     973              : 
     974              :     /* notify listeners */
     975            6 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
     976              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
     977              :                                                      DATA_TABLE_FEATURE,
     978              :                                                      feature_id
     979              :                                                    );
     980              : 
     981            6 :     U8_TRACE_END_ERR( result );
     982            6 :     return result;
     983              : }
     984              : 
     985            5 : u8_error_t data_database_writer_update_feature_key ( data_database_writer_t *this_, data_row_t feature_id, const char* new_feature_key, data_feature_t *out_old_feature )
     986              : {
     987            5 :     U8_TRACE_BEGIN();
     988            5 :     u8_error_t result = U8_ERROR_NONE;
     989              : 
     990            5 :     result |= data_database_transaction_begin ( (*this_).database );
     991              : 
     992              :     /* Note: out_old_feature is NULL if old data shall not be returned */
     993            5 :     if ( NULL != out_old_feature )
     994              :     {
     995            1 :         result |= data_database_reader_get_feature_by_id ( (*this_).db_reader, feature_id, out_old_feature );
     996              :     }
     997              : 
     998            5 :     result |= data_database_sql_builder_build_update_feature_key_cmd( &((*this_).sql_builder), feature_id, new_feature_key );
     999            5 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1000              : 
    1001            5 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1002            5 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE features SET key ... ->", feature_id );  /* do not log confidential information, only id */
    1003              : 
    1004            5 :     result |= data_database_transaction_commit ( (*this_).database );
    1005              : 
    1006              :     /* notify listeners */
    1007            5 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1008              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1009              :                                                      DATA_TABLE_FEATURE,
    1010              :                                                      feature_id
    1011              :                                                    );
    1012              : 
    1013            5 :     U8_TRACE_END_ERR( result );
    1014            5 :     return result;
    1015              : }
    1016              : 
    1017            6 : u8_error_t data_database_writer_update_feature_value ( data_database_writer_t *this_, data_row_t feature_id, const char* new_feature_value, data_feature_t *out_old_feature )
    1018              : {
    1019            6 :     U8_TRACE_BEGIN();
    1020            6 :     u8_error_t result = U8_ERROR_NONE;
    1021              : 
    1022            6 :     result |= data_database_transaction_begin ( (*this_).database );
    1023              : 
    1024              :     /* Note: out_old_feature is NULL if old data shall not be returned */
    1025            6 :     if ( NULL != out_old_feature )
    1026              :     {
    1027            2 :         result |= data_database_reader_get_feature_by_id ( (*this_).db_reader, feature_id, out_old_feature );
    1028              :     }
    1029              : 
    1030            6 :     result |= data_database_sql_builder_build_update_feature_value_cmd( &((*this_).sql_builder), feature_id, new_feature_value );
    1031            6 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1032              : 
    1033            6 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1034            6 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE features SET value ... ->", feature_id );  /* do not log confidential information, only id */
    1035              : 
    1036            6 :     result |= data_database_transaction_commit ( (*this_).database );
    1037              : 
    1038              :     /* notify listeners */
    1039            6 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1040              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1041              :                                                      DATA_TABLE_FEATURE,
    1042              :                                                      feature_id
    1043              :                                                    );
    1044              : 
    1045            6 :     U8_TRACE_END_ERR( result );
    1046            6 :     return result;
    1047              : }
    1048              : 
    1049            5 : u8_error_t data_database_writer_update_feature_description ( data_database_writer_t *this_, data_row_t feature_id, const char* new_feature_description, data_feature_t *out_old_feature )
    1050              : {
    1051            5 :     U8_TRACE_BEGIN();
    1052            5 :     u8_error_t result = U8_ERROR_NONE;
    1053              : 
    1054            5 :     result |= data_database_transaction_begin ( (*this_).database );
    1055              : 
    1056              :     /* Note: out_old_feature is NULL if old data shall not be returned */
    1057            5 :     if ( NULL != out_old_feature )
    1058              :     {
    1059            1 :         result |= data_database_reader_get_feature_by_id ( (*this_).db_reader, feature_id, out_old_feature );
    1060              :     }
    1061              : 
    1062            5 :     result |= data_database_sql_builder_build_update_feature_description_cmd( &((*this_).sql_builder), feature_id, new_feature_description );
    1063            5 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1064              : 
    1065            5 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1066            5 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE features SET description ... ->", feature_id );  /* do not log confidential information, only id */
    1067              : 
    1068            5 :     result |= data_database_transaction_commit ( (*this_).database );
    1069              : 
    1070              :     /* notify listeners */
    1071            5 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1072              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1073              :                                                      DATA_TABLE_FEATURE,
    1074              :                                                      feature_id
    1075              :                                                    );
    1076              : 
    1077            5 :     U8_TRACE_END_ERR( result );
    1078            5 :     return result;
    1079              : }
    1080              : 
    1081            5 : u8_error_t data_database_writer_update_feature_list_order ( data_database_writer_t *this_, data_row_t feature_id, int32_t new_feature_list_order, data_feature_t *out_old_feature )
    1082              : {
    1083            5 :     U8_TRACE_BEGIN();
    1084            5 :     u8_error_t result = U8_ERROR_NONE;
    1085              : 
    1086            5 :     result |= data_database_transaction_begin ( (*this_).database );
    1087              : 
    1088              :     /* Note: out_old_feature is NULL if old data shall not be returned */
    1089            5 :     if ( NULL != out_old_feature )
    1090              :     {
    1091            1 :         result |= data_database_reader_get_feature_by_id ( (*this_).db_reader, feature_id, out_old_feature );
    1092              :     }
    1093              : 
    1094            5 :     result |= data_database_sql_builder_build_update_feature_list_order_cmd( &((*this_).sql_builder), feature_id, new_feature_list_order );
    1095            5 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1096              : 
    1097            5 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1098            5 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE features SET list_order ... ->", feature_id );  /* do not log confidential information, only id */
    1099              : 
    1100            5 :     result |= data_database_transaction_commit ( (*this_).database );
    1101              : 
    1102              :     /* notify listeners */
    1103            5 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1104              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1105              :                                                      DATA_TABLE_FEATURE,
    1106              :                                                      feature_id
    1107              :                                                    );
    1108              : 
    1109            5 :     U8_TRACE_END_ERR( result );
    1110            5 :     return result;
    1111              : }
    1112              : 
    1113              : /* ================================ RELATIONSHIP ================================ */
    1114              : 
    1115          435 : u8_error_t data_database_writer_create_relationship ( data_database_writer_t *this_, const data_relationship_t *relationship, data_row_t* out_new_id )
    1116              : {
    1117          435 :     U8_TRACE_BEGIN();
    1118          435 :     assert( NULL != relationship );
    1119          435 :     u8_error_t result = U8_ERROR_NONE;
    1120          435 :     data_row_t new_id = DATA_ROW_VOID;
    1121              : 
    1122          435 :     result |= data_database_sql_builder_build_create_relationship_command( &((*this_).sql_builder), relationship );
    1123          435 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1124              : 
    1125          435 :     result |= data_database_transaction_begin ( (*this_).database );
    1126          435 :     result |= data_database_in_transaction_create( (*this_).database, sql_cmd, &new_id );
    1127          435 :     result |= data_database_transaction_commit ( (*this_).database );
    1128          435 :     U8_LOG_EVENT_INT( "sqlite3_exec: INSERT INTO relationships ... ->", new_id );  /* do not log confidential information, only id */
    1129              : 
    1130              :     /* notify listeners */
    1131              :     data_row_t from_classifier_id;
    1132          435 :     from_classifier_id = data_relationship_get_from_classifier_row_id( relationship );
    1133          435 :     data_change_notifier_emit_signal( data_database_get_notifier_ptr( (*this_).database ),
    1134              :                                       DATA_CHANGE_EVENT_TYPE_CREATE,
    1135              :                                       DATA_TABLE_RELATIONSHIP,
    1136              :                                       new_id,
    1137              :                                       DATA_TABLE_CLASSIFIER,
    1138              :                                       from_classifier_id
    1139              :                                     );
    1140              : 
    1141          435 :     if ( NULL != out_new_id )
    1142              :     {
    1143          412 :         *out_new_id = new_id;
    1144              :     }
    1145              : 
    1146          435 :     U8_TRACE_END_ERR( result );
    1147          435 :     return result;
    1148              : }
    1149              : 
    1150           15 : u8_error_t data_database_writer_delete_relationship ( data_database_writer_t *this_, data_row_t obj_id, data_relationship_t *out_old_relationship )
    1151              : {
    1152           15 :     U8_TRACE_BEGIN();
    1153           15 :     u8_error_t result = U8_ERROR_NONE;
    1154              : 
    1155           15 :     result |= data_database_transaction_begin ( (*this_).database );
    1156              : 
    1157              :     /* Note: out_old_relationship is NULL if old data shall not be returned */
    1158           15 :     if ( NULL != out_old_relationship )
    1159              :     {
    1160            5 :         result |= data_database_reader_get_relationship_by_id ( (*this_).db_reader, obj_id, out_old_relationship );
    1161              :     }
    1162              : 
    1163           15 :     result |= data_database_sql_builder_build_delete_relationship_command ( &((*this_).sql_builder), obj_id );
    1164           15 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1165              : 
    1166           15 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1167           15 :     U8_LOG_EVENT_INT( "sqlite3_exec: DELETE FROM relationships ... ->", obj_id );  /* do not log confidential information, only id */
    1168              : 
    1169           15 :     result |= data_database_transaction_commit ( (*this_).database );
    1170              : 
    1171              :     /* notify listeners */
    1172           15 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1173              :                                                      DATA_CHANGE_EVENT_TYPE_DELETE,
    1174              :                                                      DATA_TABLE_RELATIONSHIP,
    1175              :                                                      obj_id
    1176              :                                                    );
    1177              : 
    1178           15 :     U8_TRACE_END_ERR( result );
    1179           15 :     return result;
    1180              : }
    1181              : 
    1182            3 : u8_error_t data_database_writer_update_relationship_main_type ( data_database_writer_t *this_,
    1183              :                                                                 data_row_t relationship_id,
    1184              :                                                                 data_relationship_type_t new_relationship_type,
    1185              :                                                                 data_relationship_t *out_old_relationship )
    1186              : {
    1187            3 :     U8_TRACE_BEGIN();
    1188            3 :     u8_error_t result = U8_ERROR_NONE;
    1189              : 
    1190            3 :     result |= data_database_transaction_begin ( (*this_).database );
    1191              : 
    1192              :     /* Note: out_old_relationship is NULL if old data shall not be returned */
    1193            3 :     if ( NULL != out_old_relationship )
    1194              :     {
    1195            1 :         result |= data_database_reader_get_relationship_by_id ( (*this_).db_reader, relationship_id, out_old_relationship );
    1196              :     }
    1197              : 
    1198            3 :     result |= data_database_sql_builder_build_update_relationship_main_type_cmd( &((*this_).sql_builder), relationship_id, new_relationship_type );
    1199            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1200              : 
    1201            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1202            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE relationships SET main_type ... ->", relationship_id );  /* do not log confidential information, only id */
    1203              : 
    1204            3 :     result |= data_database_transaction_commit ( (*this_).database );
    1205              : 
    1206              :     /* notify listeners */
    1207            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1208              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1209              :                                                      DATA_TABLE_RELATIONSHIP,
    1210              :                                                      relationship_id
    1211              :                                                    );
    1212              : 
    1213            3 :     U8_TRACE_END_ERR( result );
    1214            3 :     return result;
    1215              : }
    1216              : 
    1217            3 : u8_error_t data_database_writer_update_relationship_stereotype ( data_database_writer_t *this_,
    1218              :                                                                  data_row_t relationship_id,
    1219              :                                                                  const char* new_relationship_stereotype,
    1220              :                                                                  data_relationship_t *out_old_relationship )
    1221              : {
    1222            3 :     U8_TRACE_BEGIN();
    1223            3 :     u8_error_t result = U8_ERROR_NONE;
    1224              : 
    1225            3 :     result |= data_database_transaction_begin ( (*this_).database );
    1226              : 
    1227              :     /* Note: out_old_relationship is NULL if old data shall not be returned */
    1228            3 :     if ( NULL != out_old_relationship )
    1229              :     {
    1230            1 :         result |= data_database_reader_get_relationship_by_id ( (*this_).db_reader, relationship_id, out_old_relationship );
    1231              :     }
    1232              : 
    1233            3 :     result |= data_database_sql_builder_build_update_relationship_stereotype_cmd( &((*this_).sql_builder), relationship_id, new_relationship_stereotype );
    1234            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1235              : 
    1236            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1237            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE relationships SET stereotype ... ->", relationship_id );  /* do not log confidential information, only id */
    1238              : 
    1239            3 :     result |= data_database_transaction_commit ( (*this_).database );
    1240              : 
    1241              :     /* notify listeners */
    1242            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1243              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1244              :                                                      DATA_TABLE_RELATIONSHIP,
    1245              :                                                      relationship_id
    1246              :                                                    );
    1247              : 
    1248            3 :     U8_TRACE_END_ERR( result );
    1249            3 :     return result;
    1250              : }
    1251              : 
    1252            3 : u8_error_t data_database_writer_update_relationship_name ( data_database_writer_t *this_,
    1253              :                                                            data_row_t relationship_id,
    1254              :                                                            const char* new_relationship_name,
    1255              :                                                            data_relationship_t *out_old_relationship )
    1256              : {
    1257            3 :     U8_TRACE_BEGIN();
    1258            3 :     u8_error_t result = U8_ERROR_NONE;
    1259              : 
    1260            3 :     result |= data_database_transaction_begin ( (*this_).database );
    1261              : 
    1262              :     /* Note: out_old_relationship is NULL if old data shall not be returned */
    1263            3 :     if ( NULL != out_old_relationship )
    1264              :     {
    1265            1 :         result |= data_database_reader_get_relationship_by_id ( (*this_).db_reader, relationship_id, out_old_relationship );
    1266              :     }
    1267              : 
    1268            3 :     result |= data_database_sql_builder_build_update_relationship_name_cmd( &((*this_).sql_builder), relationship_id, new_relationship_name );
    1269            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1270              : 
    1271            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1272            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE relationships SET name ... ->", relationship_id );  /* do not log confidential information, only id */
    1273              : 
    1274            3 :     result |= data_database_transaction_commit ( (*this_).database );
    1275              : 
    1276              :     /* notify listeners */
    1277            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1278              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1279              :                                                      DATA_TABLE_RELATIONSHIP,
    1280              :                                                      relationship_id
    1281              :                                                    );
    1282              : 
    1283            3 :     U8_TRACE_END_ERR( result );
    1284            3 :     return result;
    1285              : }
    1286              : 
    1287            4 : u8_error_t data_database_writer_update_relationship_description ( data_database_writer_t *this_, data_row_t relationship_id, const char* new_relationship_description, data_relationship_t *out_old_relationship )
    1288              : {
    1289            4 :     U8_TRACE_BEGIN();
    1290            4 :     u8_error_t result = U8_ERROR_NONE;
    1291              : 
    1292            4 :     result |= data_database_transaction_begin ( (*this_).database );
    1293              : 
    1294              :     /* Note: out_old_relationship is NULL if old data shall not be returned */
    1295            4 :     if ( NULL != out_old_relationship )
    1296              :     {
    1297            2 :         result |= data_database_reader_get_relationship_by_id ( (*this_).db_reader, relationship_id, out_old_relationship );
    1298              :     }
    1299              : 
    1300            4 :     result |= data_database_sql_builder_build_update_relationship_description_cmd( &((*this_).sql_builder), relationship_id, new_relationship_description );
    1301            4 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1302              : 
    1303            4 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1304            4 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE relationships SET description ... ->", relationship_id );  /* do not log confidential information, only id */
    1305              : 
    1306            4 :     result |= data_database_transaction_commit ( (*this_).database );
    1307              : 
    1308              :     /* notify listeners */
    1309            4 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1310              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1311              :                                                      DATA_TABLE_RELATIONSHIP,
    1312              :                                                      relationship_id
    1313              :                                                    );
    1314              : 
    1315            4 :     U8_TRACE_END_ERR( result );
    1316            4 :     return result;
    1317              : }
    1318              : 
    1319            3 : u8_error_t data_database_writer_update_relationship_list_order ( data_database_writer_t *this_, data_row_t relationship_id, int32_t new_relationship_list_order, data_relationship_t *out_old_relationship )
    1320              : {
    1321            3 :     U8_TRACE_BEGIN();
    1322            3 :     u8_error_t result = U8_ERROR_NONE;
    1323              : 
    1324            3 :     result |= data_database_transaction_begin ( (*this_).database );
    1325              : 
    1326              :     /* Note: out_old_relationship is NULL if old data shall not be returned */
    1327            3 :     if ( NULL != out_old_relationship )
    1328              :     {
    1329            1 :         result |= data_database_reader_get_relationship_by_id ( (*this_).db_reader, relationship_id, out_old_relationship );
    1330              :     }
    1331              : 
    1332            3 :     result |= data_database_sql_builder_build_update_relationship_list_order_cmd( &((*this_).sql_builder), relationship_id, new_relationship_list_order );
    1333            3 :     char *sql_cmd = data_database_sql_builder_get_string_ptr( &((*this_).sql_builder) );
    1334              : 
    1335            3 :     result |= data_database_in_transaction_execute( (*this_).database, sql_cmd );
    1336            3 :     U8_LOG_EVENT_INT( "sqlite3_exec: UPDATE relationships SET list_order ... ->", relationship_id );  /* do not log confidential information, only id */
    1337              : 
    1338            3 :     result |= data_database_transaction_commit ( (*this_).database );
    1339              : 
    1340              :     /* notify listeners */
    1341            3 :     data_change_notifier_emit_signal_without_parent( data_database_get_notifier_ptr( (*this_).database ),
    1342              :                                                      DATA_CHANGE_EVENT_TYPE_UPDATE,
    1343              :                                                      DATA_TABLE_RELATIONSHIP,
    1344              :                                                      relationship_id
    1345              :                                                    );
    1346              : 
    1347            3 :     U8_TRACE_END_ERR( result );
    1348            3 :     return result;
    1349              : }
    1350              : 
    1351              : 
    1352              : /*
    1353              : Copyright 2016-2025 Andreas Warnke
    1354              : 
    1355              : Licensed under the Apache License, Version 2.0 (the "License");
    1356              : you may not use this file except in compliance with the License.
    1357              : You may obtain a copy of the License at
    1358              : 
    1359              :     http://www.apache.org/licenses/LICENSE-2.0
    1360              : 
    1361              : Unless required by applicable law or agreed to in writing, software
    1362              : distributed under the License is distributed on an "AS IS" BASIS,
    1363              : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    1364              : See the License for the specific language governing permissions and
    1365              : limitations under the License.
    1366              : */
        

Generated by: LCOV version 2.0-1