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.67.0_covts Lines: 98.4 % 575 566
Test Date: 2025-11-06 17:22:08 Functions: 100.0 % 39 39

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

Generated by: LCOV version 2.0-1