campo-sirio/include/prefix.cpp

1290 lines
28 KiB
C++
Raw Normal View History

#include <codeb.h>
#include <diction.h>
#include <extcdecl.h>
#include <currency.h>
#include <prefix.h>
#include <progind.h>
#include <scanner.h>
#include <tabutil.h>
#include <utility.h>
#include <nditte.h>
// Definita in isam.cpp
extern int get_error(int);
///////////////////////////////////////////////////////////
// extern variables are NO-NO!
///////////////////////////////////////////////////////////
HIDDEN TPrefix* _prefhndl = NULL;
// @doc EXTERNAL
// @func Inizializza (crea) un nuovo file "prefix.txt"
//
// @rdesc Ritorna l'oggetto <c TPrefix> creato
TPrefix& prefix_init()
{
CHECK(_prefhndl == NULL, "Can't create two prefix objects");
_prefhndl = new TPrefix;
return *_prefhndl;
}
// @doc EXTERNAL
// @func Determina se il prefix e' stato inizializzato
//
// @rdesc Ritorna TRUE o FALSE
bool prefix_valid()
{
return _prefhndl != NULL;
}
// @doc EXTERNAL
// @func Legge il file "prefix.txt"
//
// @rdesc Ritorna l'oggetto <c TPrefix> letto
TPrefix& prefix()
{
CHECK(_prefhndl, "Can't access null prefix");
return *_prefhndl;
}
// @doc EXTERNAL
// @func Distrugge l'oggett <c TPrefix> in memoria
void prefix_destroy()
{
if (_prefhndl != NULL)
{
delete _prefhndl;
_prefhndl = NULL;
}
}
///////////////////////////////////////////////////////////
// TFile_manager
///////////////////////////////////////////////////////////
class TRecord_info : public TObject
{
RecDes _recdes;
TDirtype _dirtype;
int _len;
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; }
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
{
// 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
int paren2,last,from,to;
if (paren1 >= 0 && is_sub && is_upper)
paren1 = ws.find('('); // Trova la seconda parentesi (in questo caso c'e' per forza)
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" : " ");
}
bool TRecord_info::ok() const
{
return _recdes.NFields > 0 &&
_recdes.NKeys > 0 && _recdes.NKeys < MaxKeys;
}
void TRecord_info::compute_len()
{
_len = 0;
for (int f = _recdes.NFields-1; f >= 0; f--)
_len += _recdes.Fd[f].Len;
if (_len > 0)
_len++;
}
TRecord_info::TRecord_info(int logicnum)
{
memset(&_recdes, 0, sizeof(_recdes));
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)
{
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);
}
memcpy(&_recdes, rec.rec(), sizeof(RecDes));
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;
int err = DB_recinfo(fname, &fd, rec.rec(), keys.get_buffer());
if (err != NOERR)
create(rec, keys);
else
memset(&_recdes, 0, sizeof(_recdes));
}
else
memset(&_recdes, 0, sizeof(_recdes));
}
class TFile_info : public TObject
{
TFilename _name;
int _ref_count;
int _num;
int _handle;
clock_t _last_access, _last_change;
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; }
clock_t last_change() const { return _last_change; }
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(); }
void set_dirty() { _last_change = clock(); }
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
error_box("You shouldn't reopen file %s", (const char*)_name);
#endif
int err = NOERR;
if (_handle >= 0)
{
if (num() < LF_EXTERNAL && (_dir == _nordir || _dir == _comdir))
{
TRecnotype n = DB_reccount(_handle);
TDir d;
d.get(num(),_nolock,_dir,_sysdirop);
_filedes.EOD = d.eod() = n;
_filedes.EOX = d.eox() = n;
d.put(num(),_dir,_sysdirop);
}
if (index)
err = DB_tagselect(_handle, _last_key = 1);
else
_last_key = 0;
}
else
{
err = get_error(_handle);
}
return err;
}
int TFile_info::close_low()
{
int err = NOERR;
if (_handle >= 0)
{
DB_close(_handle);
_handle = -1;
_last_key = -1;
_exclusive = _locked = FALSE;
}
else
{
#ifdef DBG
error_box("You shouldn't reclose file %s", (const char*)_name);
#endif
err = _isnotopen;
}
return err;
}
int TFile_info::open(bool exclusive, bool index)
{
int err = NOERR;
if (exclusive || !index)
{
if (_ref_count > 0 || is_open())
{
#ifdef DBG
if (_ref_count > 0)
error_box("You shouldn't reopen file %d exclusively", num());
#endif
close_low();
}
_exclusive = _locked = TRUE;
err = open_low(exclusive, index);
}
touch(); // Memorizza ora apertura del file
_ref_count++;
return err;
}
int TFile_info::close()
{
int err = NOERR;
if (_ref_count > 0)
{
_ref_count--;
if (_ref_count == 0)
{
if (is_open())
{
// Chiudi fisicamente solo se necessario
if (_locked || _exclusive || dir_type() == _extdir)
err = close_low();
}
_locked = _exclusive = FALSE;
}
}
else
err = _isnotopen;
return err;
}
void TFile_info::auto_close()
{
const bool yes = is_open() && !(is_locked() || is_exclusive());
if (yes)
close_low();
else
NFCHECK("Can't auto_close file '%s'", (const char*)_name);
}
int TFile_info::auto_open(int key)
{
if (_handle < 0)
open_low(FALSE, TRUE);
if (_handle >= 0)
{
if (key > 0 && key != _last_key)
{
const int err = DB_tagselect(_handle, _last_key = key);
if (err != NOERR)
{
#ifdef DBG
NFCHECK("Can't set key %d on file %d", key, num());
#endif
return err;
}
}
}
return _handle;
}
void TFile_info::lock_record(TRecnotype)
{ _locked = TRUE; }
void TFile_info::unlock_record(TRecnotype)
{ _locked = FALSE; }
const TFilename& TFile_info::load_filedes()
{
memset(&_filedes, 0, sizeof(_filedes));
CGetFile(num(), &_filedes, _nolock, _nordir);
if (_filedes.SysName[0])
{
if (_filedes.SysName[0] != '$')
_dir = _comdir;
else
_dir = _nordir;
COpenFile(num(), &_filedes, _nolock, _dir);
_name = _filedes.SysName;
}
else
_name.cut(0);
return _name;
}
TFile_info::TFile_info(int logicnum, TFilename& name)
: _num(logicnum), _handle(-1), _ref_count(0),
_locked(FALSE), _exclusive(FALSE),
_last_access(0), _last_change(0), _last_key(-1)
{
if (logicnum < LF_EXTERNAL)
{
load_filedes();
if (name.not_empty())
{
// File dati temporaneo
_dir = _extdir;
_name = name;
_name.ext("");
}
else
name = _name;
}
else
{
// File dati esterno
_dir = _extdir;
_name = name;
_name.ext("dbf");
if (_name.exist())
{
TToken_string keys(256*MaxKeys, '$');
_name.ext("");
TTrec rec;
int err = DB_recinfo(_name, &_filedes, rec.rec(), keys.get_buffer());
if (err == NOERR && prefix().add_recdes(logicnum, rec, keys))
{
strncpy(_filedes.SysName, _name, 40);
_filedes.SysName[41] = '\0';
}
else
_name.cut(0);
}
else
_name.cut(0);
}
}
TFile_info::~TFile_info()
{
if (is_open())
close_low();
}
TFile_info& TFile_manager::fileinfo(TIsam_handle num) const
{
TFile_info* i = (TFile_info*)_fileinfo.objptr(num);
if (i == NULL && num > 0 && num < LF_EXTERNAL)
{
TFilename name;
i = new TFile_info(num, name);
if (i->ok())
((TFile_manager*)this)->_fileinfo.add(i, num);
else
{
delete i;
i = NULL;
}
}
CHECKD(i, "Unknown file ", num);
return *i;
}
TRecord_info& TFile_manager::recinfo(int logicnum) const
{
TRecord_info* i = (TRecord_info*)_recinfo.objptr(logicnum);
if (i == NULL)
{
i = new TRecord_info(logicnum);
((TFile_manager*)this)->_recinfo.add(i, logicnum);
}
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
{
delete i;
i = NULL;
}
}
return i != NULL;
}
bool TFile_manager::close_oldest()
{
int oldest = 0;
clock_t age = 0;
_open_files = 0; // Intanto ricalcolo il numero di file veramente aperti
for (int n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
{
TFile_info& i = (TFile_info&)_fileinfo[n];
if (i.is_open())
{
_open_files++;
if (!i.is_locked() && !i.is_exclusive())
{
if (oldest == 0 || i.last_access() < age)
{
oldest = n;
age = i.last_access();
}
}
}
}
if (oldest)
{
TFile_info& i = (TFile_info&)_fileinfo[oldest];
i.auto_close();
_open_files--;
}
return oldest != NULL;
}
// name : nome del file
TIsam_handle TFile_manager::get_handle(TFilename& name)
{
TFile_info* i = NULL;
TFilename fname(name); fname.ext("");
for (int num = LF_EXTERNAL; (i = (TFile_info*)_fileinfo.objptr(num)) != NULL; num++)
{
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;
}
// 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;
if (name.not_empty())
{
num = get_handle(name);
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)
{
const bool was_open = i->is_open();
err = i->close();
// Se chiuso veramente ... (Per efficienza non chiude sempre)
if (err == NOERR && !i->is_open())
{
if (was_open)
_open_files--;
if (name >= LF_EXTERNAL && i->ref_count() <= 0)
{
_fileinfo.remove(name);
_recinfo.remove(name);
}
}
}
name = 0;
return err;
}
TCodeb_handle TFile_manager::get_handle(TIsam_handle name, int key)
{
TFile_info& i = fileinfo(name);
if (i.ref_count() == 0)
NFCHECK("Can't use closed file %d", i.num());
TCodeb_handle handle = i.handle();
if (handle < 0)
{
if (_open_files >= _max_open_files)
close_oldest();
// Se ho passato key = -1 mi va bene la chiave principale
if (key < 0)
key = 1;
handle = i.auto_open(key);
if (handle >= 0)
_open_files++;
}
else
{
// Se ho passato key = -1 mi va bene la chiave corrente
if (key >= 0 && i.last_key() != key)
handle = i.auto_open(key);
}
// i.touch(); // Memorizza troppo spesso l'accesso
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);
}
const RecDes& TFile_manager::get_recdes(int logicnum) const
{
const TRecord_info& i = recinfo(logicnum);
return i;
}
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();
}
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();
}
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);
if (i.is_open())
{
if (!i.is_exclusive())
i.auto_close();
else
_open_files++;
}
if (i.ref_count() <= 0)
_fileinfo.destroy(n);
}
return _open_files;
}
void TFile_manager::close_all()
{
const int zoccolo_duro = close_closeable();
#ifdef DBG
if (zoccolo_duro > 0)
NFCHECK("%d files refuse can't be closed!", zoccolo_duro);
#endif
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();
}
}
}
const FileDes& TFile_manager::get_filedes(TIsam_handle id) const
{
TFile_info& i = fileinfo(id);
return i;
}
const TFilename& TFile_manager::get_filename(TIsam_handle id) const
{
TFile_info& i = fileinfo(id);
return i.pathname();
}
TFile_manager::TFile_manager()
: _open_files(0)
{
TConfig prawin(CONFIG_INSTALL, "Main");
_max_open_files = prawin.get_int("MaxHandles", NULL, -1, 16);
if (_max_open_files < 16)
_max_open_files = 16;
else
if (_max_open_files > 64)
_max_open_files = 64;
}
///////////////////////////////////////////////////////////
// TFirm
///////////////////////////////////////////////////////////
bool TFirm::read(long cod)
{
int err = NOERR;
if (cod < 0L)
cod = prefix().get_codditta();
_rec.destroy();
TLocalisamfile ditte(LF_NDITTE);
if (cod > 0L)
{
ditte.put("CODDITTA", cod);
err = ditte.read();
}
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);
_rec.add(name, ditta.get(name));
}
}
else
NFCHECK("Can't read firm %ld: error %d", cod, err);
return _rec.items() > 0;
}
const TString& TFirm::get(const char* attr) const
{
const TString* str = (const TString*)_rec.objptr(attr);
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())
return TCurrency::get_base_val();
return codval;
}
TFirm::TFirm(long code)
{
read(code);
}
///////////////////////////////////////////////////////////
// TPrefix
///////////////////////////////////////////////////////////
TPrefix::TPrefix() : _filelevel(0), _stdlevel(0), _items(0), _firm(NULL)
{
_prefix = ".";
CGetPref();
if (!fexist(__ptprf) || strchr(__ptprf, ' ') != NULL)
fatal_box(FR("Percorso dati non valido: '%s'"), __ptprf);
const TFilename dir(cprefix);
const long primaditta = atol(dir.name());
if (primaditta > 0L && !exist(primaditta))
set_codditta(0L, TRUE);
DB_init();
set(""); // Dati standard
_stdlevel = filelevel();
set("DEF"); // Ditta corrente
}
TPrefix::~TPrefix()
{
set();
if (_firm)
delete _firm;
_manager.close_all();
DB_exit();
}
// @doc EXTERNAL
// @mfunc Riapre tutti gli archivi della ditta attiva
void TPrefix::reopen() const
{
if (_prefix != ".")
{
((TPrefix*)this)->_manager.close_all();
((TPrefix*)this)->_manager.open_all();
}
}
// @doc EXTERNAL
// @mfunc Setta la ditta corrente
void TPrefix::set(
const char* name, // @parm Nome del direttorio dati da attivare (default NULL)
bool force, // @parm Permette di settarla anche se non esiste (default FALSE)
TFilelock mode) // @parm Permette di aprire la ditta in modo esclusivo (default _manulock)
// @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
// @flag DEF | Riapre la ditta indicata nel file prefix.txt
// @flag codice ditta | Apre la ditta indicata
{
if (name == NULL)
{
close_closeable_isamfiles();
CCloseDir(NORDIR);
CCloseDir(COMDIR);
CCloseRecDir(NORDIR);
CCloseRecDir(COMDIR);
_prefix = ".";
return;
}
if (_prefix == name)
return;
if (!force && !test(name))
return;
if (_prefix != ".")
{
_manager.close_all();
CCloseDir(NORDIR);
CCloseDir(COMDIR);
CCloseRecDir(NORDIR);
CCloseRecDir(COMDIR);
}
if (strcmp(name, "DEF") == 0)
{
CGetPref();
_splitpath(cprefix, NULL, NULL, _prefix.get_buffer(), NULL);
}
else
{
_prefix = name;
if (*name)
_makepath(cprefix, NULL, __ptprf, name, NULL);
else
strcpy(cprefix, "");
}
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 != ".")
{
FileDes d;
CGetFile(LF_DIR, &d, _nolock, NORDIR);
_filelevel = d.Flags;
_items = (int)d.EOD;
_manager.open_all();
}
}
bool TPrefix::exist(long codditta) const
{
if (codditta > 0L && codditta < 100000L)
{
TFilename s(firm2dir(codditta));
s.add("dir.gen");
if (s.exist())
{
s = s.path();
s.add("trc.gen");
return s.exist();
}
}
return FALSE;
}
bool TPrefix::test(const char* s) const
{
if (s && *s && strcmp(s, "DEF"))
{
TFilename s1(__ptprf);
s1.add(s);
s1.add("dir.gen");
if (!s1.exist())
return error_box(FR("Impossibile trovare il file '%s'"), (const char*)s1);
}
return TRUE;
}
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);
}
bool TPrefix::test(long codditta) const
{
TString16 s("com");
if (codditta > 0L)
s.format("%05ldA", codditta);
return test(s);
}
long TPrefix::get_codditta() const
{
const long codditta = atol(_prefix);
return codditta;
}
bool TPrefix::set_codditta(long codditta, bool force)
{
if (force || test(codditta))
{
TString16 s("com");
if (codditta > 0L)
s.format("%05lda", codditta);
set(s, force);
CPutPref(_prefix);
if (_firm)
_firm->read(codditta);
return TRUE;
}
return FALSE;
}
const char* TPrefix::get_studio() const
{
return __ptprf;
}
bool TPrefix::set_studio(const char* study, long ditta)
{
TFilename dirtest(study);
if (!dirtest.exist() || dirtest.find(' ') >= 0)
return FALSE;
dirtest.add("com/dir.gen");
if (!dirtest.exist())
return FALSE;
// Chiudi tutti i files!
_manager.close_all();
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);
set(old_firm, TRUE);
}
return ok;
}
// @doc EXTERNAL
// @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.
{
TString& n = get_tmp_string();
n = cod;
if (n[0] == '%')
n.ltrim(1);
const int logicnum = atoi(n);
if (logicnum == 0)
{
TTable t(cod);
n = t.description();
}
else
{
if (logicnum > 0 && logicnum < items())
{
TBaseisamfile f(logicnum);
n = f.description();
}
else n.cut(0);
}
return n;
}
const char* TPrefix::description(int cod) const
{
TString16 n; n << cod;
return description(n);
}
const TFirm& TPrefix::firm()
{
if (_firm == NULL)
_firm = new TFirm;
return *_firm;
}
// Certified 90%
// @doc EXTERNAL
// @func Converte il numero di una ditta nella sua directory dati
//
// @rdesc Restituisce il nome di una directory dati
const char* firm2dir(
long codditta) // @parm Codice ditta da convertire
{
TString8 firm;
switch (codditta)
{
case -2: // Dati generali campione
case -1: // Dati di studio
firm = ""; break;
case 0: // Dati comuni
firm = "com"; break;
default: // Dati ditta
firm.format("%05lda", codditta); break;
}
TString& path = get_tmp_string(256);
xvt_fsys_build_pathname(path.get_buffer(), NULL, __ptprf, firm, NULL, NULL);
return path;
}
int safely_close_closeable_isamfiles()
{
int f = 0;
if (_prefhndl)
f = _prefhndl->close_closeable_isamfiles();
return f;
}
bool TPrefix::build_firm_data(long codditta, bool flagcom)
{
const char * const ndir = "/dir.gen";
const char * const ntrc = "/trc.gen";
TFilename s(firm2dir(codditta)); s << ndir;
bool exist = s.exist();
if (!exist)
{
s = s.path(); s.rtrim(1); s << ntrc;
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))
return FALSE;
TLocalisamfile ditte(LF_NDITTE);
ditte.zero();
ditte.put(NDT_CODDITTA,codditta);
if (ditte.read(_isequal,_testandlock) == _islocked)
{
message_box("Archivi della ditta %ld in fase di creazione da parte di un altro utente.",codditta);
return FALSE;
}
set_autoload_new_files(yesno_box("Si desidera precaricare gli archivi standard"));
s = s.path(); s.rtrim(1);
if (!s.exist() && !make_dir(s))
return error_box("Impossibile creare il direttorio della ditta %ld (%s)",
codditta, (const char*)s);
s << ndir;
if (!fcopy(&ndir[1], s))
return error_box("Impossibile copiare il file %s della ditta %ld",
&ndir[1], codditta);
s = s.path(); s << ntrc;
if (!fcopy(&ntrc[1], s))
return error_box("Impossibile copiare il file %s della ditta %ld",
ntrc, codditta);
TDir dir, dir1;
TTrec rec;
prefix().set("");
dir1.get(LF_DIR, _nolock, _nordir, _sysdirop);
const long maxeod0 = dir1.eod();
prefix().set_codditta(codditta);
dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
if (dir.eod() == 0)
{
dir1.eod() = 1L;
dir1.put(LF_DIR, _nordir, _sysdirop);
dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
}
const long maxeod1 = dir.eod();
if (maxeod0 > maxeod1)
{
dir.get(LF_DIR, _nolock, _nordir, _sysdirop);
dir.eod() = maxeod0;
dir.put(LF_DIR, _nordir, _sysdirop);
rec.zero();
}
TString mess("Generazione archivi della ditta "); mess << codditta;
TProgind p(maxeod0 ? maxeod0 : 1, mess, FALSE, TRUE);
for (int i = LF_DIR + 1; i <= maxeod0; i++)
{
p.addstatus(1);
prefix().set("");
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);
const char* name = dir.name();
dir.flags() = 0L;
create_now = create_now && (flagcom ? dir.is_com() : dir.is_firm());
if (dir.is_valid() && create_now)
{
TSystemisamfile f(i);
f.build(30);
}
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();
}
}
ditte.reread(_unlock);
prefix().set_codditta(codditta);
set_autoload_new_files(TRUE);
return TRUE;
}