Line data Source code
1 : /* File: io_export_flat_traversal.c; Copyright and License: see below */
2 :
3 : #include "io_export_flat_traversal.h"
4 : #include "u8/u8_trace.h"
5 : #include "entity/data_diagram.h"
6 : #include "entity/data_classifier.h"
7 : #include <stdint.h>
8 : #include <stdio.h>
9 : #include <stdlib.h>
10 :
11 0 : void io_export_flat_traversal_init( io_export_flat_traversal_t *this_,
12 : data_database_reader_t *db_reader,
13 : data_stat_t *io_export_stat,
14 : io_element_writer_t *out_element_writer )
15 : {
16 0 : U8_TRACE_BEGIN();
17 0 : assert( NULL != db_reader );
18 0 : assert( NULL != io_export_stat );
19 0 : assert( NULL != out_element_writer );
20 :
21 0 : (*this_).db_reader = db_reader;
22 0 : (*this_).export_stat = io_export_stat;
23 0 : (*this_).element_writer = out_element_writer;
24 :
25 0 : U8_TRACE_END();
26 0 : }
27 :
28 0 : void io_export_flat_traversal_destroy( io_export_flat_traversal_t *this_ )
29 : {
30 0 : U8_TRACE_BEGIN();
31 :
32 0 : (*this_).db_reader = NULL;
33 0 : (*this_).export_stat = NULL;
34 0 : (*this_).element_writer = NULL;
35 :
36 0 : U8_TRACE_END();
37 0 : }
38 :
39 0 : u8_error_t io_export_flat_traversal_iterate_classifiers ( io_export_flat_traversal_t *this_, bool hierarchical )
40 : {
41 0 : U8_TRACE_BEGIN();
42 0 : u8_error_t write_err = U8_ERROR_NONE;
43 :
44 : {
45 : u8_error_t data_err;
46 : data_database_iterator_classifiers_t classifier_iterator;
47 :
48 : /* init the iterator */
49 0 : data_database_iterator_classifiers_init_empty( &classifier_iterator );
50 0 : data_err = data_database_reader_get_all_classifiers_iterator ( (*this_).db_reader, hierarchical, &classifier_iterator );
51 0 : if ( data_err != U8_ERROR_NONE )
52 : {
53 0 : write_err = -1;
54 : }
55 : else
56 : {
57 0 : while( data_database_iterator_classifiers_has_next( &classifier_iterator ) && ( write_err==0 ) )
58 : {
59 0 : data_err = data_database_iterator_classifiers_next( &classifier_iterator, &((*this_).temp_classifier) );
60 0 : if ( data_err != U8_ERROR_NONE )
61 : {
62 0 : write_err = -1;
63 : }
64 : else
65 : {
66 0 : write_err |= io_export_flat_traversal_private_traverse_classifier( this_, &((*this_).temp_classifier) );
67 :
68 0 : data_classifier_destroy( &((*this_).temp_classifier) );
69 : }
70 : }
71 : }
72 0 : data_err = data_database_iterator_classifiers_destroy( &classifier_iterator );
73 0 : if ( data_err != U8_ERROR_NONE )
74 : {
75 0 : write_err = -1;
76 : }
77 : }
78 :
79 0 : U8_TRACE_END_ERR( write_err );
80 0 : return write_err;
81 : }
82 :
83 0 : u8_error_t io_export_flat_traversal_private_traverse_classifier ( io_export_flat_traversal_t *this_,
84 : const data_classifier_t *classifier )
85 : {
86 0 : U8_TRACE_BEGIN();
87 0 : assert( NULL != classifier );
88 0 : assert( data_classifier_is_valid( classifier ) );
89 0 : u8_error_t write_err = U8_ERROR_NONE;
90 :
91 : /* start classifier */
92 : {
93 0 : const data_classifier_type_t host_type = DATA_CLASSIFIER_TYPE_VOID;
94 0 : write_err |= io_element_writer_start_classifier( (*this_).element_writer, host_type, classifier );
95 0 : write_err |= io_element_writer_assemble_classifier( (*this_).element_writer, host_type, classifier );
96 : }
97 :
98 : /* start features and relationships */
99 : {
100 0 : data_node_set_init( &((*this_).temp_node_data) );
101 : const u8_error_t data_err_2
102 0 : = data_node_set_load( &((*this_).temp_node_data),
103 : data_classifier_get_row_id( classifier ),
104 : (*this_).db_reader
105 : );
106 :
107 0 : if ( data_err_2 != U8_ERROR_NONE )
108 : {
109 0 : write_err = -1;
110 : }
111 : else
112 : {
113 : /* write the features */
114 0 : write_err |= io_export_flat_traversal_private_iterate_features( this_, &((*this_).temp_node_data) );
115 :
116 : /* write the relationships */
117 0 : write_err |= io_export_flat_traversal_private_iterate_relationships( this_, &((*this_).temp_node_data) );
118 : }
119 :
120 0 : data_node_set_destroy( &((*this_).temp_node_data) );
121 : }
122 :
123 : /* end classifier */
124 : {
125 0 : const data_classifier_type_t host_type = DATA_CLASSIFIER_TYPE_VOID;
126 0 : write_err |= io_element_writer_end_classifier( (*this_).element_writer, host_type, classifier );
127 : }
128 :
129 0 : U8_TRACE_END_ERR( write_err );
130 0 : return write_err;
131 : }
132 :
133 0 : u8_error_t io_export_flat_traversal_private_iterate_features ( io_export_flat_traversal_t *this_,
134 : const data_node_set_t *node_data )
135 : {
136 0 : U8_TRACE_BEGIN();
137 0 : assert( node_data != NULL );
138 0 : assert( data_node_set_is_valid( node_data ) );
139 0 : u8_error_t write_err = U8_ERROR_NONE;
140 :
141 : /* get parent classifier */
142 : const data_classifier_t *const classifier
143 0 : = data_node_set_get_classifier_const ( node_data );
144 :
145 : /* iterate over all features */
146 0 : const uint32_t count = data_node_set_get_feature_count ( node_data );
147 0 : for ( uint32_t index = 0; index < count; index ++ )
148 : {
149 : /* get feature */
150 : const data_feature_t *feature;
151 0 : feature = data_node_set_get_feature_const ( node_data, index );
152 0 : if (( feature != NULL ) && ( data_feature_is_valid( feature ) ))
153 0 : {
154 0 : const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
155 0 : write_err |= io_element_writer_start_feature( (*this_).element_writer, classifier_type, feature );
156 0 : write_err |= io_element_writer_assemble_feature( (*this_).element_writer, classifier, feature );
157 0 : write_err |= io_element_writer_end_feature( (*this_).element_writer, classifier_type, feature );
158 : }
159 : else
160 : {
161 0 : assert( false );
162 : }
163 : }
164 :
165 0 : U8_TRACE_END_ERR( write_err );
166 0 : return write_err;
167 : }
168 :
169 0 : u8_error_t io_export_flat_traversal_private_iterate_relationships ( io_export_flat_traversal_t *this_,
170 : const data_node_set_t *node_data )
171 : {
172 0 : U8_TRACE_BEGIN();
173 0 : assert( node_data != NULL );
174 0 : assert( data_node_set_is_valid( node_data ) );
175 0 : u8_error_t write_err = U8_ERROR_NONE;
176 :
177 0 : const data_classifier_t *const classifier = data_node_set_get_classifier_const ( node_data );
178 0 : const data_classifier_type_t host_type = data_classifier_get_main_type( classifier );
179 :
180 : /* iterate over all relationships */
181 0 : const uint32_t count = data_node_set_get_relationship_count ( node_data );
182 0 : for ( uint32_t index = 0; index < count; index ++ )
183 : {
184 : /* get relationship */
185 : const data_relationship_t *relation;
186 0 : relation = data_node_set_get_relationship_const ( node_data, index );
187 0 : if (( relation != NULL ) && ( data_relationship_is_valid( relation ) ))
188 0 : {
189 : /* determine if the relationship is outgoing */
190 0 : const bool is_outgoing
191 0 : = ( data_relationship_get_from_classifier_row_id( relation ) == data_classifier_get_row_id( classifier ) );
192 0 : if ( is_outgoing )
193 : {
194 : /* get the element types at both ends of the relationship */
195 0 : data_classifier_init_empty( &((*this_).temp_from_classifier) );
196 0 : data_feature_init_empty( &((*this_).temp_from_feature) );
197 0 : data_classifier_init_empty( &((*this_).temp_to_classifier) );
198 0 : data_feature_init_empty( &((*this_).temp_to_feature) );
199 :
200 : const u8_error_t d_err
201 0 : = io_export_flat_traversal_private_get_relationship_ends( this_,
202 : relation,
203 : node_data,
204 : &((*this_).temp_from_classifier),
205 : &((*this_).temp_from_feature),
206 : &((*this_).temp_to_classifier),
207 : &((*this_).temp_to_feature)
208 : );
209 :
210 0 : if ( d_err == U8_ERROR_NONE )
211 : {
212 : /* all classifiers found, print the relation */
213 0 : write_err |= io_element_writer_start_relationship( (*this_).element_writer, host_type, relation );
214 0 : write_err |= io_element_writer_assemble_relationship( (*this_).element_writer,
215 : classifier,
216 : relation,
217 0 : &((*this_).temp_from_classifier),
218 0 : &((*this_).temp_from_feature),
219 0 : &((*this_).temp_to_classifier),
220 0 : &((*this_).temp_to_feature)
221 : );
222 0 : write_err |= io_element_writer_end_relationship( (*this_).element_writer, host_type, relation );
223 : }
224 : else
225 : {
226 0 : write_err |= -1;
227 : }
228 :
229 0 : data_classifier_destroy( &((*this_).temp_from_classifier) );
230 0 : data_feature_destroy( &((*this_).temp_from_feature) );
231 0 : data_classifier_destroy( &((*this_).temp_to_classifier) );
232 0 : data_feature_destroy( &((*this_).temp_to_feature) );
233 : }
234 : }
235 : else
236 : {
237 0 : assert( false );
238 : }
239 : }
240 :
241 0 : U8_TRACE_END_ERR( write_err );
242 0 : return write_err;
243 : }
244 :
245 0 : u8_error_t io_export_flat_traversal_private_get_relationship_ends( io_export_flat_traversal_t *this_,
246 : const data_relationship_t *relation,
247 : const data_node_set_t *node_data,
248 : data_classifier_t *out_from_c,
249 : data_feature_t *out_from_f,
250 : data_classifier_t *out_to_c,
251 : data_feature_t *out_to_f )
252 : {
253 0 : U8_TRACE_BEGIN();
254 0 : assert( relation != NULL );
255 0 : assert( node_data != NULL );
256 0 : assert( out_from_c != NULL );
257 0 : assert( out_from_f != NULL );
258 0 : assert( out_to_c != NULL );
259 0 : assert( out_to_f != NULL );
260 0 : u8_error_t data_err = U8_ERROR_NONE;
261 :
262 : {
263 : /* get from classifier */
264 0 : const data_row_id_t from_clcassifier_row_id = data_relationship_get_from_classifier_row_id ( relation );
265 0 : bool from_classifier_found = false;
266 0 : if ( node_data != NULL )
267 : {
268 : const data_classifier_t *node_classifier
269 0 : = data_node_set_get_classifier_const( node_data );
270 0 : if (( node_classifier != NULL )
271 0 : &&( from_clcassifier_row_id == data_classifier_get_row_id ( node_classifier ) ))
272 : {
273 0 : data_classifier_replace( out_from_c, node_classifier );
274 0 : from_classifier_found = true;
275 : }
276 : }
277 0 : if ( ! from_classifier_found )
278 : {
279 0 : data_err |= data_database_reader_get_classifier_by_id ( (*this_).db_reader,
280 : from_clcassifier_row_id,
281 : out_from_c
282 : );
283 : }
284 :
285 : /* get from feature */
286 0 : const data_row_id_t from_feature_row_id = data_relationship_get_from_feature_row_id ( relation );
287 0 : bool from_feature_found = ( from_feature_row_id == DATA_ROW_ID_VOID );
288 0 : if (( node_data != NULL )&&( ! from_feature_found ))
289 : {
290 : const data_feature_t *node_feature
291 0 : = data_node_set_get_feature_by_id_const ( node_data, from_feature_row_id );
292 0 : if ( node_feature != NULL )
293 : {
294 0 : data_feature_replace( out_from_f, node_feature );
295 0 : from_feature_found = true;
296 : }
297 : }
298 0 : if ( ! from_feature_found )
299 : {
300 0 : data_err |= data_database_reader_get_feature_by_id ( (*this_).db_reader,
301 : from_feature_row_id,
302 : out_from_f
303 : );
304 : }
305 :
306 : /* get to classifier */
307 0 : const data_row_id_t to_classifier_row_id = data_relationship_get_to_classifier_row_id ( relation );
308 0 : bool to_classifier_found = false;
309 0 : if ( node_data != NULL )
310 : {
311 : const data_classifier_t *node_classifier
312 0 : = data_node_set_get_classifier_const( node_data );
313 0 : if (( node_classifier != NULL )
314 0 : &&( to_classifier_row_id == data_classifier_get_row_id ( node_classifier ) ))
315 : {
316 0 : data_classifier_replace( out_to_c, node_classifier );
317 0 : to_classifier_found = true;
318 : }
319 : }
320 0 : if ( ! to_classifier_found )
321 : {
322 0 : data_err |= data_database_reader_get_classifier_by_id ( (*this_).db_reader,
323 : to_classifier_row_id,
324 : out_to_c
325 : );
326 : }
327 :
328 : /* get to feature */
329 0 : const data_row_id_t to_feature_row_id = data_relationship_get_to_feature_row_id ( relation );
330 0 : bool to_feature_found = ( to_feature_row_id == DATA_ROW_ID_VOID );
331 0 : if (( node_data != NULL )&&( ! to_feature_found ))
332 : {
333 : const data_feature_t *node_feature
334 0 : = data_node_set_get_feature_by_id_const ( node_data, to_feature_row_id );
335 0 : if ( node_feature != NULL )
336 : {
337 0 : data_feature_replace( out_to_f, node_feature );
338 0 : to_feature_found = true;
339 : }
340 : }
341 0 : if ( ! to_feature_found )
342 : {
343 0 : data_err |= data_database_reader_get_feature_by_id ( (*this_).db_reader,
344 : to_feature_row_id,
345 : out_to_f
346 : );
347 : }
348 : }
349 :
350 0 : if ( data_err != U8_ERROR_NONE )
351 : {
352 0 : U8_LOG_ERROR_INT( "A relationship references classifier(s) and/or feature(s) that do not exist:",
353 : data_relationship_get_row_id ( relation )
354 : );
355 : }
356 0 : U8_TRACE_END_ERR( data_err );
357 0 : return data_err;
358 : }
359 :
360 :
361 : /*
362 : Copyright 2021-2024 Andreas Warnke
363 :
364 : Licensed under the Apache License, Version 2.0 (the "License");
365 : you may not use this file except in compliance with the License.
366 : You may obtain a copy of the License at
367 :
368 : http://www.apache.org/licenses/LICENSE-2.0
369 :
370 : Unless required by applicable law or agreed to in writing, software
371 : distributed under the License is distributed on an "AS IS" BASIS,
372 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
373 : See the License for the specific language governing permissions and
374 : limitations under the License.
375 : */
|