Aggiunti Multi records
git-svn-id: svn://10.65.10.50/trunk@4510 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
691485d7de
commit
f04d62f7d4
221
include/multirec.cpp
Executable file
221
include/multirec.cpp
Executable file
@ -0,0 +1,221 @@
|
||||
#include <multirec.h>
|
||||
|
||||
void TMultiple_rectype::load_rows_file(int logicnum)
|
||||
{
|
||||
const int index = log2ind(logicnum);
|
||||
TRectype & rec = get_body_record(logicnum);
|
||||
|
||||
set_body_key(rec);
|
||||
TRecord_array * r = new TRecord_array(logicnum, (TString &) _numfields[index]);
|
||||
_files.add( r, index);
|
||||
}
|
||||
|
||||
int TMultiple_rectype::find(int logicnum, const char * fieldname, const char * s, int from, bool reverse) const
|
||||
{
|
||||
const TRecord_array & recarray = body(logicnum);
|
||||
const int last = recarray.last_row();
|
||||
const int len = s ? strlen(s) : 0;
|
||||
|
||||
if (reverse)
|
||||
{
|
||||
if (from > 0)
|
||||
{
|
||||
if (len == 0)
|
||||
return from - 1;
|
||||
for (int i = recarray.pred_row(from); i > 0; i = recarray.pred_row(i))
|
||||
if (recarray[i].get(fieldname) == s)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (last > from)
|
||||
{
|
||||
if (len == 0)
|
||||
return from + 1;
|
||||
for (int i = recarray.succ_row(from); i <= last; i = recarray.succ_row(i))
|
||||
if (recarray[i].get(fieldname) == s)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int TMultiple_rectype::write_rewrite(TBaseisamfile & f, bool re) const
|
||||
{
|
||||
int err = NOERR;
|
||||
|
||||
if (_nuovo && re) // E' nuovo di zecca! quindi ...
|
||||
re = FALSE; // ... non fare la rewrite
|
||||
|
||||
if (re)
|
||||
{
|
||||
for (int i = _nfiles - 1; err == NOERR && i >= 0 ; i--)
|
||||
{
|
||||
TRecord_array * r = (TRecord_array *) _files.objptr(i);
|
||||
if (r)
|
||||
err = r->write(re);
|
||||
}
|
||||
// rewrite:
|
||||
if (err == NOERR)
|
||||
{
|
||||
err = TRectype::rewrite(f);
|
||||
if (err != NOERR)
|
||||
err = TRectype::write(f);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// write:
|
||||
if (_nuovo)
|
||||
{
|
||||
do
|
||||
{
|
||||
err = TRectype::write(f);
|
||||
if (err == _isreinsert) // usa il flag _nuovo per decidere se
|
||||
((TMultiple_rectype *)this)->renum();
|
||||
} while (err == _isreinsert);
|
||||
((TMultiple_rectype *)this)->_nuovo = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
err = TRectype::write(f);
|
||||
if (err != NOERR)
|
||||
err = TRectype::rewrite(f);
|
||||
}
|
||||
for (int i = _nfiles - 1; err == NOERR && i >= 0 ; i--)
|
||||
{
|
||||
TRecord_array * r = (TRecord_array *)_files.objptr(i);
|
||||
if (r)
|
||||
err = r->write(re);
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
void TMultiple_rectype::remove_body(int logicnum)
|
||||
{
|
||||
const int index = log2ind(logicnum);
|
||||
|
||||
if (_files.objptr(index) != NULL)
|
||||
_files.remove(index);
|
||||
}
|
||||
|
||||
int TMultiple_rectype::log2ind(int logicnum) const
|
||||
{
|
||||
if (logicnum == 0)
|
||||
return 0;
|
||||
for (int i = _nfiles - 1; i >= 0 ; i--)
|
||||
if (_logicnums[i] == logicnum)
|
||||
return i;
|
||||
NFCHECK("Can't find file %d in multiple record", logicnum);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TRecord_array & TMultiple_rectype::body(int logicnum) const
|
||||
{
|
||||
const int index = log2ind(logicnum);
|
||||
|
||||
if (_files.objptr(index) == NULL)
|
||||
((TMultiple_rectype *) this)->load_rows_file(logicnum);
|
||||
return (TRecord_array &) _files[index];
|
||||
}
|
||||
|
||||
void TMultiple_rectype::renum_key(const char * kfield,const char * val)
|
||||
{
|
||||
TRectype::renum_key(kfield, val); // Aggiorna testata
|
||||
for (int i = _nfiles - 1; i >= 0 ; i--)
|
||||
body(_logicnums[i]).renum_key(kfield, val); // Aggiorna righe
|
||||
}
|
||||
|
||||
|
||||
TRectype & TMultiple_rectype::operator =(const TRectype & r)
|
||||
{
|
||||
TRectype::operator=(r);
|
||||
reset_fields(*this);
|
||||
set_fields(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
TRectype & TMultiple_rectype::operator =(const char * r)
|
||||
{
|
||||
TRectype::operator=(r);
|
||||
reset_fields(*this);
|
||||
set_fields(*this);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void TMultiple_rectype::zero(char c)
|
||||
{
|
||||
reset_fields(*this);
|
||||
TAuto_variable_rectype::zero(c);
|
||||
for (int i = _nfiles - 1; i >= 0 ; i--)
|
||||
if (_files.objptr(i) != NULL)
|
||||
_files.remove(i);
|
||||
}
|
||||
|
||||
|
||||
int TMultiple_rectype::read(TRectype & rec, word op, word lockop)
|
||||
{
|
||||
TLocalisamfile f(num());
|
||||
|
||||
*this = rec;
|
||||
|
||||
int err = TRectype::read(f, op, lockop);
|
||||
|
||||
for (int i = _nfiles - 1; i >= 0 ; i--)
|
||||
if (_files.objptr(i) != NULL)
|
||||
_files.remove(i);
|
||||
_nuovo = err != NOERR;
|
||||
return err;
|
||||
}
|
||||
|
||||
int TMultiple_rectype::remove(TBaseisamfile & f) const
|
||||
{
|
||||
int err = NOERR;
|
||||
|
||||
for (int i = _nfiles - 1; err == NOERR && i >= 0 ; i--)
|
||||
{
|
||||
TRecord_array & r = body(_logicnums[i]);
|
||||
r.remove();
|
||||
}
|
||||
if (err == NOERR)
|
||||
err = TRectype::remove(f);
|
||||
return err;
|
||||
}
|
||||
|
||||
// @doc INTERNAL
|
||||
TMultiple_rectype::TMultiple_rectype(int hfn)
|
||||
: TAuto_variable_rectype(hfn), _nuovo(TRUE), _nfiles(0)
|
||||
{
|
||||
}
|
||||
|
||||
// @ cmember costruttore dal file
|
||||
void TMultiple_rectype::add_file(int logicnum, const char * numfield)
|
||||
{
|
||||
CHECK(_nfiles < maxfiles, "Too many files added");
|
||||
_logicnums[_nfiles] = logicnum;
|
||||
_numfields.add(numfield, _nfiles++);
|
||||
}
|
||||
|
||||
TMultiple_rectype::TMultiple_rectype(const TBaseisamfile* file)
|
||||
:TAuto_variable_rectype(file), _nuovo(TRUE), _nfiles(0)
|
||||
{
|
||||
}
|
||||
|
||||
// @ cmember costruttore dal record
|
||||
TMultiple_rectype::TMultiple_rectype(const TRectype & rec)
|
||||
:TAuto_variable_rectype(rec), _nuovo(TRUE), _nfiles(0)
|
||||
{
|
||||
}
|
||||
|
||||
// @mfunc costruttore di copia
|
||||
TMultiple_rectype::TMultiple_rectype(const TMultiple_rectype& r)
|
||||
:TAuto_variable_rectype(r), _files(r._files)
|
||||
{
|
||||
// copia..
|
||||
_nuovo=r._nuovo;
|
||||
_nfiles=r._nfiles; // file delle righe
|
||||
_numfields=r._numfields;
|
||||
}
|
||||
|
109
include/multirec.h
Executable file
109
include/multirec.h
Executable file
@ -0,0 +1,109 @@
|
||||
#ifndef __MULTIREC_H
|
||||
#define __MULTIREC_H
|
||||
|
||||
#ifndef __RELATION_H
|
||||
#include <relation.h>
|
||||
#endif
|
||||
|
||||
#ifndef __RECARRAY_H
|
||||
#include <recarray.h>
|
||||
#endif
|
||||
|
||||
#ifndef __VARREC_H
|
||||
#include <varrec.h>
|
||||
#endif
|
||||
|
||||
class TMultiple_rectype ;
|
||||
//**************************************
|
||||
// classe per il controllo dei record composti da una testata e N file di righe
|
||||
// è implementato come un TRectype che contiene anche un TRecord_array
|
||||
//
|
||||
class TMultiple_rectype : public TAuto_variable_rectype
|
||||
{
|
||||
enum { maxfiles = 20};
|
||||
// @ cmember Array di TRecord array per le righe
|
||||
TArray _files; //
|
||||
// @ cmember flag indicatore di record nuovo
|
||||
bool _nuovo;
|
||||
// @ cmember numero di file righe
|
||||
short _nfiles;
|
||||
// @ cmember file delle righe
|
||||
int _logicnums[maxfiles];
|
||||
// @ cmember Array di nomi di campo "numeratore" delle righe
|
||||
TString_array _numfields;
|
||||
|
||||
|
||||
protected:
|
||||
const TArray & files() const { return _files;}
|
||||
// @ cmember funzione per costruire la chiave delle righe
|
||||
virtual void set_body_key(TRectype & rowrec) pure;
|
||||
// @ cmember renumber la chiave del corpo
|
||||
virtual long renum(long numdoc = -1) { return -1; }
|
||||
virtual TRectype & get_body_record(int logicnum = 0) { return *(new TRectype(logicnum ? logicnum : _logicnums[0])); }
|
||||
virtual void load_rows_file(int logicnum);
|
||||
// @cmember Ritorna l'indice di <p _files> del numero logico passato
|
||||
int log2ind(int logicnum) const;
|
||||
virtual int find(int logicnum, const char * fieldname, const char * s, int from = 0, bool reverse = FALSE) const ;
|
||||
virtual int write_rewrite(TBaseisamfile& f, bool re = FALSE) const;
|
||||
void remove_body(int logicnum);
|
||||
|
||||
public:
|
||||
//***********************
|
||||
// struttura
|
||||
// @ cmember restituisce il record di testata
|
||||
const TAuto_variable_rectype& head() const { return *this; } // Ritorna la testata del documento
|
||||
// @ cmember restituisce il record di testata
|
||||
TAuto_variable_rectype& head() { return *this; } // Ritorna la testata del documento
|
||||
|
||||
|
||||
// @ cmember restituisce il record array del corpo
|
||||
TRecord_array & body(int logicnum = 0) const;
|
||||
// @ cmember restituisce il numero di record nel corpo
|
||||
int rows(int logicnum = 0) const { return body(logicnum).rows(); }
|
||||
|
||||
// @ cmember restituisce il record n-esimo del del corpo
|
||||
virtual const TRecord_array & operator[](int logicnum) const { return (const TRecord_array &)((TMultiple_rectype *)this)->body(logicnum); }
|
||||
// @ cmember restituisce il record n-esimo del del corpo
|
||||
virtual TRecord_array & operator[](int logicnum) { return (TRecord_array &)body(logicnum); }
|
||||
|
||||
bool destroy_row(int n, bool pack = FALSE, int logicnum = 0) { return body(logicnum).destroy_row(n, pack); }
|
||||
void destroy_rows(int logicnum = 0) { body(logicnum).destroy_rows(); }
|
||||
|
||||
//***********************
|
||||
// record e I/O
|
||||
virtual void dirty_fields() {}
|
||||
virtual void set_fields(TAuto_variable_rectype & rec) {}
|
||||
virtual void reset_fields(TAuto_variable_rectype & rec) { rec.remove_field(); }
|
||||
|
||||
virtual void renum_key(const char * kfield,const char * val);
|
||||
virtual TRectype & operator =(const TRectype & r);
|
||||
virtual TRectype & operator =(const char * r);
|
||||
virtual void zero(char c = '\0');
|
||||
|
||||
virtual int read(TRectype & rec, word op = _isequal, word lockop = _nolock);
|
||||
virtual int read(word op = _isequal, word lockop = _nolock) { return read(*this, op, lockop); }
|
||||
int read(TBaseisamfile & f, word op = _isequal, word lockop = _nolock) { return read(f.curr(), op, lockop); }
|
||||
|
||||
virtual int write(TBaseisamfile& f) const;
|
||||
virtual int rewrite(TBaseisamfile& f) const;
|
||||
virtual int remove(TBaseisamfile& f) const;
|
||||
|
||||
int write() const { TBaseisamfile f(num()); return write(f);}
|
||||
int rewrite() const { TBaseisamfile f(num()); return rewrite(f);}
|
||||
int remove() const { TBaseisamfile f(num()); return remove(f);}
|
||||
|
||||
|
||||
void add_file(int logicnum, const char * numfield);
|
||||
//**************************
|
||||
// @ cmember costruttore dal numero del file
|
||||
TMultiple_rectype(int hfn);
|
||||
// @ cmember costruttore dal file
|
||||
TMultiple_rectype(const TBaseisamfile* file);
|
||||
// @ cmember costruttore dal record
|
||||
TMultiple_rectype(const TRectype & rec);
|
||||
// @ cmember costruttore di copia
|
||||
TMultiple_rectype(const TMultiple_rectype& r);
|
||||
virtual ~TMultiple_rectype() {}
|
||||
};
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user