From 3679acad8c8d691c72524f52c9d6305c42af0dbb Mon Sep 17 00:00:00 2001 From: Alessandro Bonazzi Date: Mon, 23 Jan 2023 10:50:07 +0100 Subject: [PATCH] Patch level : 12.0 1232 Files correlati : ba8.exe Commento : Programma per l'esecuzione di query in interattivo o batch. Si chiama in questo modo ba8 -7 -uADMIN formato=html|txt|excel(csv)|campo|dbf variabili nel formato VARIABILE=valore,VARIABILE=valore,..... --- src/ba/ba1100.cpp | 3 +- src/ba/ba8.cpp | 3 +- src/ba/ba8.h | 2 +- src/ba/ba8200.cpp | 6 +- src/ba/ba8300.cpp | 15 ++- src/ba/ba8800.cpp | 305 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 321 insertions(+), 13 deletions(-) create mode 100644 src/ba/ba8800.cpp diff --git a/src/ba/ba1100.cpp b/src/ba/ba1100.cpp index cd6dfff51..12e93e091 100755 --- a/src/ba/ba1100.cpp +++ b/src/ba/ba1100.cpp @@ -510,8 +510,7 @@ void TManutenzione_app::dump_trc(const char * dir, const bool des_too, const lon TDir& dr = (TDir&)_dirs[i]; const long file_mod = (long)abs((int)dr.flags()); if (modules != -1 && file_mod != modules) continue; // se non fa parte del modulo lo salta - TFilename descfname; - descfname.format("%s/d%d.des", DESCDIR, i); + TFilename descfname = format("%s/d%d.des", DESCDIR, i); if (!fexist(descfname)) // crea la descrizione se non esiste { FILE * fd = fopen(descfname, "w"); diff --git a/src/ba/ba8.cpp b/src/ba/ba8.cpp index d28d49e49..aa86d2391 100755 --- a/src/ba/ba8.cpp +++ b/src/ba/ba8.cpp @@ -12,7 +12,8 @@ int main(int argc, char** argv) case 3: ba8400(argc, argv); break; // Form Converter case 4: ba8500(argc, argv); break; // Report Printer case 5: ba8600(argc, argv); break; // Ricerca documenti archiviati - case 6: ba8700(argc, argv); break; // Firma digitale + case 6: ba8700(argc, argv); break; // Firma digitale + case 7: ba8800(argc, argv); break; // Query executor default: ba8300(argc, argv); break; // Report Generator } return 0; diff --git a/src/ba/ba8.h b/src/ba/ba8.h index 522fa3e2c..112824784 100755 --- a/src/ba/ba8.h +++ b/src/ba/ba8.h @@ -5,5 +5,5 @@ int ba8400(int argc, char* argv[]); int ba8500(int argc, char* argv[]); int ba8600(int argc, char* argv[]); int ba8700(int argc, char* argv[]); - +int ba8800(int argc, char* argv[]); diff --git a/src/ba/ba8200.cpp b/src/ba/ba8200.cpp index 4def16f70..1fde69b69 100755 --- a/src/ba/ba8200.cpp +++ b/src/ba/ba8200.cpp @@ -1540,11 +1540,7 @@ void TSQL_recordset_app::main_loop() bool TSQL_recordset_app::destroy() { - if (_msk != NULL) - { - delete _msk; - _msk = NULL; - } + safe_delete(_msk); return true; } diff --git a/src/ba/ba8300.cpp b/src/ba/ba8300.cpp index 2f8ffe6bd..7bdc36ba4 100755 --- a/src/ba/ba8300.cpp +++ b/src/ba/ba8300.cpp @@ -205,7 +205,7 @@ void TSection_properties_mask::set_section(const TReport_section& rs) if (field(F_SQL).shown()) { const TRecordset* recset = rs.recordset(); - if (recset != NULL) + if (recset != nullptr) set(F_SQL, recset->query_text()); } @@ -514,13 +514,14 @@ bool TReport_mask::get_rep_path(TFilename& path) const path.add(name); path.ext("rep"); bool found = path.exist(); - if (!found) + if (!found) { TString80 fname = path.name_only(); fname.lower(); TFilename star = path.path(); star.add("*.rep"); TString_array reps; list_files(star, reps); - double best = 0.8; + + double best = 0.99; FOR_EACH_ARRAY_ROW(reps, r, row) { star = *row; star = star.name_only(); star.lower(); @@ -1221,7 +1222,7 @@ protected: virtual void main_loop(); virtual bool destroy(); virtual void print(); - + virtual void preview(); public: TReporter_app() : _msk(NULL) { } }; @@ -1232,6 +1233,12 @@ void TReporter_app::print() _msk->on_print(false); } +void TReporter_app::preview() +{ + if (_msk != NULL) + _msk->on_print(true); +} + bool TReporter_app::create() { if (!has_module(RSAUT)) diff --git a/src/ba/ba8800.cpp b/src/ba/ba8800.cpp new file mode 100644 index 000000000..a0d8f57b6 --- /dev/null +++ b/src/ba/ba8800.cpp @@ -0,0 +1,305 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/////////////////////////////////////////////////////////// +// TSQL_exec_recordset_app +/////////////////////////////////////////////////////////// + +class TSQL_exec_recordset_app : public TSkeleton_application +{ +protected: + const TString & load_query(const char * query); + bool set_vars(const char* values, TRecordset& recset) const; + bool ask_vars(const char* maskname, TRecordset& recset) const; + TRecordset* new_recordset(const char * query, const char * values); + const char * get_output_filename(const char * output, const char * query); + void save_as(TRecordsetExportFormat fmt, const char* ext = NULL); + +public: + virtual bool create(); + virtual void main_loop(); + virtual bool destroy() { return true; } +}; + +// Carica l'intera query +const TString & TSQL_exec_recordset_app::load_query(const char * query) +{ + TFilename path(query); + TString sqlstr; + + path.ext("qry"); + if (path.full()) + { + bool ok = path.exist(); + + if (!ok) + { + if (!path.is_absolute_path()) + { + path = firm2dir(-1); + path.add("custom"); + if (!path.exist()) + xvt_fsys_mkdir(path); + path.add(query); + } + path.ext("qry"); + ok = path.exist(); + } + if (ok) + { + TXmlItem xml; + ok = xml.Load(path); + if (ok) + { + path = path.name(); path.ext(""); + + const TXmlItem* desc = xml.FindFirst("description"); + if (desc != nullptr) + { + TString str; desc->GetEnclosedText(str); + if (str.blank()) + str = path.name_only(); + main_app().set_title(str); + } + const TXmlItem* sql = xml.FindFirst("sql"); + if (sql != nullptr) + sql->GetEnclosedText(sqlstr); + } + } + } + return get_tmp_string() = sqlstr; +} + +bool TSQL_exec_recordset_app::set_vars(const char* values, TRecordset& recset) const +{ + if (recset.variables().items() == 0) + return true; + + TToken_string vals(values, ','); + TString_array vars = recset.variables(); + + // Rendi visibili tutte le variabili utente al report + FOR_EACH_STR_TOKEN(vals, s) + { + TToken_string line(s, '='); + TString name = line.get(); + TString val = line.get(); + TDate d(val); + + if (d.ok()) + { + val.cut(0); + val << d.date2ansi(); + } + if (name[0] != '#') + name.insert("#"); + + const int pos = vars.find(name); + + if (pos >= 0) + { + vars.remove(pos, true); + recset.set_var(name, val, true); + } + } + return vars.items() == 0; +} + +bool TSQL_exec_recordset_app::ask_vars(const char* maskname, TRecordset& recset) const +{ + if (recset.variables().items() == 0) + return true; + + TFilename fname = maskname; fname.ext("msk"); + KEY key = K_QUIT; + if (!fname.custom_path()) + return recset.ask_variables(true); + + TMask m(maskname); + TString title; m.get_caption(title); + if (title.full()) + main_app().set_title(title); + + TVariant var; + for (int i = m.fields() - 1; i >= 0; i--) + { + TMask_field& f = m.fld(i); + const TFieldref* ref = f.field(); + if (ref != NULL) + { + TString name = ref->name(); + if (name[0] != '#') + name.insert("#"); + const TVariant& var = recset.get_var(name); + if (!var.is_null()) + f.set(var.as_string()); + } + } + key = m.run(); + const bool ok = key != K_QUIT && key != K_ESC; + if (ok) + { + // Rendi visibili tutte le variabili utente al report + for (int i = m.fields() - 1; i >= 0; i--) + { + TMask_field& f = m.fld(i); + const TFieldref* ref = f.field(); + if (ref != NULL) + { + switch (f.class_id()) + { + case CLASS_CURRENCY_FIELD: + case CLASS_REAL_FIELD: + var = real(f.get()); + break; + case CLASS_DATE_FIELD: + var = TDate(f.get()); + break; + default: + var = f.get(); + break; + } + TString name = ref->name(); + if (name[0] != '#') + name.insert("#"); + recset.set_var(name, var, true); + } + } + } + return ok; +} + +TRecordset* TSQL_exec_recordset_app::new_recordset(const char * query, const char * values) +{ + const TString& sql = load_query(query); + TRecordset* rex = create_recordset(sql); + + if (rex != nullptr) + { + if (values && *values) + { + if (!set_vars(values, *rex)) + safe_delete(rex); + } + else + { + if (!ask_vars(query, *rex)) + safe_delete(rex); + } + } + return rex; +} + +const char * TSQL_exec_recordset_app::get_output_filename(const char * output, const char * query) +{ + TFilename outfname(output); + TFilename fname; + + if (outfname.blank()) + outfname.tempdir(); + if (!is_dir(outfname)) + { + fname = outfname.name_only(); + outfname = outfname.path(); + } + if (!dexist(outfname)) + if (!make_dir(outfname)) + { + error_box(FR("Non posso creare %s uso il direttorio temporaneo"), (const char *)outfname); + outfname = outfname.tempdir(); + } + if (fname.blank()) + { + TString t(20); + + fname = query; + fname.ext(""); + _strtime_s(t.get_buffer(), t.size()); + t.strip(":"); + fname << '_' << today.date2ansi() << '_' << t; + } + outfname.add(fname); + return get_tmp_string() = outfname; +} +bool TSQL_exec_recordset_app::create() +{ + if (!has_module(RSAUT)) + return error_box(TR("Modulo non autorizzato")); + xvt_vobj_show(TASK_WIN); + xvt_sys_sleep(500); // Lasciamo il tempo di leggere il titolo + + return TSkeleton_application::create(); +} + +void TSQL_exec_recordset_app::main_loop() +{ + TFilename query = argv(2); // Carico la query da riga di comando + TFilename output = get_output_filename(argv(3), query); + TRecordsetExportFormat fmt = fmt_unknown; + const char f = argv(4)[0]; + + query.ext("qry"); + switch (toupper(f)) + { + case 'H': + fmt = fmt_html; + output.ext("html"); + break; + case 'T': + fmt = fmt_text; + output.ext("txt"); + break; + case 'E': + case 'X': + fmt = fmt_csv; + output.ext("csv"); + break; + case 'C': + fmt = fmt_campo; + output.ext("txt"); + break; + case 'D': + fmt = fmt_dbf; + output.ext("dbf"); + break; + default: + fmt = fmt_html; + break; + } + + TString values; + + if (argc() > 5) + values = argv(5); + + TRecordset * rex = new_recordset(query, values); + + if (values.full() || rex->variables().items() == 0) + { + xvt_vobj_hide(TASK_WIN); + batch(); + } + if (rex) + rex->save_as(output, fmt, 0x4); + safe_delete(rex); + batch(false); +} + +int ba8800(int argc, char* argv[]) +{ + TSQL_exec_recordset_app app; + + app.run(argc, argv, TR("Query Executor")); + return 0; +} \ No newline at end of file