572 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			572 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
// **************************************
 | 
						||
// **************************************
 | 
						||
// **************************************
 | 
						||
// *** classi per la libreria 
 | 
						||
// ***
 | 
						||
//*****
 | 
						||
#include <tabutil.h>
 | 
						||
#include "mglib.h"
 | 
						||
/*
 | 
						||
 | 
						||
 | 
						||
 | 
						||
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 (((TRectype &)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 (((TRectype &)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;   
 | 
						||
}
 | 
						||
 | 
						||
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);
 | 
						||
}
 | 
						||
 | 
						||
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; 
 | 
						||
}
 | 
						||
*/
 | 
						||
 | 
						||
// THead_lines_record 
 | 
						||
// metodi protected
 | 
						||
/*
 | 
						||
void THead_lines_record::renum_key(const char * kfield,const char * val)
 | 
						||
{
 | 
						||
  TRectype::renum_key(kfield, val);       // Aggiorna testata
 | 
						||
  _rows->renum_key(kfield, val); // Aggiorna righe  
 | 
						||
}
 | 
						||
 | 
						||
TRectype & THead_lines_record::row(int index) const  // riga del corpo
 | 
						||
{
 | 
						||
  if (index > _rows->rows() || index < 0)
 | 
						||
    CHECKD(FALSE, "Riga non esistente ", index);
 | 
						||
  return _rows->row(index, FALSE);
 | 
						||
}
 | 
						||
 | 
						||
void THead_lines_record::put_str(const char* fieldname, const char* val)
 | 
						||
{          
 | 
						||
  TString v(val);
 | 
						||
  // cambio 
 | 
						||
  //if (strcmp(fieldname, "TIPODOC") == 0 && TRectype::get("TIPODOC") != v)
 | 
						||
  //{
 | 
						||
  //  TAuto_variable_rectype::put_str(fieldname, v);
 | 
						||
  //  reset_fields(*this);
 | 
						||
  //  set_fields(*this);
 | 
						||
  //}
 | 
						||
  //else          
 | 
						||
  {
 | 
						||
    TAuto_variable_rectype::put_str(fieldname, v);
 | 
						||
    dirty_fields();                                
 | 
						||
  }
 | 
						||
}
 | 
						||
 | 
						||
//*****
 | 
						||
// metodi public
 | 
						||
THead_lines_record::THead_lines_record(int hfn, int rfn,const char *numfield):
 | 
						||
  TAuto_variable_rectype(hfn),
 | 
						||
  _file(hfn),
 | 
						||
  _rfile(rfn),
 | 
						||
  _numfield(numfield)
 | 
						||
{
 | 
						||
  _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe
 | 
						||
}
 | 
						||
 | 
						||
THead_lines_record::THead_lines_record(const TBaseisamfile* i,int rfn,const char *numfield):
 | 
						||
  TAuto_variable_rectype(i),
 | 
						||
  _numfield(numfield)
 | 
						||
{
 | 
						||
  _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe
 | 
						||
}
 | 
						||
 | 
						||
THead_lines_record::THead_lines_record(const TRectype & r,int rfn,const char *numfield):
 | 
						||
  TAuto_variable_rectype(r),
 | 
						||
  _numfield(numfield)
 | 
						||
{
 | 
						||
  _rows= new TRecord_array(rfn,numfield); // inizializza il record array delle righe
 | 
						||
}
 | 
						||
 | 
						||
// @doc INTERNAL
 | 
						||
 | 
						||
// @mfunc costruttore di copia
 | 
						||
THead_lines_record::THead_lines_record(const THead_lines_record& r):
 | 
						||
  TAuto_variable_rectype((TAuto_variable_rectype &)r)
 | 
						||
{
 | 
						||
  // copia..
 | 
						||
  _rows= new TRecord_array(* r._rows); // inizializza il record array delle righe
 | 
						||
  _nuovo=r._nuovo;
 | 
						||
  _file=r._file;    // file principale  
 | 
						||
  _rfile=r._rfile;    // file delle righe
 | 
						||
  _numfield=r._numfield; 
 | 
						||
}
 | 
						||
 | 
						||
THead_lines_record::~THead_lines_record() 
 | 
						||
{
 | 
						||
  delete _rows;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
// setta a dirty i campi
 | 
						||
void THead_lines_record::dirty_fields()
 | 
						||
{
 | 
						||
}
 | 
						||
 | 
						||
TRectype & THead_lines_record::operator =(const TRectype & r) 
 | 
						||
{
 | 
						||
  TRectype::operator=(r); 
 | 
						||
  reset_fields(*this);
 | 
						||
  set_fields(*this);
 | 
						||
  return *this;
 | 
						||
}
 | 
						||
                                   
 | 
						||
TRectype & THead_lines_record::operator =(const char * r) 
 | 
						||
{
 | 
						||
  TRectype::operator=(r); 
 | 
						||
  reset_fields(*this);
 | 
						||
  set_fields(*this);
 | 
						||
  return *this;
 | 
						||
}
 | 
						||
 | 
						||
void THead_lines_record::zero(const char * fieldname)
 | 
						||
{
 | 
						||
  // resetta il record righe solo se .....
 | 
						||
//  if (strcmp(fieldname, "TIPODOC") == 0)
 | 
						||
    reset_fields(*this);
 | 
						||
  TAuto_variable_rectype::zero(fieldname);
 | 
						||
  dirty_fields();
 | 
						||
}
 | 
						||
 | 
						||
void THead_lines_record::zero(char c)
 | 
						||
{
 | 
						||
  reset_fields(*this);
 | 
						||
  TAuto_variable_rectype::zero(c);
 | 
						||
}
 | 
						||
                                   
 | 
						||
 | 
						||
// settaggio campi variabili
 | 
						||
void THead_lines_record::set_fields(TAuto_variable_rectype & rec)
 | 
						||
{
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
int THead_lines_record::read(TBaseisamfile& f, word op, word lockop)
 | 
						||
{
 | 
						||
  TRectype line_key(_rfile);
 | 
						||
 | 
						||
  int err = TRectype::read(f,op,lockop);
 | 
						||
 | 
						||
  copy_linekey(head(),line_key);
 | 
						||
  if (err == NOERR)
 | 
						||
  {
 | 
						||
    _nuovo = FALSE;
 | 
						||
    _rows->read(line_key); //ok
 | 
						||
  }  
 | 
						||
  else
 | 
						||
  {
 | 
						||
    // nuovo oggetto: resetta tutto
 | 
						||
    _nuovo = TRUE;
 | 
						||
    destroy_rows();
 | 
						||
    _rows->set_key((TRectype *)(line_key.dup()));  // ok
 | 
						||
  }
 | 
						||
  return err;
 | 
						||
}
 | 
						||
 | 
						||
int THead_lines_record::readat(TBaseisamfile& f, TRecnotype nrec, word lockop)
 | 
						||
{
 | 
						||
  TRectype line_key(_rfile);
 | 
						||
 | 
						||
  int err = TRectype::readat(f,nrec,lockop);
 | 
						||
 | 
						||
  if (err == NOERR)
 | 
						||
  {
 | 
						||
    _nuovo = FALSE;
 | 
						||
    _rows->read(line_key); //ok
 | 
						||
  }  
 | 
						||
  else
 | 
						||
  {
 | 
						||
    // nuovo oggetto: resetta tutto
 | 
						||
    _nuovo = TRUE;
 | 
						||
    destroy_rows();
 | 
						||
    _rows->set_key((TRectype *)(line_key.dup()));  // ok
 | 
						||
  }
 | 
						||
  return err;
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
/*int THead_lines_record::read(const TRectype& rec)
 | 
						||
{
 | 
						||
  head() = rec;  
 | 
						||
  TRectype line_key(_rows->key());
 | 
						||
 | 
						||
  copy_linekey(head(),line_key);
 | 
						||
  
 | 
						||
  TLocalisamfile afile(_file);        
 | 
						||
  int err = TRectype::read(afile);
 | 
						||
  if (err == NOERR)
 | 
						||
  {
 | 
						||
    _nuovo = FALSE;
 | 
						||
    _rows->read(line_key); //ok
 | 
						||
  }  
 | 
						||
  else
 | 
						||
  {
 | 
						||
    // nuovo oggetto: resetta tutto
 | 
						||
    _nuovo = TRUE;
 | 
						||
    head() = rec;
 | 
						||
    destroy_rows();
 | 
						||
    _rows->set_key(&line_key);  // ok
 | 
						||
  }
 | 
						||
  return err;
 | 
						||
} 
 | 
						||
int THead_lines_record::write(TBaseisamfile& f) const 
 | 
						||
{
 | 
						||
  return write_rewrite(f,FALSE);
 | 
						||
}
 | 
						||
 | 
						||
int THead_lines_record::rewrite(TBaseisamfile& f) const 
 | 
						||
{
 | 
						||
  return write_rewrite(f,TRUE);
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
int THead_lines_record::write_rewrite(TBaseisamfile& f,bool re ) const 
 | 
						||
{              
 | 
						||
  const bool nuovo = _nuovo;  // E' nuovo di zecca!
 | 
						||
  if (nuovo && re)                             // quindi ...
 | 
						||
    re = FALSE;                                // ... non fare la rewrite
 | 
						||
 | 
						||
  int err = NOERR;
 | 
						||
  if (re)
 | 
						||
  {
 | 
						||
    // rewrite:
 | 
						||
    err = _rows->write(re); 
 | 
						||
    if (err == NOERR)
 | 
						||
    {
 | 
						||
      err = TRectype::rewrite(f);
 | 
						||
      if (err != NOERR)
 | 
						||
        err = TRectype::write(f);
 | 
						||
    }    
 | 
						||
  }
 | 
						||
  else
 | 
						||
  {             
 | 
						||
    // write:
 | 
						||
    if (nuovo)
 | 
						||
    {         
 | 
						||
      //THead_lines_record &myself=*this;
 | 
						||
      //if (numero() <= 0)
 | 
						||
      //  myself.renum();
 | 
						||
      do
 | 
						||
      {
 | 
						||
        err = TRectype::write(f);
 | 
						||
        if (err == _isreinsert) // usa il flag _nuovo per decidere se 
 | 
						||
          ((THead_lines_record *)this)->renum();
 | 
						||
      } while (err == _isreinsert);
 | 
						||
      ((THead_lines_record *)this)->_nuovo = FALSE;
 | 
						||
    }
 | 
						||
    else 
 | 
						||
    {
 | 
						||
      err = TRectype::write(f);
 | 
						||
      if (err != NOERR)
 | 
						||
        err = TRectype::rewrite(f);
 | 
						||
    }    
 | 
						||
    if (err == NOERR)
 | 
						||
      err = _rows->write(re);
 | 
						||
  }
 | 
						||
  return err;  
 | 
						||
}
 | 
						||
 | 
						||
 | 
						||
int THead_lines_record::remove(TBaseisamfile& f) const 
 | 
						||
{
 | 
						||
  int err = _rows->remove();
 | 
						||
  if (err == NOERR)
 | 
						||
    err = TRectype::remove(f);
 | 
						||
  return err;  
 | 
						||
}
 | 
						||
*/
 | 
						||
 | 
						||
 | 
						||
// ************************************************
 | 
						||
// TEMP!!!!!!!!!!!!!!!!
 | 
						||
 | 
						||
TRegistro_std::TRegistro_std(const char* cod, int year) : TRectype(LF_TAB)
 | 
						||
{
 | 
						||
  if (!read(cod, year))
 | 
						||
    fatal_box("Il codice richiesto non <20> stato trovato nei registri");
 | 
						||
  TTable itl("%ITL");
 | 
						||
  itl.put("CODTAB",cod_intest());
 | 
						||
  itl.read();
 | 
						||
  _intest=itl.get("S0");
 | 
						||
}
 | 
						||
 | 
						||
bool TRegistro_std::read(const char* cod, int year)
 | 
						||
{               
 | 
						||
  if (year <= 0) 
 | 
						||
  {
 | 
						||
    const TDate oggi(TODAY);
 | 
						||
    year = oggi.year();
 | 
						||
  }
 | 
						||
 | 
						||
  int err = ~NOERR;
 | 
						||
  
 | 
						||
  TTable reg("REG");
 | 
						||
  reg.setkey(1);
 | 
						||
  if (cod && *cod > ' ')
 | 
						||
  {
 | 
						||
    TString16 chiave; chiave.format("%04d%s", year, cod);
 | 
						||
    reg.put("CODTAB", chiave);
 | 
						||
    err = reg.read(); 
 | 
						||
  }
 | 
						||
  *((TRectype *)this) = reg.curr();
 | 
						||
  
 | 
						||
  return err == NOERR;
 | 
						||
}           
 | 
						||
 | 
						||
bool TRegistro_std::write(bool rewrite) const 
 | 
						||
{               
 | 
						||
  int err = ~NOERR;
 | 
						||
  TTable reg("REG");
 | 
						||
 | 
						||
  reg.set_curr((TRectype *)this);
 | 
						||
  if (rewrite)
 | 
						||
    err = reg.rewrite(); 
 | 
						||
  else
 | 
						||
    err = reg.write(); 
 | 
						||
  return err == NOERR;
 | 
						||
}           
 | 
						||
 | 
						||
 | 
						||
 | 
						||
int TRegistro_std::year() const 
 | 
						||
{                
 | 
						||
  TString16 anno(get("CODTAB")); 
 | 
						||
  anno.cut(4);
 | 
						||
  return atoi(anno);
 | 
						||
}   
 | 
						||
 | 
						||
 | 
						||
const TString& TRegistro_std::code() const 
 | 
						||
{ 
 | 
						||
  return get("CODTAB").mid(4);
 | 
						||
}
 | 
						||
 | 
						||
const TString TRegistro_std::intest() const
 | 
						||
{
 | 
						||
  return _intest;
 | 
						||
}
 | 
						||
 | 
						||
int TRegistro_std::lock()
 | 
						||
{
 | 
						||
  TTable reg("REG");
 | 
						||
  reg.put("CODTAB",this->get("CODTAB"));
 | 
						||
  return reg.read(_lock); 
 | 
						||
}
 | 
						||
 | 
						||
int TRegistro_std::unlock()
 | 
						||
{
 | 
						||
  TTable reg("REG");
 | 
						||
  reg.put("CODTAB",this->get("CODTAB"));
 | 
						||
  return reg.read(_unlock); 
 | 
						||
}
 |