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)
{
set_relation(tr.relation());
set_type(tr.type());
_tracciati_campo = tr._tracciati_campo;
}
TTracciato_record::~TTracciato_record()
{
if (_rel) delete _rel;
}
void TTracciato_record::add(const TTracciato_campo& tc, int pos)
{
_tracciati_campo.add(tc,pos);
@ -123,11 +129,24 @@ void TRecord_text::add(const TString& c, int pos)
_array.add(c, pos);
}
//////////////////////////////////////// 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)
{
_decsep = config.get_char("DECSEP",section);
@ -166,8 +185,9 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
TString sectkey = section;
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
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
TRelation *tmprel=NULL; // relazione associata al tracciato record
config.set_paragraph(section);
TString lavoro;
TString_array variables;
@ -175,7 +195,7 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
TBit_array indici(numvar);
indici.reset();
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& obj = variables.row(j).get(1);//estraggo valore
lavoro = key.left(3);
@ -189,12 +209,25 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
if (!tipo.empty())
{
TTracciato_campo& tc = (TTracciato_campo&)_tipi[tipo];
tr.add(tc, n);
tr->add(tc, 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")
{
tc.set_name(obj);
@ -266,6 +299,7 @@ void TFile_text::set_rec_parm(TConfig& config, const char* section)
continue;
}
}
tr->set_relation(tmprel);
//aggiungo il tracciato record all'assoc_array dei tracciati record
_tracciati_record.add(sectkey, tr);
}
@ -351,7 +385,7 @@ int TFile_text::read(TRecord_text& rec)
buffer.separator(_fieldsep);
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
TArray& a_tc = tr.tracciati_campo();
@ -369,7 +403,7 @@ int TFile_text::read(TRecord_text& rec)
TString tipo = buffer.mid(_typepos, _typelen);
tipo.trim();
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
TArray& a_tc = tr.tracciati_campo();
int items = a_tc.items();
@ -382,7 +416,8 @@ int TFile_text::read(TRecord_text& rec)
rec.add(lavoro, i);
}
}
return 0;
return 0;
}
//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 campo;
const TString& type = rec.type();
TTracciato_record& tr = t_rec(type);
TTracciato_record& tr = *t_rec(type);
TArray& a_tc = tr.tracciati_campo();
int items = rec.items();
if (_fixedlen)
if (_fixedlen) // campi a lunghezza fissa
{
for (int i = 0; i < items; i++)
{
TTracciato_campo& tc = tr.get(i);
campo = rec.row(i);
campo = format_textfield(tc, campo);
//buffer.insert(campo, tc.position());
buffer << campo;
buffer.insert(campo, tc.position());
//buffer << campo;
campo.cut(0);
}
CHECK(_write_file, "Impossibile scrivere su un file chiuso.");
*_write_file << buffer;
if (_recordsize<=0) // Record a lunghezza var
*_write_file << _recordsep;
if (!ok_w()) return 1;
buffer.cut(0);
}
@ -430,14 +467,33 @@ int TFile_text::write(TRecord_text& rec)
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
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;
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();
int items = a_tc.items();
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, ',');
if (!msg.blank())
validate(cur, rec, msg, campo);
}
}
rec.add(campo, i);
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)
{
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();
int items = a_tc.items();
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>
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);
CHECKS(ncampo >= 0, "Campo inesistente ", name);
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
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);
TString valore = val;
//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 length = tc.length();
char fillch=tc.filler();
if (!tc.picture().blank())
{ TString tmp;
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 (fillch == '\0' && _fixedlen)
fillch=' ';
if (tc.align() == 'R')
campo.right_just(length, tc.filler());
campo.right_just(length,fillch);
else
campo.left_just(length, tc.filler());
campo.left_just(length, fillch);
}
else
if (length > 0)

View File

@ -80,16 +80,22 @@ public:
///////////////////////////////////////////////////////////////////////
class TTracciato_record : public TObject
{
// @cmember Relazione associata al tracciato
TRelation * _rel; //
TString _type;//tipo del record
TArray _tracciati_campo;//tracciati dei vari campi
public:
TTracciato_record(const TString& tipo) : _type(tipo) {}
TTracciato_record(const TString& tipo) : _type(tipo) ,_rel(NULL){}
TTracciato_record(const TTracciato_record& tr);
virtual ~TTracciato_record() {}
virtual ~TTracciato_record();
virtual TObject* dup() const;
TArray& tracciati_campo() { return _tracciati_campo;}//ritorna un riferimento all'array dei tracciati campo
const TString& type() const {return _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(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)
@ -135,9 +141,9 @@ class TFile_text : public TObject
TAssoc_array _tracciati_record;//tracciati record per i vari tipi di record
char _decsep;//separatore decimale
int _recordsize;//dimensione dei record
char _fieldsep;//separatore di campo (se a lunghezza variabile)
TString _recordsep;//separatore di record (se a lunghezza variabile)
bool _fixedlen;//booleano TRUE lunghezza fissa FALSE lunghezza variabile
TString _recordsep;//separatore di record a lunghezza variabile (blank() se lung.fissa)
char _fieldsep; //separatore di campo (se a lunghezza variabile)
bool _fixedlen; //indicatore di lunghezza fissa dei campi
int _typepos;//posizione ove trovare la chiave nel 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
@ -182,19 +188,29 @@ public:
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
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
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);
//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); };
// @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(){return write(*_current);}//scrive su file di testo il record_text corrente
//caricamento automatico della relazione dal record_text
int autosave(TRelation& rel, const TRecord_text& rec);
//caricamento automatico della relazione dal record_text corrente
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(){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