Gestione delle relazioni nel .ini: metodi autoload e autosave e sintassi cambiata

git-svn-id: svn://10.65.10.50/trunk@5329 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
sauro 1997-10-06 12:31:55 +00:00
parent 5f8a049c87
commit d9776d32cb
2 changed files with 120 additions and 31 deletions

View File

@ -73,10 +73,16 @@ TObject* TTracciato_record::dup() const
TTracciato_record::TTracciato_record(const TTracciato_record& tr) TTracciato_record::TTracciato_record(const TTracciato_record& tr)
{ {
set_relation(tr.relation());
set_type(tr.type()); set_type(tr.type());
_tracciati_campo = tr._tracciati_campo; _tracciati_campo = tr._tracciati_campo;
} }
TTracciato_record::~TTracciato_record()
{
if (_rel) delete _rel;
}
void TTracciato_record::add(const TTracciato_campo& tc, int pos) void TTracciato_record::add(const TTracciato_campo& tc, int pos)
{ {
_tracciati_campo.add(tc,pos); _tracciati_campo.add(tc,pos);
@ -123,11 +129,24 @@ void TRecord_text::add(const TString& c, int pos)
_array.add(c, pos); _array.add(c, pos);
} }
//////////////////////////////////////// TFile_text //////////////////////////////////////// //////////////////////////////////////// TFile_text ////////////////////////////////////////
TTracciato_record& TFile_text::t_rec(const char* type) TTracciato_record* TFile_text::t_rec(const char* type)
{ {
return (TTracciato_record&)_tracciati_record[type]; return (TTracciato_record*)_tracciati_record.objptr(type);
} }
TTracciato_record* TFile_text::t_rec(int mainfile)
{
TTracciato_record *trrd;
_tracciati_record.restart();
while (trrd=(TTracciato_record *)_tracciati_record.get())
{
if (trrd->relation() && trrd->relation()->lfile().num()==mainfile)
break;
}
return trrd;
}
void TFile_text::set_gen_parm(TConfig& config, const TString& section) void TFile_text::set_gen_parm(TConfig& config, const TString& section)
{ {
_decsep = config.get_char("DECSEP",section); _decsep = config.get_char("DECSEP",section);
@ -166,8 +185,9 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
TString sectkey = section; TString sectkey = section;
sectkey.ltrim(6);//elimino la parola 'RECORD' o 'HEADER' o 'FOOTER' e gli spazi vuoti sectkey.ltrim(6);//elimino la parola 'RECORD' o 'HEADER' o 'FOOTER' e gli spazi vuoti
sectkey.trim();//per avere solo il nome del tipo del record sectkey.trim();//per avere solo il nome del tipo del record
TTracciato_record tr(sectkey);//istanzio un tracciato_record del tipo corrente TTracciato_record *tr=new TTracciato_record(sectkey);//istanzio un tracciato_record del tipo corrente
//setto tutti i dati relatvi ai tipi predefini nei tracciati campo per i diversi campi del record //setto tutti i dati relatvi ai tipi predefini nei tracciati campo per i diversi campi del record
TRelation *tmprel=NULL; // relazione associata al tracciato record
config.set_paragraph(section); config.set_paragraph(section);
TString lavoro; TString lavoro;
TString_array variables; TString_array variables;
@ -175,7 +195,7 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
TBit_array indici(numvar); TBit_array indici(numvar);
indici.reset(); indici.reset();
for (int j = 0; j < numvar; j++)//scandisco tutte le variabili della sezione for (int j = 0; j < numvar; j++)//scandisco tutte le variabili della sezione
{ {
const TString key = variables.row(j).get(0);//estraggo nome const TString key = variables.row(j).get(0);//estraggo nome
const TString& obj = variables.row(j).get(1);//estraggo valore const TString& obj = variables.row(j).get(1);//estraggo valore
lavoro = key.left(3); lavoro = key.left(3);
@ -189,12 +209,25 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
if (!tipo.empty()) if (!tipo.empty())
{ {
TTracciato_campo& tc = (TTracciato_campo&)_tipi[tipo]; TTracciato_campo& tc = (TTracciato_campo&)_tipi[tipo];
tr.add(tc, n); tr->add(tc, n);
} }
} }
indici.set(n); indici.set(n);
} }
TTracciato_campo& tc = tr.get(n);//prendo il tracciato campo con indice <n> if (lavoro == "USE") // setta la relazione
{
CHECKS(tmprel==NULL,"Relazione già definita per il tracciato: %s",sectkey);
if (atoi((const char *)obj)!=0)
tmprel= new TRelation(atoi((const char *)obj));
else
tmprel= new TRelation((const char *)obj);
}
if (lavoro == "JOI") // setta i join
{
NFCHECK("Join non ancora supportati");
continue;
}
TTracciato_campo& tc = tr->get(n);//prendo il tracciato campo con indice <n>
if (lavoro == "NAM") if (lavoro == "NAM")
{ {
tc.set_name(obj); tc.set_name(obj);
@ -266,6 +299,7 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
continue; continue;
} }
} }
tr->set_relation(tmprel);
//aggiungo il tracciato record all'assoc_array dei tracciati record //aggiungo il tracciato record all'assoc_array dei tracciati record
_tracciati_record.add(sectkey, tr); _tracciati_record.add(sectkey, tr);
} }
@ -351,7 +385,7 @@ int TFile_text::read(TRecord_text& rec)
buffer.separator(_fieldsep); buffer.separator(_fieldsep);
const char* tipo = _typefield >= 0 ? buffer.get(_typefield) : ""; const char* tipo = _typefield >= 0 ? buffer.get(_typefield) : "";
TTracciato_record& tr = t_rec(tipo); TTracciato_record& tr = *t_rec(tipo);
rec.set_type(tipo);//istanzio il tipo del record text rec.set_type(tipo);//istanzio il tipo del record text
TArray& a_tc = tr.tracciati_campo(); TArray& a_tc = tr.tracciati_campo();
@ -369,7 +403,7 @@ int TFile_text::read(TRecord_text& rec)
TString tipo = buffer.mid(_typepos, _typelen); TString tipo = buffer.mid(_typepos, _typelen);
tipo.trim(); tipo.trim();
rec.set_type(tipo);//istanzio il tipo del record text rec.set_type(tipo);//istanzio il tipo del record text
TTracciato_record& tr = t_rec(tipo); TTracciato_record& tr = *t_rec(tipo);
//ora che ho il tracciato record devo scandire i tracciati campo e caricare il record text //ora che ho il tracciato record devo scandire i tracciati campo e caricare il record text
TArray& a_tc = tr.tracciati_campo(); TArray& a_tc = tr.tracciati_campo();
int items = a_tc.items(); int items = a_tc.items();
@ -382,7 +416,8 @@ int TFile_text::read(TRecord_text& rec)
rec.add(lavoro, i); rec.add(lavoro, i);
} }
} }
return 0; return 0;
} }
//Scrive su file il record_text (valido anche per header e footer) //Scrive su file il record_text (valido anche per header e footer)
@ -391,22 +426,24 @@ int TFile_text::write(TRecord_text& rec)
TString buffer; TString buffer;
TString campo; TString campo;
const TString& type = rec.type(); const TString& type = rec.type();
TTracciato_record& tr = t_rec(type); TTracciato_record& tr = *t_rec(type);
TArray& a_tc = tr.tracciati_campo(); TArray& a_tc = tr.tracciati_campo();
int items = rec.items(); int items = rec.items();
if (_fixedlen) if (_fixedlen) // campi a lunghezza fissa
{ {
for (int i = 0; i < items; i++) for (int i = 0; i < items; i++)
{ {
TTracciato_campo& tc = tr.get(i); TTracciato_campo& tc = tr.get(i);
campo = rec.row(i); campo = rec.row(i);
campo = format_textfield(tc, campo); campo = format_textfield(tc, campo);
//buffer.insert(campo, tc.position()); buffer.insert(campo, tc.position());
buffer << campo; //buffer << campo;
campo.cut(0); campo.cut(0);
} }
CHECK(_write_file, "Impossibile scrivere su un file chiuso."); CHECK(_write_file, "Impossibile scrivere su un file chiuso.");
*_write_file << buffer; *_write_file << buffer;
if (_recordsize<=0) // Record a lunghezza var
*_write_file << _recordsep;
if (!ok_w()) return 1; if (!ok_w()) return 1;
buffer.cut(0); buffer.cut(0);
} }
@ -430,14 +467,33 @@ int TFile_text::write(TRecord_text& rec)
return 0; return 0;
} }
//Carica tutti i dati nel tracciato record (valido anche per header e footer) nel record_text
void TFile_text::autoload(TRecord_text& rec, int mainfile)
{
TTracciato_record* tr = t_rec(mainfile);
if (tr)
{
// esiste il tracciato e posso fare l'autoload
TCursor cur(tr->relation());
rec.set_type(tr->type());
_autoload(rec,cur,*tr);
}
}
//Carica tutti i dati nel tracciato record (valido anche per header e footer) nel record_text //Carica tutti i dati nel tracciato record (valido anche per header e footer) nel record_text
void TFile_text::autoload(TRecord_text& rec, TCursor& cur , const TString* tipo) void TFile_text::autoload(TRecord_text& rec, TCursor& cur , const TString* tipo)
{
const TString& type = rec.type();
if (tipo == NULL) tipo = &type;
TTracciato_record& tr = *t_rec(*tipo);
_autoload(rec,cur,tr);
}
//Carica tutti i dati nel tracciato record (valido anche per header e footer) nel record_text
void TFile_text::_autoload(TRecord_text& rec, TCursor& cur , TTracciato_record& tr )
{ {
TString campo; TString campo;
TRelation& rel = *cur.relation(); TRelation& rel = *cur.relation();
const TString& type = rec.type();
if (tipo == NULL) tipo = &type;
TTracciato_record& tr = t_rec(*tipo);
TArray& a_tc = tr.tracciati_campo(); TArray& a_tc = tr.tracciati_campo();
int items = a_tc.items(); int items = a_tc.items();
for (int i = 0; i < items; i++) for (int i = 0; i < items; i++)
@ -452,19 +508,33 @@ void TFile_text::autoload(TRecord_text& rec, TCursor& cur , const TString* tipo)
TToken_string msg (message, ','); TToken_string msg (message, ',');
if (!msg.blank()) if (!msg.blank())
validate(cur, rec, msg, campo); validate(cur, rec, msg, campo);
} }
rec.add(campo, i); rec.add(campo, i);
campo.cut(0); campo.cut(0);
} }
} }
int TFile_text::autosave(int mainfile, const TRecord_text& rec)
{
const TString& type = rec.type();//prendo il tracciato record del tipo del record_text
TTracciato_record* tr = t_rec(type);
if (tr)
if (tr->relation()->lfile().num()==mainfile)
return _autosave(*(tr->relation()),rec, *tr);
return NOERR; // l'assenza del tracciato non significa un errore
}
//Carico la relazione con i dati del record text
int TFile_text::autosave(TRelation& rel, const TRecord_text& rec) int TFile_text::autosave(TRelation& rel, const TRecord_text& rec)
{ {
const TString& type = rec.type();//prendo il tracciato record del tipo del record_text const TString& type = rec.type();//prendo il tracciato record del tipo del record_text
TTracciato_record& tr = t_rec(type); TTracciato_record& tr = *t_rec(type);
return _autosave(rel,rec, tr);
}
//Carico la relazione con i dati del record text
int TFile_text::_autosave(TRelation& rel, const TRecord_text& rec, TTracciato_record& tr )
{
TArray& a_tc = tr.tracciati_campo(); TArray& a_tc = tr.tracciati_campo();
int items = a_tc.items(); int items = a_tc.items();
TString valore; TString valore;
@ -529,7 +599,7 @@ const TString& TFile_text::get_field(const TRecord_text& rec, int ncampo)
//Scarica dal record_text il campo <name> //Scarica dal record_text il campo <name>
const TString& TFile_text::get_field(const TRecord_text& rec, const char* name) const TString& TFile_text::get_field(const TRecord_text& rec, const char* name)
{ {
TTracciato_record& tr = t_rec(rec.type()); TTracciato_record& tr = *t_rec(rec.type());
int ncampo = tr.get_pos(name); int ncampo = tr.get_pos(name);
CHECKS(ncampo >= 0, "Campo inesistente ", name); CHECKS(ncampo >= 0, "Campo inesistente ", name);
return rec.row(ncampo); return rec.row(ncampo);
@ -538,7 +608,7 @@ const TString& TFile_text::get_field(const TRecord_text& rec, const char* name)
//Carica nel record_text il campo alla posizione <ncampo> con il valore <val> già formattato //Carica nel record_text il campo alla posizione <ncampo> con il valore <val> già formattato
void TFile_text::add_field(TRecord_text& rec, const int ncampo, const char* val) void TFile_text::add_field(TRecord_text& rec, const int ncampo, const char* val)
{ {
TTracciato_record& tr = t_rec(rec.type()); TTracciato_record& tr = *t_rec(rec.type());
TTracciato_campo& tc = tr.get(ncampo); TTracciato_campo& tc = tr.get(ncampo);
TString valore = val; TString valore = val;
//valore =format_textfield(tc, valore); //valore =format_textfield(tc, valore);
@ -592,6 +662,7 @@ TString& TFile_text::format_textfield(const TTracciato_campo& tc, TString& campo
{ {
//int pos = tc.position(); //int pos = tc.position();
int length = tc.length(); int length = tc.length();
char fillch=tc.filler();
if (!tc.picture().blank()) if (!tc.picture().blank())
{ TString tmp; { TString tmp;
tmp.picture(tc.picture(), campo); tmp.picture(tc.picture(), campo);
@ -599,10 +670,12 @@ TString& TFile_text::format_textfield(const TTracciato_campo& tc, TString& campo
} }
if (length > campo.len()) if (length > campo.len())
{ {
if (fillch == '\0' && _fixedlen)
fillch=' ';
if (tc.align() == 'R') if (tc.align() == 'R')
campo.right_just(length, tc.filler()); campo.right_just(length,fillch);
else else
campo.left_just(length, tc.filler()); campo.left_just(length, fillch);
} }
else else
if (length > 0) if (length > 0)

View File

@ -80,16 +80,22 @@ public:
/////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////
class TTracciato_record : public TObject class TTracciato_record : public TObject
{ {
// @cmember Relazione associata al tracciato
TRelation * _rel; //
TString _type;//tipo del record TString _type;//tipo del record
TArray _tracciati_campo;//tracciati dei vari campi TArray _tracciati_campo;//tracciati dei vari campi
public: public:
TTracciato_record(const TString& tipo) : _type(tipo) {} TTracciato_record(const TString& tipo) : _type(tipo) ,_rel(NULL){}
TTracciato_record(const TTracciato_record& tr); TTracciato_record(const TTracciato_record& tr);
virtual ~TTracciato_record() {} virtual ~TTracciato_record();
virtual TObject* dup() const; virtual TObject* dup() const;
TArray& tracciati_campo() { return _tracciati_campo;}//ritorna un riferimento all'array dei tracciati campo TArray& tracciati_campo() { return _tracciati_campo;}//ritorna un riferimento all'array dei tracciati campo
const TString& type() const {return _type;} const TString& type() const {return _type;}
void set_type(const TString& type) {_type = type;} void set_type(const TString& type) {_type = type;}
// @cmember Restituisce la relazione associata al tracciato
TRelation * relation() const {return _rel;}
// @cmember Setta la relazione associata al tracciato
void set_relation(TRelation * rel) {_rel = rel;}
void add(const TTracciato_campo& tc, int pos = -1);//aggiunge tracciato campo all'array void add(const TTracciato_campo& tc, int pos = -1);//aggiunge tracciato campo all'array
void add(TTracciato_campo* tc, int pos = -1);//aggiunge tracciato campo all'array void add(TTracciato_campo* tc, int pos = -1);//aggiunge tracciato campo all'array
TTracciato_campo& get(int n);//ritorna il tracciato campo n dell'array (se non c'e' lo crea) TTracciato_campo& get(int n);//ritorna il tracciato campo n dell'array (se non c'e' lo crea)
@ -135,9 +141,9 @@ class TFile_text : public TObject
TAssoc_array _tracciati_record;//tracciati record per i vari tipi di record TAssoc_array _tracciati_record;//tracciati record per i vari tipi di record
char _decsep;//separatore decimale char _decsep;//separatore decimale
int _recordsize;//dimensione dei record int _recordsize;//dimensione dei record
char _fieldsep;//separatore di campo (se a lunghezza variabile) TString _recordsep;//separatore di record a lunghezza variabile (blank() se lung.fissa)
TString _recordsep;//separatore di record (se a lunghezza variabile) char _fieldsep; //separatore di campo (se a lunghezza variabile)
bool _fixedlen;//booleano TRUE lunghezza fissa FALSE lunghezza variabile bool _fixedlen; //indicatore di lunghezza fissa dei campi
int _typepos;//posizione ove trovare la chiave nel record a lunghezza fissa int _typepos;//posizione ove trovare la chiave nel record a lunghezza fissa
int _typelen;//lunghezza della chiave del record a lunghezza fissa int _typelen;//lunghezza della chiave del record a lunghezza fissa
int _typefield;//posizione ove trovare la chiave nel record a lunghezza variabile int _typefield;//posizione ove trovare la chiave nel record a lunghezza variabile
@ -182,19 +188,29 @@ public:
const TRecord_text& curr() const {return *_current;}//ritorna il record corrente const TRecord_text& curr() const {return *_current;}//ritorna il record corrente
void set_curr(TRecord_text& rec) {_current = &rec;}//setta il record corrente a rec void set_curr(TRecord_text& rec) {_current = &rec;}//setta il record corrente a rec
void set_curr(TRecord_text* rec) {_current = rec;}//setta il record corrente a rec void set_curr(TRecord_text* rec) {_current = rec;}//setta il record corrente a rec
TTracciato_record& t_rec(const char* type);//ritorna il tracciato record del tipo passato // @cmember ritorna il tracciato record del tipo passato
TTracciato_record* t_rec(const char* type);
// @cmember ritorna il tracciato record relativo alla relazione del file passato
// NB: si assume che ogni tracciato sia relativo ad una relazione diversa
TTracciato_record* t_rec(int mainfile);
const int items_tr() const {return _tracciati_record.items();}//ritorna il numero di tracciati record nel file const int items_tr() const {return _tracciati_record.items();}//ritorna il numero di tracciati record nel file
TAssoc_array& tracciati() {return _tracciati_record;}//ritorna un riferimento all'assoc_array dei tracciati record TAssoc_array& tracciati() {return _tracciati_record;}//ritorna un riferimento all'assoc_array dei tracciati record
//caricamento automatico del record_text dalla relazione // @cmember caricamento automatico del record_text dalla relazione
void autoload(TRecord_text& rec, TCursor& cur, const TString* tipo = NULL); void autoload(TRecord_text& rec, TCursor& cur, const TString* tipo = NULL);
//caricamento automatico del record_text corrente dalla relazione l // @cmember caricamento automatico del record_text corrente dalla relazione l
void autoload(TCursor& cur, const TString* tipo = NULL) {autoload(*_current, cur, tipo); }; void autoload(TCursor& cur, const TString* tipo = NULL) {autoload(*_current, cur, tipo); };
// @cmember caricamento automatico del record_text corrente dalla relazione di file principale mainfile definita sul tracciato
void autoload(TRecord_text& rec, int mainfile);
void _autoload(TRecord_text& rec, TCursor& cur , TTracciato_record& tr );
int write(TRecord_text & rec);//scrive su file di testo il record int write(TRecord_text & rec);//scrive su file di testo il record
int write(){return write(*_current);}//scrive su file di testo il record_text corrente int write(){return write(*_current);}//scrive su file di testo il record_text corrente
//caricamento automatico della relazione dal record_text //caricamento automatico della relazione dal record_text
int autosave(TRelation& rel, const TRecord_text& rec); int autosave(TRelation& rel, const TRecord_text& rec);
//caricamento automatico della relazione dal record_text corrente //caricamento automatico della relazione dal record_text corrente
int autosave(TRelation& rel) {return autosave(rel, *_current); }; int autosave(TRelation& rel) {return autosave(rel, *_current); };
//caricamento automatico della relazione definita nel tracciato dal record_text
int autosave(int mainfile, const TRecord_text& rec);
int _autosave(TRelation& rel, const TRecord_text& rec, TTracciato_record& tr );
int read(TRecord_text & rec);//legge da file di testo il record_text int read(TRecord_text & rec);//legge da file di testo il record_text
int read(){return read(*_current);}//legge da file di testo il record_text corrente int read(){return read(*_current);}//legge da file di testo il record_text corrente
//carica nel record_text il campo alla posizione <ncampo> con il valore <val> già formattato //carica nel record_text il campo alla posizione <ncampo> con il valore <val> già formattato