1998-02-24 10:37:28 +00:00
|
|
|
#include <codeb.h>
|
2003-03-27 12:14:51 +00:00
|
|
|
#include <diction.h>
|
1994-09-07 17:00:25 +00:00
|
|
|
#include <extcdecl.h>
|
1999-01-19 09:15:17 +00:00
|
|
|
#include <currency.h>
|
1998-03-13 10:35:51 +00:00
|
|
|
#include <prefix.h>
|
1998-02-24 10:37:28 +00:00
|
|
|
#include <progind.h>
|
2008-02-13 13:31:25 +00:00
|
|
|
#include <recarray.h>
|
1994-09-07 17:00:25 +00:00
|
|
|
#include <scanner.h>
|
1998-02-24 10:37:28 +00:00
|
|
|
#include <tabutil.h>
|
1994-09-07 17:00:25 +00:00
|
|
|
#include <utility.h>
|
|
|
|
|
1998-02-24 10:37:28 +00:00
|
|
|
#include <nditte.h>
|
1995-07-03 07:49:30 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
// Definita in isam.cpp
|
1995-07-03 07:49:30 +00:00
|
|
|
extern int get_error(int);
|
|
|
|
|
1995-03-22 09:07:04 +00:00
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// extern variables are NO-NO!
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
HIDDEN TPrefix* _prefhndl = NULL;
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @func Inizializza (crea) un nuovo file "prefix.txt"
|
|
|
|
//
|
|
|
|
// @rdesc Ritorna l'oggetto <c TPrefix> creato
|
1995-03-22 09:07:04 +00:00
|
|
|
TPrefix& prefix_init()
|
|
|
|
{
|
|
|
|
CHECK(_prefhndl == NULL, "Can't create two prefix objects");
|
|
|
|
_prefhndl = new TPrefix;
|
|
|
|
return *_prefhndl;
|
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1998-05-13 15:07:41 +00:00
|
|
|
// @func Determina se il prefix e' stato inizializzato
|
|
|
|
//
|
2009-05-27 13:46:20 +00:00
|
|
|
// @rdesc Ritorna true o false
|
1998-05-13 15:07:41 +00:00
|
|
|
bool prefix_valid()
|
|
|
|
{
|
|
|
|
return _prefhndl != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @func Legge il file "prefix.txt"
|
|
|
|
//
|
|
|
|
// @rdesc Ritorna l'oggetto <c TPrefix> letto
|
1995-03-22 09:07:04 +00:00
|
|
|
TPrefix& prefix()
|
|
|
|
{
|
|
|
|
CHECK(_prefhndl, "Can't access null prefix");
|
|
|
|
return *_prefhndl;
|
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @func Distrugge l'oggett <c TPrefix> in memoria
|
1995-03-22 09:07:04 +00:00
|
|
|
void prefix_destroy()
|
|
|
|
{
|
2003-05-16 13:13:39 +00:00
|
|
|
if (_prefhndl != NULL)
|
1996-05-08 11:09:13 +00:00
|
|
|
{
|
|
|
|
delete _prefhndl;
|
|
|
|
_prefhndl = NULL;
|
|
|
|
}
|
1995-03-22 09:07:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
1998-03-30 13:50:30 +00:00
|
|
|
// TFile_manager
|
1995-03-22 09:07:04 +00:00
|
|
|
///////////////////////////////////////////////////////////
|
1994-11-24 14:01:20 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
class TRecord_info : public TObject
|
|
|
|
{
|
|
|
|
RecDes _recdes;
|
|
|
|
TDirtype _dirtype;
|
|
|
|
int _len;
|
2008-03-21 16:39:47 +00:00
|
|
|
TString_array _relations;
|
|
|
|
int _logicnum;
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
protected:
|
|
|
|
void translate_key(TToken_string& t) const;
|
|
|
|
void compute_len();
|
|
|
|
|
|
|
|
bool create(TTrec& rec, TToken_string& keys);
|
|
|
|
|
|
|
|
public: // TObject
|
|
|
|
virtual bool ok() const;
|
|
|
|
|
|
|
|
public:
|
|
|
|
operator const RecDes&() const { return _recdes; }
|
|
|
|
int len() const { return _len; }
|
|
|
|
|
|
|
|
TDirtype dir_type() const { return _dirtype; }
|
|
|
|
bool mutable_dir() const { return _dirtype <= _studir; }
|
|
|
|
bool fixed_dir() const { return _dirtype > _studir; }
|
2008-03-21 16:39:47 +00:00
|
|
|
TToken_string & relation(int logicnum);
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
TRecord_info(int logicnum);
|
|
|
|
TRecord_info(const char* name);
|
|
|
|
TRecord_info(TTrec& rec, TToken_string& keys);
|
|
|
|
virtual ~TRecord_info() { }
|
|
|
|
};
|
|
|
|
|
|
|
|
void TRecord_info::translate_key(TToken_string& t) const// Traduce l'espressione chiave di CodeBase
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
1998-03-30 13:50:30 +00:00
|
|
|
// Trasforma l'espressione
|
|
|
|
TToken_string k(t.get(0),'+');
|
|
|
|
TToken_string range("",',');
|
|
|
|
TString ws;
|
|
|
|
const bool is_dup = t.get(1)[0] == 'X';
|
|
|
|
const int items = k.items();
|
|
|
|
t = "";
|
|
|
|
for (int i = 0; i<items; i++) // scorre i campi dell'espressione
|
|
|
|
{
|
|
|
|
ws = k.get(i); // Primo campo
|
|
|
|
const bool is_upper = ws.find("UPPER") >= 0;
|
|
|
|
const bool is_sub = ws.find("SUBSTR") >= 0;
|
|
|
|
int paren1 = ws.find('('); // Trova la prima parentesi aperta
|
2004-03-12 16:01:27 +00:00
|
|
|
int paren2,last,from = 0,to = 0;
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
if (paren1 >= 0 && is_sub && is_upper)
|
|
|
|
paren1 = ws.find('('); // Trova la seconda parentesi (in questo caso c'e' per forza)
|
1994-12-02 13:08:53 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
if (paren1 >= 0) // Trova la prima virgola o parentesi chiusa (per qualsiasi espressione)
|
|
|
|
{
|
|
|
|
paren2 = ws.find(',');
|
|
|
|
if (paren2 == -1) // se non ci sono virgole trova la parentesi chiusa
|
|
|
|
paren2 = ws.find(')');
|
|
|
|
CHECK(paren2 > paren1,"Something wrong happened translating CodeBase expressions.");
|
|
|
|
if (is_sub) // Se e' una sottostringa estrae i campi DA e A
|
|
|
|
{
|
|
|
|
range = ws;
|
|
|
|
last = ws.find(')');
|
|
|
|
range.sub(paren2,last); // dalla virgola alla parentesi
|
|
|
|
from = range.get_int(0);
|
|
|
|
to = range.get_int(1);
|
|
|
|
}
|
|
|
|
ws = ws.sub(paren1+1,paren2); // Nome del campo pulito pulito
|
|
|
|
ws.upper();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_upper)
|
|
|
|
t << "UPPER(";
|
|
|
|
|
|
|
|
t << ws; // aggiunge il nome del campo
|
|
|
|
|
|
|
|
if (is_sub)
|
|
|
|
{
|
|
|
|
t << "[";
|
|
|
|
t << from << ",";
|
|
|
|
t << to << "]";
|
|
|
|
}
|
|
|
|
if (is_upper)
|
|
|
|
t << ")";
|
|
|
|
t << '+';
|
|
|
|
}
|
|
|
|
t.rtrim(1); // Toglie il + in piu'
|
|
|
|
t.add(is_dup ? "X" : " ");
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
bool TRecord_info::ok() const
|
|
|
|
{
|
|
|
|
return _recdes.NFields > 0 &&
|
|
|
|
_recdes.NKeys > 0 && _recdes.NKeys < MaxKeys;
|
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
void TRecord_info::compute_len()
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
1998-03-30 13:50:30 +00:00
|
|
|
_len = 0;
|
|
|
|
for (int f = _recdes.NFields-1; f >= 0; f--)
|
|
|
|
_len += _recdes.Fd[f].Len;
|
|
|
|
if (_len > 0)
|
|
|
|
_len++;
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
2008-03-21 16:39:47 +00:00
|
|
|
TToken_string & TRecord_info::relation(int logicnum)
|
|
|
|
{
|
|
|
|
if (_relations.empty())
|
|
|
|
{
|
|
|
|
const TFilename rels("recdesc/relations.ini");
|
|
|
|
if (rels.exist())
|
|
|
|
{
|
|
|
|
TString key; key.format("%d", _logicnum);
|
|
|
|
TConfig c(rels, key);
|
|
|
|
TString_array vars;
|
|
|
|
|
|
|
|
c.list_variables(vars, true);
|
|
|
|
|
|
|
|
FOR_EACH_ARRAY_ROW(vars, r, row)
|
|
|
|
{
|
|
|
|
const int num = row->get_int();
|
|
|
|
_relations.add(row->get(), num);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TToken_string * rel = _relations.rowptr(logicnum);
|
|
|
|
|
|
|
|
if (rel == NULL)
|
|
|
|
{
|
|
|
|
const RecDes & fd = prefix().get_recdes(_logicnum);
|
|
|
|
const RecDes & rd = prefix().get_recdes(logicnum);
|
|
|
|
const KeyDes& kd = rd.Ky[0]; // Tracciato della chiave primaria
|
|
|
|
|
|
|
|
rel = new TToken_string(EMPTY_STRING);
|
|
|
|
|
|
|
|
for (int i = 0; i < kd.NkFields; i++) // Riempio tutta la chiave primaria
|
|
|
|
{
|
|
|
|
const int nPos = kd.FieldSeq[i] % MaxFields; // Posizione del campo i della chiave
|
|
|
|
const RecFieldDes& dfield = rd.Fd[nPos]; // Nome del campo i della chiave
|
|
|
|
int nBest = -1;
|
|
|
|
double dBest = 0.0;
|
|
|
|
|
|
|
|
for (int j = 0; i < fd.NFields; j++)
|
|
|
|
{
|
|
|
|
const RecFieldDes& field = fd.Fd[j];
|
|
|
|
if (field.TypeF == dfield.TypeF && field.Len == dfield.Len)
|
|
|
|
{
|
|
|
|
const double fuzzy = xvt_str_fuzzy_compare(field.Name, dfield.Name);
|
|
|
|
if (fuzzy > dBest)
|
|
|
|
{
|
|
|
|
nBest = j;
|
|
|
|
dBest = fuzzy;
|
|
|
|
if (dBest == 1.0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
rel->add(nBest >= 0 ? fd.Fd[nBest].Name : "");
|
|
|
|
}
|
|
|
|
_relations.add(rel, logicnum);
|
|
|
|
}
|
|
|
|
return *((TToken_string *) rel);
|
|
|
|
}
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
TRecord_info::TRecord_info(int logicnum)
|
|
|
|
{
|
2008-03-21 16:39:47 +00:00
|
|
|
_logicnum = logicnum;
|
1998-03-30 13:50:30 +00:00
|
|
|
memset(&_recdes, 0, sizeof(_recdes));
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
FileDes fd; memset(&fd, 0, sizeof(fd));
|
|
|
|
CGetFile(logicnum, &fd, _nolock, _nordir);
|
|
|
|
if (fd.SysName[0])
|
|
|
|
{
|
|
|
|
_dirtype = fd.SysName[0] != '$' ? _comdir : _nordir;
|
|
|
|
CGetRec(logicnum, &_recdes, _dirtype);
|
|
|
|
}
|
|
|
|
if (ok())
|
|
|
|
compute_len();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TRecord_info::create(TTrec& rec, TToken_string& keys)
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
2008-03-21 16:39:47 +00:00
|
|
|
_logicnum = rec.num();
|
1998-03-30 13:50:30 +00:00
|
|
|
rec.rehash();
|
|
|
|
const int num_keys = rec.keys();
|
|
|
|
|
|
|
|
TToken_string trans;
|
|
|
|
for (int i = 0; i < num_keys; i++)
|
|
|
|
{
|
|
|
|
trans = keys.get(i);
|
|
|
|
translate_key(trans); // Traduce l'espressione chiave di CodeBase
|
|
|
|
rec.update_keydef(i, trans);
|
|
|
|
}
|
2008-12-10 16:52:43 +00:00
|
|
|
_recdes = rec.rec();
|
1998-03-30 13:50:30 +00:00
|
|
|
compute_len();
|
|
|
|
return _len > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
TRecord_info::TRecord_info(TTrec& rec, TToken_string& keys)
|
|
|
|
: _dirtype(_extdir)
|
|
|
|
{
|
|
|
|
create(rec, keys);
|
|
|
|
}
|
|
|
|
|
|
|
|
TRecord_info::TRecord_info(const char* name)
|
|
|
|
: _dirtype(_extdir)
|
|
|
|
{
|
|
|
|
TFilename fname(name); fname.ext("dbf");
|
|
|
|
if (fname.exist())
|
|
|
|
{
|
|
|
|
TToken_string keys(256*MaxKeys, '$');
|
|
|
|
|
|
|
|
fname.ext("");
|
|
|
|
FileDes fd;
|
|
|
|
TTrec rec;
|
2008-12-10 16:52:43 +00:00
|
|
|
int err = DB_recinfo(fname, &fd, (RecDes*)&rec.rec(), keys.get_buffer());
|
1998-03-30 13:50:30 +00:00
|
|
|
if (err != NOERR)
|
|
|
|
create(rec, keys);
|
|
|
|
else
|
|
|
|
memset(&_recdes, 0, sizeof(_recdes));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
memset(&_recdes, 0, sizeof(_recdes));
|
|
|
|
}
|
|
|
|
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
class TFile_info : public TObject
|
|
|
|
{
|
|
|
|
TFilename _name;
|
|
|
|
int _ref_count;
|
|
|
|
|
|
|
|
int _num;
|
|
|
|
int _handle;
|
1998-10-01 14:04:23 +00:00
|
|
|
clock_t _last_access, _last_change;
|
1998-03-30 13:50:30 +00:00
|
|
|
bool _locked, _exclusive;
|
|
|
|
TDirtype _dir;
|
|
|
|
FileDes _filedes;
|
|
|
|
|
|
|
|
int _last_key;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
int open_low(bool exclusive, bool index);
|
|
|
|
int close_low();
|
|
|
|
|
|
|
|
public: // TObject
|
|
|
|
virtual bool ok() const { return _name.not_empty(); }
|
|
|
|
|
|
|
|
public:
|
|
|
|
const TFilename& pathname() const { return _name; }
|
|
|
|
int num() const { return _num; }
|
|
|
|
int handle() const { return _handle; }
|
|
|
|
bool is_open() const { return _handle >= 0; }
|
|
|
|
clock_t last_access() const { return _last_access; }
|
1998-10-01 14:04:23 +00:00
|
|
|
clock_t last_change() const { return _last_change; }
|
1998-03-30 13:50:30 +00:00
|
|
|
bool is_exclusive() const { return _exclusive; }
|
|
|
|
bool is_locked() const { return _locked; }
|
|
|
|
int ref_count() const { return _ref_count; }
|
|
|
|
int last_key() const { return _last_key; }
|
|
|
|
void touch() { _last_access = clock(); }
|
1998-10-01 14:04:23 +00:00
|
|
|
void set_dirty() { _last_change = clock(); }
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
TDirtype dir_type() const { return _dir; }
|
|
|
|
bool mutable_dir() const { return _dir <= _studir; }
|
|
|
|
bool fixed_dir() const { return _dir > _studir; }
|
|
|
|
|
|
|
|
int open(bool exclusive, bool index);
|
|
|
|
int close();
|
|
|
|
const TFilename& load_filedes();
|
|
|
|
|
|
|
|
void lock_record(TRecnotype rec);
|
|
|
|
void unlock_record(TRecnotype rec);
|
|
|
|
|
|
|
|
int auto_open(int key);
|
|
|
|
void auto_close();
|
|
|
|
|
|
|
|
operator const FileDes&() const { return _filedes; }
|
|
|
|
TFile_info(int logicnum, TFilename& name);
|
|
|
|
virtual ~TFile_info();
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
int TFile_info::open_low(bool exclusive, bool index)
|
|
|
|
{
|
|
|
|
if (_handle < 0)
|
|
|
|
_handle = DB_open(_name, exclusive, index);
|
|
|
|
#ifdef DBG
|
|
|
|
else
|
1998-06-24 07:11:33 +00:00
|
|
|
error_box("You shouldn't reopen file %s", (const char*)_name);
|
1998-03-30 13:50:30 +00:00
|
|
|
#endif
|
1994-09-07 17:00:25 +00:00
|
|
|
int err = NOERR;
|
1998-03-30 13:50:30 +00:00
|
|
|
if (_handle >= 0)
|
|
|
|
{
|
|
|
|
if (num() < LF_EXTERNAL && (_dir == _nordir || _dir == _comdir))
|
|
|
|
{
|
2007-02-16 13:48:27 +00:00
|
|
|
const TRecnotype n = DB_reccount(_handle);
|
2008-12-10 16:52:43 +00:00
|
|
|
_filedes.EOD = n;
|
|
|
|
_filedes.EOX = n;
|
|
|
|
TDir d; d.get(num(), _nolock, _dir, _sysdirop);
|
|
|
|
d.set_eod(n);
|
|
|
|
d.set_eox(n);
|
2007-02-16 13:48:27 +00:00
|
|
|
d.put(num(), _dir, _sysdirop);
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
1998-05-04 07:57:56 +00:00
|
|
|
|
|
|
|
if (index)
|
|
|
|
err = DB_tagselect(_handle, _last_key = 1);
|
|
|
|
else
|
|
|
|
_last_key = 0;
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
err = get_error(_handle);
|
|
|
|
}
|
|
|
|
return err;
|
1999-04-06 16:31:40 +00:00
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
int TFile_info::close_low()
|
|
|
|
{
|
|
|
|
int err = NOERR;
|
|
|
|
if (_handle >= 0)
|
|
|
|
{
|
|
|
|
DB_close(_handle);
|
|
|
|
_handle = -1;
|
1998-05-04 07:57:56 +00:00
|
|
|
_last_key = -1;
|
2009-01-07 15:50:52 +00:00
|
|
|
_exclusive = _locked = false;
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
err = _isnotopen;
|
|
|
|
}
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TFile_info::open(bool exclusive, bool index)
|
|
|
|
{
|
|
|
|
int err = NOERR;
|
|
|
|
if (exclusive || !index)
|
|
|
|
{
|
1998-05-27 10:56:30 +00:00
|
|
|
if (_ref_count > 0 || is_open())
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
1998-05-27 10:56:30 +00:00
|
|
|
#ifdef DBG
|
2009-01-07 15:50:52 +00:00
|
|
|
if (_ref_count > 0 && (_exclusive || _locked))
|
1998-06-24 07:11:33 +00:00
|
|
|
error_box("You shouldn't reopen file %d exclusively", num());
|
1998-03-30 13:50:30 +00:00
|
|
|
#endif
|
|
|
|
close_low();
|
|
|
|
}
|
2009-01-07 15:50:52 +00:00
|
|
|
_exclusive = _locked = true; // shouldn't be exclusive instead of true?
|
1998-03-30 13:50:30 +00:00
|
|
|
err = open_low(exclusive, index);
|
|
|
|
}
|
1999-01-19 09:15:17 +00:00
|
|
|
touch(); // Memorizza ora apertura del file
|
1998-03-30 13:50:30 +00:00
|
|
|
_ref_count++;
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TFile_info::close()
|
|
|
|
{
|
|
|
|
int err = NOERR;
|
|
|
|
if (_ref_count > 0)
|
|
|
|
{
|
|
|
|
_ref_count--;
|
2009-01-07 15:50:52 +00:00
|
|
|
if (_ref_count == 0 || _exclusive)
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
1998-05-27 10:56:30 +00:00
|
|
|
if (is_open())
|
|
|
|
{
|
|
|
|
// Chiudi fisicamente solo se necessario
|
1998-06-24 07:11:33 +00:00
|
|
|
if (_locked || _exclusive || dir_type() == _extdir)
|
2009-03-19 15:50:04 +00:00
|
|
|
err = close_low(); // Chiudo fisicamente il file per eliminare i lock
|
1998-05-27 10:56:30 +00:00
|
|
|
}
|
2008-12-16 10:25:17 +00:00
|
|
|
_locked = _exclusive = false;
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
err = _isnotopen;
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TFile_info::auto_close()
|
|
|
|
{
|
1998-05-27 10:56:30 +00:00
|
|
|
const bool yes = is_open() && !(is_locked() || is_exclusive());
|
1998-03-30 13:50:30 +00:00
|
|
|
if (yes)
|
|
|
|
close_low();
|
|
|
|
}
|
|
|
|
|
|
|
|
int TFile_info::auto_open(int key)
|
|
|
|
{
|
|
|
|
if (_handle < 0)
|
2009-03-19 15:50:04 +00:00
|
|
|
open_low(false, true);
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
if (_handle >= 0)
|
|
|
|
{
|
|
|
|
if (key > 0 && key != _last_key)
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
1998-03-30 13:50:30 +00:00
|
|
|
const int err = DB_tagselect(_handle, _last_key = key);
|
|
|
|
if (err != NOERR)
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
1998-03-30 13:50:30 +00:00
|
|
|
#ifdef DBG
|
|
|
|
NFCHECK("Can't set key %d on file %d", key, num());
|
|
|
|
#endif
|
|
|
|
return err;
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
}
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
return _handle;
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
void TFile_info::lock_record(TRecnotype)
|
2009-01-07 15:50:52 +00:00
|
|
|
{ _locked = true; }
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
void TFile_info::unlock_record(TRecnotype)
|
2009-01-07 15:50:52 +00:00
|
|
|
{ _locked = false; }
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
const TFilename& TFile_info::load_filedes()
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
1998-03-30 13:50:30 +00:00
|
|
|
memset(&_filedes, 0, sizeof(_filedes));
|
|
|
|
CGetFile(num(), &_filedes, _nolock, _nordir);
|
2008-12-16 10:25:17 +00:00
|
|
|
if (_filedes.SysName[0] > ' ')
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
2009-01-07 15:50:52 +00:00
|
|
|
_dir = _filedes.SysName[0] != '$' ? _comdir : _nordir;
|
2008-12-03 16:35:19 +00:00
|
|
|
_name = CAddPref(_filedes.SysName);
|
|
|
|
strncpy(_filedes.Des, dictionary_translate(_filedes.Des), sizeof(_filedes.Des)-1);
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
_name.cut(0);
|
|
|
|
return _name;
|
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
TFile_info::TFile_info(int logicnum, TFilename& name)
|
2004-03-12 16:01:27 +00:00
|
|
|
: _ref_count(0), _num(logicnum), _handle(-1),
|
|
|
|
_last_access(0),
|
2009-05-27 13:46:20 +00:00
|
|
|
_last_change(0), _locked(false), _exclusive(false), _last_key(-1)
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
|
|
|
if (logicnum < LF_EXTERNAL)
|
|
|
|
{
|
|
|
|
load_filedes();
|
2007-02-16 13:48:27 +00:00
|
|
|
if (name.full())
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
1998-03-30 13:50:30 +00:00
|
|
|
// File dati temporaneo
|
|
|
|
_dir = _extdir;
|
|
|
|
_name = name;
|
|
|
|
_name.ext("");
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
1998-03-30 13:50:30 +00:00
|
|
|
else
|
|
|
|
name = _name;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// File dati esterno
|
|
|
|
_dir = _extdir;
|
|
|
|
_name = name;
|
|
|
|
_name.ext("dbf");
|
|
|
|
if (_name.exist())
|
|
|
|
{
|
|
|
|
TToken_string keys(256*MaxKeys, '$');
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
_name.ext("");
|
|
|
|
TTrec rec;
|
2008-12-10 16:52:43 +00:00
|
|
|
int err = DB_recinfo(_name, &_filedes, (RecDes*)&rec.rec(), keys.get_buffer());
|
1998-03-30 13:50:30 +00:00
|
|
|
if (err == NOERR && prefix().add_recdes(logicnum, rec, keys))
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
strncpy(_filedes.SysName, _name, sizeof(_filedes.SysName));
|
1998-03-30 13:50:30 +00:00
|
|
|
_filedes.SysName[41] = '\0';
|
|
|
|
}
|
|
|
|
else
|
|
|
|
_name.cut(0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
_name.cut(0);
|
|
|
|
}
|
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
TFile_info::~TFile_info()
|
|
|
|
{
|
|
|
|
if (is_open())
|
|
|
|
close_low();
|
|
|
|
}
|
|
|
|
|
1998-06-24 07:11:33 +00:00
|
|
|
TFile_info& TFile_manager::fileinfo(TIsam_handle num) const
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
|
|
|
TFile_info* i = (TFile_info*)_fileinfo.objptr(num);
|
2009-03-06 12:11:03 +00:00
|
|
|
if (i == NULL && num >= LF_USER && num < LF_EXTERNAL)
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
|
|
|
TFilename name;
|
|
|
|
i = new TFile_info(num, name);
|
2009-03-06 12:11:03 +00:00
|
|
|
//if (i->ok())
|
1998-06-24 07:11:33 +00:00
|
|
|
((TFile_manager*)this)->_fileinfo.add(i, num);
|
2009-03-06 12:11:03 +00:00
|
|
|
/* else
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
|
|
|
delete i;
|
|
|
|
i = NULL;
|
2009-03-06 12:11:03 +00:00
|
|
|
}*/
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CHECKD(i, "Unknown file ", num);
|
|
|
|
return *i;
|
|
|
|
}
|
|
|
|
|
1998-06-24 07:11:33 +00:00
|
|
|
TRecord_info& TFile_manager::recinfo(int logicnum) const
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
|
|
|
TRecord_info* i = (TRecord_info*)_recinfo.objptr(logicnum);
|
|
|
|
if (i == NULL)
|
|
|
|
{
|
|
|
|
i = new TRecord_info(logicnum);
|
1998-06-24 07:11:33 +00:00
|
|
|
((TFile_manager*)this)->_recinfo.add(i, logicnum);
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
return *i;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TFile_manager::add_recdes(int logicnum, TTrec& rec, TToken_string& keys)
|
|
|
|
{
|
|
|
|
TRecord_info* i = (TRecord_info*)_recinfo.objptr(logicnum);
|
|
|
|
if (i == NULL)
|
|
|
|
{
|
|
|
|
if (logicnum < LF_EXTERNAL)
|
|
|
|
i = new TRecord_info(logicnum);
|
|
|
|
else
|
|
|
|
i = new TRecord_info(rec, keys);
|
|
|
|
if (i->ok())
|
|
|
|
_recinfo.add(i, logicnum);
|
|
|
|
else
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
1998-03-30 13:50:30 +00:00
|
|
|
delete i;
|
|
|
|
i = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return i != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool TFile_manager::close_oldest()
|
|
|
|
{
|
|
|
|
int oldest = 0;
|
|
|
|
clock_t age = 0;
|
1998-05-04 07:57:56 +00:00
|
|
|
_open_files = 0; // Intanto ricalcolo il numero di file veramente aperti
|
1998-03-30 13:50:30 +00:00
|
|
|
for (int n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
|
|
|
|
{
|
|
|
|
TFile_info& i = (TFile_info&)_fileinfo[n];
|
1998-05-04 07:57:56 +00:00
|
|
|
if (i.is_open())
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
1998-05-04 07:57:56 +00:00
|
|
|
_open_files++;
|
|
|
|
if (!i.is_locked() && !i.is_exclusive())
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
1998-05-04 07:57:56 +00:00
|
|
|
if (oldest == 0 || i.last_access() < age)
|
|
|
|
{
|
|
|
|
oldest = n;
|
|
|
|
age = i.last_access();
|
|
|
|
}
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (oldest)
|
|
|
|
{
|
|
|
|
TFile_info& i = (TFile_info&)_fileinfo[oldest];
|
|
|
|
i.auto_close();
|
|
|
|
_open_files--;
|
|
|
|
}
|
|
|
|
|
2004-03-12 16:01:27 +00:00
|
|
|
return oldest != 0; //verificare
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
2001-05-07 13:27:50 +00:00
|
|
|
// name : nome del file
|
|
|
|
TIsam_handle TFile_manager::get_handle(TFilename& name)
|
|
|
|
{
|
|
|
|
|
|
|
|
TFile_info* i = NULL;
|
|
|
|
TFilename fname(name); fname.ext("");
|
2004-03-12 16:01:27 +00:00
|
|
|
int num;
|
|
|
|
|
|
|
|
for (num = LF_EXTERNAL; (i = (TFile_info*)_fileinfo.objptr(num)) != NULL; num++)
|
2001-05-07 13:27:50 +00:00
|
|
|
{
|
|
|
|
if (i->pathname() == fname)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (i == NULL)
|
|
|
|
{
|
|
|
|
i = new TFile_info(num, name);
|
|
|
|
if (!i->ok())
|
|
|
|
{
|
|
|
|
delete i;
|
|
|
|
return -60;
|
|
|
|
}
|
|
|
|
_fileinfo.add(i, num);
|
|
|
|
}
|
|
|
|
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
// name : nome del file (vuoto per i file normali viene riempito automaticamente)
|
|
|
|
// logicnum: numero logico del file (LF_EXTERNAL per gli esterni viene generato automaticamente)
|
|
|
|
TIsam_handle TFile_manager::open(int& logicnum, TFilename& name, bool exclusive, bool index)
|
|
|
|
{
|
|
|
|
TIsam_handle num = logicnum;
|
2009-01-07 15:50:52 +00:00
|
|
|
if (name.full())
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
2001-05-07 13:27:50 +00:00
|
|
|
num = get_handle(name);
|
1998-03-30 13:50:30 +00:00
|
|
|
if (logicnum >= LF_EXTERNAL)
|
|
|
|
logicnum = num;
|
|
|
|
}
|
|
|
|
|
|
|
|
TFile_info* i = (TFile_info*)_fileinfo.objptr(num);
|
|
|
|
if (i == NULL)
|
|
|
|
{
|
|
|
|
i = new TFile_info(logicnum, name);
|
|
|
|
if (!i->ok())
|
|
|
|
{
|
|
|
|
delete i;
|
|
|
|
return -60;
|
|
|
|
}
|
|
|
|
_fileinfo.add(i, num);
|
|
|
|
}
|
|
|
|
i->open(exclusive, index);
|
|
|
|
name = i->pathname();
|
|
|
|
return num;
|
|
|
|
}
|
|
|
|
|
|
|
|
int TFile_manager::close(TIsam_handle& name)
|
|
|
|
{
|
|
|
|
int err = _isnotopen;
|
|
|
|
|
|
|
|
TFile_info* i = (TFile_info*)_fileinfo.objptr(name);
|
|
|
|
if (i != NULL)
|
|
|
|
{
|
1998-05-04 07:57:56 +00:00
|
|
|
const bool was_open = i->is_open();
|
1998-03-30 13:50:30 +00:00
|
|
|
err = i->close();
|
1998-06-24 07:11:33 +00:00
|
|
|
// Se chiuso veramente ... (Per efficienza non chiude sempre)
|
|
|
|
if (err == NOERR && !i->is_open())
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
1998-06-24 07:11:33 +00:00
|
|
|
if (was_open)
|
1998-05-04 07:57:56 +00:00
|
|
|
_open_files--;
|
1998-06-24 07:11:33 +00:00
|
|
|
if (name >= LF_EXTERNAL && i->ref_count() <= 0)
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
|
|
|
_fileinfo.remove(name);
|
|
|
|
_recinfo.remove(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
name = 0;
|
|
|
|
return err;
|
|
|
|
}
|
2008-06-23 14:01:03 +00:00
|
|
|
void TFile_manager::destroy_info(int logicnum)
|
|
|
|
{
|
|
|
|
_fileinfo.destroy(logicnum);
|
|
|
|
_recinfo.destroy(logicnum);
|
|
|
|
}
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
TCodeb_handle TFile_manager::get_handle(TIsam_handle name, int key)
|
|
|
|
{
|
|
|
|
TFile_info& i = fileinfo(name);
|
2009-03-19 15:50:04 +00:00
|
|
|
|
|
|
|
#ifdef DBG
|
1998-03-30 13:50:30 +00:00
|
|
|
if (i.ref_count() == 0)
|
2009-03-19 15:50:04 +00:00
|
|
|
{
|
|
|
|
NFCHECK("Sarebbe bene aggiungere una bella open_files(%d, ...) in TYour_app::create()", i.num());
|
|
|
|
i.open(false, true);
|
|
|
|
}
|
|
|
|
#endif
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
TCodeb_handle handle = i.handle();
|
|
|
|
if (handle < 0)
|
|
|
|
{
|
|
|
|
if (_open_files >= _max_open_files)
|
|
|
|
close_oldest();
|
|
|
|
|
2003-06-24 12:49:44 +00:00
|
|
|
// Se ho passato key = -1 mi va bene la chiave principale
|
|
|
|
if (key < 0)
|
|
|
|
key = 1;
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
handle = i.auto_open(key);
|
|
|
|
if (handle >= 0)
|
|
|
|
_open_files++;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2003-06-24 12:49:44 +00:00
|
|
|
// Se ho passato key = -1 mi va bene la chiave corrente
|
|
|
|
if (key >= 0 && i.last_key() != key)
|
1998-03-30 13:50:30 +00:00
|
|
|
handle = i.auto_open(key);
|
|
|
|
}
|
1999-01-19 09:15:17 +00:00
|
|
|
// i.touch(); // Memorizza troppo spesso l'accesso
|
1998-03-30 13:50:30 +00:00
|
|
|
return handle;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TFile_manager::lock_record(TIsam_handle num, TRecnotype rec)
|
|
|
|
{
|
|
|
|
TFile_info& i = fileinfo(num);
|
|
|
|
i.lock_record(rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TFile_manager::unlock_record(TIsam_handle num, TRecnotype rec)
|
|
|
|
{
|
|
|
|
TFile_info& i = fileinfo(num);
|
|
|
|
i.unlock_record(rec);
|
|
|
|
}
|
|
|
|
|
1998-06-24 07:11:33 +00:00
|
|
|
const RecDes& TFile_manager::get_recdes(int logicnum) const
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
|
|
|
const TRecord_info& i = recinfo(logicnum);
|
|
|
|
return i;
|
|
|
|
}
|
2008-03-21 16:39:47 +00:00
|
|
|
TToken_string& TFile_manager::get_relation(int fromlogic, int tologic) const
|
|
|
|
{
|
|
|
|
TRecord_info& i = recinfo(fromlogic);
|
|
|
|
return i.relation(tologic);
|
|
|
|
}
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
const RecDes& TFile_manager::update_recdes(int logicnum)
|
|
|
|
{
|
|
|
|
_recinfo.destroy(logicnum);
|
|
|
|
return get_recdes(logicnum);
|
|
|
|
}
|
|
|
|
|
|
|
|
int TFile_manager::get_reclen(int logicnum)
|
|
|
|
{
|
|
|
|
const TRecord_info& i = recinfo(logicnum);
|
|
|
|
return i.ok() ? i.len() : 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
TDirtype TFile_manager::get_dirtype(int logicnum)
|
|
|
|
{
|
|
|
|
const TRecord_info& i = recinfo(logicnum);
|
|
|
|
return i.dir_type();
|
|
|
|
}
|
|
|
|
|
1998-10-01 14:04:23 +00:00
|
|
|
void TFile_manager::notify_change(TIsam_handle name)
|
|
|
|
{
|
|
|
|
TFile_info& i = fileinfo(name);
|
|
|
|
i.set_dirty();
|
|
|
|
}
|
|
|
|
|
|
|
|
long TFile_manager::last_change(TIsam_handle name) const
|
|
|
|
{
|
|
|
|
TFile_info& i = fileinfo(name);
|
|
|
|
return i.last_change();
|
|
|
|
}
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
int TFile_manager::close_closeable()
|
|
|
|
{
|
|
|
|
_open_files = 0;
|
|
|
|
for (TIsam_handle n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
|
|
|
|
{
|
|
|
|
TFile_info& i = fileinfo(n);
|
1998-05-27 10:56:30 +00:00
|
|
|
if (i.is_open())
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
2008-04-04 16:04:15 +00:00
|
|
|
if (!i.is_locked() && !i.is_exclusive())
|
2008-02-13 13:31:25 +00:00
|
|
|
{
|
|
|
|
cache().discard(i.num());
|
1998-05-27 10:56:30 +00:00
|
|
|
i.auto_close();
|
2008-02-13 13:31:25 +00:00
|
|
|
}
|
1998-03-30 13:50:30 +00:00
|
|
|
else
|
1998-05-27 10:56:30 +00:00
|
|
|
_open_files++;
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
1998-05-27 10:56:30 +00:00
|
|
|
if (i.ref_count() <= 0)
|
|
|
|
_fileinfo.destroy(n);
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
return _open_files;
|
|
|
|
}
|
|
|
|
|
|
|
|
void TFile_manager::close_all()
|
|
|
|
{
|
|
|
|
const int zoccolo_duro = close_closeable();
|
2003-10-07 12:53:38 +00:00
|
|
|
#ifdef DBG
|
1998-03-30 13:50:30 +00:00
|
|
|
if (zoccolo_duro > 0)
|
2008-04-04 16:04:15 +00:00
|
|
|
NFCHECK("%d files refuse to be closed!", zoccolo_duro);
|
2003-10-07 12:53:38 +00:00
|
|
|
#endif
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
for (int n = _recinfo.last(); n > 0; n = _recinfo.pred(n))
|
|
|
|
{
|
|
|
|
const TRecord_info& r = recinfo(n);
|
|
|
|
if (r.mutable_dir())
|
|
|
|
_recinfo.destroy(n);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TFile_manager::open_all()
|
|
|
|
{
|
|
|
|
for (TIsam_handle n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
|
|
|
|
{
|
|
|
|
TFile_info& i = fileinfo(n);
|
|
|
|
if (!i.is_exclusive())
|
|
|
|
{
|
|
|
|
if (i.mutable_dir())
|
|
|
|
i.load_filedes();
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1998-06-24 07:11:33 +00:00
|
|
|
const FileDes& TFile_manager::get_filedes(TIsam_handle id) const
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
1998-06-24 07:11:33 +00:00
|
|
|
TFile_info& i = fileinfo(id);
|
1998-03-30 13:50:30 +00:00
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
1998-06-24 07:11:33 +00:00
|
|
|
const TFilename& TFile_manager::get_filename(TIsam_handle id) const
|
|
|
|
{
|
|
|
|
TFile_info& i = fileinfo(id);
|
|
|
|
return i.pathname();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
TFile_manager::TFile_manager()
|
|
|
|
: _open_files(0)
|
|
|
|
{
|
2008-12-23 09:05:22 +00:00
|
|
|
_max_open_files = xvt_sys_get_profile_int(NULL, "Main", "MaxHandles", 32);
|
2003-03-11 09:17:38 +00:00
|
|
|
if (_max_open_files < 16)
|
|
|
|
_max_open_files = 16;
|
1998-03-30 13:50:30 +00:00
|
|
|
else
|
2003-03-11 09:17:38 +00:00
|
|
|
if (_max_open_files > 64)
|
|
|
|
_max_open_files = 64;
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
1999-01-19 09:15:17 +00:00
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TFirm
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
bool TFirm::read(long cod)
|
|
|
|
{
|
|
|
|
int err = NOERR;
|
|
|
|
if (cod < 0L)
|
|
|
|
cod = prefix().get_codditta();
|
2009-03-19 15:50:04 +00:00
|
|
|
destroy();
|
2001-05-04 10:59:04 +00:00
|
|
|
TLocalisamfile ditte(LF_NDITTE);
|
1999-01-19 09:15:17 +00:00
|
|
|
if (cod > 0L)
|
|
|
|
{
|
2007-02-16 13:48:27 +00:00
|
|
|
ditte.put(NDT_CODDITTA, cod);
|
1999-01-19 09:15:17 +00:00
|
|
|
err = ditte.read();
|
|
|
|
}
|
2001-05-04 10:59:04 +00:00
|
|
|
else
|
|
|
|
err = ditte.first();
|
|
|
|
if (err == NOERR)
|
|
|
|
{
|
|
|
|
const TRectype& ditta = ditte.curr();
|
|
|
|
for (int f = ditta.items()-1; f >= 0; f--)
|
|
|
|
{
|
|
|
|
const char* name = ditta.fieldname(f);
|
2009-03-19 15:50:04 +00:00
|
|
|
add(name, ditta.get(name));
|
2001-05-04 10:59:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
NFCHECK("Can't read firm %ld: error %d", cod, err);
|
|
|
|
|
2009-03-19 15:50:04 +00:00
|
|
|
return items() > 0;
|
1999-01-19 09:15:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const TString& TFirm::get(const char* attr) const
|
|
|
|
{
|
2009-03-19 15:50:04 +00:00
|
|
|
const TString* str = (const TString*)objptr(attr);
|
1999-01-19 09:15:17 +00:00
|
|
|
if (str == NULL)
|
|
|
|
str = &EMPTY_STRING;
|
|
|
|
return *str;
|
|
|
|
}
|
|
|
|
|
|
|
|
long TFirm::get_long(const char* attr) const
|
|
|
|
{ return atol(get(attr)); }
|
|
|
|
|
|
|
|
long TFirm::codice() const
|
|
|
|
{
|
|
|
|
return get_long(NDT_CODDITTA);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TString& TFirm::codice_valuta() const
|
|
|
|
{
|
|
|
|
const TString& codval = get(NDT_VALUTA);
|
|
|
|
if (codval.empty())
|
2007-09-06 13:25:51 +00:00
|
|
|
return TCurrency::get_euro_val();
|
1999-01-19 09:15:17 +00:00
|
|
|
return codval;
|
|
|
|
}
|
|
|
|
|
2006-01-30 16:35:52 +00:00
|
|
|
const TString& TFirm::ragione_sociale() const
|
2008-04-04 16:04:15 +00:00
|
|
|
{
|
|
|
|
return get(NDT_RAGSOC);
|
2006-01-30 16:35:52 +00:00
|
|
|
}
|
|
|
|
|
1999-01-19 09:15:17 +00:00
|
|
|
TFirm::TFirm(long code)
|
2008-04-04 16:04:15 +00:00
|
|
|
{
|
|
|
|
read(code);
|
1999-01-19 09:15:17 +00:00
|
|
|
}
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TPrefix
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
2003-05-16 13:13:39 +00:00
|
|
|
TPrefix::TPrefix() : _filelevel(0), _stdlevel(0), _items(0), _firm(NULL)
|
1998-03-30 13:50:30 +00:00
|
|
|
{
|
|
|
|
_prefix = ".";
|
2008-10-07 09:02:41 +00:00
|
|
|
const char* prfx = CGetPref();
|
2003-03-27 12:14:51 +00:00
|
|
|
|
|
|
|
if (!fexist(__ptprf) || strchr(__ptprf, ' ') != NULL)
|
|
|
|
fatal_box(FR("Percorso dati non valido: '%s'"), __ptprf);
|
1998-03-30 13:50:30 +00:00
|
|
|
|
2008-10-07 09:02:41 +00:00
|
|
|
const TFilename dir(prfx);
|
2009-02-27 12:24:45 +00:00
|
|
|
long primaditta = atol(dir.name());
|
1998-03-30 13:50:30 +00:00
|
|
|
if (primaditta > 0L && !exist(primaditta))
|
2009-02-27 12:24:45 +00:00
|
|
|
{
|
|
|
|
TPointer_array ditte; firms(ditte);
|
|
|
|
primaditta = ditte.empty() ? 0L : ditte.get_long(0);
|
|
|
|
set_codditta(primaditta, TRUE);
|
|
|
|
}
|
1998-03-30 13:50:30 +00:00
|
|
|
|
|
|
|
DB_init();
|
2003-05-16 13:13:39 +00:00
|
|
|
|
|
|
|
set(""); // Dati standard
|
|
|
|
_stdlevel = filelevel();
|
|
|
|
set("DEF"); // Ditta corrente
|
1998-03-30 13:50:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
TPrefix::~TPrefix()
|
|
|
|
{
|
|
|
|
set();
|
1999-04-06 15:34:39 +00:00
|
|
|
if (_firm)
|
|
|
|
delete _firm;
|
2003-10-07 12:53:38 +00:00
|
|
|
_manager.close_all();
|
1998-03-30 13:50:30 +00:00
|
|
|
DB_exit();
|
|
|
|
}
|
1995-07-19 10:03:02 +00:00
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
1995-07-19 10:03:02 +00:00
|
|
|
// @mfunc Riapre tutti gli archivi della ditta attiva
|
|
|
|
void TPrefix::reopen() const
|
|
|
|
{
|
|
|
|
if (_prefix != ".")
|
|
|
|
{
|
2008-10-07 09:02:41 +00:00
|
|
|
TFile_manager& mgr = ((TPrefix*)this)->_manager; // Safe non const cast
|
|
|
|
mgr.close_all();
|
|
|
|
mgr.open_all();
|
1995-07-19 10:03:02 +00:00
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Setta la ditta corrente
|
|
|
|
void TPrefix::set(
|
|
|
|
const char* name, // @parm Nome del direttorio dati da attivare (default NULL)
|
2009-05-27 13:46:20 +00:00
|
|
|
bool force, // @parm Permette di settarla anche se non esiste (default false)
|
2003-01-07 12:20:49 +00:00
|
|
|
TFilelock mode) // @parm Permette di aprire la ditta in modo esclusivo (default _manulock)
|
1995-06-27 10:18:49 +00:00
|
|
|
|
|
|
|
// @comm Il parametro <p name> puo' assumere i seguenti valori:
|
|
|
|
//
|
|
|
|
// @flag NULL | Chiude tutti i files
|
|
|
|
// @flag COM | Apre il direttorio con i dati comuni
|
1996-02-05 19:00:53 +00:00
|
|
|
// @flag DEF | Riapre la ditta indicata nel file prefix.txt
|
1995-06-27 10:18:49 +00:00
|
|
|
// @flag codice ditta | Apre la ditta indicata
|
1996-05-14 11:11:50 +00:00
|
|
|
{
|
1994-09-07 17:00:25 +00:00
|
|
|
if (name == NULL)
|
|
|
|
{
|
1998-05-27 10:56:30 +00:00
|
|
|
close_closeable_isamfiles();
|
1994-09-07 17:00:25 +00:00
|
|
|
CCloseDir(NORDIR);
|
|
|
|
CCloseDir(COMDIR);
|
|
|
|
CCloseRecDir(NORDIR);
|
|
|
|
CCloseRecDir(COMDIR);
|
1995-01-27 18:00:47 +00:00
|
|
|
_prefix = ".";
|
1994-09-07 17:00:25 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
if (_prefix == name)
|
|
|
|
return;
|
|
|
|
if (!force && !test(name))
|
|
|
|
return;
|
1994-09-07 17:00:25 +00:00
|
|
|
if (_prefix != ".")
|
|
|
|
{
|
1998-03-30 13:50:30 +00:00
|
|
|
_manager.close_all();
|
1994-09-07 17:00:25 +00:00
|
|
|
CCloseDir(NORDIR);
|
|
|
|
CCloseDir(COMDIR);
|
|
|
|
CCloseRecDir(NORDIR);
|
|
|
|
CCloseRecDir(COMDIR);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (strcmp(name, "DEF") == 0)
|
|
|
|
{
|
2008-10-22 14:17:48 +00:00
|
|
|
const char* prfx = CGetPref();
|
2008-10-07 09:02:41 +00:00
|
|
|
xvt_fsys_parse_pathname(prfx, NULL, NULL, _prefix.get_buffer(), NULL, NULL);
|
2008-02-13 13:31:25 +00:00
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
_prefix = name;
|
2008-10-22 14:17:48 +00:00
|
|
|
if (_prefix.full())
|
|
|
|
{
|
|
|
|
const TString saved_prf = __ptprf; // Salvo __ptprf che viene cambiato da CGetPref
|
2008-10-22 15:12:30 +00:00
|
|
|
char* prfx = (char*)CGetPref(); // Safe non const cast for StPath cprefix
|
|
|
|
strcpy(__ptprf, saved_prf);
|
|
|
|
xvt_fsys_build_pathname(prfx, NULL, __ptprf, _prefix, NULL, NULL);
|
2008-10-22 14:17:48 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
char* prfx = (char*)CGetPref(); // Safe non const cast for StPath cprefix
|
|
|
|
*prfx = '\0';
|
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!test(_prefix))
|
|
|
|
fatal_box("Impossibile utilizzare la ditta %s", name);
|
|
|
|
|
|
|
|
COpenDir((int) mode, NORDIR);
|
|
|
|
COpenDir((int) mode, COMDIR);
|
|
|
|
COpenRecDir((int) mode, NORDIR);
|
|
|
|
COpenRecDir((int) mode, COMDIR);
|
|
|
|
if (_prefix != ".")
|
1994-09-27 10:01:39 +00:00
|
|
|
{
|
|
|
|
FileDes d;
|
|
|
|
CGetFile(LF_DIR, &d, _nolock, NORDIR);
|
|
|
|
_filelevel = d.Flags;
|
1994-12-27 14:59:25 +00:00
|
|
|
_items = (int)d.EOD;
|
1998-03-30 13:50:30 +00:00
|
|
|
_manager.open_all();
|
1994-09-27 10:01:39 +00:00
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
1994-11-10 11:22:47 +00:00
|
|
|
bool TPrefix::exist(long codditta) const
|
|
|
|
{
|
1998-05-04 07:57:56 +00:00
|
|
|
if (codditta > 0L && codditta < 100000L)
|
1994-11-10 11:22:47 +00:00
|
|
|
{
|
2009-03-19 15:50:04 +00:00
|
|
|
TFilename s = firm2dir(codditta);
|
1998-05-04 07:57:56 +00:00
|
|
|
s.add("dir.gen");
|
|
|
|
if (s.exist())
|
|
|
|
{
|
|
|
|
s = s.path();
|
|
|
|
s.add("trc.gen");
|
|
|
|
return s.exist();
|
|
|
|
}
|
1994-11-10 11:22:47 +00:00
|
|
|
}
|
2008-12-23 09:05:22 +00:00
|
|
|
return false;
|
1994-11-10 11:22:47 +00:00
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
|
|
|
|
bool TPrefix::test(const char* s) const
|
|
|
|
{
|
2006-12-13 16:22:33 +00:00
|
|
|
if (s && *s && strcmp(s, "DEF") != 0)
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
1995-04-10 15:28:03 +00:00
|
|
|
TFilename s1(__ptprf);
|
1997-10-30 16:14:49 +00:00
|
|
|
s1.add(s);
|
|
|
|
s1.add("dir.gen");
|
|
|
|
|
2006-12-13 16:22:33 +00:00
|
|
|
if (s1.exist())
|
|
|
|
{
|
|
|
|
if (xvt_fsys_access(s1, 0x2) != 0)
|
|
|
|
return error_box(FR("Impossibile accedere in lettura/scrittura al file '%s'"), (const char*)s1);
|
|
|
|
}
|
|
|
|
else
|
2003-03-27 12:14:51 +00:00
|
|
|
return error_box(FR("Impossibile trovare il file '%s'"), (const char*)s1);
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
2006-12-13 16:22:33 +00:00
|
|
|
return true;
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
1998-03-30 13:50:30 +00:00
|
|
|
void TPrefix::lock_record(TIsam_handle num, TRecnotype rec)
|
|
|
|
{
|
|
|
|
_manager.lock_record(num, rec);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TPrefix::unlock_record(TIsam_handle num, TRecnotype rec)
|
|
|
|
{
|
|
|
|
_manager.unlock_record(num, rec);
|
|
|
|
}
|
|
|
|
|
1994-09-07 17:00:25 +00:00
|
|
|
bool TPrefix::test(long codditta) const
|
|
|
|
{
|
2006-01-30 16:35:52 +00:00
|
|
|
TString8 s("com");
|
1997-06-12 15:53:39 +00:00
|
|
|
if (codditta > 0L)
|
2004-03-12 16:01:27 +00:00
|
|
|
s.format("%05lda", codditta);
|
1994-09-07 17:00:25 +00:00
|
|
|
return test(s);
|
|
|
|
}
|
|
|
|
|
|
|
|
long TPrefix::get_codditta() const
|
|
|
|
{
|
1997-12-02 13:21:19 +00:00
|
|
|
const long codditta = atol(_prefix);
|
1994-09-07 17:00:25 +00:00
|
|
|
return codditta;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TPrefix::set_codditta(long codditta, bool force)
|
|
|
|
{
|
|
|
|
if (force || test(codditta))
|
|
|
|
{
|
2006-01-30 16:35:52 +00:00
|
|
|
TString8 s("com");
|
1997-06-12 15:53:39 +00:00
|
|
|
if (codditta > 0L)
|
2001-09-19 14:52:11 +00:00
|
|
|
s.format("%05lda", codditta);
|
1994-09-07 17:00:25 +00:00
|
|
|
set(s, force);
|
1997-12-02 13:21:19 +00:00
|
|
|
CPutPref(_prefix);
|
2009-03-19 15:50:04 +00:00
|
|
|
if (_firm && _firm->read(codditta))
|
2008-12-23 09:05:22 +00:00
|
|
|
{
|
2009-03-19 15:50:04 +00:00
|
|
|
TConfig ini(CONFIG_DITTA, "Main");
|
|
|
|
FOR_EACH_ASSOC_STRING((*_firm), h, key, str)
|
|
|
|
{
|
|
|
|
if (*str > ' ')
|
|
|
|
ini.set(key, str);
|
|
|
|
}
|
2008-12-23 09:05:22 +00:00
|
|
|
}
|
|
|
|
return true;
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
2008-12-16 10:25:17 +00:00
|
|
|
return false;
|
1994-09-07 17:00:25 +00:00
|
|
|
}
|
|
|
|
|
1997-12-02 13:21:19 +00:00
|
|
|
const char* TPrefix::get_studio() const
|
|
|
|
{
|
|
|
|
return __ptprf;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool TPrefix::set_studio(const char* study, long ditta)
|
1997-12-17 10:40:18 +00:00
|
|
|
{
|
|
|
|
TFilename dirtest(study);
|
2003-03-27 12:14:51 +00:00
|
|
|
if (!dirtest.exist() || dirtest.find(' ') >= 0)
|
2008-10-22 14:17:48 +00:00
|
|
|
return false;
|
2003-03-27 12:14:51 +00:00
|
|
|
|
1997-12-17 10:40:18 +00:00
|
|
|
dirtest.add("com/dir.gen");
|
1998-02-24 10:37:28 +00:00
|
|
|
if (!dirtest.exist())
|
2008-10-22 14:17:48 +00:00
|
|
|
return false;
|
1997-12-02 13:21:19 +00:00
|
|
|
|
2003-05-12 13:52:48 +00:00
|
|
|
// Chiudi tutti i files!
|
|
|
|
_manager.close_all();
|
|
|
|
|
1997-12-02 13:21:19 +00:00
|
|
|
const TString old_study(__ptprf);
|
|
|
|
const TString old_firm(_prefix);
|
|
|
|
|
|
|
|
strcpy(__ptprf, study);
|
|
|
|
const word len = strlen(__ptprf);
|
|
|
|
if (len > 0 && __ptprf[len-1] != '\\' && __ptprf[len-1] != '/')
|
|
|
|
{
|
|
|
|
__ptprf[len] = SLASH;
|
|
|
|
__ptprf[len+1] = '\0';
|
|
|
|
}
|
|
|
|
if (!test(ditta))
|
|
|
|
ditta = 0L;
|
|
|
|
|
|
|
|
bool ok = set_codditta(ditta, TRUE);
|
|
|
|
if (!ok)
|
|
|
|
{
|
|
|
|
strcpy(__ptprf, old_study);
|
2009-05-27 13:46:20 +00:00
|
|
|
set(old_firm, true);
|
1997-12-02 13:21:19 +00:00
|
|
|
}
|
|
|
|
return ok;
|
|
|
|
}
|
|
|
|
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
1994-12-27 14:59:25 +00:00
|
|
|
|
1995-06-27 10:18:49 +00:00
|
|
|
// @mfunc Ritorna la descrizione del file passato
|
|
|
|
const char* TPrefix::description(
|
|
|
|
const char* cod) const // @parm Nome del file di cui si vuole conoscere la descrizione
|
|
|
|
|
|
|
|
// @syntax const char* description(const char* cod);
|
|
|
|
// @syntax const char* description(int cod);
|
|
|
|
//
|
|
|
|
// @comm Il parametro <p cod> puo' indicare anche il nome di una tabella. In questo caso ne
|
|
|
|
// ritorna la descrizione.
|
|
|
|
// <nl>Passando il nome di una tabella in <p cod> si ottiene la stessa cosa della
|
|
|
|
// funzione <mf TDir::Tab_des>, ma viene cercato la descrizione nel titolo della maschera.
|
1994-12-27 14:59:25 +00:00
|
|
|
{
|
2003-04-22 14:01:02 +00:00
|
|
|
TString& n = get_tmp_string();
|
|
|
|
n = cod;
|
1994-12-27 14:59:25 +00:00
|
|
|
|
|
|
|
if (n[0] == '%')
|
|
|
|
n.ltrim(1);
|
|
|
|
|
|
|
|
const int logicnum = atoi(n);
|
|
|
|
if (logicnum == 0)
|
|
|
|
{
|
1997-08-27 09:53:29 +00:00
|
|
|
TTable t(cod);
|
|
|
|
n = t.description();
|
1994-12-27 14:59:25 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (logicnum > 0 && logicnum < items())
|
|
|
|
{
|
1997-08-27 09:53:29 +00:00
|
|
|
TBaseisamfile f(logicnum);
|
1994-12-27 14:59:25 +00:00
|
|
|
n = f.description();
|
|
|
|
}
|
|
|
|
else n.cut(0);
|
|
|
|
}
|
|
|
|
|
2003-04-22 14:01:02 +00:00
|
|
|
return n;
|
1994-12-27 14:59:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* TPrefix::description(int cod) const
|
|
|
|
{
|
2006-12-13 16:22:33 +00:00
|
|
|
TString8 n; n << cod;
|
1994-12-27 14:59:25 +00:00
|
|
|
return description(n);
|
|
|
|
}
|
|
|
|
|
1999-01-19 09:15:17 +00:00
|
|
|
const TFirm& TPrefix::firm()
|
|
|
|
{
|
|
|
|
if (_firm == NULL)
|
2003-01-07 12:20:49 +00:00
|
|
|
_firm = new TFirm;
|
1999-01-19 09:15:17 +00:00
|
|
|
return *_firm;
|
|
|
|
}
|
|
|
|
|
1994-09-13 16:43:52 +00:00
|
|
|
// Certified 90%
|
1996-02-05 19:00:53 +00:00
|
|
|
// @doc EXTERNAL
|
|
|
|
|
|
|
|
// @func Converte il numero di una ditta nella sua directory dati
|
|
|
|
//
|
|
|
|
// @rdesc Restituisce il nome di una directory dati
|
2007-02-16 13:48:27 +00:00
|
|
|
// @parm Codice ditta da convertire
|
|
|
|
const char* firm2dir(long codditta)
|
1994-09-07 17:00:25 +00:00
|
|
|
{
|
2003-04-22 14:01:02 +00:00
|
|
|
TString8 firm;
|
1994-09-13 16:43:52 +00:00
|
|
|
switch (codditta)
|
|
|
|
{
|
|
|
|
case -2: // Dati generali campione
|
|
|
|
case -1: // Dati di studio
|
2008-10-22 14:17:48 +00:00
|
|
|
firm.cut(0); break;
|
1994-09-13 16:43:52 +00:00
|
|
|
case 0: // Dati comuni
|
1997-12-02 13:21:19 +00:00
|
|
|
firm = "com"; break;
|
1994-09-13 16:43:52 +00:00
|
|
|
default: // Dati ditta
|
1997-12-02 13:21:19 +00:00
|
|
|
firm.format("%05lda", codditta); break;
|
1994-09-13 16:43:52 +00:00
|
|
|
}
|
2003-04-22 14:01:02 +00:00
|
|
|
|
2009-03-19 15:50:04 +00:00
|
|
|
if (__ptprf[0] == '\0')
|
|
|
|
{
|
|
|
|
CGetPref();
|
|
|
|
CHECK(__ptprf[0], "Invalid prefix");
|
|
|
|
}
|
|
|
|
|
2008-10-22 14:17:48 +00:00
|
|
|
TString& path = get_tmp_string(_MAX_PATH);
|
|
|
|
xvt_fsys_build_pathname(path.get_buffer(), "", __ptprf, firm, NULL, NULL);
|
2003-04-22 14:01:02 +00:00
|
|
|
return path;
|
1997-06-19 15:14:28 +00:00
|
|
|
}
|
1994-09-07 17:00:25 +00:00
|
|
|
|
1998-10-01 14:04:23 +00:00
|
|
|
int safely_close_closeable_isamfiles()
|
|
|
|
{
|
|
|
|
int f = 0;
|
|
|
|
if (_prefhndl)
|
|
|
|
f = _prefhndl->close_closeable_isamfiles();
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
1998-02-24 10:37:28 +00:00
|
|
|
bool TPrefix::build_firm_data(long codditta, bool flagcom)
|
|
|
|
{
|
2003-10-27 15:06:54 +00:00
|
|
|
const char* const ndir = "dir.gen";
|
|
|
|
const char* const ntrc = "trc.gen";
|
2003-10-14 13:42:54 +00:00
|
|
|
TFilename s(firm2dir(codditta)); s.add(ndir);
|
1998-02-24 10:37:28 +00:00
|
|
|
bool exist = s.exist();
|
|
|
|
|
|
|
|
if (!exist)
|
|
|
|
{
|
2003-10-14 13:42:54 +00:00
|
|
|
s = s.path(); s.add(ntrc);
|
1998-02-24 10:37:28 +00:00
|
|
|
exist = s.exist();
|
|
|
|
}
|
|
|
|
if (exist)
|
|
|
|
return message_box("Direttorio dati danneggiato, impossibile attivare la ditta %ld", codditta);
|
|
|
|
if (!yesno_box("Gli archivi della ditta %ld non esistono: si desidera generarli?", codditta))
|
2009-05-27 13:46:20 +00:00
|
|
|
return false;
|
1998-02-24 10:37:28 +00:00
|
|
|
|
|
|
|
set_autoload_new_files(yesno_box("Si desidera precaricare gli archivi standard"));
|
2003-10-14 13:42:54 +00:00
|
|
|
s = s.path(); s.rtrim(1);
|
1998-02-24 10:37:28 +00:00
|
|
|
|
|
|
|
if (!s.exist() && !make_dir(s))
|
|
|
|
return error_box("Impossibile creare il direttorio della ditta %ld (%s)",
|
|
|
|
codditta, (const char*)s);
|
|
|
|
|
2003-10-14 13:42:54 +00:00
|
|
|
s.add(ndir);
|
2003-10-27 15:06:54 +00:00
|
|
|
if (!fcopy(ndir, s))
|
1998-02-24 10:37:28 +00:00
|
|
|
return error_box("Impossibile copiare il file %s della ditta %ld",
|
2003-10-27 15:06:54 +00:00
|
|
|
ndir, codditta);
|
2003-10-14 13:42:54 +00:00
|
|
|
s = s.path(); s.add(ntrc);
|
2003-10-27 15:06:54 +00:00
|
|
|
if (!fcopy(ntrc, s))
|
1998-02-24 10:37:28 +00:00
|
|
|
return error_box("Impossibile copiare il file %s della ditta %ld",
|
|
|
|
ntrc, codditta);
|
|
|
|
|
|
|
|
TDir dir, dir1;
|
|
|
|
TTrec rec;
|
|
|
|
|
2006-12-13 16:22:33 +00:00
|
|
|
set("");
|
1998-02-24 10:37:28 +00:00
|
|
|
dir1.get(LF_DIR, _nolock, _nordir, _sysdirop);
|
|
|
|
const long maxeod0 = dir1.eod();
|
|
|
|
|
2006-12-13 16:22:33 +00:00
|
|
|
set_codditta(codditta);
|
1998-02-24 10:37:28 +00:00
|
|
|
dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
|
|
|
|
if (dir.eod() == 0)
|
|
|
|
{
|
2008-12-10 16:52:43 +00:00
|
|
|
dir1.set_eod(1);
|
1998-02-24 10:37:28 +00:00
|
|
|
dir1.put(LF_DIR, _nordir, _sysdirop);
|
|
|
|
dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
|
|
|
|
}
|
2008-12-04 16:37:47 +00:00
|
|
|
const long maxeod1 = dir.eod();
|
1998-02-24 10:37:28 +00:00
|
|
|
|
|
|
|
if (maxeod0 > maxeod1)
|
|
|
|
{
|
|
|
|
dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
|
2008-12-10 16:52:43 +00:00
|
|
|
dir.set_eod(maxeod0);
|
1998-02-24 10:37:28 +00:00
|
|
|
dir.put(LF_DIR, _nordir, _sysdirop);
|
|
|
|
rec.zero();
|
|
|
|
}
|
2007-09-17 15:33:04 +00:00
|
|
|
TString mess(TR("Generazione archivi della ditta ")); mess << codditta;
|
2009-05-27 13:46:20 +00:00
|
|
|
TProgind p(maxeod0 ? maxeod0 : 1, mess, false, TRUE);
|
1998-02-24 10:37:28 +00:00
|
|
|
|
2007-09-17 15:33:04 +00:00
|
|
|
for (int i = LF_USER; i <= maxeod0; i++)
|
1998-02-24 10:37:28 +00:00
|
|
|
{
|
|
|
|
p.addstatus(1);
|
2006-12-13 16:22:33 +00:00
|
|
|
set("");
|
1998-02-24 10:37:28 +00:00
|
|
|
dir.get(i, _nolock, _nordir, _sysdirop);
|
|
|
|
rec.get(i);
|
|
|
|
bool create_now = dir.is_active();
|
|
|
|
|
|
|
|
prefix().set_codditta(codditta);
|
|
|
|
dir.put(i, _nordir, _sysdirop);
|
|
|
|
rec.put(i);
|
2008-12-10 16:52:43 +00:00
|
|
|
dir.set_flags(0);
|
1998-02-24 10:37:28 +00:00
|
|
|
create_now = create_now && (flagcom ? dir.is_com() : dir.is_firm());
|
|
|
|
|
|
|
|
if (dir.is_valid() && create_now)
|
|
|
|
{
|
|
|
|
TSystemisamfile f(i);
|
2009-05-27 13:46:20 +00:00
|
|
|
f.build();
|
1998-02-24 10:37:28 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
dir.put(i, _nordir, _sysdirop);
|
|
|
|
rec.put(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
TConfig c(CONFIG_STUDIO, "cg");
|
|
|
|
if (c.get_bool("StiReg"))
|
|
|
|
{
|
|
|
|
TTable reg("REG");
|
|
|
|
for (reg.first(_lock); reg.good(); reg.next(_lock))
|
|
|
|
{
|
|
|
|
reg.put("B9", "X");
|
|
|
|
reg.rewrite();
|
|
|
|
}
|
|
|
|
}
|
2006-12-13 16:22:33 +00:00
|
|
|
set_codditta(codditta);
|
1998-02-24 10:37:28 +00:00
|
|
|
set_autoload_new_files(TRUE);
|
|
|
|
|
2007-03-06 16:37:44 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2009-03-19 15:50:04 +00:00
|
|
|
int TPrefix::firms(TString_array& codes)
|
2008-12-16 10:25:17 +00:00
|
|
|
{
|
|
|
|
codes.destroy();
|
|
|
|
TFilename n = __ptprf; n.add("?????A");
|
|
|
|
SLIST dirs = xvt_fsys_list_files(DIR_TYPE, n, true);
|
|
|
|
for (SLIST_ELT e = xvt_slist_get_first(dirs); e; e = xvt_slist_get_next(dirs, e))
|
|
|
|
{
|
|
|
|
n = xvt_slist_get(dirs, e, NULL);
|
|
|
|
const TString& code = n.name_only();
|
2009-03-19 15:50:04 +00:00
|
|
|
TFilename s = firm2dir(atol(code));
|
|
|
|
s.add("dir.gen");
|
|
|
|
if (s.exist())
|
2008-12-16 10:25:17 +00:00
|
|
|
codes.add(code);
|
|
|
|
}
|
|
|
|
xvt_slist_destroy(dirs);
|
|
|
|
return codes.items();
|
|
|
|
}
|
|
|
|
|
2009-03-19 15:50:04 +00:00
|
|
|
int TPrefix::firms(TPointer_array& codes)
|
2008-12-16 10:25:17 +00:00
|
|
|
{
|
|
|
|
TString_array strcodes; firms(strcodes);
|
|
|
|
FOR_EACH_ARRAY_ROW(strcodes, t, row)
|
|
|
|
codes.add_long(atol(*row));
|
|
|
|
return codes.items();
|
|
|
|
}
|
|
|
|
|
2009-03-19 15:50:04 +00:00
|
|
|
int TPrefix::firms(TArray& ditte)
|
|
|
|
{
|
|
|
|
ditte.destroy();
|
|
|
|
TPointer_array codes; firms(codes);
|
|
|
|
for (int i = 0; i < codes.items(); i++)
|
|
|
|
{
|
|
|
|
const long codditta = codes.get_long(i);
|
|
|
|
TFilename ininame = firm2dir(codditta);
|
|
|
|
ininame.add("ditta.ini");
|
|
|
|
TConfig ini(ininame, "Main");
|
|
|
|
TAssoc_array& fields = ini.list_variables();
|
|
|
|
if (fields.empty() && prefix_valid())
|
|
|
|
{
|
|
|
|
TLocalisamfile nditte(LF_NDITTE);
|
|
|
|
TRectype& ditta = nditte.curr();
|
|
|
|
ditta.put(NDT_CODDITTA, codditta);
|
|
|
|
if (nditte.read() == NOERR)
|
|
|
|
{
|
|
|
|
for (int f = 0; f < ditta.items(); f++)
|
|
|
|
{
|
|
|
|
const char* fname = ditta.fieldname(f);
|
|
|
|
const TString& value = ditta.get(fname);
|
|
|
|
if (!value.blank())
|
|
|
|
ini.set(fname, value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (fields.empty())
|
|
|
|
{
|
|
|
|
ini.set(NDT_CODDITTA, codditta);
|
|
|
|
CHECK(!fields.empty(), "Can't genenerate firm data");
|
|
|
|
}
|
|
|
|
ditte.add(fields);
|
|
|
|
}
|
|
|
|
return ditte.items();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-03-06 16:37:44 +00:00
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
// TTable name converter
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
class TTable_names : public TObject
|
|
|
|
{
|
|
|
|
TAssoc_array _names;
|
|
|
|
TArray _ids;
|
|
|
|
long _filled;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void fill();
|
|
|
|
void add_file(int logic, const TString& table);
|
|
|
|
|
|
|
|
public:
|
|
|
|
const TString& name(int logic_num);
|
|
|
|
int logic_num(const TString& name);
|
|
|
|
|
|
|
|
TTable_names() : _filled(-1) { }
|
|
|
|
} _table_names;
|
|
|
|
|
|
|
|
void TTable_names::add_file(int logic, const TString& table)
|
|
|
|
{
|
2008-12-04 16:37:47 +00:00
|
|
|
TString8 id; id << logic;
|
2007-03-06 16:37:44 +00:00
|
|
|
_names.add(table, id);
|
|
|
|
_ids.add(table, logic);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TTable_names::fill()
|
|
|
|
{
|
|
|
|
if (_filled != prefix().get_codditta())
|
|
|
|
{
|
|
|
|
FileDes dir;
|
|
|
|
CGetFile(LF_DIR, &dir, _nolock, NORDIR);
|
|
|
|
const int nfiles = (int)dir.EOD;
|
|
|
|
|
|
|
|
TFilename n;
|
|
|
|
for (int logic = LF_USER; logic <= nfiles; logic++)
|
|
|
|
{
|
2008-12-03 16:35:19 +00:00
|
|
|
n = prefix().get_filename(logic);
|
|
|
|
n = n.name_only(); n.upper();
|
2007-06-01 14:54:57 +00:00
|
|
|
if (_names.objptr(n) == NULL)
|
2007-03-06 16:37:44 +00:00
|
|
|
add_file(logic, n);
|
|
|
|
}
|
|
|
|
_filled = prefix().get_codditta();
|
|
|
|
}
|
1998-02-24 10:37:28 +00:00
|
|
|
}
|
2002-12-18 10:56:10 +00:00
|
|
|
|
2007-03-06 16:37:44 +00:00
|
|
|
int TTable_names::logic_num(const TString& n)
|
|
|
|
{
|
|
|
|
// Non cambiare: n puo' essere temporaneo e pieno di spazi!
|
|
|
|
TString80 name = n; name.trim();
|
2007-06-01 14:54:57 +00:00
|
|
|
const int namelen = name.len();
|
2007-03-06 16:37:44 +00:00
|
|
|
if (isdigit(name[0]) || name[0] == '-')
|
|
|
|
{
|
|
|
|
int num = atoi(name);
|
2007-06-01 14:54:57 +00:00
|
|
|
if (name[namelen-1] == '@')
|
2007-03-06 16:37:44 +00:00
|
|
|
num = -num;
|
|
|
|
return num;
|
|
|
|
}
|
2007-06-01 14:54:57 +00:00
|
|
|
|
2007-06-04 10:35:18 +00:00
|
|
|
name.upper();
|
|
|
|
// ATTENZIONE: NON includere qui MAG!
|
2007-07-10 15:22:49 +00:00
|
|
|
if (namelen == 3 && name != "DOC" && name != "MOV" && name != "RIP" && name != "CDC")
|
2007-06-01 14:54:57 +00:00
|
|
|
return LF_TAB;
|
2008-10-28 19:52:45 +00:00
|
|
|
switch (name[0])
|
2008-07-25 07:59:03 +00:00
|
|
|
{
|
|
|
|
case '^': return LF_TABGEN;
|
|
|
|
case '%': return LF_TABCOM;
|
|
|
|
case '$': return LF_TAB;
|
|
|
|
case '&': return LF_TABMOD;
|
|
|
|
default : break;
|
|
|
|
}
|
2007-03-06 16:37:44 +00:00
|
|
|
|
|
|
|
TString* str = (TString*)_names.objptr(name);
|
|
|
|
if (str == NULL)
|
|
|
|
{
|
|
|
|
fill();
|
|
|
|
str = (TString*)_names.objptr(name);
|
|
|
|
}
|
|
|
|
|
|
|
|
return str == NULL ? 0 : atoi(*str);
|
|
|
|
}
|
|
|
|
|
|
|
|
const TString& TTable_names::name(int logic_num)
|
|
|
|
{
|
|
|
|
TString* str = (TString*)_ids.objptr(logic_num);
|
|
|
|
if (str == NULL)
|
|
|
|
{
|
|
|
|
fill();
|
|
|
|
str = (TString*)_ids.objptr(logic_num);
|
|
|
|
}
|
|
|
|
return str == NULL ? (const TString&)EMPTY_STRING : *str;
|
|
|
|
}
|
|
|
|
|
|
|
|
const TString& logic2table(int logic_num)
|
|
|
|
{ return _table_names.name(logic_num); }
|
|
|
|
|
|
|
|
int table2logic(const TString& name)
|
|
|
|
{ return _table_names.logic_num(name); }
|