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:
parent
918068e758
commit
2c2d972216
@ -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");
|
||||
|
@ -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();
|
||||
|
@ -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 ------------------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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!
|
||||
{
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user