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