Line data Source code
1 : /* File: io_import_elements.c; Copyright and License: see below */
2 :
3 : #include "io_import_elements.h"
4 : #include "u8/u8_error.h"
5 : #include "utf8stringbuf/utf8string.h"
6 : #include "u8/u8_trace.h"
7 : #include <assert.h>
8 : #include "io_gtk.h"
9 : #include <stdbool.h>
10 :
11 20 : void io_import_elements_init( io_import_elements_t *this_,
12 : data_database_reader_t *db_reader,
13 : ctrl_controller_t *controller,
14 : data_stat_t *io_stat,
15 : utf8stream_writer_t *out_english_report )
16 : {
17 20 : U8_TRACE_BEGIN();
18 20 : assert( NULL != db_reader );
19 20 : assert( NULL != controller );
20 20 : assert( NULL != io_stat );
21 20 : assert( NULL != out_english_report );
22 :
23 20 : (*this_).db_reader = db_reader;
24 20 : (*this_).controller = controller;
25 20 : (*this_).stat = io_stat;
26 20 : (*this_).english_report = out_english_report;
27 :
28 20 : (*this_).step = IO_IMPORT_STEP_CHECK;
29 20 : (*this_).paste_to_diagram = DATA_ROW_VOID;
30 :
31 20 : ctrl_multi_step_changer_init( &((*this_).multi_step_changer), controller, db_reader );
32 :
33 20 : data_rules_init ( &((*this_).data_rules) );
34 :
35 : /* get the id of the root diagram if there is one */
36 20 : (*this_).root_diagram = DATA_ROW_VOID;
37 : {
38 : data_small_set_t roots;
39 20 : data_small_set_init( &roots );
40 : const u8_error_t read_error
41 20 : = data_database_reader_get_diagram_ids_by_parent_id( (*this_).db_reader,
42 : DATA_ROW_VOID,
43 : &roots
44 : );
45 20 : if ( read_error != U8_ERROR_NONE )
46 : {
47 0 : U8_LOG_ERROR_HEX( "error at reading root", read_error );
48 : }
49 : else
50 : {
51 20 : if ( 1 <= data_small_set_get_count( &roots ) )
52 : {
53 16 : data_id_t first_root = data_small_set_get_id( &roots, 0 );
54 16 : (*this_).root_diagram = data_id_get_row( &first_root );
55 : }
56 : else
57 : {
58 4 : U8_LOG_EVENT( "importing to empty database" );
59 : }
60 : }
61 20 : data_small_set_destroy( &roots );
62 : }
63 :
64 20 : U8_TRACE_END();
65 20 : }
66 :
67 16 : void io_import_elements_init_for_paste( io_import_elements_t *this_,
68 : data_row_t paste_to_diagram,
69 : data_database_reader_t *db_reader,
70 : ctrl_controller_t *controller,
71 : data_stat_t *io_stat,
72 : utf8stream_writer_t *out_english_report )
73 : {
74 16 : U8_TRACE_BEGIN();
75 :
76 16 : io_import_elements_init( this_, db_reader, controller, io_stat, out_english_report );
77 16 : (*this_).step = IO_IMPORT_STEP_CREATE_D_C_F_R;
78 :
79 : /* check if diagram id exists */
80 : {
81 16 : data_diagram_init_empty( &((*this_).temp_diagram) );
82 : const u8_error_t read_error1
83 16 : = data_database_reader_get_diagram_by_id( (*this_).db_reader,
84 : paste_to_diagram,
85 : &((*this_).temp_diagram)
86 : );
87 16 : if ( U8_ERROR_NONE != read_error1 )
88 : {
89 1 : U8_LOG_ERROR_INT( "diagram id where to import json data to does not exist (anymore)", (*this_).paste_to_diagram );
90 1 : (*this_).paste_to_diagram = DATA_ROW_VOID;
91 : }
92 : else
93 : {
94 15 : (*this_).paste_to_diagram = paste_to_diagram;
95 : }
96 16 : data_diagram_destroy( &((*this_).temp_diagram) );
97 : }
98 :
99 16 : U8_TRACE_END();
100 16 : }
101 :
102 20 : void io_import_elements_destroy( io_import_elements_t *this_ )
103 : {
104 20 : U8_TRACE_BEGIN();
105 20 : assert( NULL != (*this_).db_reader );
106 20 : assert( NULL != (*this_).controller );
107 20 : assert( NULL != (*this_).stat );
108 20 : assert( NULL != (*this_).english_report );
109 :
110 20 : data_rules_destroy ( &((*this_).data_rules) );
111 20 : ctrl_multi_step_changer_destroy( &((*this_).multi_step_changer) );
112 : /* do not change the stats here */
113 :
114 20 : (*this_).db_reader = NULL;
115 20 : (*this_).controller = NULL;
116 20 : (*this_).stat = NULL;
117 20 : (*this_).english_report = NULL;
118 :
119 20 : U8_TRACE_END();
120 20 : }
121 :
122 7 : void io_import_elements_set_mode( io_import_elements_t *this_, io_import_mode_t mode, io_import_step_t step )
123 : {
124 7 : U8_TRACE_BEGIN();
125 7 : assert( ( step == IO_IMPORT_STEP_CHECK ) || ( mode != IO_IMPORT_MODE_CHECK ) );
126 7 : assert( ( step == IO_IMPORT_STEP_CREATE_D_C_F_R ) || ( mode != IO_IMPORT_MODE_PASTE ) );
127 7 : assert( ( step == IO_IMPORT_STEP_CREATE_D_C_L ) || ( step == IO_IMPORT_STEP_ADD_E_DP_F_R ) || ( mode != IO_IMPORT_MODE_IMPORT ) );
128 :
129 7 : (*this_).step = step;
130 :
131 7 : U8_TRACE_END();
132 7 : }
133 :
134 16 : u8_error_t io_import_elements_sync_diagram( io_import_elements_t *this_,
135 : const data_diagram_t *diagram_ptr,
136 : const char *parent_uuid )
137 : {
138 16 : U8_TRACE_BEGIN();
139 16 : assert( NULL != diagram_ptr );
140 : /* parent_uuid is NULL if root diagram */
141 16 : u8_error_t sync_error = U8_ERROR_NONE;
142 :
143 : /* ANY MODE: determine parent id */
144 16 : data_row_t parent_row = (*this_).root_diagram;
145 16 : const bool parent_uuid_specified
146 16 : = (( parent_uuid != NULL )&&( ! utf8string_equals_str( parent_uuid, "" )));
147 16 : if ( parent_uuid_specified )
148 : {
149 0 : data_diagram_init_empty( &((*this_).temp_diagram ) );
150 : const u8_error_t read_error1
151 0 : = data_database_reader_get_diagram_by_uuid( (*this_).db_reader,
152 : parent_uuid,
153 : &((*this_).temp_diagram)
154 : );
155 0 : if ( read_error1 == U8_ERROR_NOT_FOUND )
156 : {
157 0 : U8_TRACE_INFO_STR( "no parent found, uuid:", parent_uuid );
158 : }
159 0 : else if ( read_error1 != U8_ERROR_NONE )
160 : {
161 0 : U8_TRACE_INFO_STR( "error at searching for parent diagram:", parent_uuid );
162 : }
163 : else
164 : {
165 0 : parent_row = data_diagram_get_row( &((*this_).temp_diagram ) );
166 : }
167 0 : data_diagram_destroy( &((*this_).temp_diagram ) );
168 : }
169 :
170 : /* update default parent diagram id */
171 16 : if (( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )&&( sync_error == U8_ERROR_NONE ))
172 : {
173 10 : if ( (*this_).paste_to_diagram == DATA_ROW_VOID )
174 : {
175 0 : data_row_t parent_row = (*this_).root_diagram;
176 0 : U8_TRACE_INFO_INT( "in paste-clipboard mode, missing parent diagram set to", parent_row );
177 : }
178 : else
179 : {
180 : /* overwrite the parent diagram id, do not keep the one provided via the clipboard */
181 10 : parent_row = (*this_).paste_to_diagram;
182 : }
183 : }
184 :
185 : /* if PASTE */
186 16 : if (( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )&&( sync_error == U8_ERROR_NONE ))
187 : {
188 10 : data_diagram_copy( &((*this_).temp_diagram), diagram_ptr );
189 10 : data_diagram_set_parent_row( &((*this_).temp_diagram), parent_row );
190 : /* create new uuid for diagram if paste */
191 : {
192 : data_uuid_t new_uuid;
193 10 : data_uuid_init_new( &new_uuid );
194 10 : data_diagram_set_uuid( &((*this_).temp_diagram), data_uuid_get_string( &new_uuid ) );
195 10 : data_uuid_destroy( &new_uuid );
196 : }
197 :
198 : /* create the parsed diagram as child below the current diagram */
199 : u8_error_t modified_info;
200 10 : sync_error = ctrl_multi_step_changer_create_diagram( &((*this_).multi_step_changer),
201 : &((*this_).temp_diagram),
202 : &modified_info
203 : );
204 10 : if ( sync_error == U8_ERROR_NONE )
205 : {
206 10 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_CREATED );
207 : }
208 : else
209 : {
210 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_ERROR );
211 : }
212 10 : if ( U8_ERROR_NONE != sync_error )
213 : {
214 0 : U8_LOG_ERROR( "unexpected error at ctrl_diagram_controller_create_diagram" );
215 : }
216 : else
217 : {
218 : /* insert all consecutive elements to this new diagram */
219 10 : (*this_).paste_to_diagram = data_diagram_get_row( &((*this_).temp_diagram) );
220 : /* this new diagram is root if it is the first diagram */
221 10 : if ( (*this_).root_diagram == DATA_ROW_VOID )
222 : {
223 0 : (*this_).root_diagram = data_diagram_get_row( &((*this_).temp_diagram) );
224 : }
225 : }
226 10 : data_diagram_destroy( &((*this_).temp_diagram) );
227 : }
228 :
229 : /* if CREATE/LINK */
230 16 : if ((( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_L )||( (*this_).step == IO_IMPORT_STEP_ADD_E_DP_F_R ))
231 4 : &&( sync_error == U8_ERROR_NONE ))
232 : {
233 : /* check if the parsed diagram already exists in this database; if not, create it */
234 4 : data_diagram_init_empty( &((*this_).temp_diagram) );
235 : u8_error_t read_error;
236 4 : read_error = data_database_reader_get_diagram_by_uuid( (*this_).db_reader,
237 : data_diagram_get_uuid_const( diagram_ptr ),
238 : &((*this_).temp_diagram)
239 : );
240 4 : const bool diagram_exists = ( U8_ERROR_NONE == read_error );
241 :
242 4 : if ( diagram_exists )
243 : {
244 2 : if ( (*this_).step == IO_IMPORT_STEP_ADD_E_DP_F_R )
245 : {
246 : /* if (*this_).temp_diagram is the only valid root, set parent_row to DATA_ROW_VOID */
247 2 : if ( data_diagram_get_row( &((*this_).temp_diagram) ) == (*this_).root_diagram )
248 : {
249 1 : parent_row = DATA_ROW_VOID;
250 : }
251 :
252 : /* update the parent if wrong parent stored */
253 2 : if ( data_diagram_get_parent_row( &((*this_).temp_diagram) ) != parent_row )
254 : {
255 0 : sync_error = ctrl_multi_step_changer_update_diagram_parent_id( &((*this_).multi_step_changer),
256 0 : data_diagram_get_row( &((*this_).temp_diagram) ),
257 : parent_row
258 : );
259 :
260 : /* update root diag if this is root */
261 0 : if (( parent_row == DATA_ROW_VOID )&&( sync_error == U8_ERROR_NONE ))
262 : {
263 0 : (*this_).root_diagram = data_diagram_get_row( &((*this_).temp_diagram) );
264 : }
265 : }
266 : }
267 : else
268 : {
269 : /* do the statistics */
270 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_IGNORED );
271 : }
272 : }
273 : else
274 : {
275 2 : data_diagram_replace( &((*this_).temp_diagram), diagram_ptr );
276 2 : data_diagram_set_parent_row( &((*this_).temp_diagram), parent_row );
277 :
278 : /* create the parsed diagram as child below the current diagram */
279 : u8_error_t modified_info;
280 2 : sync_error = ctrl_multi_step_changer_create_diagram( &((*this_).multi_step_changer),
281 : &((*this_).temp_diagram),
282 : &modified_info
283 : );
284 2 : if ( sync_error == U8_ERROR_NONE )
285 : {
286 2 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_CREATED );
287 : }
288 : else
289 : {
290 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_ERROR );
291 : }
292 :
293 2 : if ( u8_error_contains( modified_info, U8_ERROR_DUPLICATE_ID ) )
294 : {
295 : /* warn on changed diagram ids. This is important because links in description texts may be affected. */
296 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAM, DATA_STAT_SERIES_WARNING );
297 : }
298 :
299 2 : if ( U8_ERROR_NONE != sync_error )
300 : {
301 0 : U8_LOG_ERROR( "unexpected error at ctrl_diagram_controller_create_diagram" );
302 : }
303 : else
304 : {
305 : /* this new diagram is root if it is the first root diagram, further diagrams will not be root */
306 2 : if (( (*this_).root_diagram == DATA_ROW_VOID )&&( parent_row == DATA_ROW_VOID )
307 1 : &&( ! parent_uuid_specified ))
308 : {
309 1 : (*this_).root_diagram = data_diagram_get_row( &((*this_).temp_diagram) );
310 : }
311 : }
312 :
313 : /* write report in case of anomalies */
314 2 : if ( u8_error_contains( modified_info, U8_ERROR_DUPLICATE_ID ) )
315 : {
316 0 : io_import_elements_private_report_id_differs( this_,
317 : data_diagram_get_data_id( diagram_ptr ),
318 0 : data_diagram_get_data_id( &((*this_).temp_diagram ) )
319 : );
320 : }
321 : }
322 4 : data_diagram_destroy( &((*this_).temp_diagram) );
323 : }
324 :
325 16 : U8_TRACE_END_ERR( sync_error );
326 16 : return sync_error;
327 : }
328 :
329 14 : u8_error_t io_import_elements_sync_diagramelement( io_import_elements_t *this_,
330 : const data_diagramelement_t *diagramelement_ptr,
331 : const char *diagram_uuid,
332 : const char *node_uuid )
333 : {
334 14 : U8_TRACE_BEGIN();
335 14 : assert( NULL != diagramelement_ptr );
336 14 : assert( NULL != diagram_uuid );
337 14 : assert( NULL != node_uuid );
338 14 : u8_error_t sync_error = U8_ERROR_NONE;
339 14 : const bool do_sync = ( (*this_).step == IO_IMPORT_STEP_ADD_E_DP_F_R );
340 14 : const bool do_check = ( (*this_).step == IO_IMPORT_STEP_CHECK );
341 :
342 : /* ANY MODE: determine classifier/feature id */
343 14 : data_row_t node_classifier_id = DATA_ROW_VOID;
344 14 : data_row_t node_feature_id = DATA_ROW_VOID;
345 14 : data_feature_type_t node_feature_type = DATA_FEATURE_TYPE_VOID;
346 14 : if (( do_check || do_sync )&&( node_uuid != NULL ))
347 : {
348 4 : if ( ! utf8string_equals_str( node_uuid, "" ) )
349 : {
350 : /* search source classifier id */
351 4 : data_classifier_init_empty( &((*this_).temp_classifier ) );
352 : const u8_error_t read_error1
353 4 : = data_database_reader_get_classifier_by_uuid( (*this_).db_reader,
354 : node_uuid,
355 : &((*this_).temp_classifier)
356 : );
357 4 : if ( U8_ERROR_NONE == read_error1 )
358 : {
359 1 : node_classifier_id = data_classifier_get_row( &((*this_).temp_classifier) );
360 1 : U8_TRACE_INFO_STR( "id found for classifier:", node_uuid );
361 : }
362 : else
363 : {
364 : /* search source feature id */
365 3 : data_feature_init_empty( &((*this_).temp_feature) );
366 : const u8_error_t read_error2
367 3 : = data_database_reader_get_feature_by_uuid( (*this_).db_reader,
368 : node_uuid,
369 : &((*this_).temp_feature)
370 : );
371 3 : if ( U8_ERROR_NONE == read_error2 )
372 : {
373 1 : node_classifier_id = data_feature_get_classifier_row( &((*this_).temp_feature) );
374 1 : node_feature_id = data_feature_get_row( &((*this_).temp_feature) );
375 1 : node_feature_type = data_feature_get_main_type( &((*this_).temp_feature) );
376 1 : U8_TRACE_INFO_STR( "id found for feature:", node_uuid );
377 : }
378 : else
379 : {
380 2 : U8_TRACE_INFO_STR( "diagramelement node not found", node_uuid );
381 : }
382 3 : data_feature_destroy( &((*this_).temp_feature) );
383 : }
384 4 : data_classifier_destroy( &((*this_).temp_classifier ) );
385 : }
386 : }
387 :
388 : /* ANY MODE: determine diagram id */
389 14 : data_row_t diagram_row = DATA_ROW_VOID;
390 14 : if (( do_check || do_sync )&&( diagram_uuid != NULL )&&( sync_error == U8_ERROR_NONE ))
391 : {
392 4 : if ( ! utf8string_equals_str( diagram_uuid, "" ) )
393 : {
394 4 : data_diagram_init_empty( &((*this_).temp_diagram ) );
395 : const u8_error_t read_error3
396 4 : = data_database_reader_get_diagram_by_uuid( (*this_).db_reader,
397 : diagram_uuid,
398 : &((*this_).temp_diagram)
399 : );
400 4 : if ( read_error3 == U8_ERROR_NOT_FOUND )
401 : {
402 2 : U8_TRACE_INFO_STR( "no diagram found, uuid:", diagram_uuid );
403 : }
404 2 : else if ( read_error3 != U8_ERROR_NONE )
405 : {
406 0 : U8_TRACE_INFO_STR( "diagram not found:", diagram_uuid );
407 : }
408 : else
409 : {
410 2 : diagram_row = data_diagram_get_row( &((*this_).temp_diagram ) );
411 : }
412 4 : data_diagram_destroy( &((*this_).temp_diagram ) );
413 : }
414 : }
415 :
416 : /* check preconditions */
417 14 : if ( do_sync )
418 : {
419 2 : if ( node_classifier_id == DATA_ROW_VOID )
420 : {
421 0 : sync_error |= U8_ERROR_VALUE_OUT_OF_RANGE;
422 0 : U8_LOG_ERROR( "diagramelement references a non-existing classifier." );
423 : }
424 2 : if (( node_feature_id != DATA_ROW_VOID )&&( node_feature_type != DATA_FEATURE_TYPE_LIFELINE ))
425 : {
426 0 : sync_error |= U8_ERROR_VALUE_OUT_OF_RANGE;
427 0 : U8_LOG_ERROR( "diagramelement references a feature which is not of type DATA_FEATURE_TYPE_LIFELINE." );
428 : }
429 2 : if ( diagram_row == DATA_ROW_VOID )
430 : {
431 0 : sync_error |= U8_ERROR_VALUE_OUT_OF_RANGE;
432 0 : U8_LOG_ERROR( "diagramelement references a non-existing classifier." );
433 : }
434 : }
435 :
436 14 : if ( do_sync && ( sync_error == U8_ERROR_NONE ) )
437 : {
438 : /* check if the parsed diagramelement already exists in this database; if not, create it */
439 2 : data_diagramelement_init_empty( &((*this_).temp_diagramelement ) );
440 : const u8_error_t read_error4
441 2 : = data_database_reader_get_diagramelement_by_uuid( (*this_).db_reader,
442 : data_diagramelement_get_uuid_const( diagramelement_ptr ),
443 : &((*this_).temp_diagramelement)
444 : );
445 2 : const bool diagramelement_exists = ( U8_ERROR_NONE == read_error4 );
446 :
447 2 : if ( diagramelement_exists )
448 : {
449 : /* do the statistics */
450 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_IGNORED );
451 0 : U8_TRACE_INFO_INT( "diagramelement did already exist:", data_diagramelement_get_row( &((*this_).temp_diagramelement) ) );
452 : }
453 : else
454 : {
455 : /* link the classifier to the current diagram */
456 2 : sync_error = data_diagramelement_reinit( &((*this_).temp_diagramelement),
457 : data_diagramelement_get_row( diagramelement_ptr ),
458 : diagram_row,
459 : node_classifier_id,
460 : data_diagramelement_get_display_flags( diagramelement_ptr ),
461 : node_feature_id, /* focused_feature_id */
462 : data_diagramelement_get_uuid_const( diagramelement_ptr )
463 : );
464 : u8_error_t modified_info;
465 : data_id_t created_lifeline;
466 2 : sync_error |= ctrl_multi_step_changer_create_diagramelement( &((*this_).multi_step_changer),
467 : &((*this_).temp_diagramelement),
468 : &modified_info,
469 : &created_lifeline
470 : );
471 2 : if ( sync_error == U8_ERROR_NONE )
472 : {
473 2 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_CREATED );
474 2 : if ( data_id_is_valid( &created_lifeline ) )
475 : {
476 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_LIFELINE, DATA_STAT_SERIES_CREATED );
477 : }
478 : }
479 : else
480 : {
481 0 : U8_LOG_ERROR( "unexpected error at ctrl_diagram_controller_create_diagramelement" );
482 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_ERROR );
483 : }
484 : (void) created_lifeline; /* currently unused */
485 :
486 : /* write report in case of anomalies */
487 2 : if ( u8_error_contains( modified_info, U8_ERROR_DUPLICATE_ID ) )
488 : {
489 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_WARNING );
490 0 : io_import_elements_private_report_id_differs( this_,
491 : data_diagramelement_get_data_id( diagramelement_ptr ),
492 0 : data_diagramelement_get_data_id( &((*this_).temp_diagramelement ) )
493 : );
494 : }
495 : }
496 2 : data_diagramelement_destroy( &((*this_).temp_diagramelement ) );
497 : }
498 :
499 14 : if ( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )
500 : {
501 : /* in paste mode, ignore diagramelements */
502 8 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_IGNORED );
503 : }
504 :
505 14 : U8_TRACE_END_ERR( sync_error );
506 14 : return sync_error;
507 : }
508 :
509 17 : u8_error_t io_import_elements_private_create_diagramelement( io_import_elements_t *this_, data_row_t classifier_id )
510 : {
511 17 : U8_TRACE_BEGIN();
512 17 : assert( DATA_ROW_VOID != classifier_id );
513 17 : u8_error_t sync_error = U8_ERROR_NONE;
514 :
515 17 : if ( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )
516 : {
517 : /* link the classifier to the current diagram */
518 17 : data_diagramelement_init_new( &((*this_).temp_diagramelement ),
519 : (*this_).paste_to_diagram,
520 : classifier_id,
521 : DATA_DIAGRAMELEMENT_FLAG_NONE,
522 : DATA_ROW_VOID
523 : );
524 : u8_error_t modified_info;
525 : data_id_t created_lifeline;
526 17 : sync_error = ctrl_multi_step_changer_create_diagramelement( &((*this_).multi_step_changer),
527 : &((*this_).temp_diagramelement ),
528 : &modified_info,
529 : &created_lifeline
530 : );
531 17 : if ( sync_error == U8_ERROR_NONE )
532 : {
533 17 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_CREATED );
534 17 : if ( data_id_is_valid( &created_lifeline ) )
535 : {
536 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_LIFELINE, DATA_STAT_SERIES_CREATED );
537 : }
538 : }
539 : else
540 : {
541 0 : U8_LOG_ERROR( "unexpected error at ctrl_diagram_controller_create_diagramelement" );
542 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_DIAGRAMELEMENT, DATA_STAT_SERIES_ERROR );
543 : }
544 : (void) created_lifeline; /* currently unused */
545 :
546 17 : data_diagramelement_destroy( &((*this_).temp_diagramelement ) );
547 : }
548 : else
549 : {
550 0 : U8_TRACE_INFO_INT( "no diagramelement created for new classifier:", classifier_id );
551 : }
552 :
553 17 : U8_TRACE_END_ERR( sync_error );
554 17 : return sync_error;
555 : }
556 :
557 21 : u8_error_t io_import_elements_sync_classifier( io_import_elements_t *this_,
558 : const data_classifier_t *classifier_ptr )
559 : {
560 21 : U8_TRACE_BEGIN();
561 21 : assert( NULL != classifier_ptr );
562 21 : u8_error_t sync_error = U8_ERROR_NONE;
563 21 : const bool do_sync = (( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )||( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_L ));
564 : /* const bool do_check = ( (*this_).step == IO_IMPORT_STEP_CHECK ); */
565 :
566 21 : if ( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )
567 : {
568 18 : if ( (*this_).paste_to_diagram == DATA_ROW_VOID )
569 : {
570 1 : sync_error = U8_ERROR_FOCUS_EMPTY;
571 1 : U8_TRACE_INFO( "in paste-clipboard mode, parent diagram must be valid" );
572 : }
573 : }
574 :
575 21 : if ( do_sync &&( sync_error == U8_ERROR_NONE ))
576 : {
577 : /* check if the parsed classifier already exists in this database; if not, create it */
578 18 : data_classifier_init_empty( &((*this_).temp_classifier ) );
579 : const u8_error_t read_error
580 18 : = data_database_reader_get_classifier_by_uuid( (*this_).db_reader,
581 : data_classifier_get_uuid_const( classifier_ptr ),
582 : &((*this_).temp_classifier)
583 : );
584 18 : const bool classifier_exists = ( U8_ERROR_NONE == read_error );
585 :
586 18 : if ( classifier_exists )
587 : {
588 : /* do the statistics */
589 4 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_IGNORED );
590 4 : U8_TRACE_INFO_INT( "classifier did already exist:", data_classifier_get_row( &((*this_).temp_classifier) ) );
591 : }
592 : else
593 : {
594 14 : data_classifier_replace( &((*this_).temp_classifier ), classifier_ptr );
595 :
596 : u8_error_t modified_info;
597 14 : sync_error = ctrl_multi_step_changer_create_classifier( &((*this_).multi_step_changer),
598 : &((*this_).temp_classifier ),
599 : &modified_info
600 : );
601 14 : if ( sync_error == U8_ERROR_NONE )
602 : {
603 14 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_CREATED );
604 : }
605 : else
606 : {
607 0 : U8_LOG_ERROR( "unexpected error at ctrl_classifier_controller_create_classifier/feature" );
608 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_ERROR );
609 : }
610 :
611 : /* write report in case of anomalies */
612 14 : if ( u8_error_contains( modified_info, U8_ERROR_DUPLICATE_ID ) )
613 : {
614 : /* warn on changed classifier ids. */
615 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_WARNING );
616 0 : io_import_elements_private_report_id_differs( this_,
617 : data_classifier_get_data_id( classifier_ptr ),
618 0 : data_classifier_get_data_id( &((*this_).temp_classifier ) )
619 : );
620 : }
621 14 : if ( u8_error_contains( modified_info, U8_ERROR_DUPLICATE_NAME ) )
622 : {
623 : /* warn on changed classifier names. */
624 3 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_CLASSIFIER, DATA_STAT_SERIES_WARNING );
625 6 : io_import_elements_private_report_name_differs( this_,
626 : data_classifier_get_name_const( classifier_ptr ),
627 3 : data_classifier_get_name_const( &((*this_).temp_classifier ) )
628 : );
629 : }
630 : }
631 :
632 18 : if (( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )&&( sync_error == U8_ERROR_NONE ))
633 : {
634 : /* in paste mode, create a diagramelement in the current diagram */
635 : /* after IO_IMPORT_STEP_CREATE_D_C_F_R there comes no other step to perform this. */
636 17 : const data_row_t classifier_row = data_classifier_get_row( &((*this_).temp_classifier ) );
637 17 : sync_error = io_import_elements_private_create_diagramelement( this_, classifier_row );
638 : }
639 :
640 18 : data_classifier_destroy( &((*this_).temp_classifier ) );
641 : }
642 :
643 21 : U8_TRACE_END_ERR( sync_error );
644 21 : return sync_error;
645 : }
646 :
647 22 : u8_error_t io_import_elements_sync_feature( io_import_elements_t *this_,
648 : const data_feature_t *feature_ptr,
649 : const char *classifier_uuid )
650 : {
651 22 : U8_TRACE_BEGIN();
652 22 : assert( NULL != feature_ptr );
653 22 : assert( NULL != classifier_uuid );
654 22 : u8_error_t sync_error = U8_ERROR_NONE;
655 : const bool is_lifeline
656 22 : = data_rules_feature_is_scenario_cond( &((*this_).data_rules), data_feature_get_main_type( feature_ptr ) );
657 44 : const bool do_sync = (( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )
658 22 : ||( is_lifeline ? ( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_L ) : ( (*this_).step == IO_IMPORT_STEP_ADD_E_DP_F_R ) ));
659 22 : const bool do_check = ( (*this_).step == IO_IMPORT_STEP_CHECK );
660 :
661 : /* ANY MODE: determine classifier id */
662 22 : data_row_t classifier_row = DATA_ROW_VOID;
663 22 : if (( do_check || do_sync )&&( classifier_uuid != NULL ))
664 : {
665 20 : if ( ! utf8string_equals_str( classifier_uuid, "" ) )
666 : {
667 20 : data_classifier_init_empty( &((*this_).temp_classifier ) );
668 : const u8_error_t read_error1
669 20 : = data_database_reader_get_classifier_by_uuid( (*this_).db_reader,
670 : classifier_uuid,
671 : &((*this_).temp_classifier)
672 : );
673 20 : if ( read_error1 == U8_ERROR_NOT_FOUND )
674 : {
675 2 : U8_TRACE_INFO_STR( "no classifier found, uuid:", classifier_uuid );
676 : }
677 18 : else if ( read_error1 != U8_ERROR_NONE )
678 : {
679 0 : U8_TRACE_INFO_STR( "parent classifier not found:", classifier_uuid );
680 : }
681 : else
682 : {
683 18 : classifier_row = data_classifier_get_row( &((*this_).temp_classifier ) );
684 : }
685 20 : data_classifier_destroy( &((*this_).temp_classifier ) );
686 : }
687 : }
688 :
689 : /* check preconditions */
690 22 : if ( do_sync )
691 : {
692 18 : if ( classifier_row == DATA_ROW_VOID )
693 : {
694 0 : sync_error |= U8_ERROR_VALUE_OUT_OF_RANGE;
695 0 : U8_LOG_ERROR( "feature references a non-existing classifier." );
696 : }
697 : }
698 :
699 22 : if ( do_sync && ( sync_error == U8_ERROR_NONE ) )
700 : {
701 : /* check if the parsed feature already exists in this database; if not, create it */
702 18 : data_feature_init_empty( &((*this_).temp_feature ) );
703 : const u8_error_t read_error
704 18 : = data_database_reader_get_feature_by_uuid( (*this_).db_reader,
705 : data_feature_get_uuid_const( feature_ptr ),
706 : &((*this_).temp_feature)
707 : );
708 18 : data_feature_destroy( &((*this_).temp_feature ) );
709 18 : const bool feature_exists = ( U8_ERROR_NONE == read_error );
710 :
711 18 : if ( feature_exists )
712 : {
713 : /* update statistics */
714 2 : const data_feature_type_t feat_type = data_feature_get_main_type( &((*this_).temp_feature) );
715 2 : const data_stat_table_t feat_or_lifeline
716 2 : = ( feat_type == DATA_FEATURE_TYPE_LIFELINE ) ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE;
717 2 : data_stat_inc_count( (*this_).stat, feat_or_lifeline, DATA_STAT_SERIES_IGNORED );
718 : }
719 : else
720 : {
721 : /* filter lifelines */
722 16 : if (( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )&&( is_lifeline ))
723 : {
724 : /* lifeline in paste mode */
725 8 : data_stat_inc_count( (*this_).stat,
726 : DATA_STAT_TABLE_LIFELINE, /* is_lifeline is true */
727 : DATA_STAT_SERIES_IGNORED
728 : );
729 8 : U8_TRACE_INFO( "lifeline dropped at json import." );
730 : }
731 : else
732 : {
733 : /* create feature */
734 8 : data_feature_copy( &((*this_).temp_feature ), feature_ptr );
735 8 : data_feature_set_classifier_row( &((*this_).temp_feature ), classifier_row );
736 :
737 : u8_error_t modified_info;
738 : const u8_error_t create_err
739 8 : = ctrl_multi_step_changer_create_feature( &((*this_).multi_step_changer),
740 : &((*this_).temp_feature ),
741 : &modified_info
742 : );
743 :
744 8 : if ( create_err == U8_ERROR_DIAGRAM_HIDES_FEATURES )
745 : {
746 : /* add to ignored and to warning. */
747 : /* ignored is needed for correct statistics */
748 : /* warning is needed to indicate that this may be different from expectation */
749 0 : data_stat_inc_count( (*this_).stat,
750 : is_lifeline ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE,
751 : DATA_STAT_SERIES_IGNORED
752 : );
753 0 : data_stat_inc_count( (*this_).stat,
754 : is_lifeline ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE,
755 : DATA_STAT_SERIES_WARNING
756 : );
757 0 : U8_LOG_WARNING( "invisible feature dropped at reading from data stream" );
758 : }
759 8 : else if ( create_err != U8_ERROR_NONE )
760 : {
761 0 : data_stat_inc_count( (*this_).stat,
762 : is_lifeline ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE,
763 : DATA_STAT_SERIES_ERROR
764 : );
765 0 : sync_error |= create_err;
766 : }
767 : else
768 : {
769 8 : data_stat_inc_count( (*this_).stat,
770 : is_lifeline ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE,
771 : DATA_STAT_SERIES_CREATED
772 : );
773 : }
774 8 : if ( sync_error != U8_ERROR_NONE )
775 : {
776 0 : U8_LOG_ERROR( "unexpected error at ctrl_classifier_controller_create_feature" );
777 : }
778 :
779 : /* write report in case of anomalies */
780 8 : if ( u8_error_contains( modified_info, U8_ERROR_DUPLICATE_ID ) )
781 : {
782 0 : data_stat_inc_count( (*this_).stat,
783 : is_lifeline ? DATA_STAT_TABLE_LIFELINE : DATA_STAT_TABLE_FEATURE,
784 : DATA_STAT_SERIES_WARNING
785 : );
786 0 : io_import_elements_private_report_id_differs( this_,
787 : data_feature_get_data_id( feature_ptr ),
788 0 : data_feature_get_data_id( &((*this_).temp_feature ) )
789 : );
790 : }
791 :
792 8 : data_feature_destroy( &((*this_).temp_feature ) );
793 : }
794 : }
795 : }
796 :
797 22 : U8_TRACE_END_ERR( sync_error );
798 22 : return sync_error;
799 : }
800 :
801 14 : u8_error_t io_import_elements_sync_relationship( io_import_elements_t *this_,
802 : const data_relationship_t *relation_ptr,
803 : const char *from_node_uuid,
804 : const char *to_node_uuid )
805 : {
806 14 : U8_TRACE_BEGIN();
807 14 : assert( NULL != relation_ptr );
808 14 : assert( NULL != from_node_uuid );
809 14 : assert( NULL != to_node_uuid );
810 14 : u8_error_t sync_error = U8_ERROR_NONE;
811 14 : const bool do_sync = (( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )||( (*this_).step == IO_IMPORT_STEP_ADD_E_DP_F_R ));
812 14 : const bool do_check = ( (*this_).step == IO_IMPORT_STEP_CHECK );
813 :
814 : /* ANY MODE: determine from classifier/feature */
815 14 : data_row_t from_classifier_id = DATA_ROW_VOID;
816 14 : data_row_t from_feature_id = DATA_ROW_VOID;
817 14 : data_feature_type_t from_feature_type = DATA_FEATURE_TYPE_VOID;
818 14 : if (( do_check || do_sync )&&( from_node_uuid != NULL ))
819 : {
820 13 : if ( ! utf8string_equals_str( from_node_uuid, "" ) )
821 : {
822 : /* search source classifier id */
823 13 : data_classifier_init_empty( &((*this_).temp_classifier ) );
824 : const u8_error_t read_error1
825 13 : = data_database_reader_get_classifier_by_uuid( (*this_).db_reader,
826 : from_node_uuid,
827 : &((*this_).temp_classifier)
828 : );
829 13 : if ( U8_ERROR_NONE == read_error1 )
830 : {
831 8 : from_classifier_id = data_classifier_get_row( &((*this_).temp_classifier) );
832 8 : U8_TRACE_INFO_STR( "id found for src classifier:", from_node_uuid );
833 : }
834 : else
835 : {
836 : /* search source feature id */
837 5 : data_feature_init_empty( &((*this_).temp_feature) );
838 : const u8_error_t read_error2
839 5 : = data_database_reader_get_feature_by_uuid( (*this_).db_reader,
840 : from_node_uuid,
841 : &((*this_).temp_feature)
842 : );
843 5 : if ( U8_ERROR_NONE == read_error2 )
844 : {
845 1 : from_classifier_id = data_feature_get_classifier_row( &((*this_).temp_feature) );
846 1 : from_feature_id = data_feature_get_row( &((*this_).temp_feature) );
847 1 : from_feature_type = data_feature_get_main_type( &((*this_).temp_feature) );
848 1 : U8_TRACE_INFO_STR( "id found for src feature:", from_node_uuid );
849 : }
850 : else
851 : {
852 4 : U8_TRACE_INFO_STR( "relationship source not found", from_node_uuid );
853 : }
854 5 : data_feature_destroy( &((*this_).temp_feature) );
855 : }
856 13 : data_classifier_destroy( &((*this_).temp_classifier ) );
857 : }
858 : }
859 :
860 : /* ANY MODE: determine to classifier/feature */
861 14 : data_row_t to_classifier_id = DATA_ROW_VOID;
862 14 : data_row_t to_feature_id = DATA_ROW_VOID;
863 14 : data_feature_type_t to_feature_type = DATA_FEATURE_TYPE_VOID;
864 14 : if (( do_check || do_sync )&&( to_node_uuid != NULL ))
865 : {
866 13 : if ( ! utf8string_equals_str( to_node_uuid, "" ) )
867 : {
868 : /* search destination classifier id */
869 13 : data_classifier_init_empty( &((*this_).temp_classifier ) );
870 : const u8_error_t read_error3
871 13 : = data_database_reader_get_classifier_by_uuid( (*this_).db_reader,
872 : to_node_uuid,
873 : &((*this_).temp_classifier)
874 : );
875 13 : if ( U8_ERROR_NONE == read_error3 )
876 : {
877 7 : to_classifier_id = data_classifier_get_row( &((*this_).temp_classifier) );
878 7 : U8_TRACE_INFO_STR( "id found for dst classifier:", to_node_uuid );
879 : }
880 : else
881 : {
882 : /* search dst feature id */
883 6 : data_feature_init_empty( &((*this_).temp_feature) );
884 : const u8_error_t read_error4
885 6 : = data_database_reader_get_feature_by_uuid( (*this_).db_reader,
886 : to_node_uuid,
887 : &((*this_).temp_feature)
888 : );
889 6 : if ( U8_ERROR_NONE == read_error4 )
890 : {
891 2 : to_classifier_id = data_feature_get_classifier_row( &((*this_).temp_feature) );
892 2 : to_feature_id = data_feature_get_row( &((*this_).temp_feature) );
893 2 : to_feature_type = data_feature_get_main_type( &((*this_).temp_feature) );
894 2 : U8_TRACE_INFO_STR( "id found for src feature:", to_node_uuid );
895 : }
896 : else
897 : {
898 4 : U8_TRACE_INFO_STR( "relationship destination not found", to_node_uuid );
899 : }
900 6 : data_feature_destroy( &((*this_).temp_feature) );
901 : }
902 13 : data_classifier_destroy( &((*this_).temp_classifier ) );
903 : }
904 : }
905 :
906 : /* check preconditions */
907 14 : bool valid_links = true;
908 14 : if ( do_sync )
909 : {
910 12 : if ( from_classifier_id == DATA_ROW_VOID )
911 : {
912 3 : valid_links = false;
913 3 : U8_LOG_ERROR( "A relationship could not be created because the source classifier could not be found." );
914 : }
915 12 : if ( to_classifier_id == DATA_ROW_VOID )
916 : {
917 3 : valid_links = false;
918 3 : U8_LOG_ERROR( "A relationship could not be created because the destination classifier could not be found." );
919 : }
920 12 : if ( ! valid_links )
921 : {
922 3 : const bool is_scenario = data_rules_relationship_is_scenario_cond( &((*this_).data_rules),
923 : from_feature_type,
924 : to_feature_type
925 : );
926 3 : U8_TRACE_INFO( is_scenario ? "relationship in interaction scenario dropped" : "general relationship dropped" );
927 :
928 3 : const bool features_ignored
929 3 : = ( 0 < data_stat_get_count( (*this_).stat, DATA_STAT_TABLE_FEATURE, DATA_STAT_SERIES_IGNORED ) )
930 3 : || ( 0 < data_stat_get_count( (*this_).stat, DATA_STAT_TABLE_LIFELINE, DATA_STAT_SERIES_IGNORED ) );
931 3 : if ( features_ignored )
932 : {
933 3 : U8_TRACE_INFO( "continuing despite illegal relationship because this may be caused by an invisible feature/lifeline" );
934 : /* add to ignored and to warning. */
935 : /* ignored is needed for correct statistics */
936 : /* warning is needed to indicate that this may be different from expectation */
937 3 : data_stat_inc_count( (*this_).stat,
938 : DATA_STAT_TABLE_RELATIONSHIP,
939 : DATA_STAT_SERIES_IGNORED
940 : );
941 3 : data_stat_inc_count( (*this_).stat,
942 : DATA_STAT_TABLE_RELATIONSHIP,
943 : DATA_STAT_SERIES_WARNING
944 : );
945 : }
946 0 : else if ( (*this_).step == IO_IMPORT_STEP_CREATE_D_C_F_R )
947 : {
948 0 : U8_TRACE_INFO( "continuing despite illegal relationship because this may be caused by incomplete model" );
949 : /* add to ignored and warning. */
950 : /* ignored is needed for correct statistics */
951 : /* warning is needed to indicate that this may be different from expectation */
952 0 : data_stat_inc_count( (*this_).stat,
953 : DATA_STAT_TABLE_RELATIONSHIP,
954 : DATA_STAT_SERIES_IGNORED
955 : );
956 0 : data_stat_inc_count( (*this_).stat,
957 : DATA_STAT_TABLE_RELATIONSHIP,
958 : DATA_STAT_SERIES_WARNING
959 : );
960 : }
961 : else
962 : {
963 0 : sync_error |= U8_ERROR_VALUE_OUT_OF_RANGE;
964 : }
965 : }
966 : }
967 :
968 14 : if ( do_sync && valid_links )
969 : {
970 : /* check if the parsed relationship already exists in this database; if not, create it */
971 9 : data_relationship_init_empty( &((*this_).temp_relationship ) );
972 : const u8_error_t read_error5
973 9 : = data_database_reader_get_relationship_by_uuid( (*this_).db_reader,
974 : data_relationship_get_uuid_const( relation_ptr ),
975 : &((*this_).temp_relationship)
976 : );
977 9 : data_relationship_destroy( &((*this_).temp_relationship ) );
978 9 : const bool relationship_exists = ( U8_ERROR_NONE == read_error5 );
979 :
980 9 : if ( relationship_exists )
981 : {
982 : /* update statistics */
983 1 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_IGNORED );
984 : }
985 : else
986 : {
987 : /* create relationship */
988 8 : data_relationship_copy( &((*this_).temp_relationship ), relation_ptr );
989 8 : data_relationship_set_row( &((*this_).temp_relationship ), data_relationship_get_row( relation_ptr ) );
990 8 : data_relationship_set_from_classifier_row( &((*this_).temp_relationship ), from_classifier_id );
991 8 : data_relationship_set_from_feature_row( &((*this_).temp_relationship ), from_feature_id );
992 8 : data_relationship_set_to_classifier_row( &((*this_).temp_relationship ), to_classifier_id );
993 8 : data_relationship_set_to_feature_row( &((*this_).temp_relationship ), to_feature_id );
994 :
995 : /* create relationship */
996 : u8_error_t modified_info;
997 : const u8_error_t create_err
998 8 : = ctrl_multi_step_changer_create_relationship( &((*this_).multi_step_changer),
999 : &((*this_).temp_relationship ),
1000 : &modified_info
1001 : );
1002 8 : if ( create_err == U8_ERROR_DIAGRAM_HIDES_RELATIONSHIPS )
1003 : {
1004 : /* add to ignored and to warning. */
1005 : /* ignored is needed for correct statistics */
1006 : /* warning is needed to indicate that this may be different from expectation */
1007 0 : data_stat_inc_count( (*this_).stat,
1008 : DATA_STAT_TABLE_RELATIONSHIP,
1009 : DATA_STAT_SERIES_IGNORED
1010 : );
1011 0 : data_stat_inc_count( (*this_).stat,
1012 : DATA_STAT_TABLE_RELATIONSHIP,
1013 : DATA_STAT_SERIES_WARNING
1014 : );
1015 0 : U8_LOG_WARNING( "invisible relationship dropped at reading from data stream" );
1016 : }
1017 8 : else if ( create_err != U8_ERROR_NONE )
1018 : {
1019 0 : U8_LOG_ERROR( "unexpected error at ctrl_classifier_controller_create_relationship" );
1020 0 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_ERROR );
1021 0 : sync_error |= create_err;
1022 : }
1023 : else
1024 : {
1025 8 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_CREATED );
1026 : }
1027 :
1028 : /* write report in case of anomalies */
1029 8 : if ( u8_error_contains( modified_info, U8_ERROR_DUPLICATE_ID ) )
1030 : {
1031 2 : data_stat_inc_count( (*this_).stat, DATA_STAT_TABLE_RELATIONSHIP, DATA_STAT_SERIES_WARNING );
1032 4 : io_import_elements_private_report_id_differs( this_,
1033 : data_relationship_get_data_id( relation_ptr ),
1034 2 : data_relationship_get_data_id( &((*this_).temp_relationship ) )
1035 : );
1036 : }
1037 :
1038 8 : data_relationship_destroy( &((*this_).temp_relationship ) );
1039 : }
1040 : }
1041 :
1042 14 : U8_TRACE_END_ERR( sync_error );
1043 14 : return sync_error;
1044 : }
1045 :
1046 2 : void io_import_elements_private_report_id_differs( io_import_elements_t *this_, data_id_t req_id, data_id_t act_id )
1047 : {
1048 2 : U8_TRACE_BEGIN();
1049 2 : u8_error_t report_err = U8_ERROR_NONE;
1050 :
1051 2 : report_err |= utf8stream_writer_write_str( (*this_).english_report, "Id changed: " );
1052 2 : report_err |= data_id_to_utf8_writer( &req_id, (*this_).english_report );
1053 2 : report_err |= utf8stream_writer_write_str( (*this_).english_report, " -> " );
1054 2 : report_err |= data_id_to_utf8_writer( &act_id, (*this_).english_report );
1055 2 : report_err |= utf8stream_writer_write_str( (*this_).english_report, ", " );
1056 2 : if ( report_err != U8_ERROR_NONE )
1057 : {
1058 0 : U8_LOG_ERROR_HEX( "Could not write report on import, ERR:", report_err );
1059 : }
1060 :
1061 2 : U8_TRACE_END();
1062 2 : }
1063 :
1064 3 : void io_import_elements_private_report_name_differs( io_import_elements_t *this_, const char *req_name, const char *act_name )
1065 : {
1066 3 : U8_TRACE_BEGIN();
1067 3 : assert( NULL != req_name );
1068 3 : assert( NULL != act_name );
1069 3 : u8_error_t report_err = U8_ERROR_NONE;
1070 :
1071 3 : report_err |= utf8stream_writer_write_str( (*this_).english_report, "Name changed: \"" );
1072 3 : report_err |= utf8stream_writer_write_str( (*this_).english_report, req_name );
1073 3 : report_err |= utf8stream_writer_write_str( (*this_).english_report, "\" -> \"" );
1074 3 : report_err |= utf8stream_writer_write_str( (*this_).english_report, act_name );
1075 3 : report_err |= utf8stream_writer_write_str( (*this_).english_report, "\", " );
1076 3 : if ( report_err != U8_ERROR_NONE )
1077 : {
1078 0 : U8_LOG_ERROR_HEX( "Could not write report on import, ERR:", report_err );
1079 : }
1080 :
1081 3 : U8_TRACE_END();
1082 3 : }
1083 :
1084 :
1085 : /*
1086 : Copyright 2021-2026 Andreas Warnke
1087 :
1088 : Licensed under the Apache License, Version 2.0 (the "License");
1089 : you may not use this file except in compliance with the License.
1090 : You may obtain a copy of the License at
1091 :
1092 : http://www.apache.org/licenses/LICENSE-2.0
1093 :
1094 : Unless required by applicable law or agreed to in writing, software
1095 : distributed under the License is distributed on an "AS IS" BASIS,
1096 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1097 : See the License for the specific language governing permissions and
1098 : limitations under the License.
1099 : */
|