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,.....
305 lines
6.2 KiB
C++
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;
|
|
} |