Patch level : 12.0 1130

Files correlati     : ba1.exe
Commento:
Aggiunta una funzione "Recupero" per recuperare files che danno errori sulla lunghezza del record.
Interno
E' protetta da password [ADMIN e (giorno+mese)]
This commit is contained in:
Alessandro Bonazzi 2022-03-29 17:14:27 +02:00
parent 06f27089fb
commit d8d564f4d3
2 changed files with 133 additions and 9 deletions

View File

@ -1918,14 +1918,135 @@ void TSystemisamfile::makelc(TRectype& rec)
// @doc EXTERNAL // @doc EXTERNAL
// @mfunc // @cmember Recupera il tracciato record dal file dbf
//
// @rdesc Ritorna l'eventuale codice di errore generato
// (vedi <t TIsamerr>)
HIDDEN void translate_key(TToken_string& t)// 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 = 0, to = 0;
if (paren1 >= 0 && is_sub && is_upper)
paren1 = ws.find('(', paren1 + 1); // 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" : " ");
}
int TSystemisamfile::recover(TDir & dir, TTrec & rec)
{
int err = NOERR;
TCodeb_handle fchk = DB_open(filename(), 1, 0);
const int lenrec = rec.len();
int lendir = dir.len();
if (fchk < 0)
return -1;
if (lenrec != lendir)
{
lendir = lenrec;
dir.set_len(lendir);
dir.put(num(), _nordir, _sysdirop);
}
const int filelen = DB_reclen(fchk);
DB_close(fchk);
if (filelen > 0 && lenrec != filelen)
{
if (yesno_box(FR("Il file %d (%s)\n"
"ha una lunghezza di %d caratteri mentre il file fisico ha una lunghezza di %d caratteri"
"\nSi desidera ripristinare il tracciato ?"),
num(), (const char*)filename(), rec.len(), filelen))
{
FileDes d;
TFilename fname = filename();
TToken_string keys(256 * MaxKeys, '$');
fname.ext("");
err = DB_recinfo(fname, &d, &rec.rec(), keys.get_buffer());
if (err == NOERR)
{
rec.set_keys(0);
dir.set_len(d.LenR);
FOR_EACH_STR_TOKEN(keys, str)
{
TToken_string s = (const char *)str;
translate_key(s);
rec.add_keydef(s);
}
dir.put(num(), _nordir, _sysdirop);
rec.put(num());
}
}
else
err = _istrcerr;
}
return err;
}
// @doc EXTERNAL
// @mfunc Esegue la conversione del tracciato record del file // @mfunc Esegue la conversione del tracciato record del file
// //
// @rdesc Ritorna il risulato della conversione, altrimenti il codice di errore generato // @rdesc Ritorna il risulato della conversione, altrimenti il codice di errore generato
// (vedi <t TIsamerr>) // (vedi <t TIsamerr>)
int TSystemisamfile::update( int TSystemisamfile::update(
const TTrec& newrec, // @parm Nuovo tracciato record con cui aggiornare il file const TTrec& newrec, // @parm Nuovo tracciato record con cui aggiornare il file
bool interactive) // @parm Indica se riportare i campi personalizzati bool interactive) // @parm Indica se riportare i campi personalizzati
{ {
//if (newrec.len() == 0) //if (newrec.len() == 0)
@ -1940,12 +2061,11 @@ int TSystemisamfile::update(
TTrec wrec(newrec); TTrec wrec(newrec);
TDir dir; dir.get(num(), _unlock, _nordir, _sysdirop); TDir dir; dir.get(num(), _unlock, _nordir, _sysdirop);
const bool is_com = prefix().is_com(); const bool is_com = prefix().is_com();
const bool toconvert = is_com ? dir.is_com() : dir.is_firm(); const bool toconvert = is_com ? dir.is_com() : dir.is_firm();
TTrec oldrec(num(), is_com ? _comdir : _nordir); TTrec oldrec(num(), is_com ? _comdir : _nordir);
if (oldrec.fields() < 0 || oldrec.fields() > MaxFields)
if (oldrec.fields() < 0 || oldrec.fields() > MaxFields)
{ {
if (yesno_box(FR("Il file %d (%s)\n" if (yesno_box(FR("Il file %d (%s)\n"
"ha %d campi ed una lunghezza record di %d" "ha %d campi ed una lunghezza record di %d"
@ -4076,6 +4196,7 @@ TRectype& TRectype::operator =(const char* rec)
const char* TRectype::key(int numkey) const const char* TRectype::key(int numkey) const
{ {
TString& tmp = get_tmp_string(256); TString& tmp = get_tmp_string(256);
__build_key(rec_des(), numkey, _rec, tmp.get_buffer(), false); __build_key(rec_des(), numkey, _rec, tmp.get_buffer(), false);
return tmp; return tmp;
} }
@ -4390,7 +4511,8 @@ long TRecfield::operator =(long l)
const real& TRecfield::operator =(const real& r) const real& TRecfield::operator =(const real& r)
{ {
const char* buff = r.string(); const char * buff = r.string();
if (_sub_field.empty()) if (_sub_field.empty())
__putfieldbuff( _len, _dec, _type, buff, _p); __putfieldbuff( _len, _dec, _type, buff, _p);
else else

View File

@ -707,8 +707,10 @@ public:
int build(); int build();
// @cmember Calcola lo spazio che il file occuperebbe se venisse esteso a <p eox> // @cmember Calcola lo spazio che il file occuperebbe se venisse esteso a <p eox>
long size(TRecnotype eox); long size(TRecnotype eox);
// @cmember Esegue la conversione del tracciato record del file // @cmember Recupera il tracciato record dal file dbf
int update(const TTrec& newrec, bool interactive = false); int recover(TDir & dir, TTrec & rec);
// @cmember Esegue la conversione del tracciato record del file
int update(const TTrec& newrec, bool interactive = false);
// @cmember Esegue sia <mf TSystemisamfile::packfile> e <mf TSystemisamfile::packindex> // @cmember Esegue sia <mf TSystemisamfile::packfile> e <mf TSystemisamfile::packindex>
int pack(bool vis = false, bool ask = true); int pack(bool vis = false, bool ask = true);