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:
guy 2009-01-07 15:50:52 +00:00
parent f318b43a1e
commit e2a19d9e23
8 changed files with 290 additions and 328 deletions

View File

@ -37,12 +37,10 @@
static CODE4 code_base; static CODE4 code_base;
static DATA4* dbdata[CB4FILES]; static DATA4* dbdata[CB4FILES];
static bool dbfast[CB4FILES];
static bool handle_ok(int handle) #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
return handle >= 0 && handle < CB4FILES &&
dbdata[handle] != NULL && dbdata[handle]->clientId >= 0;
}
static const char* find_slash_backslash(const char* s) static const char* find_slash_backslash(const char* s)
{ {
@ -77,6 +75,7 @@ void DB_init(void)
code_base.lockAttempts=1; code_base.lockAttempts=1;
code4dateFormatSet(&code_base, "CCYYMMDD"); code4dateFormatSet(&code_base, "CCYYMMDD");
code_base.optimize = OPT4EXCLUSIVE; // Is the default?
code_base.optimizeWrite = OPT4EXCLUSIVE; // Is the default? code_base.optimizeWrite = OPT4EXCLUSIVE; // Is the default?
} }
@ -91,7 +90,7 @@ void DB_exit(void)
int i; 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); DB_close(i);
} }
code4initUndo(&code_base); code4initUndo(&code_base);
@ -101,11 +100,10 @@ void DB_exit(void)
apertura del file 'filename'. Il parametro mode consente se != 0 l'apertura apertura del file 'filename'. Il parametro mode consente se != 0 l'apertura
esclusiva. Il parametro index consente se == 0 l'apertura senza indici esclusiva. Il parametro index consente se == 0 l'apertura senza indici
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_open(const char *filename,int mode,int index) int DB_open(const char *filename,int mode,int index)
{ {
int i,found; int i,found;
if (mode)
code_base.accessMode=1; // Exclusive mode
/* cerca il primo posto libero nel vettore dbdata */ /* cerca il primo posto libero nel vettore dbdata */
found=-1; found=-1;
for(i=0;i<CB4FILES;i++) for(i=0;i<CB4FILES;i++)
@ -116,23 +114,39 @@ int DB_open(const char *filename,int mode,int index)
break; break;
} }
} }
/* se non ci sono posti liberi torna -1 */ if (found >= 0)
if(found==-1) {
return(found); if (mode)
code_base.accessMode=1; // Exclusive mode
code_base.errorCode=0; code_base.errorCode=0;
if (index == 0) /* Se e' stata richiesta l'apertura senza indici, setta il flag */ if (!index)
code_base.autoOpen = 0; {
code_base.autoOpen = 0; // Se e' stata richiesta l'apertura senza indici, resetta il flag autoOpen
dbdata[found]=d4open(&code_base, filename); dbdata[found]=d4open(&code_base, filename);
if (index == 0) /* Restore the configuration of opening indexes*/
code_base.autoOpen = 1; code_base.autoOpen = 1;
if(dbdata[found]==0) }
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 code_base.errorCode;
code_base.accessMode=0; }
d4tagSelect(dbdata[found],d4tagDefault(dbdata[found])); return found;
if (d4recCount(dbdata[found]) > 0)
d4top(dbdata[found]);
return(found);
} }
@ -142,12 +156,13 @@ int DB_open(const char *filename,int mode,int index)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_close(int handle) int DB_close(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
d4close(dbdata[handle]); d4close(data);
dbdata[handle]=(DATA4 *) 0; dbdata[handle] = NULL;
dbfast[handle] = FALSE;
code_base.errorCode=0; code_base.errorCode=0;
return(0); return 0;
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -156,8 +171,8 @@ int DB_close(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
char* DB_getrecord(int handle) char* DB_getrecord(int handle)
{ {
if(!handle_ok(handle)) return((char *) 0); HANDLE2DATASTR(handle, data);
return(d4record(dbdata[handle])); return d4record(data);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -165,8 +180,8 @@ char *DB_getrecord(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_reclen(int handle) int DB_reclen(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return((int) d4recWidth(dbdata[handle])); return (int)d4recWidth(data);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -175,7 +190,8 @@ int DB_reclen(int handle)
int DB_keylen(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) long int DB_recno(int handle)
{ {
if(!handle_ok(handle)) return(-1L); HANDLE2DATA(handle, data);
return(d4recNo(dbdata[handle])); return d4recNo(data);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -192,8 +208,8 @@ long int DB_recno(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
long int DB_reccount(int handle) long int DB_reccount(int handle)
{ {
if(!handle_ok(handle)) return(-1L); HANDLE2DATA(handle, data);
return(d4recCount(dbdata[handle])); return d4recCount(data);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -205,16 +221,19 @@ int DB_tagselect(int handle,int index_no)
TAG4 *tt; TAG4 *tt;
int i; int i;
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
/* si posiziona sul primo indice */ /* si posiziona sul primo indice */
tt=d4tagNext(dbdata[handle],NULL); tt=d4tagNext(data, NULL);
if(tt==NULL) return(-1); if (tt==NULL)
for(i=1;i<index_no;i++) { return -1;
tt=d4tagNext(dbdata[handle],tt); for(i=1; i<index_no; i++)
if(tt==NULL) return(-1); {
tt=d4tagNext(data, tt);
if(tt==NULL)
return(-1);
} }
d4tagSelect(dbdata[handle],tt); d4tagSelect(data, tt);
return(0); return 0;
} }
@ -226,16 +245,18 @@ int DB_tagget(int handle)
{ {
TAG4 *tt,*tt1; TAG4 *tt,*tt1;
int i; int i;
HANDLE2DATA(handle, data);
if(!handle_ok(handle)) return(-1);
/* si posiziona sul primo indice */ /* si posiziona sul primo indice */
tt=d4tagDefault(dbdata[handle]); tt=d4tagDefault(data);
if(tt==NULL) return(-1); if(tt==NULL)
return(-1);
tt1=d4tagNext(dbdata[handle],NULL); tt1=d4tagNext(data,NULL);
i=1; i=1;
while(tt!=tt1 && tt1!=NULL) { while(tt!=tt1 && tt1!=NULL)
tt1=d4tagNext(dbdata[handle],tt1); {
tt1=d4tagNext(data,tt1);
i++; i++;
} }
return(i); return(i);
@ -247,8 +268,8 @@ int DB_tagget(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_first(int handle) int DB_first(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return(d4top(dbdata[handle])); return d4top(data);
} }
@ -258,8 +279,8 @@ int DB_first(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_last(int handle) int DB_last(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return(d4bottom(dbdata[handle])); return d4bottom(data);
} }
@ -268,8 +289,7 @@ int DB_last(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_next(int handle) int DB_next(int handle)
{ {
if(!handle_ok(handle)) return(-1); return DB_skip(handle, +1);
return(d4skip(dbdata[handle],1L));
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -277,18 +297,16 @@ int DB_next(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_prev(int handle) int DB_prev(int handle)
{ {
if(!handle_ok(handle)) return(-1); return DB_skip(handle, -1);
return(d4skip(dbdata[handle],-1L));
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
skip di n records 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); HANDLE2DATA(handle, data);
return(d4skip(dbdata[handle],recno)); return d4skip(data, recno);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -296,8 +314,8 @@ int DB_skip(int handle,long int recno)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_lock(int handle) int DB_lock(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return(d4lock(dbdata[handle],d4recNo(dbdata[handle]))); return d4lock(data, d4recNo(data));
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -305,8 +323,8 @@ int DB_lock(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_unlock(int handle) int DB_unlock(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return(d4unlock(dbdata[handle])); return d4unlock(data);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -318,12 +336,12 @@ int DB_seek(int handle,char *key)
int rc, len; int rc, len;
const char * k; const char * k;
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
rc = d4seek(dbdata[handle],key); rc = d4seek(data,key);
if (rc) if (rc)
return rc; return rc;
len = a4tagKeyLen(dbdata[handle]); len = a4tagKeyLen(data);
k = a4tagKey(dbdata[handle]); k = a4tagKey(data);
while (len > 0 && k[len-1] == ' ') len--; while (len > 0 && k[len-1] == ' ') len--;
rc = strncmp(key, k, len); rc = strncmp(key, k, len);
if (rc == 0) if (rc == 0)
@ -340,8 +358,8 @@ int DB_seek(int handle,char *key)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_eof(int handle) int DB_eof(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return(d4eof(dbdata[handle])); return d4eof(data);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -349,8 +367,8 @@ int DB_eof(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_bof(int handle) int DB_bof(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return(d4bof(dbdata[handle])); return d4bof(data);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -358,8 +376,8 @@ int DB_bof(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_go(int handle,long recno) int DB_go(int handle,long recno)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return(d4go(dbdata[handle],recno)); return d4go(data,recno);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -367,10 +385,9 @@ int DB_go(int handle,long recno)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_delete(int handle) int DB_delete(int handle)
{ {
HANDLE2DATA(handle, data);
if(!handle_ok(handle)) return(-1); d4delete(data);
d4delete(dbdata[handle]); return 0;
return(0);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -378,10 +395,9 @@ int DB_delete(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_recall(int handle) int DB_recall(int handle)
{ {
HANDLE2DATA(handle, data);
if(!handle_ok(handle)) return(-1); d4recall(data);
d4recall(dbdata[handle]); return 0;
return(0);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -389,9 +405,19 @@ int DB_recall(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_flush(int handle) int DB_flush(int handle)
{ {
int rt; int rt = 0;
while ((rt = d4flush(dbdata[handle])) == r4locked) HANDLE2DATA(handle, data);
if (dbfast[handle])
{
if (data->dataFile->nFieldsMemo > 0)
rt = d4write(data, -1);
}
else
{
while ((rt = d4flush(data)) == r4locked)
u4delaySec(); u4delaySec();
}
return rt; return rt;
} }
@ -400,9 +426,9 @@ int DB_flush(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_rewrite(int handle) int DB_rewrite(int handle)
{ {
int rt; int rt = -1;
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
while ((rt=d4write(dbdata[handle],d4recNo(dbdata[handle]))) == r4locked) while ((rt=d4write(data,d4recNo(data))) == r4locked)
u4delaySec(); u4delaySec();
if (rt == e4unique) if (rt == e4unique)
@ -410,7 +436,7 @@ int DB_rewrite(int handle)
char msg[256]; char msg[256];
DB_get_error(); DB_get_error();
sprintf(msg, "Errore in DB_rewrite(): chiave duplicata nel record %ld, file %s", 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); xvt_dm_post_fatal_exit(msg);
} }
@ -426,13 +452,12 @@ int DB_rewrite(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_add(int handle) int DB_add(int handle)
{ {
int rt; int rt = -1;
DATA4 * data = dbdata[handle]; HANDLE2DATA(handle, data);
if (data==0) return(-1);
while ((rt = d4appendStart(data,0)) == r4locked) while ((rt = d4appendStart(data,0)) == r4locked)
u4delaySec(); u4delaySec();
if (rt == 0) if (rt == 0)
{ {
d4recall(data); d4recall(data);
@ -440,8 +465,7 @@ int DB_add(int handle)
u4delaySec(); u4delaySec();
if (rt == e4unique) if (rt == e4unique)
{ {
long rec_num = d4recNo(data); const long rec_num = d4recNo(data);
DB_get_error(); DB_get_error();
if (rec_num > 0) 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 DB_lockfile(int handle)
{ {
int rt = -1; int rt = -1;
if(handle_ok(handle)) HANDLE2DATA(handle, data);
{ rt = d4lockFile(data);
rt = d4lockFile(dbdata[handle]);
if (rt==0) if (rt==0)
rt=d4lockIndex(dbdata[handle]); rt = d4lockIndex(data);
}
return rt; 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 */ for (i=0; ((i<r->NFields) && (i<MaxFields)); i++) /* Construct field_info */
{ {
field_info[i].name = (char*)u4alloc(16); // In realtà basterebbero 12 field_info[i].name = (char*)r->Fd[i].Name;
strcpy(field_info[i].name,r->Fd[i].Name);
field_info[i].len = r->Fd[i].Len; field_info[i].len = r->Fd[i].Len;
field_info[i].dec = r->Fd[i].Dec; field_info[i].dec = r->Fd[i].Dec;
switch (r->Fd[i].TypeF) 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); 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; rt=code_base.errorCode;
else else
rt=d4close(dbuilded); 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) if (rt!=0)
rt=code_base.errorCode; 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++) for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++)
{ {
u4free((char *) tag_info[i].name); u4free((char *) tag_info[i].name);
@ -997,13 +1001,14 @@ void DB_zero_error(void)
int DB_index_seek(int handle, const char* from) int DB_index_seek(int handle, const char* from)
{ {
TAG4 *t; TAG4* t = NULL;
HANDLE2DATA(handle, data);
if(!handle_ok(handle)) return(-1); t = d4tagDefault(data);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); if (t==NULL)
return -1;
if (tfile4seek(t->tagFile,from,strlen(from)) < 0) return(DB_get_error()); if (tfile4seek(t->tagFile, from, strlen(from)) < 0)
return(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) long DB_index_recno(int handle)
{ {
TAG4 *t; TAG4 *t;
HANDLE2DATA(handle, data);
t=d4tagDefault(data);
if (t==NULL)
return(-1);
if(!handle_ok(handle)) return(-1); return tfile4recNo(t->tagFile);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1);
return(tfile4recNo(t->tagFile));
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1027,11 +1033,11 @@ long DB_index_recno(int handle)
long DB_index_next(int handle) long DB_index_next(int handle)
{ {
TAG4 *t; TAG4 *t;
HANDLE2DATA(handle, data);
if(!handle_ok(handle)) return(-1); t = d4tagDefault(data);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); if (t==NULL)
return -1;
return(tfile4skip(t->tagFile,1L)); return tfile4skip(t->tagFile,1L);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1040,18 +1046,17 @@ long DB_index_next(int handle)
char* DB_index_getkey(int handle) char* DB_index_getkey(int handle)
{ {
static char* key = NULL; static char key[MAXLEN];
TAG4 *t; TAG4 *t;
int klen; int klen;
if (key == NULL) HANDLE2DATASTR(handle, data);
key = malloc(MAXLEN);
if(!handle_ok(handle)) if ((t=d4tagDefault(data))==NULL)
return(NULL); return(NULL);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(NULL); klen=a4tagKeyLen(data);
klen=a4tagKeyLen(dbdata[handle]);
if (klen > (MAXLEN-1)) klen=MAXLEN-1; 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'; key[klen]='\0';
return key; return key;
} }
@ -1061,12 +1066,12 @@ char* DB_index_getkey(int handle)
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_index_go(int handle, const char* key, long recno) int DB_index_go(int handle, const char* key, long recno)
{ {
TAG4 *t; TAG4* t = NULL;
HANDLE2DATA(handle, data);
if(!handle_ok(handle)) return(-1); t = d4tagDefault(data);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); if (t==NULL)
return -1;
return(tfile4go(t->tagFile, key, recno, FALSE)); return tfile4go(t->tagFile, key, recno, FALSE);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1075,11 +1080,12 @@ int DB_index_go(int handle, const char* key, long recno)
int DB_index_eof(int handle) int DB_index_eof(int handle)
{ {
TAG4 *t; TAG4* t = NULL;
HANDLE2DATA(handle, data);
if(!handle_ok(handle)) return(-1); t = d4tagDefault(data);
if ((t=d4tagDefault(dbdata[handle]))==NULL) return(-1); if (t==NULL)
return(tfile4eof(t->tagFile)); return -1;
return tfile4eof(t->tagFile);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1088,9 +1094,8 @@ int DB_index_eof(int handle)
int DB_lock_rec(int handle, long nrec) int DB_lock_rec(int handle, long nrec)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
if(d4lock(dbdata[handle],nrec)==r4locked) return(-1); return d4lock(data, nrec)==r4locked ? -1 : 0;
else return(0);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1098,11 +1103,10 @@ int DB_lock_rec(int handle,long nrec)
in modo esclusivo dalla presente applicazione, non da altri programmi!!! in modo esclusivo dalla presente applicazione, non da altri programmi!!!
--------------------------------------------------------------------------*/ --------------------------------------------------------------------------*/
int DB_file_locked(int handle) int DB_file_locked(int handle)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return a4lockTest(dbdata[handle]); return a4lockTest(data);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1112,8 +1116,8 @@ int DB_file_locked(int handle)
int DB_rec_locked(int handle, long nrec) int DB_rec_locked(int handle, long nrec)
{ {
if(!handle_ok(handle)) return(-1); HANDLE2DATA(handle, data);
return(d4lockTest(dbdata[handle],nrec)); return d4lockTest(data,nrec);
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1122,7 +1126,7 @@ int DB_rec_locked(int handle,long nrec)
long DB_getconf() long DB_getconf()
{ {
return(u4switch()); return u4switch();
} }
/*------------------------------------------------------------------------- /*-------------------------------------------------------------------------
@ -1131,26 +1135,24 @@ long DB_getconf()
long DB_changed(int handle) long DB_changed(int handle)
{ {
return(a4indexVersion(dbdata[handle])); HANDLE2DATA(handle, data);
return a4indexVersion(data);
} }
char* DB_memoptr( const int handle, const char * fieldname ) char* DB_memoptr( const int handle, const char * fieldname )
{ {
FIELD4* f = d4field( dbdata[ handle ], fieldname ); FIELD4* f = NULL;
HANDLE2DATASTR(handle, data);
f = d4field(data, fieldname);
return f4memoPtr(f); 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 ); FIELD4* f = NULL;
int ret = f4memoAssign( f, data ); HANDLE2DATA(handle, data);
f = d4field(data, fieldname);
if (ret == 0) return f4memoAssign(f, memo);
{
d4flush(dbdata[handle]);
d4unlock(dbdata[handle]);
}
return ret;
} }
long DB_version(char* str, int maxstr) long DB_version(char* str, int maxstr)

View File

@ -30,54 +30,6 @@
#include <codeb.h> #include <codeb.h>
#include <nditte.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 RECLOCKTYPES 0xFF00
#define READTYPES 0x00FF #define READTYPES 0x00FF
#define INVFLD 255 #define INVFLD 255
@ -1048,17 +1000,7 @@ int TBaseisamfile::_write(const TRectype& rec)
memcpy(DB_getrecord(fhnd), rec.string(), dst_len); memcpy(DB_getrecord(fhnd), rec.string(), dst_len);
_lasterr = DB_add(fhnd); _lasterr = DB_add(fhnd);
if (_lasterr == NOERR) 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
_lasterr = get_error(_lasterr); _lasterr = get_error(_lasterr);
_recno = DB_recno(fhnd); _recno = DB_recno(fhnd);
@ -1121,16 +1063,7 @@ int TBaseisamfile::_rewrite(const TRectype& rec)
memcpy(DB_getrecord(fhnd), rec.string(), len); memcpy(DB_getrecord(fhnd), rec.string(), len);
_lasterr = DB_rewrite(fhnd); _lasterr = DB_rewrite(fhnd);
if (_lasterr == NOERR) 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(); rec_cache(_logicnum).notify_change();
}
else else
_lasterr = get_error(_lasterr); _lasterr = get_error(_lasterr);
} }
@ -1194,8 +1127,7 @@ int TBaseisamfile::_remove(const TRectype& rec)
CHECK(!rec.empty(), "Can't remove an empty record"); CHECK(!rec.empty(), "Can't remove an empty record");
TRectype save_rec(rec); TRectype save_rec(rec);
// Forza l'uso della chiave principale (per chiavi duplicate?) const int fhnd = handle(1); // Forza l'uso della chiave principale (per chiavi duplicate?)
const int fhnd = handle(1);
_lasterr = cisread(fhnd, 1, save_rec, _isequal + _nolock, _recno); // Si Posiziona per sicurezza... _lasterr = cisread(fhnd, 1, save_rec, _isequal + _nolock, _recno); // Si Posiziona per sicurezza...
if (_lasterr == NOERR) if (_lasterr == NOERR)
@ -1204,14 +1136,6 @@ int TBaseisamfile::_remove(const TRectype& rec)
if (_lasterr == NOERR) if (_lasterr == NOERR)
{ {
DB_flush(fhnd); 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 else
{ {
@ -2107,20 +2031,21 @@ int TSystemisamfile::update(
if (dir.eod() > 0 && oldrec.len() > 0) 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 // Apro il file destinazione in modo esclusivo e senza indici
int tmpnum = num(); //int tmpnum = num();
TIsam_handle ishandle = prefix().open_isamfile(tmpnum, tmpfname, TRUE, FALSE); //TIsam_handle ishandle = prefix().open_isamfile(tmpnum, tmpfname, true, false);
TCodeb_handle fhnd = ishandle > 0 ? prefix().get_handle(ishandle) : ishandle; // TCodeb_handle fhnd = ishandle > 0 ? prefix().get_handle(ishandle) : ishandle;
TCodeb_handle fhnd = DB_open(tmpfname, 1, 0);
if (fhnd < 0) if (fhnd < 0)
{ {
err = get_error(fhnd); err = get_error(fhnd);
return err; return err;
} }
err = _open_ex(_excllock, false);
if (err != NOERR)
return err;
TString s(256); s << TR("Aggiornamento") << ' ' << fname; TString s(256); s << TR("Aggiornamento") << ' ' << fname;
const TRecnotype nitems = items(); const TRecnotype nitems = items();
@ -2180,14 +2105,29 @@ int TSystemisamfile::update(
memcpy(DB_getrecord(fhnd),nrec.string(),lenr); memcpy(DB_getrecord(fhnd),nrec.string(),lenr);
err=DB_add(fhnd); err=DB_add(fhnd);
if ( err == NOERR && memo_inside) 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) if (err != NOERR)
err=get_error(err); err=get_error(err);
setstatus(err); setstatus(err);
} }
close(); close();
prefix().close_isamfile(ishandle); //prefix().close_isamfile(ishandle);
DB_close(fhnd);
if (err != NOERR) if (err != NOERR)
err = get_error(err); err = get_error(err);
@ -3262,30 +3202,24 @@ void TRectype::init(int logicnum)
else else
setempty(TRUE); setempty(TRUE);
const bool has_memo_fld = _length > 0 && lf_has_memo(_logicnum); if (_length > 0 && lf_has_memo(logicnum))
if(has_memo_fld)
init_memo(RECORD_NON_FISICO); init_memo(RECORD_NON_FISICO);
} }
TRectype::TRectype(int logicnum) TRectype::TRectype(int logicnum)
: _memo_data(NULL) : _memo_data(NULL)
{ {
init(logicnum); init(logicnum);
} }
TRectype::TRectype(const TBaseisamfile* i) TRectype::TRectype(const TBaseisamfile* i)
: _memo_data(NULL) : _memo_data(NULL)
{ {
init(i->num()); init(i->num());
} }
TRectype::TRectype(const TRectype& r) TRectype::TRectype(const TRectype& r)
: : _memo_data(NULL)
_memo_data(NULL)
{ {
init(r._logicnum); 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); CHECKD(recno >= 0, "Maiale! Non fare le GO con _recno < 0: ", recno);
const TCodeb_handle cb_handle = prefix().get_handle(file); const TCodeb_handle cb_handle = prefix().get_handle(file);
DB_go( cb_handle, recno); 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)) 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); *this = (const char*)DB_getrecord(cb_handle);
init_memo(recno, file); init_memo(recno, file);
} }

View File

@ -392,7 +392,7 @@ int TFile_info::close_low()
DB_close(_handle); DB_close(_handle);
_handle = -1; _handle = -1;
_last_key = -1; _last_key = -1;
_exclusive = _locked = FALSE; _exclusive = _locked = false;
} }
else else
{ {
@ -412,12 +412,12 @@ int TFile_info::open(bool exclusive, bool index)
if (_ref_count > 0 || is_open()) if (_ref_count > 0 || is_open())
{ {
#ifdef DBG #ifdef DBG
if (_ref_count > 0) if (_ref_count > 0 && (_exclusive || _locked))
error_box("You shouldn't reopen file %d exclusively", num()); error_box("You shouldn't reopen file %d exclusively", num());
#endif #endif
close_low(); close_low();
} }
_exclusive = _locked = TRUE; _exclusive = _locked = true; // shouldn't be exclusive instead of true?
err = open_low(exclusive, index); err = open_low(exclusive, index);
} }
touch(); // Memorizza ora apertura del file touch(); // Memorizza ora apertura del file
@ -431,7 +431,7 @@ int TFile_info::close()
if (_ref_count > 0) if (_ref_count > 0)
{ {
_ref_count--; _ref_count--;
if (_ref_count == 0) if (_ref_count == 0 || _exclusive)
{ {
if (is_open()) if (is_open())
{ {
@ -477,10 +477,10 @@ int TFile_info::auto_open(int key)
} }
void TFile_info::lock_record(TRecnotype) void TFile_info::lock_record(TRecnotype)
{ _locked = TRUE; } { _locked = true; }
void TFile_info::unlock_record(TRecnotype) void TFile_info::unlock_record(TRecnotype)
{ _locked = FALSE; } { _locked = false; }
const TFilename& TFile_info::load_filedes() const TFilename& TFile_info::load_filedes()
{ {
@ -488,10 +488,7 @@ const TFilename& TFile_info::load_filedes()
CGetFile(num(), &_filedes, _nolock, _nordir); CGetFile(num(), &_filedes, _nolock, _nordir);
if (_filedes.SysName[0] > ' ') if (_filedes.SysName[0] > ' ')
{ {
if (_filedes.SysName[0] != '$') _dir = _filedes.SysName[0] != '$' ? _comdir : _nordir;
_dir = _comdir;
else
_dir = _nordir;
_name = CAddPref(_filedes.SysName); _name = CAddPref(_filedes.SysName);
strncpy(_filedes.Des, dictionary_translate(_filedes.Des), sizeof(_filedes.Des)-1); 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 TFile_manager::open(int& logicnum, TFilename& name, bool exclusive, bool index)
{ {
TIsam_handle num = logicnum; TIsam_handle num = logicnum;
if (name.not_empty()) if (name.full())
{ {
num = get_handle(name); num = get_handle(name);
if (logicnum >= LF_EXTERNAL) 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 TToken_string& TFile_manager::get_relation(int fromlogic, int tologic) const
{ {
TRecord_info& i = recinfo(fromlogic); TRecord_info& i = recinfo(fromlogic);
return i.relation(tologic); return i.relation(tologic);
} }

View File

@ -4,6 +4,24 @@
#include <tabutil.h> #include <tabutil.h>
#include <user.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 // TRecord_Array
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -329,14 +347,13 @@ int TRecord_array::read(const TRectype& filter)
return read(f); return read(f);
} }
int TRecord_array::remove_from(int pos) const int TRecord_array::remove_from(TIsamfile& f, int pos) const
{ {
int err = NOERR; int err = NOERR;
TRectype* rec = (TRectype*)key().dup(); TRectype* rec = (TRectype*)key().dup();
CHECK(!rec->empty(), "Can't use empty key"); CHECK(!rec->empty(), "Can't use empty key");
TLocalisamfile f(_file);
rec->put(_num, pos); rec->put(_num, pos);
for (int e = rec->read(f, _isgteq); e == NOERR && good(*rec); e = rec->next(f)) 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; 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 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 last_on_file = 0; // Last record found on file
int err = NOERR; int err = NOERR;
TLocalisamfile f(_file); TFast_isamfile f(_file);
const int u = _data.last(); const int u = _data.last();
//TRectype* rec = (TRectype*)key().dup();
CHECK(u<1 || !key().empty(), "Can't write rows using an empty key"); CHECK(u<1 || !key().empty(), "Can't write rows using an empty key");
int i; int i;
for (i = 1; i <= u; i++) for (i = 1; i <= u; i++)
@ -430,7 +452,7 @@ int TRecord_array::write(bool re) const
// Cancella eventuali residui successivi // Cancella eventuali residui successivi
if (err == NOERR && last_on_file != EOR) if (err == NOERR && last_on_file != EOR)
remove_from(i + _offset); remove_from(f, i + _offset);
return err; return err;
} }

View File

@ -9,8 +9,6 @@
#include <isam.h> #include <isam.h>
#endif #endif
#include <user.h>
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
// TRecord_Array // TRecord_Array
/////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
@ -48,6 +46,9 @@ protected:
bool good(const TRectype& rec) const; bool good(const TRectype& rec) const;
// @cmember Duplica un record array // @cmember Duplica un record array
virtual TObject* dup() const { return new TRecord_array(*this);} virtual TObject* dup() const { return new TRecord_array(*this);}
int remove_from(TIsamfile& f, int pos) const;
// @access Public Member // @access Public Member
public: public:
// @cmember Ritorna il record che fa da chiave per tutti gli altri // @cmember Ritorna il record che fa da chiave per tutti gli altri

View File

@ -960,6 +960,15 @@ bool TRelation_application::find(word k)
return err == NOERR; 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) bool TRelation_application::save(bool check_dirty)
{ {
@ -967,7 +976,10 @@ bool TRelation_application::save(bool check_dirty)
int pos = _mask->id2pos(DLG_SAVEREC); int pos = _mask->id2pos(DLG_SAVEREC);
if (pos < 0 || !_mask->fld(pos).active()) if (pos < 0 || !_mask->fld(pos).active())
return TRUE; {
edit_cancel();
return true;
}
int err = NOERR; int err = NOERR;
const int mode = _mask->mode(); const int mode = _mask->mode();
@ -983,12 +995,8 @@ bool TRelation_application::save(bool check_dirty)
if (!dirty && !was_dirty) if (!dirty && !was_dirty)
{ {
if (mode == MODE_MOD) edit_cancel();
{ return true;
get_relation()->restore_status();
get_relation()->lfile().reread(_unlock); // Unlock main file
}
return TRUE;
} }
const KEY last = _mask->last_key(); const KEY last = _mask->last_key();
@ -1036,12 +1044,8 @@ bool TRelation_application::save(bool check_dirty)
if (k == K_ESC || k == K_NO) if (k == K_ESC || k == K_NO)
{ {
if (mode == MODE_MOD) edit_cancel();
{ was_dirty = false;
get_relation()->restore_status();
get_relation()->lfile().reread(_unlock); // Unlock main file
}
was_dirty = FALSE;
return k == K_NO; return k == K_NO;
} }

View File

@ -170,6 +170,8 @@ protected:
// @cmember Richiede la maschera da usare // @cmember Richiede la maschera da usare
virtual TMask* get_mask(int mode) pure; 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 // @cmember:(INTERNAL) Salva i contenuti della maschera su file
virtual bool save(bool check_dirty); virtual bool save(bool check_dirty);
// @cmember Legge dalla relazione i valori nella maschera <p m> // @cmember Legge dalla relazione i valori nella maschera <p m>
@ -189,7 +191,7 @@ protected:
virtual const char* get_next_key() virtual const char* get_next_key()
{ return ""; } { return ""; }
virtual bool get_next_key(TToken_string& key) virtual bool get_next_key(TToken_string& key)
{ return FALSE; } { return false; }
// @cmember Richiede se il record corrente e' protetto (non cancellabile) // @cmember Richiede se il record corrente e' protetto (non cancellabile)
virtual bool protected_record(TRectype&) virtual bool protected_record(TRectype&)

View File

@ -158,7 +158,7 @@ bool TLog_report::log(int sev, const char* msg)
return ok; 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); load(name);
if (recordset() == NULL) if (recordset() == NULL)