campo-sirio/include/multirec.cpp

246 lines
5.6 KiB
C++
Raw Normal View History

#include <multirec.h>
void TMultiple_rectype::set_body_key(TRectype & rowrec)
{
const RecDes* recd = rowrec.rec_des(); // Descrizione del record della testata
const KeyDes& kd = recd->Ky[0]; // Elenco dei campi della chiave 1
// Copia tutti i campi chiave, tranne l'ultimo, in tutti i records
for (int i = kd.NkFields-2; i >= 0; i--)
{
const int nf = kd.FieldSeq[i] % MaxFields;
const RecFieldDes& rf = recd->Fd[nf];
const TString& val = get(rf.Name);
rowrec.renum_key(rf.Name, val);
}
}
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 && ((TMultiple_rectype *)this)->renum())
((TMultiple_rectype *)this)->renum_key();
} while (err == _isreinsert);
((TMultiple_rectype *)this)->_nuovo = (err != NOERR);
}
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(_logicnums[index]);
return (TRecord_array &) _files[index];
}
void TMultiple_rectype::renum_key()
{
for (int i = _nfiles - 1; i >= 0 ; i--)
{
const int logicnum = _logicnums[i];
TRecord_array * b = (TRecord_array *) _files.objptr(i);
if (b)
{
TRectype * rec = new TRectype(b->key());
set_body_key(*rec);
b->set_key(rec); // 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;
}