Modificato isam

git-svn-id: svn://10.65.10.50/trunk@3672 c028cbd2-c16b-5b4b-a496-9718f37d4682
This commit is contained in:
alex 1996-09-26 15:28:04 +00:00
parent 7a3e6da413
commit 837d492680
5 changed files with 635 additions and 1420 deletions

View File

@ -357,792 +357,7 @@ void CPutRec(logicname,recd,dirflg)
} }
/* /*
@($) zerodes FILES
@(ID)
Azzera il Tracciato Record "r".
@(FD)
@(ISV)
i,j = contatori.
@(FSV)
@(IN)
NON UTILIZZARE !!.
Se si utilizza spiegarne dettagliatamente il motivo.
@(FN)
*/
void zerordes(r)
RecDes *r; /* descrittore record */
{
int i,j ;
r->NFields = 0;
for (i = 0; i < MaxFields; i++)
{
strcpy(r->Fd[i].Name, "");
r->Fd[i].TypeF = NullF;
r->Fd[i].Len = 0;
r->Fd[i].Dec = 0;
r->Fd[i].RecOff = 0;
}
for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD;
r->NKeys = 0;
for (i = 1; i < MaxKeys; i++)
{
r->Ky[i].DupKeys = FALSE;
r->Ky[i].NkFields = 0;
for (j = 0; j < MKFields; j++) r->Ky[i].FieldSeq[j] = INVFLD;
for (j = 0; j < MKFields; j++) r->Ky[i].FromCh[j] = INVFLD;
for (j = 0; j < MKFields; j++) r->Ky[i].ToCh[j] = INVFLD;
}
}
/*
@($) setrdes FILES
@(ID)
Dato il tracciato record crea la struttura HASH (sortFd) per l'accesso veloce
ai campi.
@(FD)
@(ISV)
pos = indirizzo Hash.
i = contatore.
nf = variabile di lavoro.
tmppos = indirizzo hash per l'accesso ai campi.
@(FSV)
@(IN)
NON UTILIZZARE !!.
Se si utilizza spiegarne dettagliatamente il motivo.
@(FN)
*/
word setrdes(r)
RecDes *r; /* descrittore record */
{
int pos, tmppos, nf, i;
for (i = 0; i < MaxFields; i++) r->SortFd[i] = INVFLD;
if (r->NFields)
{
for (i = 0; i < r->NFields; i++)
{
nf = i;
pos = hashfun(r->Fd[nf].Name);
while (TRUE)
{
if (r->SortFd[pos] == INVFLD)
{
r->SortFd[pos] = (byte) nf;
break;
}
else
{
if (strcmp(r->Fd[r->SortFd[pos]].Name, r->Fd[nf].Name) <= 0)
{
pos++;
if (pos >= MaxFields)
pos = 0;
}
else
{
tmppos = r->SortFd[pos];
r->SortFd[pos] = (byte) nf;
nf = tmppos;
}
}
}
}
r->Fd[0].RecOff = 1;
for (i = 1; i < r->NFields; i++)
r->Fd[i].RecOff = r->Fd[i - 1].RecOff + r->Fd[i - 1].Len;
return(r->Fd[r->NFields - 1].RecOff + r->Fd[r->NFields - 1].Len);
}
return(0);
}
/*
@(SHF) Funzioni per la gestione dei campi dei record
@($) setdec FILES
@(ID)
Data la stringa "s" (contenente un numero) Aggiusta il numero dei decimali in
base a "dec".
@(FD)
@(ISV)
s1 = stringa di lavoro.
i = contatore.
l = lunghezza stringa s1.
carry = eventuale riporto approssimazione.
@(FSV)
@(IN)
NON UTILIZZARE !!.
Se si utilizza spiegarne dettagliatamente il motivo.
@(FN)
*/
void setdec(s,dec)
char *s; /* stringa che deve contenere un numero */
int dec; /* numero di decimali che deve avere il numero */
{
char *s1;
int i, l, carry;
if (LENGTH(s) == 0) strcpy(s, "0");
if ((s1 = strchr(s, ',')) != NULL) *s1 = '.';
s1 = strchr(s, '.');
if ((dec) && (s1 == NULL))
{
strcat(s, ".");
s1 = strchr(s, '.');
}
else
if (!dec)
{
if (s1 == NULL) return ;
l = LENGTH(s1); /* occhio verificare */
carry = (s1[1] >= '5');
*s1 = '\0';
while (carry)
{
s1--;
if (*s1 == '-') break;
if (*s1 == '9')
{
*s1 = '0';
if (s == s1) break;
}
else
{
(*s1)++;
carry = FALSE;
}
}
if (carry)
{
for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1];
s[(*s1 == '-')] = '1';
}
return;
}
s1++;
l = LENGTH(s1);
if (l > dec)
{
carry = (s1[dec] >= '5');
s1[dec] = '\0';
while (carry)
{
dec--;
if (s1[dec] == '9')
{
s1[dec] = '0';
if (!dec) break;
}
else
{
s1[dec]++;
carry = FALSE;
}
}
s1--;
while (carry)
{
s1--;
if (*s1 == '-') break;
if (*s1 == '9')
{
*s1 = '0';
if (s == s1) break;
}
else
{
(*s1)++;
carry = FALSE;
}
}
if (carry)
{
for (i = l; i > (*s1 == '-'); i--) s[i] = s[i - 1];
s[(*s1 == '-')] = '1';
}
}
else
while (l++ < dec) strcat(s1, "0");
}
/*
@($) hashfun FILES
@(ID)
Data la stringa "s" costruisce la chiave Hash.
@(FD)
@(ISV)
l = lunghezza della stringa "s".
w[82] = copia di lavoro della stringa "s".
temp = variabile di lavoro.
pw = puntatore ai caratteri della stringa.
Utilizza l'operatore OR Esclusivo.
@(FSV)
@(IN)
Restituisce l'indirizzo HASH.
@(FN)
*/
int hashfun(const char* s) /* stringa da eleborare */
{
char w[82];
unsigned short temp = 0, *pw = (unsigned short *)w;
int l = LENGTH(s);
strcpy(w, s);
if (ODD(l))
{
w[l++] = ' ';
w[l] = '\0';
}
while ((char *) pw < w + l)
{
temp ^= *pw;
pw++;
}
l = (short) (temp % (MaxFields - 3));
if (l < 0) l = -l;
return(l);
}
/*
@($) findfld FILES
@(ID)
Ricerca all'interno di un record il campo di nome "s".
@(FD)
@(ISV)
i= variabile di lavoro.
startp = variabile di lavoro.
cmp = variabile di lavoro.
@(FSV)
*/
int findfld(recd,s)
RecDes *recd; /* Descrittore record Tracciato Record */
char *s; /* stringa contenente il nome del campo */
{
int i, cmp, startp;
i = hashfun(s);
startp = i;
if (recd->SortFd[i] == INVFLD) return(-1);
do
{
if (!(cmp = strcmp(recd->Fd[recd->SortFd[i]].Name, s)))
return((int) (recd->SortFd[i]));
else
if (cmp > 0) return(-1);
else
if (++i >= MaxFields) i = 0;
if (recd->SortFd[i] == INVFLD) return(-1);
}
while (i != startp) ;
return(-1);
}
/*
@(#) CFieldSize FILES
@(ID)
Restituisce la lunghezza del campo.
@(FD)
@(ISV)
p = puntatore al campo.
@(FSV)
*/
unsigned int CFieldSize(fieldname,recd)
char *fieldname; /* nome del campo */
RecDes *recd; /* descrittore record */
{
int p;
if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Len);
else return(0);
}
/*
@(#) CFieldDec FILES
@(ID)
Restituisce il numero di decimali presenti nel campo.
@(FD)
@(ISV)
p = puntatore al campo.
@(FSV)
*/
unsigned int CFieldDec(fieldname,recd)
char *fieldname; /* nome del campo */
RecDes *recd; /* descrittore record */
{
int p;
if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].Dec);
else return(0);
}
/*
@(#) CFieldType FILES
@(ID)
Restituisce un intero rappresentante il tipo del campo.
@(FD)
@(ISV)
p = posizione all'interno del record del campo.
@(FSV)
*/
int CFieldType(fieldname,recd)
char *fieldname; /* nome del campo */
RecDes *recd; /* descrittore record */
{
int p;
if ((p = findfld(recd, fieldname)) != -1) return(recd->Fd[p].TypeF);
else return(NullF);
}
/*
@($) getfrmt FILES
@(ID)
Prepara il il formato per dsprintf per il campo "nf" del tracciato record "recd".
@(FD)
@(ISV)
len = lunghezza del campo.
dec = numero di decimali presenti nel campo.
@(FSV)
*/
void getfrmt(recd,nf,frm)
RecDes *recd; /* descrittore record */
int nf; /* numero campo */
char *frm; /* stringa in formato per dsprintf */
{
int len, dec;
strcpy(frm, "");
len = recd->Fd[nf].Len;
dec = recd->Fd[nf].Dec;
if (recd->Fd[nf].TypeF == IntF) sprintf(frm, "%%%dd", len);
else
if (recd->Fd[nf].TypeF == Int4F) sprintf(frm, "%%%dld", len);
else
if (recd->Fd[nf].TypeF == RealF) sprintf(frm, "%%%d.%dt",len, dec);
/*cambiare */
else
if (recd->Fd[nf].TypeF == WordF) sprintf(frm, "%%%du", len);
else
if (recd->Fd[nf].TypeF == ZeroF) sprintf(frm, "%%0%dd", len);
else
if (recd->Fd[nf].TypeF == EZeroF) sprintf(frm, "%%0%dld", len);
}
/*
@(#) CGetField FILES
@(ID)
Estrae il valore di un campo dal record e lo pone in "fout".
Restituisce un eventuale codice errore.
@(FD)
@(ISV)
r = variabile che contiene l'eventuale codice errore.
p = variabile per la chiamata di "findfld".
s = puntatore alla zona di memoria allocata.
frm= stringa per contenere un formato per la dsprintf.
@(FSV)
@(IN)
Si osservi che "fout" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere.
@(FN)
*/
#ifndef FOXPRO
/*
@(#) CPutField FILES
@(ID)
Scrive il contenuto della variabile puntata da "fin" nel campo "fieldname" del record.
Restituisce un eventuale codice errore.
@(FD)
@(ISV)
r = variabile che contiene l'eventuale codice errore.
p = variabile per la chiamata di "findfld".
s = puntatore alla zona di memoria allocata.
frm= stringa per contenere un formato per la dsprintf.
@(FSV)
@(IN)
Si osservi che "fin" deve essere un puntatore a una variabile di tipo coerente con il campo da leggere.
@(FN)
*/
int CPutField(fieldname,recd,fin,recout)
char *fieldname; /* nome del campo */
RecDes *recd; /* descrittore record */
void *fin; /* puntatore al valore da scrivere */
RecType recout; /* buffer contenetnte il record */
{
int p;
char s[256], frm[30];
strcpy(s, "");
p = findfld(recd, fieldname);
getfrmt(recd, p, frm);
if (recd->Fd[p].TypeF == AlfaF) strcpy(s, (char *) fin);
else
if ((recd->Fd[p].TypeF == IntF) || (recd->Fd[p].TypeF == ZeroF))
sprintf(s, frm, *((int *) fin));
else
if ((recd->Fd[p].TypeF == Int4F) || (recd->Fd[p].TypeF == EZeroF))
sprintf(s, frm, *((long *) fin)) ;
else
#ifndef __LONGDOUBLE__
if (recd->Fd[p].TypeF == RealF) dsprintf(s, frm, (DEC *) fin);
else
#endif
if (recd->Fd[p].TypeF == WordF) sprintf(s, frm, *((unsigned *) fin)) ;
else
if (recd->Fd[p].TypeF == CharF)
{
s[0] = *((char *) fin);
s[1] = '\0';
}
else
if (recd->Fd[p].TypeF == BoolF)
{
s[0] = *((BOOLEAN*) fin) ? 'X' : ' ';
s[1] = '\0';
}
return CPutFieldBuff(fieldname, recd, s, recout);
}
#endif /* FOXPRO */
/*
@(#) CGetFieldBuff FILES
@(ID)
Estrae il valore di un campo dal record e lo pone nella stringa "s".
Restituisce un eventuale codice errore.
@(FD)
@(ISV)
p = puntatore al campo.
i = contatore.
Off = offest in byte all'interno del record per il campo in oggetto.
len = lunghezza campo.
s1 = stringa di lavoro.
d = data in formato stringa.
@(FSV)
@(IN)
Utilizzato per il Data Entry.
@(FN)
*/
int CGetFieldBuff(fieldname,recd,recin,s)
char *fieldname; /* nome del campo */
RecDes *recd; /* descrittore record */
RecType recin; /* buffer contenente il record */
char *s; /* stringa per l'output */
{
int p, i;
char *s1;
if ((p = findfld(recd, fieldname)) != -1)
{
const int tipo = recd->Fd[p].TypeF;
unsigned int off = recd->Fd[p].RecOff;
byte len = recd->Fd[p].Len;
if ((tipo != AlfaF) && (tipo != DateF) && (tipo != ZeroF) && (tipo != EZeroF))
{
while ((recin[off] == ' ') && (len))
{
off++;
len--;
}
if ((tipo != RealF) && (tipo != CharF))
{
while ((recin[off] == '0') && (len))
{
off++;
len--;
}
}
}
else
if ((tipo == ZeroF) || (tipo == EZeroF))
{
char* c = &recin[off];
for (i = 0; i < len; i++, c++)
{
if (*c == ' ')
*c = '0';
else
if (*c != '0')
break;
}
if (i == len)
{
off += len;
len = 0;
}
}
if (len)
{
s1 = recin + off;
for (i = 0; i < len; i++) s[i] = s1[i];
s[len] = '\0';
while ((len) && (s[len - 1] == ' ')) s[--len] = '\0';
}
else strcpy(s, "");
if ((tipo == RealF))
if ((s1 = strchr(s, ',')) != NULL) *s1 = '.';
return(0);
}
else
{
strcpy(s, "");
return(-1);
}
}
/*
@(#) CPutFieldBuff FILES
@(ID)
Scrive il contenuto della stringa "s" nel campo "fieldname" del record.
Restituisce un eventuale codice errore.
@(FD)
@(ISV)
p = puntatore al campo.
i = contatore.
l = variabile di lavoro.
off = offest in byte all'interno del record per il campo in oggetto.
len = lunghezza campo.
s1,s2 = stringa di lavoro.
d = data in formato stringa.
@(FSV)
@(IN)
Utilizzato per il Data Entry
@(FN)
*/
int CPutFieldBuff(fieldname,recd,s,recout)
char *fieldname; /* nome del campo */
RecDes *recd; /* descrittore record */
char *s; /* stringa contenente il valore da scrivere nel campo */
RecType recout; /* buffer contenente il record */
{
int p, off, len, l, i;
char *s1;
/*
char *s2;
s2 = malloc(256);
*/
char s2[256];
strcpy(s2, s);
if ((p = findfld(recd, fieldname)) != -1)
{
off = recd->Fd[p].RecOff;
len = recd->Fd[p].Len;
if (recd->Fd[p].TypeF == RealF) setdec(s2, recd->Fd[p].Dec);
l = LENGTH(s2);
if (l > len)
l = len;
s1 = recout + off ;
for (i = 0; i < l ; i++) s1[i] = s2[i] ;
if ((recd->Fd[p].TypeF == IntF) ||
(recd->Fd[p].TypeF == Int4F) ||
(recd->Fd[p].TypeF == WordF) ||
(recd->Fd[p].TypeF == RealF) ||
(recd->Fd[p].TypeF == ZeroF) ||
(recd->Fd[p].TypeF == EZeroF))
{
char c;
if ((recd->Fd[p].TypeF == ZeroF) ||
(recd->Fd[p].TypeF == EZeroF))
c = '0';
else c = ' ';
if (l == 0) s1[l++] = '0';
while (l < len)
{
for (i = l; i > 0; i--) s1[i] = s1[i - 1];
s1[0] = c;
l++;
}
}
else
while (l < len) s1[l++] = ' ';
/* free(s2); */
return(0);
}
else
{
strcpy(s, "");
/* free(s2); */
return(-1);
}
}
/*
@(#) CZeroField FILES
@(ID)
Azzera un campo.
@(FD)
@(ISV)
p = puntatore al campo.
s = stringa messaggio.
@(FSV)
*/
int CZeroField(fieldname,recd,recout)
char *fieldname; /* nonme del campo */
RecDes *recd; /* descrittore record */
RecType recout; /* buffer contenente il record */
{
int p;
if ((p = findfld(recd, fieldname)) != -1)
{
if (recd->Fd[p].TypeF == DateF)
memset(recout + recd->Fd[p].RecOff, '0', recd->Fd[p].Len);
else
{
memset(recout + recd->Fd[p].RecOff, Blank, recd->Fd[p].Len);
if ((recd->Fd[p].TypeF == IntF) ||
(recd->Fd[p].TypeF == Int4F) ||
(recd->Fd[p].TypeF == WordF))
{
*(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0';
}
else
if (recd->Fd[p].TypeF == RealF)
{
if (recd->Fd[p].Dec)
{
memset(recout + recd->Fd[p].RecOff + recd->Fd[p].Len -
recd->Fd[p].Dec - 2, '0', recd->Fd[p].Dec + 2);
*(recout + recd->Fd[p].RecOff + recd->Fd[p].Len -
recd->Fd[p].Dec - 1) = '.';
}
else *(recout + recd->Fd[p].RecOff + recd->Fd[p].Len - 1) = '0';
}
return(NoErr);
}
}
else return(-1);
return(NoErr);
}
/*
@(#) CZeroRec FILES
@(ID)
Azzera tutto il record.
@(FD)
@(ISV)
i = contatore.
junk = variabile spazzatura per la chiamata di CZeroField.
@(FSV)
*/
void CZeroRec(recd,recout)
RecDes *recd; /* descrittore record */
RecType recout; /* buffer contenente il record */
{
int i, junk;
IRecallRec(recout) ;
for (i = 0; i < recd->NFields; i++) junk = CZeroField(recd->Fd[i].Name,
recd, recout);
}
/*
@($) prefname FILES @($) prefname FILES
@(ID) @(ID)

View File

@ -121,18 +121,6 @@ extern "C" {
/* @(:) 2.3.01.144 */ /* @(:) 2.3.01.144 */
void zerordes(RecDes *); void zerordes(RecDes *);
word setrdes(RecDes *); word setrdes(RecDes *);
int findfld(RecDes *,char *);
unsigned int CFieldSize(char *, RecDes *);
unsigned int CFieldDec(char *, RecDes *);
int CFieldType(char *, RecDes *);
int CGetField(char *, RecDes *, RecType, void *);
int CPutField(char *, RecDes *, void *, RecType);
int CGetFieldBuff(char *, RecDes *, RecType, char *);
int CPutFieldBuff(char *, RecDes *, char *, RecType);
int CZeroField(char *, RecDes *, RecType);
void CZeroRec(RecDes *, RecType);
int CBuildKey(RecDes *,int ,RecType, char *);
int CCalcLenKey(RecDes *,int);
char *CGetPref(void); char *CGetPref(void);
void CPutPref(char *); void CPutPref(char *);
char *CAddPref(char *); char *CAddPref(char *);
@ -140,11 +128,6 @@ extern "C" {
char *CInsPref(char *, int); char *CInsPref(char *, int);
/* @(:) 2.3.01.144 */ /* @(:) 2.3.01.144 */
char *CGetIdxName(char *); char *CGetIdxName(char *);
/* @(!) 2.3.01.155 */
char **getlinesdf(char *, int *);
void loadrfd(RecDes *, RecType, char **, char **);
void dumprfd(RecDes *, RecType, char **, int *, int *, int *, char *);
/* @(:) 2.3.01.155 */
#ifdef __cplusplus #ifdef __cplusplus
}; };

View File

@ -1025,7 +1025,7 @@ bool TCursor::ok() const
if (key < (const char *) kf || (kt.not_empty() && kt < (const char *) key.left(kt.len()))) if (key < (const char *) kf || (kt.not_empty() && kt < (const char *) key.left(kt.len())))
return FALSE; return FALSE;
if (_filter_update || _filterfunction_update) _if->update(); if (update_relation()) _if->update();
if ((_filterfunction ? _filterfunction(_if) : TRUE ) && if ((_filterfunction ? _filterfunction(_if) : TRUE ) &&
(_fexpr ? __evalcondition(*_if, _fexpr) : TRUE)) (_fexpr ? __evalcondition(*_if, _fexpr) : TRUE))
return TRUE; return TRUE;
@ -2001,7 +2001,7 @@ bool TRecord_array::destroy_row(
if (ok && pack) if (ok && pack)
{ {
for (int i = size()-1; i > index; i--) for (int i = size()-1; i >= index; i--)
{ {
TRectype* r = (TRectype*)objptr(i); TRectype* r = (TRectype*)objptr(i);
if (r != NULL) if (r != NULL)

View File

@ -396,7 +396,7 @@ protected:
void filter(const char* filter, const TRectype* from = NULL, const TRectype* to = NULL); void filter(const char* filter, const TRectype* from = NULL, const TRectype* to = NULL);
// @cmember Indica se e' possibile fare l'update sulla relazione (se e' possibile // @cmember Indica se e' possibile fare l'update sulla relazione (se e' possibile
// sia sull'espressione-filtro che sulla funzione-filtro) // sia sull'espressione-filtro che sulla funzione-filtro)
bool update_relation() bool update_relation() const
{return (_filter_update || _filterfunction_update);} {return (_filter_update || _filterfunction_update);}
// @access Public Member // @access Public Member

View File

@ -54,13 +54,20 @@ int TTable::last(word lockop)
int TTable::next(word lockop) int TTable::next(word lockop)
{ {
const TRecnotype nrec = recno();
const TRecnotype nrec = recno();
/*
if (nrec != filehnd()->RecNo) if (nrec != filehnd()->RecNo)
{ {
read(); read();
if (bad()) return status(); if (bad())
{
if (status() == _iskeynotfound)
setstatus(NOERR);
return status();
}
} }
*/
TBaseisamfile::next(lockop); TBaseisamfile::next(lockop);
if (_tabname != (const char *)_cod) if (_tabname != (const char *)_cod)
@ -75,10 +82,20 @@ int TTable::next(word lockop)
int TTable::prev(word lockop) int TTable::prev(word lockop)
{ {
read();
if (bad()) return status();
TRecnotype nrec = recno(); const TRecnotype nrec = recno();
/*
if (nrec != filehnd()->RecNo)
{
read();
if (bad())
{
if (status() == _iskeynotfound)
setstatus(NOERR);
return status();
}
}
*/
TBaseisamfile::prev(lockop); TBaseisamfile::prev(lockop);
if (_tabname != (const char *)_cod) if (_tabname != (const char *)_cod)