LCOV - code coverage report
Current view: top level - data/source/storage - data_database_writer.c (source / functions) Hit Total Coverage
Test: crystal-facet-uml_v1.61.0_covts Lines: 550 560 98.2 %
Date: 2024-10-26 21:44:38 Functions: 38 38 100.0 %

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

Generated by: LCOV version 1.16