Patch level : 10.0
Files correlati : tutti Ricompilazione Demo : [ ] Commento : Migliorate prestazioni in fase di scrittura su file aperti in modo esclusivo Migliorata gestione dei lock nelle applicazioni di modifica tabelle git-svn-id: svn://10.65.10.50/trunk@17992 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
f318b43a1e
commit
e2a19d9e23
384
include/codeb.c
384
include/codeb.c
@ -36,13 +36,11 @@
|
||||
#define MAXLEN 137 /* Lunghezza massima chiave */
|
||||
|
||||
static CODE4 code_base;
|
||||
static DATA4 *dbdata[CB4FILES];
|
||||
static DATA4* dbdata[CB4FILES];
|
||||
static bool dbfast[CB4FILES];
|
||||
|
||||
static bool handle_ok(int handle)
|
||||
{
|
||||
return handle >= 0 && handle < CB4FILES &&
|
||||
dbdata[handle] != NULL && dbdata[handle]->clientId >= 0;
|
||||
}
|
||||
#define HANDLE2DATA(handle, data) DATA4* data = dbdata[handle]; if (handle < 0 || handle >= CB4FILES || data == NULL || data->clientId < 0) return -1
|
||||
#define HANDLE2DATASTR(handle, data) DATA4* data = dbdata[handle]; if (handle < 0 || handle >= CB4FILES || data == NULL || data->clientId < 0) return NULL
|
||||
|
||||
static const char* find_slash_backslash(const char* s)
|
||||
{
|
||||
@ -77,6 +75,7 @@ void DB_init(void)
|
||||
code_base.lockAttempts=1;
|
||||
code4dateFormatSet(&code_base, "CCYYMMDD");
|
||||
|
||||
code_base.optimize = OPT4EXCLUSIVE; // Is the default?
|
||||
code_base.optimizeWrite = OPT4EXCLUSIVE; // Is the default?
|
||||
}
|
||||
|
||||
@ -89,9 +88,9 @@ void DB_init(void)
|
||||
void DB_exit(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0; i< CB4FILES; i++)
|
||||
for (i = 0; i < CB4FILES; i++)
|
||||
{
|
||||
if (handle_ok(i))
|
||||
if (dbdata[i] != NULL)
|
||||
DB_close(i);
|
||||
}
|
||||
code4initUndo(&code_base);
|
||||
@ -101,11 +100,10 @@ void DB_exit(void)
|
||||
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; // Exclusive mode
|
||||
/* cerca il primo posto libero nel vettore dbdata */
|
||||
found=-1;
|
||||
for(i=0;i<CB4FILES;i++)
|
||||
@ -116,23 +114,39 @@ int DB_open(const char *filename,int mode,int index)
|
||||
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, 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);
|
||||
if (found >= 0)
|
||||
{
|
||||
if (mode)
|
||||
code_base.accessMode=1; // Exclusive mode
|
||||
|
||||
code_base.errorCode=0;
|
||||
if (!index)
|
||||
{
|
||||
code_base.autoOpen = 0; // Se e' stata richiesta l'apertura senza indici, resetta il flag autoOpen
|
||||
dbdata[found]=d4open(&code_base, filename);
|
||||
code_base.autoOpen = 1;
|
||||
}
|
||||
else
|
||||
dbdata[found]=d4open(&code_base, filename);
|
||||
|
||||
if (mode)
|
||||
code_base.accessMode=0; // Not-Exclusive mode
|
||||
|
||||
if(dbdata[found]!=NULL)
|
||||
{
|
||||
HANDLE2DATA(found, data);
|
||||
|
||||
// Guy: Non capisco bene perche' seleziono comunque un indice
|
||||
d4tagSelect(data, d4tagDefault(data));
|
||||
if (d4recCount(data) > 0)
|
||||
d4top(data);
|
||||
|
||||
dbfast[found] = mode!=0; // Ottimizabile se esclusivo
|
||||
}
|
||||
else
|
||||
return code_base.errorCode;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
@ -142,31 +156,32 @@ int DB_open(const char *filename,int mode,int index)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_close(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
HANDLE2DATA(handle, data);
|
||||
|
||||
d4close(dbdata[handle]);
|
||||
dbdata[handle]=(DATA4 *) 0;
|
||||
d4close(data);
|
||||
dbdata[handle] = NULL;
|
||||
dbfast[handle] = FALSE;
|
||||
code_base.errorCode=0;
|
||||
return(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)
|
||||
char* DB_getrecord(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return((char *) 0);
|
||||
return(d4record(dbdata[handle]));
|
||||
HANDLE2DATASTR(handle, data);
|
||||
return d4record(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna la lunghezza del record
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_reclen(int handle)
|
||||
int DB_reclen(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return((int) d4recWidth(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return (int)d4recWidth(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -175,7 +190,8 @@ int DB_reclen(int handle)
|
||||
|
||||
int DB_keylen(int handle)
|
||||
{
|
||||
return a4tagKeyLen(dbdata[handle]);
|
||||
HANDLE2DATA(handle, data);
|
||||
return a4tagKeyLen(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -183,8 +199,8 @@ int DB_keylen(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
long int DB_recno(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1L);
|
||||
return(d4recNo(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4recNo(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -192,29 +208,32 @@ long int DB_recno(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
long int DB_reccount(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1L);
|
||||
return(d4recCount(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4recCount(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
seleziona un indice sul database specificato
|
||||
torna -1 se errore, altrimenti 0
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_tagselect(int handle,int index_no)
|
||||
int DB_tagselect(int handle,int index_no)
|
||||
{
|
||||
TAG4 *tt;
|
||||
int i;
|
||||
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
HANDLE2DATA(handle, data);
|
||||
/* 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);
|
||||
tt=d4tagNext(data, NULL);
|
||||
if (tt==NULL)
|
||||
return -1;
|
||||
for(i=1; i<index_no; i++)
|
||||
{
|
||||
tt=d4tagNext(data, tt);
|
||||
if(tt==NULL)
|
||||
return(-1);
|
||||
}
|
||||
d4tagSelect(dbdata[handle],tt);
|
||||
return(0);
|
||||
d4tagSelect(data, tt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -226,16 +245,18 @@ int DB_tagget(int handle)
|
||||
{
|
||||
TAG4 *tt,*tt1;
|
||||
int i;
|
||||
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
HANDLE2DATA(handle, data);
|
||||
|
||||
/* si posiziona sul primo indice */
|
||||
tt=d4tagDefault(dbdata[handle]);
|
||||
if(tt==NULL) return(-1);
|
||||
tt=d4tagDefault(data);
|
||||
if(tt==NULL)
|
||||
return(-1);
|
||||
|
||||
tt1=d4tagNext(dbdata[handle],NULL);
|
||||
tt1=d4tagNext(data,NULL);
|
||||
i=1;
|
||||
while(tt!=tt1 && tt1!=NULL) {
|
||||
tt1=d4tagNext(dbdata[handle],tt1);
|
||||
while(tt!=tt1 && tt1!=NULL)
|
||||
{
|
||||
tt1=d4tagNext(data,tt1);
|
||||
i++;
|
||||
}
|
||||
return(i);
|
||||
@ -247,8 +268,8 @@ int DB_tagget(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_first(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4top(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4top(data);
|
||||
}
|
||||
|
||||
|
||||
@ -258,8 +279,8 @@ int DB_first(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_last(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4bottom(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4bottom(data);
|
||||
}
|
||||
|
||||
|
||||
@ -268,8 +289,7 @@ int DB_last(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_next(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4skip(dbdata[handle],1L));
|
||||
return DB_skip(handle, +1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -277,18 +297,16 @@ int DB_next(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_prev(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4skip(dbdata[handle],-1L));
|
||||
return DB_skip(handle, -1);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
skip di n records
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_skip(int handle,long int recno)
|
||||
int DB_skip(int handle, long recno)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4skip(dbdata[handle],recno));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4skip(data, recno);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -296,8 +314,8 @@ int DB_skip(int handle,long int recno)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_lock(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4lock(dbdata[handle],d4recNo(dbdata[handle])));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4lock(data, d4recNo(data));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -305,8 +323,8 @@ int DB_lock(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_unlock(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4unlock(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4unlock(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -318,12 +336,12 @@ int DB_seek(int handle,char *key)
|
||||
int rc, len;
|
||||
const char * k;
|
||||
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
rc = d4seek(dbdata[handle],key);
|
||||
HANDLE2DATA(handle, data);
|
||||
rc = d4seek(data,key);
|
||||
if (rc)
|
||||
return rc;
|
||||
len = a4tagKeyLen(dbdata[handle]);
|
||||
k = a4tagKey(dbdata[handle]);
|
||||
len = a4tagKeyLen(data);
|
||||
k = a4tagKey(data);
|
||||
while (len > 0 && k[len-1] == ' ') len--;
|
||||
rc = strncmp(key, k, len);
|
||||
if (rc == 0)
|
||||
@ -340,8 +358,8 @@ int DB_seek(int handle,char *key)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_eof(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4eof(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4eof(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -349,8 +367,8 @@ int DB_eof(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_bof(int handle)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4bof(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4bof(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -358,8 +376,8 @@ int DB_bof(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_go(int handle,long recno)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4go(dbdata[handle],recno));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4go(data,recno);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -367,10 +385,9 @@ int DB_go(int handle,long recno)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_delete(int handle)
|
||||
{
|
||||
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
d4delete(dbdata[handle]);
|
||||
return(0);
|
||||
HANDLE2DATA(handle, data);
|
||||
d4delete(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -378,10 +395,9 @@ int DB_delete(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_recall(int handle)
|
||||
{
|
||||
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
d4recall(dbdata[handle]);
|
||||
return(0);
|
||||
HANDLE2DATA(handle, data);
|
||||
d4recall(data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -389,9 +405,19 @@ int DB_recall(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_flush(int handle)
|
||||
{
|
||||
int rt;
|
||||
while ((rt = d4flush(dbdata[handle])) == r4locked)
|
||||
u4delaySec();
|
||||
int rt = 0;
|
||||
HANDLE2DATA(handle, data);
|
||||
|
||||
if (dbfast[handle])
|
||||
{
|
||||
if (data->dataFile->nFieldsMemo > 0)
|
||||
rt = d4write(data, -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
while ((rt = d4flush(data)) == r4locked)
|
||||
u4delaySec();
|
||||
}
|
||||
return rt;
|
||||
}
|
||||
|
||||
@ -400,9 +426,9 @@ int DB_flush(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_rewrite(int handle)
|
||||
{
|
||||
int rt;
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
while ((rt=d4write(dbdata[handle],d4recNo(dbdata[handle]))) == r4locked)
|
||||
int rt = -1;
|
||||
HANDLE2DATA(handle, data);
|
||||
while ((rt=d4write(data,d4recNo(data))) == r4locked)
|
||||
u4delaySec();
|
||||
|
||||
if (rt == e4unique)
|
||||
@ -410,7 +436,7 @@ int DB_rewrite(int handle)
|
||||
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]));
|
||||
d4recNo(data) + 1, d4fileName(data));
|
||||
xvt_dm_post_fatal_exit(msg);
|
||||
}
|
||||
|
||||
@ -426,13 +452,12 @@ int DB_rewrite(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_add(int handle)
|
||||
{
|
||||
int rt;
|
||||
DATA4 * data = dbdata[handle];
|
||||
|
||||
if (data==0) return(-1);
|
||||
int rt = -1;
|
||||
HANDLE2DATA(handle, data);
|
||||
|
||||
while ((rt = d4appendStart(data,0)) == r4locked)
|
||||
u4delaySec();
|
||||
|
||||
if (rt == 0)
|
||||
{
|
||||
d4recall(data);
|
||||
@ -440,8 +465,7 @@ int DB_add(int handle)
|
||||
u4delaySec();
|
||||
if (rt == e4unique)
|
||||
{
|
||||
long rec_num = d4recNo(data);
|
||||
|
||||
const long rec_num = d4recNo(data);
|
||||
DB_get_error();
|
||||
if (rec_num > 0)
|
||||
{
|
||||
@ -460,7 +484,7 @@ int DB_add(int handle)
|
||||
}
|
||||
}
|
||||
|
||||
return(rt);
|
||||
return rt;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -469,12 +493,10 @@ int DB_add(int handle)
|
||||
int DB_lockfile(int handle)
|
||||
{
|
||||
int rt = -1;
|
||||
if(handle_ok(handle))
|
||||
{
|
||||
rt = d4lockFile(dbdata[handle]);
|
||||
if (rt==0)
|
||||
rt=d4lockIndex(dbdata[handle]);
|
||||
}
|
||||
HANDLE2DATA(handle, data);
|
||||
rt = d4lockFile(data);
|
||||
if (rt==0)
|
||||
rt = d4lockIndex(data);
|
||||
return rt;
|
||||
}
|
||||
|
||||
@ -808,8 +830,7 @@ int DB_build(const char* filename, const RecDes* r)
|
||||
|
||||
for (i=0; ((i<r->NFields) && (i<MaxFields)); i++) /* Construct field_info */
|
||||
{
|
||||
field_info[i].name = (char*)u4alloc(16); // In realtà basterebbero 12
|
||||
strcpy(field_info[i].name,r->Fd[i].Name);
|
||||
field_info[i].name = (char*)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)
|
||||
@ -851,31 +872,14 @@ int DB_build(const char* filename, const RecDes* r)
|
||||
|
||||
do_key(ff,r,tag_info, MaxKeys);
|
||||
|
||||
if ((dbuilded=d4create(&code_base, (char *)filename, field_info, tag_info))==0) /* deve solo creare il file dati vuoto */
|
||||
if ((dbuilded=d4create(&code_base, filename, field_info, tag_info))==0) /* deve solo creare il file dati vuoto */
|
||||
rt=code_base.errorCode;
|
||||
else
|
||||
rt=d4close(dbuilded);
|
||||
|
||||
/* Non abbiamo mai usato e speriamo mai useremo questo genere di files!!!!
|
||||
if (u4switch() & 2 || u4switch() & 8) //Rebuild filename.cgp for CLIPPER AND DBIII only
|
||||
{
|
||||
FILE* fp;
|
||||
char xx[81];
|
||||
strcpy(xx,filename);
|
||||
strcat(xx,".cgp");
|
||||
fp=fopen(xx,"w");
|
||||
if (fp != 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);
|
||||
@ -997,13 +1001,14 @@ void DB_zero_error(void)
|
||||
|
||||
int DB_index_seek(int handle, const 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);
|
||||
TAG4* t = NULL;
|
||||
HANDLE2DATA(handle, data);
|
||||
t = d4tagDefault(data);
|
||||
if (t==NULL)
|
||||
return -1;
|
||||
if (tfile4seek(t->tagFile, from, strlen(from)) < 0)
|
||||
return DB_get_error();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
@ -1014,11 +1019,12 @@ int DB_index_seek(int handle, const char* from)
|
||||
long DB_index_recno(int handle)
|
||||
{
|
||||
TAG4 *t;
|
||||
HANDLE2DATA(handle, data);
|
||||
t=d4tagDefault(data);
|
||||
if (t==NULL)
|
||||
return(-1);
|
||||
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1);
|
||||
|
||||
return(tfile4recNo(t->tagFile));
|
||||
return tfile4recNo(t->tagFile);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1027,11 +1033,11 @@ long DB_index_recno(int handle)
|
||||
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));
|
||||
HANDLE2DATA(handle, data);
|
||||
t = d4tagDefault(data);
|
||||
if (t==NULL)
|
||||
return -1;
|
||||
return tfile4skip(t->tagFile,1L);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1040,18 +1046,17 @@ long DB_index_next(int handle)
|
||||
|
||||
char* DB_index_getkey(int handle)
|
||||
{
|
||||
static char* key = NULL;
|
||||
static char key[MAXLEN];
|
||||
TAG4 *t;
|
||||
int klen;
|
||||
|
||||
HANDLE2DATASTR(handle, data);
|
||||
|
||||
if (key == NULL)
|
||||
key = malloc(MAXLEN);
|
||||
if(!handle_ok(handle))
|
||||
if ((t=d4tagDefault(data))==NULL)
|
||||
return(NULL);
|
||||
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(NULL);
|
||||
klen=a4tagKeyLen(dbdata[handle]);
|
||||
klen=a4tagKeyLen(data);
|
||||
if (klen > (MAXLEN-1)) klen=MAXLEN-1;
|
||||
memcpy(key,a4tagKey(dbdata[handle]),klen); /* tfile4key non restituisce una null terminated string */
|
||||
memcpy(key,a4tagKey(data),klen); /* tfile4key non restituisce una null terminated string */
|
||||
key[klen]='\0';
|
||||
return key;
|
||||
}
|
||||
@ -1061,12 +1066,12 @@ char* DB_index_getkey(int handle)
|
||||
--------------------------------------------------------------------------*/
|
||||
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));
|
||||
TAG4* t = NULL;
|
||||
HANDLE2DATA(handle, data);
|
||||
t = d4tagDefault(data);
|
||||
if (t==NULL)
|
||||
return -1;
|
||||
return tfile4go(t->tagFile, key, recno, FALSE);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1075,22 +1080,22 @@ int DB_index_go(int handle, const char* key, long recno)
|
||||
|
||||
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));
|
||||
TAG4* t = NULL;
|
||||
HANDLE2DATA(handle, data);
|
||||
t = d4tagDefault(data);
|
||||
if (t==NULL)
|
||||
return -1;
|
||||
return tfile4eof(t->tagFile);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Blocca il record indicato
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_lock_rec(int handle,long nrec)
|
||||
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);
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4lock(data, nrec)==r4locked ? -1 : 0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1098,11 +1103,10 @@ int DB_lock_rec(int handle,long nrec)
|
||||
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]);
|
||||
HANDLE2DATA(handle, data);
|
||||
return a4lockTest(data);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1110,10 +1114,10 @@ int DB_file_locked(int handle)
|
||||
non da altri programmi!!!
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_rec_locked(int handle,long nrec)
|
||||
int DB_rec_locked(int handle, long nrec)
|
||||
{
|
||||
if(!handle_ok(handle)) return(-1);
|
||||
return(d4lockTest(dbdata[handle],nrec));
|
||||
HANDLE2DATA(handle, data);
|
||||
return d4lockTest(data,nrec);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1122,7 +1126,7 @@ int DB_rec_locked(int handle,long nrec)
|
||||
|
||||
long DB_getconf()
|
||||
{
|
||||
return(u4switch());
|
||||
return u4switch();
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
@ -1131,26 +1135,24 @@ long DB_getconf()
|
||||
|
||||
long DB_changed(int handle)
|
||||
{
|
||||
return(a4indexVersion(dbdata[handle]));
|
||||
HANDLE2DATA(handle, data);
|
||||
return a4indexVersion(data);
|
||||
}
|
||||
|
||||
char* DB_memoptr( const int handle, const char * fieldname )
|
||||
{
|
||||
FIELD4* f = d4field( dbdata[ handle ], fieldname );
|
||||
return f4memoPtr( f );
|
||||
FIELD4* f = NULL;
|
||||
HANDLE2DATASTR(handle, data);
|
||||
f = d4field(data, fieldname);
|
||||
return f4memoPtr(f);
|
||||
}
|
||||
|
||||
int DB_memowrite( const int handle, const char* fieldname, const char* data )
|
||||
int DB_memowrite( const int handle, const char* fieldname, const char* memo )
|
||||
{
|
||||
FIELD4* f = d4field(dbdata[handle], fieldname );
|
||||
int ret = f4memoAssign( f, data );
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
d4flush(dbdata[handle]);
|
||||
d4unlock(dbdata[handle]);
|
||||
}
|
||||
return ret;
|
||||
FIELD4* f = NULL;
|
||||
HANDLE2DATA(handle, data);
|
||||
f = d4field(data, fieldname);
|
||||
return f4memoAssign(f, memo);
|
||||
}
|
||||
|
||||
long DB_version(char* str, int maxstr)
|
||||
|
135
include/isam.cpp
135
include/isam.cpp
@ -30,54 +30,6 @@
|
||||
#include <codeb.h>
|
||||
#include <nditte.h>
|
||||
|
||||
#ifdef JOURNAL
|
||||
#include <journal.h>
|
||||
|
||||
static FILE* _journal = (FILE*)0xFFFF;
|
||||
|
||||
FILE* get_journal()
|
||||
{
|
||||
if (_journal == (FILE*)0xFFFF)
|
||||
{
|
||||
TConfig ini(CONFIG_INSTALL, "Main");
|
||||
const TString& name = ini.get("Journal");
|
||||
if (name.not_empty())
|
||||
_journal = fopen(name, "ab");
|
||||
else
|
||||
_journal = NULL;
|
||||
}
|
||||
return _journal;
|
||||
}
|
||||
|
||||
TJournalHeader& get_journal_header(int num, const char* op, const char* type)
|
||||
{
|
||||
static TJournalHeader jh;
|
||||
const int size = sizeof(TJournalHeader);
|
||||
CHECKD(size == 64, "Invalid journal header: ", size);
|
||||
|
||||
memset(&jh, 0, size);
|
||||
strcpy(jh._signature, "J00");
|
||||
jh._header_length = size;
|
||||
time(&jh._time);
|
||||
jh._firm = prefix().get_codditta();
|
||||
jh._logic_num = num;
|
||||
strcpy(jh._operation, op);
|
||||
strcpy(jh._type, type);
|
||||
jh._data_size = 0;
|
||||
return jh;
|
||||
}
|
||||
|
||||
void write_journal(TJournalHeader& jh, void* data, int len)
|
||||
{
|
||||
FILE* j = get_journal();
|
||||
jh._data_size = len;
|
||||
fwrite(&jh, sizeof(TJournalHeader), 1, j);
|
||||
fwrite(data, len, 1, j);
|
||||
fflush(j);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#define RECLOCKTYPES 0xFF00
|
||||
#define READTYPES 0x00FF
|
||||
#define INVFLD 255
|
||||
@ -1048,17 +1000,7 @@ int TBaseisamfile::_write(const TRectype& rec)
|
||||
memcpy(DB_getrecord(fhnd), rec.string(), dst_len);
|
||||
_lasterr = DB_add(fhnd);
|
||||
|
||||
if (_lasterr == NOERR)
|
||||
{
|
||||
#ifdef JOURNAL
|
||||
if (get_journal())
|
||||
{
|
||||
TJournalHeader& jh = get_journal_header(num(), "ADD", "REC");
|
||||
write_journal(jh, rec.string(), dst_len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
if (_lasterr != NOERR)
|
||||
_lasterr = get_error(_lasterr);
|
||||
|
||||
_recno = DB_recno(fhnd);
|
||||
@ -1121,16 +1063,7 @@ int TBaseisamfile::_rewrite(const TRectype& rec)
|
||||
memcpy(DB_getrecord(fhnd), rec.string(), len);
|
||||
_lasterr = DB_rewrite(fhnd);
|
||||
if (_lasterr == NOERR)
|
||||
{
|
||||
#ifdef JOURNAL
|
||||
if (get_journal())
|
||||
{
|
||||
TJournalHeader& jh = get_journal_header(num(), "MOD", "REC");
|
||||
write_journal(jh, rec.string(), len);
|
||||
}
|
||||
#endif
|
||||
rec_cache(_logicnum).notify_change();
|
||||
}
|
||||
else
|
||||
_lasterr = get_error(_lasterr);
|
||||
}
|
||||
@ -1194,8 +1127,7 @@ int TBaseisamfile::_remove(const TRectype& rec)
|
||||
CHECK(!rec.empty(), "Can't remove an empty record");
|
||||
|
||||
TRectype save_rec(rec);
|
||||
// Forza l'uso della chiave principale (per chiavi duplicate?)
|
||||
const int fhnd = handle(1);
|
||||
const int fhnd = handle(1); // Forza l'uso della chiave principale (per chiavi duplicate?)
|
||||
_lasterr = cisread(fhnd, 1, save_rec, _isequal + _nolock, _recno); // Si Posiziona per sicurezza...
|
||||
|
||||
if (_lasterr == NOERR)
|
||||
@ -1204,14 +1136,6 @@ int TBaseisamfile::_remove(const TRectype& rec)
|
||||
if (_lasterr == NOERR)
|
||||
{
|
||||
DB_flush(fhnd);
|
||||
#ifdef JOURNAL
|
||||
if (get_journal())
|
||||
{
|
||||
const int len = DB_reclen(fhnd);
|
||||
TJournalHeader& jh = get_journal_header(num(), "DEL", "REC");
|
||||
write_journal(jh, rec.string(), len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1220,7 +1144,7 @@ int TBaseisamfile::_remove(const TRectype& rec)
|
||||
}
|
||||
}
|
||||
|
||||
if(_lasterr == NOERR)
|
||||
if (_lasterr == NOERR)
|
||||
{
|
||||
if (curr().has_memo( ))
|
||||
curr().init_memo();
|
||||
@ -2107,19 +2031,20 @@ int TSystemisamfile::update(
|
||||
|
||||
if (dir.eod() > 0 && oldrec.len() > 0)
|
||||
{
|
||||
err = _open_ex(_excllock, FALSE);
|
||||
if (err != NOERR)
|
||||
return err;
|
||||
|
||||
// Apro il file destinazione in modo esclusivo e senza indici
|
||||
int tmpnum = num();
|
||||
TIsam_handle ishandle = prefix().open_isamfile(tmpnum, tmpfname, TRUE, FALSE);
|
||||
TCodeb_handle fhnd = ishandle > 0 ? prefix().get_handle(ishandle) : ishandle;
|
||||
if (fhnd < 0 )
|
||||
//int tmpnum = num();
|
||||
//TIsam_handle ishandle = prefix().open_isamfile(tmpnum, tmpfname, true, false);
|
||||
// TCodeb_handle fhnd = ishandle > 0 ? prefix().get_handle(ishandle) : ishandle;
|
||||
TCodeb_handle fhnd = DB_open(tmpfname, 1, 0);
|
||||
if (fhnd < 0)
|
||||
{
|
||||
err=get_error(fhnd);
|
||||
err = get_error(fhnd);
|
||||
return err;
|
||||
}
|
||||
|
||||
err = _open_ex(_excllock, false);
|
||||
if (err != NOERR)
|
||||
return err;
|
||||
|
||||
TString s(256); s << TR("Aggiornamento") << ' ' << fname;
|
||||
|
||||
@ -2180,14 +2105,29 @@ int TSystemisamfile::update(
|
||||
memcpy(DB_getrecord(fhnd),nrec.string(),lenr);
|
||||
err=DB_add(fhnd);
|
||||
if ( err == NOERR && memo_inside)
|
||||
nrec.write_memo(ishandle, DB_recno(fhnd));
|
||||
{
|
||||
// nrec.write_memo(ishandle, DB_recno(fhnd));
|
||||
for (j = outfld.last(); j >= 0; j = outfld.pred(j))
|
||||
{
|
||||
const TRecfield* in_fld = (const TRecfield*)infld.objptr(j);
|
||||
const TRecfield* out_fld = (const TRecfield*)outfld.objptr(j);
|
||||
if (in_fld != NULL && out_fld != NULL && out_fld->type() == _memofld)
|
||||
{
|
||||
const TFixed_string val(*in_fld);
|
||||
if (val.full())
|
||||
DB_memowrite(fhnd, out_fld->name(), val);
|
||||
}
|
||||
}
|
||||
DB_flush(fhnd);
|
||||
}
|
||||
if (err != NOERR)
|
||||
err=get_error(err);
|
||||
setstatus(err);
|
||||
|
||||
}
|
||||
close();
|
||||
prefix().close_isamfile(ishandle);
|
||||
//prefix().close_isamfile(ishandle);
|
||||
DB_close(fhnd);
|
||||
|
||||
if (err != NOERR)
|
||||
err = get_error(err);
|
||||
@ -3262,30 +3202,24 @@ void TRectype::init(int logicnum)
|
||||
else
|
||||
setempty(TRUE);
|
||||
|
||||
const bool has_memo_fld = _length > 0 && lf_has_memo(_logicnum);
|
||||
|
||||
if(has_memo_fld)
|
||||
if (_length > 0 && lf_has_memo(logicnum))
|
||||
init_memo(RECORD_NON_FISICO);
|
||||
}
|
||||
|
||||
TRectype::TRectype(int logicnum)
|
||||
: _memo_data(NULL)
|
||||
|
||||
{
|
||||
init(logicnum);
|
||||
}
|
||||
|
||||
|
||||
TRectype::TRectype(const TBaseisamfile* i)
|
||||
: _memo_data(NULL)
|
||||
{
|
||||
init(i->num());
|
||||
}
|
||||
|
||||
|
||||
TRectype::TRectype(const TRectype& r)
|
||||
:
|
||||
_memo_data(NULL)
|
||||
: _memo_data(NULL)
|
||||
|
||||
{
|
||||
init(r._logicnum);
|
||||
@ -3342,11 +3276,12 @@ void TRectype::write_memo(TIsam_handle file, const TRecnotype recno)
|
||||
CHECKD(recno >= 0, "Maiale! Non fare le GO con _recno < 0: ", recno);
|
||||
const TCodeb_handle cb_handle = prefix().get_handle(file);
|
||||
DB_go( cb_handle, recno);
|
||||
for( int i = _memo_data->last( ); i > 0; i = _memo_data->pred( i ) )
|
||||
FOR_EACH_ARRAY_ROW_BACK((*_memo_data), i, memo)
|
||||
{
|
||||
if (_memo_data->is_dirty(i))
|
||||
DB_memowrite( cb_handle, r.Fd[ i ].Name, _memo_data->row( i ) );
|
||||
DB_memowrite(cb_handle, r.Fd[i].Name, *memo);
|
||||
}
|
||||
DB_flush(cb_handle);
|
||||
*this = (const char*)DB_getrecord(cb_handle);
|
||||
init_memo(recno, file);
|
||||
}
|
||||
|
@ -392,7 +392,7 @@ int TFile_info::close_low()
|
||||
DB_close(_handle);
|
||||
_handle = -1;
|
||||
_last_key = -1;
|
||||
_exclusive = _locked = FALSE;
|
||||
_exclusive = _locked = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -412,12 +412,12 @@ int TFile_info::open(bool exclusive, bool index)
|
||||
if (_ref_count > 0 || is_open())
|
||||
{
|
||||
#ifdef DBG
|
||||
if (_ref_count > 0)
|
||||
if (_ref_count > 0 && (_exclusive || _locked))
|
||||
error_box("You shouldn't reopen file %d exclusively", num());
|
||||
#endif
|
||||
close_low();
|
||||
}
|
||||
_exclusive = _locked = TRUE;
|
||||
_exclusive = _locked = true; // shouldn't be exclusive instead of true?
|
||||
err = open_low(exclusive, index);
|
||||
}
|
||||
touch(); // Memorizza ora apertura del file
|
||||
@ -431,7 +431,7 @@ int TFile_info::close()
|
||||
if (_ref_count > 0)
|
||||
{
|
||||
_ref_count--;
|
||||
if (_ref_count == 0)
|
||||
if (_ref_count == 0 || _exclusive)
|
||||
{
|
||||
if (is_open())
|
||||
{
|
||||
@ -477,10 +477,10 @@ int TFile_info::auto_open(int key)
|
||||
}
|
||||
|
||||
void TFile_info::lock_record(TRecnotype)
|
||||
{ _locked = TRUE; }
|
||||
{ _locked = true; }
|
||||
|
||||
void TFile_info::unlock_record(TRecnotype)
|
||||
{ _locked = FALSE; }
|
||||
{ _locked = false; }
|
||||
|
||||
const TFilename& TFile_info::load_filedes()
|
||||
{
|
||||
@ -488,10 +488,7 @@ const TFilename& TFile_info::load_filedes()
|
||||
CGetFile(num(), &_filedes, _nolock, _nordir);
|
||||
if (_filedes.SysName[0] > ' ')
|
||||
{
|
||||
if (_filedes.SysName[0] != '$')
|
||||
_dir = _comdir;
|
||||
else
|
||||
_dir = _nordir;
|
||||
_dir = _filedes.SysName[0] != '$' ? _comdir : _nordir;
|
||||
_name = CAddPref(_filedes.SysName);
|
||||
strncpy(_filedes.Des, dictionary_translate(_filedes.Des), sizeof(_filedes.Des)-1);
|
||||
}
|
||||
@ -665,7 +662,7 @@ TIsam_handle TFile_manager::get_handle(TFilename& name)
|
||||
TIsam_handle TFile_manager::open(int& logicnum, TFilename& name, bool exclusive, bool index)
|
||||
{
|
||||
TIsam_handle num = logicnum;
|
||||
if (name.not_empty())
|
||||
if (name.full())
|
||||
{
|
||||
num = get_handle(name);
|
||||
if (logicnum >= LF_EXTERNAL)
|
||||
@ -768,7 +765,6 @@ const RecDes& TFile_manager::get_recdes(int logicnum) const
|
||||
TToken_string& TFile_manager::get_relation(int fromlogic, int tologic) const
|
||||
{
|
||||
TRecord_info& i = recinfo(fromlogic);
|
||||
|
||||
return i.relation(tologic);
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,24 @@
|
||||
#include <tabutil.h>
|
||||
#include <user.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TFast_isamfile
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
class TFast_isamfile : public TIsamfile
|
||||
{
|
||||
public:
|
||||
TFast_isamfile(int logicnum);
|
||||
~TFast_isamfile() { close(); }
|
||||
};
|
||||
|
||||
TFast_isamfile::TFast_isamfile(int logicnum) : TIsamfile(logicnum)
|
||||
{
|
||||
int err = open(_excllock);
|
||||
if (err != NOERR)
|
||||
err = open(_manulock);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TRecord_Array
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -329,14 +347,13 @@ int TRecord_array::read(const TRectype& filter)
|
||||
return read(f);
|
||||
}
|
||||
|
||||
int TRecord_array::remove_from(int pos) const
|
||||
int TRecord_array::remove_from(TIsamfile& f, int pos) const
|
||||
{
|
||||
int err = NOERR;
|
||||
|
||||
TRectype* rec = (TRectype*)key().dup();
|
||||
CHECK(!rec->empty(), "Can't use empty key");
|
||||
|
||||
TLocalisamfile f(_file);
|
||||
rec->put(_num, pos);
|
||||
for (int e = rec->read(f, _isgteq); e == NOERR && good(*rec); e = rec->next(f))
|
||||
{
|
||||
@ -356,6 +373,11 @@ int TRecord_array::remove_from(int pos) const
|
||||
return err;
|
||||
}
|
||||
|
||||
int TRecord_array::remove_from(int pos) const
|
||||
{
|
||||
TFast_isamfile f(_file);
|
||||
return remove_from(f, pos);
|
||||
}
|
||||
|
||||
int TRecord_array::write(bool re) const
|
||||
{
|
||||
@ -363,10 +385,10 @@ int TRecord_array::write(bool re) const
|
||||
int last_on_file = 0; // Last record found on file
|
||||
int err = NOERR;
|
||||
|
||||
TLocalisamfile f(_file);
|
||||
TFast_isamfile f(_file);
|
||||
|
||||
const int u = _data.last();
|
||||
|
||||
//TRectype* rec = (TRectype*)key().dup();
|
||||
CHECK(u<1 || !key().empty(), "Can't write rows using an empty key");
|
||||
int i;
|
||||
for (i = 1; i <= u; i++)
|
||||
@ -430,9 +452,9 @@ int TRecord_array::write(bool re) const
|
||||
|
||||
// Cancella eventuali residui successivi
|
||||
if (err == NOERR && last_on_file != EOR)
|
||||
remove_from(i + _offset);
|
||||
|
||||
return err;
|
||||
remove_from(f, i + _offset);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int TRecord_array::remove() const
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include <isam.h>
|
||||
#endif
|
||||
|
||||
#include <user.h>
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// TRecord_Array
|
||||
///////////////////////////////////////////////////////////
|
||||
@ -48,6 +46,9 @@ protected:
|
||||
bool good(const TRectype& rec) const;
|
||||
// @cmember Duplica un record array
|
||||
virtual TObject* dup() const { return new TRecord_array(*this);}
|
||||
|
||||
int remove_from(TIsamfile& f, int pos) const;
|
||||
|
||||
// @access Public Member
|
||||
public:
|
||||
// @cmember Ritorna il record che fa da chiave per tutti gli altri
|
||||
|
@ -960,6 +960,15 @@ bool TRelation_application::find(word k)
|
||||
return err == NOERR;
|
||||
}
|
||||
|
||||
void TRelation_application::edit_cancel()
|
||||
{
|
||||
if (_mask->mode() == MODE_MOD)
|
||||
{
|
||||
TRelation* rel = get_relation();
|
||||
rel->restore_status();
|
||||
rel->lfile().reread(_unlock); // Unlock main file
|
||||
}
|
||||
}
|
||||
|
||||
bool TRelation_application::save(bool check_dirty)
|
||||
{
|
||||
@ -967,7 +976,10 @@ bool TRelation_application::save(bool check_dirty)
|
||||
|
||||
int pos = _mask->id2pos(DLG_SAVEREC);
|
||||
if (pos < 0 || !_mask->fld(pos).active())
|
||||
return TRUE;
|
||||
{
|
||||
edit_cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
int err = NOERR;
|
||||
const int mode = _mask->mode();
|
||||
@ -983,12 +995,8 @@ bool TRelation_application::save(bool check_dirty)
|
||||
|
||||
if (!dirty && !was_dirty)
|
||||
{
|
||||
if (mode == MODE_MOD)
|
||||
{
|
||||
get_relation()->restore_status();
|
||||
get_relation()->lfile().reread(_unlock); // Unlock main file
|
||||
}
|
||||
return TRUE;
|
||||
edit_cancel();
|
||||
return true;
|
||||
}
|
||||
|
||||
const KEY last = _mask->last_key();
|
||||
@ -1035,13 +1043,9 @@ bool TRelation_application::save(bool check_dirty)
|
||||
k = yesnocancel_box(TR("Si desidera registrare?"));
|
||||
|
||||
if (k == K_ESC || k == K_NO)
|
||||
{
|
||||
if (mode == MODE_MOD)
|
||||
{
|
||||
get_relation()->restore_status();
|
||||
get_relation()->lfile().reread(_unlock); // Unlock main file
|
||||
}
|
||||
was_dirty = FALSE;
|
||||
{
|
||||
edit_cancel();
|
||||
was_dirty = false;
|
||||
return k == K_NO;
|
||||
}
|
||||
|
||||
|
@ -170,6 +170,8 @@ protected:
|
||||
// @cmember Richiede la maschera da usare
|
||||
virtual TMask* get_mask(int mode) pure;
|
||||
|
||||
// @cmember:(INTERNAL) Annulla la modifica di un record: toglie il lock
|
||||
void edit_cancel();
|
||||
// @cmember:(INTERNAL) Salva i contenuti della maschera su file
|
||||
virtual bool save(bool check_dirty);
|
||||
// @cmember Legge dalla relazione i valori nella maschera <p m>
|
||||
@ -189,7 +191,7 @@ protected:
|
||||
virtual const char* get_next_key()
|
||||
{ return ""; }
|
||||
virtual bool get_next_key(TToken_string& key)
|
||||
{ return FALSE; }
|
||||
{ return false; }
|
||||
|
||||
// @cmember Richiede se il record corrente e' protetto (non cancellabile)
|
||||
virtual bool protected_record(TRectype&)
|
||||
|
@ -158,7 +158,7 @@ bool TLog_report::log(int sev, const char* msg)
|
||||
return ok;
|
||||
}
|
||||
|
||||
TLog_report::TLog_report(const char* title, const char* name)
|
||||
TLog_report::TLog_report(const char* title, const char* name) : _kill_duplicates(false)
|
||||
{
|
||||
load(name);
|
||||
if (recordset() == NULL)
|
||||
|
Loading…
x
Reference in New Issue
Block a user