campo-sirio/include/codebase.c
guy ec9e033319 Patch level : 2.0 664
Files correlati     :
Ricompilazione Demo : [ ]
Commento            :

EP20153
problema sui list-box: non e' piu' possibile selezionare una voce facendo
doppio click su di essa.Es: entro nel programma documenti interattivi vado
su file impostazioni stampante e provo a selezionare un font dal list box


git-svn-id: svn://10.65.10.50/trunk@11683 c028cbd2-c16b-5b4b-a496-9718f37d4682
2003-12-19 10:34:43 +00:00

1189 lines
33 KiB
C
Executable File

#define XVT_INCL_NATIVE
#include <xvt.h>
#include <statbar.h>
#define S4OFF_REPORT
#if XVT_OS == XVT_OS_WIN32
#define S4DLL
#define S4WIN32
#endif
#include <d4all.h>
#include <codeb.h>
#include <rectypes.h>
/*--------------------------------------------------------------------------
Utility
--------------------------------------------------------------------------*/
HIDDEN void progind_create(long m, const char* t, bool b, bool c, int n)
{
statbar_set_title(TASK_WIN, t);
}
HIDDEN void progind_destroy()
{
statbar_set_title(TASK_WIN, NULL); // Restore default title
}
HIDDEN void progind_set_status(long l)
{
}
/*--------------------------------------------------------------------------
numero massimo di database aperti contemporaneamente
--------------------------------------------------------------------------*/
#define CB4FILES 64
#define MAXLEN 137 /* Lunghezza massima chiave */
static CODE4 code_base;
static DATA4 *dbdata[CB4FILES];
bool handle_ok(int handle)
{
return handle >= 0 && handle < CB4FILES && dbdata[handle] != NULL;
}
static char* find_slash_backslash(const char* s)
{
const char* slash = NULL;
for ( ; *s; s++)
{
if (*s == '\\' || *s == '/')
slash = s;
}
return (char*)slash;
}
/*--------------------------------------------------------------------------
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<CB4FILES;i++)
dbdata[i]=(DATA4*)NULL;
code4init(&code_base);
code_base.readLock=0;
code_base.errDefaultUnique=e4unique;
code_base.safety=0;
code_base.lockAttempts=1;
// code_base.optimize_write = 0;
code4dateFormatSet(&code_base, "CCYYMMDD");
}
/*--------------------------------------------------------------------------
reset di CodeBase
questa funzione dovrebbe essere chiamata prima di uscire da un eseguibile
per una questione di correttezza formale. Non usandola comunque non acca-
de niente di drammatico
--------------------------------------------------------------------------*/
void DB_exit(void)
{
int i;
code4initUndo(&code_base);
for(i=0;i<CB4FILES;i++)
{
if (handle_ok(i))
DB_close(i);
}
}
/*-------------------------------------------------------------------------
apertura del file 'filename'. Il parametro mode consente se != 0 l'apertura
esclusiva. Il parametro index consente se == 0 l'apertura senza indici
--------------------------------------------------------------------------*/
int DB_open(const char *filename,int mode,int index)
{
int i,found;
if (mode) code_base.accessMode=1;
/* cerca il primo posto libero nel vettore dbdata */
found=-1;
for(i=0;i<CB4FILES;i++)
{
if(dbdata[i]==(DATA4*)NULL)
{
found=i;
break;
}
}
/* se non ci sono posti liberi torna -1 */
if(found==-1) return(found);
code_base.errorCode=0;
if (index == 0) /* Se e' stata richiesta l'apertura senza indici, setta il flag */
code_base.autoOpen = 0;
dbdata[found]=d4open(&code_base,(char*)filename);
if (index == 0) /* Restore the configuration of opening indexes*/
code_base.autoOpen = 1;
if(dbdata[found]==0)
return code_base.errorCode;
code_base.accessMode=0;
d4tagSelect(dbdata[found],d4tagDefault(dbdata[found]));
if (d4recCount(dbdata[found]) > 0)
d4top(dbdata[found]);
return(found);
}
/*-------------------------------------------------------------------------
chiusura del database inviduato da handle
torna -1 se il database non puo essere chiuso
--------------------------------------------------------------------------*/
int DB_close(int handle)
{
if(!handle_ok(handle)) return(-1);
d4close(dbdata[handle]);
dbdata[handle]=(DATA4 *) 0;
code_base.errorCode=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(!handle_ok(handle)) return((char *) 0);
return(d4record(dbdata[handle]));
}
/*-------------------------------------------------------------------------
torna la lunghezza del record
--------------------------------------------------------------------------*/
int DB_reclen(int handle)
{
if(!handle_ok(handle)) return(-1);
return((int) d4recWidth(dbdata[handle]));
}
/*-------------------------------------------------------------------------
torna la lunghezza della chiave corrente
--------------------------------------------------------------------------*/
int DB_keylen(int handle)
{
return a4tagKeyLen(dbdata[handle]);
}
/*-------------------------------------------------------------------------
torna il numero del record attuale
--------------------------------------------------------------------------*/
long int DB_recno(int handle)
{
if(!handle_ok(handle)) return(-1L);
return(d4recNo(dbdata[handle]));
}
/*-------------------------------------------------------------------------
torna il numero complessivo dei records presenti nell'archivio
--------------------------------------------------------------------------*/
long int DB_reccount(int handle)
{
if(!handle_ok(handle)) 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(!handle_ok(handle)) return(-1);
/* si posiziona sul primo indice */
tt=d4tagNext(dbdata[handle],NULL);
if(tt==NULL) return(-1);
for(i=1;i<index_no;i++) {
tt=d4tagNext(dbdata[handle],tt);
if(tt==NULL) return(-1);
}
d4tagSelect(dbdata[handle],tt);
return(0);
}
/*-------------------------------------------------------------------------
torna il numero dell'indice selezionato
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_tagget(int handle)
{
TAG4 *tt,*tt1;
int i;
if(!handle_ok(handle)) return(-1);
/* si posiziona sul primo indice */
tt=d4tagDefault(dbdata[handle]);
if(tt==NULL) return(-1);
tt1=d4tagNext(dbdata[handle],NULL);
i=1;
while(tt!=tt1 && tt1!=NULL) {
tt1=d4tagNext(dbdata[handle],tt1);
i++;
}
return(i);
}
/*-------------------------------------------------------------------------
si posiziona sul primo record
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_first(int handle)
{
if(!handle_ok(handle)) return(-1);
return(d4top(dbdata[handle]));
}
/*-------------------------------------------------------------------------
si posiziona sull'ultimorecord
torna -1 se errore
--------------------------------------------------------------------------*/
int DB_last(int handle)
{
if(!handle_ok(handle)) return(-1);
return(d4bottom(dbdata[handle]));
}
/*-------------------------------------------------------------------------
skip avanti di un record
--------------------------------------------------------------------------*/
int DB_next(int handle)
{
if(!handle_ok(handle)) return(-1);
return(d4skip(dbdata[handle],1L));
}
/*-------------------------------------------------------------------------
skip indietro di un record
--------------------------------------------------------------------------*/
int DB_prev(int handle)
{
if(!handle_ok(handle)) return(-1);
return(d4skip(dbdata[handle],-1L));
}
/*-------------------------------------------------------------------------
skip di n records
--------------------------------------------------------------------------*/
int DB_skip(int handle,long int recno)
{
if(!handle_ok(handle)) return(-1);
return(d4skip(dbdata[handle],recno));
}
/*-------------------------------------------------------------------------
locka il record attuale
--------------------------------------------------------------------------*/
int DB_lock(int handle)
{
if(!handle_ok(handle)) return(-1);
return(d4lock(dbdata[handle],d4recNo(dbdata[handle])));
}
/*-------------------------------------------------------------------------
slocka il record attuale
--------------------------------------------------------------------------*/
int DB_unlock(int handle)
{
if(!handle_ok(handle)) return(-1);
return(d4unlock(dbdata[handle]));
}
/*-------------------------------------------------------------------------
cerca la chiave, torna r4after se not found ma si e' posizionato sul record
successivo, se torna r4eof e' su eof
--------------------------------------------------------------------------*/
int DB_seek(int handle,char *key)
{
int rc, len;
const char * k;
if(!handle_ok(handle)) return(-1);
rc = d4seek(dbdata[handle],key);
if (rc)
return rc;
len = a4tagKeyLen(dbdata[handle]);
k = a4tagKey(dbdata[handle]);
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(!handle_ok(handle)) return(-1);
return(d4eof(dbdata[handle]));
}
/*-------------------------------------------------------------------------
torna 1 se bof, 0 altrimenti
--------------------------------------------------------------------------*/
int DB_bof(int handle)
{
if(!handle_ok(handle)) return(-1);
return(d4bof(dbdata[handle]));
}
/*-------------------------------------------------------------------------
legge un record per numero record
--------------------------------------------------------------------------*/
int DB_go(int handle,long recno)
{
if(!handle_ok(handle)) return(-1);
return(d4go(dbdata[handle],recno));
}
/*-------------------------------------------------------------------------
cancella il record attuale. Non cancella le chiavi.
--------------------------------------------------------------------------*/
int DB_delete(int handle)
{
if(!handle_ok(handle)) return(-1);
d4delete(dbdata[handle]);
return(0);
}
/*-------------------------------------------------------------------------
ripristina il record attuale
--------------------------------------------------------------------------*/
int DB_recall(int handle)
{
if(!handle_ok(handle)) return(-1);
d4recall(dbdata[handle]);
return(0);
}
/*-------------------------------------------------------------------------
--------------------------------------------------------------------------*/
int DB_flush(int handle)
{
int rt;
while ((rt = d4flush(dbdata[handle])) == r4locked)
u4delaySec();
return rt;
}
/*-------------------------------------------------------------------------
riscrive il record attuale
--------------------------------------------------------------------------*/
int DB_rewrite(int handle)
{
int rt;
if(!handle_ok(handle)) return(-1);
while ((rt=d4write(dbdata[handle],d4recNo(dbdata[handle]))) == r4locked)
u4delaySec();
if (rt == 0)
{
while ((rt = d4flush(dbdata[handle])) == r4locked)
u4delaySec();
}
if (rt == e4unique)
{
char msg[256];
DB_get_error();
sprintf(msg, "Errore in DB_rewrite(): chiave duplicata nel record %ld, file %s",
d4recNo(dbdata[handle]) + 1, d4fileName(dbdata[handle]));
xvt_dm_post_fatal_exit(msg);
}
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 (d4lockAll(data) == r4locked)
u4delaySec();
}
while ((rt = d4appendStart(data,0)) == r4locked)
u4delaySec();
if (rt == 0)
{
d4recall(data);
while ((rt = d4append(data)) == r4locked)
u4delaySec();
if (rt == e4unique)
{
long rec_num = d4recNo(data);
DB_get_error();
if (rec_num > 0)
{
char msg[256];
sprintf(msg, "Errore in DB_add(): chiave duplicata nell' indice %ld, file %s",
rec_num + 1, d4fileName(data));
xvt_dm_post_fatal_exit(msg);
}
else
rt = _isreinsert;
}
else
if (rt == 0)
{
while ((rt = d4flush(data)) == r4locked)
u4delaySec();
}
}
DB_unlock(handle);
if (is_locked == 0)
d4unlock(data);
return(rt);
}
/*-------------------------------------------------------------------------
Blocca in modo esclusivo il file dati ed indice
--------------------------------------------------------------------------*/
int DB_lockfile(int handle)
{
int rt;
if(!handle_ok(handle)) return(-1);
rt = d4lockFile(dbdata[handle]);
if (rt==0) rt=d4lockIndex(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 n_keys)
{
int i,j;
char tiname[9]; /* Tag name, max 8 characters long! */
char* dot;
strcpy(tiname,fname);
dot = strchr(tiname, '.');
if (dot) *dot = '\0';
_strupr(tiname);
for (i=0; ((i < MaxKeys) && (i < n_keys)); i++)
{
tag_info[i].name=(char *)u4alloc(9);
tag_info[i].expression=(char *)u4alloc(256);
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= i == 0 ? e4unique : r4unique_continue;
/* tag_info[i].unique=e4unique; */
strcpy((char *)tag_info[i].filter,".NOT. DELETED()"); /* Not available for DBIII and CLIPPER */
strcpy((char *)tag_info[i].name,tiname) ;
if (strlen(tiname) < 8)
strcat((char *)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((char *) tag_info[i].expression,"UPPER(");
}
if (r->Ky[i].FromCh[j] != 255) /* When partial field is specified */
strcat((char *)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((char *)tag_info[i].expression,"STR(");
break;
case _datefld:
strcat((char *)tag_info[i].expression,"DTOS(");
break;
case _boolfld:
strcat((char *)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((char *)tag_info[i].expression,r->Fd[nf].Name); /* Append field name */
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((char *)tag_info[i].expression,",");
sprintf(ts,"%d",r->Fd[nf].Len);
strcat((char *)tag_info[i].expression,ts);
strcat((char *)tag_info[i].expression,",0)");
}
break;
case _boolfld:
strcat((char *)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((char *)tag_info[i].expression,")");
if (r->Ky[i].FromCh[j] != 255) /* If partial field was specified */
{ /* add parameters to SUBSTR */
char ts[8];
strcat((char *)tag_info[i].expression,",");
sprintf(ts,"%d",r->Ky[i].FromCh[j] + 1);
strcat((char *)tag_info[i].expression,ts);
strcat((char *)tag_info[i].expression,",");
sprintf(ts,"%d",r->Ky[i].ToCh[j] - r->Ky[i].FromCh[j] + 1);
strcat((char *)tag_info[i].expression,ts);
strcat((char *)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((char *)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;
code_base.autoOpen = 0;
handle=DB_open(filename,1,0); /* Exclusive mode open! */
if (handle > -1)
{
if (vis)
{
char s[_MAX_PATH];
strcpy(s,"Compattamento ");
strcat(s, filename);
progind_create(100L,s,0,0,60);
}
if (eod < d4recCount(dbdata[handle]))
{
rt=d4zap(dbdata[handle],++eod,d4recCount(dbdata[handle]));
} else
rt=d4pack(dbdata[handle]);
if (vis)
progind_destroy();
DB_close(handle);
}
else
rt=code_base.errorCode;
code_base.autoOpen = 1;
return rt;
}
/*-------------------------------------------------------------------------
Compatta il file dati
--------------------------------------------------------------------------*/
int DB_packmemo(short vis, const char * filename)
{
int rt=0,handle;
code_base.autoOpen = 0;
handle=DB_open(filename,1,0); /* Exclusive mode open! */
if (handle > -1)
{
char s[81];
if (vis)
{
strcpy(s,"Compattamento memo file : ");
strcat(s,(char*)filename);
progind_create(100L,s,0,0,60);
}
rt=d4memoCompress(dbdata[handle]);
if (vis)
progind_destroy();
DB_close(handle);
}
else
rt=code_base.errorCode;
code_base.autoOpen = 1;
return rt;
}
/*-------------------------------------------------------------------------
Elimina i record duplicati
--------------------------------------------------------------------------*/
int DB_clean_file(int handle, char * filename, char * ff, RecDes * r, short vis)
{
TAG4INFO tags[2];
TAG4 * t;
char s[256], s0[256];
int l = 0, lt = 0, rt = 0;
long cnt = 0;
INDEX4 *w = NULL;
long items = DB_reccount(handle);
if (items == 0)
return 0;
s[0] = '\0';
do_key(ff, r, tags, 1);
strcat((char *) tags[0].expression, "+STR(RECNO(),9)");
w = i4create(dbdata[handle],(char*)filename,tags);
u4free((char *) tags[0].name);
u4free((char *) tags[0].expression);
u4free((char *) tags[0].filter);
if (w == NULL) return code_base.errorCode;
t = d4tagDefault(dbdata[handle]);
lt = expr4len(t->tagFile->expr);
l = lt - 9;
if (vis)
progind_create(items,"Ricerca record duplicati",0,1,60);
rt = tfile4bottom(t->tagFile);
while (code_base.errorCode == 0)
{
strncpy(s0, a4tagKey(dbdata[handle]), lt);
if (vis)
progind_set_status(++cnt);
if (!strncmp(s, s0, l))
{
d4go(dbdata[handle],tfile4recNo(t->tagFile));
d4delete(dbdata[handle]);
tfile4seek(t->tagFile, s0, lt);
}
strncpy(s, s0, lt);
if (tfile4skip(t->tagFile, -1L) >= 0)
break;
} // while
rt = code_base.errorCode;
if (vis)
progind_destroy();
i4close(w);
return rt;
}
/*-------------------------------------------------------------------------
Compatta gli indici
--------------------------------------------------------------------------*/
int DB_yesnobox(const char* msg)
{
return xvt_dm_post_ask("Si", "No", NULL, msg) == RESP_DEFAULT;
}
int DB_packindex(short vis, const char * filename, RecDes *r, long *peod, bool ask)
{
int rt=0,handle;
TAG4INFO tags[MaxKeys+1];
char s[256];
INDEX4 * w = NULL;
strcpy(s,"Ricostruzione indici file : ");
strcat(s,filename);
code_base.autoOpen=0 ;
handle=DB_open(filename,1,0); /* Exclusive mode open */
if (handle >= 0)
{
int i;
char *ff = find_slash_backslash(filename);
if (vis)
progind_create((long)r->NKeys,s,0,1,60);
if ((ff == NULL) || *ff == '\0')
ff = (char *)filename;
else
ff++;
do_key(ff,r,tags, r->NKeys);
w = i4create(dbdata[handle],NULL,tags);
if (vis)
{
progind_set_status((long)r->NKeys);
progind_destroy();
}
if (w == NULL) rt = code_base.errorCode;
if (rt == e4unique || rt == r4unique)
{
rt = 0;
if (!ask || DB_yesnobox("Sono stati rilevati alcuni records duplicati:\nsi desidera eliminarli?"))
rt = DB_clean_file(handle, (char*) filename, ff, r, vis);
else
tags[0].unique = r4unique_continue;
if (rt == 0)
{
if (vis)
progind_create((long)r->NKeys,s,0,1,60);
w = i4create(dbdata[handle],(char*)filename,tags);
if (w == NULL) rt = code_base.errorCode;
if (vis)
{
progind_set_status((long)r->NKeys);
progind_destroy();
}
}
}
if (rt == 0)
{
if (u4switch() & 2 || u4switch() & 8) /* Clipper and DBIII */
{
FILE *fp;
char cgp[81];
strcpy(cgp,filename);
strcat(cgp,".cgp");
if ((fp=fopen(cgp,"w"))!=NULL)
{
int j;
for (j=0; j<r->NKeys;j++)
fprintf(fp,"%s\n",tags[j].name);
fclose(fp);
}
}
}
for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++)
{
u4free((char *) tags[i].name);
u4free((char *) tags[i].expression);
u4free((char *) tags[i].filter);
}
*peod=DB_reccount(handle);
DB_close(handle);
}
code_base.autoOpen = 1;
return(rt);
}
/*-------------------------------------------------------------------------
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(filename);
for (i=0; ((i<r->NFields) && (i<MaxFields)); i++) /* Construct field_info */
{
field_info[i].name = (char*)u4alloc(12);
strcpy(field_info[i].name,r->Fd[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, r->NKeys);
if ((dbuilded=d4create(&code_base, (char *)filename, field_info, tag_info))==0) /* deve solo creare il file dati vuoto */
rt=code_base.errorCode;
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.errorCode;
for (i=0; ((i < MaxFields) && (i < r->NFields)); i++)
u4free(field_info[i].name);
for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++)
{
u4free((char *) tag_info[i].name);
u4free((char *) tag_info[i].expression);
u4free((char *) tag_info[i].filter);
}
return(rt) ;
}
/*-------------------------------------------------------------------------
reperisce il tracciato record e la stringa di definizione delle chiavi
Stringa di definizione chiavi:
expression1|unique1$expression2|unique2$expression3|unique3
--------------------------------------------------------------------------*/
int DB_recinfo(const char * filename, FileDes *d, RecDes *r, char* keys)
{
/* filename must not have extension since it's used to search index name too*/
FIELD4INFO *field_info; /* Definizione del tracciato record */
TAG4INFO *tag_info; /* Definizione delle chiavi */
INDEX4 *index_file;
DATA4 *data_file;
int rt=0,num_fields,i;
data_file = d4open(&code_base, (char*)filename);
if (data_file != NULL)
{
field_info = d4fieldInfo(data_file);
index_file = d4index(data_file,"" /*(char*)filename */);
if (index_file == NULL)
{
char msg[256];
sprintf(msg, "Il file %s e' senza indici.",filename);
xvt_dm_post_fatal_exit(msg);
}
tag_info = i4tagInfo(index_file);
d->EOD = d->EOX = d4recCount(data_file);
d->LenR = (word)d4recWidth(data_file);
d->Flags = 0L;
strcpy(d->Des,"File esterno");
strcpy(d->FCalc,"");
strcpy(d->GenPrompt,"");
if (field_info != NULL && tag_info != NULL)
{
/* Compile field information */
num_fields = d4numFields(data_file);
r->NFields = num_fields;
for (i=0; ((i<num_fields) && (i<MaxFields)); i++)
{
strcpy(r->Fd[i].Name,field_info[i].name);
_strupr(r->Fd[i].Name);
r->Fd[i].Len = (unsigned char)field_info[i].len;
r->Fd[i].Dec = (unsigned char)field_info[i].dec;
switch(field_info[i].type)
{
case r4str:
if (r->Fd[i].Len > 1)
r->Fd[i].TypeF = _alfafld;
else
r->Fd[i].TypeF = _charfld;
break;
case r4log:
r->Fd[i].TypeF = _boolfld;
break;
case r4date:
r->Fd[i].TypeF = _datefld;
break;
case r4memo:
r->Fd[i].TypeF = _memofld;
break;
case r4num:
if (r->Fd[i].Dec > 0)
r->Fd[i].TypeF = _realfld;
else
r->Fd[i].TypeF = r->Fd[i].Len < 6 ? _intfld : _longfld;
break;
default:
break;
}
}
strcpy(keys,"");
/* Compile key definition */
for (i=0; i < MaxKeys; i++) /* Browse all tags */
{
if (tag_info[i].name == NULL)
break;
strcat(keys,tag_info[i].expression);
/* Tell me if you're unique my Boy... */
strcat(keys,"|");
strcat(keys,tag_info[i].unique == 0 ? "X" : " ");
strcat(keys,"$");
}
r->NKeys = i;
u4free(field_info);
u4free(tag_info);
}
else
rt = code_base.errorCode;
d4close(data_file);
}
else
rt = code_base.errorCode;
return (rt);
}
/*-------------------------------------------------------------------------
ritorna l'ultimo errore
--------------------------------------------------------------------------*/
int DB_get_error(void)
{
int rt = code_base.errorCode;
code_base.errorCode=0;
return (rt);
}
/*-------------------------------------------------------------------------
Azzera la viarabile globale d'errore
--------------------------------------------------------------------------*/
void DB_zero_error(void)
{
code_base.errorCode=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(!handle_ok(handle)) return(-1);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1);
if (tfile4seek(t->tagFile,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(!handle_ok(handle)) return(-1);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1);
return(tfile4recNo(t->tagFile));
}
/*-------------------------------------------------------------------------
Si posiziona sulla chiave successiva dell'indice corrente
--------------------------------------------------------------------------*/
long DB_index_next(int handle)
{
TAG4 *t;
if(!handle_ok(handle)) return(-1);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1);
return(tfile4skip(t->tagFile,1L));
}
/*-------------------------------------------------------------------------
Restituisce la chiave corrente
--------------------------------------------------------------------------*/
char* DB_index_getkey(int handle)
{
static char* key = NULL;
TAG4 *t;
int klen;
if (key == NULL)
key = malloc(MAXLEN);
if(!handle_ok(handle))
return(NULL);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(NULL);
klen=a4tagKeyLen(dbdata[handle]);
if (klen > (MAXLEN-1)) klen=MAXLEN-1;
memcpy(key,a4tagKey(dbdata[handle]),klen); /* tfile4key non restituisce una null terminated string */
key[klen]='\0';
return key;
}
/*-------------------------------------------------------------------------
Si posiziona sulla chiave ed il record indicati
--------------------------------------------------------------------------*/
int DB_index_go(int handle, const char* key, long recno)
{
TAG4 *t;
if(!handle_ok(handle)) return(-1);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1);
return(tfile4go(t->tagFile, key, recno, FALSE));
}
/*-------------------------------------------------------------------------
Restituisce vero se l'indice e' alla fine
--------------------------------------------------------------------------*/
int DB_index_eof(int handle)
{
TAG4 *t;
if(!handle_ok(handle)) return(-1);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1);
return(tfile4eof(t->tagFile));
}
/*-------------------------------------------------------------------------
Blocca il record indicato
--------------------------------------------------------------------------*/
int DB_lock_rec(int handle,long nrec)
{
if(!handle_ok(handle)) 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(!handle_ok(handle)) return(-1);
return a4lockTest(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(!handle_ok(handle)) return(-1);
return(d4lockTest(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)
{
return(a4indexVersion(dbdata[handle]));
}
char* DB_memoptr( const int handle, const char * fieldname )
{
FIELD4 * f;
f = d4field( dbdata[ handle ], ( char *)fieldname );
return f4memoPtr( f );
}
int DB_memowrite( const int handle, const char * fieldname, const char * data )
{
int ret;
FIELD4 * f;
f = d4field(dbdata[handle], fieldname );
ret = f4memoAssign( f, ( char * )data );
d4flush(dbdata[handle]);
d4unlock(dbdata[handle]);
return ret;
}