Line data Source code
1 : /* File: main_commands.c; Copyright and License: see below */
2 :
3 : #include "main_commands.h"
4 : #include "gui_main.h"
5 : #include "gui_error_info_printer.h"
6 : #include "io_exporter.h"
7 : #include "io_importer.h"
8 : #include "ctrl_controller.h"
9 : #include "u8/u8_trace.h"
10 : #include "u8/u8_log.h"
11 : #include <gtk/gtk.h>
12 : #include <stdbool.h>
13 : #include <assert.h>
14 :
15 : static io_data_file_t single_big_data_file; /*!< a data_file struct, placed in the data segment due to its >5MB size */
16 :
17 0 : u8_error_t main_commands_init ( main_commands_t *this_, bool start_gui, int argc, char **argv )
18 : {
19 0 : U8_TRACE_BEGIN();
20 0 : u8_error_t result = U8_ERROR_NONE;
21 :
22 0 : (*this_).argc = argc;
23 0 : (*this_).argv = argv;
24 :
25 : /* initialize the base libraries: gobject, gio, glib, gdk and gtk */
26 0 : if ( start_gui )
27 : {
28 0 : gtk_init();
29 : /* if this program was not terminated, gtk init was successful. */
30 : }
31 : else
32 : {
33 0 : const gboolean success = gtk_init_check();
34 0 : if ( ! success )
35 : {
36 0 : U8_LOG_WARNING("gtk could not be initialized.");
37 : /* no error here, if no gui requested - test fail otherwise */
38 : }
39 : }
40 :
41 0 : U8_TRACE_INFO("starting DB and its controller...");
42 0 : U8_TRACE_INFO_INT("sizeof(io_data_file_t)/B:",sizeof(io_data_file_t));
43 0 : (*this_).data_file = &single_big_data_file;
44 0 : io_data_file_init( (*this_).data_file );
45 :
46 0 : U8_TRACE_END_ERR( result );
47 0 : return result;
48 : }
49 :
50 0 : void main_commands_destroy ( main_commands_t *this_ )
51 : {
52 0 : U8_TRACE_BEGIN();
53 :
54 0 : U8_TRACE_INFO("stopping DB and its controller...");
55 0 : io_data_file_destroy( (*this_).data_file );
56 :
57 0 : U8_TRACE_END();
58 0 : }
59 :
60 0 : u8_error_t main_commands_repair ( main_commands_t *this_,
61 : const char *data_file_path,
62 : bool check_only,
63 : utf8stream_writer_t *out_english_report )
64 : {
65 0 : U8_TRACE_BEGIN();
66 0 : assert( data_file_path != NULL );
67 0 : const bool do_repair = ( ! check_only );
68 0 : u8_error_t result = U8_ERROR_NONE;
69 :
70 0 : U8_TRACE_INFO("opening DB...");
71 : u8_error_info_t err_info;
72 0 : result |= io_data_file_open( (*this_).data_file, data_file_path, check_only, &err_info );
73 0 : if ( result != U8_ERROR_NONE )
74 : {
75 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
76 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
77 0 : utf8stream_writer_write_str( out_english_report, "\n" );
78 : }
79 0 : result |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
80 :
81 0 : U8_TRACE_INFO("reparing/testing...");
82 0 : utf8stream_writer_write_str( out_english_report, "\n\n" );
83 0 : result |= ctrl_controller_repair_database( io_data_file_get_controller_ptr( (*this_).data_file ),
84 : do_repair,
85 : NULL,
86 : NULL,
87 : out_english_report
88 : );
89 0 : utf8stream_writer_write_str( out_english_report, "\n" );
90 0 : U8_TRACE_INFO("reparing/testing finished.");
91 :
92 0 : U8_TRACE_INFO("closing DB...");
93 0 : io_data_file_close( (*this_).data_file );
94 :
95 0 : U8_TRACE_END_ERR( result );
96 0 : return result;
97 : }
98 :
99 0 : u8_error_t main_commands_start_gui ( main_commands_t *this_,
100 : const char *data_file_path,
101 : utf8stream_writer_t *out_english_report )
102 : {
103 0 : U8_TRACE_BEGIN();
104 0 : u8_error_t result = U8_ERROR_NONE;
105 :
106 0 : U8_TRACE_TIMESTAMP();
107 0 : U8_TRACE_INFO("opening DB...");
108 0 : if ( NULL != data_file_path )
109 : {
110 : u8_error_info_t err_info;
111 0 : result |= io_data_file_open_writeable( (*this_).data_file, data_file_path, &err_info );
112 0 : if ( result != U8_ERROR_NONE )
113 : {
114 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
115 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
116 0 : utf8stream_writer_write_str( out_english_report, "\n" );
117 : }
118 0 : result |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
119 : }
120 :
121 0 : U8_TRACE_TIMESTAMP();
122 0 : U8_TRACE_INFO("running GUI...");
123 0 : gui_main( (*this_).data_file, (*this_).argc, (*this_).argv );
124 0 : U8_TRACE_INFO("GUI stopped.");
125 :
126 0 : U8_TRACE_TIMESTAMP();
127 0 : U8_TRACE_INFO("closing DB...");
128 0 : io_data_file_close( (*this_).data_file );
129 :
130 0 : U8_TRACE_END_ERR( result );
131 0 : return result;
132 : }
133 :
134 0 : u8_error_t main_commands_export ( main_commands_t *this_,
135 : const char *data_file_path,
136 : io_file_format_t export_format,
137 : const char *export_directory,
138 : utf8stream_writer_t *out_english_report )
139 : {
140 0 : U8_TRACE_BEGIN();
141 0 : assert( data_file_path != NULL );
142 0 : assert( export_directory != NULL );
143 0 : u8_error_t export_err = U8_ERROR_NONE;
144 :
145 0 : U8_TRACE_INFO("opening DB...");
146 : u8_error_info_t err_info;
147 0 : export_err |= io_data_file_open_read_only( (*this_).data_file, data_file_path, &err_info );
148 0 : if ( export_err != U8_ERROR_NONE )
149 : {
150 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
151 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
152 0 : utf8stream_writer_write_str( out_english_report, "\n" );
153 : }
154 0 : export_err |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
155 :
156 0 : U8_TRACE_INFO("exporting DB...");
157 0 : U8_TRACE_INFO_STR( "chosen folder:", export_directory );
158 0 : const char *document_filename = io_data_file_get_filename_const( (*this_).data_file );
159 0 : if ( io_data_file_is_open( (*this_).data_file ) )
160 : {
161 : static data_database_reader_t db_reader;
162 0 : data_database_reader_init( &db_reader, io_data_file_get_database_ptr( (*this_).data_file ) );
163 : static io_exporter_t exporter;
164 0 : io_exporter_init( &exporter, &db_reader );
165 : {
166 : data_stat_t export_stat;
167 0 : data_stat_init ( &export_stat );
168 0 : export_err = io_exporter_export_files( &exporter, export_format, export_directory, document_filename, &export_stat );
169 0 : export_err |= main_commands_private_report_stat( this_, &export_stat, "exported", out_english_report );
170 0 : data_stat_trace( &export_stat );
171 0 : data_stat_destroy ( &export_stat );
172 : }
173 0 : io_exporter_destroy( &exporter );
174 0 : data_database_reader_destroy( &db_reader );
175 : }
176 : else
177 : {
178 0 : export_err = U8_ERROR_NO_DB;
179 : }
180 :
181 0 : U8_TRACE_INFO("closing DB...");
182 0 : io_data_file_close( (*this_).data_file );
183 :
184 0 : U8_TRACE_END_ERR( export_err );
185 0 : return export_err;
186 : }
187 :
188 0 : u8_error_t main_commands_import ( main_commands_t *this_,
189 : const char *data_file_path,
190 : io_import_mode_t import_mode,
191 : const char *import_file_path,
192 : utf8stream_writer_t *out_english_report )
193 : {
194 0 : U8_TRACE_BEGIN();
195 0 : assert( data_file_path != NULL );
196 0 : assert( import_file_path != NULL );
197 0 : u8_error_t import_err = U8_ERROR_NONE;
198 :
199 0 : U8_TRACE_INFO("opening DB...");
200 : u8_error_info_t err_info;
201 0 : import_err |= io_data_file_open_writeable( (*this_).data_file, data_file_path, &err_info );
202 0 : if ( import_err != U8_ERROR_NONE )
203 : {
204 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
205 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
206 0 : utf8stream_writer_write_str( out_english_report, "\n" );
207 : }
208 0 : import_err |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
209 :
210 0 : U8_TRACE_INFO("importing data...");
211 0 : U8_TRACE_INFO_STR( "chosen data:", import_file_path );
212 0 : if ( io_data_file_is_open( (*this_).data_file ) )
213 : {
214 : static data_database_reader_t db_reader;
215 0 : data_database_reader_init( &db_reader, io_data_file_get_database_ptr( (*this_).data_file ) );
216 : static io_importer_t importer;
217 0 : io_importer_init( &importer, &db_reader, io_data_file_get_controller_ptr( (*this_).data_file ));
218 : {
219 : data_stat_t import_stat;
220 0 : data_stat_init ( &import_stat );
221 : u8_error_info_t err_info;
222 0 : import_err = io_importer_import_file( &importer, import_mode, import_file_path, &import_stat, &err_info, out_english_report );
223 0 : import_err |= main_commands_private_report_stat( this_, &import_stat, "imported", out_english_report );
224 0 : import_err |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
225 0 : data_stat_trace( &import_stat );
226 0 : data_stat_destroy ( &import_stat );
227 : }
228 0 : io_importer_destroy( &importer );
229 0 : data_database_reader_destroy( &db_reader );
230 : }
231 : else
232 : {
233 0 : import_err = U8_ERROR_NO_DB;
234 : }
235 :
236 0 : U8_TRACE_INFO("closing DB...");
237 0 : io_data_file_close( (*this_).data_file );
238 :
239 : {
240 0 : utf8stream_writer_write_str( out_english_report, "\nplease test the integrity of the database_file:\n" );
241 0 : utf8stream_writer_write_str( out_english_report, "crystal-facet-uml -t " );
242 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
243 0 : utf8stream_writer_write_str( out_english_report, "\n\n" );
244 : }
245 :
246 0 : U8_TRACE_END_ERR( import_err );
247 0 : return import_err;
248 : }
249 :
250 : static const char *const series[DATA_STAT_SERIES_MAX] = {
251 : [DATA_STAT_SERIES_CREATED] = " new/exp",
252 : [DATA_STAT_SERIES_MODIFIED] = "modified",
253 : [DATA_STAT_SERIES_DELETED] = " deleted",
254 : [DATA_STAT_SERIES_IGNORED] = " ignored",
255 : [DATA_STAT_SERIES_WARNING] = "warnings",
256 : [DATA_STAT_SERIES_ERROR] = " errors",
257 : };
258 :
259 : static const char *const tables[DATA_STAT_TABLE_MAX] = {
260 : [DATA_TABLE_VOID] = "life",
261 : [DATA_TABLE_CLASSIFIER] = "clas",
262 : [DATA_TABLE_FEATURE] = "feat",
263 : [DATA_TABLE_RELATIONSHIP] = "rel",
264 : [DATA_TABLE_DIAGRAMELEMENT] = "d_ele",
265 : [DATA_TABLE_DIAGRAM] = "diag",
266 : };
267 :
268 0 : u8_error_t main_commands_private_report_stat ( main_commands_t *this_,
269 : const data_stat_t *stat,
270 : const char* mode_name,
271 : utf8stream_writer_t *out_english_report )
272 : {
273 0 : U8_TRACE_BEGIN();
274 0 : assert( stat != NULL );
275 0 : assert( mode_name != NULL );
276 0 : assert( out_english_report != NULL );
277 0 : u8_error_t write_err = U8_ERROR_NONE;
278 :
279 : /* HEADLINE */
280 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n\t" );
281 :
282 0 : for ( int tables_idx = 0; tables_idx < DATA_STAT_TABLE_MAX; tables_idx ++ )
283 : {
284 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t" );
285 0 : write_err |= utf8stream_writer_write_str( out_english_report, tables[tables_idx] );
286 : }
287 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n" );
288 :
289 : /* TABLE */
290 0 : for ( int series_idx = 0; series_idx < DATA_STAT_SERIES_MAX; series_idx ++ )
291 : {
292 0 : const uint_fast32_t s_cnt = data_stat_get_series_count( stat, series_idx );
293 :
294 0 : if ( series_idx == DATA_STAT_SERIES_CREATED )
295 : {
296 0 : write_err |= utf8stream_writer_write_str( out_english_report, mode_name );
297 : }
298 : else
299 : {
300 0 : write_err |= utf8stream_writer_write_str( out_english_report, series[series_idx] );
301 : }
302 0 : write_err |= utf8stream_writer_write_str( out_english_report, ": " );
303 :
304 0 : for ( int tables_idx = 0; tables_idx < DATA_STAT_TABLE_MAX; tables_idx ++ )
305 : {
306 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t" );
307 0 : const uint_fast32_t cnt = data_stat_get_count( stat, tables_idx, series_idx );
308 0 : if ( cnt != 0 )
309 : {
310 0 : write_err |= utf8stream_writer_write_int( out_english_report, cnt );
311 : }
312 : }
313 :
314 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t: " );
315 0 : write_err |= utf8stream_writer_write_int( out_english_report, s_cnt );
316 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n" );
317 : }
318 :
319 : /* ROW OF SUMS */
320 0 : write_err |= utf8stream_writer_write_str( out_english_report, " SUM:" );
321 0 : for ( int tables_idx = 0; tables_idx < DATA_STAT_TABLE_MAX; tables_idx ++ )
322 : {
323 0 : const uint_fast32_t t_cnt = data_stat_get_table_count( stat, tables_idx );
324 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t" );
325 0 : write_err |= utf8stream_writer_write_int( out_english_report, t_cnt );
326 : }
327 0 : const uint_fast32_t total = data_stat_get_total_count( stat );
328 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t: " );
329 0 : write_err |= utf8stream_writer_write_int( out_english_report, total );
330 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n" );
331 :
332 0 : U8_TRACE_END_ERR( write_err );
333 0 : return write_err;
334 : }
335 :
336 0 : u8_error_t main_commands_private_report_error_info ( main_commands_t *this_,
337 : const u8_error_info_t *error_info,
338 : utf8stream_writer_t *out_english_report )
339 : {
340 0 : U8_TRACE_BEGIN();
341 0 : assert( error_info != NULL );
342 0 : assert( out_english_report != NULL );
343 0 : u8_error_t write_err = U8_ERROR_NONE;
344 :
345 0 : if ( u8_error_info_is_error( error_info ) )
346 : {
347 : char info_string_buf[80];
348 0 : utf8stringbuf_t info_string = UTF8STRINGBUF(info_string_buf);
349 0 : utf8stringbuf_clear( &info_string );
350 : {
351 : gui_error_info_printer_t my_err_info_printer;
352 0 : gui_error_info_printer_init( &my_err_info_printer );
353 0 : write_err |= gui_error_info_printer_show_error_info( &my_err_info_printer, error_info, info_string );
354 0 : gui_error_info_printer_destroy( &my_err_info_printer );
355 : }
356 0 : write_err |= utf8stream_writer_write_str( out_english_report, utf8stringbuf_get_string( &info_string ) );
357 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n" );
358 : }
359 :
360 0 : U8_TRACE_END_ERR( write_err );
361 0 : return write_err;
362 : }
363 :
364 :
365 : /*
366 : Copyright 2016-2025 Andreas Warnke
367 :
368 : Licensed under the Apache License, Version 2.0 (the "License");
369 : you may not use this file except in compliance with the License.
370 : You may obtain a copy of the License at
371 :
372 : http://www.apache.org/licenses/LICENSE-2.0
373 :
374 : Unless required by applicable law or agreed to in writing, software
375 : distributed under the License is distributed on an "AS IS" BASIS,
376 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
377 : See the License for the specific language governing permissions and
378 : limitations under the License.
379 : */
|