Patch level : 4.0
Files correlati : Ricompilazione Demo : [ ] Commento : Riporto preventivo delle nuove classi nate nella 3.0 git-svn-id: svn://10.65.10.50/trunk@14680 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
a173626ae7
commit
13949df405
28
include/bagn010a.rep
Executable file
28
include/bagn010a.rep
Executable file
@ -0,0 +1,28 @@
|
||||
|
||||
<report name="bagn010a" lpi="6">
|
||||
<description>Log di elaborazione</description>
|
||||
<font face="Arial" size="10" />
|
||||
<section type="Head" />
|
||||
<section type="Head" level="1">
|
||||
<field type="Stringa" valign="center" align="center" width="80" height="3" pattern="1">
|
||||
<font face="Arial" bold="1" size="24" />
|
||||
<source>#TITLE</source>
|
||||
</field>
|
||||
</section>
|
||||
<section type="Body" />
|
||||
<section type="Body" level="1">
|
||||
<field type="Array" width="10" pattern="1">
|
||||
<source>A</source>
|
||||
<list>
|
||||
<li Value=" " Code="0" />
|
||||
<li Value="-" Code="1" />
|
||||
<li Value="!" Code="2" />
|
||||
</list>
|
||||
</field>
|
||||
<field x="4" type="Stringa" dynamic_height="1" width="80" height="4" pattern="1">
|
||||
<source>B</source>
|
||||
</field>
|
||||
</section>
|
||||
<section type="Foot" />
|
||||
<section type="Foot" level="1" />
|
||||
</report>
|
159
include/reputils.cpp
Executable file
159
include/reputils.cpp
Executable file
@ -0,0 +1,159 @@
|
||||
#include <diction.h>
|
||||
#include <reputils.h>
|
||||
#include <textset.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TAS400_report
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
TRecordset* TAS400_report::recordset() const
|
||||
{
|
||||
return _set != NULL ? _set : TReport::recordset();
|
||||
}
|
||||
|
||||
bool TAS400_report::set_recordset(TRecordset* rs)
|
||||
{
|
||||
if (_set != NULL && _owned)
|
||||
delete _set;
|
||||
_set = rs;
|
||||
_owned = true;
|
||||
|
||||
const TAS400_recordset& recset = *(TAS400_recordset*)_set;
|
||||
|
||||
TReport_section& body = section('B', 1);
|
||||
body.destroy();
|
||||
|
||||
const int reclen = recset.record_length();
|
||||
const int keypos = recset.key_position();
|
||||
const int keylen = recset.key_length();
|
||||
const int tabstop = 10;
|
||||
|
||||
// Genera sfondo solo per colonne dispari
|
||||
for (int x = tabstop; x < reclen; x += 2*tabstop)
|
||||
{
|
||||
TReport_field* b = new TReport_field(&body);
|
||||
b->set_type('R');
|
||||
b->set_pos(x*100, 0);
|
||||
b->set_size(tabstop*100, 100);
|
||||
b->set_pattern(PAT_SOLID);
|
||||
b->set_back_color(MAKE_COLOR(192,255,255)); // Light Cyan
|
||||
body.add(b);
|
||||
}
|
||||
|
||||
// Genera sfondo per la chiave se presente
|
||||
if (keylen > 0)
|
||||
{
|
||||
TReport_field* b = new TReport_field(&body);
|
||||
b->set_type('R');
|
||||
b->set_pos(keypos*100, 0);
|
||||
b->set_size(keylen*100, 100);
|
||||
b->set_pattern(PAT_SOLID);
|
||||
b->set_back_color(MAKE_COLOR(255,192,192)); // Light Fucsia
|
||||
body.add(b);
|
||||
}
|
||||
|
||||
// Genera campi a passo fisso per evitare errori di arrotondamento font
|
||||
TString16 src; // Nome della sorgente di ogni colonna
|
||||
for (int k = 0; k < reclen; k += tabstop)
|
||||
{
|
||||
TReport_field* f = new TReport_field(&body);
|
||||
f->set_type('S');
|
||||
src.format("A[%d,%d]", k+1, k+tabstop);
|
||||
f->set_field(src);
|
||||
f->set_pos(k*100, 0);
|
||||
f->set_size(tabstop*100, 100);
|
||||
body.add(f);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TAS400_report::set_recordset(const TString& query)
|
||||
{
|
||||
TAS400_recordset* rs = (TAS400_recordset*)recordset();
|
||||
if (rs == NULL || !_owned)
|
||||
{
|
||||
rs = new TAS400_recordset(query);
|
||||
TAS400_report::set_recordset(rs);
|
||||
}
|
||||
else
|
||||
rs->exec(query);
|
||||
return true;
|
||||
}
|
||||
|
||||
TAS400_report::TAS400_report(const char* query)
|
||||
: _set(NULL), _owned(false)
|
||||
{
|
||||
set_recordset(TFixed_string(query));
|
||||
}
|
||||
|
||||
TAS400_report::TAS400_report(TRecordset& asr)
|
||||
: _set(NULL), _owned(false)
|
||||
{
|
||||
set_recordset(&asr);
|
||||
_owned = false; // il metodo precedente forza _owned = true
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TLog_report
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
void TLog_report::set_title(const char* title)
|
||||
{
|
||||
_title = title;
|
||||
}
|
||||
|
||||
bool TLog_report::get_usr_val(const TString& name, TVariant& var) const
|
||||
{
|
||||
if (name == "#TITLE")
|
||||
{
|
||||
var = _title;
|
||||
return true;
|
||||
}
|
||||
return TReport::get_usr_val(name, var);
|
||||
}
|
||||
|
||||
bool TLog_report::set_usr_val(const TString& name, const TVariant& var)
|
||||
{
|
||||
if (name == "#TITLE")
|
||||
{
|
||||
set_title(var.as_string());
|
||||
return true;
|
||||
}
|
||||
|
||||
return TReport::set_usr_val(name, var);
|
||||
}
|
||||
|
||||
void TLog_report::reset()
|
||||
{
|
||||
TText_recordset* csv = (TText_recordset*)recordset();
|
||||
if (csv)
|
||||
csv->destroy();
|
||||
}
|
||||
|
||||
bool TLog_report::log(int sev, const char* msg)
|
||||
{
|
||||
TText_recordset* csv = (TText_recordset*)recordset();
|
||||
bool ok = csv != NULL;
|
||||
if (ok)
|
||||
{
|
||||
ok = csv->new_rec() >= 0;
|
||||
if (ok)
|
||||
{
|
||||
csv->set(0u, TVariant((long)sev));
|
||||
csv->set(1, TVariant(msg));
|
||||
}
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
TLog_report::TLog_report(const char* title, const char* name)
|
||||
{
|
||||
load(name);
|
||||
if (recordset() == NULL)
|
||||
{
|
||||
TCSV_recordset* csv = new TCSV_recordset("CSV(\"\t\")"); // tab separated
|
||||
set_recordset(csv);
|
||||
}
|
||||
set_title(title);
|
||||
}
|
50
include/reputils.h
Executable file
50
include/reputils.h
Executable file
@ -0,0 +1,50 @@
|
||||
#ifndef __REPUTILS_H
|
||||
#define __REPUTILS_H
|
||||
|
||||
#ifndef __REPORT_H
|
||||
#include <report.h>
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TAS400_report
|
||||
// Report dinamico per visualizzare file di testo AS400
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TAS400_report : public TReport
|
||||
{
|
||||
TRecordset* _set; // TAS400_recordset
|
||||
bool _owned;
|
||||
|
||||
protected:
|
||||
virtual TRecordset* recordset() const;
|
||||
virtual bool set_recordset(TRecordset* recset);
|
||||
|
||||
public:
|
||||
virtual bool set_recordset(const TString& query);
|
||||
|
||||
TAS400_report(const char* query);
|
||||
TAS400_report(TRecordset& recset); // TAS400_recordset!!!
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TLog_report
|
||||
// Report per visualizzare file di log
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TLog_report : public TReport
|
||||
{
|
||||
TString _title;
|
||||
|
||||
protected:
|
||||
virtual bool use_mask() { return false; }
|
||||
virtual bool get_usr_val(const TString& name, TVariant& var) const;
|
||||
virtual bool set_usr_val(const TString& name, const TVariant& var);
|
||||
|
||||
public:
|
||||
void reset();
|
||||
bool log(int severity, const char* msg); // severity: 0=normal; 1=warning; 2=error
|
||||
void set_title(const char* title);
|
||||
TLog_report(const char* title, const char* name = "bagn010a");
|
||||
};
|
||||
|
||||
#endif
|
575
include/textset.cpp
Executable file
575
include/textset.cpp
Executable file
@ -0,0 +1,575 @@
|
||||
#include <textset.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TText_recordset
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
bool TText_recordset::destroy(TRecnotype r)
|
||||
{
|
||||
const bool ok = _rec.destroy(r, true);
|
||||
if (ok && (_curr == r || _curr > _rec.items()))
|
||||
_curr = -1;
|
||||
return ok;
|
||||
}
|
||||
|
||||
const TRecordset_column_info& TText_recordset::column_info(const char* column) const
|
||||
{
|
||||
return column_info(find_column(column));
|
||||
}
|
||||
|
||||
TRecnotype TText_recordset::new_rec(const char* rec)
|
||||
{
|
||||
_curr = _rec.add(rec);
|
||||
const int l = row(_curr).size(); // Forse sarebbe piu' sicuro len()
|
||||
if (l > _info._width)
|
||||
_info._width = l;
|
||||
return _curr;
|
||||
}
|
||||
|
||||
TToken_string& TText_recordset::row(TRecnotype n) const
|
||||
{
|
||||
if (n < 0)
|
||||
n = current_row();
|
||||
if (n < 0 || n >= items())
|
||||
n = ((TText_recordset*)this)->new_rec(); // Clausola di salvaguardia
|
||||
return (TToken_string&)_rec.row(n);
|
||||
}
|
||||
|
||||
TRecnotype TText_recordset::items() const
|
||||
{
|
||||
TRecnotype n = _rec.items();
|
||||
if (n == 0 && _query.full() && _query.find("CREATE ") < 0)
|
||||
{
|
||||
((TText_recordset*)this)->exec(_query);
|
||||
n = _rec.items();
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
bool TText_recordset::move_to(TRecnotype pos)
|
||||
{
|
||||
_curr = pos;
|
||||
return pos >= 0 && pos < items();
|
||||
}
|
||||
|
||||
void TText_recordset::requery()
|
||||
{
|
||||
}
|
||||
|
||||
bool TText_recordset::load_file(const TFilename& n)
|
||||
{
|
||||
TString str(4096);
|
||||
char* buf = str.get_buffer();
|
||||
ifstream f(n);
|
||||
while (f)
|
||||
{
|
||||
f.getline(buf, str.size());
|
||||
new_rec(buf);
|
||||
}
|
||||
return items() > 0;
|
||||
}
|
||||
|
||||
int TText_recordset::find_column(const char* column) const
|
||||
{
|
||||
int n = 0;
|
||||
if (column && *column)
|
||||
{
|
||||
if (real::is_natural(column))
|
||||
n = atoi(column);
|
||||
else
|
||||
{
|
||||
for (const char* c = column; isalpha(*c); c++)
|
||||
{
|
||||
n *= 26;
|
||||
n += toupper(*c)-'A';
|
||||
}
|
||||
}
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
const TVariant& TText_recordset::get(unsigned int column) const
|
||||
{
|
||||
const TRecnotype n = current_row();
|
||||
if (column == 0 && n >= 0 && n < items())
|
||||
{
|
||||
TVariant& var = get_tmp_var();
|
||||
var.set(((TText_recordset*)this)->row(n));
|
||||
return var;
|
||||
}
|
||||
return NULL_VARIANT;
|
||||
}
|
||||
|
||||
bool TText_recordset::set(unsigned int column, const TVariant& var)
|
||||
{
|
||||
const bool ok = column == 0;
|
||||
if (ok)
|
||||
row() = var.as_string();
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TText_recordset::set(const char* column, const TVariant& var)
|
||||
{
|
||||
return set(find_column(column), var);
|
||||
}
|
||||
|
||||
TQuery_type TText_recordset::parse_query(const char* query, TFilename& table)
|
||||
{
|
||||
TQuery_type qt = _qt_none;
|
||||
|
||||
TString q(query); q.trim();
|
||||
const int ct = q.find("CREATE TABLE ");
|
||||
if (ct >= 0)
|
||||
{
|
||||
const TToken_string t(q.mid(ct), ' ');
|
||||
t.get(2, table); // Furbastro: prendo la terza parola della query
|
||||
table.trim();
|
||||
if (table.not_empty())
|
||||
qt = _qt_create;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int se = q.find("SELECT ");
|
||||
if (se >= 0)
|
||||
{
|
||||
int n = q.find("FROM ", se);
|
||||
table = q.mid(n+5);
|
||||
n = table.find("WHERE");
|
||||
if (n > 0)
|
||||
table.cut(n-1);
|
||||
n = table.find(',');
|
||||
if (n > 0)
|
||||
table.cut(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
table = query;
|
||||
}
|
||||
table.trim();
|
||||
if (table.not_empty())
|
||||
qt = _qt_select;
|
||||
}
|
||||
return qt;
|
||||
}
|
||||
|
||||
bool TText_recordset::exec(const char* query)
|
||||
{
|
||||
TFilename name;
|
||||
const TQuery_type qt = parse_query(query, name);
|
||||
if (qt != _qt_none)
|
||||
{
|
||||
_query = query; _query.trim();
|
||||
if (qt == _qt_select)
|
||||
{
|
||||
destroy();
|
||||
load_file(name);
|
||||
}
|
||||
}
|
||||
return qt != _qt_none;
|
||||
}
|
||||
|
||||
bool TText_recordset::save_as_text(const char* path)
|
||||
{
|
||||
bool ok = path && *path;
|
||||
if (ok)
|
||||
{
|
||||
ofstream out(path);
|
||||
for (bool ok = move_first(); ok; ok = move_next())
|
||||
out << row() << endl;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TText_recordset::save_as(const char* path, TRecordsetExportFormat fmt)
|
||||
{
|
||||
if (fmt == fmt_text || fmt == fmt_unknown)
|
||||
{
|
||||
TFilename n = path;
|
||||
if (n.blank())
|
||||
parse_query(_query, n);
|
||||
if (n.full())
|
||||
return save_as_text(n);
|
||||
}
|
||||
return TRecordset::save_as(path, fmt);
|
||||
}
|
||||
|
||||
TText_recordset::TText_recordset(const char* query) : _query(query), _curr(-1)
|
||||
{
|
||||
_info._name = "A";
|
||||
_info._pos = _info._width = 0;
|
||||
_info._type = _alfafld;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TCSV_recordset
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
TQuery_type TCSV_recordset::parse_query(const char* query, TFilename& table)
|
||||
{
|
||||
TString q(query);
|
||||
|
||||
if (q.starts_with("CSV(", true))
|
||||
{
|
||||
const int apici = q.find('"');
|
||||
if (apici > 0)
|
||||
_separator = q[apici+1];
|
||||
else
|
||||
_separator = ',';
|
||||
|
||||
q = q.after(')');
|
||||
q.trim();
|
||||
}
|
||||
return TText_recordset::parse_query(q, table);
|
||||
}
|
||||
|
||||
|
||||
unsigned int TCSV_recordset::columns() const
|
||||
{
|
||||
unsigned int c = _trc.items();
|
||||
if (c == 0)
|
||||
{
|
||||
items();
|
||||
c = _trc.items();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
const TRecordset_column_info& TCSV_recordset::column_info(unsigned int column) const
|
||||
{
|
||||
if (column >= 0 && column < columns())
|
||||
{
|
||||
TRecordset_column_info* ci = (TRecordset_column_info*)_trc.objptr(column);
|
||||
if (ci != NULL)
|
||||
return *ci;
|
||||
}
|
||||
return TText_recordset::column_info(column);
|
||||
}
|
||||
|
||||
TRecnotype TCSV_recordset::new_rec(const char* rec)
|
||||
{
|
||||
const TRecnotype n = TText_recordset::new_rec(rec);
|
||||
if (n >= 0)
|
||||
row(n).separator(_separator);
|
||||
return n;
|
||||
}
|
||||
|
||||
bool TCSV_recordset::load_file(const TFilename& n)
|
||||
{
|
||||
if (!TText_recordset::load_file(n))
|
||||
return false;
|
||||
|
||||
_trc.destroy();
|
||||
int cols = 1;
|
||||
int i;
|
||||
for (i = items()-1; i >= 0; i--)
|
||||
{
|
||||
const TToken_string& r = row(i);
|
||||
const int c = r.items();
|
||||
if (c > cols)
|
||||
cols = c;
|
||||
}
|
||||
|
||||
for (i = 0; i < cols; i++)
|
||||
_trc.add(new TRecordset_column_info);
|
||||
|
||||
TString val;
|
||||
for (i = items()-1; i >= 0; i--)
|
||||
{
|
||||
const TToken_string& r = row(i);
|
||||
for (int c = r.items()-1; c >= 0; c--)
|
||||
{
|
||||
r.get(c, val);
|
||||
if (val.full())
|
||||
{
|
||||
TRecordset_column_info& ci = *(TRecordset_column_info*)_trc.objptr(c);
|
||||
const int l = val.len();
|
||||
if (l > ci._width)
|
||||
{
|
||||
ci._width = l;
|
||||
if (l == 8 || l == 10 && TDate::isdate(val))
|
||||
ci._type = _datefld;
|
||||
else
|
||||
{
|
||||
if (!real::is_null(val))
|
||||
{
|
||||
if (real::is_natural(val))
|
||||
ci._type = _intfld;
|
||||
else
|
||||
ci._type = _realfld;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TCSV_recordset::set(unsigned int column, const TVariant& var)
|
||||
{
|
||||
TToken_string& r = row();
|
||||
r.add(var.as_string(), column);
|
||||
return true;
|
||||
}
|
||||
|
||||
const TVariant& TCSV_recordset::get(unsigned int column) const
|
||||
{
|
||||
const TRecnotype n = current_row();
|
||||
if (n >= 0 && n < items())
|
||||
{
|
||||
const char* val = row(n).get(column);
|
||||
if (val != NULL)
|
||||
{
|
||||
TVariant& var = get_tmp_var();
|
||||
var.set(val);
|
||||
return var;
|
||||
}
|
||||
}
|
||||
return NULL_VARIANT;
|
||||
}
|
||||
|
||||
TCSV_recordset::TCSV_recordset(const char* query)
|
||||
: TText_recordset(query), _separator(',')
|
||||
{ }
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TAS400_recordset
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
bool TAS400_recordset::load_file(const TFilename& n)
|
||||
{
|
||||
TString row(record_length(), ' ');
|
||||
ifstream f(n, ios::binary);
|
||||
char* buf = row.get_buffer();
|
||||
TRecnotype r = -1;
|
||||
while (f)
|
||||
{
|
||||
*buf = '\0';
|
||||
f.read(buf, record_length());
|
||||
if (*buf)
|
||||
r = new_rec(buf);
|
||||
else
|
||||
break;
|
||||
}
|
||||
return r >= 0;
|
||||
}
|
||||
|
||||
TQuery_type TAS400_recordset::parse_query(const char* query, TFilename& table)
|
||||
{
|
||||
TString q(query);
|
||||
if (q.find("AS400(") >= 0)
|
||||
{
|
||||
const int da = q.find('(');
|
||||
const int al = q.find(')', da);
|
||||
TToken_string k(q.sub(da+1, al), ',');
|
||||
_info._width = k.get_int(0);
|
||||
_key._width = k.get_int();
|
||||
_key._pos = k.get_int();
|
||||
q = q.mid(al+1);
|
||||
q.trim();
|
||||
}
|
||||
return TText_recordset::parse_query(q, table);
|
||||
}
|
||||
|
||||
bool TAS400_recordset::set_field(const TAS400_column_info& fi, const TVariant& var)
|
||||
{
|
||||
TToken_string& r = row();
|
||||
switch (fi._type)
|
||||
{
|
||||
case _intfld:
|
||||
case _longfld:
|
||||
{
|
||||
TString16 str;
|
||||
str.format("%*ld", fi._width, var.as_int());
|
||||
r.overwrite(str, fi._pos);
|
||||
}
|
||||
break;
|
||||
case _intzerofld:
|
||||
case _longzerofld:
|
||||
{
|
||||
TString16 str;
|
||||
str.format("%0*ld", fi._width, var.as_int());
|
||||
r.overwrite(str, fi._pos);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
r.overwrite(var.as_string(), fi._pos, fi._width);
|
||||
break;
|
||||
}
|
||||
bool ok = true;
|
||||
if (fi._required && var.is_empty())
|
||||
ok = false;
|
||||
return ok;
|
||||
}
|
||||
|
||||
TAS400_column_info* TAS400_recordset::parse_field(const char* column, int& c, bool create)
|
||||
{
|
||||
CHECK(column && *column > ' ', "NULL field name");
|
||||
TAS400_column_info* ci = NULL;
|
||||
|
||||
TString16 trc;
|
||||
TString80 fld(column);
|
||||
const int dot = fld.find('.');
|
||||
if (dot > 0)
|
||||
{
|
||||
trc = fld.left(dot);
|
||||
fld.ltrim(dot+1);
|
||||
}
|
||||
else
|
||||
trc = rec_type();
|
||||
|
||||
TArray* info = (TArray*)_trc.objptr(trc);
|
||||
if (info == NULL && create)
|
||||
{
|
||||
info = new TArray;
|
||||
_trc.add(trc, info);
|
||||
}
|
||||
|
||||
if (info != NULL)
|
||||
{
|
||||
if (create)
|
||||
{
|
||||
ci = new TAS400_column_info;
|
||||
ci->_name = fld;
|
||||
c = info->add(ci);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (c = info->last(); c >= 0; c--)
|
||||
{
|
||||
TAS400_column_info* aci = (TAS400_column_info*)info->objptr(c);
|
||||
if (aci->_name == fld)
|
||||
{
|
||||
ci = aci;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return ci;
|
||||
}
|
||||
|
||||
int TAS400_recordset::find_column(const char* column) const
|
||||
{
|
||||
int c = -1;
|
||||
((TAS400_recordset*)this)->parse_field(column, c, false);
|
||||
return c;
|
||||
}
|
||||
|
||||
const TRecordset_column_info& TAS400_recordset::column_info(const char* column) const
|
||||
{
|
||||
int c = -1;
|
||||
TRecordset_column_info* ci = ((TAS400_recordset*)this)->parse_field(column, c, false);
|
||||
if (ci != NULL)
|
||||
return *ci;
|
||||
return TText_recordset::column_info(column);
|
||||
}
|
||||
|
||||
const TVariant& TAS400_recordset::get(const char* column) const
|
||||
{
|
||||
int c = -1;
|
||||
if (column && column[1] != '\0')
|
||||
{
|
||||
TAS400_column_info* ci = ((TAS400_recordset*)this)->parse_field(column, c, false);
|
||||
if (ci != NULL)
|
||||
{
|
||||
const TRecnotype n = current_row();
|
||||
if (n >= 0 && n < items())
|
||||
{
|
||||
const TString& str = row(n).mid(ci->_pos, ci->_width);
|
||||
TVariant& var = get_tmp_var();
|
||||
var.set(str);
|
||||
return var;
|
||||
}
|
||||
return ci->_default;
|
||||
}
|
||||
}
|
||||
c = TText_recordset::find_column(column);
|
||||
return TText_recordset::get(c);
|
||||
}
|
||||
|
||||
TRecnotype TAS400_recordset::new_rec(const char* trc)
|
||||
{
|
||||
CHECK(record_length() > 0, "Lunghezza record nulla");
|
||||
TString str(record_length(), ' ');
|
||||
const TRecnotype n = TText_recordset::new_rec(str);
|
||||
if (trc && (int)strlen(trc) == key_length())
|
||||
{
|
||||
TArray* info = (TArray*)_trc.objptr(trc);
|
||||
if (info != NULL) // Se il tracciato e' noto, riempio di zeri i campi opportuni
|
||||
{
|
||||
FOR_EACH_ARRAY_ITEM_BACK((*info), i, obj)
|
||||
{
|
||||
const TAS400_column_info& ci = *(const TAS400_column_info*)obj;
|
||||
if (ci._default.is_null())
|
||||
{
|
||||
if (ci._type == _intzerofld || ci._type == _longzerofld)
|
||||
set_field(ci, NULL_VARIANT);
|
||||
}
|
||||
else
|
||||
set_field(ci, ci._default);
|
||||
}
|
||||
}
|
||||
row(n).overwrite(trc, key_position());
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
const TString& TAS400_recordset::rec_type(TRecnotype r) const
|
||||
{
|
||||
const TToken_string& riga = row(r);
|
||||
return riga.mid(key_position(), key_length());
|
||||
}
|
||||
|
||||
bool TAS400_recordset::create_field(const char* nam, int pos, int len,
|
||||
TFieldtypes typ, bool req, const TVariant& def)
|
||||
{
|
||||
CHECK(nam && *nam, "Null field name");
|
||||
CHECKD(pos >= 0 && pos < record_length(), "Invalid field position ", pos);
|
||||
CHECKD(len > 0 && pos+len <= record_length(), "Invalid field lenght ", len);
|
||||
|
||||
int c = -1;
|
||||
TAS400_column_info* ci = parse_field(nam, c, true);
|
||||
const bool ok = ci != NULL;
|
||||
if (ok)
|
||||
{
|
||||
ci->_pos = pos;
|
||||
ci->_width = len;
|
||||
ci->_type = typ;
|
||||
ci->_required = req;
|
||||
ci->_default = def;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TAS400_recordset::set(const char* column, const TVariant& var)
|
||||
{
|
||||
int c = -1;
|
||||
TAS400_column_info* ci = parse_field(column, c, false);
|
||||
bool ok = ci != NULL;
|
||||
if (ok)
|
||||
ok = set_field(*ci, var);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool TAS400_recordset::save_as_text(const char* path)
|
||||
{
|
||||
bool valid = path && *path;
|
||||
if (valid)
|
||||
{
|
||||
ofstream out(path, ios::binary);
|
||||
for (bool ok = move_first(); ok; ok = move_next())
|
||||
out << row(); // NON mettere << endl
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
TAS400_recordset::TAS400_recordset(const char* query)
|
||||
: TText_recordset(query)
|
||||
{
|
||||
TFilename n;
|
||||
if (parse_query(query, n) == _qt_select && n.exist())
|
||||
load_file(n);
|
||||
}
|
129
include/textset.h
Executable file
129
include/textset.h
Executable file
@ -0,0 +1,129 @@
|
||||
#ifndef __TEXTSET_H
|
||||
#define __TEXTSET_H
|
||||
|
||||
#ifndef __REPORT_H
|
||||
#include <report.h>
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TText_recordset
|
||||
// Classe virtuale per gestire file di testo generici
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
enum TQuery_type { _qt_none, _qt_select, _qt_create };
|
||||
|
||||
class TText_recordset : public TRecordset
|
||||
{
|
||||
TRecnotype _curr;
|
||||
TString_array _rec;
|
||||
|
||||
protected:
|
||||
TString _query;
|
||||
TRecordset_column_info _info; // Informazioni sull'unica colonna esistente
|
||||
|
||||
protected:
|
||||
virtual TQuery_type parse_query(const char* query, TFilename& table);
|
||||
virtual bool load_file(const TFilename& n);
|
||||
TToken_string& row(TRecnotype n = -1) const;
|
||||
|
||||
public:
|
||||
virtual unsigned int columns() const { return 1; }
|
||||
virtual const TRecordset_column_info& column_info(unsigned int) const { return _info; }
|
||||
virtual const TRecordset_column_info& column_info(const char* column) const;
|
||||
virtual int find_column(const char* column) const;
|
||||
|
||||
virtual TRecnotype items() const;
|
||||
virtual bool move_to(TRecnotype pos);
|
||||
virtual TRecnotype current_row() const { return _curr; }
|
||||
virtual void requery();
|
||||
virtual const TVariant& get(unsigned int column) const;
|
||||
|
||||
public:
|
||||
virtual const TString& query_text() const { return _query; }
|
||||
|
||||
virtual bool destroy(TRecnotype r = -1);
|
||||
virtual TRecnotype new_rec(const char* buf = NULL);
|
||||
virtual bool set(unsigned int fld, const TVariant& var);
|
||||
virtual bool set(const char* fld, const TVariant& var);
|
||||
virtual bool exec(const char* query);
|
||||
|
||||
virtual bool save_as_text(const char* path);
|
||||
virtual bool save_as(const char* path, TRecordsetExportFormat fmt = fmt_text);
|
||||
|
||||
TText_recordset(const char* query);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TCSV_recordset
|
||||
// Classe per file di testo con campi separati da virgola (o altro separatore)
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TCSV_recordset : public TText_recordset
|
||||
{
|
||||
char _separator;
|
||||
TArray _trc;
|
||||
|
||||
protected:
|
||||
virtual TQuery_type parse_query(const char* query, TFilename& table);
|
||||
|
||||
public:
|
||||
virtual unsigned int columns() const;
|
||||
virtual const TRecordset_column_info& column_info(unsigned int column) const;
|
||||
virtual const TVariant& get(unsigned int column) const;
|
||||
virtual TRecnotype new_rec(const char* buf = NULL);
|
||||
virtual bool set(unsigned int fld, const TVariant& var);
|
||||
virtual bool load_file(const TFilename& n);
|
||||
|
||||
public:
|
||||
TCSV_recordset(const char* query);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TAS400_recordset
|
||||
// Classe per file di testo con record a lunghezza fissa
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
struct TAS400_column_info : public TRecordset_column_info
|
||||
{
|
||||
TVariant _default;
|
||||
bool _required;
|
||||
|
||||
TAS400_column_info() : _required(false) { }
|
||||
};
|
||||
|
||||
class TAS400_recordset : public TText_recordset
|
||||
{
|
||||
protected:
|
||||
TAS400_column_info _key;
|
||||
TAssoc_array _trc;
|
||||
|
||||
protected:
|
||||
virtual TQuery_type parse_query(const char* query, TFilename& table);
|
||||
virtual bool load_file(const TFilename& n);
|
||||
virtual int find_column(const char* column) const;
|
||||
|
||||
virtual bool save_as_text(const char* path);
|
||||
|
||||
TAS400_column_info* parse_field(const char* column, int& c, bool create);
|
||||
bool set_field(const TAS400_column_info& fi, const TVariant& var);
|
||||
|
||||
public:
|
||||
virtual TRecnotype new_rec(const char* buf = NULL);
|
||||
virtual bool set(const char* column, const TVariant& var);
|
||||
|
||||
virtual const TRecordset_column_info& column_info(const char* colunmn) const;
|
||||
virtual const TVariant& get(const char* colunmn) const;
|
||||
|
||||
public:
|
||||
bool create_field(const char* name, int pos, int len, TFieldtypes t = _alfafld,
|
||||
bool required = false, const TVariant& def = NULL_VARIANT);
|
||||
|
||||
int record_length() const { return _info._width; }
|
||||
int key_length() const { return _key._width; }
|
||||
int key_position() const { return _key._pos; }
|
||||
virtual const TString& rec_type(TRecnotype r = -1) const;
|
||||
|
||||
TAS400_recordset(const char* query);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user