1996-12-12 16:19:39 +00:00
|
|
|
#ifndef __RECARRAY_H
|
|
|
|
#define __RECARRAY_H
|
|
|
|
|
|
|
|
#ifndef __ASSOC_H
|
|
|
|
#include <assoc.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef __ISAM_H
|
|
|
|
#include <isam.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TRecord_Array
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @class TRecord_array | Classe per la gestione di un array di record
|
|
|
|
//
|
|
|
|
// @base public | TArray
|
1997-06-02 10:05:56 +00:00
|
|
|
class TRecord_array : public TObject
|
1996-12-12 16:19:39 +00:00
|
|
|
|
|
|
|
// @author:(INTERNAL) Guido
|
|
|
|
|
|
|
|
// @access:(INTERNAL) Private Member
|
|
|
|
{
|
|
|
|
// @cmember:(INTERNAL) Numero logico del file principale
|
|
|
|
int _file;
|
1997-06-02 10:05:56 +00:00
|
|
|
// @cmember:(INTERNAL) Array di records
|
|
|
|
TArray _data;
|
1996-12-12 16:19:39 +00:00
|
|
|
// @cmember:(INTERNAL) Offset iniziale del record array
|
|
|
|
int _offset;
|
|
|
|
// @cmember:(INTERNAL) Nome del campo col numero di riga
|
|
|
|
TString16 _num;
|
|
|
|
|
|
|
|
// @access Protected Member
|
|
|
|
protected:
|
|
|
|
// @cmember Ritorna il numero riga del record <p r>
|
|
|
|
int rec2row(const TRectype& r) const;
|
|
|
|
// @cmember Ritorna il nome del campo con numero di riga
|
|
|
|
const TString& num_field() const
|
|
|
|
{ return _num; }
|
|
|
|
// @cmember Elimina il record di posizione <p i> (ritorna il risultato dell'operazione)
|
|
|
|
int remove_from(int i) const;
|
|
|
|
// @cmember Confronta i campi della chiave 1 scartando l'ultimo
|
|
|
|
bool good(const TRectype& rec) const;
|
1997-08-06 12:19:18 +00:00
|
|
|
// @cmember Duplica un record array
|
|
|
|
virtual TObject* dup() const { return new TRecord_array(*this);}
|
1996-12-12 16:19:39 +00:00
|
|
|
// @access Public Member
|
1997-06-02 10:05:56 +00:00
|
|
|
public:
|
1996-12-12 16:19:39 +00:00
|
|
|
// @cmember Ritorna il record che fa da chiave per tutti gli altri
|
|
|
|
const TRectype& key() const;
|
|
|
|
// @cmember Ritorna il numero di righe presenti
|
|
|
|
int rows() const
|
1997-06-02 10:05:56 +00:00
|
|
|
{ return _data.items()-1; }
|
1996-12-12 16:19:39 +00:00
|
|
|
|
|
|
|
// @cmember Ritorna la riga successiva non vuota a partire da <p r>
|
|
|
|
int succ_row(int r) const
|
1997-06-02 10:05:56 +00:00
|
|
|
{ return _data.succ(r - _offset) + _offset; }
|
1996-12-12 16:19:39 +00:00
|
|
|
// @cmember Ritorna la riga precedente non vuota a partire da <p r>
|
|
|
|
int pred_row(int r) const
|
1997-06-02 10:05:56 +00:00
|
|
|
{ return _data.pred(r - _offset) + _offset; };
|
1996-12-12 16:19:39 +00:00
|
|
|
// @cmember Ritorna l'ultma riga non vuota
|
|
|
|
int last_row() const
|
1997-06-02 10:05:56 +00:00
|
|
|
{ return _data.last() + _offset; }
|
1996-12-12 16:19:39 +00:00
|
|
|
// @cmember Ritorna la prima riga non vuota
|
|
|
|
int first_row() const
|
|
|
|
{ return succ_row(0); }
|
|
|
|
|
|
|
|
// @cmember Ritorna il record <p r>-esimo
|
|
|
|
const TRectype& row(int r) const
|
|
|
|
{ CHECKD(r > _offset, "Bad record number ", r); return (const TRectype&)operator[](r - _offset); }
|
|
|
|
|
|
|
|
// @cmember Controlla se esiste la riga <p r> (TRUE se esiste)
|
|
|
|
bool exist(int r) const;
|
|
|
|
// @cmember Ritorna la riga <p r>-esima; se tale riga non esiste e se <p create> assume il valore TRUE la riga viene creata
|
|
|
|
TRectype& row(int r, bool create);
|
1997-06-02 10:05:56 +00:00
|
|
|
// @cmember Ritorna la riga <p r>-esima se tale riga esiste
|
|
|
|
const TRectype& operator [](int r) const { return (const TRectype &) ((TRecord_array *) this)->row(r, FALSE);}
|
|
|
|
// @cmember Ritorna la riga <p r>-esima se tale riga esiste
|
|
|
|
TRectype& operator [](int r) { return row(r, FALSE);}
|
1996-12-12 16:19:39 +00:00
|
|
|
|
|
|
|
// @cmember Inserisce una riga alla posizione indicata nel record, sposta gli altri elementi se la posizione era gia' occupata
|
|
|
|
virtual int insert_row(TRectype* r);
|
|
|
|
// @cmember Inserisce una riga alla posizione indicata nel record, sposta gli altri elementi se la posizione era gia' occupata
|
|
|
|
int insert_row(const TRectype& r)
|
|
|
|
{ return insert_row((TRectype*)r.dup()); }
|
|
|
|
|
|
|
|
// @cmember Aggiunge/sostituisce una riga alla posizione indicata nel record
|
|
|
|
virtual int add_row(TRectype* r);
|
|
|
|
// @cmember Aggiunge/sostituisce una riga alla posizione indicata nel record
|
|
|
|
int add_row(const TRectype& r)
|
|
|
|
{ return add_row((TRectype*)r.dup()); }
|
|
|
|
// @cmember Compatta le righe piene
|
|
|
|
virtual void pack() ;
|
|
|
|
// @cmember Cancella una riga identificata da <p n>
|
|
|
|
virtual bool destroy_row(int n, bool pack = FALSE);
|
|
|
|
// @cmember Cancella una riga identificata da <p r>
|
|
|
|
virtual bool destroy_row(const TRectype& r, bool pack = FALSE)
|
|
|
|
{ return destroy_row(rec2row(r), pack); }
|
|
|
|
// @cmember Cancella tutte le righe
|
|
|
|
void destroy_rows();
|
1997-08-06 12:19:18 +00:00
|
|
|
// @cmember Copia un record array
|
|
|
|
TRecord_array& copy(const TRecord_array& a);
|
|
|
|
// @cmember Operatore di assegnamento di un record array
|
|
|
|
TRecord_array& operator= (const TRecord_array& a) { return copy(a); }
|
|
|
|
|
1996-12-12 16:19:39 +00:00
|
|
|
// @cmember Ritorna il numero logico del file principale
|
|
|
|
int logic_num() const
|
|
|
|
{ return _file; }
|
|
|
|
// @cmember Cambia l'intera chiave (solo se vuoto)
|
|
|
|
void set_key(TRectype* r);
|
|
|
|
// @cmember Rinumera il campo chiave in seguito a reinsert
|
|
|
|
bool renum_key(const char* field, const TString& num);
|
|
|
|
// @cmember Rinumera il campo chiave in seguito a reinsert
|
|
|
|
bool renum_key(const char* field, long num);
|
|
|
|
|
|
|
|
// @cmember Legge tutto l'array dal file
|
|
|
|
virtual int read(const TRectype& r);
|
|
|
|
// @cmember Legge tutto l'array dal file
|
|
|
|
virtual int read(TRectype* r);
|
|
|
|
// @cmember Aggiorna il file (se <p re> == TRUE allora viene aggiornato il record se esisteva)
|
|
|
|
virtual int write(bool re = FALSE) const;
|
|
|
|
// @cmember Aggiorna il record sul file
|
|
|
|
virtual int rewrite() const
|
|
|
|
{ return write(TRUE); }
|
|
|
|
// @cmember Cancella tutti i record dal file
|
|
|
|
virtual int remove() const;
|
|
|
|
|
|
|
|
// @cmember Costruttore
|
|
|
|
TRecord_array(const TRectype& r, const char* numfield, int first = 1);
|
|
|
|
// @cmember Costruttore
|
|
|
|
TRecord_array(int logicnum, const char* numfield, int first = 1);
|
|
|
|
// @cmember Costruttore
|
|
|
|
TRecord_array(const TRecord_array& a);
|
|
|
|
// @cmember Distruttore
|
|
|
|
virtual ~TRecord_array();
|
|
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TFile_cache
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
1997-09-26 10:18:05 +00:00
|
|
|
class TFile_cache : public TObject
|
1996-12-12 16:19:39 +00:00
|
|
|
{
|
|
|
|
TToken_string _code;
|
1998-07-20 13:15:59 +00:00
|
|
|
TString16 _filecode;
|
1996-12-12 16:19:39 +00:00
|
|
|
TLocalisamfile* _file;
|
|
|
|
int _key;
|
|
|
|
long _last_firm;
|
1997-09-26 10:18:05 +00:00
|
|
|
int _error;
|
1998-10-20 12:42:57 +00:00
|
|
|
long _last_read, _limit;
|
|
|
|
bool _test_changes;
|
1997-09-26 10:18:05 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
TAssoc_array _cache;
|
1996-12-12 16:19:39 +00:00
|
|
|
|
1997-09-26 10:18:05 +00:00
|
|
|
protected:
|
1997-10-14 15:26:48 +00:00
|
|
|
void init_file(TLocalisamfile* f=NULL);
|
1996-12-12 16:19:39 +00:00
|
|
|
void test_firm();
|
1997-09-26 10:18:05 +00:00
|
|
|
|
1996-12-12 16:19:39 +00:00
|
|
|
const TObject& query(const char* chiave);
|
|
|
|
virtual TObject* rec2obj(const TRectype& rec) const pure;
|
1997-09-26 10:18:05 +00:00
|
|
|
TLocalisamfile & file();
|
1996-12-12 16:19:39 +00:00
|
|
|
|
|
|
|
public:
|
1998-10-01 14:04:23 +00:00
|
|
|
virtual bool discard(const char* victim);
|
|
|
|
|
1997-09-26 10:18:05 +00:00
|
|
|
int io_result();
|
|
|
|
const int key_number() const
|
1998-07-20 13:15:59 +00:00
|
|
|
{ return _key; }
|
|
|
|
|
1998-12-10 16:25:48 +00:00
|
|
|
bool already_loaded(const char* code) const;
|
|
|
|
bool already_loaded(long code) const;
|
|
|
|
|
1998-07-20 13:15:59 +00:00
|
|
|
long items() const
|
|
|
|
{ return _cache.items(); }
|
|
|
|
|
|
|
|
long fill();
|
|
|
|
void destroy();
|
1998-10-20 12:42:57 +00:00
|
|
|
virtual void flush();
|
|
|
|
|
|
|
|
void set_items_limit(long l) { _limit = l; }
|
|
|
|
void test_file_changes(bool t = TRUE) { _test_changes = t; }
|
1997-09-26 10:18:05 +00:00
|
|
|
|
1997-10-14 15:26:48 +00:00
|
|
|
TFile_cache(TLocalisamfile *f,int key = 1);
|
1996-12-12 16:19:39 +00:00
|
|
|
TFile_cache(int num, int key = 1);
|
|
|
|
TFile_cache(const char* table, int key = 1);
|
|
|
|
virtual ~TFile_cache();
|
|
|
|
};
|
|
|
|
|
|
|
|
class TDecoder : public TFile_cache
|
|
|
|
{
|
|
|
|
TString16 _outf;
|
|
|
|
|
|
|
|
protected:
|
1997-09-26 10:18:05 +00:00
|
|
|
virtual TObject* rec2obj(const TRectype& rec) const;
|
1996-12-12 16:19:39 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
const TString& decode(const char* code);
|
|
|
|
const TString& decode(long code);
|
|
|
|
|
|
|
|
TDecoder(int num, const char* field, int key = 1);
|
|
|
|
TDecoder(const char* table, const char* field = "S0", int key = 1);
|
|
|
|
virtual ~TDecoder() { }
|
|
|
|
};
|
|
|
|
|
|
|
|
class TRecord_cache : public TFile_cache
|
|
|
|
{
|
|
|
|
protected:
|
1997-09-26 10:18:05 +00:00
|
|
|
virtual TObject* rec2obj(const TRectype& rec) const;
|
1998-11-04 18:04:26 +00:00
|
|
|
// @cmember Elimina la chiave dalla cache
|
1996-12-12 16:19:39 +00:00
|
|
|
|
|
|
|
public:
|
1997-09-26 10:18:05 +00:00
|
|
|
// @cmember ritorna il campo (chiama get(chiave))
|
1996-12-12 16:19:39 +00:00
|
|
|
const TString& get(const char* chiave, const char* campo);
|
1997-09-26 10:18:05 +00:00
|
|
|
// @cmember ritorna il record con una determinata chiave
|
|
|
|
virtual const TRectype& get(const char* chiave);
|
1996-12-12 16:19:39 +00:00
|
|
|
|
|
|
|
TRecord_cache(int num, int key = 1);
|
1997-10-14 15:26:48 +00:00
|
|
|
TRecord_cache(TLocalisamfile *f, int key = 1);
|
1996-12-12 16:19:39 +00:00
|
|
|
TRecord_cache(const char* table, int key = 1);
|
|
|
|
virtual ~TRecord_cache() { }
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|