diff --git a/include/codeb.c b/include/codeb.c new file mode 100755 index 000000000..942068ae3 --- /dev/null +++ b/include/codeb.c @@ -0,0 +1,914 @@ +/* + Attenzione!. Per costruire la DLL accertarsi che siano attivati i seguenti switch: + 1) S4DLL_BUILD definito da command line del compilatore + 2) Uno solo tra S4FOX S4CLIPPER S4NDX e S4MDX, definito in d4all.h + + Gli altri switch di configurazione generale sono a piacere (S4DEBUG, S4ERROR_HOOK, ecc.) + + Per costruire WINUNO.LIB Accertarsi che d4all.h non abbia definito S4DLL o S4UNIX, + e tanto meno S4DLL_BUILD, altrimenti per costruire la library di UNIX e' necessario + cambiare ogni volta. La definizione di tali simboli avviene qui dentro. + Inoltre deve essere attivo uno solo degli switch di selezione formato database + (S4FOX, S4MDX ecc.); nel caso si faccia uso della DLL non importa quale si e' definito. + E' importante solo in caso di utilizzo di una static Library. + + Per costruire l'aga.fll e' necessario togliere le funzioni progind* e definire S4DLL. + +*/ +#if XVT_OS == XVT_OS_SCOUNIX +#define S4UNIX +#else +#define S4DLL +#endif + +#ifdef XVT /* This not recommended in Unix!*/ +#undef S4UNIX +#define S4DLL +#endif + +#ifdef FOXPRO +#undef S4UNIX +#define S4DLL +#endif + +#include +#include +#include +#include +#include +#include +#define MAXLEN 128 // Lunghezza massima chiave + +extern char* CUpString(char *); + +static CODE4 code_base; +static DATA4 *dbdata[CB4FILES]; +static X4FILTER xdb[CB4FILES]; + + +static char * find_slash_backslash(char * str) +{ + int l=strlen(str); + static char * xstr ; + xstr = str + l; + + while (xstr-- && l--) + if (*xstr == '\\' || *xstr == '/') + break; + if (l == 0) + return NULL; + else + return xstr; +} + + +/*-------------------------------------------------------------------------- + funzione di filtro usata su tutti i database + --------------------------------------------------------------------------*/ +int S4CALL notdelete(void *fd) +{ + if(d4deleted(fd)) return r4ignore; + else return r4keep; +} + +/*-------------------------------------------------------------------------- + inizializzazione di CodeBase e delle variabili necessarie + questa funzione deve essere chiamata SOLO una volta all'interno + di ciascun eseguibile + --------------------------------------------------------------------------*/ +void DB_init(void) +{ + int i; + for(i=0;i 0) + x4top(&xdb[found]); + return(found); +} + + +/*------------------------------------------------------------------------- + chiusura del database inviduato da handle + torna -1 se il database non puo essere chiuso + --------------------------------------------------------------------------*/ +int DB_close(int handle) +{ + if(dbdata[handle]==0) return(-1); + d4close(dbdata[handle]); + dbdata[handle]=(DATA4 *) 0; + code_base.error_code=0; + return(0); +} + +/*------------------------------------------------------------------------- + torna il puntatore al buffer del record del database individuato da + handle. In caso di errore torna (char *) 0 + --------------------------------------------------------------------------*/ +char *DB_getrecord(int handle) +{ + if(dbdata[handle]==0) return((char *) 0); + return(d4record(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + torna la lunghezza del record + --------------------------------------------------------------------------*/ +int DB_reclen(int handle) +{ + if(dbdata[handle]==0) return(-1); + return((int) d4record_width(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + torna la lunghezza della chiave corrente + --------------------------------------------------------------------------*/ + +int DB_keylen(int handle) +{ + TAG4 *t; + + if (dbdata[handle]==0) return(-1); + if ((t=d4tag_default(dbdata[handle]))== NULL) return (-1); + return(strlen(t4key(t))); +} + +/*------------------------------------------------------------------------- + torna il numero del record attuale + --------------------------------------------------------------------------*/ +long int DB_recno(int handle) +{ + if(dbdata[handle]==0) return(-1L); + return(d4recno(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + torna il numero complessivo dei records presenti nell'archivio + --------------------------------------------------------------------------*/ +long int DB_reccount(int handle) +{ + if(dbdata[handle]==0) return(-1L); + return(d4reccount(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + seleziona un indice sul database specificato + torna -1 se errore, altrimenti 0 + --------------------------------------------------------------------------*/ +int DB_tagselect(int handle,int index_no) +{ + TAG4 *tt; + int i; + + if(dbdata[handle]==0) return(-1); + // si posiziona sul primo indice + tt=d4tag_next(dbdata[handle],NULL); + if(tt==NULL) return(-1); + for(i=1;ifile.name,0,0); + else + strcpy(fn,dbdata[handle]->file.name); + if ((i=d4index(dbdata[handle],fn)) == NULL) + return(e4index); + rt=i4lock(i); + if (rt == 0) + rt=t4remove_calc(t,recno); + i4unlock(i); + return(rt); +} + +/*------------------------------------------------------------------------- + riscrive il record attuale + --------------------------------------------------------------------------*/ +int DB_rewrite(int handle) +{ + if(dbdata[handle]==0) return(-1); + return(d4write(dbdata[handle],d4recno(dbdata[handle]))); +} + + +/*------------------------------------------------------------------------- + appende il record attuale + --------------------------------------------------------------------------*/ +int DB_add(int handle) +{ + if(dbdata[handle]==0) return(-1); + d4append_start(dbdata[handle],0); + d4recall(dbdata[handle]); + return(d4append(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + Blocca in modo esclusivo il file dati ed indice + --------------------------------------------------------------------------*/ +int DB_lockfile(int handle) +{ + int rt; + + if(dbdata[handle]==0) return(-1); + rt = d4lock_file(dbdata[handle]); + if (rt>=0) rt=d4lock_index(dbdata[handle]); + return(rt); +} + +HIDDEN int is_inkey(RecDes *r, int numfield) +{ + int found=0,i,j; + + for (i=0; ((i < MaxKeys) && (i < r->NKeys) && !found); i++) + for (j=0; ((j < r->Ky[i].NkFields) && !found); j++) + if (numfield == r->Ky[i].FieldSeq[j]) + found=1; + return(found); +} + +HIDDEN void do_key(char *fname, RecDes *r, TAG4INFO *tag_info) +{ + int i,j; + char tiname[9]; // Tag name, max 8 characters long! + + strcpy(tiname,fname); + CUpString(tiname); + for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++) + { + tag_info[i].name=(char *)u4alloc(9); + tag_info[i].expression=(char *)u4alloc(128); + tag_info[i].filter=(char*)u4alloc(20); + tag_info[i].descending=0; + if (r->Ky[i].DupKeys) + tag_info[i].unique=0; + else + tag_info[i].unique=e4unique; + strcpy(tag_info[i].filter,""); // Not available for DBIII and CLIPPER + strcpy(tag_info[i].name,tiname) ; + if (strlen(tiname) < 8) + strcat(tag_info[i].name," "); + tag_info[i].name[strlen(tag_info[i].name)-1] = '0' + i + 1; + for (j=0; j < r->Ky[i].NkFields; j++) + { + int nf= r->Ky[i].FieldSeq[j]; + if (nf > MaxFields) // When Upper field is specified + { + nf -= MaxFields; + strcat(tag_info[i].expression,"UPPER("); + } + if (r->Ky[i].FromCh[j] != 255) // When partial field is specified + strcat(tag_info[i].expression,"SUBSTR("); + + switch (r->Fd[nf].TypeF) // When numeric field in key is specified + { + case _intfld: + case _longfld: + case _realfld: + case _wordfld: + case _intzerofld: + case _longzerofld: + strcat(tag_info[i].expression,"STR("); + break; + case _datefld: + strcat(tag_info[i].expression,"DTOS("); + break; + case _boolfld: + strcat(tag_info[i].expression,"IIF("); // Logical fields are in key too... + break; + default: // It's a non sense to keep _realfld in key... + break; // however it's possible to have it... + } // Le chiavi composte da campi data non necessitano di funzioni di traduzione. + + strcat(tag_info[i].expression,r->Fd[nf].Name); // Append field name + + if (r->Ky[i].FromCh[j] != 255) // If partial field was specified + { // add parameters to SUBSTR + char ts[8]; + + strcat(tag_info[i].expression,","); + sprintf(ts,"%d",r->Ky[i].FromCh[j]); + strcat(tag_info[i].expression,ts); + strcat(tag_info[i].expression,","); + sprintf(ts,"%d",r->Ky[i].ToCh[j] - r->Ky[i].FromCh[j] + 1); + strcat(tag_info[i].expression,ts); + strcat(tag_info[i].expression,")"); + } + + switch (r->Fd[nf].TypeF) // If numeric field was specified + { // add parameters to STR + case _intfld: + case _longfld: + case _realfld: // Questo tipo di campo(real) non ha senso in un a chiave... + case _wordfld: + case _intzerofld: + case _longzerofld: + { + char ts[8]; + strcat(tag_info[i].expression,","); + sprintf(ts,"%d",r->Fd[nf].Len); + strcat(tag_info[i].expression,ts); + strcat(tag_info[i].expression,",0)"); + } + break; + case _boolfld: // Orgssbb... Che culo. + strcat(tag_info[i].expression,",\"T\",\"F\")"); + break; + default: + break; + } + + // Close parentheses if UPPER or DTOS operators were used: + if (r->Ky[i].FieldSeq[j] > MaxFields || (r->Fd[nf].TypeF == _datefld)) + strcat(tag_info[i].expression,")"); + // If there's another field in key adds "+" operator: + if (j < (r->Ky[i].NkFields-1)) + strcat(tag_info[i].expression,"+"); + } + } + tag_info[i].name=NULL; + tag_info[i].expression=NULL; + tag_info[i].filter=NULL; + tag_info[i].unique=0; + tag_info[i].descending=0; +} + +/*------------------------------------------------------------------------- + Compatta il file dati + --------------------------------------------------------------------------*/ +int DB_packfile(short vis, const char * filename, long eod) +{ + int rt=0,handle; + + // if(dbdata[handle]==0) return(-1); + // codebase.auto_open = 0 cosi' non apre gli indici + code_base.auto_open = 0; + handle=DB_open(filename,1); // Exclusive mode open! + if (handle > -1) + { + char s[81]; + + if (vis) + { + strcpy(s,"Compattamento dati file : "); + strcat(s,(char*)filename); +#ifndef FOXPRO + progind_create(10L,s,1,1,1); +#endif + } + if (eod < d4reccount(dbdata[handle])) + { + rt=d4zap(dbdata[handle],++eod,d4reccount(dbdata[handle])); + } else + rt=d4pack(dbdata[handle]); + if (vis) + { +#ifndef FOXPRO + progind_set_status((long)10); + progind_destroy(); +#endif + } + DB_close(handle); + } + else + rt=code_base.error_code; + code_base.auto_open = 1; + return rt; +} + +/*------------------------------------------------------------------------- + Compatta gli indici + --------------------------------------------------------------------------*/ +int DB_packindex(short vis, const char * filename, RecDes *r, long *peod) +{ + int rt=0,handle; + TAG4INFO tags[MaxKeys+1]; + char s[82]; + + strcpy(s,"Ricostruzione indici file : "); + strcat(s,filename); + + // codebase.auto_open = 0 cosi' non apre gli indici + code_base.auto_open=0 ; + handle=DB_open(filename,1); // Exclusive mode open + if (handle > -1) + { + int i; + char *ff = find_slash_backslash((char *)filename); + if (vis) + { +#ifndef FOXPRO + progind_create((long)r->NKeys,s,1,1,1); +#endif + } + if (ff == NULL || *ff == NULL) + ff = filename; + else + ff++; + do_key(ff,r,tags); + if (u4switch() &2 || u4switch() & 8) // Clipper and DBIII + { + rt = (int)i4create(dbdata[handle],(char*)filename,tags); +#ifndef FOXPRO + progind_set_status((long)r->NKeys); +#endif + if (rt!=0 && code_base.error_code==0) + { + FILE *fp; + char cgp[81]; + + strcpy(cgp,filename); + strcat(cgp,".CGP"); + if ((fp=fopen(cgp,"w"))!=NULL) + { + int j; + + for (j=0; jNKeys;j++) + fprintf(fp,"%s\n",tags[j].name); + fclose(fp); + } + } + } + if (u4switch() & 1 || u4switch() & 4) // FOXPRO and DBIV + { + rt = (int)i4create(dbdata[handle],NULL,tags); +#ifndef FOXPRO + progind_set_status((long)r->NKeys); +#endif + } + for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++) + { + u4free(tags[i].name); + u4free(tags[i].expression); + u4free(tags[i].filter); + } + if (vis) + { +#ifndef FOXPRO + progind_destroy(); +#endif + } + *peod=DB_reccount(handle); + DB_close(handle); + } + code_base.auto_open = 1; + return(code_base.error_code); +} + + +/*------------------------------------------------------------------------- + costruisce il file filename + --------------------------------------------------------------------------*/ + +int DB_build(const char * filename, RecDes *r) +{ + + FIELD4INFO field_info[MaxFields+1]; // Numero di campi in un record + TAG4INFO tag_info[MaxKeys+1]; // Numero di chiavi in un file + DATA4 *dbuilded; + int rt=0,i; + char *ff = find_slash_backslash((char *)filename); + + + for (i=0; ((iNFields) && (iFd[i].Name); + field_info[i].len = r->Fd[i].Len; + field_info[i].dec = r->Fd[i].Dec; + switch (r->Fd[i].TypeF) + { + case _intfld: + case _longfld: + case _realfld: // It's a non sense to keep this in key! + case _wordfld: + case _intzerofld: + case _longzerofld: + field_info[i].type=r4num; + break; + case _boolfld: + field_info[i].type=r4log; + break; + case _datefld: + field_info[i].type=r4date; + break; + case _charfld: + default: + field_info[i].type=r4str; + break; + } + } + field_info[i].name=NULL; + field_info[i].type=0; + field_info[i].len=0; + field_info[i].dec=0; + + if (ff == NULL || *ff == NULL) + ff = (char *) filename; + else + ff++; + do_key(ff,r,tag_info); + + if ((dbuilded=d4create(&code_base, (char *)filename, field_info, tag_info))==0) // deve solo creare il file dati vuoto + rt=code_base.error_code; + else + rt=d4close(dbuilded); + if (u4switch() & 2 || u4switch() & 8) // Rebuild filename.cgp for CLIPPER AND DBIII only + { + FILE* fp; + char xx[81]; + + strcpy(xx,(char*)filename); + + strcat(xx,".cgp"); + if ((fp=fopen(xx,"w"))!=NULL) + { + int j; + for (j=0; tag_info[j].name ; j++) + fprintf(fp,"%s\n",tag_info[j].name); + fclose(fp); + } + } + if (rt!=0) + rt=code_base.error_code; + for (i=0; ((i < MaxFields) && (i < r->NFields)); i++) + u4free(field_info[i].name); + for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++) + { + u4free(tag_info[i].name); + u4free(tag_info[i].expression); + u4free(tag_info[i].filter); + } + return(rt) ; +} + +/*------------------------------------------------------------------------- + ritorna l'ultimo errore + --------------------------------------------------------------------------*/ + +int DB_get_error(void) +{ + int rt = code_base.error_code; + code_base.error_code=0; + return (rt); +} + +/*------------------------------------------------------------------------- + Azzera la viarabile globale d'errore + --------------------------------------------------------------------------*/ + +void DB_zero_error(void) +{ + code_base.error_code=0; +} + +/*------------------------------------------------------------------------- + Si posiziona sull'indice attivo alla chiave indicata, restituisce + la prima chiave che trova >= a from. (TCusrsor) + --------------------------------------------------------------------------*/ + +int DB_index_seek(int handle, char* from) +{ + TAG4 *t; + + if(dbdata[handle]==0) return(-1); + if ((t=d4tag_default(dbdata[handle]))==NULL) return(-1); + + if (t4seek(t,from,strlen(from)) < 0) return(DB_get_error()); + return(0); + +} + +/*------------------------------------------------------------------------- + Ritorna il numero di record corrispondente alla chiave corrente + --------------------------------------------------------------------------*/ + +long DB_index_recno(int handle) +{ + TAG4 *t; + + if(dbdata[handle]==0) return(-1); + if ((t=d4tag_default(dbdata[handle]))==NULL) return(-1); + + return(t4recno(t)); +} + +/*------------------------------------------------------------------------- + Si posiziona sulla chiave successiva dell'indice corrente + --------------------------------------------------------------------------*/ +long DB_index_next(int handle) +{ + TAG4 *t; + + if(dbdata[handle]==0) return(-1); + if ((t=d4tag_default(dbdata[handle]))==NULL) return(-1); + + return(t4skip(t,1L)); +} + +/*------------------------------------------------------------------------- + Restituisce la chiave corrente + --------------------------------------------------------------------------*/ + +char* DB_index_getkey(int handle) +{ + TAG4 *t; + static char key[MAXLEN]; + int klen; + + if(dbdata[handle]==0) return(NULL); + if ((t=d4tag_default(dbdata[handle]))==NULL) return(NULL); + klen=expr4key_len(t->expr); + if (klen > (MAXLEN-1)) klen=MAXLEN-1; + memcpy(key,t4key(t),klen); // t4key non restituisce una null terminated string + key[klen]='\0'; + return(key); +} + +/*------------------------------------------------------------------------- + Restituisce vero se l'indice e' alla fine + --------------------------------------------------------------------------*/ + +int DB_index_eof(int handle) +{ + TAG4 *t; + + if(dbdata[handle]==0) return(-1); + if ((t=d4tag_default(dbdata[handle]))==NULL) return(-1); + return(t4eof(t)); +} + +/*------------------------------------------------------------------------- + Blocca il record indicato + --------------------------------------------------------------------------*/ + +int DB_lock_rec(int handle,long nrec) +{ + if(dbdata[handle]==0) return(-1); + if(d4lock(dbdata[handle],nrec)==r4locked) return(-1); + else return(0); +} + +/*------------------------------------------------------------------------- + Ritorna vero se il file e' bloccato in modo exclusive + --------------------------------------------------------------------------*/ + + +int DB_file_locked(int handle) +{ + if(dbdata[handle]==0) return(-1); + return(d4lock_test_file(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + Ritorna vero se il record nrec e' bloccato + --------------------------------------------------------------------------*/ + +int DB_rec_locked(int handle,long nrec) +{ + if(dbdata[handle]==0) return(-1); + return(d4lock_test(dbdata[handle],nrec)); +} + +/*------------------------------------------------------------------------- + restituisce la configurazione della libreria + --------------------------------------------------------------------------*/ + +long DB_getconf() +{ + return(u4switch()); +} + +/*------------------------------------------------------------------------- + Restituisce il numero di versione scritto sull'header dell'indice + --------------------------------------------------------------------------*/ + +long DB_changed(int handle) +{ + INDEX4 *i; + char fn[32]; + + if(dbdata[handle]==0) return(-1); + if (u4switch() & 2 || u4switch() & 8) // Clipper & DBIII + u4name_piece(fn,32,dbdata[handle]->file.name,0,0); + else + strcpy(fn,dbdata[handle]->file.name); + i=d4index(dbdata[handle],fn); + if (i == NULL) return(-1); + + return(i4changed(i)); +} diff --git a/include/codeb.h b/include/codeb.h new file mode 100755 index 000000000..77b60a78f --- /dev/null +++ b/include/codeb.h @@ -0,0 +1,74 @@ +/*-------------------------------------------------------------------------- + CODEBASE.H + data : 23.01.95 + scopo: interfaccia verso CodeBase 5.0 +--------------------------------------------------------------------------*/ +#ifndef __CODEBASE_H +#define __CODEBASE_H + +#ifndef __EXTCTYPE_H +#include +#endif + +/*-------------------------------------------------------------------------- + numero massimo di database aperti contemporaneamente +--------------------------------------------------------------------------*/ +#define CB4FILES 50 + +/*-------------------------------------------------------------------------- + prototipi funzioni +--------------------------------------------------------------------------*/ +#ifdef __cplusplus +extern "C" { +#endif +void DB_init(void); +void DB_exit(void); +int DB_open(const char *filename,int mode); +int DB_close(int handle); +char *DB_getrecord(int handle); +int DB_reclen(int handle); +int DB_keylen(int handle); +long int DB_recno(int handle); +long int DB_reccount(int handle); +int DB_tagselect(int handle,int index_no); +int DB_tagget(int handle); +int DB_first(int handle); +int DB_last(int handle); +int DB_next(int handle); +int DB_prev(int handle); +int DB_skip(int handle,long int recno); +int DB_lock(int handle); +int DB_lockrec(int handle, long recno); // Per sbloccare il record basta la DB_unlock() +int DB_unlock(int handle); +int DB_seek(int handle,char *key); +int DB_eof(int handle); +int DB_bof(int handle); +int DB_go(int handle,long int recno); +int DB_delete(int handle); +int DB_recall(int handle); +int DB_delkey(int handle, char* key, long recno); +int DB_rewrite(int handle); +int DB_add(int handle); +int DB_lockfile(int handle); // Per sbloccare il file basta la DB_unlock() +int DB_packfile(short vis, const char * filename, long eod); +int DB_packindex(short vis, const char * filename, RecDes *r, long *peod ); +int DB_build(const char * filename, RecDes *r); +int DB_get_error(void); +void DB_zero_error(void); +int DB_index_seek(int handle, char* from); +long DB_index_recno(int handle); +long DB_index_next(int handle); +char* DB_index_getkey(int handle); +int DB_index_eof(int handle); +int DB_lock_rec(int handle,long nrec); +int DB_file_locked(int handle); +int DB_rec_locked(int handle,long nrec); +long DB_getconf(); +long DB_changed(int handle); // returns true if the index of the key is changed +#ifdef __cplusplus +}; +#endif +#endif + + + diff --git a/include/extctype.h b/include/extctype.h index cc98566f8..6ca7ec655 100755 --- a/include/extctype.h +++ b/include/extctype.h @@ -199,13 +199,13 @@ typedef struct typedef struct { - SecDef f; - FilCtrl i; + int fhnd; FileDes *d; RecDes *r; - RecNoType RecNo; + RecNoType RecNo; INT16 ln; - INT16 ft; + INT16 ft; + int knum; } isdef ; diff --git a/include/files.cpp b/include/files.cpp index cf87765fc..a4a7f2d4d 100755 --- a/include/files.cpp +++ b/include/files.cpp @@ -136,7 +136,7 @@ const char *TDir::name () const } const char *TDir::des () const -{ +{ return _dir->Des; } @@ -146,9 +146,11 @@ const char* TDir::tab_des(const char* tab) TString256 tmp; tmp << DESCDIR << "/d" << t << ".des"; - + +#ifndef FOXPRO TConfig cnf(tmp, DESCTAB); t = cnf.get("Description", NULL, -1, tab); +#endif return strcpy(__tmp_string, t); } diff --git a/include/isam.cpp b/include/isam.cpp index 38fc20b64..b96c2a179 100755 --- a/include/isam.cpp +++ b/include/isam.cpp @@ -12,12 +12,13 @@ #include #include -#include +#include #include #include #include -#include +#include #include +#include #if XVT_OS==XVT_OS_WIN #include @@ -31,6 +32,26 @@ #define NOT_LINKED(i,f) CHECKS(i != NULL, "Record senza tracciato: impossibile eseguire ", f) #define NOT_OPEN() CHECKS(_isamfile != NULL, "File chiuso: ", (const char*)name()) +#define INTTLOCK 0x600 +#define RECLOCKTYPES 0xFF00 +#define READTYPES 0x00FF + +isfdptr* openf; +Str80 cprefix; + +HIDDEN int error_codes_g[] = {-1,_isnotopen,-1,-1,-1,_islocked,-1,-1,-1,-1,-1,-1,_isfilefull, + -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,_iskeynotfound,_ispatherr,-1,-1,_isdupkey}; + +HIDDEN int error_codes_ra[] = {NOERR,NOERR,_iskeynotfound,_iseof,_isbof,_isnrecerr} ; +// Codici da 0 a 9 +HIDDEN int error_codes_rb[] = {-1,-1,_isreinsert,-1,-1,_islocked,-1,_isalropen,_iskeyerr } ; +// Codici da 10 a ... + +extern "C" { + void CUpString(char*); + void crtrim(char*); +}; + HIDDEN char _isam_string[257]; HIDDEN void UNKNOWN_FIELD(int num, const char* name) @@ -38,7 +59,293 @@ HIDDEN void UNKNOWN_FIELD(int num, const char* name) #define NOALLOC (char **) -1 -HIDDEN bool __autoload = TRUE; +HIDDEN bool __autoload = TRUE; + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Funzioni implementate per la gestione file dati tramite Codebase +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Inizio(@) + +void get_idx_names(int logicnum, TToken_string& i_names) // Returns a Token_string with the index names. (Current prefix!) +{ + long c = DB_getconf(); + TDir d; + TTrec r; + d.get(logicnum); + r.get(logicnum); + TFilename f(d.name()); + + if ( c & 1) f.ext("cdx"); + if ( c & 4) f.ext("mdx"); + i_names.cut(0); + i_names.add(f); + f.ext(""); + f.rtrim(1); + if (c & 2 || c & 8) // DBIII or CLIPPER format, returns f_name + .cgp, f_nameX + .n{d|t}x + for (int j=1; j<=r.keys();j++) + { + TString xx=f.name(); + if (xx.len()<8) + f << ('0' + j); + else + f[8] = ('0' + j); + if (c & 2) // CLIPPER + f.ext("ndx"); + else // DBIII + f.ext("ntx"); + i_names.add(f); + } + i_names.restart(); +} + +int get_error(int err) +{ + + if (err > 0) + { + if (err >= 10) + { + if (err > 80 || error_codes_rb[err/10]==-1) return err; + else + return(error_codes_rb[err/10]); + } + else + return(error_codes_ra[err]); + } + else + if (err < 0) + { + int ierr = DB_get_error(); + if (ierr < 0) ierr = -ierr; + if (ierr > 340 || error_codes_g[ierr/10]==-1) return (-ierr); + return (error_codes_g[ierr/10]); + } + DB_zero_error(); + return(NOERR); +} + +HIDDEN void browse_null(char *start, int nc) +{ + for (int i = nc - 1; i >= 0 ; i--) // Anche il primo byte(deletion flag) deve essere cambiato. nc comprende il primo byte + if (start[i] == '\0') start[i] = ' '; +} + + +HIDDEN void getisfd(isfdptr & isfd, int logicnum) +{ + isfd = new isdef ; + isfd->r = new RecDes ; + isfd->d = new FileDes ; + CGetFile(logicnum, isfd->d, _nolock, _nordir); + const TFixed_string name(isfd->d->SysName); + if (name.not_empty() && name[0] == '%') + isfd->ft = _comdir; + else + isfd->ft = _nordir; + COpenFile(logicnum, isfd->d, _nolock, isfd->ft); + CGetRec(logicnum, isfd->r, isfd->ft); + isfd->ln = logicnum; +} + +HIDDEN void relisfd(isfdptr & isfd) + +{ + if (isfd->ln > 0 && isfd->fhnd >= 0) + { + TDir d; + + d.get(isfd->ln, _lock, (TDirtype) isfd->ft, _sysdirop); + d.eod() = isfd->d->EOD; + d.eox() = isfd->d->EOX; + d.put(isfd->ln, (TDirtype) isfd->ft, _sysdirop); + } + delete isfd->d; + delete isfd->r; + delete isfd; +} + +HIDDEN int CBuildKey(RecDes *recd, int numkey, RecType recin, char *key) + /* *recd; descrittore record */ + /* numkey; numero chiave */ + /* recin; buffer contenente il record */ + /* *key; valore della chiave */ + +{ + int i, nf, l = 0, len, off; + /* TrDate wd ; + char s1[10]; + */ + BOOLEAN upp; + + strcpy(key, ""); + if (numkey-- <= recd->NKeys) + { + for (i = 0; i < recd->Ky[numkey].NkFields; i++) + { + if ((upp = (recd->Ky[numkey].FieldSeq[i] > MaxFields)) == TRUE) + nf = recd->Ky[numkey].FieldSeq[i] - MaxFields; + else + nf = recd->Ky[numkey].FieldSeq[i]; + if (recd->Ky[numkey].FromCh[i] == 255) + { + off = recd->Fd[nf].RecOff; + len = recd->Fd[nf].Len; + } + else + { + /* + if (recd->Fd[nf].TypeF == _datefld) + { + off = recd->Fd[nf].RecOff; + len = recd->Fd[nf].Len; + strncpy(s1, (recin + off), len); + s1[len] = '\0'; + off = recd->Ky[numkey].FromCh[i]; + len = recd->Ky[numkey].ToCh[i] - + recd->Ky[numkey].FromCh[i] + 1; + } + else + { + */ + off = recd->Fd[nf].RecOff + recd->Ky[numkey].FromCh[i]; + len = recd->Ky[numkey].ToCh[i] - + recd->Ky[numkey].FromCh[i] + 1; + /* } */ + } + if ((l + len) > 80) + { + strcpy(key, ""); + return(_iskeylenerr); + } + /* if ((recd->Fd[nf].TypeF == _datefld) && (recd->Ky[numkey].FromCh[i] != 255)) + strncpy((key + l), &s1[off], len); + else + { + */ + strncpy((key + l), (recin + off), len); +#ifdef XVT_OS + if (recin[off] == '\0') memset(key + l, ' ', len); + else + if ((recd->Fd[nf].TypeF == _intfld) || + (recd->Fd[nf].TypeF == _longfld) || + (recd->Fd[nf].TypeF == _wordfld)) + { + int w = l, j = l + len; + while (w < j && key[w] == ' ') w++; + while (w < j && key[w] == '0') + key[w++] = ' '; + } +#endif + /* } */ + l += len; + } + key[l] = '\0'; + crtrim(key); + if (upp) CUpString(key) ; + return(NOERR); + } + return(_ispatherr); +} + +HIDDEN int cisstart(isfdptr isfd, int keynum, TRectype & record, unsigned int mode) + +{ + // It seems quite unuseful... Quando cambio la chiave con setkey, la d4tagselect + // seleziona gia' l'indice, rendendo inutile il senso della cisstart + return NOERR; +} + + +HIDDEN int cisread(isfdptr isfd, TRectype & record, int mode) +{ + // Non usare mai _isnextn o _isprevn, usare il metodo skip! + + int rmode = (mode & READTYPES), lmode = (mode & RECLOCKTYPES); + BOOLEAN nolock = (lmode == _nolock); + BOOLEAN unlock = (lmode == _unlock); + BOOLEAN tlock = (lmode == INTTLOCK); + char key[128]; + int err = NOERR ; + + + if (nolock || unlock || tlock) lmode = 0; + do + { + if (rmode==_isfirst) + err=DB_first(isfd->fhnd); + if (rmode==_islast) + err=DB_last(isfd->fhnd); + if (rmode==_isnext) + err=DB_next(isfd->fhnd); + if (rmode==_isprev) + err=DB_prev(isfd->fhnd); + if (rmode==_iscurr) + err=DB_go(isfd->fhnd,DB_recno(isfd->fhnd)); + if (err != NOERR) err=get_error(err); + if (rmode==_isnextn || rmode==_isprevn) + { + error_box("_isnextn and _isprevn not supported in cisread"); + err=_iskeynotfound; + } + if (rmode>=_isequal && rmode<=_isgteq) + { + err=CBuildKey(isfd->r,DB_tagget(isfd->fhnd),record.string(),key); + if (err == NOERR) + { + err=DB_seek(isfd->fhnd,key); + if (err != NOERR)err=get_error(err); + } + if (rmode != _isequal && err == _iskeynotfound) err = NOERR; + } + if (rmode != _isequal && err == _iseof) + DB_last(isfd->fhnd); + if (!tlock && err == _islocked) + { + CBuildKey(isfd->r, DB_tagget(isfd->fhnd), record.string(), key); + message_box("Codice %s in uso da parte\ndi un altro utente.", key); + } + } while (!tlock && err ==_islocked); + if (err == NOERR && lmode == _lock) + { + err=DB_lock(isfd->fhnd); + if (err != NOERR) err=get_error(err); + } + if (err == NOERR && unlock) + { + err=DB_unlock(isfd->fhnd); + if (err != NOERR) err=get_error(err); + } + if (err == NOERR) + memcpy(record.string(),DB_getrecord(isfd->fhnd),DB_reclen(isfd->fhnd)); + isfd->RecNo = DB_recno(isfd->fhnd); + return err; +} + +HIDDEN int delkeys(isfdptr fd, char* record,long recno) +{ + int rt=NOERR,oldkey=DB_tagget(fd->fhnd); + + + for (int i=1; i<=fd->r->NKeys;i++) + { + char key[128]; + + DB_tagselect(fd->fhnd,i); + rt=CBuildKey(fd->r,i,record,key); + if (rt!=NOERR) break; + rt=DB_delkey(fd->fhnd,key,recno); + if (rt!=NOERR) break; + } + + DB_tagselect(fd->fhnd,oldkey); + return(rt); +} +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Funzioni implementate per la gestione file dati tramite Codebase +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Fine(@) + void set_autoload_new_files(bool on) { @@ -78,7 +385,7 @@ TExtrectype::TExtrectype(const TTrec& r) : TRectype(6) TExtrectype::~TExtrectype() { - delete _rec; + // delete _rec; // delete _i; } @@ -89,7 +396,6 @@ TExtrectype::~TExtrectype() TBaseisamfile::TBaseisamfile(int logicnum, bool linkrecinst) { - TTrec r; _isamfile = NULL; _logicnum = logicnum; @@ -111,12 +417,10 @@ TBaseisamfile::TBaseisamfile(int logicnum, bool linkrecinst) _delrec = FALSE; } - r.get(logicnum); - /* - _historicfile = ((r.field(RFLD_SYS_DATE) != FIELDERR) && - (r.field(RFLD_SYS_FIRST) != FIELDERR) && - (r.field(RFLD_SYS_LAST) != FIELDERR)); - */ + + // _historicfile = ((r.field(RFLD_SYS_DATE) != FIELDERR) && + // (r.field(RFLD_SYS_FIRST) != FIELDERR) && + // (r.field(RFLD_SYS_LAST) != FIELDERR)); _historicfile = FALSE; } @@ -203,7 +507,7 @@ int TBaseisamfile::delhr(const TRectype& rec, TDate& atdate) long TBaseisamfile::items() const { - return filehnd()->i.Base[filehnd()->i.PN].PEOD; + return(DB_reccount(filehnd()->fhnd)); } const char* TBaseisamfile::name() const @@ -236,20 +540,29 @@ const char* TBaseisamfile::description() const return _isamfile->d->Des; } +TRecnotype TBaseisamfile::eod() const +{ + NOT_OPEN(); + return(DB_reccount(_isamfile->fhnd)); +} void TBaseisamfile::setkey(int nkey) { CHECKD(nkey > 0 && nkey-1 <= _isamfile->r->NKeys, "Chiave non valida ", nkey); NOT_OPEN(); - _isamfile->i.PN = nkey - 1; + + int rt = DB_tagselect(_isamfile->fhnd,nkey); + if (rt>=0) _isamfile->knum=nkey; + if (rt!=NOERR) rt=get_error(rt); + if (_lasterr == NOERR) setstatus(rt); } int TBaseisamfile::getkey() const { NOT_OPEN(); - return _isamfile->i.PN + 1; + return (DB_tagget(_isamfile->fhnd)); } int TBaseisamfile::first(word lockop) @@ -257,7 +570,8 @@ int TBaseisamfile::first(word lockop) { NOT_OPEN(); curr().setdirty(); - cisread(_isamfile, curr().string(), _isfirst + lockop, &_lasterr); + _lasterr=cisread(_isamfile, curr(), _isfirst + lockop); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); _recno = _isamfile->RecNo; return _lasterr; } @@ -268,7 +582,8 @@ int TBaseisamfile::last(word lockop) { NOT_OPEN(); curr().setdirty(); - cisread(_isamfile, curr().string(), _islast + lockop, &_lasterr); + _lasterr=cisread(_isamfile, curr(), _islast + lockop ); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); _recno = _isamfile->RecNo; return _lasterr; } @@ -279,7 +594,8 @@ int TBaseisamfile::next(word lockop) { NOT_OPEN(); curr().setdirty(); - cisread(_isamfile, curr().string(), _isnext + lockop, &_lasterr); + _lasterr=cisread(_isamfile, curr(), _isnext + lockop); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); _recno = _isamfile->RecNo; return _lasterr; } @@ -287,34 +603,8 @@ int TBaseisamfile::next(word lockop) int TBaseisamfile::next(TDate& atdate) -{ - TRectype wr(curr()); - TRecfield fll(curr(), RFLD_SYS_LAST), - fd(wr, RFLD_SYS_DATE); - TRecnotype wrn; - - NOT_OPEN(); - if (!_historicfile) - error_box("%s not historic file", filename()); - if (_lasthf == -1L) return _iseof; - curr().setdirty(); - _hf.read(curr().string(), _lasthf); - wrn = fll.ptr(); - if (wrn < 0L) - { - readat(-wrn); - atdate = eotime; - _lasthf = -1L; - } - else - { - _hf.read(curr().string(), wrn); - _lasthf = wrn; - wrn = fll.ptr(); - if (wrn < 0) readat(wr, -wrn); - else _hf.read(wr.string(), wrn); - atdate = (const TDate&)fd - 1L; - } +{ + error_box("TBaseisamfile::next(TDate&) is no more available"); return NOERR; } @@ -324,7 +614,8 @@ int TBaseisamfile::prev(word lockop) { NOT_OPEN(); curr().setdirty(); - cisread(_isamfile, curr().string(), _isprev + lockop, &_lasterr); + _lasterr=cisread(_isamfile, curr(), _isprev + lockop); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); _recno = _isamfile->RecNo; return _lasterr; } @@ -332,25 +623,8 @@ int TBaseisamfile::prev(word lockop) int TBaseisamfile::prev(TDate& atdate) -{ - TRecfield flf(curr(), RFLD_SYS_LAST), - fd(curr(), RFLD_SYS_DATE); - TRecnotype wrn; - - NOT_OPEN(); - if (!_historicfile) - error_box("%s not historic file", filename()); - if (_lasthf == -1L) return _isbof; - curr().setdirty(); - _hf.read(curr().string(), _lasthf); - wrn = flf.ptr(); - atdate = (const TDate&) fd - 1L; - if (wrn < 0L) _lasthf = -1L; - else - { - _hf.read(curr().string(), wrn); - _lasthf = wrn; - } +{ + error_box("TBaseisamfile::prev(TDate&) is no more available"); return NOERR; } @@ -360,13 +634,8 @@ int TBaseisamfile::reread(word lockop, TDate& atdate) NOT_OPEN(); curr().setdirty(); - if ((!_historicfile) || (atdate == botime)) - return cisread(_isamfile, curr().string(), _iscurr + lockop, &_lasterr); - else - { - if (cisread(_isamfile, curr().string(), _iscurr + lockop, &_lasterr) == NOERR) - _lasterr = gethr(curr(), atdate); - } + _lasterr=cisread(_isamfile, curr(), _iscurr + lockop); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); _recno = _isamfile->RecNo; return _lasterr; } @@ -377,13 +646,8 @@ int TBaseisamfile::reread(TRectype& rec, word lockop, TDate& atdate) { NOT_OPEN(); rec.setdirty(); - if ((!_historicfile) || (atdate == botime)) - cisread(_isamfile, rec.string(), _iscurr + lockop, &_lasterr); - else - { - if (cisread(_isamfile, rec.string(), _iscurr + lockop, &_lasterr) == NOERR) - _lasterr = gethr(rec, atdate); - } + _lasterr=cisread(_isamfile, rec, _iscurr + lockop); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); _recno = _isamfile->RecNo; return _lasterr; } @@ -391,15 +655,37 @@ int TBaseisamfile::reread(TRectype& rec, word lockop, TDate& atdate) int TBaseisamfile::skip(TRecnotype nrec, word lockop) -{ +{ + int rmode = (lockop & READTYPES), lmode = (lockop & RECLOCKTYPES); + BOOLEAN nolock = (lmode == _nolock); + BOOLEAN unlock = (lmode == _unlock); + BOOLEAN tlock = (lmode == INTTLOCK); + char key[128]; + NOT_OPEN(); if (!nrec) return NOERR; - curr().setdirty(); - if (nrec >0) - cisread(_isamfile, curr().string(), _isnextn + lockop + (UINT16) nrec, &_lasterr); - else - cisread(_isamfile, curr().string(), _isprevn + lockop - (UINT16) nrec, &_lasterr); - _recno = _isamfile->RecNo; + curr().setdirty(); + _lasterr=DB_skip(_isamfile->fhnd,nrec); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + do { + if (!tlock && _lasterr == _islocked) + { + CBuildKey(_isamfile->r, DB_tagget(_isamfile->fhnd), curr().string(), key); + message_box("Codice %s in uso da parte\ndi un altro utente.", key); + } + _lasterr=cisread(_isamfile,curr(),_iscurr + lockop); + } while (!tlock && _lasterr ==_islocked); + if (_lasterr == NOERR && lmode == _lock) + { + _lasterr=DB_lock(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr=get_error(_lasterr); + } + if (_lasterr == NOERR && unlock) + { + _lasterr=DB_unlock(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr=get_error(_lasterr); + } + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); return _lasterr; } @@ -410,13 +696,8 @@ int TBaseisamfile::read(word op, word lockop, TDate& atdate) CHECKD(op >= _iscurr && op <= _isgteq, "Invalid read operation : ", op); NOT_OPEN(); curr().setdirty(); - if ((!_historicfile) || (atdate == botime)) - cisread(_isamfile, curr().string(), op + lockop, &_lasterr); - else - { - if (cisread(_isamfile, curr().string(), op + lockop, &_lasterr) == NOERR) - _lasterr = gethr(curr(), atdate); - } + _lasterr=cisread(_isamfile, curr(), op + lockop); + if (_lasterr != NOERR) _lasterr=get_error(_lasterr); _recno = _isamfile->RecNo; return _lasterr; } @@ -428,13 +709,8 @@ int TBaseisamfile::read(TRectype& rec, word op, word lockop, TDate& atdate) CHECKD(op >= _iscurr && op <= _isgteq, "Invalid read operation : ", op); NOT_OPEN(); rec.setdirty(); - if ((!_historicfile) || (atdate == botime)) - cisread(_isamfile, rec.string(), op + lockop, &_lasterr); - else - { - if (cisread(_isamfile, rec.string(), op + lockop, &_lasterr) == NOERR) - _lasterr = gethr(rec, atdate); - } + _lasterr=cisread(_isamfile, rec, op + lockop); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); _recno = _isamfile->RecNo; return _lasterr; } @@ -445,8 +721,11 @@ int TBaseisamfile::readat(TRecnotype nrec, word lockop) { NOT_OPEN(); curr().setdirty(); - cisreadrec(_isamfile, nrec, curr().string(), lockop, &_lasterr); - _recno = _isamfile->RecNo; + _lasterr=DB_go(_isamfile->fhnd,nrec); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + else + memcpy(curr().string(),DB_getrecord(_isamfile->fhnd),DB_reclen(_isamfile->fhnd)); + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); return _lasterr; } @@ -456,7 +735,10 @@ int TBaseisamfile::readat(TRectype& rec, TRecnotype nrec, word lockop) { NOT_OPEN(); rec.setdirty(); - cisreadrec(_isamfile, nrec, rec.string(), lockop, &_lasterr); + _lasterr=DB_go(_isamfile->fhnd,nrec); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + else + memcpy(rec.string(),DB_getrecord(_isamfile->fhnd),DB_reclen(_isamfile->fhnd)); _recno = _isamfile->RecNo; return _lasterr; } @@ -466,11 +748,11 @@ int TBaseisamfile::write(TDate& atdate) { NOT_OPEN(); - if ((!_historicfile) || (atdate == botime)) - ciswrite(_isamfile, curr().string(), &_lasterr); - else - _lasterr = addhr(curr(), atdate); - _recno = _isamfile->RecNo; + browse_null(curr().string(),DB_reclen(_isamfile->fhnd)); + memcpy(DB_getrecord(_isamfile->fhnd),curr().string(),DB_reclen(_isamfile->fhnd)); + _lasterr = DB_add(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); return _lasterr; } @@ -479,11 +761,11 @@ int TBaseisamfile::write(const TRectype& rec, TDate& atdate) { NOT_OPEN(); - if ((!_historicfile) || (atdate == botime)) - ciswrite(_isamfile, rec.string(), &_lasterr); - else - _lasterr = addhr(rec, atdate); - _recno = _isamfile->RecNo; + browse_null(rec.string(),DB_reclen(_isamfile->fhnd)); + memcpy(DB_getrecord(_isamfile->fhnd),rec.string(),DB_reclen(_isamfile->fhnd)); + _lasterr = DB_add(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); return _lasterr; } @@ -492,11 +774,14 @@ int TBaseisamfile::rewrite(TDate& atdate) { NOT_OPEN(); - if ((!_historicfile) || (atdate == botime)) - cisrewrite(_isamfile, curr().string(), &_lasterr); - else - _lasterr = rewhr(curr(), atdate); - _recno = _isamfile->RecNo; + TRectype save_rec(curr()); + + _lasterr = cisread(_isamfile, curr(), _isequal + _nolock); // Si Posiziona per sicurezza... + memcpy(DB_getrecord(_isamfile->fhnd),save_rec.string(),DB_reclen(_isamfile->fhnd)); + if (_lasterr == NOERR) + _lasterr = DB_rewrite(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); return _lasterr; } @@ -504,12 +789,14 @@ int TBaseisamfile::rewrite(TDate& atdate) int TBaseisamfile::rewrite(const TRectype& rec, TDate& atdate) { - NOT_OPEN(); - if ((!_historicfile) || (atdate == botime)) - cisrewrite(_isamfile, rec.string(), &_lasterr); - else - _lasterr = rewhr(rec, atdate); - _recno = _isamfile->RecNo; + NOT_OPEN(); + TRectype save_rec(rec); + _lasterr = cisread(_isamfile,(TRectype&) rec, _isequal + _nolock); // Si Posiziona per sicurezza... + memcpy(DB_getrecord(_isamfile->fhnd),save_rec.string(),DB_reclen(_isamfile->fhnd)); + if (_lasterr == NOERR) + _lasterr = DB_rewrite(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); return _lasterr; } @@ -518,7 +805,15 @@ int TBaseisamfile::rewriteat(TRecnotype nrec) { NOT_OPEN(); - return cisrewrec(_isamfile, nrec, curr().string(), &_lasterr); + if ((_lasterr=DB_go(_isamfile->fhnd,nrec))== NOERR) + { + memcpy(DB_getrecord(_isamfile->fhnd),curr().string(),DB_reclen(_isamfile->fhnd)); + _lasterr=DB_rewrite(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + } else + _lasterr = get_error(_lasterr); + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); + return _lasterr; } @@ -526,16 +821,25 @@ int TBaseisamfile::rewriteat(const TRectype& rec, TRecnotype nrec) { NOT_OPEN(); - return cisrewrec(_isamfile, nrec, curr().string(), &_lasterr); + if ((_lasterr=DB_go(_isamfile->fhnd,nrec))== NOERR) + { + memcpy(DB_getrecord(_isamfile->fhnd),rec.string(),DB_reclen(_isamfile->fhnd)); + _lasterr=DB_rewrite(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + } else + _lasterr = get_error(_lasterr); + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); + return _lasterr; } int TBaseisamfile::remove(TDate& atdate) { - NOT_OPEN(); + NOT_OPEN(); - // rimozione campi memo + // rimozione campi memo +#ifndef FOXPRO TMemo_file* memo = NULL; for (int i = 0; i < curr().items(); i++) @@ -552,12 +856,24 @@ int TBaseisamfile::remove(TDate& atdate) } } if (memo != NULL) delete memo; +#endif - if ((!_historicfile) || (atdate == botime)) - cisdelete(_isamfile, curr().string(), &_lasterr); - else - _lasterr = delhr(curr(), atdate); - _recno = _isamfile->RecNo; + if ((_lasterr=cisread(_isamfile, curr(), _isequal + _lock)) == NOERR) + { + _lasterr = DB_delete(_isamfile->fhnd); // Put only deletion flag on record, must remove keys too! + if (_lasterr != NOERR) + _lasterr = get_error(_lasterr); + else + { + _lasterr=delkeys(_isamfile,curr().string(), _isamfile->RecNo); + if (_lasterr != NOERR) + { + DB_recall(_isamfile->fhnd); + _lasterr = get_error(_lasterr); + } + } + } + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); return _lasterr; } @@ -566,11 +882,23 @@ int TBaseisamfile::remove(const TRectype& rec, TDate& atdate) { NOT_OPEN(); - if ((!_historicfile) || (atdate == botime)) - cisdelete(_isamfile, rec.string(), &_lasterr); - else - _lasterr = delhr(rec, atdate); - _recno = _isamfile->RecNo; + memcpy(DB_getrecord(_isamfile->fhnd),rec.string(),DB_reclen(_isamfile->fhnd)); + if ((_lasterr=cisread(_isamfile, (TRectype&) rec, _isequal + _lock))==NOERR) + { + _lasterr = DB_delete(_isamfile->fhnd); // Put only deletion flag on record, must remove keys too! + if (_lasterr != NOERR) + _lasterr = get_error(_lasterr); + else + { + _lasterr=delkeys(_isamfile,rec.string(),_isamfile->RecNo); + if (_lasterr != NOERR) + { + DB_recall(_isamfile->fhnd); + _lasterr = get_error(_lasterr); + } + } + } + _recno = _isamfile->RecNo = DB_recno(_isamfile->fhnd); return _lasterr; } @@ -579,7 +907,9 @@ int TBaseisamfile::lock() { NOT_OPEN(); - return cislock(_isamfile, &_lasterr); + _lasterr = DB_lockfile(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + return _lasterr; } @@ -587,27 +917,27 @@ int TBaseisamfile::unlock() { NOT_OPEN(); - return cisunlock(_isamfile, &_lasterr); + _lasterr = DB_unlock(_isamfile->fhnd); + if (_lasterr != NOERR) _lasterr = get_error(_lasterr); + return (_lasterr); } void TBaseisamfile::indexon() { - IndexOn(); } bool TBaseisamfile::empty() { - return _isamfile->i.Base[_isamfile->i.PN].PEOD == 0; + return (DB_reccount(_isamfile->fhnd) == 0); } void TBaseisamfile::indexoff() { - IndexOff(); } @@ -617,40 +947,29 @@ int TBaseisamfile::_open(unsigned int mode) { CHECKS(filehnd() == NULL, "File already open ", (const char*)filename()); - int err; - - if ((cisopen(&_isamfile, _logicnum, NOALLOC, mode, &err) == NOERR) && - (_historicfile)) - { - TFilename s(filename()); - - s.ext("hst"); - _hf.len() = filehnd()->d->LenR; - _hf.base() = 1; - _hf.open(s); - if (_hf.status() == 2) + getisfd(_isamfile,num()); + if ((filehnd()->fhnd = DB_open(filehnd()->d->SysName,mode==_excllock)) >= 0) + { + TRecnotype n=DB_reccount(filehnd()->fhnd); + TDir d; + d.get(num()); + if ((filehnd()->d->EOD != n && n > 0) || (n >= d.eox())) { - _hf.create(s); - _hf.open(s); + filehnd()->d->EOD = d.eod() = n; + filehnd()->d->EOX = d.eox() = (TRecnotype) (n*1.2); + d.put(num()); } - if (_hf.error()) return err = _hf.status(); - _lasthf = -1L; - _hfhd = _hf; - _hfhd.len() = sizeof(TRecnotype); - _hfhd.base() = 0; + filehnd()->ln = num(); + openf[num() - 1] = filehnd(); + _recno = -1L; + _lasterr = NOERR; + } else + { + _lasterr = get_error(filehnd()->fhnd); + relisfd(_isamfile); + fatal_box("Il file %d non puo' essere aperto, errore %d",num(),_lasterr); } - - if (err == NOERR) - { - isdef * fh = filehnd(); - const TRecnotype nitems = fh->i.Base[0].PEOX; - if (fh->d->EOX != nitems) - recover(); - } - _recno = -1L; - // _current->_i = filehnd(); - setstatus(err); - return err; + return (_lasterr); } @@ -661,8 +980,34 @@ int TBaseisamfile::_close() if (filehnd() != NULL) { - cisclose(ptrfilehnd(), NULL, &err); - clearfilehnd(); + if (num() > 0) + { + TDir d; + TRecnotype n=DB_reccount(filehnd()->fhnd); + d.get(num()); + if ((filehnd()->d->EOD != n && n > 0) || (n >= d.eox())) + { + filehnd()->d->EOD=d.eod()=n; + filehnd()->d->EOX = d.eox() = (TRecnotype) (n*1.2); + d.put(num()); + } + CHECK(openf[num() - 1] != NULL, "Open file array corrupted"); + err=DB_close(filehnd()->fhnd); + if (err != NOERR) err = get_error(err); + if ((err == NOERR) && (num() > 0)) + openf[num() - 1] = NULL ; + } + else + if (filehnd() == NULL) + { + err = _isnotopen; + error_box("File n. %d close : Error n. %d ", num(), err); + } + if (err == NOERR) + { + relisfd(_isamfile); + clearfilehnd(); + } } // _current->_i = NULL; setstatus(err); @@ -676,7 +1021,7 @@ int TBaseisamfile::_close() // Attenzione linkrecinst puo' valere 0, 1, 2. // Se vale 2 significa che si sta costruendo un file temporaneo -// per cui linkrecinst va' considerato FALSE +// per cui linkrecinst va' considerato FALSE TLocalisamfile::TLocalisamfile(int logicnum, bool linkrecinst) : TBaseisamfile(logicnum, linkrecinst == TRUE) @@ -711,10 +1056,22 @@ int TLocalisamfile::close() else { if (_isamfile) - { - cisclose(&_isamfile, NULL, &err); - _isamfile = NULL; - } + { + TRecnotype n = DB_reccount(filehnd()->fhnd); + TDir d; + d.get(num()); + if ((filehnd()->d->EOD!=n && n > 0) || (n > d.eox())) + { + filehnd()->d->EOD = d.eod() = n; + filehnd()->d->EOX = d.eox() = n; + d.put(num()); + } + err = DB_close(_isamfile->fhnd); + if (err != NOERR) err = get_error(err); + relisfd(_isamfile); + _isamfile=NULL; + } + openf[num() -1] = NULL; } setstatus(err); return err; @@ -786,11 +1143,23 @@ TIsamfile::~TIsamfile() int TIsamfile::flags(bool updateeod) { - int err; - + TDir d; + int err = NOERR; + + if (filehnd()->ln <= 0) return NOERR ; NOT_OPEN(); + + const TDirtype dirtype = (TDirtype) filehnd()->ft; + + d.get(num(), _lock, dirtype); + if ((err = d.status(dirtype)) == NOERR) + { + d.flags() = filehnd()->d->Flags; + if (updateeod) d.eod() = filehnd()->d->EOD; + d.put(num(), dirtype); + } setstatus(err); - return cisupdflags(filehnd(), &err, updateeod); + return err; } /////////////////////////////////////////////////////////// @@ -816,7 +1185,7 @@ TIsamtempfile::TIsamtempfile(int logicnum, const char* radix, bool create) } } - n.ext("dta"); + n.ext("dbf"); if (!create) { @@ -862,27 +1231,43 @@ TIsamtempfile::~TIsamtempfile() int TIsamtempfile::open(const char* radix, bool create, TRecnotype eod, TRecnotype eox) { + int err = NOERR; + TFilename tmpname; + CHECKS(filehnd() == NULL, "File already open", (const char*)filename()); - int err; - if ((cisopentemp(ptrfilehnd(), _logicnum, (char*)radix, NOALLOC, create, eod, eox, &err) == NOERR) && - (_historicfile)) + if (radix[0] == '%') + tmpname << &radix[1] ; + else + tmpname.temp(radix); + getisfd (_isamfile, num()); + strcpy(filehnd()->d->SysName, (const char*)tmpname); + filehnd()->d->EOX = eox; + if (create) { - TFilename s(filename()); s.ext("hst"); - - _hf.len() = filehnd()->d->LenR; - _hf.base() = 1; - _hf.open(s); - if (_hf.status() == 2) - { - _hf.create(s); - _hf.open(s); + err=DB_build(filehnd()->d->SysName, filehnd()->r) ; + if (err == NOERR) + filehnd()->d->EOD = 0L; + else + { + err = get_error(err); + relisfd(_isamfile); + fatal_box("Create temporary file: Error n. %d ", errno); } - if (_hf.error()) return err = _hf.status(); - _lasthf = -1L; - _hfhd = _hf; - _hfhd.len() = sizeof(TRecnotype); - _hfhd.base() = 0; + } + else + filehnd()->d->EOD = eod; + filehnd()->fhnd = DB_open(filehnd()->d->SysName, 0); + if (filehnd()->fhnd < 0) err = get_error(filehnd()->fhnd); + if (err != NOERR) + { + relisfd(_isamfile); + fatal_box("Open temporary file: Error n. %d ",errno); + } + else + { + filehnd()->ln = -num(); + filehnd()->knum = 1 ; } // _current->_i = filehnd(); _recno = -1L; @@ -897,7 +1282,38 @@ int TIsamtempfile::close() if (filehnd() != NULL) { - cisclosetemp(ptrfilehnd(), NULL, _autodel, &err); + err=DB_close(filehnd()->fhnd); + if (err != NOERR) err = get_error(err); + if (_autodel && err==NOERR) + { + TFilename f(filehnd()->d->SysName); + long c = DB_getconf(); + + f.ext("dbf"); + ::remove((const char*)f); + if (c & 1) // FOXPRO format + f.ext("cdx"); + if (c & 4) // DBIV format + f.ext("mdx"); + if (c & 8 || c & 2) // CLIPPER and DBIII format + { + f.ext("cgp"); + FILE *fp=fopen((const char*)f,"r"); + char in[16]; + while (fgets(in,16,fp)!=NULL) + { + TFilename a(in); + if (c & 8) // DBIII format + a.ext("ndx"); + else + a.ext("ntx"); // CLIPPER format + ::remove((const char *)a); + } + fclose(fp); + } + ::remove((const char *)f); + } + relisfd(_isamfile); clearfilehnd(); } // _current->_i = NULL; @@ -913,18 +1329,28 @@ int TSystemisamfile::build(TRecnotype eox) { CHECKS(filehnd() == NULL, "Can't build open file", (const char*)filename()); - - int err; + int err=NOERR; TDir d; - + TTrec r; + d.get(num()); + r.get(num()); + TFilename f(d.name()); f = f.path(); if (!is_not_slash(f.right(1)[0])) f.rtrim(1); if (!fexist(f)) make_dir(f); - - cisbuild(filehnd(), num(), eox, &err); + err=DB_build(d.name(),r.rec()); + if (err == NOERR) + { + isfdptr i; + getisfd(i,num()); + i->d->EOX = eox; + relisfd(i); + } + else + err = get_error(err); setstatus(err); clearfilehnd(); @@ -946,9 +1372,19 @@ int TSystemisamfile::build(TRecnotype eox) int TSystemisamfile::extend(TRecnotype eox) { + int err = NOERR; + isfdptr i; + CHECKS(filehnd() == NULL, "Can't extend open file ", (const char*)filename()); - int err; - cisextend(filehnd(), num(), eox, &err); + getisfd(i,num()); + if (num() > 0) + { + if (eox < i->d->EOD) + err = _ispathfull; + else + i->d->EOX = eox; + } + relisfd(i); setstatus(err); clearfilehnd(); return err; @@ -958,9 +1394,7 @@ int TSystemisamfile::extend(TRecnotype eox) long TSystemisamfile::size(TRecnotype eox) { - int err; - const long size = cisextension(num(), eox, &err); - if (err != NOERR) setstatus(err); + const long size = (100 * (unsigned)512); return size; } @@ -1085,20 +1519,20 @@ int TSystemisamfile::update(TTrec& newrec, bool vis) if (toconvert && dir.eox() > 0L) { - TRecnotype ni = 0L; - TFilename tmpfname; - - tmpfname.temp(NULL); - FILE* f = fopen(tmpfname, "w"); - err = ferror(f); - - if (f == NULL) + TRecnotype ni = 0L; + isfdptr i0; + TFilename tmpfname("tmpf"); + + open(_excllock); + getisfd(i0, num()); + err=DB_build((const char*) tmpfname, newrec.rec()); + if (err != NOERR) { - clearerr(f); - setstatus(err); - return err; + err=get_error(err); + return (err); } - open(); + i0->fhnd=DB_open((const char*)tmpfname,0); + if (i0->fhnd < 0 ) err=get_error(i0->fhnd); TFilename fname(filename()); TString s(80); s.format("Aggiornamento archivio %s", (const char*) fname); @@ -1106,65 +1540,123 @@ int TSystemisamfile::update(TTrec& newrec, bool vis) int nflds = curr().items(); TArray fld(nflds); TExtrectype nrec(newrec); - TRecnotype i; + TRecnotype i = 0; for (int j = 0; j < nflds; j++) fld.add(TString(curr().fieldname(j)), j); - for (i = 1; i <= nitems && !p.iscancelled(); i++) + for (first(); good(); next()) { - if ((i % 50) == 0) p.setstatus(i + 1); - readat(i); - if (curr().valid()) - { - nrec.zero(); - ni++; - for (j = 0; j < nflds; j++) - if (nrec.exist((const TString&) fld[j])) - nrec.put((const TString&) fld[j], get((const TString&) fld[j])); - if (lcf) - makelc((TRectype &)nrec); - fwrite(nrec.string(), lenr, 1, f); - } + if ((i++ % 50) == 0) p.setstatus(i + 1); + nrec.zero(); + ni++; + for (j = 0; j < nflds; j++) + if (nrec.exist((const TString&) fld[j])) + nrec.put((const TString&) fld[j], get((const TString&) fld[j])); + if (lcf) + makelc((TRectype &)nrec); + memcpy(DB_getrecord(i0->fhnd),nrec.string(),DB_reclen(i0->fhnd)); + err=DB_add(i0->fhnd); + if (err != NOERR) err=get_error(err); + setstatus(err); } - p.setstatus(nitems); + err=DB_close(i0->fhnd); close(); - fclose(f); - fcopy(tmpfname, fname); - ::remove(tmpfname); - dir.eod() = ni; + if (err!=NOERR) err=get_error(err); + relisfd(i0); + p.setstatus(nitems); + if (err == NOERR) + { + long c = DB_getconf(); + fname.ext("dbf"); + tmpfname.ext("dbf"); + fcopy((const char*)tmpfname,(const char*)fname); + ::remove((const char*)tmpfname); + if (c & 1) // FOXPRO format + tmpfname.ext("cdx"); + if (c & 4) // DBIV format + tmpfname.ext("mdx"); + if (c & 8 || c & 2) + { + tmpfname.ext("cgp"); + char in[16]; + FILE *fp=fopen((const char *) tmpfname,"r"); + while (fgets(in,16,fp)!=NULL) + { + TFilename a(in); + a.rtrim(1); // Cut \n + if (c & 8) // DBIII format + a.ext("ndx"); + else + a.ext("ntx"); // CLIPPER format + ::remove((const char *)a); + } + fclose(fp); + } + ::remove((const char*)tmpfname); + dir.eod() = ni; + } } - // aggiornare il log file dir.set_len(lenr); dir.put(num(), _nordir, _sysdirop); newrec.put(num()); if (toconvert && dir.eox() > 0L) packindex(); - exec_convapp(lev, FALSE); + exec_convapp(lev, FALSE); + setstatus(err); return err; } int TSystemisamfile::packfile(bool vis) -{ - CHECKS(filehnd() == NULL, "Can't pack open file", (const char*)filename()); - - int err; - setstatus(creorgfile(num(), vis, &err)); - return err; +{ + int err=NOERR; + TDir d; + d.get(num()); + CHECKS(filehnd() == NULL, "Can't pack open file", (const char*)filename()); + err=DB_packfile(vis,d.name(),d.eod()); + if (err != NOERR) err = get_error(err); + if (err != NOERR) error_box("Errore in compattamento dati.\nFile %d : %d", num(),err); + setstatus(err); + return err; } int TSystemisamfile::packindex(bool vis) { + int err=NOERR; + TRecnotype peod; + TTrec r; + TDir d; + CHECKS(filehnd() == NULL, "Can't pack index of open file", (const char*)filename()); - int err; - setstatus(creorgindex(num(), vis, &err)); + + r.get(num()); + d.get(num()); + err=DB_packindex(vis,d.name(),r.rec(),&peod); + if (err != NOERR) err = get_error(err); + if (err != NOERR) error_box("Errore in compattamento indici.\nFile %d : %d", num(),err); + else + if (peod >= 0 && peod != d.eod()) + { + d.eod() = peod; + d.put(num()); + } + setstatus(err); return err; } +int TSystemisamfile::pack(bool vis) +{ + int err=NOERR; + + if ((err=packfile(vis))==NOERR) + err=packindex(vis); + setstatus(err); + return err; +} int TSystemisamfile::load(const char* from, char fs, char fd, char rs, bool vis, bool extended) @@ -1454,52 +1946,6 @@ int TSystemisamfile::dump(const char* to, int nkey, char fs, char fd, char rs, b void TBaseisamfile::recover() { - isdef * fh = filehnd(); - const TRecnotype nitems = fh->i.Base[0].PEOX; - - TFilename fn = filename(); - fn = fn.name(); - - if (getkey() != 1) - fatal_box("La chiave per il recover dell'archivio %s deve essere 1 non %d", - (const char *)fn, getkey()); - -#ifndef FOXPRO - if (yesno_box("La dimensione dell'archivio %s e' errata. Cerco di recuperarlo?", (const char *)fn)) - { - TDir d; - TString mess(80); - - mess.format("Ricostruzione archivio %s : I Fase", (const char*) fn); - TProgind p(nitems ? nitems : 1, mess, TRUE, TRUE, 70); - - const TDirtype dir = (fh->ft == 0) ? _nordir : _comdir; - d.get(num(), _lock, dir, _sysdirop); - d.eod() = fh->d->EOD = nitems; - d.eox() = fh->d->EOX = nitems; - d.put(num(), dir, _sysdirop); - for (TRecnotype r = 1; r <= nitems; r++) - { - p.addstatus(1); - CRead(&fh->f, curr().string(), r, _nolock); - curr().discard(); - CWrite(&fh->f, curr().string(), r, _nolock); - } - p.close_modal(); - - mess.format("Ricostruzione archivio %s : II Fase", (const char*) fn); - TProgind pi(items() ? items() : 1, mess, TRUE, TRUE, 70); - for (first(); good(); next()) - { - pi.addstatus(1); - curr().recall(); - rewrite(); - } - message_box("L'archivio %s deve essere compattato", (const char *) fn); - } - else -#endif - fatal_box("L'archivio %s e' incosistente e deve essere corretto prima di utilizzarlo", (const char *)fn); } @@ -1508,26 +1954,30 @@ void TBaseisamfile::recover() //////////////////////////////////////////////////////////// TRectype::TRectype(int logicnum) : _cod(NULL) -{ - TDir wdir; +{ _logicnum = logicnum; - wdir.get(_logicnum, _nolock, _nordir, _sysdirop); - if (wdir.name()[0] == '%') - wdir.get(_logicnum, _nolock, _comdir, _sysdirop); - _length = wdir.len(); + // _i = openf[_logicnum - 1]; + if (openf[_logicnum - 1] != NULL) + _length = DB_reclen(openf[logicnum - 1]->fhnd); + else + { + TDir wdir; + wdir.get(_logicnum, _nolock, _nordir, _sysdirop); + if (wdir.name()[0] == '%') + wdir.get(_logicnum, _nolock, _comdir, _sysdirop); + _length = wdir.len(); + } _rec = new char [ _length ]; - // _i = openf[_logicnum - 1]; *_tab = '\0'; setempty(TRUE); } - -TRectype::TRectype(const TBaseisamfile* i) : _cod(NULL) +TRectype::TRectype(const TBaseisamfile* i): _cod(NULL) { _logicnum = i->num(); if (i->filehnd() != NULL) - _length = i->filehnd()->d->LenR; + _length = DB_reclen(i->filehnd()->fhnd); else { TDir wdir; @@ -1537,9 +1987,9 @@ TRectype::TRectype(const TBaseisamfile* i) : _cod(NULL) wdir.get(_logicnum, _nolock, _comdir, _sysdirop); _length = wdir.len(); } - *_tab = '\0'; + *_tab = '\0'; _rec = new char [ _length ]; - // _i = i->filehnd(); + //_i = i->filehnd(); setempty(TRUE); } @@ -1727,9 +2177,18 @@ const char* TRectype::get_str(const char* fieldname) const strcpy(_isam_string, (const char*) f); } else + { if (CGetFieldBuff((char*) fieldname, rd, _rec, _isam_string) == -1) UNKNOWN_FIELD(num(), fieldname); - + if (CFieldType((char*) fieldname,rd) == _boolfld) + { + if (toupper(*_isam_string) == 'T' || toupper(*_isam_string) == 'Y' + || toupper(*_isam_string) == 'S' || toupper(*_isam_string) == 'X') + strcpy(_isam_string,"X"); + else + strcpy(_isam_string," "); + } + } return _isam_string; } @@ -1797,7 +2256,11 @@ bool TRectype::get_bool(const char* fieldname) const // NOT_LINKED(_i, "get_bool"); if (CGetFieldBuff((char*) fieldname, rec_des(), _rec, _isam_string) == -1) UNKNOWN_FIELD(num(), fieldname); - return *_isam_string == 'X'; + if (toupper(*_isam_string) == 'T' || toupper(*_isam_string) == 'Y' + || toupper(*_isam_string) == 'S' || toupper(*_isam_string) == 'X') + return TRUE; + else + return FALSE; } @@ -1909,7 +2372,7 @@ void TRectype::put(const char* fieldname, bool val) { // NOT_LINKED(_i, "put"); - char* s = val ? "X" : " "; + char* s = val ? "T" : "F"; if (CPutFieldBuff((char*) fieldname, rec_des(), s, _rec) == -1) UNKNOWN_FIELD(num(), fieldname); setempty(FALSE); @@ -1935,8 +2398,21 @@ void TRectype::put(const char* fieldname, const char* val) f = val; } else - if (CPutFieldBuff((char*) fieldname, rec_des(), (char*) val, _rec) == -1) + { + TString wval; + wval=val; + + if (CFieldType((char*) fieldname,rec_des()) == _boolfld) + { + if (toupper(*val) == 'T' || toupper(*val) == 'Y' + || toupper(*val) == 'S' || toupper(*val) == 'X') + wval="T"; + else + wval="F"; + } + if (CPutFieldBuff((char*) fieldname, rec_des(), (char*) (const char*)wval, _rec) == -1) UNKNOWN_FIELD(num(), fieldname); + } setempty(FALSE); } @@ -2118,7 +2594,7 @@ HIDDEN void __putfieldbuff(byte l, byte d, byte t, const char* s, char* recout) if (*s2) { TDate dt(s2); - sprintf(s2,"%06ld", (long) dt); + sprintf(s2,"%8s", dt.string(ANSI)); } } else if (t == _realfld) setdec(s2, d); @@ -2285,13 +2761,12 @@ TRecnotype TRecfield::ptr() const void TTransaction::begin() { - StTrans(); } void TTransaction::end(bool success) { - if (success) EndTrans(); - else AbTrans(); + if (success) ; + else ; } diff --git a/include/isam.h b/include/isam.h index d29d9a4cc..56abf4737 100755 --- a/include/isam.h +++ b/include/isam.h @@ -80,9 +80,9 @@ public: void settab(const char *tab); char* string() const { return _rec;} // Ritorna il puntatore all'inizio. NON dovrebbe essere usata! - void discard() { *_rec = char(_deleted);} // Setta il flag di cancellazione - void recall() { *_rec = char(_valid);} // Ripristina il flag di cancellazione - bool isdeleted() const { return *_rec == _deleted;} // Chiede se e' cancellato + void discard() { *_rec = '*';} // Setta il flag di cancellazione + void recall() { *_rec = ' ';} // Ripristina il flag di cancellazione + bool isdeleted() const { return *_rec == '*';} // Chiede se e' cancellato int len() const { return _length;} // Ritorna la lunghezza TFieldtypes type(const char* fieldname) const; // Ritorna il tipo del campo int length(const char* fieldname) const; // Ritorna lunghezza campo @@ -135,7 +135,7 @@ public: // const isdef* filehnd() const { return _i; } // Ritorna il file isam associato int num() const { return _logicnum;} // Ritorna il numero logico bool empty() const {return _isempty;} // Ritorna se e' vuoto - bool valid() const {return _rec[0] == 0;} // Ritorna se il record non e'cancellato + bool valid() const {return _rec[0] == ' ';} // Ritorna se il record non e'cancellato const char* key(int numkey = 1) const; // Ritorna l'espressione della chiave numero numkey bool ok() const { return _rec != NULL; } @@ -238,7 +238,7 @@ public: bool empty(); // Vero se il file e' vuoto int num() const { return _logicnum;} // Ritorna il numero logico del record corrente const char* description() const; - TRecnotype eod() const { return filehnd()->d->EOD;} + TRecnotype eod() const ; isdef* filehnd() const { return (isdef*) _isamfile;} // Ritorna l'handle del file isam nella tabella @@ -341,8 +341,9 @@ public: int extend(TRecnotype eox); // Estende un file preesistente long size(TRecnotype eox); // Calcola lo spazio che il file occuperebbe se venisse esteso a eox int update(TTrec& newrec, bool vis = TRUE); - - int packfile(bool vis = TRUE); // Rimuove fisicamente i record cancellati + + int pack(bool vis = TRUE); // Esegue packfile e packindex + int packfile(bool vis = TRUE); // Rimuove fisicamente i record cancellati int packindex(bool vis = TRUE); // La stessa cosa sugli indici // @DES Importa un file ascii. from e' il nome del file da importare @@ -495,6 +496,7 @@ public: // @DPUB extern TTransaction transaction; extern TRectype** openrec; +extern void get_idx_names(int logicnum, TToken_string& i_names); // @END #undef extern diff --git a/include/prassi.ver b/include/prassi.ver index 0a5eb7dc8..c2572eb74 100755 --- a/include/prassi.ver +++ b/include/prassi.ver @@ -1,2 +1,2 @@ #define VERSION "1.4" -#define INTERNAL_VERSION "0" +#define INTERNAL_VERSION "1" diff --git a/include/prefix.cpp b/include/prefix.cpp index bc3059dca..31dc4c2b9 100755 --- a/include/prefix.cpp +++ b/include/prefix.cpp @@ -14,6 +14,11 @@ #include #include +#include +#include + +extern int get_error(int); + /////////////////////////////////////////////////////////// // extern variables are NO-NO! @@ -96,9 +101,10 @@ HIDDEN int closeall(bool changestudy, TBit_array& excl, TBit_array& toclose) d.get(i + 1, _nolock, _nordir, _sysdirop); if (toclose[i + 1] || changestudy || d.name()[0] != '%') { - excl.set(i, isfd->f.LockMode == _excllock); - CClose(&isfd->f); - CBCloseFile(&isfd->i, &err); + excl.set(i, DB_file_locked(isfd->fhnd) == _excllock); + 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); } } @@ -140,9 +146,10 @@ HIDDEN void openall(bool changestudy, TBit_array& excl, int oldmax, TBit_array& *isfd->r = *r.rec(); if (excllock(CInsPref((char*) glockname, NORDIR), FALSE) == -1 && errno == EACCES) fatal_box("Can't reopen file n. %d : file in use", i + 1); - COpen(&isfd->f, isfd->d->SysName, isfd->d->LenR, 0, excl[i]); - if ((err = isfd->f.IOR) == NOERR) - CBOpenFile (&isfd->i, CGetIdxName(isfd->d->SysName), excl[i], &err); + err=DB_open(isfd->d->SysName,excl[i]==_excllock); + if (err<0) err=get_error(err); + 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); } diff --git a/include/rectypes.h b/include/rectypes.h index d713d6cf5..577898ed1 100755 --- a/include/rectypes.h +++ b/include/rectypes.h @@ -13,9 +13,8 @@ enum TFilelock { _excllock = 0x100, _autolock = 0x200, _manulock = 0x400}; enum TReclock { _unlock = 0x1000, _nolock = 0x2000, _lock = 0x4000, _testandlock = (int)0x8000} ; - enum TRecstates { _valid, _deleted}; -enum TDirtype { _nordir, _comdir } ; -enum TDirop { _nordirop, _sysdirop }; + enum TDirtype { _nordir, _comdir } ; + enum TDirop { _nordirop, _sysdirop }; enum TFieldtypes { _nullfld, _alfafld, _intfld, _longfld, _realfld, _datefld, _wordfld, _charfld, _boolfld , _intzerofld, _longzerofld, _memofld} ; diff --git a/include/relation.cpp b/include/relation.cpp index f9500c572..082c5f701 100755 --- a/include/relation.cpp +++ b/include/relation.cpp @@ -1,4 +1,4 @@ -// $Id: relation.cpp,v 1.49 1995-06-28 16:35:26 guy Exp $ +// $Id: relation.cpp,v 1.50 1995-07-03 07:49:22 angelo Exp $ // relation.cpp // fv 12/8/93 // relation class for isam files @@ -17,14 +17,19 @@ #include #include +#include + // *** check if not already defined #define NOTFOUND (-1) // *** maximum number of elements in a cursor working page #define CMAXELPAGE 8000 + #define print_name(out, f) out << (f.num() == LF_TABCOM ? "%" : "") << f.name() +extern int get_error(int); + HIDDEN const char* field_type_str(TFieldtypes f) { const char* c = ""; @@ -735,14 +740,15 @@ int TRelation::remove(TDate& atdate) /////////////////////////////////////////////////////////// -HIDDEN bool __evalcondition(const TRectype& r,TExpression* cond) +HIDDEN bool __evalcondition(const TRelation* r,TExpression* cond) { for (int i = 0; i < cond->numvar(); i++) { const char* s = cond->varname(i); - - cond->setvar(i, r.get(s)); + TFieldref f(s,0); + + cond->setvar(i, f.read(r)); } return (bool) *cond; } @@ -768,17 +774,14 @@ FILE* TCursor::open_index(bool create) TRecnotype TCursor::buildcursor(TRecnotype rp) { - TRecnotype ap = 0, junkl; - char s[82]; - int junk, l, pagecnt = 0; - Page p; - int pos; - const int kl = file().filehnd()->i.Base[file().filehnd()->i.PN].KeyLen; + + TRecnotype oldrecno=0,pos,ap = 0; + int junk, l, pagecnt = 0; const bool filtered = has_filter(); FILE* _f = open_index(TRUE); - if (file().filehnd()->i.Base[file().filehnd()->i.PN].PEOD == 0) + if (DB_reccount(file().filehnd()->fhnd) == 0) { fclose(_f); return 0; @@ -787,62 +790,56 @@ TRecnotype TCursor::buildcursor(TRecnotype rp) fseek(_f, 0L, SEEK_SET); l = strlen(to()); - BTrRead(&file().filehnd()->i, (char*)(const char*) from(), s, &junkl, &junk); + junk=DB_index_seek(file().filehnd()->fhnd, (char*)(const char*) from()); + if (junk < 0) junk=get_error(junk); if (junk == _iseof) return 0; - TRecnotype* page = new TRecnotype [CMAXELPAGE]; - - if (GetAPage(&file().filehnd()->i, &p, file().filehnd()->i.CurPag, &junk) != NOERR) - fatal_box("Can't read index n. %d - file n. %d", file().filehnd()->i.PN + 1, file().filehnd()->ln); - - pos = file().filehnd()->i.Pos - 1; - _pos = -1; + TRecnotype* page = new TRecnotype [CMAXELPAGE]; + pos = DB_index_recno(file().filehnd()->fhnd); + _pos=-1; + while (TRUE) - { - if (pos >= p.PA.PageHeader.NKey) - { - if (p.PA.PageHeader.Next == -1L) break; - file().filehnd()->i.CurPag = p.PA.PageHeader.Next; - if (GetAPage(&file().filehnd()->i, &p, file().filehnd()->i.CurPag, &junk) != NOERR) - fatal_box("Can't read index n. %d - file n. %d", file().filehnd()->i.PN + 1, file().filehnd()->ln); - pos = 0; - } - const char* s0 = p.PA.AreaForKey + pos++ * (kl + 4); + { + 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 (l && (strncmp(to(), s0, l) < 0)) break; - + if (recno == oldrecno) break; // means that no more keys are available + oldrecno=recno; if (pagecnt == CMAXELPAGE) - { - if (filtered) pagecnt = filtercursor(pagecnt, page); - fwrite(page, sizeof(junkl), pagecnt, _f); - if (pos == -1) - for (int i = 0; i < pagecnt; i++) - if (page[i] == rp) - { - _pos = ap + i; - break; - } - ap += pagecnt; - pagecnt = 0; - } - page[pagecnt++] = *((long *)(s0 + kl)); - } - if (pagecnt) - { - if (filtered) pagecnt = filtercursor(pagecnt, page); - fwrite(page, sizeof(junkl), pagecnt, _f); - if (pos == -1) - for (int i = 0; i < pagecnt; i++) + { + if (filtered) pagecnt = filtercursor(pagecnt,page); + fwrite(page,sizeof(TRecnotype),pagecnt,_f); + for (int i= 0; i< pagecnt; i++) if (page[i] == rp) { _pos = ap + i; - break; + break; } + ap += pagecnt; + 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); + } // while + if (pagecnt) + { + if (filtered) pagecnt = filtercursor(pagecnt, page); + fwrite(page, sizeof(TRecnotype), pagecnt, _f); + for (int i = 0; i < pagecnt; i++) + if (page[i] == rp) + { + _pos = ap + i; + break; + } ap += pagecnt; } - if (_pos == -1 ) pos = 0; + if (_pos == -1) pos=0; delete page; - - fclose(_f); + fclose (_f); return ap; } @@ -850,18 +847,19 @@ TRecnotype TCursor::buildcursor(TRecnotype rp) int TCursor::filtercursor(int pagecnt, TRecnotype* page) { - int np = 0; - TRectype& rec = file().curr(); - for (int i = 0; i < pagecnt; i++) + int np=0, handle=file().filehnd()->fhnd; + TRectype& rec=file().curr(); + for (int i=0; i< pagecnt; i++) { - CRead(&file().filehnd()->f, rec.string(), page[i], _nolock); + file().readat(rec,page[i]); + if (update_relation()) _if->update(); if ((_filterfunction ? _filterfunction(_if) : TRUE ) && - (_fexpr ? __evalcondition(rec, _fexpr) : TRUE)) + (_fexpr ? __evalcondition(_if, _fexpr) : TRUE)) { if (np < i) page[np] = page[i]; np++; } - } + } return np; } @@ -881,34 +879,30 @@ bool TCursor::ok() const } if (key < kf || (kt.not_empty() && kt < key.left(kt.len()))) - return FALSE; + return FALSE; + if (_filter_update || _filterfunction_update) _if->update(); if ((_filterfunction ? _filterfunction(_if) : TRUE ) && - (_fexpr ? __evalcondition(rec, _fexpr) : TRUE)) + (_fexpr ? __evalcondition(_if, _fexpr) : TRUE)) return TRUE; return FALSE; -} +} bool TCursor::changed() { isdef* fh = file().filehnd(); - if (_frozen && _lastrec != 0L) return _filename != fh->f.name; + if (_frozen && _lastrec > 0L) return _filename != fh->d->SysName; -#if XVT_OS==XVT_OS_SCOUNIX - const TRecnotype eod = file().eod(); -#else - int junk = 0; - const TRecnotype eod = cisgeteod(fh, &junk); -#endif + const TRecnotype eod = DB_reccount(fh->fhnd); if (_lastrec != eod || - (_lastkrec != fh->i.Base[_nkey -1].PEOD) || - (_filename != fh->f.name)) + (_lastkrec != DB_changed(fh->fhnd)) || + (_filename != fh->d->SysName)) { // _lastrec = eod; - // _lastkrec = fh->i.Base[_nkey -1].PEOD; - // _filename = fh->f.name; + // _filename = fh->d->SysName; + // _lastkrec = DB_changed(fh->fhnd); return TRUE; } else return FALSE; @@ -924,19 +918,13 @@ TRecnotype TCursor::update() const TRecnotype totrec = buildcursor(file().recno()); main_app().end_wait(); - - isdef* fh = file().filehnd(); -#if XVT_OS==XVT_OS_SCOUNIX - const TRecnotype eod = file().eod(); -#else - int junk = 0; - const TRecnotype eod = cisgeteod(fh, &junk); -#endif + isdef* fh = file().filehnd(); + const TRecnotype eod = DB_reccount(fh->fhnd); _lastrec = eod; - _lastkrec = fh->i.Base[_nkey -1].PEOD; - _filename = fh->f.name; + _filename = fh->d->SysName; + _lastkrec = DB_changed(fh->fhnd); return totrec; } @@ -1066,7 +1054,7 @@ TRecnotype TCursor::read(TIsamop op, TReclock lockop, TDate& atdate) TCursor::TCursor(TRelation* r, const char* fil, int nkey, const TRectype *from, const TRectype* to) -: _if(r), _nkey(nkey), _frozen(FALSE), _filterfunction(NULL), _fexpr(NULL) +: _if(r), _nkey(nkey), _frozen(FALSE), _filterfunction(NULL), _fexpr(NULL), _filter_update(FALSE), _filterfunction_update(FALSE) { file().setkey(_nkey); _pos = 0; @@ -1111,16 +1099,27 @@ TRecnotype TCursor::readrec() fclose(_f); curr().setdirty(); - CRead(&file().filehnd()->f, curr().string(), nrec, _nolock); + file().readat(nrec); repos(); return nrec; } int TCursor::lock(TReclock l) { - SecDef* sd = &file().filehnd()->f; - CLockRec(sd, _pos, l); - return sd->IOR; + int rt=NOERR; + switch(l) + { + case _lock: + rt=DB_lock_rec(file().filehnd()->fhnd,_pos); + break; + case _unlock: + rt=DB_unlock(file().filehnd()->fhnd); + break; + default: + break; + } + if (rt < NOERR) rt=get_error(rt); + return(rt); } TRecnotype TCursor::operator =(const TRecnotype pos) diff --git a/include/relation.h b/include/relation.h index c562397ba..d3ac2dace 100755 --- a/include/relation.h +++ b/include/relation.h @@ -1,4 +1,4 @@ -/* $Id: relation.h,v 1.21 1995-06-28 16:35:30 guy Exp $ */ +/* $Id: relation.h,v 1.22 1995-07-03 07:49:25 angelo Exp $ */ // join.h // fv 12/8/93 // join class for isam files @@ -106,7 +106,7 @@ public: void save_status () ; void restore_status () ; - + // positioning operators. return status TRecnotype operator +=(const TRecnotype npos) { return skip(npos); } TRecnotype operator -=(const TRecnotype npos) { return skip(-npos); } @@ -164,6 +164,7 @@ public: // Classe TCursor : public TObject + class TExpression; typedef bool (*FILTERFUNCTION)(const TRelation* r); @@ -172,31 +173,33 @@ class TCursor : public TObject { TRelation* _if; int _nkey; - TRecnotype _pos; // Posizione corrente + TRecnotype _pos; // Posizione corrente TRecnotype _totrec; TRecnotype _lastrec; - TRecnotype _lastkrec; + TRecnotype _lastkrec; TFilename _filename; - TString _filter; // Filtro - TString _keyfrom; // chiave iniziale - TString _keyto; // chiave finale - TExpression* _fexpr; // Espressione relativo filtro + TString _filter; // Filtro + TString _keyfrom; // chiave iniziale + TString _keyto; // chiave finale + TExpression* _fexpr; // Espressione relativo filtro bool _frozen; + bool _filter_update; // Flag che permette l'update della relazione per l'espressione-filtro + bool _filterfunction_update;// Flag che permette l'update della relazione per la funzione-filtro FILTERFUNCTION _filterfunction; TFilename _indexname; - virtual TRecnotype buildcursor(TRecnotype rp); - int filtercursor(int pagecnt, TRecnotype* page); - bool changed(); - - FILE* open_index(bool create = FALSE); TRecnotype update(); protected: + FILE* open_index(bool create = FALSE); + virtual bool changed(); + virtual TRecnotype buildcursor(TRecnotype rp); + virtual int filtercursor(int pagecnt, TRecnotype* page); TRecnotype readrec(); void filter(const char* filter, const TRectype* from = NULL, const TRectype* to = NULL); + bool update_relation() {return (_filter_update || _filterfunction_update);} public: // @FPUB @@ -205,7 +208,7 @@ public: TRecnotype operator -=(const TRecnotype npos) { return operator +=(-npos); } TRecnotype operator ++() { return operator +=(1); } TRecnotype operator --() { return operator -=(1); } - TRecnotype pos() const { return _pos; } + TRecnotype& pos() { return _pos; } TRecnotype items(); TRecnotype size() const { return file().eod(); } @@ -223,7 +226,7 @@ public: const char* filter() const { return _filter; } void freeze(bool on = TRUE) { _frozen = on; } bool frozen() const { return _frozen; } - void setfilter(const char* filter_expr) { filter(filter_expr); } + void setfilter(const char* filter_expr, bool update=FALSE) { filter(filter_expr); _filter_update = update; } void setregion(const TRectype& from, const TRectype& to) { filter(NULL,&from, &to); } @@ -232,6 +235,9 @@ public: TLocalisamfile& file(const char* name) const { return _if->lfile(name); } int repos() { return _if->position_rels(); } + TExpression* expression() const { return _fexpr; } + FILTERFUNCTION filterfunction() const { return _filterfunction; } + void setkey() { file().setkey(_nkey); } void setkey(int nkey); int key() const { return _nkey; } @@ -239,7 +245,7 @@ public: bool next_match(int lognum, const char* fl = NULL, int nk = 0); bool is_first_match(int ln); - void set_filterfunction(FILTERFUNCTION ff) { _filterfunction = ff; _lastrec = 0L;} + void set_filterfunction(FILTERFUNCTION ff, bool update=FALSE) { _filterfunction = ff; _lastrec = 0L; _filterfunction_update = update;} bool has_filter() const { return _filter.not_empty() || _filterfunction; } void save_status () { _if->save_status(); } @@ -277,7 +283,7 @@ public: void set_name(const char* n) { _name = n; } void set_from(int f) { if (f > 0) f--; else f = 0; _from = f; } void set_to(int t) { _to = t; } - + int from() const { return _from; } int to() const { return _to; } int len(TRectype &rec) const; diff --git a/include/sheet.cpp b/include/sheet.cpp index 2e9b2a20f..88d9eb469 100755 --- a/include/sheet.cpp +++ b/include/sheet.cpp @@ -209,10 +209,9 @@ void TSheet::handler(WINDOW win, EVENT* ep) select(nuo); if (ep->type == E_MOUSE_DBL) dispatch_e_char(win, K_ENTER); - else if (_checkable && _check_enabled && !_disabled[nuo] && vec == nuo) + else if (vec == nuo) { - _checked.not(nuo); - force_update(); + dispatch_e_char(win, K_SPACE); } } else diff --git a/include/stdtypes.cpp b/include/stdtypes.cpp index c91040b7b..88bacd0af 100755 --- a/include/stdtypes.cpp +++ b/include/stdtypes.cpp @@ -15,10 +15,12 @@ #include #include #include +#include #define REFKEY "CAMPOKEY" #define VERKEY "ìpÙˆ¬cê<" +extern isfdptr *openf; HIDDEN long _stdlevel = 0; long get_std_level() @@ -66,6 +68,7 @@ void init_global_vars() if (SerNo && !muflag) fatal_box("Abnormal termination: check protection or serial number\n"); #endif + DB_init(); } void free_global_vars() @@ -79,6 +82,7 @@ void free_global_vars() delete openrec; prefix_destroy(); } + DB_exit(); } diff --git a/include/stdtypes.h b/include/stdtypes.h index b4611d090..d07fad043 100755 --- a/include/stdtypes.h +++ b/include/stdtypes.h @@ -56,8 +56,10 @@ long get_std_level(); void init_global_vars(); void free_global_vars(); +#ifdef __cplusplus extern void* operator new(unsigned); extern void operator delete(void*); +#endif // @END