campo-sirio/src/ba/ba8800.cpp
Alessandro Bonazzi 3679acad8c 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 <query> <outputfile> <formato> <variabili> -uADMIN

formato=html|txt|excel(csv)|campo|dbf
variabili nel formato VARIABILE=valore,VARIABILE=valore,.....
2023-01-23 10:50:07 +01:00

305 lines
6.2 KiB
C++

#include <applicat.h>
#include <automask.h>
#include <defmask.h>
#include <extcdecl.h>
#include <modaut.h>
#include <odbcrset.h>
#include <prefix.h>
#include <relation.h>
#include <sheet.h>
#include <tree.h>
#include <treectrl.h>
#include <utility.h>
#include <xml.h>
///////////////////////////////////////////////////////////
// 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;
}