diff --git a/include/relation.cpp b/include/relation.cpp index 230873ffb..44a123c31 100755 --- a/include/relation.cpp +++ b/include/relation.cpp @@ -14,7 +14,6 @@ #include <xvtility.h> #include <codeb.h> - // *** check if not already defined #define NOTFOUND (-1) @@ -77,6 +76,7 @@ public: int num() const { return _num; } int link() const { return _numto; } int alias() const { return _alias; } + bool allow_lock() const { return _allow_lock; } bool write_enable() const { return _write_enable; } void write_enable(bool we) { _write_enable = we; } TRectype& load_rec(TRectype& r, const TBaseisamfile& from) const; @@ -470,8 +470,8 @@ void TRelation::write_enable(const char* name, const bool on) bool TRelation::add( TLocalisamfile* f, // @parm Descrittore del file da aggiungere const char* relexprs, // @parm Espressione della relazione - int key, // @parm Chiave del file principale - int linkto, // @parm Posizione a cui aggiungere il file + int key, // @parm Chiave del file + int linkto, // @parm Posizione alla quale aggiungere il file int alias, // @parm Alias da dare al file da aggiungere bool allow_lock) // @parm Indica se fare il lock sul file oppure ignorarli // @parm int | logicnum | Numero logico del file da aggiungere @@ -524,11 +524,21 @@ bool TRelation::add(const char* tabname, const char* relexprs, int key, // @mfunc Sostituisce nella relazione un file void TRelation::replace( TLocalisamfile* f, // @parm Descrittore del file sostituto - int index) // @parm Posizione nel quale sostituire il file (default 0) + int index, // @parm Posizione nel quale sostituire il file (default 0) + const char* relexprs, // @parm Nuova Espressione della relazione + int key) // @parm Nuova Chiave del file + { const TLocalisamfile* p = (const TLocalisamfile*)_files.objptr(index); CHECK(p && p->num() == f->num(), "Can't replace a file with different logic number"); _files.add(f, index); + if (relexprs && *relexprs ) + { + TRelationdef* oldr=(TRelationdef*)_reldefs.objptr(index-1); + TRelationdef* r = new TRelationdef(this, index, key, oldr->link(), + relexprs, oldr->alias(), oldr->allow_lock()); + _reldefs.add(r,index-1); + } } TRectype& TRelationdef::load_rec(TRectype& r, const TBaseisamfile& from) const @@ -591,14 +601,20 @@ int TRelation::position_rels( // build record for (int j = 0 ; j < rd._fields.items(); j++) // for each field { - const char* expr = rd.evaluate_expr(j, to); + TString expr (rd.evaluate_expr(j, to)); TFieldref& s = (TFieldref&) rd._fields[j]; + if (from.is_sorted() && from.curr().type(s.name()) ==_alfafld) + expr.rpad(s.len(from.curr()),'~'); s.write(expr, furr); } // for each field + if (from.is_sorted()) + { + ((TSortedfile &)from).setregion(from.curr(),from.curr()); + from.first(); // read record: if not found, zero current record - - from.read(op, lck, atdate); + } else + from.read(op, lck, atdate); if (from.bad()) { bool eq = TRUE; @@ -2230,5 +2246,204 @@ TRelation_description::~TRelation_description() } +//////////////////////////////////// +// TSortedfile +//////////////////////////////////// +// @mfunc Avanza di <p npos> record +int TSortedfile::operator +=(const TRecnotype npos) +{ + *_curs+=npos; + setstatus(_curs->file().status()); + return _curs->test(); +} + // @mfunc Sposta indietro di <p npos> record +int TSortedfile::operator -=(const TRecnotype npos) +{ + *_curs-=npos; + setstatus(_curs->file().status()); + return _curs->test(); +} + // @mfunc Avanza al record successivo +int TSortedfile::operator ++() +{ + return *this+=1; +} + // @mfunc Indietreggia al record precedente +int TSortedfile::operator --() +{ + return *this-=1; +} + +// @mfunc Si posiziona sul primo record del file (vedi <t TReclock>) +int TSortedfile::first(word lockop ) +{ + _curs->first_item(); + setstatus(_curs->file().status()); + return _curs->items()>0; +} +// @mfunc Si posiziona sull'ultimo record del file (vedi <t TReclock>) +int TSortedfile::last(word lockop ) +{ + _curs->last_item(); + setstatus(_curs->file().status()); + return _curs->items()>0; +} +// @mfunc Si posiziona sul successivo record del file (vedi <t TReclock>) +int TSortedfile::next(word lockop ) +{ + _curs->succ_item(); + setstatus(_curs->file().status()); + return _curs->pos()<=_curs->items(); +} +// @mfunc Si posiziona sul precedente record del file (vedi <t TReclock>) +int TSortedfile::prev(word lockop ) +{ + _curs->pred_item(); + setstatus(_curs->file().status()); + return _curs->pos()>0; +} + +// @mfunc Salta <p nrec> record dalla posizione corrente (vedi <t TReclock>) +int TSortedfile::skip(TRecnotype nrec, word lockop ) +{ +// return *this+=nrec; manca il lock... + setstatus(_curs->file().status()); + error_box("Operazione 'skip' non consentita sul cursore"); + return 0; +} + +// @mfunc Rilegge l'ultimo record letto (vedi <t TReclock>) +int TSortedfile::reread(word lockop , TDate& atdate ) +{ + return reread(curr(),lockop,atdate); +} +// @mfunc Rilegge l'ultimo record letto e lo copia in <p rec> (vedi <t TReclock>) +int TSortedfile::reread(TRectype& rec, word lockop , TDate& atdate) +{ + return 0; +} + + +// @mfunc Legge il record (vedi <t TReclock> e <t TIsamop>) +int TSortedfile::read(word op , word lockop , TDate& atdate ) +{ + return read(curr(),op,lockop,atdate); +} +// @mfunc Legge il record e lo copia in <p rec> (vedi <t TReclock> e <t TIsamop>) +int TSortedfile::read(TRectype& rec, word op , word lockop, TDate& atdate ) +{ + _curs->read((TIsamop)op,(TReclock)lockop,atdate); + setstatus(_curs->file().status()); + return status(); +} + +// @mfunc Legge il record alla posizione <p nrec> e lo copia in <p rec> (vedi <t TReclock>) +int TSortedfile::readat(TRectype& rec, TRecnotype nrec, word lockop ) +{ + *_curs=nrec; + //read(_isequal,lockop); + rec=curr(); + setstatus(_curs->file().status()); + return status(); +} +// @mfunc Legge il record alla posizione <p nrec> e lo copia in <p rec> (vedi <t TReclock>) +int TSortedfile::readat(TRecnotype nrec, word lockop ) +{ + return readat(curr(),nrec, lockop ); +} + +// @mfunc Aggiunge un record + int TSortedfile::write(TDate& atdate) +{ + return write(curr(),atdate); +} +// @mfunc Aggiunge un record copiando da <p rec> + int TSortedfile::write(const TRectype& rec, TDate& atdate ) + { + return 0; + } + +// @mfunc Riscrive un record + int TSortedfile::rewrite(TDate& atdate ) + { + return 0; + } +// @mfunc Riscrive un record (il record <p rec>) + int TSortedfile::rewrite(const TRectype& rec, TDate& atdate ) + { + return 0; + } + +// @mfunc Riscrive un record alla posizione <p nrec> copiando da <p rec> +int TSortedfile::rewriteat(TRecnotype nrec) +{ + return rewriteat(curr(),nrec); +} +// @mfunc Riscrive un record alla posizione <p nrec> copiando da <p rec> +int TSortedfile::rewriteat(const TRectype& rec, TRecnotype nrec) +{ + error_box("Operazione 'rewriteat' non consentita sul cursore"); + return 0; +} + +// @mfunc Elimina il record +int TSortedfile::remove(TDate& atdate ) +{ + return remove(curr(),atdate); +} +// @mfunc Elimina il record copiando da <p rec> +int TSortedfile::remove(const TRectype& rec, TDate& atdate ) +{ + return 0; +} + +// @mfunc Attiva la chiave <p nkey> sul file aperto +void TSortedfile::setkey(int nkey) +{ + _curs->setkey(nkey); +} +// @mfunc Resetta la regione del file (chiama <p TCursor::setregion> +void TSortedfile::setregion(const TRectype &f,const TRectype &t) +{ + _curs->setregion(f,t); +} + + // @mfunc +TRecnotype TSortedfile::eod() const +{ + return _curs->items(); +} + // @mfunc +bool TSortedfile::empty() +{ + return _curs->items()==0; +} + +// @mfunc Costruttore. +TSortedfile::TSortedfile(int logicnum,TRelation * rel,const char * ordexpr,const char * filter, int nkey) + :TLocalisamfile(logicnum),_rel(NULL) +{ + // costruisce il cursore + if (!rel) + { + _rel = new TRelation(logicnum); + } + else + _rel=rel; + _curs = new TSorted_cursor(_rel,ordexpr,filter,nkey); + _curs->setfilter(filter,TRUE); //BUG: cursors doesn't update rel. + + if (&curr()!=&(_curs->file().curr())) + _curs->file().set_curr(&curr()); +} +// @mfunc Distruttore +TSortedfile::~TSortedfile() +{ + delete _curs; + if (_rel) delete _rel; +} + + +// // *** EOF relation.cpp diff --git a/include/relation.h b/include/relation.h index e4f7431dc..919c05765 100755 --- a/include/relation.h +++ b/include/relation.h @@ -126,7 +126,7 @@ public: // @cmember Aggiunge una nuovo file alla relazione partendo dal nome della tabella bool add(const char* tabname, const char* relexprs, int key = 1, int linkto = 0, int alias = 0, bool allow_lock = FALSE); // @cmember Sostituisce nella relazione un file - void replace(TLocalisamfile* f, int index = 0); + void replace(TLocalisamfile* f, int index = 0,const char * relexprs="",int key=1); // @cmember Aggiunge il record corrente virtual int write (bool force = TRUE, TDate& atdate = (TDate&)botime); @@ -650,6 +650,106 @@ public: // @devnote Domani o doman l'altro gestira' l'editing interattivo e grafico }; +// @doc EXTERNAL + +// @class TSortedfile | Classe per la definizione di ordinamenti arbitrari sui file isam +// +// @base public | TLocalisamfile +// +// @author:(INTERNAL) Augusto +class TSortedfile : public TLocalisamfile +{ + TRelation * _rel; + TSorted_cursor * _curs; + // @access:(INTERNAL) Private Member + +// @access Protected Members +protected: + // @cmember Apre il file con lock (vedi <mf TBaseisamfile::_open>) + int open(unsigned int mode = _manulock); + // @cmember Chiude il file aperto + int close() ; + +// @access Public Members +public: + // @cmember Avanza di <p npos> record + virtual int operator +=(const TRecnotype npos); + // @cmember Sposta indietro di <p npos> record + virtual int operator -=(const TRecnotype npos); + // @cmember Avanza al record successivo + virtual int operator ++(); + // @cmember Indietreggia al record precedente + virtual int operator --(); + // @cmember Ritorna TRUE se tabella + virtual bool tab() const + { return FALSE;} + + // @cmember Si posiziona sul primo record del file (vedi <t TReclock>) + virtual int first(word lockop = _nolock); + // @cmember Si posiziona sull'ultimo record del file (vedi <t TReclock>) + virtual int last(word lockop = _nolock); + // @cmember Si posiziona sul successivo record del file (vedi <t TReclock>) + virtual int next(word lockop = _nolock); + // @cmember Si posiziona sul precedente record del file (vedi <t TReclock>) + virtual int prev(word lockop = _nolock); + // @cmember Rilegge l'ultimo record letto (vedi <t TReclock>) + virtual int reread(word lockop = _nolock, TDate& atdate = (TDate&)botime); + // @cmember Rilegge l'ultimo record letto e lo copia in <p rec> (vedi <t TReclock>) + virtual int reread(TRectype& rec, word lockop = _nolock, TDate& atdate = (TDate&)botime); + // @cmember Salta <p nrec> record dalla posizione corrente (vedi <t TReclock>) + virtual int skip(TRecnotype nrec, word lockop = _nolock); + // @cmember Legge il record (vedi <t TReclock> e <t TIsamop>) + virtual int read(word op = _isequal, word lockop = _nolock, TDate& atdate = (TDate&)botime); + // @cmember Legge il record e lo copia in <p rec> (vedi <t TReclock> e <t TIsamop>) + virtual int read(TRectype& rec, word op = _isequal, word lockop = _nolock, TDate& atdate = (TDate&)botime); + // @cmember Legge il record alla posizione <p nrec> (vedi <t TReclock>) + virtual int readat(TRecnotype nrec, word lockop = _nolock); + // @cmember Legge il record alla posizione <p nrec> e lo copia in <p rec> (vedi <t TReclock>) + virtual int readat(TRectype& rec, TRecnotype nrec, word lockop = _nolock); + // @cmember Aggiunge un record + virtual int write(TDate& atdate = (TDate&)botime); + // @cmember Aggiunge un record copiando da <p rec> + virtual int write(const TRectype& rec, TDate& atdate = (TDate&)botime); + // @cmember Riscrive un record + virtual int rewrite(TDate& atdate = (TDate&)botime); + // @cmember Riscrive un record (il record <p rec>) + virtual int rewrite(const TRectype& rec, TDate& atdate = (TDate&)botime); + // @cmember Riscrive un record alla posizione <p nrec> + virtual int rewriteat(TRecnotype nrec); + // @cmember Riscrive un record alla posizione <p nrec> copiando da <p rec> + virtual int rewriteat(const TRectype& rec, TRecnotype nrec); + // @cmember Elimina il record + virtual int remove(TDate& atdate = (TDate&)botime); + // @cmember Elimina il record copiando da <p rec> + virtual int remove(const TRectype& rec, TDate& atdate = (TDate&)botime); + // @cmember + virtual TRecnotype eod() const ; + // @cmember + virtual bool empty(); + // @cmember Ritorna il numero del record corrente + virtual TRecnotype recno() const + {return _curs->pos();} + // @cmember setta la chiave + void setkey(int nkey); + // @cmember Resetta la regione del file (chiama <p TCursor::setregion> + void setregion(const TRectype &f,const TRectype &t); + + // TO REMOVE + TRelation &relation() + {return *_rel;} + // TO REMOVE + TSorted_cursor &cursor() + {return *_curs;} + // @cmember Restituisce se il file � ordinato con indice esterno (default:FALSE) + virtual bool is_sorted() + {return TRUE;} + // @cmember Costruttore. + TSortedfile(int logicnum,TRelation * rel,const char * ordexpr="",const char * filter="", int nkey=1); + // @cmember Distruttore + virtual ~TSortedfile(); +}; + + #endif // ** EOF relation.h