1994-12-28 11:01:33 +00:00
# ifndef __ISAM_H
# define __ISAM_H
# ifndef __SYSFLD_H
# include <sysfld.h>
# endif
# ifndef FOXPRO
# ifndef __REAL_H
# include <real.h>
# endif
# endif
# ifndef __DATE_H
# include <date.h>
# endif
# ifndef __STRINGS_H
# include <strings.h>
# endif
# ifndef __FILES_H
# include <files.h>
# endif
# ifndef __LFFILES_H
# include <lffiles.h>
# endif
// @M
# define FIELDERR -1
const int MAX_KEYS = 8 ;
// @END
// @C
// Classe TRectype : public TObject
//
// Tipo record
//
// @END
class TRectype : public TSortable
{
friend class TExtrectype ;
friend class TRecfield ;
friend class TBaseisamfile ;
friend class TLocalisamfile ;
friend class TIsamtempfile ;
// DPRIV
char * _rec ; // Puntatore a inizio record
int _logicnum ; // Numero logico
int _length ; // Lunghezza
isdef * _i ; // Puntatore al file isam
bool _isempty ; // Se il record e' vuoto
char _tab [ 5 ] ; // identificatore della tabella
TRecfield * _cod ; // campo "COD" della tabella
// @END
protected :
// FPROT
const char * start ( int nf ) const ;
void setempty ( bool val ) { _isempty = val ; } // Rende vero is_empty
virtual TObject * dup ( ) const ; // Duplica record
virtual int compare ( const TSortable & s ) const ;
// @END
public :
// FPUB
int items ( ) const ;
void setdirty ( ) { setempty ( FALSE ) ; }
void settab ( const char * tab ) ;
char * string ( ) const { return _rec ; } // Ritorna il puntatore all'inizio. NON dovrebbe essere usata!
void discard ( ) { * _rec = char ( _deleted ) ; } // Setta il flag di cancellazione
void recall ( ) { * _rec = char ( _valid ) ; } // Ripristina il flag di cancellazione
bool isdeleted ( ) const { return * _rec = = _deleted ; } // Chiede se e' cancellato
int len ( ) const { return _length ; } // Ritorna la lunghezza
TFieldtypes type ( const char * fieldname ) const ; // Ritorna il tipo del campo
int length ( const char * fieldname ) const ; // Ritorna lunghezza campo
int ndec ( const char * fieldname ) const ; // Ritorna numero di decimali
bool exist ( const char * fieldname ) const ; // Ritorna l'esistenza del campo
const char * fieldname ( int i ) const ; // Ritorna il nome del campo i
// @DES Get tipizzata. Ritorna il contenuto del campo nei vari tipi
// @FPUB
# ifndef FOXPRO
int get_int ( const char * fieldname ) const ;
long get_long ( const char * fieldname ) const ;
word get_word ( const char * fieldname ) const ;
char get_char ( const char * fieldname ) const ;
bool get_bool ( const char * fieldname ) const ;
real get_real ( const char * fieldname ) const ;
# endif
TDate get_date ( const char * fieldname ) const ;
// @DES Get non tipizzata. Il campo e' ritornato come TString&
// @FPUB
const TString & get ( const char * fieldname ) const ;
// @DES Put tipizzata
// @FPUB
# ifndef FOXPRO
void put ( const char * fieldname , int val ) ;
void put ( const char * fieldname , long val ) ;
void put ( const char * fieldname , word val ) ;
void put ( const char * fieldname , const TDate & val ) ;
void put ( const char * fieldname , char val ) ;
void put ( const char * fieldname , bool val ) ;
void put ( const char * fieldname , const real & val ) ;
# endif
// @DES Put NON tipizzata
// @FPUB
void put ( const char * fieldname , const char * val ) ;
// void put(const char* fieldname, TString& val);
void zero ( const char * fieldname ) ; // Vuota campo puntato da fieldname
void zero ( ) ; // Vuota tutto il record
void zero ( char c ) ; // Vuota tutto il record usando il carattere c
TRectype & operator = ( const TRectype & rec ) ; // assegnazione tra TRectype
TRectype & operator = ( const char * rec ) ; // assegnazione tra TRectype
TRectype & operator = ( const TBaseisamfile & f ) ;
const isdef * filehnd ( ) const { return _i ; } // Ritorna il file isam associato
int num ( ) const { return _logicnum ; } // Ritorna il numero logico
bool empty ( ) const { return _isempty ; } // Ritorna se e' vuoto
bool valid ( ) const { return _rec [ 0 ] = = 0 ; } // Ritorna se il record non e'cancellato
const char * key ( int numkey = 1 ) const ; // Ritorna l'espressione della chiave numero numkey
bool ok ( ) const { return _i ! = NULL ; }
TRectype ( int logicnum ) ; // Costruisce un record staccato da un file. Bisogna poi chiamare linkfile(). Sarebbe meglio utilizzare una delle altre due
TRectype ( const TBaseisamfile * i ) ; // Costruisce record e lo associa al file isam i
TRectype ( const TRectype & r ) ; // Costruisce il record a partire da r
virtual ~ TRectype ( ) ;
} ;
// @C
// Classe TBaseisamfile : public TObject
//
// File isam di base
//
// @END
class TBaseisamfile : public TObject
{
// @DPRIV
isdef * _isamfile ; // Descrittore file isam
int _logicnum ; // Numero logico del record corrente
int _lasterr ; // Ultimo errore
bool _delrec ; // Per sapere se rimuovere il record alla fine
bool _delopenrec ; // Per sapere se rimuovere il record alla fine dalla lista interna di record
TRectype * _current ; // Puntatore a record corrente
TFile _hf ;
TFile _hfhd ;
bool _historicfile ; // Vero se il file e' archivio storico
TRecnotype _lasthf ;
TRecnotype _recno ;
friend class TRectype ;
friend class TLocalisamfile ;
friend class TIsamfile ;
friend class TIsamtempfile ;
friend class TRecfield ;
// friend class TCursor;
// @END
// @FPRIV
// friend TRecnotype __buildcursor(TFilecursor* tic, TRecnotype rp);
// friend TRecnotype __filtercursor(TFilecursor* tic);
// friend bool __evalcondition(TBaseisamfile* i,TString& condition);
// friend void __readrec(TFilecursor* tic);
int gethr ( TRectype & rec , TDate & atdate ) ;
int addhr ( const TRectype & rec , TDate & atdate ) ;
int rewhr ( const TRectype & rec , TDate & atdate ) ;
int delhr ( const TRectype & rec , TDate & atdate ) ;
protected :
// @FPROT
isdef * * ptrfilehnd ( ) const { return ( isdef * * ) & _isamfile ; }
void clearfilehnd ( ) { _isamfile = NULL ; }
void recover ( ) ;
int _open ( unsigned int mode = _manulock ) ; // Apre isam file con lock
int _close ( ) ;
const char * filename ( ) const ;
public :
// @FPUB
void setkey ( int nkey ) ; // Attiva una chiave
int getkey ( ) const ; // Ritorna la chiave
void setstatus ( int status ) { _lasterr = status ; } // Setta _lasterr
virtual int first ( word lockop = _nolock ) ;
virtual int last ( word lockop = _nolock ) ;
virtual int next ( word lockop = _nolock ) ;
virtual int next ( TDate & atdate ) ;
virtual int prev ( word lockop = _nolock ) ;
virtual int prev ( TDate & atdate ) ;
virtual int reread ( word lockop = _nolock , TDate & atdate = ( TDate & ) botime ) ;
virtual int reread ( TRectype & rec , word lockop = _nolock , TDate & atdate = ( TDate & ) botime ) ;
virtual int skip ( TRecnotype nrec , word lockop = _nolock ) ;
virtual int read ( word op = _isequal , word lockop = _nolock , TDate & atdate = ( TDate & ) botime ) ;
virtual int read ( TRectype & rec , word op = _isequal , word lockop = _nolock , TDate & atdate = ( TDate & ) botime ) ;
virtual int readat ( TRecnotype nrec , word lockop = _nolock ) ;
virtual int readat ( TRectype & rec , TRecnotype nrec , word lockop = _nolock ) ;
virtual int write ( TDate & atdate = ( TDate & ) botime ) ;
virtual int write ( const TRectype & rec , TDate & atdate = ( TDate & ) botime ) ;
virtual int rewrite ( TDate & atdate = ( TDate & ) botime ) ;
virtual int rewrite ( const TRectype & rec , TDate & atdate = ( TDate & ) botime ) ;
virtual int rewriteat ( TRecnotype nrec ) ;
virtual int rewriteat ( const TRectype & rec , TRecnotype nrec ) ;
virtual int remove ( TDate & atdate = ( TDate & ) botime ) ;
virtual int remove ( const TRectype & rec , TDate & atdate = ( TDate & ) botime ) ;
virtual const char * name ( ) const ;
TRecnotype recno ( ) const { return _recno ; }
int lock ( ) ; // Attiva lock di tutto il file
int unlock ( ) ; // Disattiva lock di tutto il file
void indexon ( ) ; // Accende gli indici
void indexoff ( ) ; // Spegne gli indici
int status ( ) const { return _lasterr ; } // Ritorna _lasterr
TRectype & curr ( ) const { return * _current ; } // Ritorna puntatore a record corrente
bool eof ( ) const { return status ( ) = = _iseof | | status ( ) = = _isemptyfile ; } // Vero se siamo a fine file
bool bof ( ) const { return status ( ) = = _isbof | | status ( ) = = _isemptyfile ; } // Vero se siamo a inizio file
bool good ( ) const { return status ( ) = = NOERR ; } // Vero se _lasterr non contiene codici d'errore
bool bad ( ) const { return status ( ) ! = NOERR ; } // Vero se _lasterr contiene codici d'errore
bool empty ( ) ; // Vero se il file e' vuoto
int num ( ) const { return _logicnum ; } // Ritorna il numero logico del record corrente
const char * description ( ) const ;
TRecnotype eod ( ) const { return filehnd ( ) - > d - > EOD ; }
isdef * filehnd ( ) const { return ( isdef * ) _isamfile ; } // Ritorna l'handle del file isam nella tabella
long items ( ) const ; // n.o di records nel file
// @DES Get tipizzata. Ritorna il contenuto del campo nei vari tipi
// @FPUB
# ifndef FOXPRO
int get_int ( const char * fieldname ) const
{ return curr ( ) . get_int ( fieldname ) ; }
long get_long ( const char * fieldname ) const
{ return curr ( ) . get_long ( fieldname ) ; }
word get_word ( const char * fieldname ) const
{ return curr ( ) . get_word ( fieldname ) ; }
char get_char ( const char * fieldname ) const
{ return curr ( ) . get_char ( fieldname ) ; }
bool get_bool ( const char * fieldname ) const
{ return curr ( ) . get_bool ( fieldname ) ; }
real get_real ( const char * fieldname ) const
{ return curr ( ) . get_real ( fieldname ) ; }
# endif
TDate get_date ( const char * fieldname ) const
{ return curr ( ) . get_date ( fieldname ) ; }
// @DES Get non tipizzata. Il campo e' ritornato come TString&
// @FPUB
const TString & get ( const char * fieldname ) const
{ return curr ( ) . get ( fieldname ) ; }
// @DES Put NON tipizzata
// @FPUB
# ifndef FOXPRO
void put ( const char * fieldname , int val )
{ curr ( ) . put ( fieldname , val ) ; }
void put ( const char * fieldname , long val )
{ curr ( ) . put ( fieldname , val ) ; }
void put ( const char * fieldname , word val )
{ curr ( ) . put ( fieldname , val ) ; }
void put ( const char * fieldname , const TDate & val )
{ curr ( ) . put ( fieldname , val ) ; }
void put ( const char * fieldname , char val )
{ curr ( ) . put ( fieldname , val ) ; }
void put ( const char * fieldname , bool val )
{ curr ( ) . put ( fieldname , val ) ; }
void put ( const char * fieldname , const real & val )
{ curr ( ) . put ( fieldname , val ) ; }
# endif
// @DES Put NON tipizzata
// @FPUB
void put ( const char * fieldname , const char * val )
{ curr ( ) . put ( fieldname , val ) ; }
void zero ( const char * fieldname ) { curr ( ) . zero ( fieldname ) ; }
void zero ( ) { curr ( ) . zero ( ) ; }
void zero ( char c ) { curr ( ) . zero ( c ) ; }
TRectype & operator = ( const TRectype & rec ) { return curr ( ) = rec ; }
TBaseisamfile ( int logicnum , bool linkrecinst = TRUE ) ;
virtual ~ TBaseisamfile ( ) ;
} ;
// @C
// Classe TIsamfile : public TBaseisamfile
//
// File isam
//
// @END
class TIsamfile : public TBaseisamfile
{
public :
// @FPUB
int flags ( bool updateeod = FALSE ) ;
int open ( unsigned int mode = _manulock ) { return _open ( mode ) ; } // Apre isam file con lock
int close ( ) { return _close ( ) ; }
TIsamfile ( int logicnum , bool linkrecinst = TRUE ) ;
virtual ~ TIsamfile ( ) ;
} ;
// @C
// Classe TIsamtempfile : public TBaseisamfile
//
// File isam temporaneo
//
// @END
class TIsamtempfile : public TBaseisamfile
{
public :
// @FPUB
int open ( char * radix , bool create = TRUE , TRecnotype eod = 0 ,
TRecnotype eox = 100 ) ; // Apre il file. radix e' la radice del path del file, se create e' falso vuol dire che il file esiste gia', e allora eod dice quanti record ci sono; eox quanti bisogna aggiungerne
int close ( bool flagdel = TRUE ) ; // Chiude il file e se e' vero flagdel lo cancella
TIsamtempfile ( int logicnum , bool linkrecinst = FALSE ) ;
virtual ~ TIsamtempfile ( ) ;
} ;
// @C
// Classe TSystemisamfile : public TBaseisamfile
//
// @END
class TSystemisamfile : public TIsamfile
{
TArray _flds ;
TArray _exps ;
bool getlcf ( long flev ) ;
bool exec_convapp ( long flev , const bool before ) ;
void makelc ( TRectype & rec ) ;
public :
// @FPUB
int build ( TRecnotype eox ) ; // Costruisce un file isam
int extend ( TRecnotype eox ) ; // Estende un file preesistente
long size ( TRecnotype eox ) ; // Calcola lo spazio che il file occuperebbe se venisse esteso a eox
int update ( TTrec & newrec , bool vis = TRUE ) ;
int packfile ( bool vis = TRUE ) ; // Rimuove fisicamente i record cancellati
int packindex ( bool vis = TRUE ) ; // La stessa cosa sugli indici
// @DES Importa un file ascii. from e' il nome del file da importare
int load ( const char * from , char fs = ' | ' , char fd = ' \0 ' , char rs = ' \n ' , bool vis = TRUE , bool extended = FALSE ) ;
// @DES Esporta VERSO un file ascii.
int dump ( const char * to , int nkey = 1 , char fs = ' | ' , char fd = ' \0 ' , char rs = ' \n ' , bool vis = TRUE , bool withdeleted = FALSE ) ;
TSystemisamfile ( int logicnum , bool linkrecinst = TRUE )
: TIsamfile ( logicnum , linkrecinst ) { }
virtual ~ TSystemisamfile ( ) { }
} ;
// @C
// Classe TLocalisamfile : public TBaseisamfile
//
// @END
class TLocalisamfile : public TBaseisamfile
{
// @DPRIV
bool _was_open ; // Vero se il file e' stato aperto come Localisamfile
bool _isatab ; // Vero se il file e' una tabella
public :
// @FPUB
virtual int operator + = ( const TRecnotype npos ) ; // Avanza npos record
virtual int operator - = ( const TRecnotype npos ) ; // Sposta indietro di npos
virtual int operator + + ( ) ; // record successivo
virtual int operator - - ( ) ; // record precedente
bool tab ( ) const { return _isatab ; } // Ritorna vero se tabella
void settab ( bool fl = FALSE ) { _isatab = fl ; } // Setta il flag _isatab
int open ( unsigned int mode = _manulock ) ;
int close ( ) ;
// Costruttore. linkrecinst dice se il file deve utilizzare un area record separata oppure la stessa.
TLocalisamfile ( int logicnum , bool linkrecinst = TRUE ) ;
virtual ~ TLocalisamfile ( ) ;
} ;
// @C
// Classe TRec_array : public TArray
//
// @END
class TRec_array : public TArray
{
public :
// @FPUB
TRec_array ( int dimension , TBaseisamfile & i ) ;
} ;
// @C
// Classe TRecfield : public TObject
//
// @END
class TRecfield : public TObject
{
// @DPRIV
char _name [ 12 ] ; // Nome campo
TRectype * _rec ; // Puntatore a inizio record
char * _p ; // Puntatore a inizio campo
byte _len ; // Lunghezza campo
byte _dec ; // Numero di decimali
byte _type ; // Tipo del campo
// @END
// @FPRIV
void set ( int from , int to ) ;
public :
// @FPUB
// @DES Operatore di assegnazione (=) per i vari tipi
// @FPUB
int operator = ( int i ) ;
long operator = ( long l ) ;
const TDate & operator = ( const TDate & d ) ;
const char * operator = ( const char * s ) ;
# ifndef FOXPRO
const real & operator = ( const real & r ) ;
# endif // FOXPRO
// @DES Operatore di estrazione per i vari tipi
// @FPUB
operator int ( ) const ;
operator long ( ) const ;
operator const char * ( ) const ;
operator TDate ( ) const ;
# ifndef FOXPRO
operator const real ( ) const ;
# endif // FOXPRO
void setptr ( TRecnotype r ) ; // Scrive un campo packed. Sarebbe meglio non usare mai campi packed.
TRecnotype ptr ( ) const ; // Legge un campo packed. Sarebbe meglio non usare mai campi packed.
const char * pos ( ) const { return ( const char * ) _p ; } // Ritorna un puntatore all'inizio del campo nel record. Dovrebbe essere protected!
int len ( ) const { return ( int ) _len ; } // Ritorna la lunghezza
int dec ( ) const { return ( int ) _dec ; } // Ritorna il numero di decimali
TFieldtypes type ( ) const { return ( TFieldtypes ) _type ; } // Ritorna il tipo del campo
TRectype & record ( ) const { return * _rec ; } // Ritorna puntatore a inizio record
TRecfield ( TRectype & rec , const char * name , int from = 0 , int to = - 1 ) ;
} ;
// @C
// Classe TTransaction
//
// @END
class TTransaction
{
public :
// @FPUB
void begin ( ) ;
void end ( bool success = TRUE ) ;
void abort ( ) { end ( FALSE ) ; }
} ;
# ifdef __ISAM_CPP
# define extern
# endif
// @DPUB
extern TTransaction transaction ;
extern TRectype * * openrec ;
// @END
# undef extern
void set_autoload_new_files ( bool on ) ;
# endif // __ISAM_