guy 76719be75d isam.cpp Aggiunta funzione per costruire la stringa chiave da un record
isam.h       Aggiunti prototipo funzione precedente
maskfld.h    Aggiunta funzione per settare il modo di trim dei campi
relation.cpp Aggiunto codice di debug nella TRecord_array::remove_from


git-svn-id: svn://10.65.10.50/trunk@2125 c028cbd2-c16b-5b4b-a496-9718f37d4682
1995-11-10 13:37:28 +00:00

521 lines
17 KiB
C++
Executable File

#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
#ifndef __TEXT_H
class TTextfile;
#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
bool _isempty; // Se il record e' vuoto
char _tab[5]; // identificatore della tabella
TRecfield * _cod; // campo "COD" della tabella
// @END
protected: // TObject
virtual int compare(const TSortable& s) const;
protected:
const char* start(int nf) const;
void setempty(bool val) { _isempty = val;} // Rende vero is_empty
public: // TObject
virtual TObject* dup() const; // Duplica record
virtual int read(TBaseisamfile& f, word op = _isequal);
virtual int next(TBaseisamfile& f);
virtual int write(TBaseisamfile& f) const;
virtual int rewrite(TBaseisamfile& f) const;
virtual int remove(TBaseisamfile& f) const;
virtual void renum_key(const char* field, const char* val);
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 = '*';} // Setta il flag di cancellazione
void recall() { *_rec = ' ';} // Ripristina il flag di cancellazione
bool isdeleted() const { return *_rec == '*';} // 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
const char* build_key(int key = 1) const;
int compare_key(const TRectype& rec, int key = 1) const;
bool same_key(const TRectype& rec, int key = 1) const { return compare_key(rec, key) == 0; }
const char* get_str(const char* fieldname) const ;
#ifndef FOXPRO
const TString& get(const char* fieldname) const ;
TString sget(const char* fieldname) const { return ((TString)get(fieldname)); }
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 ;
bool get_memo(const char* fieldname, TTextfile& txt) const ;
#endif
TDate get_date(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);
void put(const char* fieldname, TTextfile& txt);
#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
void blank(const char * fieldname) { put(fieldname, " "); } // Riempie il campo di spazi
TRectype& operator =(const TRectype& rec); // assegnazione tra TRectype
TRectype& operator =(const char* rec); // assegnazione tra TRectype
TRectype& operator =(const TBaseisamfile& f);
virtual RecDes* rec_des() const; // Ritorna il descrittore del record
int num() const { return _logicnum;} // Ritorna il numero logico
bool empty() const {return _isempty;} // Ritorna se e' vuoto
bool valid() const {return _rec[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 _rec != 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 ;
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);}
bool get_memo(const char* fieldname, TTextfile& txt)
{ return curr().get_memo(fieldname, txt); }
#endif
TDate get_date(const char* fieldname) const
{ return curr().get_date(fieldname);}
#ifndef FOXPRO
const TString& get(const char* fieldname) const
{ return curr().get(fieldname);}
TString sget(const char* fieldname) const
{ return ((TString)get(fieldname)); }
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);}
void put(const char* fieldname, TTextfile& txt)
{ curr().put(fieldname, txt); }
#else
const char* get_str(const char* fieldname) const
{ return curr().get_str(fieldname);}
#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);}
void blank(const char * fieldname) { curr().blank(fieldname); }
TRectype& operator =(const TRectype& rec) { return curr() = rec;}
TBaseisamfile(int logicnum, bool linkrecinst = FALSE);
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);
virtual ~TIsamfile();
};
// @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 pack(bool vis = TRUE); // Esegue packfile e packindex
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 = FALSE)
: 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
int _oldkey; // Old key if already open
protected:
int open(unsigned int mode = _manulock);
int close() ;
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
virtual bool tab() const { return FALSE;} // Ritorna vero se tabella
// Costruttore. linkrecinst dice se il file deve utilizzare un area record separata oppure la stessa.
TLocalisamfile(int logicnum, bool linkrecinst = FALSE);
virtual ~TLocalisamfile();
};
// @C
// Classe TIsamtempfile : public TLocalisamfile
//
// File isam temporaneo
//
// @END
class TIsamtempfile : public TLocalisamfile
{
bool _autodel; // Settato a true se create = 2: cancella il file in chiusura
protected:
// 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 open(const char* radix, bool create, TRecnotype eod, TRecnotype eox);
int close();
public:
void set_autodel(bool val=TRUE) {_autodel = val;}
TIsamtempfile(int logicnum, const char* radix, bool create);
virtual ~TIsamtempfile();
};
// @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);
};
/*
class TTransaction
{
public:
// @FPUB
void begin();
void end(bool success = TRUE);
void abort() { end(FALSE);}
};
*/
#ifdef __ISAM_CPP
#define extern
#endif
// @DPUB
extern TRectype** openrec;
extern void get_idx_names(int logicnum, TToken_string& i_names);
// @END
#undef extern
void set_autoload_new_files(bool on);
#endif // __ISAM_