Files correlati : Ricompilazione Demo : [ ] Commento : Riportata la versione 1.7 patch 054 sul main trunk (II) git-svn-id: svn://10.65.10.50/trunk@9665 c028cbd2-c16b-5b4b-a496-9718f37d4682
		
			
				
	
	
		
			271 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			271 lines
		
	
	
		
			8.7 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);}
 | |
| // @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 Distruttore
 | |
|   virtual ~TRecord_array();
 | |
| };
 | |
| 
 | |
| ///////////////////////////////////////////////////////////
 | |
| // TFile_cache
 | |
| ///////////////////////////////////////////////////////////
 | |
| 
 | |
| class TFile_cache : public TObject
 | |
| { 
 | |
|   static unsigned long _hits, _misses;
 | |
| 
 | |
|   TToken_string _code;
 | |
|   TString16 _filecode;
 | |
|   TLocalisamfile* _file;
 | |
|   int _key;
 | |
|   long _last_firm;
 | |
|   int _error;
 | |
|   long _last_read, _limit;
 | |
|   bool _test_changes;
 | |
| 
 | |
| protected:
 | |
|   TAssoc_array _cache;
 | |
| 
 | |
| 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; }
 | |
|   
 | |
|   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
 | |
| {
 | |
| 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(); }
 | |
| 
 | |
|   const TRectype& get(int file, const char* key)
 | |
|   { return rec_cache(file).get(key); }
 | |
|   const TRectype& get(int file, long key)
 | |
|   { return rec_cache(file).get(key); }
 | |
|   const TRectype& get(const char* table, const char* key);
 | |
| 
 | |
|   const TString& get(int file, const char* key, const char * campo)
 | |
|   { return get(file, key).get(campo); }
 | |
|   const TString& get(int file, long key, const char * campo)
 | |
|   { return get(file, key).get(campo); }
 | |
|   const TString& get(const char* table, const char* key, const char * campo)
 | |
|   { return get(table, key).get(campo); }
 | |
| 
 | |
|   void test_file_changes(int file, bool t = TRUE) 
 | |
|   { rec_cache(file).test_file_changes(t); }
 | |
| };
 | |
| 
 | |
| TDB_cache& cache();
 | |
| TRecord_cache& rec_cache(int file);
 | |
| 
 | |
| 
 | |
| #endif
 | |
| 
 |