Aggiunti record a campi variabili
git-svn-id: svn://10.65.10.50/trunk@3446 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
0943757210
commit
607e672174
427
include/varrec.cpp
Executable file
427
include/varrec.cpp
Executable file
@ -0,0 +1,427 @@
|
||||
#include <varrec.h>
|
||||
|
||||
#ifndef __RELATION_H
|
||||
#include <relation.h>
|
||||
#endif
|
||||
|
||||
// @doc INTERNAL
|
||||
//
|
||||
// @class TVariable_field | Oggetto campo virtuale
|
||||
//
|
||||
// @base public | TObject
|
||||
class TVariable_field : public TObject
|
||||
|
||||
// @author:(INTERNAL) Sandro
|
||||
|
||||
{
|
||||
TVariable_rectype * _rec;
|
||||
TString _name;
|
||||
TExpression * _e;
|
||||
TString _value;
|
||||
TToken_string * _put_string;
|
||||
VIRTUAL_GET_FUNCTION _getfunc;
|
||||
bool _destroy_expression;
|
||||
|
||||
public:
|
||||
// @access Public Member
|
||||
// @cmember Duplica il campo
|
||||
virtual TObject* dup() const;
|
||||
|
||||
// @cmember ritorna il nome del campo
|
||||
const char * name() const { return _name;}
|
||||
// @cmember ritorna il valore del campo
|
||||
TString & get() const;
|
||||
// @cmember aggiorna il valore del campo utilizzando <p val>
|
||||
void put(const char * val);
|
||||
// @cmember azzera il valore del campo
|
||||
void zero();
|
||||
// @cmember il campo non ha formule o funzioni collegate
|
||||
bool plain() const { return _e == NULL && _getfunc == NULL;}
|
||||
|
||||
// @ cmember Costruttore con una espressione di calcolo
|
||||
TVariable_field(const char * name, TVariable_rectype * rec = NULL, const char * expr = "", TTypeexp type = _strexpr);
|
||||
// @ cmember Costruttore con una funzione
|
||||
TVariable_field(const char * name, TVariable_rectype * rec, VIRTUAL_GET_FUNCTION getfunc);
|
||||
// @ cmember Costruttore con una espressione di calcolo
|
||||
TVariable_field(const char * name, TVariable_rectype * rec, TExpression * expr, TTypeexp type = _strexpr);
|
||||
// @ cmember Costruttore con un variable_field
|
||||
TVariable_field(const TVariable_field & f);
|
||||
// @ cmember Distruttore
|
||||
~TVariable_field();
|
||||
};
|
||||
|
||||
TVariable_field::TVariable_field(
|
||||
const char * name, //
|
||||
TVariable_rectype * rec, //
|
||||
const char * expr, //
|
||||
TTypeexp type) //
|
||||
: _rec(rec), _name(name), _e(NULL) , _getfunc(NULL),
|
||||
_put_string(NULL), _destroy_expression(TRUE)
|
||||
{
|
||||
if (expr && *expr)
|
||||
{
|
||||
_e = new TExpression(expr, type);
|
||||
if (TFixed_string(expr).find('-') == -1) _put_string = new TToken_string(expr, '+');
|
||||
}
|
||||
}
|
||||
|
||||
TVariable_field::TVariable_field(
|
||||
const char * name, //
|
||||
TVariable_rectype * rec, //
|
||||
VIRTUAL_GET_FUNCTION getfunc) //
|
||||
: _name(name), _e(NULL) , _rec(rec), _getfunc(getfunc),
|
||||
_put_string(NULL), _destroy_expression(FALSE)
|
||||
{
|
||||
CHECK(_getfunc, "You must pass a valid VIRTUAL_GET_FUNCTION");
|
||||
}
|
||||
|
||||
TVariable_field::TVariable_field(
|
||||
const char * name, //
|
||||
TVariable_rectype * rec, //
|
||||
TExpression * expr, //
|
||||
TTypeexp type) //
|
||||
: _rec(rec), _name(name), _e(expr) , _getfunc(NULL),
|
||||
_put_string(NULL), _destroy_expression(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
TVariable_field::TVariable_field(const TVariable_field & f)
|
||||
: _rec(f._rec), _name(f._name), _e(NULL) , _getfunc(f._getfunc),
|
||||
_put_string(NULL), _destroy_expression(f._destroy_expression)
|
||||
{
|
||||
if (f._e)
|
||||
_e = (TExpression *) f._e->dup();
|
||||
if (f._put_string)
|
||||
_put_string = new TToken_string(*f._put_string);
|
||||
|
||||
}
|
||||
|
||||
TVariable_field::~TVariable_field()
|
||||
{
|
||||
if (_destroy_expression && _e) delete _e;
|
||||
if (_put_string) delete _put_string;
|
||||
}
|
||||
|
||||
TObject* TVariable_field::dup() const
|
||||
{
|
||||
TVariable_field* o = new TVariable_field(*this);
|
||||
return o;
|
||||
}
|
||||
|
||||
TString & TVariable_field::get() const
|
||||
{
|
||||
TString & v = (TString &) _value;
|
||||
if (_e)
|
||||
{
|
||||
CHECK(_rec, "NULL Record pointer with an expression");
|
||||
const int items = _e->numvar();
|
||||
for (int i = 0; i < items; i++)
|
||||
_e->setvar(i, _rec->get(_e->varname(i)));
|
||||
|
||||
// v = _e->type() == _strexpr ? (const char *) (*_e) : ((const real &) (*_e)).string();
|
||||
v = *_e;
|
||||
}
|
||||
else
|
||||
if (_getfunc)
|
||||
{
|
||||
CHECK(_rec, "NULL Record pointer with a function");
|
||||
v = _getfunc(*_rec);
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
void TVariable_field::put(const char * val)
|
||||
{
|
||||
if (!_getfunc)
|
||||
{
|
||||
if (_e == NULL)
|
||||
_value = val;
|
||||
else
|
||||
{
|
||||
if (_e->type() == _strexpr && _rec && _put_string)
|
||||
{
|
||||
const TString work_val(val);
|
||||
int start = 0;
|
||||
|
||||
for (const char * s = _put_string->get(0); s && *s; s = _put_string->get())
|
||||
{
|
||||
TFieldref f(s, 0);
|
||||
const int len = f.len(*_rec);
|
||||
f = work_val.mid(start, len);
|
||||
start += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TVariable_field::zero()
|
||||
{
|
||||
_value.cut(0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// TVariable_rectype
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
TVariable_rectype::TVariable_rectype(int logicnum)
|
||||
: TRectype(logicnum), _memo_fld_to_load(FALSE)
|
||||
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
TVariable_rectype::TVariable_rectype(const TBaseisamfile* i)
|
||||
: TRectype(i), _memo_fld_to_load(FALSE)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
TVariable_rectype::TVariable_rectype(const TRectype& r)
|
||||
: TRectype(r), _memo_fld_to_load(FALSE)
|
||||
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
TVariable_rectype::TVariable_rectype(const TVariable_rectype& r)
|
||||
: TRectype((const TRectype &) r), _memo_fld_to_load(FALSE)
|
||||
|
||||
{
|
||||
_virtual_fields = r._virtual_fields;
|
||||
_memo_fld = r._memo_fld;
|
||||
}
|
||||
|
||||
void TVariable_rectype::unknown_field(const char* name) const
|
||||
{
|
||||
if (!auto_virtual_fields())
|
||||
TRectype::unknown_field(name);
|
||||
}
|
||||
|
||||
void TVariable_rectype::write_memo(isdef * file, const TRecnotype recno)
|
||||
{
|
||||
if (_memo_fld.not_empty())
|
||||
{
|
||||
TToken_string t(256, '\n');
|
||||
TString s(80);
|
||||
for (TVariable_field * vf = (TVariable_field *) _virtual_fields.first_item(); vf;
|
||||
vf = (TVariable_field *) _virtual_fields.succ_item())
|
||||
{
|
||||
const TString & val = vf->get();
|
||||
|
||||
if (val.not_empty())
|
||||
{
|
||||
s = vf->name();
|
||||
s << "=" << val;
|
||||
t.add(s);
|
||||
}
|
||||
}
|
||||
put(_memo_fld, t);
|
||||
}
|
||||
TRectype::write_memo(file, recno);
|
||||
}
|
||||
|
||||
TVariable_field * TVariable_rectype::add_field(const char * fieldname, const char * expr, TTypeexp type)
|
||||
{
|
||||
CHECKS(!TRectype::exist(fieldname), "Field already exist ", fieldname);
|
||||
TVariable_field * f = new TVariable_field(fieldname, this, expr, type);
|
||||
_virtual_fields.add(fieldname, f, TRUE);
|
||||
return f;
|
||||
}
|
||||
|
||||
TVariable_field * TVariable_rectype::add_field(const char * fieldname, TExpression * expr,
|
||||
TTypeexp type)
|
||||
{
|
||||
CHECKS(!TRectype::exist(fieldname), "Field already exist ", fieldname);
|
||||
TVariable_field * f = new TVariable_field(fieldname, this, expr, type);
|
||||
_virtual_fields.add(fieldname, f, TRUE);
|
||||
return f;
|
||||
}
|
||||
|
||||
TVariable_field * TVariable_rectype::add_field(const char * fieldname, VIRTUAL_GET_FUNCTION getfunc)
|
||||
{
|
||||
CHECKS(!TRectype::exist(fieldname), "Field already exist ", fieldname);
|
||||
CHECK(getfunc, "You must pass a valid VIRTUAL_GET_FUNCTION");
|
||||
TVariable_field * f = new TVariable_field(fieldname, this, getfunc);
|
||||
_virtual_fields.add(fieldname, f, TRUE);
|
||||
return f;
|
||||
}
|
||||
|
||||
void TVariable_rectype::remove_field(const char * fieldname)
|
||||
{
|
||||
if (fieldname)
|
||||
{
|
||||
if (_virtual_fields.is_key(fieldname))
|
||||
_virtual_fields.remove(fieldname);
|
||||
}
|
||||
else
|
||||
_virtual_fields.destroy();
|
||||
}
|
||||
|
||||
const char * TVariable_rectype::get_variable_field_names(bool restart)
|
||||
{
|
||||
TVariable_field * f = (TVariable_field *) (restart ? _virtual_fields.first_item() :
|
||||
_virtual_fields.succ_item());
|
||||
return f != NULL ? (const char *) f->name() : NULL;
|
||||
}
|
||||
|
||||
void TVariable_rectype::set_memo_fld( const char * fieldname)
|
||||
{
|
||||
if (fieldname && *fieldname)
|
||||
{
|
||||
CHECK(exist(fieldname), "Unknown memo field");
|
||||
CHECK(type(fieldname) == _memofld, "Incorrect field type");
|
||||
_memo_fld = fieldname;
|
||||
}
|
||||
else
|
||||
_memo_fld.cut(0);
|
||||
}
|
||||
|
||||
void TVariable_rectype::init_memo( const TRecnotype recno)
|
||||
{
|
||||
TRectype::init_memo(recno);
|
||||
if (recno != RECORD_NON_FISICO)
|
||||
_memo_fld_to_load = _memo_fld.not_empty();
|
||||
}
|
||||
|
||||
TObject* TVariable_rectype::dup() const
|
||||
{
|
||||
TVariable_rectype* o = new TVariable_rectype(*this);
|
||||
return o;
|
||||
}
|
||||
|
||||
TFieldtypes TVariable_rectype::type(const char* fieldname) const
|
||||
|
||||
{
|
||||
if (_virtual_fields.objptr(fieldname))
|
||||
return _alfafld;
|
||||
return TRectype::type(fieldname);
|
||||
}
|
||||
|
||||
|
||||
int TVariable_rectype::length(const char* fieldname) const
|
||||
|
||||
{
|
||||
if (_virtual_fields.objptr(fieldname))
|
||||
return 255;
|
||||
return TRectype::length(fieldname);
|
||||
}
|
||||
|
||||
|
||||
int TVariable_rectype::ndec(const char* fieldname) const
|
||||
|
||||
{
|
||||
if (_virtual_fields.objptr(fieldname))
|
||||
return 0;
|
||||
return TRectype::ndec(fieldname);
|
||||
}
|
||||
|
||||
|
||||
bool TVariable_rectype::exist(const char* fieldname) const
|
||||
{
|
||||
if (_virtual_fields.is_key(fieldname))
|
||||
return TRUE;
|
||||
return TRectype::exist(fieldname);
|
||||
}
|
||||
|
||||
const TString & TVariable_rectype::get_str(const char* fieldname) const
|
||||
{
|
||||
TVariable_field * f = (TVariable_field *) _virtual_fields.objptr(fieldname);
|
||||
|
||||
if (_memo_fld_to_load && f == NULL)
|
||||
{
|
||||
((TVariable_rectype *) this)->_memo_fld_to_load = FALSE;
|
||||
TToken_string values(get(_memo_fld), '\n');
|
||||
for (const char * s = values.get(0); s && *s; s = values.get())
|
||||
{
|
||||
char * val = strchr(s, '=');
|
||||
if (val)
|
||||
{
|
||||
*val = '\0';
|
||||
val++;
|
||||
if (*val)
|
||||
{
|
||||
TVariable_field * v = (TVariable_field *) _virtual_fields.objptr(s);
|
||||
|
||||
if (v == NULL)
|
||||
v = ((TVariable_rectype *) this)->add_field(s);
|
||||
v->put(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
f = (TVariable_field *) _virtual_fields.objptr(fieldname);
|
||||
}
|
||||
if (f)
|
||||
return f->get();
|
||||
else
|
||||
return TRectype::get_str(fieldname);
|
||||
}
|
||||
|
||||
void TVariable_rectype::put_str(const char* fieldname, const char* val)
|
||||
{
|
||||
TVariable_field * f = (TVariable_field *) _virtual_fields.objptr(fieldname);
|
||||
|
||||
if (f == NULL && auto_virtual_fields() && !TRectype::exist(fieldname))
|
||||
{
|
||||
_virtual_fields.add(fieldname, TVariable_field(fieldname));
|
||||
f = (TVariable_field *) _virtual_fields.objptr(fieldname);
|
||||
}
|
||||
if (f)
|
||||
f->put(val);
|
||||
else
|
||||
TRectype::put_str(fieldname, val);
|
||||
}
|
||||
|
||||
void TVariable_rectype::zero(const char* fieldname)
|
||||
|
||||
{
|
||||
TVariable_field * f = (TVariable_field *) _virtual_fields.objptr(fieldname);
|
||||
if (f)
|
||||
f->zero();
|
||||
else
|
||||
TRectype::zero(fieldname);
|
||||
}
|
||||
|
||||
|
||||
HIDDEN void zero_virtual_fields(const TObject & o)
|
||||
|
||||
{
|
||||
TVariable_field & v = (TVariable_field &) o;
|
||||
v.zero();
|
||||
}
|
||||
|
||||
void TVariable_rectype::zero(char c)
|
||||
|
||||
{
|
||||
TRectype::zero(c);
|
||||
_virtual_fields.for_each(zero_virtual_fields);
|
||||
}
|
||||
|
||||
|
||||
// Certified 99%
|
||||
TVariable_rectype & TVariable_rectype::operator =(const TVariable_rectype & rec)
|
||||
|
||||
{
|
||||
TRectype::operator =(rec);
|
||||
_virtual_fields = rec._virtual_fields;
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
TVariable_rectype & TVariable_rectype::operator =(const TRectype & rec)
|
||||
|
||||
{
|
||||
TRectype::operator =(rec);
|
||||
_virtual_fields.for_each(zero_virtual_fields);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Certified 99%
|
||||
TVariable_rectype & TVariable_rectype::operator =(const char* rec)
|
||||
{
|
||||
TRectype::operator =(rec);
|
||||
_virtual_fields.for_each(zero_virtual_fields);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
128
include/varrec.h
Executable file
128
include/varrec.h
Executable file
@ -0,0 +1,128 @@
|
||||
#ifndef __VARREC_H
|
||||
#define __VARREC_H
|
||||
|
||||
#ifndef __ISAM_H
|
||||
#include <isam.h>
|
||||
#endif
|
||||
|
||||
#ifndef __EXPR_H
|
||||
#include <expr.h>
|
||||
#endif
|
||||
|
||||
class TVariable_rectype;
|
||||
class TVariable_field;
|
||||
|
||||
// @doc EXTERNAL
|
||||
//
|
||||
// @type VIRTUAL_GET_FUNCTION | Prototipo funzione di calcolo del valore di un campo virtuale
|
||||
// da definire quando non sia sufficente una semplice espressione
|
||||
typedef const char * (*VIRTUAL_GET_FUNCTION)(TVariable_rectype & r);
|
||||
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TRectype | Classe per la definizione del record di file con campi virtuali (variabili)
|
||||
|
||||
class TVariable_rectype : public TRectype
|
||||
|
||||
// @author:(INTERNAL) Sandro
|
||||
|
||||
{
|
||||
// @access:(INTERNAL) Private Member
|
||||
TAssoc_array _virtual_fields;
|
||||
TString16 _memo_fld;
|
||||
bool _memo_fld_to_load;
|
||||
|
||||
protected:
|
||||
// @cmember Segnalazione di un campo inesistente
|
||||
virtual void unknown_field(const char* name) const;
|
||||
// @cmember Indica se il record implementa i campi variabili automatici
|
||||
virtual bool auto_virtual_fields() const { return TRUE; }
|
||||
// @cmember Ritorna il contenuto del campo <p fieldname> (non tipizzata)
|
||||
virtual const TString & get_str(const char* fieldname) const ;
|
||||
// @cmember Setta il contenuto del campo <p fieldname> (non tipizzata)
|
||||
virtual void put_str(const char* fieldname, const char* val);
|
||||
// void put(const char* fieldname, TString& val);
|
||||
|
||||
public:
|
||||
// @access Public Member
|
||||
// @cmember Duplica il tipo di record
|
||||
virtual TObject* dup() const;
|
||||
|
||||
// @cmember Setta il record come non suoto (chiama <mf TRectype::setempty>
|
||||
|
||||
TFieldtypes type(const char* fieldname) const;
|
||||
// @cmember Ritorna la lunghezza del campo <p fieldname>
|
||||
int length(const char* fieldname) const;
|
||||
// @cmember Ritorna numero di decimali del campo <p fieldname>
|
||||
int ndec(const char* fieldname) const;
|
||||
// @cmember Indica se esiste il campo <p fieldname>
|
||||
bool exist(const char* fieldname) const;
|
||||
|
||||
// @cmember Vuota il campo puntato da <p fieldname>
|
||||
virtual void zero(const char * fieldname);
|
||||
// @cmember Vuota tutto il record usando il carattere <p c>
|
||||
virtual void zero(char c = '\0');
|
||||
|
||||
// @cmember Assegnazione tra TVariable_rectype e TRectype
|
||||
TVariable_rectype& operator =(const TRectype& rec);
|
||||
// @cmember Assegnazione tra TVariable_rectype
|
||||
TVariable_rectype& operator =(const TVariable_rectype& rec);
|
||||
// @cmember Assegnazione tra TRectype const char *
|
||||
TVariable_rectype& operator =(const char* rec);
|
||||
|
||||
|
||||
void set_memo_fld(const char * fieldname);
|
||||
void reset_memo_fld() { set_memo_fld(NULL); }
|
||||
virtual void init_memo(const TRecnotype recno = RECORD_NON_FISICO);
|
||||
virtual void write_memo(isdef * file, const TRecnotype recno);
|
||||
|
||||
virtual TVariable_field * add_field(const char * fieldname, const char * expr = "", TTypeexp type = _strexpr);
|
||||
virtual TVariable_field * add_field(const char * fieldname, TExpression * expr, TTypeexp type = _strexpr);
|
||||
virtual TVariable_field * add_field(const char * fieldname, VIRTUAL_GET_FUNCTION getfunc);
|
||||
virtual void remove_field(const char * fieldname = NULL);
|
||||
virtual const char * get_variable_field_names(bool restart = FALSE) ;
|
||||
|
||||
// @cmember Costruttore Costruisce un record staccato da un file.
|
||||
// Sarebbe meglio utilizzare una delle altre due
|
||||
TVariable_rectype(int logicnum);
|
||||
// @cmember Costruttore. Costruisce record e lo associa al file isam <p i>
|
||||
TVariable_rectype(const TBaseisamfile* i);
|
||||
// @cmember Costruttore. Costruisce il record a partire da <p r>
|
||||
TVariable_rectype(const TRectype & r);
|
||||
// @cmember Costruttore. Costruisce il record a partire da <p r>
|
||||
TVariable_rectype(const TVariable_rectype & r);
|
||||
|
||||
// @cmember Distruttore
|
||||
virtual ~TVariable_rectype() {}
|
||||
};
|
||||
|
||||
// @doc EXTERNAL
|
||||
|
||||
// @class TRectype | Classe per la definizione del record di file con campi virtuali (variabili)
|
||||
|
||||
class TAuto_variable_rectype : public TVariable_rectype
|
||||
|
||||
// @author:(INTERNAL) Sandro
|
||||
|
||||
|
||||
{
|
||||
protected:
|
||||
virtual bool auto_virtual_fields() const { return TRUE; }
|
||||
|
||||
public:
|
||||
// @cmember Costruttore Costruisce un record staccato da un file.
|
||||
// Sarebbe meglio utilizzare una delle altre due
|
||||
TAuto_variable_rectype(int logicnum) : TVariable_rectype(logicnum) {}
|
||||
// @cmember Costruttore. Costruisce record e lo associa al file isam <p i>
|
||||
TAuto_variable_rectype(const TBaseisamfile* i) : TVariable_rectype(i) {}
|
||||
// @cmember Costruttore. Costruisce il record a partire da <p r>
|
||||
TAuto_variable_rectype(const TRectype & r) : TVariable_rectype(r) {}
|
||||
// @cmember Costruttore. Costruisce il record a partire da <p r>
|
||||
TAuto_variable_rectype(const TVariable_rectype & r) : TVariable_rectype(r) {}
|
||||
|
||||
// @cmember Distruttore
|
||||
virtual ~TAuto_variable_rectype() {}
|
||||
};
|
||||
|
||||
#endif // __VARREC_
|
Loading…
x
Reference in New Issue
Block a user