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_upgrade ( main_commands_t *this_,
61 : const char *data_file_path,
62 : utf8stream_writer_t *out_english_report )
63 : {
64 0 : U8_TRACE_BEGIN();
65 0 : u8_error_t result = U8_ERROR_NONE;
66 :
67 0 : assert( data_file_path != NULL );
68 :
69 0 : U8_TRACE_INFO("opening DB...");
70 : u8_error_info_t err_info;
71 0 : result |= io_data_file_open_writeable( (*this_).data_file, data_file_path, &err_info ); /* upgrade is implicitely done */
72 0 : if ( result != U8_ERROR_NONE )
73 : {
74 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
75 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
76 0 : utf8stream_writer_write_str( out_english_report, "\n" );
77 : }
78 0 : result |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
79 :
80 0 : U8_TRACE_INFO("closing DB...");
81 0 : io_data_file_close( (*this_).data_file );
82 :
83 0 : U8_TRACE_END_ERR( result );
84 0 : return result;
85 : }
86 :
87 0 : u8_error_t main_commands_repair ( main_commands_t *this_,
88 : const char *data_file_path,
89 : bool check_only,
90 : utf8stream_writer_t *out_english_report )
91 : {
92 0 : U8_TRACE_BEGIN();
93 0 : assert( data_file_path != NULL );
94 0 : const bool do_repair = ( ! check_only );
95 0 : u8_error_t result = U8_ERROR_NONE;
96 :
97 0 : U8_TRACE_INFO("opening DB...");
98 : u8_error_info_t err_info;
99 0 : result |= io_data_file_open( (*this_).data_file, data_file_path, check_only, &err_info );
100 0 : if ( result != U8_ERROR_NONE )
101 : {
102 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
103 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
104 0 : utf8stream_writer_write_str( out_english_report, "\n" );
105 : }
106 0 : result |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
107 :
108 0 : U8_TRACE_INFO("reparing/testing...");
109 0 : utf8stream_writer_write_str( out_english_report, "\n\n" );
110 0 : result |= ctrl_controller_repair_database( io_data_file_get_controller_ptr( (*this_).data_file ),
111 : do_repair,
112 : NULL,
113 : NULL,
114 : out_english_report
115 : );
116 0 : utf8stream_writer_write_str( out_english_report, "\n" );
117 0 : U8_TRACE_INFO("reparing/testing finished.");
118 :
119 0 : U8_TRACE_INFO("closing DB...");
120 0 : io_data_file_close( (*this_).data_file );
121 :
122 0 : U8_TRACE_END_ERR( result );
123 0 : return result;
124 : }
125 :
126 0 : u8_error_t main_commands_start_gui ( main_commands_t *this_,
127 : const char *data_file_path,
128 : utf8stream_writer_t *out_english_report )
129 : {
130 0 : U8_TRACE_BEGIN();
131 0 : u8_error_t result = U8_ERROR_NONE;
132 :
133 0 : U8_TRACE_TIMESTAMP();
134 0 : U8_TRACE_INFO("opening DB...");
135 0 : if ( NULL != data_file_path )
136 : {
137 : u8_error_info_t err_info;
138 0 : result |= io_data_file_open_writeable( (*this_).data_file, data_file_path, &err_info );
139 0 : if ( result != U8_ERROR_NONE )
140 : {
141 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
142 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
143 0 : utf8stream_writer_write_str( out_english_report, "\n" );
144 : }
145 0 : result |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
146 : }
147 :
148 0 : U8_TRACE_TIMESTAMP();
149 0 : U8_TRACE_INFO("running GUI...");
150 0 : gui_main( (*this_).data_file, (*this_).argc, (*this_).argv );
151 0 : U8_TRACE_INFO("GUI stopped.");
152 :
153 0 : U8_TRACE_TIMESTAMP();
154 0 : U8_TRACE_INFO("closing DB...");
155 0 : io_data_file_close( (*this_).data_file );
156 :
157 0 : U8_TRACE_END_ERR( result );
158 0 : return result;
159 : }
160 :
161 0 : u8_error_t main_commands_export ( main_commands_t *this_,
162 : const char *data_file_path,
163 : io_file_format_t export_format,
164 : const char *export_directory,
165 : utf8stream_writer_t *out_english_report )
166 : {
167 0 : U8_TRACE_BEGIN();
168 0 : assert( data_file_path != NULL );
169 0 : assert( export_directory != NULL );
170 0 : u8_error_t export_err = U8_ERROR_NONE;
171 :
172 0 : U8_TRACE_INFO("opening DB...");
173 : u8_error_info_t err_info;
174 0 : export_err |= io_data_file_open_read_only( (*this_).data_file, data_file_path, &err_info );
175 0 : if ( export_err != U8_ERROR_NONE )
176 : {
177 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
178 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
179 0 : utf8stream_writer_write_str( out_english_report, "\n" );
180 : }
181 0 : export_err |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
182 :
183 0 : U8_TRACE_INFO("exporting DB...");
184 0 : U8_TRACE_INFO_STR( "chosen folder:", export_directory );
185 0 : const char *document_filename = io_data_file_get_filename_const( (*this_).data_file );
186 0 : if ( io_data_file_is_open( (*this_).data_file ) )
187 : {
188 : static data_database_reader_t db_reader;
189 0 : data_database_reader_init( &db_reader, io_data_file_get_database_ptr( (*this_).data_file ) );
190 : static io_exporter_t exporter;
191 0 : io_exporter_init( &exporter, &db_reader );
192 : {
193 : data_stat_t export_stat;
194 0 : data_stat_init ( &export_stat );
195 0 : export_err = io_exporter_export_files( &exporter, export_format, export_directory, document_filename, &export_stat );
196 0 : export_err |= main_commands_private_report_stat( this_, &export_stat, "exported", out_english_report );
197 0 : data_stat_trace( &export_stat );
198 0 : data_stat_destroy ( &export_stat );
199 : }
200 0 : io_exporter_destroy( &exporter );
201 0 : data_database_reader_destroy( &db_reader );
202 : }
203 : else
204 : {
205 0 : export_err = U8_ERROR_NO_DB;
206 : }
207 :
208 0 : U8_TRACE_INFO("closing DB...");
209 0 : io_data_file_close( (*this_).data_file );
210 :
211 0 : U8_TRACE_END_ERR( export_err );
212 0 : return export_err;
213 : }
214 :
215 0 : u8_error_t main_commands_import ( main_commands_t *this_,
216 : const char *data_file_path,
217 : io_import_mode_t import_mode,
218 : const char *import_file_path,
219 : utf8stream_writer_t *out_english_report )
220 : {
221 0 : U8_TRACE_BEGIN();
222 0 : assert( data_file_path != NULL );
223 0 : assert( import_file_path != NULL );
224 0 : u8_error_t import_err = U8_ERROR_NONE;
225 :
226 0 : U8_TRACE_INFO("opening DB...");
227 : u8_error_info_t err_info;
228 0 : import_err |= io_data_file_open_writeable( (*this_).data_file, data_file_path, &err_info );
229 0 : if ( import_err != U8_ERROR_NONE )
230 : {
231 0 : utf8stream_writer_write_str( out_english_report, "error opening database_file " );
232 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
233 0 : utf8stream_writer_write_str( out_english_report, "\n" );
234 : }
235 0 : import_err |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
236 :
237 0 : U8_TRACE_INFO("importing data...");
238 0 : U8_TRACE_INFO_STR( "chosen data:", import_file_path );
239 0 : if ( io_data_file_is_open( (*this_).data_file ) )
240 : {
241 : static data_database_reader_t db_reader;
242 0 : data_database_reader_init( &db_reader, io_data_file_get_database_ptr( (*this_).data_file ) );
243 : static io_importer_t importer;
244 0 : io_importer_init( &importer, &db_reader, io_data_file_get_controller_ptr( (*this_).data_file ));
245 : {
246 : data_stat_t import_stat;
247 0 : data_stat_init ( &import_stat );
248 : u8_error_info_t err_info;
249 0 : import_err = io_importer_import_file( &importer, import_mode, import_file_path, &import_stat, &err_info, out_english_report );
250 0 : import_err |= main_commands_private_report_stat( this_, &import_stat, "imported", out_english_report );
251 0 : import_err |= main_commands_private_report_error_info( this_, &err_info, out_english_report );
252 0 : data_stat_trace( &import_stat );
253 0 : data_stat_destroy ( &import_stat );
254 : }
255 0 : io_importer_destroy( &importer );
256 0 : data_database_reader_destroy( &db_reader );
257 : }
258 : else
259 : {
260 0 : import_err = U8_ERROR_NO_DB;
261 : }
262 :
263 0 : U8_TRACE_INFO("closing DB...");
264 0 : io_data_file_close( (*this_).data_file );
265 :
266 : {
267 0 : utf8stream_writer_write_str( out_english_report, "\nplease test the integrity of the database_file:\n" );
268 0 : utf8stream_writer_write_str( out_english_report, "crystal-facet-uml -t " );
269 0 : utf8stream_writer_write_str( out_english_report, data_file_path );
270 0 : utf8stream_writer_write_str( out_english_report, "\n\n" );
271 : }
272 :
273 0 : U8_TRACE_END_ERR( import_err );
274 0 : return import_err;
275 : }
276 :
277 : static const char *const series[DATA_STAT_SERIES_MAX] = {
278 : [DATA_STAT_SERIES_CREATED] = " new/exp",
279 : [DATA_STAT_SERIES_MODIFIED] = "modified",
280 : [DATA_STAT_SERIES_DELETED] = " deleted",
281 : [DATA_STAT_SERIES_IGNORED] = " ignored",
282 : [DATA_STAT_SERIES_WARNING] = "warnings",
283 : [DATA_STAT_SERIES_ERROR] = " errors",
284 : };
285 :
286 : static const char *const tables[DATA_STAT_TABLE_MAX] = {
287 : [DATA_TABLE_VOID] = "life",
288 : [DATA_TABLE_CLASSIFIER] = "clas",
289 : [DATA_TABLE_FEATURE] = "feat",
290 : [DATA_TABLE_RELATIONSHIP] = "rel",
291 : [DATA_TABLE_DIAGRAMELEMENT] = "d_ele",
292 : [DATA_TABLE_DIAGRAM] = "diag",
293 : };
294 :
295 0 : u8_error_t main_commands_private_report_stat ( main_commands_t *this_,
296 : const data_stat_t *stat,
297 : const char* mode_name,
298 : utf8stream_writer_t *out_english_report )
299 : {
300 0 : U8_TRACE_BEGIN();
301 0 : assert( stat != NULL );
302 0 : assert( mode_name != NULL );
303 0 : assert( out_english_report != NULL );
304 0 : u8_error_t write_err = U8_ERROR_NONE;
305 :
306 : /* HEADLINE */
307 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n\t" );
308 :
309 0 : for ( int tables_idx = 0; tables_idx < DATA_STAT_TABLE_MAX; tables_idx ++ )
310 : {
311 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t" );
312 0 : write_err |= utf8stream_writer_write_str( out_english_report, tables[tables_idx] );
313 : }
314 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n" );
315 :
316 : /* TABLE */
317 0 : for ( int series_idx = 0; series_idx < DATA_STAT_SERIES_MAX; series_idx ++ )
318 : {
319 0 : const uint_fast32_t s_cnt = data_stat_get_series_count( stat, series_idx );
320 :
321 0 : if ( series_idx == DATA_STAT_SERIES_CREATED )
322 : {
323 0 : write_err |= utf8stream_writer_write_str( out_english_report, mode_name );
324 : }
325 : else
326 : {
327 0 : write_err |= utf8stream_writer_write_str( out_english_report, series[series_idx] );
328 : }
329 0 : write_err |= utf8stream_writer_write_str( out_english_report, ": " );
330 :
331 0 : for ( int tables_idx = 0; tables_idx < DATA_STAT_TABLE_MAX; tables_idx ++ )
332 : {
333 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t" );
334 0 : const uint_fast32_t cnt = data_stat_get_count( stat, tables_idx, series_idx );
335 0 : if ( cnt != 0 )
336 : {
337 0 : write_err |= utf8stream_writer_write_int( out_english_report, cnt );
338 : }
339 : }
340 :
341 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t: " );
342 0 : write_err |= utf8stream_writer_write_int( out_english_report, s_cnt );
343 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n" );
344 : }
345 :
346 : /* ROW OF SUMS */
347 0 : write_err |= utf8stream_writer_write_str( out_english_report, " SUM:" );
348 0 : for ( int tables_idx = 0; tables_idx < DATA_STAT_TABLE_MAX; tables_idx ++ )
349 : {
350 0 : const uint_fast32_t t_cnt = data_stat_get_table_count( stat, tables_idx );
351 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t" );
352 0 : write_err |= utf8stream_writer_write_int( out_english_report, t_cnt );
353 : }
354 0 : const uint_fast32_t total = data_stat_get_total_count( stat );
355 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\t: " );
356 0 : write_err |= utf8stream_writer_write_int( out_english_report, total );
357 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n" );
358 :
359 0 : U8_TRACE_END_ERR( write_err );
360 0 : return write_err;
361 : }
362 :
363 0 : u8_error_t main_commands_private_report_error_info ( main_commands_t *this_,
364 : const u8_error_info_t *error_info,
365 : utf8stream_writer_t *out_english_report )
366 : {
367 0 : U8_TRACE_BEGIN();
368 0 : assert( error_info != NULL );
369 0 : assert( out_english_report != NULL );
370 0 : u8_error_t write_err = U8_ERROR_NONE;
371 :
372 0 : if ( u8_error_info_is_error( error_info ) )
373 : {
374 : char info_string_buf[80];
375 0 : utf8stringbuf_t info_string = UTF8STRINGBUF(info_string_buf);
376 0 : utf8stringbuf_clear( info_string );
377 : {
378 : gui_error_info_printer_t my_err_info_printer;
379 0 : gui_error_info_printer_init( &my_err_info_printer );
380 0 : write_err |= gui_error_info_printer_show_error_info( &my_err_info_printer, error_info, info_string );
381 0 : gui_error_info_printer_destroy( &my_err_info_printer );
382 : }
383 0 : write_err |= utf8stream_writer_write_str( out_english_report, utf8stringbuf_get_string(info_string) );
384 0 : write_err |= utf8stream_writer_write_str( out_english_report, "\n" );
385 : }
386 :
387 0 : U8_TRACE_END_ERR( write_err );
388 0 : return write_err;
389 : }
390 :
391 :
392 : /*
393 : Copyright 2016-2024 Andreas Warnke
394 :
395 : Licensed under the Apache License, Version 2.0 (the "License");
396 : you may not use this file except in compliance with the License.
397 : You may obtain a copy of the License at
398 :
399 : http://www.apache.org/licenses/LICENSE-2.0
400 :
401 : Unless required by applicable law or agreed to in writing, software
402 : distributed under the License is distributed on an "AS IS" BASIS,
403 : WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
404 : See the License for the specific language governing permissions and
405 : limitations under the License.
406 : */
|