Aggiunto Codebase 5.1, per supporto files.
- sheet.cpp : modificata gesione doppio click del mouse. git-svn-id: svn://10.65.10.50/trunk@1533 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
parent
9775ccaaac
commit
76a217510a
914
include/codeb.c
Executable file
914
include/codeb.c
Executable file
@ -0,0 +1,914 @@
|
||||
/*
|
||||
Attenzione!. Per costruire la DLL accertarsi che siano attivati i seguenti switch:
|
||||
1) S4DLL_BUILD definito da command line del compilatore
|
||||
2) Uno solo tra S4FOX S4CLIPPER S4NDX e S4MDX, definito in d4all.h
|
||||
|
||||
Gli altri switch di configurazione generale sono a piacere (S4DEBUG, S4ERROR_HOOK, ecc.)
|
||||
|
||||
Per costruire WINUNO.LIB Accertarsi che d4all.h non abbia definito S4DLL o S4UNIX,
|
||||
e tanto meno S4DLL_BUILD, altrimenti per costruire la library di UNIX e' necessario
|
||||
cambiare ogni volta. La definizione di tali simboli avviene qui dentro.
|
||||
Inoltre deve essere attivo uno solo degli switch di selezione formato database
|
||||
(S4FOX, S4MDX ecc.); nel caso si faccia uso della DLL non importa quale si e' definito.
|
||||
E' importante solo in caso di utilizzo di una static Library.
|
||||
|
||||
Per costruire l'aga.fll e' necessario togliere le funzioni progind* e definire S4DLL.
|
||||
|
||||
*/
|
||||
#if XVT_OS == XVT_OS_SCOUNIX
|
||||
#define S4UNIX
|
||||
#else
|
||||
#define S4DLL
|
||||
#endif
|
||||
|
||||
#ifdef XVT /* This not recommended in Unix!*/
|
||||
#undef S4UNIX
|
||||
#define S4DLL
|
||||
#endif
|
||||
|
||||
#ifdef FOXPRO
|
||||
#undef S4UNIX
|
||||
#define S4DLL
|
||||
#endif
|
||||
|
||||
#include <d4all.h>
|
||||
#include <x4filter.h>
|
||||
#include <i4chang.h>
|
||||
#include <codeb.h>
|
||||
#include <rectypes.h>
|
||||
#include <progind.h>
|
||||
#define MAXLEN 128 // Lunghezza massima chiave
|
||||
|
||||
extern char* CUpString(char *);
|
||||
|
||||
static CODE4 code_base;
|
||||
static DATA4 *dbdata[CB4FILES];
|
||||
static X4FILTER xdb[CB4FILES];
|
||||
|
||||
|
||||
static char * find_slash_backslash(char * str)
|
||||
{
|
||||
int l=strlen(str);
|
||||
static char * xstr ;
|
||||
xstr = str + l;
|
||||
|
||||
while (xstr-- && l--)
|
||||
if (*xstr == '\\' || *xstr == '/')
|
||||
break;
|
||||
if (l == 0)
|
||||
return NULL;
|
||||
else
|
||||
return xstr;
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
funzione di filtro usata su tutti i database
|
||||
--------------------------------------------------------------------------*/
|
||||
int S4CALL notdelete(void *fd)
|
||||
{
|
||||
if(d4deleted(fd)) return r4ignore;
|
||||
else return r4keep;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
inizializzazione di CodeBase e delle variabili necessarie
|
||||
questa funzione deve essere chiamata SOLO una volta all'interno
|
||||
di ciascun eseguibile
|
||||
--------------------------------------------------------------------------*/
|
||||
void DB_init(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<CB4FILES;i++) {
|
||||
dbdata[i]=(DATA4 *) 0;
|
||||
}
|
||||
d4init(&code_base);
|
||||
code_base.read_lock=0;
|
||||
code_base.default_unique_error=e4unique;
|
||||
code_base.safety=0;
|
||||
code_base.lock_attempts=1;
|
||||
u4ncpy(code_base.date_format,"CCYYMMDD",sizeof(code_base.date_format));
|
||||
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
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)
|
||||
{
|
||||
d4init_undo(&code_base);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
apertura del file 'filename'. Il parametro mode consente se != 0 l'apertura
|
||||
esclusiva
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_open(const char *filename,int mode)
|
||||
{
|
||||
int i,found;
|
||||
|
||||
if (mode) code_base.exclusive=1;
|
||||
// cerca il primo posto libero nel vettore dbdata
|
||||
found=-1;
|
||||
for(i=0;i<CB4FILES;i++) {
|
||||
if(dbdata[i]==(DATA4 *) 0) {
|
||||
found=i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// se non ci sono posti liberi torna -1
|
||||
if(found==-1) return(found);
|
||||
code_base.error_code=0;
|
||||
dbdata[found]=d4open(&code_base,(char*)filename);
|
||||
if(dbdata[found]==0) return(-1);
|
||||
x4init(&xdb[found],dbdata[found],notdelete,dbdata[found]);
|
||||
code_base.exclusive=0;
|
||||
d4tag_select(dbdata[found],d4tag_default(dbdata[found]));
|
||||
if (d4reccount(dbdata[found]) > 0)
|
||||
x4top(&xdb[found]);
|
||||
return(found);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
chiusura del database inviduato da handle
|
||||
torna -1 se il database non puo essere chiuso
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_close(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
d4close(dbdata[handle]);
|
||||
dbdata[handle]=(DATA4 *) 0;
|
||||
code_base.error_code=0;
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna il puntatore al buffer del record del database individuato da
|
||||
handle. In caso di errore torna (char *) 0
|
||||
--------------------------------------------------------------------------*/
|
||||
char *DB_getrecord(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return((char *) 0);
|
||||
return(d4record(dbdata[handle]));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna la lunghezza del record
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_reclen(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return((int) d4record_width(dbdata[handle]));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna la lunghezza della chiave corrente
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_keylen(int handle)
|
||||
{
|
||||
TAG4 *t;
|
||||
|
||||
if (dbdata[handle]==0) return(-1);
|
||||
if ((t=d4tag_default(dbdata[handle]))== NULL) return (-1);
|
||||
return(strlen(t4key(t)));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna il numero del record attuale
|
||||
--------------------------------------------------------------------------*/
|
||||
long int DB_recno(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1L);
|
||||
return(d4recno(dbdata[handle]));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna il numero complessivo dei records presenti nell'archivio
|
||||
--------------------------------------------------------------------------*/
|
||||
long int DB_reccount(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1L);
|
||||
return(d4reccount(dbdata[handle]));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
seleziona un indice sul database specificato
|
||||
torna -1 se errore, altrimenti 0
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_tagselect(int handle,int index_no)
|
||||
{
|
||||
TAG4 *tt;
|
||||
int i;
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
// si posiziona sul primo indice
|
||||
tt=d4tag_next(dbdata[handle],NULL);
|
||||
if(tt==NULL) return(-1);
|
||||
for(i=1;i<index_no;i++) {
|
||||
tt=d4tag_next(dbdata[handle],tt);
|
||||
if(tt==NULL) return(-1);
|
||||
}
|
||||
d4tag_select(dbdata[handle],tt);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna il nuemero dell'indice selezionato
|
||||
torna -1 se errore
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_tagget(int handle)
|
||||
{
|
||||
TAG4 *tt,*tt1;
|
||||
int i;
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
// si posiziona sul primo indice
|
||||
tt=d4tag_selected(dbdata[handle]);
|
||||
if(tt==NULL) return(-1);
|
||||
|
||||
tt1=d4tag_next(dbdata[handle],NULL);
|
||||
i=1;
|
||||
while(tt!=tt1 && tt1!=NULL) {
|
||||
tt1=d4tag_next(dbdata[handle],tt1);
|
||||
i++;
|
||||
}
|
||||
return(i);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
si posiziona sul primo record
|
||||
torna -1 se errore
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_first(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(x4top(&xdb[handle]));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
si posiziona sull'ultimorecord
|
||||
torna -1 se errore
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_last(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(x4bottom(&xdb[handle]));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
skip avanti di un record
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_next(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(x4skip(&xdb[handle],1L));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
skip indietro di un record
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_prev(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(x4skip(&xdb[handle],-1L));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
skip di n records
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_skip(int handle,long int recno)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(x4skip(&xdb[handle],recno));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
locka il record attuale
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_lock(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
if(d4lock(dbdata[handle],d4recno(dbdata[handle]))==r4locked) return(-1);
|
||||
else return(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
slocka il record attuale
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_unlock(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) 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)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(x4seek(&xdb[handle],key));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna 1 se eof, 0 altrimenti
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_eof(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(d4eof(dbdata[handle]));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
torna 1 se tof, 0 altrimenti
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_bof(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(d4bof(dbdata[handle]));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
legge un record per numero record
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_go(int handle,long int recno)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(x4go(&xdb[handle],recno));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
cancella il record attuale
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_delete(int handle)
|
||||
{
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
d4delete(dbdata[handle]);
|
||||
return(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
ripristina il record attuale
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_recall(int handle)
|
||||
{
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
d4recall(dbdata[handle]);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
cancella dall'indice corrente la chiave specificata
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_delkey(int handle, char* key, long recno)
|
||||
{
|
||||
INDEX4* i;
|
||||
TAG4* t;
|
||||
int rt=0;
|
||||
char fn[32];
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
t=d4tag_default(dbdata[handle]);
|
||||
|
||||
if (u4switch() & 2 || u4switch() & 8) // Clipper & DBIII
|
||||
u4name_piece(fn,32,dbdata[handle]->file.name,0,0);
|
||||
else
|
||||
strcpy(fn,dbdata[handle]->file.name);
|
||||
if ((i=d4index(dbdata[handle],fn)) == NULL)
|
||||
return(e4index);
|
||||
rt=i4lock(i);
|
||||
if (rt == 0)
|
||||
rt=t4remove_calc(t,recno);
|
||||
i4unlock(i);
|
||||
return(rt);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
riscrive il record attuale
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_rewrite(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(d4write(dbdata[handle],d4recno(dbdata[handle])));
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
appende il record attuale
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_add(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
d4append_start(dbdata[handle],0);
|
||||
d4recall(dbdata[handle]);
|
||||
return(d4append(dbdata[handle]));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Blocca in modo esclusivo il file dati ed indice
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_lockfile(int handle)
|
||||
{
|
||||
int rt;
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
rt = d4lock_file(dbdata[handle]);
|
||||
if (rt>=0) rt=d4lock_index(dbdata[handle]);
|
||||
return(rt);
|
||||
}
|
||||
|
||||
HIDDEN int is_inkey(RecDes *r, int numfield)
|
||||
{
|
||||
int found=0,i,j;
|
||||
|
||||
for (i=0; ((i < MaxKeys) && (i < r->NKeys) && !found); i++)
|
||||
for (j=0; ((j < r->Ky[i].NkFields) && !found); j++)
|
||||
if (numfield == r->Ky[i].FieldSeq[j])
|
||||
found=1;
|
||||
return(found);
|
||||
}
|
||||
|
||||
HIDDEN void do_key(char *fname, RecDes *r, TAG4INFO *tag_info)
|
||||
{
|
||||
int i,j;
|
||||
char tiname[9]; // Tag name, max 8 characters long!
|
||||
|
||||
strcpy(tiname,fname);
|
||||
CUpString(tiname);
|
||||
for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++)
|
||||
{
|
||||
tag_info[i].name=(char *)u4alloc(9);
|
||||
tag_info[i].expression=(char *)u4alloc(128);
|
||||
tag_info[i].filter=(char*)u4alloc(20);
|
||||
tag_info[i].descending=0;
|
||||
if (r->Ky[i].DupKeys)
|
||||
tag_info[i].unique=0;
|
||||
else
|
||||
tag_info[i].unique=e4unique;
|
||||
strcpy(tag_info[i].filter,""); // Not available for DBIII and CLIPPER
|
||||
strcpy(tag_info[i].name,tiname) ;
|
||||
if (strlen(tiname) < 8)
|
||||
strcat(tag_info[i].name," ");
|
||||
tag_info[i].name[strlen(tag_info[i].name)-1] = '0' + i + 1;
|
||||
for (j=0; j < r->Ky[i].NkFields; j++)
|
||||
{
|
||||
int nf= r->Ky[i].FieldSeq[j];
|
||||
if (nf > MaxFields) // When Upper field is specified
|
||||
{
|
||||
nf -= MaxFields;
|
||||
strcat(tag_info[i].expression,"UPPER(");
|
||||
}
|
||||
if (r->Ky[i].FromCh[j] != 255) // When partial field is specified
|
||||
strcat(tag_info[i].expression,"SUBSTR(");
|
||||
|
||||
switch (r->Fd[nf].TypeF) // When numeric field in key is specified
|
||||
{
|
||||
case _intfld:
|
||||
case _longfld:
|
||||
case _realfld:
|
||||
case _wordfld:
|
||||
case _intzerofld:
|
||||
case _longzerofld:
|
||||
strcat(tag_info[i].expression,"STR(");
|
||||
break;
|
||||
case _datefld:
|
||||
strcat(tag_info[i].expression,"DTOS(");
|
||||
break;
|
||||
case _boolfld:
|
||||
strcat(tag_info[i].expression,"IIF("); // Logical fields are in key too...
|
||||
break;
|
||||
default: // It's a non sense to keep _realfld in key...
|
||||
break; // however it's possible to have it...
|
||||
} // Le chiavi composte da campi data non necessitano di funzioni di traduzione.
|
||||
|
||||
strcat(tag_info[i].expression,r->Fd[nf].Name); // Append field name
|
||||
|
||||
if (r->Ky[i].FromCh[j] != 255) // If partial field was specified
|
||||
{ // add parameters to SUBSTR
|
||||
char ts[8];
|
||||
|
||||
strcat(tag_info[i].expression,",");
|
||||
sprintf(ts,"%d",r->Ky[i].FromCh[j]);
|
||||
strcat(tag_info[i].expression,ts);
|
||||
strcat(tag_info[i].expression,",");
|
||||
sprintf(ts,"%d",r->Ky[i].ToCh[j] - r->Ky[i].FromCh[j] + 1);
|
||||
strcat(tag_info[i].expression,ts);
|
||||
strcat(tag_info[i].expression,")");
|
||||
}
|
||||
|
||||
switch (r->Fd[nf].TypeF) // If numeric field was specified
|
||||
{ // add parameters to STR
|
||||
case _intfld:
|
||||
case _longfld:
|
||||
case _realfld: // Questo tipo di campo(real) non ha senso in un a chiave...
|
||||
case _wordfld:
|
||||
case _intzerofld:
|
||||
case _longzerofld:
|
||||
{
|
||||
char ts[8];
|
||||
strcat(tag_info[i].expression,",");
|
||||
sprintf(ts,"%d",r->Fd[nf].Len);
|
||||
strcat(tag_info[i].expression,ts);
|
||||
strcat(tag_info[i].expression,",0)");
|
||||
}
|
||||
break;
|
||||
case _boolfld: // Orgssbb... Che culo.
|
||||
strcat(tag_info[i].expression,",\"T\",\"F\")");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Close parentheses if UPPER or DTOS operators were used:
|
||||
if (r->Ky[i].FieldSeq[j] > MaxFields || (r->Fd[nf].TypeF == _datefld))
|
||||
strcat(tag_info[i].expression,")");
|
||||
// If there's another field in key adds "+" operator:
|
||||
if (j < (r->Ky[i].NkFields-1))
|
||||
strcat(tag_info[i].expression,"+");
|
||||
}
|
||||
}
|
||||
tag_info[i].name=NULL;
|
||||
tag_info[i].expression=NULL;
|
||||
tag_info[i].filter=NULL;
|
||||
tag_info[i].unique=0;
|
||||
tag_info[i].descending=0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Compatta il file dati
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_packfile(short vis, const char * filename, long eod)
|
||||
{
|
||||
int rt=0,handle;
|
||||
|
||||
// if(dbdata[handle]==0) return(-1);
|
||||
// codebase.auto_open = 0 cosi' non apre gli indici
|
||||
code_base.auto_open = 0;
|
||||
handle=DB_open(filename,1); // Exclusive mode open!
|
||||
if (handle > -1)
|
||||
{
|
||||
char s[81];
|
||||
|
||||
if (vis)
|
||||
{
|
||||
strcpy(s,"Compattamento dati file : ");
|
||||
strcat(s,(char*)filename);
|
||||
#ifndef FOXPRO
|
||||
progind_create(10L,s,1,1,1);
|
||||
#endif
|
||||
}
|
||||
if (eod < d4reccount(dbdata[handle]))
|
||||
{
|
||||
rt=d4zap(dbdata[handle],++eod,d4reccount(dbdata[handle]));
|
||||
} else
|
||||
rt=d4pack(dbdata[handle]);
|
||||
if (vis)
|
||||
{
|
||||
#ifndef FOXPRO
|
||||
progind_set_status((long)10);
|
||||
progind_destroy();
|
||||
#endif
|
||||
}
|
||||
DB_close(handle);
|
||||
}
|
||||
else
|
||||
rt=code_base.error_code;
|
||||
code_base.auto_open = 1;
|
||||
return rt;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Compatta gli indici
|
||||
--------------------------------------------------------------------------*/
|
||||
int DB_packindex(short vis, const char * filename, RecDes *r, long *peod)
|
||||
{
|
||||
int rt=0,handle;
|
||||
TAG4INFO tags[MaxKeys+1];
|
||||
char s[82];
|
||||
|
||||
strcpy(s,"Ricostruzione indici file : ");
|
||||
strcat(s,filename);
|
||||
|
||||
// codebase.auto_open = 0 cosi' non apre gli indici
|
||||
code_base.auto_open=0 ;
|
||||
handle=DB_open(filename,1); // Exclusive mode open
|
||||
if (handle > -1)
|
||||
{
|
||||
int i;
|
||||
char *ff = find_slash_backslash((char *)filename);
|
||||
if (vis)
|
||||
{
|
||||
#ifndef FOXPRO
|
||||
progind_create((long)r->NKeys,s,1,1,1);
|
||||
#endif
|
||||
}
|
||||
if (ff == NULL || *ff == NULL)
|
||||
ff = filename;
|
||||
else
|
||||
ff++;
|
||||
do_key(ff,r,tags);
|
||||
if (u4switch() &2 || u4switch() & 8) // Clipper and DBIII
|
||||
{
|
||||
rt = (int)i4create(dbdata[handle],(char*)filename,tags);
|
||||
#ifndef FOXPRO
|
||||
progind_set_status((long)r->NKeys);
|
||||
#endif
|
||||
if (rt!=0 && code_base.error_code==0)
|
||||
{
|
||||
FILE *fp;
|
||||
char cgp[81];
|
||||
|
||||
strcpy(cgp,filename);
|
||||
strcat(cgp,".CGP");
|
||||
if ((fp=fopen(cgp,"w"))!=NULL)
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j=0; j<r->NKeys;j++)
|
||||
fprintf(fp,"%s\n",tags[j].name);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (u4switch() & 1 || u4switch() & 4) // FOXPRO and DBIV
|
||||
{
|
||||
rt = (int)i4create(dbdata[handle],NULL,tags);
|
||||
#ifndef FOXPRO
|
||||
progind_set_status((long)r->NKeys);
|
||||
#endif
|
||||
}
|
||||
for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++)
|
||||
{
|
||||
u4free(tags[i].name);
|
||||
u4free(tags[i].expression);
|
||||
u4free(tags[i].filter);
|
||||
}
|
||||
if (vis)
|
||||
{
|
||||
#ifndef FOXPRO
|
||||
progind_destroy();
|
||||
#endif
|
||||
}
|
||||
*peod=DB_reccount(handle);
|
||||
DB_close(handle);
|
||||
}
|
||||
code_base.auto_open = 1;
|
||||
return(code_base.error_code);
|
||||
}
|
||||
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
costruisce il file filename
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_build(const char * filename, RecDes *r)
|
||||
{
|
||||
|
||||
FIELD4INFO field_info[MaxFields+1]; // Numero di campi in un record
|
||||
TAG4INFO tag_info[MaxKeys+1]; // Numero di chiavi in un file
|
||||
DATA4 *dbuilded;
|
||||
int rt=0,i;
|
||||
char *ff = find_slash_backslash((char *)filename);
|
||||
|
||||
|
||||
for (i=0; ((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 _charfld:
|
||||
default:
|
||||
field_info[i].type=r4str;
|
||||
break;
|
||||
}
|
||||
}
|
||||
field_info[i].name=NULL;
|
||||
field_info[i].type=0;
|
||||
field_info[i].len=0;
|
||||
field_info[i].dec=0;
|
||||
|
||||
if (ff == NULL || *ff == NULL)
|
||||
ff = (char *) filename;
|
||||
else
|
||||
ff++;
|
||||
do_key(ff,r,tag_info);
|
||||
|
||||
if ((dbuilded=d4create(&code_base, (char *)filename, field_info, tag_info))==0) // deve solo creare il file dati vuoto
|
||||
rt=code_base.error_code;
|
||||
else
|
||||
rt=d4close(dbuilded);
|
||||
if (u4switch() & 2 || u4switch() & 8) // Rebuild filename.cgp for CLIPPER AND DBIII only
|
||||
{
|
||||
FILE* fp;
|
||||
char xx[81];
|
||||
|
||||
strcpy(xx,(char*)filename);
|
||||
|
||||
strcat(xx,".cgp");
|
||||
if ((fp=fopen(xx,"w"))!=NULL)
|
||||
{
|
||||
int j;
|
||||
for (j=0; tag_info[j].name ; j++)
|
||||
fprintf(fp,"%s\n",tag_info[j].name);
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
if (rt!=0)
|
||||
rt=code_base.error_code;
|
||||
for (i=0; ((i < MaxFields) && (i < r->NFields)); i++)
|
||||
u4free(field_info[i].name);
|
||||
for (i=0; ((i < MaxKeys) && (i < r->NKeys)); i++)
|
||||
{
|
||||
u4free(tag_info[i].name);
|
||||
u4free(tag_info[i].expression);
|
||||
u4free(tag_info[i].filter);
|
||||
}
|
||||
return(rt) ;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
ritorna l'ultimo errore
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_get_error(void)
|
||||
{
|
||||
int rt = code_base.error_code;
|
||||
code_base.error_code=0;
|
||||
return (rt);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Azzera la viarabile globale d'errore
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
void DB_zero_error(void)
|
||||
{
|
||||
code_base.error_code=0;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Si posiziona sull'indice attivo alla chiave indicata, restituisce
|
||||
la prima chiave che trova >= a from. (TCusrsor)
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_index_seek(int handle, char* from)
|
||||
{
|
||||
TAG4 *t;
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
if ((t=d4tag_default(dbdata[handle]))==NULL) return(-1);
|
||||
|
||||
if (t4seek(t,from,strlen(from)) < 0) return(DB_get_error());
|
||||
return(0);
|
||||
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Ritorna il numero di record corrispondente alla chiave corrente
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
long DB_index_recno(int handle)
|
||||
{
|
||||
TAG4 *t;
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
if ((t=d4tag_default(dbdata[handle]))==NULL) return(-1);
|
||||
|
||||
return(t4recno(t));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Si posiziona sulla chiave successiva dell'indice corrente
|
||||
--------------------------------------------------------------------------*/
|
||||
long DB_index_next(int handle)
|
||||
{
|
||||
TAG4 *t;
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
if ((t=d4tag_default(dbdata[handle]))==NULL) return(-1);
|
||||
|
||||
return(t4skip(t,1L));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Restituisce la chiave corrente
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
char* DB_index_getkey(int handle)
|
||||
{
|
||||
TAG4 *t;
|
||||
static char key[MAXLEN];
|
||||
int klen;
|
||||
|
||||
if(dbdata[handle]==0) return(NULL);
|
||||
if ((t=d4tag_default(dbdata[handle]))==NULL) return(NULL);
|
||||
klen=expr4key_len(t->expr);
|
||||
if (klen > (MAXLEN-1)) klen=MAXLEN-1;
|
||||
memcpy(key,t4key(t),klen); // t4key non restituisce una null terminated string
|
||||
key[klen]='\0';
|
||||
return(key);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Restituisce vero se l'indice e' alla fine
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_index_eof(int handle)
|
||||
{
|
||||
TAG4 *t;
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
if ((t=d4tag_default(dbdata[handle]))==NULL) return(-1);
|
||||
return(t4eof(t));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Blocca il record indicato
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_lock_rec(int handle,long nrec)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
if(d4lock(dbdata[handle],nrec)==r4locked) return(-1);
|
||||
else return(0);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Ritorna vero se il file e' bloccato in modo exclusive
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
int DB_file_locked(int handle)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(d4lock_test_file(dbdata[handle]));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Ritorna vero se il record nrec e' bloccato
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
int DB_rec_locked(int handle,long nrec)
|
||||
{
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
return(d4lock_test(dbdata[handle],nrec));
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
restituisce la configurazione della libreria
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
long DB_getconf()
|
||||
{
|
||||
return(u4switch());
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------------
|
||||
Restituisce il numero di versione scritto sull'header dell'indice
|
||||
--------------------------------------------------------------------------*/
|
||||
|
||||
long DB_changed(int handle)
|
||||
{
|
||||
INDEX4 *i;
|
||||
char fn[32];
|
||||
|
||||
if(dbdata[handle]==0) return(-1);
|
||||
if (u4switch() & 2 || u4switch() & 8) // Clipper & DBIII
|
||||
u4name_piece(fn,32,dbdata[handle]->file.name,0,0);
|
||||
else
|
||||
strcpy(fn,dbdata[handle]->file.name);
|
||||
i=d4index(dbdata[handle],fn);
|
||||
if (i == NULL) return(-1);
|
||||
|
||||
return(i4changed(i));
|
||||
}
|
74
include/codeb.h
Executable file
74
include/codeb.h
Executable file
@ -0,0 +1,74 @@
|
||||
/*--------------------------------------------------------------------------
|
||||
CODEBASE.H
|
||||
data : 23.01.95
|
||||
scopo: interfaccia verso CodeBase 5.0
|
||||
--------------------------------------------------------------------------*/
|
||||
#ifndef __CODEBASE_H
|
||||
#define __CODEBASE_H
|
||||
|
||||
#ifndef __EXTCTYPE_H
|
||||
#include <extctype.h>
|
||||
#endif
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
numero massimo di database aperti contemporaneamente
|
||||
--------------------------------------------------------------------------*/
|
||||
#define CB4FILES 50
|
||||
|
||||
/*--------------------------------------------------------------------------
|
||||
prototipi funzioni
|
||||
--------------------------------------------------------------------------*/
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
void DB_init(void);
|
||||
void DB_exit(void);
|
||||
int DB_open(const char *filename,int mode);
|
||||
int DB_close(int handle);
|
||||
char *DB_getrecord(int handle);
|
||||
int DB_reclen(int handle);
|
||||
int DB_keylen(int handle);
|
||||
long int DB_recno(int handle);
|
||||
long int DB_reccount(int handle);
|
||||
int DB_tagselect(int handle,int index_no);
|
||||
int DB_tagget(int handle);
|
||||
int DB_first(int handle);
|
||||
int DB_last(int handle);
|
||||
int DB_next(int handle);
|
||||
int DB_prev(int handle);
|
||||
int DB_skip(int handle,long int recno);
|
||||
int DB_lock(int handle);
|
||||
int DB_lockrec(int handle, long recno); // Per sbloccare il record basta la DB_unlock()
|
||||
int DB_unlock(int handle);
|
||||
int DB_seek(int handle,char *key);
|
||||
int DB_eof(int handle);
|
||||
int DB_bof(int handle);
|
||||
int DB_go(int handle,long int recno);
|
||||
int DB_delete(int handle);
|
||||
int DB_recall(int handle);
|
||||
int DB_delkey(int handle, char* key, long recno);
|
||||
int DB_rewrite(int handle);
|
||||
int DB_add(int handle);
|
||||
int DB_lockfile(int handle); // Per sbloccare il file basta la DB_unlock()
|
||||
int DB_packfile(short vis, const char * filename, long eod);
|
||||
int DB_packindex(short vis, const char * filename, RecDes *r, long *peod );
|
||||
int DB_build(const char * filename, RecDes *r);
|
||||
int DB_get_error(void);
|
||||
void DB_zero_error(void);
|
||||
int DB_index_seek(int handle, char* from);
|
||||
long DB_index_recno(int handle);
|
||||
long DB_index_next(int handle);
|
||||
char* DB_index_getkey(int handle);
|
||||
int DB_index_eof(int handle);
|
||||
int DB_lock_rec(int handle,long nrec);
|
||||
int DB_file_locked(int handle);
|
||||
int DB_rec_locked(int handle,long nrec);
|
||||
long DB_getconf();
|
||||
long DB_changed(int handle); // returns true if the index of the key is changed
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -199,13 +199,13 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SecDef f;
|
||||
FilCtrl i;
|
||||
int fhnd;
|
||||
FileDes *d;
|
||||
RecDes *r;
|
||||
RecNoType RecNo;
|
||||
RecNoType RecNo;
|
||||
INT16 ln;
|
||||
INT16 ft;
|
||||
INT16 ft;
|
||||
int knum;
|
||||
} isdef ;
|
||||
|
||||
|
||||
|
@ -136,7 +136,7 @@ const char *TDir::name () const
|
||||
}
|
||||
|
||||
const char *TDir::des () const
|
||||
{
|
||||
{
|
||||
return _dir->Des;
|
||||
}
|
||||
|
||||
@ -146,9 +146,11 @@ const char* TDir::tab_des(const char* tab)
|
||||
|
||||
TString256 tmp;
|
||||
tmp << DESCDIR << "/d" << t << ".des";
|
||||
|
||||
|
||||
#ifndef FOXPRO
|
||||
TConfig cnf(tmp, DESCTAB);
|
||||
t = cnf.get("Description", NULL, -1, tab);
|
||||
#endif
|
||||
|
||||
return strcpy(__tmp_string, t);
|
||||
}
|
||||
|
1117
include/isam.cpp
1117
include/isam.cpp
File diff suppressed because it is too large
Load Diff
@ -80,9 +80,9 @@ public:
|
||||
void settab(const char *tab);
|
||||
char* string() const { return _rec;} // Ritorna il puntatore all'inizio. NON dovrebbe essere usata!
|
||||
|
||||
void discard() { *_rec = char(_deleted);} // Setta il flag di cancellazione
|
||||
void recall() { *_rec = char(_valid);} // Ripristina il flag di cancellazione
|
||||
bool isdeleted() const { return *_rec == _deleted;} // Chiede se e' cancellato
|
||||
void discard() { *_rec = '*';} // Setta il flag di cancellazione
|
||||
void recall() { *_rec = ' ';} // Ripristina il flag di cancellazione
|
||||
bool isdeleted() const { return *_rec == '*';} // Chiede se e' cancellato
|
||||
int len() const { return _length;} // Ritorna la lunghezza
|
||||
TFieldtypes type(const char* fieldname) const; // Ritorna il tipo del campo
|
||||
int length(const char* fieldname) const; // Ritorna lunghezza campo
|
||||
@ -135,7 +135,7 @@ public:
|
||||
// const isdef* filehnd() const { return _i; } // Ritorna il file isam associato
|
||||
int num() const { return _logicnum;} // Ritorna il numero logico
|
||||
bool empty() const {return _isempty;} // Ritorna se e' vuoto
|
||||
bool valid() const {return _rec[0] == 0;} // Ritorna se il record non e'cancellato
|
||||
bool valid() const {return _rec[0] == ' ';} // Ritorna se il record non e'cancellato
|
||||
const char* key(int numkey = 1) const; // Ritorna l'espressione della chiave numero numkey
|
||||
bool ok() const { return _rec != NULL; }
|
||||
|
||||
@ -238,7 +238,7 @@ public:
|
||||
bool empty(); // Vero se il file e' vuoto
|
||||
int num() const { return _logicnum;} // Ritorna il numero logico del record corrente
|
||||
const char* description() const;
|
||||
TRecnotype eod() const { return filehnd()->d->EOD;}
|
||||
TRecnotype eod() const ;
|
||||
|
||||
isdef* filehnd() const { return (isdef*) _isamfile;} // Ritorna l'handle del file isam nella tabella
|
||||
|
||||
@ -341,8 +341,9 @@ public:
|
||||
int extend(TRecnotype eox); // Estende un file preesistente
|
||||
long size(TRecnotype eox); // Calcola lo spazio che il file occuperebbe se venisse esteso a eox
|
||||
int update(TTrec& newrec, bool vis = TRUE);
|
||||
|
||||
int packfile(bool vis = TRUE); // Rimuove fisicamente i record cancellati
|
||||
|
||||
int pack(bool vis = TRUE); // Esegue packfile e packindex
|
||||
int packfile(bool vis = TRUE); // Rimuove fisicamente i record cancellati
|
||||
int packindex(bool vis = TRUE); // La stessa cosa sugli indici
|
||||
|
||||
// @DES Importa un file ascii. from e' il nome del file da importare
|
||||
@ -495,6 +496,7 @@ public:
|
||||
// @DPUB
|
||||
extern TTransaction transaction;
|
||||
extern TRectype** openrec;
|
||||
extern void get_idx_names(int logicnum, TToken_string& i_names);
|
||||
// @END
|
||||
#undef extern
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
#define VERSION "1.4"
|
||||
#define INTERNAL_VERSION "0"
|
||||
#define INTERNAL_VERSION "1"
|
||||
|
@ -14,6 +14,11 @@
|
||||
#include <scanner.h>
|
||||
#include <utility.h>
|
||||
|
||||
#include <lffiles.h>
|
||||
#include <codeb.h>
|
||||
|
||||
extern int get_error(int);
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// extern variables are NO-NO!
|
||||
@ -96,9 +101,10 @@ HIDDEN int closeall(bool changestudy, TBit_array& excl, TBit_array& toclose)
|
||||
d.get(i + 1, _nolock, _nordir, _sysdirop);
|
||||
if (toclose[i + 1] || changestudy || d.name()[0] != '%')
|
||||
{
|
||||
excl.set(i, isfd->f.LockMode == _excllock);
|
||||
CClose(&isfd->f);
|
||||
CBCloseFile(&isfd->i, &err);
|
||||
excl.set(i, DB_file_locked(isfd->fhnd) == _excllock);
|
||||
err=DB_close(isfd->fhnd);
|
||||
if (err != NOERR) err=get_error(err);
|
||||
if (err != NOERR) fatal_box("Can't close file %d. Error n. %d",isfd->ln,err);
|
||||
exclunlock(CInsPref((char*) glockname, _nordir), FALSE);
|
||||
}
|
||||
}
|
||||
@ -140,9 +146,10 @@ HIDDEN void openall(bool changestudy, TBit_array& excl, int oldmax, TBit_array&
|
||||
*isfd->r = *r.rec();
|
||||
if (excllock(CInsPref((char*) glockname, NORDIR), FALSE) == -1 && errno == EACCES)
|
||||
fatal_box("Can't reopen file n. %d : file in use", i + 1);
|
||||
COpen(&isfd->f, isfd->d->SysName, isfd->d->LenR, 0, excl[i]);
|
||||
if ((err = isfd->f.IOR) == NOERR)
|
||||
CBOpenFile (&isfd->i, CGetIdxName(isfd->d->SysName), excl[i], &err);
|
||||
err=DB_open(isfd->d->SysName,excl[i]==_excllock);
|
||||
if (err<0) err=get_error(err);
|
||||
if (err == _islocked)
|
||||
fatal_box("Can't reopen file n. %d : file in use", i + 1);
|
||||
if (err != NOERR)
|
||||
fatal_box("Can't reopen file n. %d : error n. %d", i + 1, err);
|
||||
}
|
||||
|
@ -13,9 +13,8 @@ enum TFilelock { _excllock = 0x100, _autolock = 0x200,
|
||||
_manulock = 0x400};
|
||||
enum TReclock { _unlock = 0x1000, _nolock = 0x2000, _lock = 0x4000,
|
||||
_testandlock = (int)0x8000} ;
|
||||
enum TRecstates { _valid, _deleted};
|
||||
enum TDirtype { _nordir, _comdir } ;
|
||||
enum TDirop { _nordirop, _sysdirop };
|
||||
enum TDirtype { _nordir, _comdir } ;
|
||||
enum TDirop { _nordirop, _sysdirop };
|
||||
enum TFieldtypes { _nullfld, _alfafld, _intfld, _longfld, _realfld,
|
||||
_datefld, _wordfld, _charfld, _boolfld , _intzerofld, _longzerofld,
|
||||
_memofld} ;
|
||||
|
@ -1,4 +1,4 @@
|
||||
// $Id: relation.cpp,v 1.49 1995-06-28 16:35:26 guy Exp $
|
||||
// $Id: relation.cpp,v 1.50 1995-07-03 07:49:22 angelo Exp $
|
||||
// relation.cpp
|
||||
// fv 12/8/93
|
||||
// relation class for isam files
|
||||
@ -17,14 +17,19 @@
|
||||
#include <utility.h>
|
||||
#include <xvtility.h>
|
||||
|
||||
#include <codeb.h>
|
||||
|
||||
// *** check if not already defined
|
||||
#define NOTFOUND (-1)
|
||||
|
||||
// *** maximum number of elements in a cursor working page
|
||||
#define CMAXELPAGE 8000
|
||||
|
||||
|
||||
#define print_name(out, f) out << (f.num() == LF_TABCOM ? "%" : "") << f.name()
|
||||
|
||||
extern int get_error(int);
|
||||
|
||||
HIDDEN const char* field_type_str(TFieldtypes f)
|
||||
{
|
||||
const char* c = "";
|
||||
@ -735,14 +740,15 @@ int TRelation::remove(TDate& atdate)
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
HIDDEN bool __evalcondition(const TRectype& r,TExpression* cond)
|
||||
HIDDEN bool __evalcondition(const TRelation* r,TExpression* cond)
|
||||
|
||||
{
|
||||
for (int i = 0; i < cond->numvar(); i++)
|
||||
{
|
||||
const char* s = cond->varname(i);
|
||||
|
||||
cond->setvar(i, r.get(s));
|
||||
TFieldref f(s,0);
|
||||
|
||||
cond->setvar(i, f.read(r));
|
||||
}
|
||||
return (bool) *cond;
|
||||
}
|
||||
@ -768,17 +774,14 @@ FILE* TCursor::open_index(bool create)
|
||||
|
||||
TRecnotype TCursor::buildcursor(TRecnotype rp)
|
||||
{
|
||||
TRecnotype ap = 0, junkl;
|
||||
char s[82];
|
||||
int junk, l, pagecnt = 0;
|
||||
Page p;
|
||||
int pos;
|
||||
const int kl = file().filehnd()->i.Base[file().filehnd()->i.PN].KeyLen;
|
||||
|
||||
TRecnotype oldrecno=0,pos,ap = 0;
|
||||
int junk, l, pagecnt = 0;
|
||||
const bool filtered = has_filter();
|
||||
|
||||
FILE* _f = open_index(TRUE);
|
||||
|
||||
if (file().filehnd()->i.Base[file().filehnd()->i.PN].PEOD == 0)
|
||||
if (DB_reccount(file().filehnd()->fhnd) == 0)
|
||||
{
|
||||
fclose(_f);
|
||||
return 0;
|
||||
@ -787,62 +790,56 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
|
||||
fseek(_f, 0L, SEEK_SET);
|
||||
|
||||
l = strlen(to());
|
||||
BTrRead(&file().filehnd()->i, (char*)(const char*) from(), s, &junkl, &junk);
|
||||
junk=DB_index_seek(file().filehnd()->fhnd, (char*)(const char*) from());
|
||||
if (junk < 0) junk=get_error(junk);
|
||||
if (junk == _iseof) return 0;
|
||||
|
||||
TRecnotype* page = new TRecnotype [CMAXELPAGE];
|
||||
|
||||
if (GetAPage(&file().filehnd()->i, &p, file().filehnd()->i.CurPag, &junk) != NOERR)
|
||||
fatal_box("Can't read index n. %d - file n. %d", file().filehnd()->i.PN + 1, file().filehnd()->ln);
|
||||
|
||||
pos = file().filehnd()->i.Pos - 1;
|
||||
_pos = -1;
|
||||
TRecnotype* page = new TRecnotype [CMAXELPAGE];
|
||||
pos = DB_index_recno(file().filehnd()->fhnd);
|
||||
_pos=-1;
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
if (pos >= p.PA.PageHeader.NKey)
|
||||
{
|
||||
if (p.PA.PageHeader.Next == -1L) break;
|
||||
file().filehnd()->i.CurPag = p.PA.PageHeader.Next;
|
||||
if (GetAPage(&file().filehnd()->i, &p, file().filehnd()->i.CurPag, &junk) != NOERR)
|
||||
fatal_box("Can't read index n. %d - file n. %d", file().filehnd()->i.PN + 1, file().filehnd()->ln);
|
||||
pos = 0;
|
||||
}
|
||||
const char* s0 = p.PA.AreaForKey + pos++ * (kl + 4);
|
||||
{
|
||||
if (DB_index_eof(file().filehnd()->fhnd)) break;
|
||||
const char* s0 = DB_index_getkey(file().filehnd()->fhnd);
|
||||
const TRecnotype recno = DB_index_recno(file().filehnd()->fhnd);
|
||||
if (l && (strncmp(to(), s0, l) < 0)) break;
|
||||
|
||||
if (recno == oldrecno) break; // means that no more keys are available
|
||||
oldrecno=recno;
|
||||
if (pagecnt == CMAXELPAGE)
|
||||
{
|
||||
if (filtered) pagecnt = filtercursor(pagecnt, page);
|
||||
fwrite(page, sizeof(junkl), pagecnt, _f);
|
||||
if (pos == -1)
|
||||
for (int i = 0; i < pagecnt; i++)
|
||||
if (page[i] == rp)
|
||||
{
|
||||
_pos = ap + i;
|
||||
break;
|
||||
}
|
||||
ap += pagecnt;
|
||||
pagecnt = 0;
|
||||
}
|
||||
page[pagecnt++] = *((long *)(s0 + kl));
|
||||
}
|
||||
if (pagecnt)
|
||||
{
|
||||
if (filtered) pagecnt = filtercursor(pagecnt, page);
|
||||
fwrite(page, sizeof(junkl), pagecnt, _f);
|
||||
if (pos == -1)
|
||||
for (int i = 0; i < pagecnt; i++)
|
||||
{
|
||||
if (filtered) pagecnt = filtercursor(pagecnt,page);
|
||||
fwrite(page,sizeof(TRecnotype),pagecnt,_f);
|
||||
for (int i= 0; i< pagecnt; i++)
|
||||
if (page[i] == rp)
|
||||
{
|
||||
_pos = ap + i;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
ap += pagecnt;
|
||||
pagecnt = 0;
|
||||
}
|
||||
page[pagecnt++] = recno;
|
||||
DB_index_next(file().filehnd()->fhnd);
|
||||
int rt=get_error(-1);
|
||||
if (rt != NOERR)
|
||||
fatal_box("Can't read index n. %d - file n. %d",DB_tagget(file().filehnd()->fhnd),file().filehnd()->ln);
|
||||
} // while
|
||||
if (pagecnt)
|
||||
{
|
||||
if (filtered) pagecnt = filtercursor(pagecnt, page);
|
||||
fwrite(page, sizeof(TRecnotype), pagecnt, _f);
|
||||
for (int i = 0; i < pagecnt; i++)
|
||||
if (page[i] == rp)
|
||||
{
|
||||
_pos = ap + i;
|
||||
break;
|
||||
}
|
||||
ap += pagecnt;
|
||||
}
|
||||
if (_pos == -1 ) pos = 0;
|
||||
if (_pos == -1) pos=0;
|
||||
delete page;
|
||||
|
||||
fclose(_f);
|
||||
fclose (_f);
|
||||
return ap;
|
||||
}
|
||||
|
||||
@ -850,18 +847,19 @@ TRecnotype TCursor::buildcursor(TRecnotype rp)
|
||||
int TCursor::filtercursor(int pagecnt, TRecnotype* page)
|
||||
|
||||
{
|
||||
int np = 0;
|
||||
TRectype& rec = file().curr();
|
||||
for (int i = 0; i < pagecnt; i++)
|
||||
int np=0, handle=file().filehnd()->fhnd;
|
||||
TRectype& rec=file().curr();
|
||||
for (int i=0; i< pagecnt; i++)
|
||||
{
|
||||
CRead(&file().filehnd()->f, rec.string(), page[i], _nolock);
|
||||
file().readat(rec,page[i]);
|
||||
if (update_relation()) _if->update();
|
||||
if ((_filterfunction ? _filterfunction(_if) : TRUE ) &&
|
||||
(_fexpr ? __evalcondition(rec, _fexpr) : TRUE))
|
||||
(_fexpr ? __evalcondition(_if, _fexpr) : TRUE))
|
||||
{
|
||||
if (np < i) page[np] = page[i];
|
||||
np++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return np;
|
||||
}
|
||||
|
||||
@ -881,34 +879,30 @@ bool TCursor::ok() const
|
||||
}
|
||||
|
||||
if (key < kf || (kt.not_empty() && kt < key.left(kt.len())))
|
||||
return FALSE;
|
||||
return FALSE;
|
||||
if (_filter_update || _filterfunction_update) _if->update();
|
||||
if ((_filterfunction ? _filterfunction(_if) : TRUE ) &&
|
||||
(_fexpr ? __evalcondition(rec, _fexpr) : TRUE))
|
||||
(_fexpr ? __evalcondition(_if, _fexpr) : TRUE))
|
||||
return TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
bool TCursor::changed()
|
||||
|
||||
{
|
||||
isdef* fh = file().filehnd();
|
||||
|
||||
if (_frozen && _lastrec != 0L) return _filename != fh->f.name;
|
||||
if (_frozen && _lastrec > 0L) return _filename != fh->d->SysName;
|
||||
|
||||
#if XVT_OS==XVT_OS_SCOUNIX
|
||||
const TRecnotype eod = file().eod();
|
||||
#else
|
||||
int junk = 0;
|
||||
const TRecnotype eod = cisgeteod(fh, &junk);
|
||||
#endif
|
||||
const TRecnotype eod = DB_reccount(fh->fhnd);
|
||||
|
||||
if (_lastrec != eod ||
|
||||
(_lastkrec != fh->i.Base[_nkey -1].PEOD) ||
|
||||
(_filename != fh->f.name))
|
||||
(_lastkrec != DB_changed(fh->fhnd)) ||
|
||||
(_filename != fh->d->SysName))
|
||||
{
|
||||
// _lastrec = eod;
|
||||
// _lastkrec = fh->i.Base[_nkey -1].PEOD;
|
||||
// _filename = fh->f.name;
|
||||
// _filename = fh->d->SysName;
|
||||
// _lastkrec = DB_changed(fh->fhnd);
|
||||
return TRUE;
|
||||
}
|
||||
else return FALSE;
|
||||
@ -924,19 +918,13 @@ TRecnotype TCursor::update()
|
||||
const TRecnotype totrec = buildcursor(file().recno());
|
||||
|
||||
main_app().end_wait();
|
||||
|
||||
isdef* fh = file().filehnd();
|
||||
|
||||
#if XVT_OS==XVT_OS_SCOUNIX
|
||||
const TRecnotype eod = file().eod();
|
||||
#else
|
||||
int junk = 0;
|
||||
const TRecnotype eod = cisgeteod(fh, &junk);
|
||||
#endif
|
||||
isdef* fh = file().filehnd();
|
||||
const TRecnotype eod = DB_reccount(fh->fhnd);
|
||||
|
||||
_lastrec = eod;
|
||||
_lastkrec = fh->i.Base[_nkey -1].PEOD;
|
||||
_filename = fh->f.name;
|
||||
_filename = fh->d->SysName;
|
||||
_lastkrec = DB_changed(fh->fhnd);
|
||||
|
||||
return totrec;
|
||||
}
|
||||
@ -1066,7 +1054,7 @@ TRecnotype TCursor::read(TIsamop op, TReclock lockop, TDate& atdate)
|
||||
|
||||
TCursor::TCursor(TRelation* r, const char* fil, int nkey,
|
||||
const TRectype *from, const TRectype* to)
|
||||
: _if(r), _nkey(nkey), _frozen(FALSE), _filterfunction(NULL), _fexpr(NULL)
|
||||
: _if(r), _nkey(nkey), _frozen(FALSE), _filterfunction(NULL), _fexpr(NULL), _filter_update(FALSE), _filterfunction_update(FALSE)
|
||||
{
|
||||
file().setkey(_nkey);
|
||||
_pos = 0;
|
||||
@ -1111,16 +1099,27 @@ TRecnotype TCursor::readrec()
|
||||
fclose(_f);
|
||||
|
||||
curr().setdirty();
|
||||
CRead(&file().filehnd()->f, curr().string(), nrec, _nolock);
|
||||
file().readat(nrec);
|
||||
repos();
|
||||
return nrec;
|
||||
}
|
||||
|
||||
int TCursor::lock(TReclock l)
|
||||
{
|
||||
SecDef* sd = &file().filehnd()->f;
|
||||
CLockRec(sd, _pos, l);
|
||||
return sd->IOR;
|
||||
int rt=NOERR;
|
||||
switch(l)
|
||||
{
|
||||
case _lock:
|
||||
rt=DB_lock_rec(file().filehnd()->fhnd,_pos);
|
||||
break;
|
||||
case _unlock:
|
||||
rt=DB_unlock(file().filehnd()->fhnd);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (rt < NOERR) rt=get_error(rt);
|
||||
return(rt);
|
||||
}
|
||||
|
||||
TRecnotype TCursor::operator =(const TRecnotype pos)
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $Id: relation.h,v 1.21 1995-06-28 16:35:30 guy Exp $ */
|
||||
/* $Id: relation.h,v 1.22 1995-07-03 07:49:25 angelo Exp $ */
|
||||
// join.h
|
||||
// fv 12/8/93
|
||||
// join class for isam files
|
||||
@ -106,7 +106,7 @@ public:
|
||||
|
||||
void save_status () ;
|
||||
void restore_status () ;
|
||||
|
||||
|
||||
// positioning operators. return status
|
||||
TRecnotype operator +=(const TRecnotype npos) { return skip(npos); }
|
||||
TRecnotype operator -=(const TRecnotype npos) { return skip(-npos); }
|
||||
@ -164,6 +164,7 @@ public:
|
||||
|
||||
|
||||
// Classe TCursor : public TObject
|
||||
|
||||
class TExpression;
|
||||
|
||||
typedef bool (*FILTERFUNCTION)(const TRelation* r);
|
||||
@ -172,31 +173,33 @@ class TCursor : public TObject
|
||||
{
|
||||
TRelation* _if;
|
||||
int _nkey;
|
||||
TRecnotype _pos; // Posizione corrente
|
||||
TRecnotype _pos; // Posizione corrente
|
||||
TRecnotype _totrec;
|
||||
TRecnotype _lastrec;
|
||||
TRecnotype _lastkrec;
|
||||
TRecnotype _lastkrec;
|
||||
TFilename _filename;
|
||||
TString _filter; // Filtro
|
||||
TString _keyfrom; // chiave iniziale
|
||||
TString _keyto; // chiave finale
|
||||
TExpression* _fexpr; // Espressione relativo filtro
|
||||
TString _filter; // Filtro
|
||||
TString _keyfrom; // chiave iniziale
|
||||
TString _keyto; // chiave finale
|
||||
TExpression* _fexpr; // Espressione relativo filtro
|
||||
bool _frozen;
|
||||
bool _filter_update; // Flag che permette l'update della relazione per l'espressione-filtro
|
||||
bool _filterfunction_update;// Flag che permette l'update della relazione per la funzione-filtro
|
||||
FILTERFUNCTION _filterfunction;
|
||||
TFilename _indexname;
|
||||
|
||||
virtual TRecnotype buildcursor(TRecnotype rp);
|
||||
int filtercursor(int pagecnt, TRecnotype* page);
|
||||
bool changed();
|
||||
|
||||
FILE* open_index(bool create = FALSE);
|
||||
TRecnotype update();
|
||||
|
||||
|
||||
protected:
|
||||
FILE* open_index(bool create = FALSE);
|
||||
virtual bool changed();
|
||||
virtual TRecnotype buildcursor(TRecnotype rp);
|
||||
virtual int filtercursor(int pagecnt, TRecnotype* page);
|
||||
TRecnotype readrec();
|
||||
void filter(const char* filter, const TRectype* from = NULL,
|
||||
const TRectype* to = NULL);
|
||||
bool update_relation() {return (_filter_update || _filterfunction_update);}
|
||||
|
||||
public:
|
||||
// @FPUB
|
||||
@ -205,7 +208,7 @@ public:
|
||||
TRecnotype operator -=(const TRecnotype npos) { return operator +=(-npos); }
|
||||
TRecnotype operator ++() { return operator +=(1); }
|
||||
TRecnotype operator --() { return operator -=(1); }
|
||||
TRecnotype pos() const { return _pos; }
|
||||
TRecnotype& pos() { return _pos; }
|
||||
TRecnotype items();
|
||||
TRecnotype size() const { return file().eod(); }
|
||||
|
||||
@ -223,7 +226,7 @@ public:
|
||||
const char* filter() const { return _filter; }
|
||||
void freeze(bool on = TRUE) { _frozen = on; }
|
||||
bool frozen() const { return _frozen; }
|
||||
void setfilter(const char* filter_expr) { filter(filter_expr); }
|
||||
void setfilter(const char* filter_expr, bool update=FALSE) { filter(filter_expr); _filter_update = update; }
|
||||
void setregion(const TRectype& from, const TRectype& to)
|
||||
{ filter(NULL,&from, &to); }
|
||||
|
||||
@ -232,6 +235,9 @@ public:
|
||||
TLocalisamfile& file(const char* name) const { return _if->lfile(name); }
|
||||
int repos() { return _if->position_rels(); }
|
||||
|
||||
TExpression* expression() const { return _fexpr; }
|
||||
FILTERFUNCTION filterfunction() const { return _filterfunction; }
|
||||
|
||||
void setkey() { file().setkey(_nkey); }
|
||||
void setkey(int nkey);
|
||||
int key() const { return _nkey; }
|
||||
@ -239,7 +245,7 @@ public:
|
||||
bool next_match(int lognum, const char* fl = NULL, int nk = 0);
|
||||
bool is_first_match(int ln);
|
||||
|
||||
void set_filterfunction(FILTERFUNCTION ff) { _filterfunction = ff; _lastrec = 0L;}
|
||||
void set_filterfunction(FILTERFUNCTION ff, bool update=FALSE) { _filterfunction = ff; _lastrec = 0L; _filterfunction_update = update;}
|
||||
bool has_filter() const { return _filter.not_empty() || _filterfunction; }
|
||||
|
||||
void save_status () { _if->save_status(); }
|
||||
@ -277,7 +283,7 @@ public:
|
||||
void set_name(const char* n) { _name = n; }
|
||||
void set_from(int f) { if (f > 0) f--; else f = 0; _from = f; }
|
||||
void set_to(int t) { _to = t; }
|
||||
|
||||
|
||||
int from() const { return _from; }
|
||||
int to() const { return _to; }
|
||||
int len(TRectype &rec) const;
|
||||
|
@ -209,10 +209,9 @@ void TSheet::handler(WINDOW win, EVENT* ep)
|
||||
select(nuo);
|
||||
if (ep->type == E_MOUSE_DBL)
|
||||
dispatch_e_char(win, K_ENTER);
|
||||
else if (_checkable && _check_enabled && !_disabled[nuo] && vec == nuo)
|
||||
else if (vec == nuo)
|
||||
{
|
||||
_checked.not(nuo);
|
||||
force_update();
|
||||
dispatch_e_char(win, K_SPACE);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -15,10 +15,12 @@
|
||||
#include <checks.h>
|
||||
#include <isam.h>
|
||||
#include <prefix.h>
|
||||
#include <codeb.h>
|
||||
|
||||
#define REFKEY "CAMPOKEY"
|
||||
#define VERKEY "ìpÙˆ¬cê<"
|
||||
|
||||
extern isfdptr *openf;
|
||||
HIDDEN long _stdlevel = 0;
|
||||
|
||||
long get_std_level()
|
||||
@ -66,6 +68,7 @@ void init_global_vars()
|
||||
if (SerNo && !muflag)
|
||||
fatal_box("Abnormal termination: check protection or serial number\n");
|
||||
#endif
|
||||
DB_init();
|
||||
}
|
||||
|
||||
void free_global_vars()
|
||||
@ -79,6 +82,7 @@ void free_global_vars()
|
||||
delete openrec;
|
||||
prefix_destroy();
|
||||
}
|
||||
DB_exit();
|
||||
}
|
||||
|
||||
|
||||
|
@ -56,8 +56,10 @@ long get_std_level();
|
||||
void init_global_vars();
|
||||
void free_global_vars();
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern void* operator new(unsigned);
|
||||
extern void operator delete(void*);
|
||||
#endif
|
||||
|
||||
// @END
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user