prefix.* Migliorata gestione handles dei file aperti

progind.cpp  Corretta gestione messaggi multiriga per XI_R4
progind.h    Trasformate da void a bool i metodi setstatus e addstatus
rectypes.h   Aggiunti due nuovi TDirtype _studir e extdir
relapp.cpp   Migliorata gestione stringhe fisse
relation.cpp Adeguati i cursori alla nuova gestione handles
relation.h   Tolto _filename dai cursori e messo _indexfirm


git-svn-id: svn://10.65.10.50/trunk@6457 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
guy 1998-03-30 13:50:30 +00:00
parent 918068e758
commit 2c2d972216
8 changed files with 902 additions and 194 deletions

View File

@ -1,5 +1,6 @@
#include <codeb.h>
#include <extcdecl.h>
#include <prefix.h>
#include <progind.h>
#include <scanner.h>
@ -8,27 +9,17 @@
#include <nditte.h>
// Definita in isam.cpp
extern int get_error(int);
///////////////////////////////////////////////////////////
// extern variables are NO-NO!
///////////////////////////////////////////////////////////
HIDDEN TString16 _user;
HIDDEN TPrefix* _prefhndl = NULL;
// @doc EXTERNAL
// @func Ritorna il nome dell'utente attuale
//
// @rdesc Ritorno il nome dell'utente attuale
TString& user()
{
return _user;
}
// @doc EXTERNAL
// @func Inizializza (crea) un nuovo file "prefix.txt"
//
// @rdesc Ritorna l'oggetto <c TPrefix> creato
@ -62,6 +53,689 @@ void prefix_destroy()
}
}
///////////////////////////////////////////////////////////
// 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;
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; }
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(); }
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
NFCHECK("Can'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);
}
}
else
{
err = get_error(_handle);
}
return err;
}
int TFile_info::close_low()
{
int err = NOERR;
if (_handle >= 0)
{
DB_close(_handle);
_handle = -1;
}
else
{
#ifdef DBG
NFCHECK("Can'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
NFCHECK("Can't reopen file %d exclusively", _num);
#endif
close_low();
}
_exclusive = _locked = TRUE;
err = open_low(exclusive, index);
}
_ref_count++;
return err;
}
int TFile_info::close()
{
int err = NOERR;
if (_ref_count > 0)
{
_ref_count--;
if (_ref_count == 0)
{
if (is_open())
err = close_low();
_locked = _exclusive = FALSE;
_last_key = -1;
}
}
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_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)
{
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())
_fileinfo.add(i, num);
else
{
delete i;
i = NULL;
}
}
CHECKD(i, "Unknown file ", num);
return *i;
}
TRecord_info& TFile_manager::recinfo(int logicnum)
{
TRecord_info* i = (TRecord_info*)_recinfo.objptr(logicnum);
if (i == NULL)
{
i = new TRecord_info(logicnum);
_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;
for (int n = _fileinfo.last(); n > 0; n = _fileinfo.pred(n))
{
TFile_info& i = (TFile_info&)_fileinfo[n];
if (i.is_open() && !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 (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())
{
TFile_info* i = NULL;
for (num = LF_EXTERNAL; (i = (TFile_info*)_fileinfo.objptr(num)) != NULL; num++)
{
if (i->pathname() == name)
break;
}
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)
{
err = i->close();
if (err == NOERR && i->ref_count() == 0)
{
if (name >= LF_EXTERNAL)
{
_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'use not open file %d", i.num());
TCodeb_handle handle = i.handle();
if (handle < 0)
{
if (_open_files >= _max_open_files)
close_oldest();
handle = i.auto_open(key);
if (handle >= 0)
_open_files++;
}
else
{
if (i.last_key() != key)
handle = i.auto_open(key);
}
i.touch();
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 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();
}
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.ref_count() > 0)
{
if (i.is_open())
{
if (!i.is_locked() && !i.is_exclusive())
i.auto_close();
else
_open_files++;
}
}
else
{
#ifdef DBG
if (i.is_open())
{
NFCHECK("File %d is open without references?", i.num());
_open_files++;
}
else
#endif
_fileinfo.destroy(n);
}
}
return _open_files;
}
void TFile_manager::close_all()
{
const int zoccolo_duro = close_closeable();
if (zoccolo_duro > 0)
NFCHECK("%d files refuse to be closed!", zoccolo_duro);
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 name)
{
TFile_info& i = fileinfo(name);
return i;
}
TFile_manager::TFile_manager()
: _open_files(0)
{
TConfig prawin(CONFIG_INSTALL, "Main");
_max_open_files = prawin.get_int("MaxHandles", NULL, 16);
if (_max_open_files < 8)
_max_open_files = 8;
else
if (_max_open_files > 32)
_max_open_files = 32;
}
///////////////////////////////////////////////////////////
// TPrefix
///////////////////////////////////////////////////////////
@ -75,107 +749,28 @@ TPrefix::TPrefix() : _filelevel(0), _items(0)
const TFilename dir(cprefix);
const long primaditta = atol(dir.name());
if (primaditta > 0 && !exist(primaditta))
set("com", TRUE);
if (primaditta > 0L && !exist(primaditta))
set_codditta(0L, TRUE);
DB_init();
}
TPrefix::~TPrefix()
{
set();
DB_exit();
}
HIDDEN int closeall(bool changestudy, TBit_array& excl, TBit_array& toclose)
{
if (!openf) return 0;
TDir d;
d.get(1);
const int max = (int) d.eod();
int err = NOERR;
for (int i = 1; i < max; i++)
if (openf[i] != NULL)
{
isfdptr isfd = openf[i];
d.get(i + 1, _nolock, _nordir, _sysdirop);
if (toclose[i + 1] || changestudy || !d.is_com())
{
excl.set(i, DB_file_locked(isfd->fhnd) != 0);
err=DB_close(isfd->fhnd);
if (err != NOERR) err=get_error(err);
if (err != NOERR) fatal_box("Can't close file %d. Error n. %d",isfd->ln,err);
exclunlock(CInsPref((char*) glockname, _nordir), FALSE);
}
}
return max;
}
HIDDEN void openall(bool changestudy, TBit_array& excl, int oldmax, TBit_array& toopen)
{
if (!openf)
return ;
TDir d;
d.get(1);
const int max = (int) d.eod();
for (int i = max; i < oldmax; i++)
if (openf[i] != NULL)
{
d.get(i + 1, _nolock, _nordir, _sysdirop);
if (changestudy || !d.is_com())
fatal_box("Can't reopen file n. %d", i + 1);
}
int err = NOERR;
for (i = 1; i < max; i++)
if (openf[i] != NULL)
{
isfdptr isfd = openf[i];
d.get(i + 1, _nolock, _nordir, _sysdirop);
const bool com = d.is_com();
if (toopen[i + 1] || changestudy || !com)
{
isfd->ft = com ? _comdir : _nordir;
d.get(i + 1, _nolock, (TDirtype) isfd->ft);
*isfd->d = *d.filedesc();
TTrec r;
r.get(i + 1, (TDirtype) isfd->ft);
*isfd->r = *r.rec();
if (excllock(CInsPref((char*) glockname, NORDIR), FALSE) == -1)
fatal_box("Can't reopen file n. %d : file in use", i + 1);
isfd->fhnd = DB_open(isfd->d->SysName, excl[i],TRUE);
if (isfd->fhnd < 0 ) err=get_error(isfd->fhnd);
else err = NOERR;
if (err == _islocked)
fatal_box("Can't reopen file n. %d : file in use", i + 1);
if (err != NOERR)
fatal_box("Can't reopen file n. %d : error n. %d", i + 1, err);
}
}
}
// @doc EXTERNAL
// @mfunc Riapre tutti gli archivi della ditta attiva
void TPrefix::reopen() const
{
if (_prefix != ".")
{
TBit_array excl, comfiles;
comfiles.set(LF_PCON);
comfiles.set(LF_CLIFO);
comfiles.set(LF_INDSP);
comfiles.set(LF_CAUSALI);
comfiles.set(LF_RCAUSALI);
int max = closeall(FALSE, excl, comfiles);
openall(FALSE, excl, max, comfiles);
((TPrefix*)this)->_manager.close_all();
((TPrefix*)this)->_manager.open_all();
}
}
@ -204,21 +799,13 @@ void TPrefix::set(
return;
}
if (_prefix == name) return;
if (!force && !test(name)) return;
TBit_array excl, comfiles;
int max = 0;
comfiles.set(LF_PCON);
comfiles.set(LF_CLIFO);
comfiles.set(LF_INDSP);
comfiles.set(LF_CAUSALI);
comfiles.set(LF_RCAUSALI);
if (_prefix == name)
return;
if (!force && !test(name))
return;
if (_prefix != ".")
{
max = closeall(FALSE, excl, comfiles);
_manager.close_all();
CCloseDir(NORDIR);
CCloseDir(COMDIR);
CCloseRecDir(NORDIR);
@ -249,11 +836,10 @@ void TPrefix::set(
if (_prefix != ".")
{
FileDes d;
CGetFile(LF_DIR, &d, _nolock, NORDIR);
_filelevel = d.Flags;
_items = (int)d.EOD;
openall(FALSE, excl, max, comfiles);
_manager.open_all();
}
}
@ -287,6 +873,16 @@ bool TPrefix::test(const char* s) const
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");

View File

@ -1,14 +1,62 @@
#ifndef __PREFIX_H
#define __PREFIX_H
#ifndef __EXTCTYPE_H
#include <extctype.h>
#endif
#ifndef __RECTYPES_H
#include <rectypes.h>
#endif
#ifndef __STRINGS_H
#include <strings.h>
#ifndef __ASSOC_H
#include <assoc.h>
#endif
class TFile_info;
class TRecord_info;
class TTrec;
typedef int TIsam_handle;
typedef int TCodeb_handle;
class TFile_manager : public TObject
{
TArray _fileinfo;
TArray _recinfo;
int _open_files, _max_open_files;
protected:
TFile_info& fileinfo(TIsam_handle handle);
TRecord_info& recinfo(int logicnum);
bool close_oldest();
public:
TIsam_handle open(int& logicnum, TFilename& name, bool excl, bool idx);
int close(TIsam_handle& name);
void lock_record(TIsam_handle num, TRecnotype rec);
void unlock_record(TIsam_handle num, TRecnotype rec);
const FileDes& get_filedes(TIsam_handle name);
const RecDes& get_recdes(int logicnum);
const RecDes& update_recdes(int logicnum);
TDirtype get_dirtype(int logicnum);
bool add_recdes(int logicnum, TTrec& rec, TToken_string& keys);
TCodeb_handle get_handle(TIsam_handle name, int key);
int get_reclen(int logicnum);
int close_closeable();
void close_all();
void open_all();
TFile_manager();
virtual ~TFile_manager() { }
};
// @doc EXTERNAL
// @class TPrefix | Classe contenente le informazioni sulla ditta correntemente in uso
@ -27,6 +75,8 @@ class TPrefix : public TObject
long _filelevel;
// @cmember:(INTERNAL) Numero di files esitenti
int _items;
TFile_manager _manager;
// @access Protected Member
protected:
@ -74,7 +124,40 @@ public:
bool build_firm_data(long codditta, bool flagcom = FALSE);
// @cmember Riapre tutti gli archivi della ditta attiva
void reopen() const ;
TIsam_handle open_isamfile(int& logicnum, TFilename& name, bool excl = FALSE, bool idx = TRUE)
{ return _manager.open(logicnum, name, excl, idx); }
int close_isamfile(TIsam_handle& name)
{ return _manager.close(name); }
void lock_record(TIsam_handle num, TRecnotype rec);
void unlock_record(TIsam_handle num, TRecnotype rec);
int close_closeable_isamfiles()
{ return _manager.close_closeable(); }
TDirtype get_dirtype(TIsam_handle name)
{ return _manager.get_dirtype(name); }
int get_handle(TIsam_handle name, int key = 0)
{ return _manager.get_handle(name, key); }
const RecDes& get_recdes(int logicnum)
{ return _manager.get_recdes(logicnum); }
bool add_recdes(int logicnum, TTrec& rec, TToken_string& keys)
{ return _manager.add_recdes(logicnum, rec, keys); }
const RecDes& update_recdes(int logicnum)
{ return _manager.update_recdes(logicnum); }
int get_reclen(int logicnum)
{ return _manager.get_reclen(logicnum); }
const FileDes& get_filedes(TIsam_handle name)
{ return _manager.get_filedes(name); }
// @cmember Costruttore
TPrefix();
// @cmember Distruttore
@ -84,8 +167,6 @@ public:
const char* firm2dir(long codditta);
TString& user();
TPrefix& prefix_init();
TPrefix& prefix();
void prefix_destroy();

View File

@ -46,8 +46,7 @@ TIndwin::TIndwin(long max, const char* txt, bool cancel, bool bar, int div)
_text = new TMultiline_control(win(), DLG_NULL, 1, 1, hor-2, lines+1, 512, "CD", "");
_text->set_read_only();
testo.replace('\n', '\r');
_text->set_caption(testo);
set_text(testo);
if (bar)
{
@ -72,9 +71,21 @@ void TIndwin::set_text(
// @comm Si puo' chiamare questa funzione per cambiare il testo, ma
// le dimensioni della finestra sono calcolate sul primo testo
// passato, quindi occorre dimensionare correttamente il primo passato
// (es. inserire degli spazi) se se ne prevede uno piu' lungo.
// (es. inserire degli spazi) quando se ne prevede uno piu' lungo.
{
#ifdef XI_R4
_text->set_caption(t);
#else
TString testo(t);
testo.replace('\n', '\r');
_text->set_caption(testo);
#endif
if (_bar)
{
RCT r; get_bar_rct(r);
xvt_dwin_invalidate_rect(win(), &r);
}
}
TIndwin::~TIndwin()
@ -104,6 +115,16 @@ KEY TIndwin::check_stop()
return k;
}
RCT* TIndwin::get_bar_rct(RCT& r) const
{
xvt_vobj_get_client_rect(win(), &r);
r.left += CHARX;
r.right -= CHARX;
r.top = (int)_bar;
r.bottom = r.top + 2*CHARY;
return &r;
}
void TIndwin::update_bar()
{
if (_status >= _max)
@ -116,13 +137,10 @@ void TIndwin::update_bar()
const double prc = (double)_status/_max;
WINDOW w = win();
RCT r; xvt_vobj_get_client_rect(w, &r);
// Rettangolo contenente l'intera barra
r.left += CHARX; r.right -= CHARX;
r.top = (int)_bar;
r.bottom = r.top + 2*CHARY;
// Rettangolo contenente l'intera barra
RCT r; get_bar_rct(r);
RCT b = r;
if (CAMPI_SCAVATI)
@ -151,7 +169,7 @@ void TIndwin::update_bar()
char n[8]; sprintf(n, "%d%%", int(prc * 100.0 + 0.5));
xvt_dwin_draw_text(w, r.left+r.right/2-CHARX, (r.bottom+r.top+CHARY)/2-3, n, -1);
check_stop();
}
@ -183,16 +201,19 @@ TProgind::TProgind(long max, const char* txt, bool cancel, bool bar, int div)
: TIndwin(max, txt, cancel, bar, div)
{}
void TProgind::setstatus(long l)
bool TProgind::setstatus(long l)
{
CHECK(l >= 0, "Bad progind status");
const long old_perc = _status * 100L / _max;
_status = l > _max ? _max : l;
const long new_perc = _status * 100L / _max;
if (new_perc > old_perc)
const bool tictac = new_perc != old_perc;
if (tictac)
{
update_bar();
do_events();
}
return tictac;
}
// TTimerind ------------------------------------------------------------

View File

@ -50,6 +50,9 @@ protected:
// @cmember Ritorna il numero di linee necessarie per scrivere il testo nella finestra
word measure_text(TToken_string& t, word& len) const;
// @cmember Calcola il rettangolo della barra di attesa
RCT* get_bar_rct(RCT& r) const;
// @cmember Gestisce gli eventi tasto della finestra
virtual bool on_key(KEY k);
@ -105,10 +108,10 @@ public:
void setmax(long m)
{ _max = m; }
// @cmember Setta lo stato della barra d'attesa
void setstatus(long l);
bool setstatus(long l);
// @cmember Aggiorna la barra d'attesa aggiungendo l'incremento fatto dell'applicazione
void addstatus(long l)
{ setstatus(_status+l); }
bool addstatus(long l)
{ return setstatus(_status+l); }
// @cmember Costruttore
TProgind(long max, const char* txt = NULL, bool cancel = TRUE, bool bar = TRUE, int div = 60);
// @cmember Distruttore

View File

@ -22,7 +22,7 @@ enum TFilelock {
enum TReclock {
_unlock = 0x1000, // @emem Sblocca il record
_nolock = 0x2000, // @emem Nessuna operazione di lock
_lock = 0x4000, // @emem Blocca il record
_lock = 0x4000, // @emem Blocca il record
_testandlock = (int)0x8000} ; // @emem Blocca il record se possibile, altrimenti ritorna errore
// @doc EXTERNAL
@ -30,7 +30,9 @@ enum TReclock {
// @enum TDirtype | Comandi per la gestione di <c TDir>
enum TDirtype {
_nordir, // @emem Riferimento operazioni col prefix corrente
_comdir } ; // @emem Riferimento operazioni al direttorio comune
_comdir, // @emem Riferimento operazioni al direttorio comune
_studir, // @emem Riferimento operazioni al direttorio studio
_extdir }; // @emem Riferimento operazioni ad un direttorio assoluto
// @doc EXTERNAL
@ -94,7 +96,9 @@ enum TIsamerr {
_isalropen = 222, // @emem File gia' aperto
_isdeadlock = 223, // @emem Condizione di deadlock
_isreinsert = 224, // @emem Chiave primaria duplicata
_islocked = 225} ; // @emem Record bloccato
_islocked = 225, // @emem Record bloccato
_isbadtrc = 226 // @emem Tracciato Record errato o mancante
};
typedef long TRecnotype;

View File

@ -1105,7 +1105,7 @@ bool TRelation_application::filter()
TAssoc_array field_values;
const char * s;
TString80 t;
TString t, v;
while((s = body.get()) != NULL)
{
@ -1115,7 +1115,7 @@ bool TRelation_application::filter()
CHECKS(u > 0, "Invalid edit message ", (const char *) body);
if (u > 0)
{
const TString v(t.mid(u + 1));
v = t.mid(u + 1);
t.cut(u);
field_values.add(t, v);

View File

@ -968,8 +968,10 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
const bool filtered = has_filter();
FILE* _f = open_index(TRUE);
const int handle = file().handle();
if (DB_reccount(file().filehnd()->fhnd) == 0)
if (DB_reccount(handle) == 0)
{
close_index(_f);
return 0;
@ -978,19 +980,19 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
rewind(_f);
l = strlen(to());
junk=DB_index_seek(file().filehnd()->fhnd, (char*)(const char*) from());
junk=DB_index_seek(handle, (char*)(const char*) from());
if (junk < 0) junk=get_error(junk);
if (junk == _iseof) return 0;
TRecnotype* page = new TRecnotype [CMAXELPAGE];
pos = DB_index_recno(file().filehnd()->fhnd);
pos = DB_index_recno(handle);
_pos=-1;
while (TRUE)
{
if (DB_index_eof(file().filehnd()->fhnd)) break;
const char* s0 = DB_index_getkey(file().filehnd()->fhnd);
const TRecnotype recno = DB_index_recno(file().filehnd()->fhnd);
if (DB_index_eof(handle)) break;
const char* s0 = DB_index_getkey(handle);
const TRecnotype recno = DB_index_recno(handle);
if (l && (strncmp(to(), s0, l) < 0)) break;
if (recno == oldrecno) break; // means that no more keys are available
oldrecno=recno;
@ -1008,10 +1010,9 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
pagecnt = 0;
}
page[pagecnt++] = recno;
DB_index_next(file().filehnd()->fhnd);
int rt=get_error(-1);
if (rt != NOERR)
fatal_box("Can't read index n. %d - file n. %d",DB_tagget(file().filehnd()->fhnd),file().filehnd()->ln);
long rec = DB_index_next(handle);
if (rec < 0)
fatal_box("Can't read index n. %d - file n. %d",file().getkey(),file().num());
} // while
if (pagecnt)
{
@ -1025,7 +1026,7 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
}
ap += pagecnt;
}
if (_pos == -1) pos=0;
if (_pos == -1) pos = 0;
delete page;
close_index(_f);
return ap;
@ -1033,9 +1034,8 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
int TCursor::filtercursor(int pagecnt, TRecnotype* page)
{
int np=0, handle=file().filehnd()->fhnd;
int np=0; /*, handle = file().handle(); */
TRectype& rec=file().curr();
for (int i=0; i< pagecnt; i++)
{
@ -1086,20 +1086,18 @@ bool TCursor::ok() const
bool TCursor::changed()
{
isdef* fh = file().filehnd();
if (_frozen && _lastrec > 0L)
return _filename != fh->d->SysName;
const TRecnotype eod = DB_reccount(fh->fhnd);
if (_lastrec != eod ||
(_lastkrec != DB_changed(fh->fhnd)) ||
(_filename != fh->d->SysName))
{
// _lastrec = eod;
// _filename = fh->d->SysName;
// _lastkrec = DB_changed(fh->fhnd);
if (prefix().get_dirtype(file().num()) == _nordir &&
_index_firm != prefix().get_codditta())
return TRUE;
if (_frozen && _lastrec > 0L)
return FALSE;
const int handle = file().handle();
const TRecnotype eod = DB_reccount(handle);
if (_lastrec != eod ||
_lastkrec != DB_changed(handle))
return TRUE;
}
if (!curr().valid())
return TRUE;
@ -1108,23 +1106,21 @@ bool TCursor::changed()
}
TRecnotype TCursor::update()
{
begin_wait();
TWait_cursor hourglass;
file().setkey(_nkey);
if (file().curr().empty()) file().curr().zero();
if (file().curr().empty())
file().curr().zero();
file().read(_isgteq);
const TRecnotype totrec = buildcursor(file().recno());
isdef* fh = file().filehnd();
const TRecnotype eod = DB_reccount(fh->fhnd);
const int handle = file().handle();
const TRecnotype eod = DB_reccount(handle);
_lastrec = eod;
_filename = fh->d->SysName;
_lastkrec = DB_changed(fh->fhnd);
end_wait();
_index_firm = prefix().get_codditta();
_lastkrec = DB_changed(handle);
return totrec;
}
@ -1295,7 +1291,7 @@ TRecnotype TCursor::read(TIsamop op, TReclock lockop)
FILE* _f = open_index();
if (fseek(_f, 0L, SEEK_SET) != 0)
fatal_box("Can't repos cursor : File %d\n", file().filehnd()->ln);
fatal_box("Can't repos cursor : File %d\n", curfile.num());
TRecnotype *page = new TRecnotype [CMAXELPAGE];
int pagecnt;
@ -1339,10 +1335,16 @@ TCursor::TCursor(TRelation* r, const char* fil, int nkey,
TCursor::~TCursor()
{
if (_indexname.not_empty())
{
if (_indexname == _last_name && _last_ndx != NULL)
{
_last_created = TRUE; // Force close
close_index(_last_ndx);
}
::remove(_indexname);
}
if (_fexpr)
delete _fexpr;
}
@ -1350,23 +1352,23 @@ TCursor::~TCursor()
TRecnotype TCursor::readrec()
{
TRecnotype& nrec = file().filehnd()->RecNo;
TRecnotype nrec = 0L;
if (_pos >= items())
{
file().setstatus(_iseof);
curr().zero();
return nrec = 0L;
return nrec;
}
file().setstatus(NOERR);
FILE* _f = open_index();
if (fseek(_f, _pos * sizeof(TRecnotype), SEEK_SET) != 0)
fatal_box("Can't seek position %ld in cursor n. %d\n", _pos, file().filehnd()->ln);
fatal_box("Can't seek position %ld in cursor n. %d\n", _pos, file().num());
if (fread(&nrec, sizeof(TRecnotype), 1, _f) != 1)
fatal_box("Can't read position %ld in cursor n. %d\n", _pos, file().filehnd()->ln);
fatal_box("Can't read position %ld in cursor n. %d\n", _pos, file().num());
close_index(_f);
@ -1389,10 +1391,10 @@ int TCursor::lock(
switch(l)
{
case _lock:
rt=DB_lock_rec(file().filehnd()->fhnd,_pos);
rt=DB_lock_rec(file().handle(),_pos);
break;
case _unlock:
rt=DB_unlock(file().filehnd()->fhnd);
rt=DB_unlock(file().handle());
break;
default:
break;
@ -1549,28 +1551,29 @@ TRecnotype TSorted_cursor::buildcursor(TRecnotype rp)
FILE* _f = open_index(TRUE);
if (DB_reccount(file().filehnd()->fhnd) == 0)
if (file().empty())
{
close_index(_f);
return 0;
}
const int handle = file().handle();
fseek(_f, 0L, SEEK_SET);
l = strlen(to());
junk=DB_index_seek(file().filehnd()->fhnd, (char*)(const char*) from());
junk=DB_index_seek(handle, (char*)(const char*) from());
if (junk < 0) junk=get_error(junk);
if (junk == _iseof) return 0;
TRecnotype* page = new TRecnotype [CMAXELPAGE];
pos = DB_index_recno(file().filehnd()->fhnd);
pos = DB_index_recno(handle);
TCursor::pos()=-1;
while (TRUE)
{
if (DB_index_eof(file().filehnd()->fhnd)) break;
const char* s0 = DB_index_getkey(file().filehnd()->fhnd);
const TRecnotype recno = DB_index_recno(file().filehnd()->fhnd);
if (DB_index_eof(handle)) break;
const char* s0 = DB_index_getkey(handle);
const TRecnotype recno = DB_index_recno(handle);
if (l && (strncmp(to(), s0, l) < 0)) break;
if (recno == oldrecno) break; // means that no more keys are available
oldrecno=recno;
@ -1587,10 +1590,10 @@ TRecnotype TSorted_cursor::buildcursor(TRecnotype rp)
pagecnt = 0;
}
page[pagecnt++] = recno; // lasciare cosi' altrimenti la readat legge due volte lo stesso record
DB_index_next(file().filehnd()->fhnd);
int rt=get_error(-1);
if (rt != NOERR)
fatal_box("Can't read index n. %d - file n. %d",DB_tagget(file().filehnd()->fhnd),file().filehnd()->ln);
long rec = DB_index_next(handle);
if (rec < 0)
fatal_box("Can't read index n. %d - file n. %d",file().getkey(),file().num());
} // while
if (pagecnt)
{
@ -1629,7 +1632,7 @@ TRecnotype TSorted_cursor::buildcursor(TRecnotype rp)
int TSorted_cursor::filtercursor(int pagecnt, TRecnotype* page)
{
int np=0, handle=file().filehnd()->fhnd;
int np=0 /*, handle=file().filehnd()->fhnd */;
TRectype& rec=file().curr();
TString s;
El_To_Sort Element;
@ -1657,7 +1660,7 @@ int TSorted_cursor::filtercursor(int pagecnt, TRecnotype* page)
s.cut(s.len()-1);
TFieldref f(s,0);
TString sf=f.read(*relation());
TRectype& frec = file(f.file()).curr();
TRectype& frec = file(f.file()).curr();
TFieldtypes fld_type = frec.type(f.name());
if (fld_type == _datefld) // Se il campo e' di tipo data, la converte in ANSI!
{

View File

@ -235,8 +235,8 @@ class TCursor : public TContainer
TRecnotype _lastrec;
// @cmember:(INTERNAL) Chiave dell'ultimo record
TRecnotype _lastkrec;
// @cmember:(INTERNAL) Nome assoluto del file principale
TFilename _filename;
// @cmember:(INTERNAL) Ditta di creazione indice
long _index_firm;
// @cmember:(INTERNAL) Filtro definito con la <mf TCursor::set_filter>
TString _filter;
// @cmember:(INTERNAL) Nome della chiave iniziale