diff --git a/src/include/isam.cpp b/src/include/isam.cpp index 8af59c191..00c95888d 100755 --- a/src/include/isam.cpp +++ b/src/include/isam.cpp @@ -1918,14 +1918,135 @@ void TSystemisamfile::makelc(TRectype& rec) // @doc EXTERNAL +// @mfunc // @cmember Recupera il tracciato record dal file dbf +// +// @rdesc Ritorna l'eventuale codice di errore generato +// (vedi ) + + +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 // // @rdesc Ritorna il risulato della conversione, altrimenti il codice di errore generato // (vedi ) int TSystemisamfile::update( - const TTrec& newrec, // @parm Nuovo tracciato record con cui aggiornare il file - bool interactive) // @parm Indica se riportare i campi personalizzati + const TTrec& newrec, // @parm Nuovo tracciato record con cui aggiornare il file + bool interactive) // @parm Indica se riportare i campi personalizzati { //if (newrec.len() == 0) @@ -1935,17 +2056,16 @@ int TSystemisamfile::update( setstatus(_istrcerr); return status(); } - + int err = NOERR; TTrec wrec(newrec); TDir dir; dir.get(num(), _unlock, _nordir, _sysdirop); - const bool is_com = prefix().is_com(); const bool toconvert = is_com ? dir.is_com() : dir.is_firm(); - 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" "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 { TString& tmp = get_tmp_string(256); + __build_key(rec_des(), numkey, _rec, tmp.get_buffer(), false); return tmp; } @@ -4390,7 +4511,8 @@ long TRecfield::operator =(long l) const real& TRecfield::operator =(const real& r) { - const char* buff = r.string(); + const char * buff = r.string(); + if (_sub_field.empty()) __putfieldbuff( _len, _dec, _type, buff, _p); else diff --git a/src/include/isam.h b/src/include/isam.h index 08932f11d..bbcb0a27a 100755 --- a/src/include/isam.h +++ b/src/include/isam.h @@ -707,8 +707,10 @@ public: int build(); // @cmember Calcola lo spazio che il file occuperebbe se venisse esteso a

long size(TRecnotype eox); - // @cmember Esegue la conversione del tracciato record del file - int update(const TTrec& newrec, bool interactive = false); + // @cmember Recupera il tracciato record dal file dbf + 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 e int pack(bool vis = false, bool ask = true);