#include #include #include #include #include #include #include #define DAYBIAS 36525L #define DAYYEAR 365 extern "C" { int findfld(RecDes *, const char *); }; byte m1[12] = {31,28,31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; int m2[12] = {31,59,90,120,151,181,212,243,273,304,334,365}; HIDDEN int CGetField(const char *fieldname,RecDes* recd,RecType recin,long* d) { int p, i; unsigned int off; byte len; char *s1, s[10]; if ((p = findfld(recd, fieldname)) != -1) { off = recd->Fd[p].RecOff; len = recd->Fd[p].Len; if (recd->Fd[p].TypeF != _datefld) { while ((recin[off] == ' ') && (len)) { off++; len--; } } if (len) { s1 = recin + off; for (i = 0; i < len; i++) s[i] = s1[i]; s[len] = '\0'; while ((len) && (s[len - 1] == ' ')) s[--len] = '\0'; } else strcpy(s, ""); if (recd->Fd[p].TypeF == _datefld) { if (strlen(s)) *d=atol(s); else *d=0; } return (0); } else { fatal_box("Non esiste il campo %s", fieldname); return(-1); } } class TIsam_date_converter : public TApplication { TFilename _logfile; bool _errors_found; protected: virtual bool create () ; virtual bool destroy(); void update(); void update_dir(); void convert_dir(); int convert_file(int logicnum); public: TIsam_date_converter() {} ~TIsam_date_converter() {} }; bool TIsam_date_converter::create() // initvar e arrmask { TApplication::create(); update(); return FALSE; } bool TIsam_date_converter::destroy() // releasev e arrmask { return TApplication::destroy() ; } void TIsam_date_converter::update() { _logfile.temp("cnvlog"); FILE * fp = fopen(_logfile,"w"); fclose(fp); _errors_found = FALSE; long firm = get_firm(); TString pref; if (firm == 0) pref = prefix().name(); do_events(); begin_wait(); // Converte i files in formato DBIII, FOXPRO... prefix().set(""); update_dir(); set_autoload_new_files(FALSE); prefix().set("com"); update_dir(); convert_dir(); TLocalisamfile ditte(LF_NDITTE); for (ditte.first(); !ditte.eof(); ditte.next()) { const long codditta = ditte.get_long("CODDITTA"); const TRecnotype rec = ditte.recno(); if (prefix().exist(codditta)) { set_firm(codditta); update_dir(); convert_dir(); } } if (firm > 0) set_firm(firm); else prefix().set(pref); set_autoload_new_files(TRUE); end_wait(); if (_errors_found) { TString80 s; s << "Esaminare il file di log " << _logfile << " per il riepilogo degli errori." ; message_box(s); } else ::remove(_logfile); } void TIsam_date_converter::update_dir() { TDir d; d.get(LF_DIR); const int items = (int)d.eod(); TString80 s("Aggiornamento direttorio "); TString pref(prefix().name()); if (pref.empty()) s << "standard"; else if (pref == "com") s << "comune"; else s << " della ditta " << atol (pref); TProgind p((long)(items ? items : 1), s, TRUE, TRUE, 70); p.setstatus(1L); for (int i = 2; i <= items; i++) { p.addstatus(1L); d.get(i, _nolock, _nordir, _sysdirop); TFilename s(d.name()); s.ext(""); strcpy((char *) d.name(), s); d.put(i, _nordir, _sysdirop); } } void TIsam_date_converter::convert_dir() { const TString pref(prefix().name()); const bool is_com = prefix().is_com(); TDir d; d.get(LF_DIR); const int items = (int)d.eod(); TString80 s("Aggiornamento archivi "); if (pref == "com") s << "comuni"; else s << " della ditta " << atol (pref); TProgind p((long)(items ? items : 1), s, TRUE, TRUE, 70); p.setstatus(1L); for (int i = 2; i <= items; i++) { p.setstatus((long)(i+1)); d.get(i, _nolock, _nordir, _sysdirop); const bool to_convert = (is_com ? d.is_com() : d.is_firm()); if (to_convert) convert_file(i); } } int TIsam_date_converter::convert_file(int logicnum) { TDir dir; TTrec r; int err = NOERR; bool restore_original=FALSE, retry_file=FALSE; r.get(logicnum); RecDes *rd=r.rec(); TRecnotype i; const int nflds = r.fields(); const int nkeys = r.keys(); do // External loop creation file in case of a disk full error. { // Appending records can easily reduce disk space! dir.get(logicnum); if (dir.len() == 0 || nflds < 1 || nkeys < 1) return 0; const char * fp = dir.name(); TFilename old(fp); const TRecnotype nitems = dir.eod(); const TRecnotype neox = dir.eox(); TFile f(dir.len()); old.ext("dta"); if (fexist(old)) { f.open(old); { TSystemisamfile newfile(logicnum); bool retry = FALSE; do // Internal loop creation file in case of a disk full error. { // The program asks to continue (suspending momentanely execution), newfile.build(10); // permitting the user to switch to a DOS session and free space on disk. switch (newfile.status()) { case NOERR: retry=FALSE; break; case _isfilefull: if (!yesno_box("Il disco e' pieno. Non riesco a creare il file %s. Riprovo?", fp)) { message_box("Liberare spazio sull'unita' interessata e rieseguire la conversione."); stop_run(); } retry=TRUE; break; default: fatal_box("Non riesco a creare il file %s : errore n. %d", fp, newfile.status()); break; } } while (retry); } TString s(80); s.format("Aggiornamento archivio %s", fp); TProgind p((long)(nitems ? nitems : 1), s, TRUE, TRUE, 70); TLocalisamfile newfile(logicnum); TToken_string ts(128); // Build token_string with the names of date fields and logical fields TToken_string tslog(128); for (int j=0; jFd[j].TypeF == _datefld) ts.add(rd->Fd[j].Name); else if (rd->Fd[j].TypeF == _boolfld) tslog.add(rd->Fd[j].Name); const int tslog_items = tslog.items(); const int ts_items = ts.items(); for (i = 1; newfile.good() && i <= dir.eod(); i++) { f.read(newfile.curr().string(),i); newfile.curr().setdirty(); if (newfile.curr().string()[0] == '\0') { newfile.curr().recall(); if (tslog_items > 0) for (const char * field_name = tslog.get(0); field_name != NULL; field_name = tslog.get()) { const TString16 value(newfile.curr().get(field_name)); newfile.put(field_name,value == "X"); } if (ts_items > 0) for (const char *field_name = ts.get(0); field_name != NULL; field_name = ts.get()) { long wd; CGetField(field_name,rd,newfile.curr().string(),&wd); TDate d(wd); newfile.put(field_name,d); } } else newfile.curr().discard(); if ((i % 50) == 0) p.setstatus((long)(i + 1)); if (!newfile.curr().isdeleted()) newfile.write(); } p.setstatus((long)nitems); f.close(); err=newfile.status(); if (newfile.good()) { old.ext("dta"); ::remove(old); old.ext("ndx"); ::remove(old); restore_original=FALSE; retry_file=FALSE; } else { _errors_found=TRUE; if (err == _isfilefull) { if (!yesno_box("Il disco e' pieno. Non riesco a scrivere sul file %s. Riprovo?", fp)) { message_box("Liberare spazio sull'unita' interessata e rieseguire la conversione."); retry_file=FALSE; } else retry_file=TRUE; } else { error_box("Errore n.ro %d nella conversione dell' archivio %s:\n %ld records non convertiti.", err, fp, nitems - i + 2); retry_file=FALSE; } restore_original=TRUE; } } else { // Crea il file se non esiste il relativo .DTA. const TString pref(prefix().name()); const bool is_com = prefix().is_com(); prefix().set(""); dir.get(logicnum); const int module = abs((int)dir.flags()); prefix().set(pref); dir.get(logicnum, _nolock, _nordir, _sysdirop); bool to_create = (is_com ? dir.is_com() : dir.is_firm()); if (to_create && has_module(module, CHK_DONGLE)) { dir.get(logicnum); TFilename s(dir.name()); s.ext("dbf"); if (!fexist(s)) // Crea il file solo se non esiste il .DBF { TSystemisamfile f(logicnum); bool retry = FALSE; do { f.build(10); switch (f.status()) { case NOERR: break; case _isfilefull: if (!yesno_box("Il disco e' pieno. Non riesco a creare il file %s. Riprovo?", fp)) { message_box("Liberare spazio sull'unita' interessata e rieseguire la conversione."); stop_run(); } retry=TRUE; break; default: fatal_box("Non riesco a creare il file %s : errore n. %d", fp, f.status()); break; } } while (retry); } } } if (restore_original) { // Remove files partially converted old.ext("dbf"); ::remove(old); TToken_string t(10); get_idx_names(logicnum,t); for (const char * name=t.get(0); name != NULL; name=t.get()) ::remove(name); if (t.items() > 1) // A .cgp must be removed too! { old.ext("cgp"); ::remove(old); } // Put dir to restore original EOD and EOX. dir.get(logicnum,_lock,_nordir,_sysdirop); dir.eod()=nitems; dir.eox()=neox; dir.put(logicnum,_nordir,_sysdirop); if (!retry_file) { FILE *f = fopen((const char*)_logfile,"a"); old.ext("dta"); fprintf(f,"File: %s (%d). %ld records non convertiti. Errore %d.\n", (const char*) old, logicnum, nitems-i+2, err); fclose(f); } } } while (retry_file && (err == _isfilefull)); if (err == _isfilefull) // This happens only when the user decides to answer NO. stop_run(); return err; } int main(int argc, char** argv) { TIsam_date_converter a; a.run(argc, argv, "Conversione a CodeBase"); return 0; }