ba1.cpp Aggiunti commenti ba1300.cpp Nessuna differenza ba2* Gestione backup con pkzip ba3* e b4* Aggiornata get_next_key git-svn-id: svn://10.65.10.50/trunk@6594 c028cbd2-c16b-5b4b-a496-9718f37d4682
736 lines
15 KiB
C++
Executable File
736 lines
15 KiB
C++
Executable File
#include <time.h>
|
|
|
|
#include <browfile.h>
|
|
#include <relapp.h>
|
|
#include <tree.h>
|
|
#include <urldefid.h>
|
|
|
|
class TPianoconti_tree : public TBidirectional_tree
|
|
{
|
|
TArray _cursor; // Gruppi, Conti, Sottoconti, Clienti, Fornitori
|
|
int _curindex;
|
|
TToken_string _curnode;
|
|
|
|
private:
|
|
TCursor& cursor() const { return (TCursor&)_cursor[_curindex]; }
|
|
TCursor& cursor(int n) const { return (TCursor&)_cursor[n]; }
|
|
bool update_curr();
|
|
void restore_curr();
|
|
|
|
protected:
|
|
virtual void node2id(const TObject* node, TString& id) const;
|
|
|
|
public:
|
|
virtual bool has_root() const;
|
|
virtual bool goto_root();
|
|
virtual bool has_son() const;
|
|
virtual bool goto_firstson();
|
|
virtual bool has_rbrother() const;
|
|
virtual bool goto_rbrother();
|
|
virtual bool has_father() const;
|
|
virtual bool goto_father();
|
|
virtual bool has_lbrother() const;
|
|
virtual bool goto_lbrother();
|
|
|
|
virtual bool goto_node(const TString &id);
|
|
virtual TObject* curr_node() const;
|
|
virtual bool get_description(TString& desc) const;
|
|
|
|
TPianoconti_tree();
|
|
virtual ~TPianoconti_tree();
|
|
};
|
|
|
|
TPianoconti_tree::TPianoconti_tree()
|
|
{
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
TRelation* rel = new TRelation(i < 3 ? LF_PCON : LF_CLIFO);
|
|
TCursor* cur = NULL;
|
|
switch (i)
|
|
{
|
|
case 0: cur = new TCursor(rel, "CONTO==0"); break;
|
|
case 1: cur = new TCursor(rel, "(CONTO!=0)&&(SOTTOCONTO==0)"); break;
|
|
case 2: cur = new TCursor(rel, "SOTTOCONTO!=0"); break;
|
|
case 3:
|
|
case 4:
|
|
{
|
|
TRectype rec(rel->curr());
|
|
rec.put("TIPOCF", i == 3 ? "C" : "F");
|
|
cur = new TCursor(rel, "", 1, &rec, &rec);
|
|
}
|
|
break;
|
|
default: break;
|
|
}
|
|
CHECK(cur, "Invalid tree cursor");
|
|
_cursor.add(cur);
|
|
}
|
|
goto_root();
|
|
}
|
|
|
|
TPianoconti_tree::~TPianoconti_tree()
|
|
{
|
|
for (int i = _cursor.last(); i >= 0; i--)
|
|
{
|
|
TRelation* rel = cursor(i).relation();
|
|
delete rel;
|
|
}
|
|
_cursor.destroy();
|
|
}
|
|
|
|
bool TPianoconti_tree::update_curr()
|
|
{
|
|
_curnode.cut(0);
|
|
_curnode.add(_curindex);
|
|
_curnode.add(cursor(0).pos());
|
|
if (_curindex > 0)
|
|
_curnode.add(cursor(1).pos());
|
|
if (_curindex > 1)
|
|
_curnode.add(cursor().pos());
|
|
return TRUE;
|
|
}
|
|
|
|
void TPianoconti_tree::restore_curr()
|
|
{
|
|
_curindex = _curnode.get_int(0);
|
|
cursor(0) = _curnode.get_long();
|
|
if (_curindex > 0)
|
|
cursor(1) = _curnode.get_long();
|
|
if (_curindex > 1)
|
|
cursor() = _curnode.get_long();
|
|
}
|
|
|
|
void TPianoconti_tree::node2id(const TObject* node, TString& id) const
|
|
{
|
|
id = *(const TToken_string*)node;
|
|
}
|
|
|
|
TObject* TPianoconti_tree::curr_node() const
|
|
{
|
|
return &((TPianoconti_tree*)this)->_curnode;
|
|
}
|
|
|
|
bool TPianoconti_tree::goto_root()
|
|
{
|
|
for (int c = _cursor.last(); c >= 0; c--)
|
|
{
|
|
TCursor& cur = cursor(c);
|
|
cur.freeze(FALSE);
|
|
cur = 0L;
|
|
cur.freeze(TRUE);
|
|
}
|
|
_curindex = 0;
|
|
update_curr();
|
|
return cursor().items() > 0;
|
|
}
|
|
|
|
bool TPianoconti_tree::goto_firstson()
|
|
{
|
|
bool ok = _curindex < 2;
|
|
if (ok)
|
|
{
|
|
if (_curindex == 0)
|
|
{
|
|
TCursor& cur = cursor(1);
|
|
TRectype& curr = cur.curr();
|
|
const TString16 gruppo = cursor().curr().get("GRUPPO");
|
|
curr.zero();
|
|
curr.put("GRUPPO", gruppo);
|
|
TRecnotype pos = cur.read(_isgteq);
|
|
ok = pos >= 0 && curr.get("GRUPPO") == gruppo;
|
|
if (ok)
|
|
{
|
|
_curindex = 1;
|
|
update_curr();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
char tipo = cursor().curr().get_char("TMCF");
|
|
if (tipo <= ' ')
|
|
{
|
|
TCursor& cur = cursor(2);
|
|
TRectype& curr = cur.curr();
|
|
const TString16 gruppo = cursor().curr().get("GRUPPO");
|
|
const TString16 conto = cursor().curr().get("CONTO");
|
|
curr.zero();
|
|
curr.put("GRUPPO", gruppo);
|
|
curr.put("CONTO", conto);
|
|
TRecnotype pos = cur.read(_isgteq);
|
|
ok = pos >= 0 && curr.get("GRUPPO") == gruppo && curr.get("CONTO") == conto;
|
|
if (ok)
|
|
{
|
|
_curindex = 2;
|
|
update_curr();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const int i = tipo == 'C' ? 3 : 4;
|
|
ok = cursor(i).items() > 0;
|
|
if (ok)
|
|
{
|
|
_curindex = i;
|
|
cursor() = 0;
|
|
update_curr();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TPianoconti_tree::has_son() const
|
|
{
|
|
return _curindex < 2;
|
|
}
|
|
|
|
bool TPianoconti_tree::goto_rbrother()
|
|
{
|
|
TCursor& cur = cursor();
|
|
bool ok = cur.pos() < cur.items()-1;
|
|
if (ok)
|
|
{
|
|
TRectype& curr = cur.curr();
|
|
TString16 gruppo, conto;
|
|
if (_curindex == 1 || _curindex == 2)
|
|
gruppo = curr.get("GRUPPO");
|
|
if (_curindex == 2)
|
|
conto = curr.get("CONTO");
|
|
|
|
++cur;
|
|
|
|
if (_curindex == 1 || _curindex == 2)
|
|
ok = curr.get("GRUPPO") == gruppo;
|
|
if (ok && _curindex == 2)
|
|
ok = curr.get("CONTO") == conto;
|
|
|
|
if (ok)
|
|
update_curr();
|
|
else
|
|
--cur;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TPianoconti_tree::has_rbrother() const
|
|
{
|
|
const TString old = _curnode;
|
|
bool ok = ((TPianoconti_tree*)this)->goto_rbrother();
|
|
if (ok)
|
|
((TPianoconti_tree*)this)->goto_node(old);
|
|
return ok;
|
|
}
|
|
|
|
bool TPianoconti_tree::has_root() const
|
|
{ return cursor(0).items() > 0; }
|
|
|
|
bool TPianoconti_tree::has_father() const
|
|
{ return _curindex > 0; }
|
|
|
|
bool TPianoconti_tree::has_lbrother() const
|
|
{
|
|
const TString old = _curnode;
|
|
bool ok = ((TPianoconti_tree*)this)->goto_lbrother();
|
|
if (ok)
|
|
((TPianoconti_tree*)this)->goto_node(old);
|
|
return ok;
|
|
}
|
|
|
|
bool TPianoconti_tree::goto_father()
|
|
{
|
|
bool ok = _curindex > 0;
|
|
if (ok)
|
|
{
|
|
if (_curindex >= 2)
|
|
_curindex = 1;
|
|
else
|
|
_curindex = 0;
|
|
update_curr();
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TPianoconti_tree::goto_lbrother()
|
|
{
|
|
TCursor& cur = cursor();
|
|
bool ok = cur.pos() > 0;
|
|
if (ok)
|
|
{
|
|
TRectype& curr = cur.curr();
|
|
TString16 gruppo, conto;
|
|
if (_curindex == 1 || _curindex == 2)
|
|
gruppo = curr.get("GRUPPO");
|
|
if (_curindex == 2)
|
|
conto = curr.get("CONTO");
|
|
|
|
--cur;
|
|
|
|
if (_curindex == 1 || _curindex == 2)
|
|
ok = curr.get("GRUPPO") == gruppo;
|
|
if (ok && _curindex == 2)
|
|
ok = curr.get("CONTO") == conto;
|
|
|
|
if (ok)
|
|
update_curr();
|
|
else
|
|
++cur;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool TPianoconti_tree::goto_node(const TString &id)
|
|
{
|
|
_curnode = id;
|
|
restore_curr();
|
|
return TRUE;
|
|
}
|
|
|
|
bool TPianoconti_tree::get_description(TString& desc) const
|
|
{
|
|
desc = cursor(0).curr().get("GRUPPO");
|
|
if (_curindex > 0)
|
|
desc << '.' << cursor(1).curr().get("CONTO");
|
|
const TRectype& curr = cursor().curr();
|
|
if (_curindex == 2)
|
|
desc << '.' << curr.get("SOTTOCONTO");
|
|
else
|
|
{
|
|
if (_curindex > 2)
|
|
desc << '.' << curr.get("CODCF");
|
|
}
|
|
if (_curindex <= 2)
|
|
desc << ' ' << curr.get("DESCR");
|
|
else
|
|
desc << ' ' << curr.get("RAGSOC");
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TTab_application : public TRelation_application
|
|
{
|
|
TMask* _msk;
|
|
TRelation* _rel;
|
|
|
|
protected:
|
|
virtual TMask* get_mask(int mode);
|
|
virtual TRelation* get_relation() const;
|
|
virtual bool changing_mask(int mode);
|
|
virtual bool user_create();
|
|
virtual bool user_destroy();
|
|
|
|
public:
|
|
TTab_application();
|
|
virtual ~TTab_application();
|
|
};
|
|
|
|
// @cmember Costruttore
|
|
TTab_application::TTab_application()
|
|
: _msk(NULL), _rel(NULL)
|
|
{ }
|
|
|
|
// @cmember Distruttore
|
|
TTab_application::~TTab_application()
|
|
{ }
|
|
|
|
// @cmember Indica se la futura <mf TTab_application::get_mask> ritornera' una maschera diversa
|
|
// dalla corrente.
|
|
bool TTab_application::changing_mask(int mode)
|
|
{ return FALSE; }
|
|
|
|
// @cmember Richiede la maschera da usare
|
|
TMask* TTab_application::get_mask(int mode)
|
|
{
|
|
CHECK(_msk, "Null mask");
|
|
return _msk;
|
|
}
|
|
|
|
// @cmember Ritorna la relazione da modificare
|
|
TRelation* TTab_application::get_relation() const
|
|
{
|
|
CHECK(_rel, "Null relation");
|
|
return _rel;
|
|
}
|
|
|
|
bool TTab_application::user_create()
|
|
{
|
|
if (argc() < 3)
|
|
return FALSE;
|
|
|
|
TString16 tabname = argv(2);
|
|
tabname.upper();
|
|
_rel = new TRelation(tabname);
|
|
|
|
TString16 t(tabname);
|
|
if (t[0] == '%') t.ltrim(1);
|
|
TString16 m; m << "BATB" << t;
|
|
_msk = new TMask(m) ;
|
|
|
|
TString tit;
|
|
_msk->get_caption(tit);
|
|
set_title(tit);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool TTab_application::user_destroy()
|
|
{
|
|
if (_msk) delete _msk;
|
|
if (_rel) delete _rel;
|
|
return TRUE;
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Test Relapp
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TTestrel_application : public TRelation_application
|
|
{
|
|
const char* _maskname;
|
|
const char* _num;
|
|
|
|
TRelation* _rel;
|
|
TMask* _msk;
|
|
|
|
protected:
|
|
virtual bool user_create();
|
|
virtual bool user_destroy();
|
|
virtual TMask* get_mask(int) { return _msk; }
|
|
virtual bool changing_mask(int) { return FALSE;}
|
|
virtual TRelation* get_relation() const { return _rel; }
|
|
virtual int read(TMask& m);
|
|
virtual int write(const TMask&);
|
|
virtual int rewrite(const TMask&);
|
|
virtual bool remove() { return FALSE; }
|
|
|
|
public:
|
|
TTestrel_application(const char* name, const char* num);
|
|
};
|
|
|
|
TTestrel_application::TTestrel_application(const char* name, const char* num)
|
|
: _maskname(name), _num(num),
|
|
_msk(NULL), _rel(NULL)
|
|
{}
|
|
|
|
|
|
bool TTestrel_application::user_create()
|
|
{
|
|
const int id = atoi(_num);
|
|
if (id > 0) _rel = new TRelation(id);
|
|
else _rel = new TRelation(_num);
|
|
|
|
_msk = new TMask(_maskname);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
bool TTestrel_application::user_destroy()
|
|
{
|
|
delete _msk;
|
|
delete _rel;
|
|
return TRUE;
|
|
}
|
|
|
|
int TTestrel_application::read(TMask& m)
|
|
{
|
|
m.autoload(*_rel);
|
|
return NOERR;
|
|
}
|
|
|
|
int TTestrel_application::write(const TMask& m)
|
|
{
|
|
m.autosave(*_rel);
|
|
return NOERR;
|
|
}
|
|
|
|
int TTestrel_application::rewrite(const TMask& m)
|
|
{
|
|
m.autosave(*_rel);
|
|
return NOERR;
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// Testmask
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TTest_application : public TSkeleton_application
|
|
{
|
|
TFilename _maskname;
|
|
|
|
protected:
|
|
virtual void main_loop();
|
|
|
|
static bool tree_handler(TMask_field& f, KEY k);
|
|
|
|
public:
|
|
void fill_trees(TMask& msk);
|
|
|
|
TTest_application(const char* name) : _maskname(name) {}
|
|
virtual~ TTest_application() {}
|
|
};
|
|
|
|
bool TTest_application::tree_handler(TMask_field& f, KEY k)
|
|
{
|
|
if (k == K_SPACE || k == K_CTRL+K_SPACE)
|
|
{
|
|
TMask_field& next_field = f.mask().field(f.dlg()+1);
|
|
if (next_field.class_id() == CLASS_BROWSEFILE_FIELD)
|
|
{
|
|
TTree_field& tf = (TTree_field&)f;
|
|
TBrowsefile_field& bf = (TBrowsefile_field&)next_field;
|
|
TString str;
|
|
tf.tree()->get_description(str);
|
|
str.insert(k == K_CTRL+K_SPACE ? "** " : "* ", 0);
|
|
bf.add_line(str);
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
void TTest_application::fill_trees(TMask& msk)
|
|
{
|
|
for (int f = msk.fields()-1; f >= 0; f--)
|
|
{
|
|
if (msk.fld(f).is_kind_of(CLASS_TREE_FIELD))
|
|
{
|
|
TTree* t = new TPianoconti_tree;
|
|
TTree_field& tf = (TTree_field&)msk.fld(f);
|
|
tf.set_tree(t);
|
|
// tf.hide_leaves();
|
|
tf.set_handler(tree_handler);
|
|
}
|
|
}
|
|
}
|
|
|
|
void TTest_application::main_loop()
|
|
{
|
|
TMask m(_maskname);
|
|
|
|
#ifdef DBG
|
|
fill_trees(m);
|
|
#endif
|
|
|
|
while (m.run() != K_QUIT);
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
class TBenchmark_application : public TSkeleton_application
|
|
{
|
|
clock_t _timer_start;
|
|
TString _text;
|
|
|
|
protected:
|
|
virtual void main_loop();
|
|
|
|
void initializing();
|
|
void start_test(const char* msg);
|
|
void update_bar(long rec);
|
|
void stop_test();
|
|
|
|
void test_relation_scan();
|
|
void test_cursor_scan();
|
|
void test_file_scan();
|
|
void test_file_random();
|
|
|
|
public:
|
|
TBenchmark_application() { }
|
|
virtual ~TBenchmark_application() { }
|
|
};
|
|
|
|
void TBenchmark_application::main_loop()
|
|
{
|
|
TString test = argv(1); test.upper();
|
|
const bool test_all = test.find('*') >= 0;
|
|
|
|
if (test_all || test.find('F') >= 0)
|
|
test_file_scan();
|
|
|
|
if (test_all || test.find('R') >= 0)
|
|
test_relation_scan();
|
|
|
|
if (test_all || test.find('C') >= 0)
|
|
test_cursor_scan();
|
|
|
|
if (test_all || test.find('T') >= 0)
|
|
test_file_random();
|
|
}
|
|
|
|
void TBenchmark_application::initializing()
|
|
{
|
|
xvt_statbar_set("Initializing...");
|
|
do_events();
|
|
}
|
|
|
|
void TBenchmark_application::start_test(const char* text)
|
|
{
|
|
_text = text;
|
|
xvt_statbar_set(_text);
|
|
do_events();
|
|
|
|
clock_t t;
|
|
_timer_start = clock();
|
|
do
|
|
{
|
|
t = clock();
|
|
} while (t == _timer_start);
|
|
_timer_start = t;
|
|
}
|
|
|
|
void TBenchmark_application::stop_test()
|
|
{
|
|
const clock_t t = clock() - _timer_start;
|
|
const double s = (double)t / CLOCKS_PER_SEC;
|
|
TString msg;
|
|
msg.format("%s\nTempo totale: %.1lf s", (const char*)_text, s);
|
|
message_box(msg);
|
|
}
|
|
|
|
void TBenchmark_application::update_bar(long rec)
|
|
{
|
|
rec++;
|
|
if ((rec % 500) == 0)
|
|
{
|
|
const double sec = double(clock() - _timer_start) / CLOCKS_PER_SEC;
|
|
if (sec > 0.0)
|
|
{
|
|
TString80 msg;
|
|
msg.format("%ld record (%ld rec/sec)", rec, long(rec / sec));
|
|
xvt_statbar_set(msg);
|
|
do_events();
|
|
}
|
|
}
|
|
}
|
|
|
|
void TBenchmark_application::test_file_scan()
|
|
{
|
|
initializing();
|
|
|
|
TSystemisamfile comuni(LF_COMUNI);
|
|
int err = comuni.open(_excllock);
|
|
|
|
if (err == NOERR)
|
|
{
|
|
start_test("Scansione file COMUNI in modo esclusivo");
|
|
comuni.first();
|
|
for (TRecnotype rec = 0; comuni.good(); rec++)
|
|
{
|
|
comuni.next();
|
|
update_bar(rec);
|
|
}
|
|
comuni.close();
|
|
stop_test();
|
|
}
|
|
}
|
|
|
|
|
|
void TBenchmark_application::test_relation_scan()
|
|
{
|
|
initializing();
|
|
|
|
TRelation comuni(LF_COMUNI);
|
|
start_test("Scansione relazione COMUNI");
|
|
|
|
comuni.first();
|
|
for (TRecnotype rec = 0; !comuni.eof(); rec++)
|
|
{
|
|
comuni.next();
|
|
update_bar(rec);
|
|
}
|
|
|
|
stop_test();
|
|
}
|
|
|
|
void TBenchmark_application::test_cursor_scan()
|
|
{
|
|
initializing();
|
|
|
|
TRelation comuni(LF_COMUNI);
|
|
TCursor cur(&comuni);
|
|
|
|
TRecnotype tot = cur.items();
|
|
cur.freeze();
|
|
|
|
start_test("Scansione cursore COMUNI");
|
|
|
|
cur = 0L;
|
|
for (TRecnotype c = 0; c < tot; c++)
|
|
{
|
|
++cur;
|
|
update_bar(c);
|
|
}
|
|
|
|
stop_test();
|
|
}
|
|
|
|
void TBenchmark_application::test_file_random()
|
|
{
|
|
initializing();
|
|
|
|
TLocalisamfile comuni(LF_COMUNI);
|
|
|
|
start_test("Lettura random del file COMUNI");
|
|
|
|
TRectype& rec = comuni.curr();
|
|
char code[8];
|
|
long found, notfound;
|
|
|
|
for (long n = 0; n < 4000; n++)
|
|
{
|
|
const char l = 'A' + rand() % 26;
|
|
const int c = rand() % 100;
|
|
sprintf(code, "%c%03d", l, c);
|
|
rec.zero();
|
|
rec.put("COM", code);
|
|
if (comuni.read() == NOERR)
|
|
found++;
|
|
else
|
|
notfound++;
|
|
update_bar(n);
|
|
}
|
|
|
|
stop_test();
|
|
}
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
TApplication::check_parameters(argc, argv);
|
|
|
|
if (argc > 1 && *argv[1] == '-')
|
|
{
|
|
TBenchmark_application bma;
|
|
bma.run(argc, argv, "Benchmark");
|
|
return 0;
|
|
}
|
|
|
|
if (argc < 3)
|
|
{
|
|
TFilename n = argv[1];
|
|
if (n.not_empty())
|
|
{
|
|
TTest_application a(n);
|
|
n = n.name(); n.insert("Test Mask ", 0);
|
|
a.run(argc, argv, n);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (isdigit(argv[2][0]))
|
|
{
|
|
TTestrel_application a(argv[1], argv[2]);
|
|
a.run(argc, argv, "Test Relation Application");
|
|
}
|
|
else
|
|
{
|
|
TTab_application a;
|
|
a.run(argc, argv, "Test Table Application");
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|