campo-sirio/include/recarray.h
guy e9a34d143f Migliorata gestione sheet ricerca
git-svn-id: svn://10.65.10.50/branches/R_10_00@23179 c028cbd2-c16b-5b4b-a496-9718f37d4682
2016-02-25 11:34:01 +00:00

292 lines
9.6 KiB
C++
Executable File

#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
class TRecord_array : public TObject
// @author:(INTERNAL) Guido
// @access:(INTERNAL) Private Member
{
// @cmember:(INTERNAL) Numero logico del file principale
int _file;
// @cmember:(INTERNAL) Array di records
TArray _data;
// @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;
// @cmember Duplica un record array
virtual TObject* dup() const { return new TRecord_array(*this);}
int remove_from(TIsamfile& f, int pos) const;
// @access Public Member
public:
// @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
{ return _data.items()-1; }
// @cmember Ritorna la riga successiva non vuota a partire da <p r>
int succ_row(int r) const
{ return _data.succ(r - _offset) + _offset; }
// @cmember Ritorna la riga precedente non vuota a partire da <p r>
int pred_row(int r) const
{ return _data.pred(r - _offset) + _offset; };
// @cmember Ritorna l'ultma riga non vuota
int last_row() const
{ return _data.last() + _offset; }
// @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);
// @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);}
// @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();
// @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); }
// @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 Ordina il Record Array secondo il criterio definito in <t COMPARE_FUNCTION>
void sort(COMPARE_FUNCTION sort_func);
// @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 Costruttore moderno (c) by Guy
TRecord_array(const char* keytok, int logicnum, int first = 1);
// @cmember Distruttore
virtual ~TRecord_array();
};
///////////////////////////////////////////////////////////
// TFile_cache
///////////////////////////////////////////////////////////
class TFile_cache : public TObject
{
static unsigned long _hits, _misses;
TToken_string _code;
TString8 _filecode; // Codice tabella es: %STA, &AUT, LVCAU
TLocalisamfile* _file;
int _key;
long _last_firm, _limit;
unsigned long _last_file_test, _last_file_time;
int _error;
bool _test_changes, _changed;
protected:
TAssoc_array _cache;
void construct(int key); // Common costruction
protected:
void init_file(TLocalisamfile* f=NULL);
void test_firm();
void kill_file();
const TObject& query(const char* chiave);
virtual TObject* rec2obj(const TRectype& rec) const pure;
TLocalisamfile& file();
public:
virtual bool discard(const char* victim);
int io_result();
const int key_number() const
{ return _key; }
bool already_loaded(const char* code) const;
bool already_loaded(long code) const;
long items() const
{ return _cache.items(); }
long fill();
void destroy();
virtual void flush();
void set_items_limit(long l) { _limit = l; }
void test_file_changes(bool t = TRUE) { _test_changes = t; }
void notify_change();
static void stats(unsigned long& hits, unsigned long& misses);
TFile_cache(TLocalisamfile *f,int key = 1);
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:
virtual TObject* rec2obj(const TRectype& rec) const;
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:
virtual TObject* rec2obj(const TRectype& rec) const;
// @cmember Elimina la chiave dalla cache
public:
// @cmember ritorna il record con una determinata chiave
virtual const TRectype& get(const char* chiave);
// @cmember ritorna il campo (chiama get(chiave))
const TString& get(const char* chiave, const char* campo);
// @cmember ritorna il record con una determinata chiave numerica
const TRectype& get(long chiave);
const TString& get(long chiave, const char* campo);
TRecord_cache(int num, int key = 1);
TRecord_cache(TLocalisamfile *f, int key = 1);
TRecord_cache(const char* table, int key = 1);
virtual ~TRecord_cache() { }
};
class TDB_cache : public TArray
{
protected:
int build_table_key(const char* table, const char* key, TToken_string& k) const;
public:
TRecord_cache& rec_cache(int file);
bool discard(int file, const char* key);
bool discard(const char *table, const char* key);
bool discard(const TRectype& rec);
void flush(int file) { rec_cache(file).flush(); }
void discard(int file);
const TRectype& get(int file, const char* key_tok) { return rec_cache(file).get(key_tok); }
const TRectype& get(int file, long key) { return rec_cache(file).get(key); }
const TRectype& get(const char* table, const char* key_tok);
const TRectype& get(const TRectype& key);
// Smarter get: no token string key needed
const TRectype& get_rec(int file, const char* key1, const char* key2=NULL, const char* key3=NULL, const char* key4=NULL);
// clifo&anagr get: no token string key needed
const TRectype& get_rec(int file, char c, long n);
const TString& get(int file, const char* key_tok, const char * campo);
const TString& get(int file, long key, const char * campo);
const TString& get(const char* table, const char* key_tok, const char* campo);
void test_file_changes(int file, bool t = TRUE)
{ rec_cache(file).test_file_changes(t); }
};
// Best performance by exclusive locking ... when possible :-)
class TFast_isamfile : public TIsamfile
{
public:
TFast_isamfile(int logicnum);
~TFast_isamfile();
};
TDB_cache& cache();
TRecord_cache& rec_cache(int file);
const TString_array& user_and_groups();
#endif