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 2 : 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 2 : U8_TRACE_BEGIN();
17 2 : assert( NULL != db_reader );
18 2 : assert( NULL != io_export_stat );
19 2 : assert( NULL != out_element_writer );
20 :
21 2 : (*this_).db_reader = db_reader;
22 2 : (*this_).export_stat = io_export_stat;
23 2 : (*this_).element_writer = out_element_writer;
24 :
25 2 : U8_TRACE_END();
26 2 : }
27 :
28 2 : void io_export_flat_traversal_destroy( io_export_flat_traversal_t *this_ )
29 : {
30 2 : U8_TRACE_BEGIN();
31 :
32 2 : (*this_).db_reader = NULL;
33 2 : (*this_).export_stat = NULL;
34 2 : (*this_).element_writer = NULL;
35 :
36 2 : U8_TRACE_END();
37 2 : }
38 :
39 4 : u8_error_t io_export_flat_traversal_iterate_classifiers( io_export_flat_traversal_t *this_, bool hierarchical )
40 : {
41 4 : U8_TRACE_BEGIN();
42 4 : u8_error_t write_err = U8_ERROR_NONE;
43 :
44 : {
45 : u8_error_t data_err;
46 : data_classifier_iterator_t classifier_iterator;
47 :
48 : /* init the iterator */
49 4 : data_classifier_iterator_init_empty( &classifier_iterator );
50 4 : data_err = data_database_reader_get_all_classifiers ( (*this_).db_reader, hierarchical, &classifier_iterator );
51 4 : if ( data_err != U8_ERROR_NONE )
52 : {
53 0 : write_err |= data_err;
54 : }
55 : else
56 : {
57 4 : while( data_classifier_iterator_has_next( &classifier_iterator ) && ( write_err == U8_ERROR_NONE ) )
58 : {
59 0 : data_err = data_classifier_iterator_next( &classifier_iterator, &((*this_).temp_classifier) );
60 0 : if ( data_err != U8_ERROR_NONE )
61 : {
62 0 : write_err |= data_err;
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 4 : data_err = data_classifier_iterator_destroy( &classifier_iterator );
73 4 : if ( data_err != U8_ERROR_NONE )
74 : {
75 0 : write_err |= data_err;
76 : }
77 : }
78 :
79 4 : U8_TRACE_END_ERR( write_err );
80 4 : 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 : u8_error_t data_err_3 = U8_ERROR_NONE;
101 :
102 : /* write the features */
103 : data_feature_iterator_t feature_iterator;
104 0 : data_err_3 |= data_feature_iterator_init_empty( &feature_iterator );
105 0 : data_err_3 |= data_database_reader_get_features_by_classifier_id( (*this_).db_reader,
106 : data_classifier_get_row_id( classifier ),
107 : &feature_iterator
108 : );
109 0 : write_err |= io_export_flat_traversal_private_iterate_features( this_, classifier, &feature_iterator );
110 0 : data_err_3 |= data_feature_iterator_destroy( &feature_iterator );
111 :
112 : /* write the relationships */
113 : data_relationship_iterator_t rel_iterator;
114 0 : data_err_3 |= data_relationship_iterator_init_empty( &rel_iterator );
115 0 : data_err_3 |= data_database_reader_get_relationships_by_classifier_id( (*this_).db_reader,
116 : data_classifier_get_row_id( classifier ),
117 : &rel_iterator
118 : );
119 0 : write_err |= io_export_flat_traversal_private_iterate_relationships( this_, classifier, &rel_iterator );
120 0 : data_err_3 |= data_relationship_iterator_destroy( &rel_iterator );
121 :
122 : /* if errors at reading the database, add these to the result */
123 0 : if ( data_err_3 != U8_ERROR_NONE )
124 : {
125 0 : write_err |= data_err_3;
126 : }
127 : }
128 :
129 : /* end classifier */
130 : {
131 0 : const data_classifier_type_t host_type = DATA_CLASSIFIER_TYPE_VOID;
132 0 : write_err |= io_element_writer_end_classifier( (*this_).element_writer, host_type, classifier );
133 : }
134 :
135 0 : U8_TRACE_END_ERR( write_err );
136 0 : return write_err;
137 : }
138 :
139 0 : u8_error_t io_export_flat_traversal_private_iterate_features( io_export_flat_traversal_t *this_,
140 : const data_classifier_t *classifier,
141 : data_feature_iterator_t *feature_iterator )
142 : {
143 0 : U8_TRACE_BEGIN();
144 0 : assert( classifier != NULL );
145 0 : assert( data_classifier_is_valid( classifier ) );
146 0 : assert( feature_iterator != NULL );
147 0 : u8_error_t write_err = U8_ERROR_NONE;
148 0 : u8_error_t data_err = U8_ERROR_NONE;
149 :
150 : /* iterate over all features */
151 0 : while ( data_feature_iterator_has_next( feature_iterator ) )
152 : {
153 : /* get feature */
154 0 : data_err |= data_feature_iterator_next( feature_iterator, &((*this_).temp_from_feature) );
155 0 : if ( data_feature_is_valid( &((*this_).temp_from_feature) ) )
156 : {
157 0 : const data_classifier_type_t classifier_type = data_classifier_get_main_type( classifier );
158 0 : write_err |= io_element_writer_start_feature( (*this_).element_writer, classifier_type, &((*this_).temp_from_feature) );
159 0 : write_err |= io_element_writer_assemble_feature( (*this_).element_writer, classifier, &((*this_).temp_from_feature) );
160 0 : write_err |= io_element_writer_end_feature( (*this_).element_writer, classifier_type, &((*this_).temp_from_feature) );
161 : }
162 : else
163 : {
164 0 : assert( false );
165 : }
166 : }
167 :
168 0 : write_err |= data_err; /* result is the combination of writing errors and reading errors */
169 0 : U8_TRACE_END_ERR( write_err );
170 0 : return write_err;
171 : }
172 :
173 0 : u8_error_t io_export_flat_traversal_private_iterate_relationships( io_export_flat_traversal_t *this_,
174 : const data_classifier_t *classifier,
175 : data_relationship_iterator_t *relationship_iterator )
176 : {
177 0 : U8_TRACE_BEGIN();
178 0 : assert( classifier != NULL );
179 0 : assert( relationship_iterator != NULL );
180 0 : assert( data_classifier_is_valid( classifier ) );
181 0 : assert( relationship_iterator != NULL );
182 0 : u8_error_t write_err = U8_ERROR_NONE;
183 0 : u8_error_t data_err = U8_ERROR_NONE;
184 :
185 0 : const data_classifier_type_t host_type = data_classifier_get_main_type( classifier );
186 :
187 : /* iterate over all relationships */
188 0 : while ( data_relationship_iterator_has_next( relationship_iterator ) )
189 : {
190 : /* get relationship */
191 0 : data_err |= data_relationship_iterator_next( relationship_iterator, &((*this_).temp_relationship) );
192 0 : const data_relationship_t *const relation = &((*this_).temp_relationship);
193 0 : if ( data_relationship_is_valid( relation ) )
194 : {
195 : /* determine if the relationship is outgoing */
196 0 : const bool is_outgoing
197 0 : = ( data_relationship_get_from_classifier_row_id( relation ) == data_classifier_get_row_id( classifier ) );
198 0 : if ( is_outgoing )
199 : {
200 : /* get the element types at both ends of the relationship */
201 0 : data_classifier_init_empty( &((*this_).temp_from_classifier) );
202 0 : data_feature_init_empty( &((*this_).temp_from_feature) );
203 0 : data_classifier_init_empty( &((*this_).temp_to_classifier) );
204 0 : data_feature_init_empty( &((*this_).temp_to_feature) );
205 :
206 : const u8_error_t d_err
207 0 : = io_export_flat_traversal_private_get_relationship_ends( this_,
208 : classifier,
209 : relation,
210 : &((*this_).temp_from_classifier),
211 : &((*this_).temp_from_feature),
212 : &((*this_).temp_to_classifier),
213 : &((*this_).temp_to_feature)
214 : );
215 :
216 0 : if ( d_err == U8_ERROR_NONE )
217 : {
218 : /* all classifiers found, print the relation */
219 0 : write_err |= io_element_writer_start_relationship( (*this_).element_writer, host_type, relation );
220 0 : write_err |= io_element_writer_assemble_relationship( (*this_).element_writer,
221 : classifier,
222 : relation,
223 0 : &((*this_).temp_from_classifier),
224 0 : &((*this_).temp_from_feature),
225 0 : &((*this_).temp_to_classifier),
226 0 : &((*this_).temp_to_feature)
227 : );
228 0 : write_err |= io_element_writer_end_relationship( (*this_).element_writer, host_type, relation );
229 : }
230 : else
231 : {
232 0 : write_err |= d_err;
233 : }
234 :
235 0 : data_classifier_destroy( &((*this_).temp_from_classifier) );
236 0 : data_feature_destroy( &((*this_).temp_from_feature) );
237 0 : data_classifier_destroy( &((*this_).temp_to_classifier) );
238 0 : data_feature_destroy( &((*this_).temp_to_feature) );
239 : }
240 : }
241 : else
242 : {
243 0 : assert( false );
244 : }
245 : }
246 :
247 0 : write_err |= data_err; /* result is the combination of writing errors and reading errors */
248 0 : U8_TRACE_END_ERR( write_err );
249 0 : return write_err;
250 : }
251 :
252 0 : u8_error_t io_export_flat_traversal_private_get_relationship_ends( io_export_flat_traversal_t *this_,
253 : const data_classifier_t *classifier,
254 : const data_relationship_t *relation,
255 : data_classifier_t *out_from_c,
256 : data_feature_t *out_from_f,
257 : data_classifier_t *out_to_c,
258 : data_feature_t *out_to_f )
259 : {
260 0 : U8_TRACE_BEGIN();
261 0 : assert( classifier != NULL );
262 0 : assert( relation != NULL );
263 0 : assert( out_from_c != NULL );
264 0 : assert( out_from_f != NULL );
265 0 : assert( out_to_c != NULL );
266 0 : assert( out_to_f != NULL );
267 0 : u8_error_t data_err = U8_ERROR_NONE;
268 :
269 : {
270 : /* get from classifier */
271 0 : const data_row_t from_classifier_row_id = data_relationship_get_from_classifier_row_id( relation );
272 0 : if ( from_classifier_row_id == data_classifier_get_row_id ( classifier ) )
273 : {
274 0 : data_classifier_replace( out_from_c, classifier );
275 : }
276 : else
277 : {
278 0 : data_err |= data_database_reader_get_classifier_by_id( (*this_).db_reader,
279 : from_classifier_row_id,
280 : out_from_c
281 : );
282 : }
283 :
284 : /* get from feature */
285 0 : const data_row_t from_feature_row_id = data_relationship_get_from_feature_row_id( relation );
286 0 : if ( from_feature_row_id != DATA_ROW_VOID )
287 : {
288 0 : data_err |= data_database_reader_get_feature_by_id( (*this_).db_reader,
289 : from_feature_row_id,
290 : out_from_f
291 : );
292 : }
293 : else
294 : {
295 0 : data_feature_init_empty( out_from_f );
296 : }
297 :
298 : /* get to classifier */
299 0 : const data_row_t to_classifier_row_id = data_relationship_get_to_classifier_row_id( relation );
300 0 : if ( to_classifier_row_id == data_classifier_get_row_id ( classifier ) )
301 : {
302 0 : data_classifier_replace( out_to_c, classifier );
303 : }
304 : else
305 : {
306 0 : data_err |= data_database_reader_get_classifier_by_id( (*this_).db_reader,
307 : to_classifier_row_id,
308 : out_to_c
309 : );
310 : }
311 :
312 : /* get to feature */
313 0 : const data_row_t to_feature_row_id = data_relationship_get_to_feature_row_id( relation );
314 0 : if ( to_feature_row_id != DATA_ROW_VOID )
315 : {
316 0 : data_err |= data_database_reader_get_feature_by_id( (*this_).db_reader,
317 : to_feature_row_id,
318 : out_to_f
319 : );
320 : }
321 : else
322 : {
323 0 : data_feature_init_empty( out_to_f );
324 : }
325 : }
326 :
327 0 : if ( data_err != U8_ERROR_NONE )
328 : {
329 0 : U8_LOG_ERROR_INT( "A relationship references classifier(s) and/or feature(s) that do not exist:",
330 : data_relationship_get_row_id ( relation )
331 : );
332 : }
333 0 : U8_TRACE_END_ERR( data_err );
334 0 : return data_err;
335 : }
336 :
337 :
338 : /*
339 : Copyright 2021-2024 Andreas Warnke
340 :
341 : Licensed under the Apache License, Version 2.0 (the "License");
342 : you may not use this file except in compliance with the License.
343 : You may obtain a copy of the License at
344 :
345 : http://www.apache.org/licenses/LICENSE-2.0
346 :
347 : Unless required by applicable law or agreed to in writing, software
348 : distributed under the License is distributed on an "AS IS" BASIS,
349 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
350 : See the License for the specific language governing permissions and
351 : limitations under the License.
352 : */
|