From d5cc1b62e26bd5909ae897c1d087c565e9966105 Mon Sep 17 00:00:00 2001 From: augusto Date: Wed, 14 Jan 1998 17:49:01 +0000 Subject: [PATCH] Modifiche per geenrare l'oggetto absaldo per derivazione git-svn-id: svn://10.65.10.50/trunk@5939 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- ab/ablib01.cpp | 402 ++++++++++++++++++++++++++++--------------------- ab/ablib01.h | 161 +++++++++++++++----- 2 files changed, 356 insertions(+), 207 deletions(-) diff --git a/ab/ablib01.cpp b/ab/ablib01.cpp index e2fedf5cd..3ab6f50f9 100755 --- a/ab/ablib01.cpp +++ b/ab/ablib01.cpp @@ -9,21 +9,111 @@ /**************************************************************************************************/ // TAnalisi_bil /**************************************************************************************************/ + +TAlbero_AB::TAlbero_AB(int filenum) + :TRectype(filenum) +{ +} + +int TAlbero_AB::write(TBaseisamfile &analisi) const +{ + int err = TRectype::write(analisi); + if (err==NOERR) + { + commit_body(); + } + if (err) + CHECK (FALSE,"Errore di scrittura del record sull'isamfile"); + return err; +} + +int TAlbero_AB::rewrite(TBaseisamfile &analisi) const +{ + int err = TRectype::rewrite(analisi); + if (err==NOERR) + { + commit_body(); + } + if (err) + CHECK (FALSE,"Errore di scrittura del record sull'isamfile"); + return err; +} + +//Leggo la "testata" del record +int TAlbero_AB::read(TBaseisamfile& analisi, word isop, word lockop) +{ + int err=TRectype::read(analisi, isop, lockop); + if (err==NOERR) + read_body(FALSE); + return err; +} + +//Leggo la testata del record basandomi sulla posizione +int TAlbero_AB::readat(TBaseisamfile& analisi, TRecnotype nrec, word lockop) +{ + int err=TRectype::readat(analisi, nrec, lockop); + if (err==NOERR) + read_body(FALSE); + return err; +} + + +int TAlbero_AB::remove(TBaseisamfile& f) const +{ +/*Abilitare questa parte solo per effettuare un debug della delete_node +// anche se messa in questa posizione, la chiamata non ha senso + TLocalisamfile lf(LF_RELANA); + TNumeric_id id; + id = 17; + _inter_tree->delete_node(id); + int errc = commit_body(lf); + if (errc != NOERR) + { + message_box("Errore nell'aggiornameno del file dati"); + //return errc; + } + return 0; +*/ + + +//*Abilitare solo questa parte per il test della remove_tree + _inter_tree->delete_tree(); + int errc = commit_body(); + if (errc != NOERR) + { + message_box("Errore nell'aggiornameno del file dati"); + //return errc; + } + int err = TRectype::remove(f); + return err; +} + +void TAlbero_AB::zero() +{ + _inter_tree->zero(); + TRectype::zero() ; +} + + +/**************************************************************************************************/ +// TAnalisi_bil +/**************************************************************************************************/ + + TAnalisi_bil::TAnalisi_bil() - :TRectype(LF_ANALISI) + :TAlbero_AB(LF_ANALISI) { _voci = new TLocalisamfile(LF_VOCI); _analisi= new TLocalisamfile(LF_ANALISI); _relaz = NULL; _ana = NULL; - _inter_tree = new TInsert_albero(); + _inter_tree = new TLocal_relana3(); _newrec = new TRectype(LF_RELANA); } TAnalisi_bil::~TAnalisi_bil() { - delete _inter_tree ; delete _voci; delete _ana; delete _relaz; @@ -31,81 +121,32 @@ TAnalisi_bil::~TAnalisi_bil() delete _newrec; } -//Estraggo un nodo: in ingresso ho un id e il codice della tabella; -//in output ho il record e le informazioni per sapere cosa fare di quel record -TRectype TInsert_albero::extract_node(const TString &codtab,TNumeric_id &id, TString &status) -{ - TToken_string key = codtab; - TRectype rec(LF_RELANA); - THash_object *row_status; - - if (id == ID_NULLO) - { //Gestione interna - _status_node.restart(); - row_status = _status_node.get_hashobj(); - status = (TString&)row_status->obj(); - id = (TNumeric_id)row_status->key(); - } - else - { - status = *(TString*)_status_node.objptr(id.string()); - } - - //Posso accedere alla cache (con la get) solo se il nodo non - //è stato rimosso: se il nodo è stato rimosso, non sarà presente - //nella cache, e quindi la get di un nodo che non esiste è un record - //vuoto; questo record vuoto causerà errori nel momento in cui chiamerò - //la flush per il distruttore; devo quindi evitare questo - //caso l'utilizzo della get - if (status != NODO_RIMOSSO) - { - key.add(id.string()); //La chiave è completamente ricostruita per la ricerca sulla cache - rec = _ana_cache->get(key); //passo la chiave (formata da codtab e id) e ritorna il rectype - } - else - { //Riempio manualmente il record che deve essere rimosso: inserisco solo la chiave - rec.put(ABRA_CODAN,codtab); - rec.put(ABRA_ID,id.string()); - } - //A questo punto il record è completo e so già quale operazione devo compierci sopra - - //Questa parte serve per gestire l'assoc_array degli status - if ((rec.empty()) && (status != NODO_RIMOSSO)) - { //Chiave non trovata: la chiave ricercata non è presente nella cache - fatal_box("Errore nella lettura della cache o nella costruzione del record."); - } - _status_node.remove(id.string()); - return rec; //Ritorno un Trectype e passo la stauts node +void TAnalisi_bil::put_headkey(TRectype &rec) const +{ + rec.put(ABAN_CODAN, get(ABAN_CODAN)); } - -int TAnalisi_bil::write(TBaseisamfile &analisi) const -{ - TLocalisamfile relana(LF_RELANA); - int err = commit_body(relana); - if (err) - CHECK (FALSE,"Errore di scrittura del record sull'isamfile"); - return err; -} - //Scrive tutto il contenuto della cache sull'isamfile, aggiungendo, modificando //o rimuovendo i nodi necessari -int TAnalisi_bil::commit_body(TLocalisamfile &relana) const + +int TAlbero_AB::commit_body() const { - TRectype rec(LF_RELANA); + TRectype rec(_inter_tree->current().num()); + TLocalisamfile filebody(rec.num()); TString status; //Estraggo un nodo per volta basandomi sull'assoc_array degli status - while (_inter_tree->status_node_items() > 0) + while (_inter_tree->dirty_nodes() > 0) { TNumeric_id id; - int prova = _inter_tree->status_node_items(); - rec= _inter_tree->extract_node(get(ABAN_CODAN), id, status); - + int prova = _inter_tree->dirty_nodes(); + id=ID_NULLO; + rec= _inter_tree->extract_dirtynode(id, status); + put_headkey(rec); //Ho un rectype e uno status node if (status == NODO_AGGIUNTO) { - if (relana.curr().empty()) + if (filebody.curr().empty()) { //Se il cursor di relana è posizionato in modo errato: //lo sistemo sull'ultimo record del file //DOMANDA: - Perchè ??? @@ -116,22 +157,22 @@ int TAnalisi_bil::commit_body(TLocalisamfile &relana) const // In tutti gli altri casi (quando l'ultima azione è stata una write o una rewrite o una remove di un record // che non sia l'ultimo) questo problema non esiste. //RISPOSTA ESATTA: - Bho !!! - relana.last(); + filebody.last(); } - int err = relana.write(rec); + int err = filebody.write(rec); if (err != NOERR) return err; } if (status == NODO_MODIFICATO) { - int err = relana.rewrite(rec); + int err = filebody.rewrite(rec); if (err != NOERR) return err; } if (status == NODO_RIMOSSO) { - relana.read(rec); //Devo leggere sul file per posizionare il cursore: stesso motivo di prima - int err = relana.remove(rec); + filebody.read(rec); //Devo leggere sul file per posizionare il cursore: stesso motivo di prima + int err = filebody.remove(rec); if (err != NOERR) return err; } @@ -140,24 +181,6 @@ int TAnalisi_bil::commit_body(TLocalisamfile &relana) const return NOERR; } -//Leggo la "testata" del record -int TAnalisi_bil::read(TBaseisamfile& analisi, word isop, word lockop) -{ - int err=TRectype::read(analisi, isop, lockop); - if (err==NOERR) - read_body(FALSE); - return err; -} - -//Leggo la testata del record basandomi sulla posizione -int TAnalisi_bil::readat(TBaseisamfile& analisi, TRecnotype nrec, word lockop) -{ - int err=TRectype::readat(analisi, nrec, lockop); - if (err==NOERR) - read_body(FALSE); - return err; -} - //Leggo il "corpo" del record int TAnalisi_bil::read_body(bool lock_struct ) { @@ -189,44 +212,6 @@ int TAnalisi_bil::read_body(bool lock_struct ) } return 0; } - -int TAnalisi_bil::remove(TBaseisamfile& f) const -{ -/*Abilitare questa parte solo per effettuare un debug della delete_node -// anche se messa in questa posizione, la chiamata non ha senso - TLocalisamfile lf(LF_RELANA); - TNumeric_id id; - id = 17; - _inter_tree->delete_node(id); - int errc = commit_body(lf); - if (errc != NOERR) - { - message_box("Errore nell'aggiornameno del file dati"); - //return errc; - } - return 0; -*/ - - -//*Abilitare solo questa parte per il test della remove_tree - TLocalisamfile lf(LF_RELANA); - _inter_tree->delete_tree(); - int errc = commit_body(lf); - if (errc != NOERR) - { - message_box("Errore nell'aggiornameno del file dati"); - //return errc; - } - int err = TRectype::remove(f); - return err; -} - -void TAnalisi_bil::zero() -{ - _inter_tree->zero(); - TRectype::zero() ; -} - //Naviga l'albero delle relazioni void TAnalisi_bil::naviga_relazioni(const TNumeric_id & begin_relana, const TNumeric_id & id_prec,const TNumeric_id & id_padre) { @@ -360,30 +345,99 @@ bool TAnalisi_bil::TArray_fratelli::used(TObject *o) } /**************************************************************************************************/ -// TInsert_albero +// TAlbero_locale /**************************************************************************************************/ -TInsert_albero::TInsert_albero() +TLocal_relana3::TLocal_relana3() : + TAlbero_locale(LF_RELANA) +{ +} + +TLocal_relana3::~TLocal_relana3() +{} + +TLocal_balance3::TLocal_balance3() : + TAlbero_locale(LF_MOVDETT) +{ +} + +TLocal_balance3::~TLocal_balance3() +{} + + +TAlbero_locale::TAlbero_locale(int filenum) { // versione definitiva: -// _currnode = new TRectype(LF_RELANA); -// _ana_cache = new TRWrecord_cache(new TIsamtempfile(LF_RELANA,"",TRUE,TRUE)); +// _currnode = new TRectype(filenum); +// _local_cahe = new TRWrecord_cache(new TIsamtempfile(filenum,"",TRUE,TRUE)); // debug mods: - _currnode = new TRectype(LF_RELANA); - _f= new TIsamtempfile(LF_RELANA,"/com/relana",FALSE,FALSE); - _ana_cache = new TRWrecord_cache(_f); + _currnode = new TRectype(filenum); + if (filenum==LF_RELANA) + _f= new TIsamtempfile(filenum,"/com/relana",FALSE,FALSE); + else + _f= new TIsamtempfile(filenum,"",FALSE,FALSE); + _local_cahe = new TRWrecord_cache(_f); //zero(); // resetta l'albero locale } -TInsert_albero::~TInsert_albero() +TAlbero_locale::~TAlbero_locale() { - delete _ana_cache; + delete _local_cahe; delete _f; } + +//Estraggo un nodo: se specifico l'id in ingresso estrae il nodo con quell'id; +//altrimenti ne sceglie uno a caso tra quelli "dirty" +//in output ho il record e le informazioni per sapere cosa fare di quel record +TRectype TAlbero_locale::extract_dirtynode(TNumeric_id &id, TString &status) +{ + TToken_string key = get_headkey(); + TRectype rec(current()); + THash_object *row_status; + + if (id == ID_NULLO) + { //Gestione interna + _status_node.restart(); + row_status = _status_node.get_hashobj(); + status = (TString&)row_status->obj(); + id = (TNumeric_id)row_status->key(); + } + else + { + status = *(TString*)_status_node.objptr(id.string()); + } + + //Posso accedere alla cache (con la get) solo se il nodo non + //è stato rimosso: se il nodo è stato rimosso, non sarà presente + //nella cache, e quindi la get di un nodo che non esiste è un record + //vuoto; questo record vuoto causerà errori nel momento in cui chiamerò + //la flush per il distruttore; devo quindi evitare questo + //caso l'utilizzo della get + if (status != NODO_RIMOSSO) + { + key.add(id.string()); //La chiave è completamente ricostruita per la ricerca sulla cache + rec = _local_cahe->get(key); //passo la chiave (formata da codtab e id) e ritorna il rectype + } + else + { //Riempio manualmente il record che deve essere rimosso: inserisco solo la chiave + //rec.put(ABRA_CODAN, ??? ); + rec.put(ABRA_ID,id.string()); + } + //A questo punto il record è completo e so già quale operazione devo compierci sopra + + //Questa parte serve per gestire l'assoc_array degli status + if ((rec.empty()) && (status != NODO_RIMOSSO)) + { //Chiave non trovata: la chiave ricercata non è presente nella cache + fatal_box("Errore nella lettura della cache o nella costruzione del record."); + } + _status_node.remove(id.string()); + return rec; //Ritorno un Trectype e passo la stauts node +} + //Setta lo stato del nodo: cioè decide che cosa dovrò fare con questo nodo -void TInsert_albero::set_status_node(const TNumeric_id &id, const char *status) +void TAlbero_locale::set_status_node(const TNumeric_id &id, const char *status) { // STATUS A priorità assoluta e rimane sempre A // STATUS M priorità su R ma non su A @@ -424,7 +478,7 @@ void TInsert_albero::set_status_node(const TNumeric_id &id, const char *status) } //Restituisce un nuovo id -TNumeric_id &TInsert_albero::new_id(TNumeric_id id) +TNumeric_id &TAlbero_locale::new_id(TNumeric_id id) { if (id == ID_NULLO) _last_insert_id+1; @@ -435,12 +489,12 @@ TNumeric_id &TInsert_albero::new_id(TNumeric_id id) //Inserisce il nodo (che ho in ingresso) nella struttura ad albero doppiamente linkata //di relana aggiornando tutti i link -bool TInsert_albero::insert_node(TRectype & node,const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id) +bool TAlbero_locale::insert_node(TRectype & node,const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id) { TNumeric_id id_succ; TToken_string key; - key.add(node.get(ABRA_CODAN)); - TRectype parente(LF_RELANA); + key=get_headkey(); + TRectype parente(current()); if (id == ID_NULLO) id = new_id(id); else @@ -449,9 +503,9 @@ bool TInsert_albero::insert_node(TRectype & node,const TNumeric_id id_prec, cons if (id_prec != ID_NULLO) { //Aggiorno il successivo del mio precedente dicendogli che il suo successivo sono io key.add(id_prec.string()); - parente = _ana_cache->get(key); + parente = _local_cahe->get(key); parente.put(ABRA_IDSUCC,id.string()); - _ana_cache->put(parente); + _local_cahe->put(parente); set_status_node(id_prec,NODO_MODIFICATO); //Setto l'eventuale flag di array modificato per il fratello } else @@ -459,9 +513,9 @@ bool TInsert_albero::insert_node(TRectype & node,const TNumeric_id id_prec, cons if (id_padre != ID_NULLO) { //Sono un primo figlio: rintraccio mio padre e gli dico che il suo primo figlio ora, sono io key.add(id_padre.string()); - parente = _ana_cache->get(key); + parente = _local_cahe->get(key); parente.put(ABRA_IDFIGLIO,id.string()); - _ana_cache->put(parente); + _local_cahe->put(parente); set_status_node(id_padre,NODO_MODIFICATO); //Setto l'eventuale flag di array modificato per il padre } // Sono una radice principale e quindi sono orfana di padre } @@ -471,7 +525,7 @@ bool TInsert_albero::insert_node(TRectype & node,const TNumeric_id id_prec, cons node.put(ABRA_IDPADRE,id_padre.string()); node.put(ABRA_IDSUCC,id_succ.string()); node.put(ABRA_IDFIGLIO,ID_NULLO); - _ana_cache->put(node); + _local_cahe->put(node); //set_current(node); goto_node(node); set_status_node(id,NODO_MODIFICATO); @@ -480,14 +534,14 @@ bool TInsert_albero::insert_node(TRectype & node,const TNumeric_id id_prec, cons //Questa funzione aggiorna i link dei "parenti" di un nodo che sta per essere rimosso -bool TInsert_albero::delete_node(const TNumeric_id &id) +bool TAlbero_locale::delete_node(const TNumeric_id &id) { - TRectype parente(LF_RELANA); + TRectype parente(current()); TNumeric_id id_padre, id_figlio, id_prec, id_succ; goto_node(id); - TToken_string key = _currnode->get(ABRA_CODAN); + TToken_string key = get_headkey(); // id = _currnode->get_real(ABRA_ID); id_padre = _currnode->get_real(ABRA_IDPADRE); @@ -499,11 +553,11 @@ bool TInsert_albero::delete_node(const TNumeric_id &id) if (id_padre != ID_NULLO) { key.add(id_padre.string(),1); - parente=_ana_cache->get(key); //padre + parente=_local_cahe->get(key); //padre if (parente.get(ABRA_IDFIGLIO) == id.string()) { //Il nodo che sta per essere rimosso è il primo figlio di un padre parente.put(ABRA_IDFIGLIO,id_succ.string()); //Aggiorno il padre - _ana_cache->put(parente); + _local_cahe->put(parente); } } @@ -512,9 +566,9 @@ bool TInsert_albero::delete_node(const TNumeric_id &id) if (id_prec != ID_NULLO) { key.add(id_prec.string(),1); - parente=_ana_cache->get(key); //fratello sinistro + parente=_local_cahe->get(key); //fratello sinistro parente.put(ABRA_IDSUCC,id_succ.string()); //Assegno al mio fratello sinistro il mio fratello destro - _ana_cache->put(parente); + _local_cahe->put(parente); } //Dico a mio fratello successivo chi il suo precedente non sono più io, @@ -522,9 +576,9 @@ bool TInsert_albero::delete_node(const TNumeric_id &id) if (id_succ != ID_NULLO) { key.add(id_succ.string(),1); - parente=_ana_cache->get(key); //fratello destro + parente=_local_cahe->get(key); //fratello destro parente.put(ABRA_IDPREC,id_prec.string()); //Assegno al mio fratello destro il mio fratello sinistro - _ana_cache->put(parente); + _local_cahe->put(parente); } //I miei vicini mi hanno già escluso: non sono più raggiungibile @@ -534,7 +588,7 @@ bool TInsert_albero::delete_node(const TNumeric_id &id) //node.put(ABRA_IDPADRE,ID_NULLO); _currnode->put(ABRA_IDPREC,ID_NULLO); _currnode->put(ABRA_IDSUCC,ID_NULLO); - _ana_cache->put(*_currnode); + _local_cahe->put(*_currnode); //Elimino i miei figli TNumeric_id nextnode_id; @@ -566,23 +620,22 @@ bool TInsert_albero::delete_node(const TNumeric_id &id) return TRUE; } -void TInsert_albero::zero() +void TAlbero_locale::zero() { delete_tree(); // cancella l'albero _status_node.destroy(); _currnode->put(ABRA_ID,ID_NULLO); } -bool TInsert_albero::delete_tree() +bool TAlbero_locale::delete_tree() { goto_root(); remove_subtree(ID_NULLO); //Non eliminando il link coi fratelli della radice, remove_subtree naviga tutto l'albero return TRUE; } -//Questa funzione elimina tutti i nodi sottostanti al nodo -//"principale" che sta per essere eliminato -bool TInsert_albero::remove_subtree(const TNumeric_id thisnode_id) +//Questa funzione elimina il nodo corrente e tutti i nodi sottostanti +bool TAlbero_locale::remove_subtree(const TNumeric_id return_id) { TNumeric_id myself_id; //cerco il figlio @@ -623,47 +676,47 @@ bool TInsert_albero::remove_subtree(const TNumeric_id thisnode_id) //non è previsto uno status, non dovrebbe esistere nella cache CHECK (FALSE,"Errore nella consistenza della cache"); } - if (thisnode_id != ID_NULLO) - goto_node(thisnode_id); + if (return_id != ID_NULLO) + goto_node(return_id); else _currnode->put(ABRA_ID,ID_NULLO); return TRUE; } -bool TInsert_albero::has_son() +bool TAlbero_locale::has_son() { return (_currnode->get_real(ABRA_IDFIGLIO) != ID_NULLO); } -bool TInsert_albero::goto_firstson() +bool TAlbero_locale::goto_firstson() { goto_node(_currnode->get_real(ABRA_IDFIGLIO)); return TRUE; } -bool TInsert_albero::has_rbrother() +bool TAlbero_locale::has_rbrother() { return (_currnode->get_real(ABRA_IDSUCC) != ID_NULLO); } -bool TInsert_albero::goto_rbrother() +bool TAlbero_locale::goto_rbrother() { goto_node(_currnode->get_real(ABRA_IDSUCC)); return TRUE; } -bool TInsert_albero::goto_root() +bool TAlbero_locale::goto_root() { //Il _current sarà posizionato sull'ultimo nodo che è stato visitato - if (current()->get_real(ABRA_ID)==ID_NULLO) + if (current().get_real(id_fieldname())==ID_NULLO) return FALSE; TToken_string key; TNumeric_id id_prec, id_padre; - key.add(_currnode->get(ABRA_CODAN)); + key=get_headkey(); key.add(_currnode->get(ABRA_ID)); do { - *_currnode = _ana_cache->get(key); + *_currnode = _local_cahe->get(key); id_prec = _currnode->get_real(ABRA_IDPREC); id_padre = _currnode->get_real(ABRA_IDPADRE); if (id_prec != ID_NULLO) @@ -679,6 +732,15 @@ bool TInsert_albero::goto_root() return TRUE; } +void TAlbero_locale::goto_node(const TNumeric_id id) +{ + TToken_string key; + key=get_headkey(); + key.add(id.string()); + *_currnode = _local_cahe->get(key); +} + + /**************************************************************************************************/ // TAlbero_relana /**************************************************************************************************/ diff --git a/ab/ablib01.h b/ab/ablib01.h index 40e5a4af5..86db32503 100755 --- a/ab/ablib01.h +++ b/ab/ablib01.h @@ -29,6 +29,9 @@ #include "relana.h" #endif //_RELANA_H +#include "saldi.h" +#include "movdett.h" + #define TIPO_ANALISI "A" @@ -207,11 +210,10 @@ public: // @cmember Distruttore virtual ~TAlbero_relvoci() ; }; - // Struttura da albero basata su un file temporaneo cached -class TInsert_albero : public TAlbero_bidir +class TAlbero_locale : public TAlbero_bidir { - TRWrecord_cache * _ana_cache; + TRWrecord_cache * _local_cahe; TLocalisamfile *_f; // da rimuovere !! @@ -219,24 +221,25 @@ class TInsert_albero : public TAlbero_bidir TNumeric_id _last_insert_id; TAssoc_array _status_node; -// debug - void write_cache() { _ana_cache->flush(); } protected: +// debug + void write_cache() { _local_cahe->flush(); } + // @cmember Elimina il sottoalbero dei figli di un nodo // @cmember che sta per essere eliminato da un struttura di tipo lista doppiamente lincata bool remove_subtree(const TNumeric_id lastnode_id); // @cmember genera/setta il nuovo id TNumeric_id &new_id(TNumeric_id); - void goto_node(const TNumeric_id id) - { - TToken_string key; - key.add(_currnode->get(ABRA_CODAN)); - key.add(id.string()); - *_currnode = _ana_cache->get(key); - } + void goto_node(const TNumeric_id id); void goto_node(TRectype &node) {*_currnode = node;} + virtual const char * idfather_fieldname() pure ; + virtual const char * idson_fieldname() pure; + virtual const char * idsucc_fieldname() pure; + virtual const char * idprec_fieldname() pure; + virtual const char * id_fieldname() pure; + virtual const char * get_headkey(); public: // @cmember Inserisce un nodo in una struttura di tipo lista doppiamente lincata bool insert_node(TRectype &node, const TNumeric_id id_prec, const TNumeric_id id_padre, TNumeric_id id); @@ -247,7 +250,7 @@ protected: // @cmember Lancia la rimozione di tutto l'albero void zero(); // @cmember Restituisce il nodo corrente - TRectype * current() const {return (TRectype * )_currnode;} + TRectype & current() const {return *_currnode;} // @cmember Restituisce TRUE se esiste un figlio di un nodo virtual bool has_son(); @@ -264,21 +267,95 @@ protected: // ***** gestione interfaccia Database/copia locale // @cmember Estrae un nodo dall'albero - TRectype extract_node(const TString &codtab,TNumeric_id &id, TString& status); + TRectype extract_dirtynode(TNumeric_id &id, TString& status); // @cmember Ritorna il numero di elementi dell'assoc_array status_node - int status_node_items() { return _status_node.items();} + int dirty_nodes() { return _status_node.items();} // @cmember Setta lo stato del nodo: valori ammessi = nodo ggiunto, nodo odificato, nodo imosso void set_status_node(const TNumeric_id &id, const char *status); // @cmember Ritorna lo stato di un nodo const char* get_status_node(const TNumeric_id &id); + public: // @cmember Costruttore - TInsert_albero(); + TAlbero_locale(int filenum); // @cmember Distruttore - virtual ~TInsert_albero(); + virtual ~TAlbero_locale(); }; -class TAnalisi_bil: public TRectype +// Copia locale dell'albero di una tabella analisi +class TLocal_relana3 : public TAlbero_locale +{ +protected: + + virtual const char * idfather_fieldname() {return ABRA_IDPADRE;} + virtual const char * idson_fieldname(){return ABRA_IDFIGLIO;} + virtual const char * idsucc_fieldname(){return ABRA_IDSUCC;} + virtual const char * idprec_fieldname(){return ABRA_IDPREC;} + virtual const char * id_fieldname(){return ABRA_IDPADRE;} + virtual const char * get_headkey() {return " ";} + + public: + + // @cmember Costruttore + TLocal_relana3(); + // @cmember Distruttore + virtual ~TLocal_relana3(); +}; + +// Copia locale dell'albero dei dettagli di un saldo +class TLocal_balance3 : public TAlbero_locale +{ +protected: + + virtual const char * idfather_fieldname() {return ABMD_IDPADRE;} + virtual const char * idson_fieldname(){return ABMD_IDFIGLIO;} + virtual const char * idsucc_fieldname(){return ABMD_IDSUCC;} + virtual const char * idprec_fieldname(){return ABMD_IDPREC;} + virtual const char * id_fieldname(){return ABMD_IDPADRE;} + virtual const char * get_headkey() {return " | | | ";} + + public: + + // @cmember Costruttore + TLocal_balance3(); + // @cmember Distruttore + virtual ~TLocal_balance3(); +}; + +class TAlbero_AB: public TRectype +{ + protected: + TAlbero_locale *_inter_tree; + // @cmember Esegue la scrittura del body del record + virtual int commit_body() const; + // @cmember Esegue la lettura del body del rocord + virtual int read_body(bool lockstruct); + // @cmember Copia la chiave sul record dei nodi dell'albero + virtual void put_headkey(TRectype &rec) const; + public: + // @cmember Costruttore + TAlbero_AB(int filenum); + // #cmember Distruttore + virtual ~TAlbero_AB() ; + // @cmember Esegue la lettura della testata di un record da LF_ANALISI e del suo "body" + virtual int read(TBaseisamfile& analisi, word isop=_isequal, word lockop=_nolock); + // @cmember Esegue la lettura della testata di un record alla posizione nrec da LF_ANALISI e del suo "body" + virtual int readat(TBaseisamfile& f, TRecnotype nrec, word lockop = _nolock); + // @cmember Scrive una tabella di analisi + virtual int write(TBaseisamfile& analisi) const; + // @cmember Riscrive una tabella di analisi + virtual int rewrite(TBaseisamfile& analisi) const; + // @cmember Elimina una intera tabella di analisi con tutto il suo contenuto + virtual int remove(TBaseisamfile& f) const; + // @cmember Azzera l record + virtual void zero(); + TAlbero_locale * user_tree() + {return _inter_tree;} +}; + + + +class TAnalisi_bil: public TAlbero_AB { class TArray_fratelli: public TAssoc_array { @@ -293,7 +370,7 @@ class TAnalisi_bil: public TRectype TLocalisamfile *_voci; TAlbero_relvoci *_relaz; TAlbero_relana *_ana; - TInsert_albero *_inter_tree; + TLocal_relana3 *_inter_tree; TRectype * _newrec; //buffer per l'inserimento dodo per nodo protected: // @cmember Esegue una navigazione dell'albero di rel_voci e di rel_ana @@ -309,32 +386,42 @@ class TAnalisi_bil: public TRectype bool lock_tabella(); // @cmember Sblocca una tabella di analisi bool unlock_tabella(); + // @cmember Esegue la scrittura del body del record scrive il contenuto di una tabella di analisi + virtual int commit_body() const; + // @cmember Esegue la lettura del body del rocord: legge il contenuto di una tabella di analisi + virtual int read_body(bool lockstruct); + // @cmember Copia la chiave sul record dei nodi dell'albero + virtual void put_headkey(TRectype &rec) const; public: // @cmember Costruttore TAnalisi_bil(); // #cmember Distruttore virtual ~TAnalisi_bil() ; - // @cmember Ritrona il tipo di analisi + // @cmember Ritorna il tipo di analisi const TString &type() {return get(ABAN_TIPOAN);} // @cmember Setta il tipo di analisi void set_type(const char * tipo) {put(ABAN_TIPOAN,tipo);} - // @cmember Esegue la lettura della testata di un record da LF_ANALISI - virtual int read(TBaseisamfile& analisi, word isop=_isequal, word lockop=_nolock); - // @cmember Esegue la lettura della testata di un record alla posizione nrec da LF_ANALISI - virtual int readat(TBaseisamfile& f, TRecnotype nrec, word lockop = _nolock); - // @cmember Serve per lanciare la scrittura del body del record - virtual int write(TBaseisamfile& analisi) const; - // @cmember Elimina una intera tabella di analisi con tutto il suo contenuto - virtual int remove(TBaseisamfile& f) const; - // @cmember Azzera l record - virtual void zero(); - // @cmember Esegue la scrittura del body del record scrive il contenuto di una tabella di analisi - int commit_body(TLocalisamfile &relana) const; - // @cmember Esegue la lettura del body del rocord: legge il contenuto di una tabella di analisi - int read_body(bool lockstruct); - // @cmember Restituisce l'oggetto ad albero "copia locale" - TInsert_albero & user_tree() - {return *_inter_tree;} }; +class TABsaldo: public TRectype +{ + TLocalisamfile *_saldi; + TAlbero_relana *_movdett; + TLocal_balance3 *_inter_tree; + TRectype * _newrec; //buffer per l'inserimento dodo per nodo + protected: + // @cmember Esegue la scrittura del body del record scrive il contenuto di una tabella di analisi + virtual int commit_body() const; + // @cmember Esegue la lettura del body del rocord: legge il contenuto di una tabella di analisi + virtual int read_body(bool lockstruct); + // @cmember Copia la chiave sul record dei nodi dell'albero + virtual void put_headkey(TRectype &rec) const; + public: + // @cmember Costruttore + TABsaldo(); + // #cmember Distruttore + virtual ~ TABsaldo() ; +}; + + #endif //__ANALISI_H \ No newline at end of file