From d9776d32cbbc84045f669cc45aa3b6fe4abc877d Mon Sep 17 00:00:00 2001 From: sauro Date: Mon, 6 Oct 1997 12:31:55 +0000 Subject: [PATCH] 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 --- include/filetext.cpp | 119 ++++++++++++++++++++++++++++++++++--------- include/filetext.h | 32 +++++++++--- 2 files changed, 120 insertions(+), 31 deletions(-) diff --git a/include/filetext.cpp b/include/filetext.cpp index c6e94d5b3..de23e1bd8 100755 --- a/include/filetext.cpp +++ b/include/filetext.cpp @@ -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 + 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 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 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 con il valore 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) diff --git a/include/filetext.h b/include/filetext.h index 589f350ee..1b7a5851b 100755 --- a/include/filetext.h +++ b/include/filetext.h @@ -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 con il valore già formattato