1995-11-27 08:39:18 +00:00
|
|
|
/* $Id: relation.h,v 1.31 1995-11-27 08:39:10 guy Exp $ */
|
1994-09-22 07:48:15 +00:00
|
|
|
// join.h
|
|
|
|
// fv 12/8/93
|
|
|
|
// join class for isam files
|
|
|
|
|
|
|
|
#ifndef __RELATION_H
|
|
|
|
#define __RELATION_H
|
|
|
|
|
|
|
|
#ifndef __ISAM_H
|
|
|
|
#include <isam.h>
|
|
|
|
#endif
|
|
|
|
|
1995-08-03 14:55:31 +00:00
|
|
|
#ifndef __SORT_H
|
1995-11-27 08:39:18 +00:00
|
|
|
class TSort;
|
1995-08-03 14:55:31 +00:00
|
|
|
#endif
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
class TRelation : public TObject
|
|
|
|
{
|
|
|
|
friend class TRelationdef;
|
1995-05-09 09:12:26 +00:00
|
|
|
friend class TRelation_description;
|
|
|
|
friend class TCursor;
|
1994-09-22 07:48:15 +00:00
|
|
|
|
|
|
|
TToken_string _status; // stato della relazione
|
1995-05-09 09:12:26 +00:00
|
|
|
TArray _files; // file descriptors
|
|
|
|
TArray _reldefs; // TRelationdef array
|
1994-09-22 07:48:15 +00:00
|
|
|
int _errors;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
int log2ind(int logicnum) const;
|
1995-01-09 16:51:21 +00:00
|
|
|
int alias2ind(int alias) const;
|
1994-09-22 07:48:15 +00:00
|
|
|
int name2ind(const char* name) const;
|
|
|
|
|
|
|
|
TRelationdef& reldef(int i) const { return (TRelationdef&)_reldefs[i]; }
|
|
|
|
TLocalisamfile& file(int i = 0) const { return (TLocalisamfile&)_files[i]; }
|
|
|
|
|
|
|
|
// position_rels fa tutto il lavoro: se non trova un record
|
|
|
|
// adatto su un file, svuota il record corrente e non ritorna errore.
|
|
|
|
// write etc. poi procedono normalmente
|
|
|
|
int position_rels(TIsamop op = _isequal, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime, int first = 0);
|
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
public: // TObject
|
|
|
|
virtual bool ok() const { return good(); }
|
|
|
|
virtual void print_on(ostream& out) const;
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
public:
|
|
|
|
int update() { return position_rels(_isequal, _nolock);}
|
|
|
|
void zero();
|
|
|
|
virtual int next(TReclock lockop = _nolock) { return file().next(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
|
|
|
virtual int prev(TReclock lockop = _nolock) { return file().prev(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
|
|
|
virtual int next(TDate& atdate) { return file().next(atdate) == NOERR ? position_rels(_isequal, _nolock, atdate) : file().status(); }
|
|
|
|
virtual int prev(TDate& atdate) { return file().prev(atdate) == NOERR ? position_rels(_isequal, _nolock, atdate) : file().status(); }
|
|
|
|
virtual int first(TReclock lockop = _nolock) { return file().first(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
|
|
|
virtual int last(TReclock lockop = _nolock) { return file().last(lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
|
|
|
virtual int skip(TRecnotype nrec, TReclock lockop = _nolock) { return file().skip(nrec, lockop) == NOERR ? position_rels(_isequal, lockop) : file().status(); }
|
|
|
|
virtual int read(TIsamop op = _isgteq, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime) { return file().read(op, lockop, atdate) == NOERR ? position_rels(_isequal, lockop, atdate) : file().status();}
|
1995-11-27 08:39:18 +00:00
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
TLocalisamfile& lfile(int logicnum = 0) const;
|
|
|
|
TLocalisamfile& lfile(const char* name) const;
|
1995-11-27 08:39:18 +00:00
|
|
|
TLocalisamfile& operator[] (int logicnum) const { return lfile(logicnum); }
|
|
|
|
|
1995-06-01 09:09:30 +00:00
|
|
|
void write_enable(int logicnum = 0, const bool on = TRUE) ;
|
1994-09-22 07:48:15 +00:00
|
|
|
void write_enable(const char* name, const bool on = TRUE) ;
|
1995-06-01 09:09:30 +00:00
|
|
|
void write_disable(int logicnum = 0) { write_enable(logicnum, FALSE); }
|
1994-09-22 07:48:15 +00:00
|
|
|
void write_disable(const char* name) { write_enable(name, FALSE); }
|
|
|
|
|
|
|
|
TRectype& curr(int logicnum = 0) const { return lfile(logicnum).curr(); }
|
|
|
|
// next_match for 0ne-to-many relations; positions logicnum (!= main)
|
|
|
|
// on next matching record; returns TRUE or FALSE if no more matches; in
|
|
|
|
// any case relation is kept consistent except when inconsistent in
|
|
|
|
// first place
|
|
|
|
bool next_match(int logicnum, const char* fieldlist = NULL, int nkey = 0);
|
|
|
|
|
1995-02-10 17:42:33 +00:00
|
|
|
bool add(TLocalisamfile* f, const char* relexprs, int key,
|
|
|
|
int linkto, int alias, bool allow_lock);
|
1994-09-22 07:48:15 +00:00
|
|
|
bool add(int logicnum, const char* relexprs, int key = 1,
|
1995-01-09 16:51:21 +00:00
|
|
|
int linkto = 0, int alias = 0, bool allow_lock = FALSE);
|
1994-09-22 07:48:15 +00:00
|
|
|
bool add(const char* tabname, const char* relexprs, int key = 1,
|
1995-01-09 16:51:21 +00:00
|
|
|
int linkto = 0, int alias = 0, bool allow_lock = FALSE);
|
1995-02-10 17:42:33 +00:00
|
|
|
void replace(TLocalisamfile* f, int index = 0);
|
1994-09-22 07:48:15 +00:00
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
// write methods
|
1994-09-22 07:48:15 +00:00
|
|
|
virtual int write (bool force = TRUE, TDate& atdate = (TDate&)botime);
|
|
|
|
virtual int rewrite(bool force = TRUE, TDate& atdate = (TDate&)botime);
|
|
|
|
virtual int remove (TDate& atdate = (TDate&)botime);
|
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
// status methods
|
|
|
|
// return the status of the relation when called
|
1994-09-22 07:48:15 +00:00
|
|
|
// with no args, or the status of the file when called with
|
|
|
|
// a logical number
|
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
bool eof( int logicnum = 0) const { return lfile(logicnum).eof(); }
|
|
|
|
bool bof( int logicnum = 0) const { return lfile(logicnum).bof(); }
|
|
|
|
bool status(int logicnum = 0) const { return lfile(logicnum).status(); }
|
|
|
|
bool good( int logicnum = 0) const { return lfile(logicnum).good(); }
|
|
|
|
bool bad( int logicnum = 0) const { return lfile(logicnum).bad(); }
|
|
|
|
bool empty( int logicnum = 0) const { return lfile(logicnum).empty(); }
|
1994-09-22 07:48:15 +00:00
|
|
|
|
|
|
|
// isconsistent() returns TRUE if every file in the relation is
|
|
|
|
// OK, current record is non-empty, and relation is consistent.
|
|
|
|
// If it's not and reset is TRUE, it tries to reset the relation
|
|
|
|
// to a consistent state (based on main record) -- no further check
|
|
|
|
// is done.
|
|
|
|
// Also called internally by update and remove.
|
|
|
|
bool isconsistent(bool reset = FALSE);
|
|
|
|
|
|
|
|
// TRUE se c'e' un record ed e' il primo match (non si e' mai fatta
|
|
|
|
// position_rels)
|
|
|
|
bool is_first_match(int logicnum);
|
|
|
|
|
1995-05-09 09:12:26 +00:00
|
|
|
// items() ritorna il numero di files collegati
|
|
|
|
int items() { return _reldefs.items(); }
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
void save_status () ;
|
|
|
|
void restore_status () ;
|
1995-07-03 07:49:30 +00:00
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
// positioning operators. return status
|
1994-09-22 07:48:15 +00:00
|
|
|
TRecnotype operator +=(const TRecnotype npos) { return skip(npos); }
|
|
|
|
TRecnotype operator -=(const TRecnotype npos) { return skip(-npos); }
|
|
|
|
TRecnotype operator ++() { return next(); }
|
|
|
|
TRecnotype operator --() { return prev(); }
|
1994-12-20 15:11:26 +00:00
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
TRelation(int logicnum);
|
|
|
|
TRelation(const char* tabname);
|
1995-02-10 17:42:33 +00:00
|
|
|
TRelation(TLocalisamfile* f);
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
virtual ~TRelation();
|
|
|
|
};
|
|
|
|
|
1995-04-10 15:28:03 +00:00
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TRecord_Array
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class TRecord_array : private TArray
|
|
|
|
{
|
1995-04-14 12:14:16 +00:00
|
|
|
int _file; // Numero logico del file principale
|
1995-04-18 11:03:46 +00:00
|
|
|
int _offset; // Offset iniziale del record array
|
1995-04-14 12:14:16 +00:00
|
|
|
TString16 _num; // Nome del campo col numero di riga
|
1995-04-10 15:28:03 +00:00
|
|
|
|
1995-08-09 09:54:36 +00:00
|
|
|
protected:
|
1995-04-14 12:14:16 +00:00
|
|
|
int rec2row(const TRectype& r) const; // Estrae il numero riga di un record
|
1995-08-09 09:54:36 +00:00
|
|
|
const TString& num_field() const { return _num; }
|
1995-09-19 15:45:42 +00:00
|
|
|
int remove_from(int i) const;
|
1995-11-13 12:08:59 +00:00
|
|
|
bool good(const TRectype& rec) const;
|
1995-04-10 15:28:03 +00:00
|
|
|
|
|
|
|
public:
|
1995-08-09 09:54:36 +00:00
|
|
|
const TRectype& key() const;
|
1995-04-14 12:14:16 +00:00
|
|
|
int rows() const { return items()-1; } // Numero di righe presenti
|
1995-08-21 07:47:18 +00:00
|
|
|
|
|
|
|
int succ_row(int r) const { return succ(r - _offset) + _offset; }
|
|
|
|
int pred_row(int r) const { return pred(r - _offset) + _offset; };
|
1995-04-18 11:03:46 +00:00
|
|
|
int last_row() const { return last() + _offset; } // Ultima riga
|
1995-08-21 07:47:18 +00:00
|
|
|
int first_row() const { return succ_row(0); } // Prima riga
|
1995-04-10 15:28:03 +00:00
|
|
|
|
1995-08-09 09:54:36 +00:00
|
|
|
const TRectype& row(int r) const // Riga r costante
|
1995-04-18 11:03:46 +00:00
|
|
|
{ CHECKD(r > _offset, "Bad record number ", r); return (const TRectype&)operator[](r - _offset); }
|
1995-04-10 15:28:03 +00:00
|
|
|
|
1995-08-09 09:54:36 +00:00
|
|
|
bool exist(int r) const; // Controlla se esiste la riga r
|
|
|
|
TRectype& row(int r, bool create); // Riga r con possibilita' di crearla
|
1995-04-10 15:28:03 +00:00
|
|
|
|
1995-08-09 09:54:36 +00:00
|
|
|
virtual int add_row(TRectype* r); // Aggiungi/cambia una riga
|
|
|
|
int add_row(const TRectype& r) { return add_row((TRectype*)r.dup()); }
|
1995-04-14 12:14:16 +00:00
|
|
|
virtual bool destroy_row(int n, bool pack = FALSE); // Cancella una riga
|
|
|
|
virtual bool destroy_row(const TRectype& r, bool pack = FALSE) { return destroy_row(rec2row(r), pack); }
|
|
|
|
void destroy_rows(); // Cancella tutte le righe
|
|
|
|
|
1995-09-19 15:45:42 +00:00
|
|
|
int logic_num() const { return _file; }
|
1995-08-28 07:51:30 +00:00
|
|
|
void set_key(TRectype* r); // Cambia l'intera chiave (solo se vuoto!)
|
1995-04-14 12:14:16 +00:00
|
|
|
bool renum_key(const char* field, const TString& num);
|
1995-05-29 10:25:10 +00:00
|
|
|
bool renum_key(const char* field, long num); // Rinumera campo chiave in seguito a reinsert
|
1995-04-14 12:14:16 +00:00
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
virtual int read(const TRectype& r); // Leggi tutto l'array da file
|
1995-08-09 09:54:36 +00:00
|
|
|
virtual int read(TRectype* r); // Leggi tutto l'array da file
|
|
|
|
virtual int write(bool re = FALSE) const; // Aggiorna il file
|
|
|
|
virtual int rewrite() const { return write(TRUE); }
|
1995-09-19 15:45:42 +00:00
|
|
|
virtual int remove() const; // Cancella tutti i record dal file
|
1995-05-29 10:25:10 +00:00
|
|
|
|
1995-04-18 11:03:46 +00:00
|
|
|
TRecord_array(const TRectype& r, const char* numfield, int first = 1);
|
|
|
|
TRecord_array(int logicnum, const char* numfield, int first = 1);
|
1995-08-09 09:54:36 +00:00
|
|
|
TRecord_array(const TRecord_array& a);
|
1995-04-10 15:28:03 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
// Classe TCursor : public TObject
|
1995-07-03 07:49:30 +00:00
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
class TExpression;
|
|
|
|
|
|
|
|
typedef bool (*FILTERFUNCTION)(const TRelation* r);
|
|
|
|
|
1995-11-22 13:55:07 +00:00
|
|
|
class TCursor : public TContainer
|
1994-09-22 07:48:15 +00:00
|
|
|
{
|
|
|
|
TRelation* _if;
|
|
|
|
int _nkey;
|
1995-07-03 07:49:30 +00:00
|
|
|
TRecnotype _pos; // Posizione corrente
|
1994-09-22 07:48:15 +00:00
|
|
|
TRecnotype _totrec;
|
|
|
|
TRecnotype _lastrec;
|
1995-07-03 07:49:30 +00:00
|
|
|
TRecnotype _lastkrec;
|
1995-05-29 10:25:10 +00:00
|
|
|
TFilename _filename;
|
1995-07-03 07:49:30 +00:00
|
|
|
TString _filter; // Filtro
|
|
|
|
TString _keyfrom; // chiave iniziale
|
|
|
|
TString _keyto; // chiave finale
|
|
|
|
TExpression* _fexpr; // Espressione relativo filtro
|
1995-05-29 10:25:10 +00:00
|
|
|
bool _frozen;
|
1995-07-03 07:49:30 +00:00
|
|
|
bool _filter_update; // Flag che permette l'update della relazione per l'espressione-filtro
|
|
|
|
bool _filterfunction_update;// Flag che permette l'update della relazione per la funzione-filtro
|
1995-05-29 10:25:10 +00:00
|
|
|
FILTERFUNCTION _filterfunction;
|
|
|
|
TFilename _indexname;
|
1994-09-22 07:48:15 +00:00
|
|
|
|
|
|
|
TRecnotype update();
|
|
|
|
|
|
|
|
|
|
|
|
protected:
|
1995-07-03 07:49:30 +00:00
|
|
|
FILE* open_index(bool create = FALSE);
|
|
|
|
virtual bool changed();
|
|
|
|
virtual TRecnotype buildcursor(TRecnotype rp);
|
|
|
|
virtual int filtercursor(int pagecnt, TRecnotype* page);
|
1994-09-22 07:48:15 +00:00
|
|
|
TRecnotype readrec();
|
|
|
|
void filter(const char* filter, const TRectype* from = NULL,
|
|
|
|
const TRectype* to = NULL);
|
1995-07-03 07:49:30 +00:00
|
|
|
bool update_relation() {return (_filter_update || _filterfunction_update);}
|
1994-09-22 07:48:15 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
// @FPUB
|
1994-09-22 16:47:50 +00:00
|
|
|
TRecnotype operator =(const TRecnotype nr); // Va alla posizione nr
|
|
|
|
TRecnotype operator +=(const TRecnotype nr);
|
|
|
|
TRecnotype operator -=(const TRecnotype npos) { return operator +=(-npos); }
|
1995-11-22 13:55:07 +00:00
|
|
|
TObject* first_item( ){ operator =( 0 ); return &curr( ); }
|
|
|
|
TObject* succ_item( ){ operator +=( 1 ); return &curr( ); }
|
|
|
|
TObject* pred_item( ){ operator -=( 1 ); return &curr( );}
|
|
|
|
TObject* last_item( ){ operator =( items( ) -1 ); return &curr( ); }
|
|
|
|
long objects( ) { return items( ); }
|
|
|
|
|
1995-07-03 07:49:30 +00:00
|
|
|
TRecnotype& pos() { return _pos; }
|
1994-09-22 07:48:15 +00:00
|
|
|
TRecnotype items();
|
|
|
|
TRecnotype size() const { return file().eod(); }
|
1994-09-22 16:47:50 +00:00
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
const TString& from() const { return _keyfrom; }
|
|
|
|
const TString& to() const { return _keyto; }
|
|
|
|
|
|
|
|
TRectype& curr(int log = 0) const { return _if->curr(log); }
|
1994-09-22 16:47:50 +00:00
|
|
|
TRectype& curr(const char * tab) const { return _if->lfile(tab).curr(); }
|
1994-09-22 07:48:15 +00:00
|
|
|
TRecnotype read(TIsamop op = _isgteq, TReclock lockop = _nolock, TDate& atdate = (TDate&)botime);
|
1994-09-22 16:47:50 +00:00
|
|
|
int lock(TReclock = _lock);
|
|
|
|
int unlock() { return lock(_unlock); }
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
virtual bool ok() const;
|
|
|
|
|
|
|
|
const char* filter() const { return _filter; }
|
|
|
|
void freeze(bool on = TRUE) { _frozen = on; }
|
|
|
|
bool frozen() const { return _frozen; }
|
1995-07-03 07:49:30 +00:00
|
|
|
void setfilter(const char* filter_expr, bool update=FALSE) { filter(filter_expr); _filter_update = update; }
|
1994-09-22 07:48:15 +00:00
|
|
|
void setregion(const TRectype& from, const TRectype& to)
|
|
|
|
{ filter(NULL,&from, &to); }
|
|
|
|
|
|
|
|
TRelation* relation() const { return _if; }
|
|
|
|
TLocalisamfile& file(int lnum = 0) const { return _if->lfile(lnum); }
|
|
|
|
TLocalisamfile& file(const char* name) const { return _if->lfile(name); }
|
|
|
|
int repos() { return _if->position_rels(); }
|
|
|
|
|
1995-07-03 07:49:30 +00:00
|
|
|
TExpression* expression() const { return _fexpr; }
|
|
|
|
FILTERFUNCTION filterfunction() const { return _filterfunction; }
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
void setkey() { file().setkey(_nkey); }
|
|
|
|
void setkey(int nkey);
|
|
|
|
int key() const { return _nkey; }
|
|
|
|
|
|
|
|
bool next_match(int lognum, const char* fl = NULL, int nk = 0);
|
|
|
|
bool is_first_match(int ln);
|
|
|
|
|
1995-07-03 07:49:30 +00:00
|
|
|
void set_filterfunction(FILTERFUNCTION ff, bool update=FALSE) { _filterfunction = ff; _lastrec = 0L; _filterfunction_update = update;}
|
1994-09-22 07:48:15 +00:00
|
|
|
bool has_filter() const { return _filter.not_empty() || _filterfunction; }
|
|
|
|
|
|
|
|
void save_status () { _if->save_status(); }
|
|
|
|
void restore_status () { _if->restore_status(); }
|
|
|
|
|
1995-04-14 12:14:16 +00:00
|
|
|
TCursor(TRelation* f, const char* filter = "", int key = 1, const TRectype* from = NULL, const TRectype* to = NULL);
|
1994-09-22 07:48:15 +00:00
|
|
|
virtual ~TCursor();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
1995-08-03 14:55:31 +00:00
|
|
|
|
|
|
|
// Classe TSorted_cursor. Costruisce e gestisce un cursore ordinato per chiavi diverse da quelle specificate nel file.
|
|
|
|
// Il formato dell'espressione deve essere: [LF->]FIELDNAME[[from,to]][+|-]... Inoltre tutta l'espressione puo' essere racchiusa
|
|
|
|
// dall'operatore UPPER(), per controlli non case-sensitive.
|
|
|
|
// FIELDNAME e' il nome del campo per quale si vuole effettuare il sort, LF indica il numero logico del file(appartenente alla relazione!).
|
|
|
|
// from e to sono parametri opzionali usati per specificare un sottocampo. Per default prende l'intera lunghezza.
|
|
|
|
// + e - sono parametri opzionali usati per specificare il tipo di ordinamento: + significa crescente, - significa
|
|
|
|
// decrescente. Per default l'ordinamento e' +(crescente). E' cosi' possibile creare chiavi con campi non appartententi al
|
|
|
|
// file principale della relazione.
|
|
|
|
// Es. "CODCF-|TIPOCF|SOTTOCONTO+|UPPER(20->RAGSOC[1,40]-)"
|
|
|
|
|
|
|
|
class TSorted_cursor : public TCursor
|
|
|
|
{
|
|
|
|
TToken_string _order_expr;
|
|
|
|
TSort *_sort;
|
|
|
|
bool _is_changed_expr;
|
|
|
|
bool _is_valid_expr;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
bool check_expr(TString& s); // Controlla il formato della singola espressione di un campo di sort
|
|
|
|
bool is_upper(TString& s); // Controlla se la singola espressione contiene l'operatore UPPER(), ritornandone l'argomento
|
|
|
|
virtual TRecnotype buildcursor(TRecnotype rp); // Vedi i TCursor
|
|
|
|
virtual int filtercursor(int pagecnt, TRecnotype* page); // Vedi i TCursor
|
|
|
|
virtual bool changed(); // Vedi i TCursor
|
|
|
|
|
|
|
|
public:
|
1995-08-24 12:47:05 +00:00
|
|
|
TRecnotype operator =(const TRecnotype nr) {return TCursor::operator =(nr); }
|
1995-08-03 14:55:31 +00:00
|
|
|
void change_order(const char * order_expr); // Permette di cambiare l'ordinamento del cursore.
|
|
|
|
TSorted_cursor(TRelation *f,const char * order_expr, const char * filter = "", int key = 1, const TRectype* from = NULL, const TRectype* to = NULL);
|
|
|
|
virtual ~TSorted_cursor();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
// Classe TFieldref : public TObject
|
|
|
|
|
|
|
|
class TFieldref : public TObject
|
|
|
|
{
|
1995-05-29 10:25:10 +00:00
|
|
|
short _fileid; // Numero del file
|
|
|
|
TString _id; // Nome tabella o stringa col numero del file
|
|
|
|
TString _name; // Nome del campo
|
|
|
|
int _from, _to; // Substring
|
1994-09-22 07:48:15 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
virtual void print_on(ostream& out) const;
|
|
|
|
|
|
|
|
public:
|
|
|
|
TFieldref();
|
|
|
|
TFieldref(const TString&, short defid);
|
|
|
|
|
|
|
|
TFieldref& operator =(const TString& s); // Operatore di assegnazione
|
|
|
|
|
|
|
|
virtual bool ok() const { return _name.not_empty(); } // Vero se il numero del file e' valido
|
|
|
|
|
|
|
|
int file() const { return _fileid; } // ritorna il file
|
1995-05-29 10:25:10 +00:00
|
|
|
void set_file(int f);
|
|
|
|
|
1995-05-30 16:01:38 +00:00
|
|
|
const TString& name() const { return _name; } // ritorna il nome del campo
|
1995-05-29 10:25:10 +00:00
|
|
|
void set_name(const char* n) { _name = n; }
|
|
|
|
void set_from(int f) { if (f > 0) f--; else f = 0; _from = f; }
|
|
|
|
void set_to(int t) { _to = t; }
|
1995-07-03 07:49:30 +00:00
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
int from() const { return _from; }
|
|
|
|
int to() const { return _to; }
|
|
|
|
int len(TRectype &rec) const;
|
1995-06-28 16:35:30 +00:00
|
|
|
const char* read(const TRelation*) const;
|
1994-09-22 07:48:15 +00:00
|
|
|
const char* read(const TRectype&) const;
|
1995-06-28 16:35:30 +00:00
|
|
|
void write(const char* val, TRelation*) const;
|
1994-09-22 07:48:15 +00:00
|
|
|
void write(const char* val, TRectype& rec) const;
|
1995-05-09 09:12:26 +00:00
|
|
|
};
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
// Converte una stringa in numero logico o numero tabella
|
|
|
|
int name2log(const char* name);
|
1995-05-09 09:12:26 +00:00
|
|
|
|
|
|
|
class TRelation_description : public TObject
|
|
|
|
{
|
|
|
|
// gestisce l'uso interattivo di una relazione (scelta campi, descrizione)
|
|
|
|
// domani o doman l'altro gestira' l'editing interattivo e grafico
|
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
TRelation* _rel; // relation described
|
1995-05-09 09:12:26 +00:00
|
|
|
TString_array _files;
|
|
|
|
TArray _fields;
|
|
|
|
int _cur_file;
|
|
|
|
int _cur_field;
|
|
|
|
bool _menu;
|
|
|
|
TToken_string _cfile, _cfield;
|
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
protected:
|
|
|
|
void init_files_array();
|
|
|
|
void read_rel();
|
1995-05-09 09:12:26 +00:00
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
public: // TObject
|
|
|
|
virtual bool ok() const { return _files.items() > 0; }
|
|
|
|
|
1995-05-09 09:12:26 +00:00
|
|
|
public:
|
|
|
|
|
|
|
|
// "choose" interface: after choosing a field (must return TRUE)
|
|
|
|
// methods allow to know all data concerning the field
|
|
|
|
// parameters set the one initially selected
|
1995-05-29 10:25:10 +00:00
|
|
|
bool choose_file (int id = 0);
|
|
|
|
bool set_cur_file(int id = 0);
|
1995-05-09 09:12:26 +00:00
|
|
|
|
|
|
|
// file must have been chosen: first file in list if called
|
|
|
|
// before choose_file
|
|
|
|
bool choose_field(const char* fld = "");
|
|
|
|
|
|
|
|
// if wanted, build a menu tree and set current field upon
|
|
|
|
// selecting it (should be popup)
|
|
|
|
bool build_menu(const char* title = "Database");
|
|
|
|
bool remove_menu();
|
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
// if choose_file == TRUE or menu has been used these return valid data
|
|
|
|
int file_num();
|
1995-05-09 09:12:26 +00:00
|
|
|
const char* file_desc();
|
1995-05-29 10:25:10 +00:00
|
|
|
void file_desc(const char* desc);
|
|
|
|
bool set_field_description(const char* field, const char* des);
|
|
|
|
const char* get_field_description(const char* field);
|
|
|
|
|
|
|
|
// if choose_field == TRUE or menu has been used these return valid data
|
1995-05-09 09:12:26 +00:00
|
|
|
const char* field_desc();
|
1995-05-29 10:25:10 +00:00
|
|
|
void field_desc(const char* desc);
|
1995-05-09 09:12:26 +00:00
|
|
|
const char* field_name();
|
|
|
|
int field_len();
|
|
|
|
TFieldtypes field_type();
|
|
|
|
|
1995-05-29 10:25:10 +00:00
|
|
|
const TString_array& get_all_desc() const { return _files; }
|
|
|
|
void change_relation(TRelation& rel, TString_array& arr);
|
|
|
|
|
|
|
|
virtual void print_on(ostream& out) const;
|
1995-05-09 09:12:26 +00:00
|
|
|
|
|
|
|
TRelation_description(TRelation& r);
|
|
|
|
virtual ~TRelation_description();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
1994-09-22 07:48:15 +00:00
|
|
|
#endif
|
|
|
|
// ** EOF relation.h
|