From e029749e8bfab098dbefc2f695ce200bb055eeef Mon Sep 17 00:00:00 2001 From: guy Date: Mon, 4 Dec 1995 11:06:12 +0000 Subject: [PATCH] assoc.h Aggiunti due const key() r obj() codeb.c Corretta fatal_box isam.cpp Aggiunto NOT_OPEN al metodo TBaseisamfile::items() git-svn-id: svn://10.65.10.50/trunk@2233 c028cbd2-c16b-5b4b-a496-9718f37d4682 --- include/assoc.h | 4 +- include/codeb.c | 2128 +++++++++++++++++++++++----------------------- include/isam.cpp | 3 +- 3 files changed, 1068 insertions(+), 1067 deletions(-) diff --git a/include/assoc.h b/include/assoc.h index 7acc37891..e3ca37874 100755 --- a/include/assoc.h +++ b/include/assoc.h @@ -26,10 +26,10 @@ class THash_object : public TObject public: // @cmember Ritorna la chiave di ordinamento - TString& key() + const TString& key() const { return _key; } // @cmember Ritorna l'oggetto - TObject& obj() + TObject& obj() const { return *_obj; } // @cmember Costruttore (inizializza la chiave) diff --git a/include/codeb.c b/include/codeb.c index 8ced240b2..c234639f7 100755 --- a/include/codeb.c +++ b/include/codeb.c @@ -1,1064 +1,1064 @@ -/* - 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(expr4key_len(t->expr)); -} - -/*------------------------------------------------------------------------- - 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;iexpr); - k = t4key(tt); - while (len > 0 && k[len-1] == ' ') len--; - rc = strncmp(key, k, len); - if (rc == 0) - return 0; - else - if (rc < 0) - return r4after; - else - return r4eof; -} - -/*------------------------------------------------------------------------- - torna 1 se eof, 0 altrimenti - --------------------------------------------------------------------------*/ -int DB_eof(int handle) -{ - if(dbdata[handle]==0) return(-1); - return(d4eof(dbdata[handle])); -} - -/*------------------------------------------------------------------------- - torna 1 se tof, 0 altrimenti - --------------------------------------------------------------------------*/ -int DB_bof(int handle) -{ - if(dbdata[handle]==0) return(-1); - return(d4bof(dbdata[handle])); -} - -/*------------------------------------------------------------------------- - legge un record per numero record - --------------------------------------------------------------------------*/ -int DB_go(int handle,long int recno) -{ - if(dbdata[handle]==0) return(-1); - return(x4go(&xdb[handle],recno)); -} - -/*------------------------------------------------------------------------- - cancella il record attuale. Non cancella le chiavi. - --------------------------------------------------------------------------*/ -int DB_delete(int handle) -{ - - if(dbdata[handle]==0) return(-1); - d4delete(dbdata[handle]); - return(0); -} - -/*------------------------------------------------------------------------- - ripristina il record attuale - --------------------------------------------------------------------------*/ -int DB_recall(int handle) -{ - - if(dbdata[handle]==0) return(-1); - d4recall(dbdata[handle]); - return(0); -} - - -/*------------------------------------------------------------------------- - cancella dall'indice corrente la chiave specificata - --------------------------------------------------------------------------*/ -int DB_delkey(int handle, char* key, long recno) -{ - INDEX4* i; - TAG4* t; - int rt=0; - int is_locked = 0; /* Diverso da 0 se il file e' bloccato in modo esclusivo */ - /* (dati o indice) da me stesso*/ - char fn[64]; - - if(dbdata[handle]==0) return(-1); - t=d4tag_default(dbdata[handle]); - - if (u4switch() & 2 || u4switch() & 8) /* Clipper & DBIII */ - u4name_piece(fn,64,dbdata[handle]->file.name,0,0); - else - strcpy(fn,dbdata[handle]->file.name); - if ((i=d4index(dbdata[handle],fn)) == NULL) - return(e4index); - is_locked = DB_file_locked(handle); - if (is_locked == 0) /* Se non e' stato bloccato in modo esclusivo */ - { - while ((rt=i4lock(i)) == r4locked) -#ifdef DBG - yesnofatal_box("Sono in attesa nella DB_delkeys"); -#else - u4delay_sec(); -#endif - } - if (rt == 0) - rt=t4remove_calc(t,recno); - if (is_locked == 0) /* Siccome ho fatto il lock dell'indice, devo anche sbloccarlo */ - i4unlock(i); - return(rt); -} - -/*------------------------------------------------------------------------- - cancella dall'indice corrente la chiave specificata - --------------------------------------------------------------------------*/ -int DB_flush(int handle) -{ - int rt; - - while ((rt = d4flush(dbdata[handle])) == r4locked) -#ifdef DBG - yesnofatal_box("Sono in attesa nella DB_flush"); -#else - u4delay_sec(); -#endif - return rt; -} - -/*------------------------------------------------------------------------- - riscrive il record attuale - --------------------------------------------------------------------------*/ -int DB_rewrite(int handle) -{ - int rt; - if(dbdata[handle]==0) return(-1); - while ((rt=d4write(dbdata[handle],d4recno(dbdata[handle]))) == r4locked) -#ifdef DBG - yesnofatal_box("Sono in attesa nella DB_rewrite"); -#else - u4delay_sec(); -#endif - if (rt == 0) - { - while ((rt = d4flush(dbdata[handle])) == r4locked) -#ifdef DBG - yesnofatal_box("Sono in attesa nella DB_rewrite (d4flush)"); -#else - u4delay_sec(); -#endif - } - if (rt == e4unique) - { - DB_get_error(); - fatal_box("Errore in DB_rewrite(): chiave duplicata nell' indice %d, file %s", - dbdata[handle]->rec_num + 1, dbdata[handle]->file.name); - } - rt=DB_unlock(handle); - return (rt); -} - - -/*------------------------------------------------------------------------- - appende il record attuale - --------------------------------------------------------------------------*/ -int DB_add(int handle) -{ - int rt; - int is_locked = 0; - DATA4 * data = dbdata[handle]; - - if (data==0) return(-1); - is_locked = DB_file_locked(handle); - if (is_locked == 0) /* Se non e' stato gia' bloccato in modo esclusivo */ - { - while (file4lock(&data->file, L4LOCK_POS_OLD, 1L) == r4locked) -#ifdef DBG - yesnofatal_box("Sono in attesa nella DB_add"); -#else - u4delay_sec(); -#endif - } - while ((rt = d4append_start(data,0)) == r4locked) -#ifdef DBG - yesnofatal_box("Sono in attesa nella DB_add (d4append_start)"); -#else - u4delay_sec(); -#endif - if (rt == 0) - { - d4recall(data); - while ((rt = d4append(data)) == r4locked) -#ifdef DBG - yesnofatal_box("Sono in attesa nella DB_add (d4append)"); -#else - u4delay_sec(); -#endif - if (rt == e4unique) - { - DB_get_error(); - if (data->rec_num > 0) - fatal_box("Errore in DB_add(): chiave duplicata nell' indice %d, file %s", - data->rec_num + 1, data->file.name); - else - rt = _isreinsert; - } - else - if (rt == 0) - { - while ((rt = d4flush(data)) == r4locked) -#ifdef DBG - yesnofatal_box("Sono in attesa nella DB_add (d4flush)"); -#else - u4delay_sec(); -#endif - } - } - DB_unlock(handle); - if (is_locked == 0) - { - file4unlock(&data->file, L4LOCK_POS_OLD, 1L); - } - return(rt); -} - -/*------------------------------------------------------------------------- - 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. DELETED()"); /* 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: - 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)) && (strlen(r->Fd[nf].Name) > 0)) - 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 == '\0') - ff = (char *)filename; - else - ff++; - do_key(ff,r,tags); - if (u4switch() &2 || u4switch() & 8) /* Clipper and DBIII */ - { - INDEX4 * w = i4create(dbdata[handle],(char*)filename,tags); -#ifndef FOXPRO - progind_set_status((long)r->NKeys); -#endif - if (w != NULL && 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 */ - { - INDEX4 * w = i4create(dbdata[handle],NULL,tags); - if (w == NULL) rt = code_base.error_code; -#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 _memofld: - field_info[i].type=r4memo; - field_info[i].len = 10; - field_info[i].dec = 0; - 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 == '\0') - 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(non zero) se il file dati od indice sono stati bloccati - in modo esclusivo dalla presente applicazione, non da altri programmi!!! - --------------------------------------------------------------------------*/ - - -int DB_file_locked(int handle) -{ - if(dbdata[handle]==0) return(-1); - return(d4lock_test_file(dbdata[handle]) + d4lock_test_index(dbdata[handle])); -} - -/*------------------------------------------------------------------------- - Ritorna vero se il record nrec e' bloccato dalla presente applicazione, - non da altri programmi!!! - --------------------------------------------------------------------------*/ - -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[64]; - - if(dbdata[handle]==0) return(-1); - if (u4switch() & 2 || u4switch() & 8) /* Clipper & DBIII */ - u4name_piece(fn,64,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)); -} - -char* DB_memoptr( const int handle, const char * fieldname ) -{ - FIELD4 * f; - f = d4field( dbdata[ handle ], ( char *)fieldname ); - return f4memo_ptr( f ); -} - -int DB_memowrite( const int handle, const char * fieldname, const char * data ) -{ - int ret; - - FIELD4 * f; - f = d4field( dbdata[ handle ], fieldname ); - ret = f4memo_assign( f, ( char * )data ); - d4flush_data( dbdata[ handle ] ); - return ret; -} - +/* + 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(expr4key_len(t->expr)); +} + +/*------------------------------------------------------------------------- + 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;iexpr); + k = t4key(tt); + while (len > 0 && k[len-1] == ' ') len--; + rc = strncmp(key, k, len); + if (rc == 0) + return 0; + else + if (rc < 0) + return r4after; + else + return r4eof; +} + +/*------------------------------------------------------------------------- + torna 1 se eof, 0 altrimenti + --------------------------------------------------------------------------*/ +int DB_eof(int handle) +{ + if(dbdata[handle]==0) return(-1); + return(d4eof(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + torna 1 se tof, 0 altrimenti + --------------------------------------------------------------------------*/ +int DB_bof(int handle) +{ + if(dbdata[handle]==0) return(-1); + return(d4bof(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + legge un record per numero record + --------------------------------------------------------------------------*/ +int DB_go(int handle,long int recno) +{ + if(dbdata[handle]==0) return(-1); + return(x4go(&xdb[handle],recno)); +} + +/*------------------------------------------------------------------------- + cancella il record attuale. Non cancella le chiavi. + --------------------------------------------------------------------------*/ +int DB_delete(int handle) +{ + + if(dbdata[handle]==0) return(-1); + d4delete(dbdata[handle]); + return(0); +} + +/*------------------------------------------------------------------------- + ripristina il record attuale + --------------------------------------------------------------------------*/ +int DB_recall(int handle) +{ + + if(dbdata[handle]==0) return(-1); + d4recall(dbdata[handle]); + return(0); +} + + +/*------------------------------------------------------------------------- + cancella dall'indice corrente la chiave specificata + --------------------------------------------------------------------------*/ +int DB_delkey(int handle, char* key, long recno) +{ + INDEX4* i; + TAG4* t; + int rt=0; + int is_locked = 0; /* Diverso da 0 se il file e' bloccato in modo esclusivo */ + /* (dati o indice) da me stesso*/ + char fn[64]; + + if(dbdata[handle]==0) return(-1); + t=d4tag_default(dbdata[handle]); + + if (u4switch() & 2 || u4switch() & 8) /* Clipper & DBIII */ + u4name_piece(fn,64,dbdata[handle]->file.name,0,0); + else + strcpy(fn,dbdata[handle]->file.name); + if ((i=d4index(dbdata[handle],fn)) == NULL) + return(e4index); + is_locked = DB_file_locked(handle); + if (is_locked == 0) /* Se non e' stato bloccato in modo esclusivo */ + { + while ((rt=i4lock(i)) == r4locked) +#ifdef DBG + yesnofatal_box("Sono in attesa nella DB_delkeys"); +#else + u4delay_sec(); +#endif + } + if (rt == 0) + rt=t4remove_calc(t,recno); + if (is_locked == 0) /* Siccome ho fatto il lock dell'indice, devo anche sbloccarlo */ + i4unlock(i); + return(rt); +} + +/*------------------------------------------------------------------------- + cancella dall'indice corrente la chiave specificata + --------------------------------------------------------------------------*/ +int DB_flush(int handle) +{ + int rt; + + while ((rt = d4flush(dbdata[handle])) == r4locked) +#ifdef DBG + yesnofatal_box("Sono in attesa nella DB_flush"); +#else + u4delay_sec(); +#endif + return rt; +} + +/*------------------------------------------------------------------------- + riscrive il record attuale + --------------------------------------------------------------------------*/ +int DB_rewrite(int handle) +{ + int rt; + if(dbdata[handle]==0) return(-1); + while ((rt=d4write(dbdata[handle],d4recno(dbdata[handle]))) == r4locked) +#ifdef DBG + yesnofatal_box("Sono in attesa nella DB_rewrite"); +#else + u4delay_sec(); +#endif + if (rt == 0) + { + while ((rt = d4flush(dbdata[handle])) == r4locked) +#ifdef DBG + yesnofatal_box("Sono in attesa nella DB_rewrite (d4flush)"); +#else + u4delay_sec(); +#endif + } + if (rt == e4unique) + { + DB_get_error(); + fatal_box("Errore in DB_rewrite(): chiav duplicata nell' indice %ld, file %s", + dbdata[handle]->rec_num + 1, dbdata[handle]->file.name); + } + rt=DB_unlock(handle); + return (rt); +} + + +/*------------------------------------------------------------------------- + appende il record attuale + --------------------------------------------------------------------------*/ +int DB_add(int handle) +{ + int rt; + int is_locked = 0; + DATA4 * data = dbdata[handle]; + + if (data==0) return(-1); + is_locked = DB_file_locked(handle); + if (is_locked == 0) /* Se non e' stato gia' bloccato in modo esclusivo */ + { + while (file4lock(&data->file, L4LOCK_POS_OLD, 1L) == r4locked) +#ifdef DBG + yesnofatal_box("Sono in attesa nella DB_add"); +#else + u4delay_sec(); +#endif + } + while ((rt = d4append_start(data,0)) == r4locked) +#ifdef DBG + yesnofatal_box("Sono in attesa nella DB_add (d4append_start)"); +#else + u4delay_sec(); +#endif + if (rt == 0) + { + d4recall(data); + while ((rt = d4append(data)) == r4locked) +#ifdef DBG + yesnofatal_box("Sono in attesa nella DB_add (d4append)"); +#else + u4delay_sec(); +#endif + if (rt == e4unique) + { + DB_get_error(); + if (data->rec_num > 0) + fatal_box("Errore in DB_add(): chiave duplicata nell' indice %ld, file %s", + data->rec_num + 1, data->file.name); + else + rt = _isreinsert; + } + else + if (rt == 0) + { + while ((rt = d4flush(data)) == r4locked) +#ifdef DBG + yesnofatal_box("Sono in attesa nella DB_add (d4flush)"); +#else + u4delay_sec(); +#endif + } + } + DB_unlock(handle); + if (is_locked == 0) + { + file4unlock(&data->file, L4LOCK_POS_OLD, 1L); + } + return(rt); +} + +/*------------------------------------------------------------------------- + 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. DELETED()"); /* 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: + 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)) && (strlen(r->Fd[nf].Name) > 0)) + 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 == '\0') + ff = (char *)filename; + else + ff++; + do_key(ff,r,tags); + if (u4switch() &2 || u4switch() & 8) /* Clipper and DBIII */ + { + INDEX4 * w = i4create(dbdata[handle],(char*)filename,tags); +#ifndef FOXPRO + progind_set_status((long)r->NKeys); +#endif + if (w != NULL && 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 */ + { + INDEX4 * w = i4create(dbdata[handle],NULL,tags); + if (w == NULL) rt = code_base.error_code; +#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 _memofld: + field_info[i].type=r4memo; + field_info[i].len = 10; + field_info[i].dec = 0; + 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 == '\0') + 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(non zero) se il file dati od indice sono stati bloccati + in modo esclusivo dalla presente applicazione, non da altri programmi!!! + --------------------------------------------------------------------------*/ + + +int DB_file_locked(int handle) +{ + if(dbdata[handle]==0) return(-1); + return(d4lock_test_file(dbdata[handle]) + d4lock_test_index(dbdata[handle])); +} + +/*------------------------------------------------------------------------- + Ritorna vero se il record nrec e' bloccato dalla presente applicazione, + non da altri programmi!!! + --------------------------------------------------------------------------*/ + +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[64]; + + if(dbdata[handle]==0) return(-1); + if (u4switch() & 2 || u4switch() & 8) /* Clipper & DBIII */ + u4name_piece(fn,64,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)); +} + +char* DB_memoptr( const int handle, const char * fieldname ) +{ + FIELD4 * f; + f = d4field( dbdata[ handle ], ( char *)fieldname ); + return f4memo_ptr( f ); +} + +int DB_memowrite( const int handle, const char * fieldname, const char * data ) +{ + int ret; + + FIELD4 * f; + f = d4field( dbdata[ handle ], fieldname ); + ret = f4memo_assign( f, ( char * )data ); + d4flush_data( dbdata[ handle ] ); + return ret; +} + diff --git a/include/isam.cpp b/include/isam.cpp index 31246c6df..4a89dda7e 100755 --- a/include/isam.cpp +++ b/include/isam.cpp @@ -600,7 +600,8 @@ int TBaseisamfile::delhr(const TRectype& rec, TDate& atdate) } long TBaseisamfile::items() const -{ +{ + NOT_OPEN(); return(DB_reccount(filehnd()->fhnd)); }