home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Jason Aller Floppy Collection
/
125.img
/
PRO-C4.ZIP
/
BENCH1.ZIP
/
BENCH
/
IEMBAY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-28
|
34KB
|
1,195 lines
/* ==( io/src/iembay.c )== */
/* ----------------------------------------------- */
/* Pro-C Copyright (C) 1988 - 1990 Vestronix Inc. */
/* Modification to this source is not supported */
/* by Vestronix Inc. */
/* All Rights Reserved */
/* ----------------------------------------------- */
/* Written VvA 01-Nov-88 for v.1.3 */
/* Modified VvA 11-Apr-90 see comments below */
/* ----------------------------------------------- */
/* %W% (%H% %T%) */
/*
* Modifications
*
* 11-Apr-90 VvA - adapted to V.2
*/
/* Emerald Bay specific I/O calls via general IOGEN.C interface */
# include <stdio.h>
# include <iodef.h>
# include <iomsg.h>
# include <proc.io>
# include <bench.h>
# include <iosup.h>
# include <eb.h>
/* Function prototypes */
# ifdef ANSI
static int i_addrec(int, char *);
static int i_close_file(int, char *);
static int i_commit(int, char *);
static int i_delrec(int, char *);
static int i_filename(int, char *);
static int i_findkey(int, char *);
static int i_firstkey(int, char *);
static int i_init_file(int, char *);
static int i_lastkey(int, char *);
static int i_lockrec(int, char *);
static int i_login(int, char *);
static int i_logoff(int, char *);
static int i_nextrec(int, char *);
static int i_open_file(int, char *);
static int i_prevrec(int, char *);
static int i_rereadrec(int, char *);
static int i_rollback(int, char *);
static int i_selectinx(int, char *);
static int i_transact(int, char *);
static int i_unlock_rec(int, char *);
static int i_updrec(int, char *);
static int create_file(int);
static int length_check(int);
static int load_keys(int);
static int buff2eb(int, char *);
static int eb2buff(int, char *, char *);
static int io_xlate(int, int, char *);
static void setupkey(int, char *, char *, int *);
# else
static int i_addrec();
static int i_close_file();
static int i_commit();
static int i_delrec();
static int i_filename();
static int i_findkey();
static int i_firstkey();
static int i_init_file();
static int i_lastkey();
static int i_lockrec();
static int i_login();
static int i_logoff();
static int i_nextrec();
static int i_open_file();
static int i_prevrec();
static int i_rereadrec();
static int i_rollback();
static int i_selectinx();
static int i_transact();
static int i_unlock_rec();
static int i_updrec();
static int create_file();
static int length_check();
static int load_keys();
static int buff2eb();
static int eb2buff();
static int io_xlate();
static void setupkey();
# endif
#define EB_FLDLEN 512 /* Emerald Bay field length limit */
/*
* structure for Emerald Bay specific values
*/
struct ixinfo
{
int ix_num; /* index handle from Emerald Bay */
char ixname[FILENAME_LEN];
NDXARG *ndxdesc;
};
struct emb_def
{
FLDARG *flddesc;
TEXTOBJECT *txtfld[MAX_FLDS]; /* ptrs only, allocated if a memo fld */
struct ixinfo fdkey[MAX_KEYS+1];
};
static struct emb_def efd[MAX_FILES];
static char usrname[21] = { "" };
static char pasword[21] = { "" };
static char keybuff[EB_FLDLEN * MAX_SEGS + MAX_SEGS];
static int dberrno; /* error code global */
static int dbhdl; /* global handle for Emerald Bay database file */
static int EB_OPENMODE;
static int EB_SHAREMODE;
/*
*
* Interface Functions
*
*/
/*
* Sets up File Name - Name is passed in buffer
*/
static int i_filename(fd_sys, buffer)
int fd_sys;
char *buffer;
{
for ( ; (*buffer != '.') && (*buffer != NULL); buffer++)
;
*buffer = NULL;
return(IOGOOD);
}
/*
* Overall initialization
* - called once only, each time set of files is opened
* - overall database name is passed in buffer
*/
static int i_init_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if (!*buffer || (buffer == NULL)) /* if no overall name passed */
strcpy(buffer, "PRO_C1");
if ((dbhdl = DbLogin(buffer, pasword)) < 0) /* open the database */
{
if (dbhdl != DBNODB)
return(io_xlate(fd_sys, dbhdl, "EB INIT1"));
if (DbCreate(buffer, pasword) == -1) /* or try to create it */
{
errmsg("Database file pair %s could not be created", buffer);
return(IOERROR);
}
if ((dbhdl = DbLogin(buffer, pasword)) < 0)
{
errmsg("Database %s just created cannot be opened", buffer);
return(IOERROR);
}
}
return(IOGOOD);
}
/*
* File open function - required parameters are in fd structure.
* - dbhdl contains the overall database handle for all operations,
* until the files are closed
*/
static int i_open_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int tbhdl;
char tblname[FILENAME_LEN];
struct fd_def *fptr = &fd[fd_sys];
strcpy(tblname, fptr->filname); /* table name in database */
if (fptr->openmode & OUTPUT_FLAG) /* create call destroys old file */
{
if ((dberrno = DbDropTable(dbhdl, tblname)) < 0)
return(io_xlate(fd_sys, dberrno, "EB OUTP"));
create_file(fd_sys);
}
if ((tbhdl = DbOpenTable(dbhdl, tblname)) < 0)
{
if (fptr->openmode & INPUT_FLAG)
return(io_xlate(fd_sys, tbhdl, "EB OPEN1"));
if (create_file(fd_sys) != IOGOOD)
return(IOERROR);
free(efd[fd_sys].flddesc); /* will be reloaded in lengthcheck */
}
else /* file & indexes have been opened successfully */
fptr->fd_num = tbhdl;
EB_OPENMODE = (fptr->openmode & INPUT_FLAG) ? READONLY : READWRITE;
EB_SHAREMODE = (fptr->openmode & P_EXCLUSIVE) ? EXCLUSIVE : SHARE;
dberrno = DbSetLockMode(fptr->fd_num, EB_OPENMODE, EB_SHAREMODE);
if (dberrno < 0)
return(io_xlate(fd_sys, dberrno, "EB OPEN2"));
if (length_check(fd_sys) != IOGOOD)
{
errmsg(FileRecLenChg_s, fptr->filname);
return(IOERROR);
}
return(IOGOOD);
}
/*
* Checks field count and char field lengths for changes since last use,
* and loads the Emerald Bay field and index parameters.
* - this is called even for a just-created database table
* - Emerald Bay adds a rec_no field #0 to all tables, which has to be
* taken into account in reloading established tables & indexes. This
* is taken into account for the length check.
*/
static int length_check(fd_sys)
int fd_sys;
{
int j, fcnt, kcnt, nsegs = 0, ix, tmperror;
char ndxname[FILENAME_LEN];
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
if ((fcnt = DbGetNumberOfFields(fptr->fd_num)) < 0)
return(io_xlate(fd_sys, fcnt, "EB LCHK1"));
if (fcnt != fptr->fld_cnt+1) /* field count has changed */
return(IOERROR);
/*
* Field reallocation and reloading takes into account the 0th field used by
* Emerald Bay for rec_no
*/
eptr->flddesc = (FLDARG *)alloc(sizeof(FLDARG) * (fcnt+1));
if ((dberrno = DbGetNamedFieldInfo(fptr->fd_num, "rec_no", &(eptr->flddesc[0]))) < 0)
return(io_xlate(fd_sys, dberrno, "EB LCHK2A"));
for (j = 1; j < fcnt; j++) /* load and check field information */
{
if ((dberrno = DbGetNamedFieldInfo(fptr->fd_num, fptr->flds[j-1].fldname, &(eptr->flddesc[j]))) < 0)
return(io_xlate(fd_sys, dberrno, "EB LCHK2B"));
tmperror = FALSE;
if (fptr->flds[j-1].fldlen != eptr->flddesc[j].fldlen)
{
tmperror = TRUE;
if ((fptr->flds[j-1].fldtype == FLTTYP) && (eptr->flddesc[j].fldlen == sizeof(double)))
tmperror = FALSE;
if ((fptr->flds[j-1].fldtype == LOGTYP) && (eptr->flddesc[j].fldlen == sizeof(int)))
tmperror = FALSE;
if ((fptr->flds[j-1].fldtype == DATTYP) && (eptr->flddesc[j].fldlen == sizeof(long)))
tmperror = FALSE;
if ((fptr->flds[j-1].fldtype == MEMTYP))
tmperror = FALSE;
}
if (tmperror)
return(IOERROR);
}
/*
* Note that the keyinfo structure index will be 1 less than the fdkey
* structure index, to allow for Emerald Bay's reserved 0th rec_no index.
*/
strcpy(eptr->fdkey[0].ixname, "rec_no"); /* Emerald Bay reserved */
strcpy(ndxname, fptr->filname); /* index names match their file */
if ((ix = strlen(ndxname)) > 7) /* ix is index id offset */
ix = 7;
ndxname[ix] = '\0';
strcat(ndxname, "0");
for (kcnt = 0; kcnt < fptr->key_cnt; kcnt++)
{
ndxname[ix] = (char)(kcnt + 49); /* sequential index names */
strcpy(eptr->fdkey[kcnt+1].ixname, ndxname);
}
/*
* Note that this load counts one more than keyinfo structure's number of
* keys to allow for the 0th rec_no index.
*/
for (j = 0; j <= fptr->key_cnt; j++) /* load index information */
{
eptr->fdkey[j].ndxdesc = (NDXARG *)alloc(sizeof(NDXARG));
if ((dberrno = DbGetNamedIndexInfo(fptr->fd_num, eptr->fdkey[j].ixname, eptr->fdkey[j].ndxdesc)) < 0)
return(io_xlate(fd_sys, dberrno, "EB LCHK3"));
eptr->fdkey[j].ix_num = eptr->fdkey[j].ndxdesc->ndxid;
}
for (j = 0; j < fptr->fld_cnt; j++) /* if a memo, allocate text object */
if (fptr->flds[j].fldtype == MEMTYP)
eptr->txtfld[j+1] = DbTextInit(fptr->fd_num, eptr->flddesc[j+1].fldid);
return(IOGOOD);
}
/*
* Creates a new table.
* - at this point, PRO-C and Emerald Bay fields still have the same
* index into field information structure arrays.
*/
static int create_file(fd_sys)
int fd_sys;
{
int j;
int tbhdl;
char dfname[FILENAME_LEN];
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
strcpy(dfname, fptr->filname);
eptr->flddesc = (FLDARG *)alloc(sizeof(FLDARG) * (fptr->fld_cnt+2));
for (j = 0; j < fptr->fld_cnt; j++) /* load field descriptions */
{
strcpy(eptr->flddesc[j].fldname, fptr->flds[j].fldname);
switch(fptr->flds[j].fldtype)
{
case CHRTYP :
eptr->flddesc[j].fldtype = DTYPSTR;
eptr->flddesc[j].fldlen = fptr->flds[j].fldlen;
break;
case INTTYP :
eptr->flddesc[j].fldtype = DTYPINT;
break;
case LNGTYP :
eptr->flddesc[j].fldtype = DTYPLNG;
break;
case FLTTYP :
case DBLTYP :
eptr->flddesc[j].fldtype = DTYPDBL;
break;
case DATTYP :
if (fptr->flds[j].fldlen == 6)
eptr->flddesc[j].fldtype = DTYPDAT;
else
eptr->flddesc[j].fldtype = DTYPLNG;
break;
case MEMTYP :
eptr->flddesc[j].fldtype = DTYPBIN;
break;
case LOGTYP :
eptr->flddesc[j].fldtype = DTYPLOG;
break;
}
eptr->flddesc[j].fldrepl = 0;
eptr->flddesc[j].fldreq = FALSE; /* is field required? */
eptr->flddesc[j].flddefflag = FALSE; /* is default supplied? */
}
eptr->flddesc[j].fldname[0] = '\0';
if ((tbhdl = DbMakeTable(dbhdl, dfname, eptr->flddesc)) < 0)
return(io_xlate(fd_sys, tbhdl, "EB CRT1"));
if ((tbhdl = DbOpenTable(dbhdl, dfname)) < 0)
return(io_xlate(fd_sys, tbhdl, "EB CRT2"));
fptr->fd_num = tbhdl;
if ((dberrno = DbGetNamedFieldInfo(fptr->fd_num, "rec_no", &(eptr->flddesc[0]))) < 0)
return(io_xlate(fd_sys, dberrno, "EB CRT3A"));
for (j = 1; j <= fptr->fld_cnt; j++) /* complete the field info */
{
if ((dberrno = DbGetNamedFieldInfo(fptr->fd_num, fptr->flds[j-1].fldname, &(eptr->flddesc[j]))) < 0)
return(io_xlate(fd_sys, dberrno, "EB CRT3B"));
}
if (load_keys(fd_sys) > 0) /* create indexes */
{
free(eptr->flddesc); /* will be reloaded in lengthcheck */
return(IOGOOD);
}
else
return(IOERROR);
}
/*
* Load key information.
* - this is called only when the file is being created
* - creation of indexes must be done in non-shared (personal engine) mode
* - index names are created by adding sequential numbers to the name of
* the data table to which they refer.
* - assignment of values to Emerald Bay information structures already
* takes into account the reserved field 0 for the record number,
* although this information is not yet used here
* - this information is reloaded in length_check() after this function
* has been completed
*/
static int load_keys(fd_sys)
int fd_sys;
{
int ndxid, kcnt, fx, j, nkeys = 0;
NDXARG *tndxdesc;
char ndxname[FILENAME_LEN];
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
tndxdesc = (NDXARG *)alloc(sizeof(NDXARG));
strcpy(ndxname, fptr->filname); /* index names match their file */
if ((ndxid = strlen(ndxname)) > 7) /* ndxid is index id offset */
ndxid = 7;
ndxname[ndxid] = '\0';
strcat(ndxname, "0");
for (kcnt = 0; kcnt < fptr->key_cnt; kcnt++)
{
ndxname[ndxid] = (char)(nkeys + 49); /* sequential index names */
strcpy(tndxdesc->ndxname, ndxname);
tndxdesc->ndxcase = TRUE; /* make the key case sensitive */
for (j = 0; j < MAXNDX; j++)
tndxdesc->ndxatr[j] = 0;
tndxdesc->ndxtype = (fptr->keys[kcnt].keytype == KEY_UNIQUE) ? TRUE : FALSE;
for (j = 0; j < fptr->keys[kcnt].segcount; j++)
{
fx = fptr->keys[kcnt].fldindex[j];
tndxdesc->ndxatr[j] = eptr->flddesc[fx+1].fldid;
}
if ((dberrno = DbMakeIndex(fptr->fd_num, tndxdesc)) < 0)
{
nkeys = -1;
free(tndxdesc);
io_xlate(fd_sys, dberrno, "EB ICRT");
break;
}
nkeys++; /* increment key count */
}
free(tndxdesc);
return(nkeys);
}
/*
* File close function.
* - DbCloseTable function closes all indexes associated with the table
* - DbLogout and DbExit close the overall database after all the
* individual tables are closed
*/
static int i_close_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int i, j = 0;
for (j = 0; j < fd[fd_sys].fld_cnt; j++) /* deallocate memo buffers */
if (fd[fd_sys].flds[j].fldtype == MEMTYP)
DbTextClose(efd[fd_sys].txtfld[j+1]);
if ((dberrno = DbCloseTable(fd[fd_sys].fd_num)) < 0)
return(io_xlate(fd_sys, dberrno, "EB CLOSE1"));
fd[fd_sys].active = NO;
for (i = 0; i < MAX_FILES; i++) /* how many tables are still open? */
if (fd[i].active == YES)
j++;
if (!j) /* close database if all tables are now closed */
{
if ((dberrno = DbLogout(dbhdl)) < 0)
{
errmsg("Error closing Emerald Bay database file");
return(IOERROR);
}
DbExit();
}
return(IOGOOD);
}
/*
* Index is selected in IOGEN.
* - fd[fd_sys].cur_key refers to the keyinfo structure for PRO-C
* - when referring to fdkey structure, add 1 to the value to bring it
* into line with Emerald Bay's 0th rec_no index.
*/
static int i_selectinx(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* Find a record by key value
*/
static int i_findkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ck, klen;
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
ck = fptr->cur_key;
setupkey(fd_sys, buffer, keybuff, &klen);
if (fptr->exact)
dberrno = DbSearch(fptr->fd_num, eptr->fdkey[ck+1].ix_num, keybuff, klen, EQUAL);
else
dberrno = DbSearch(fptr->fd_num, eptr->fdkey[ck+1].ix_num, keybuff, klen, GREATEQ);
if (dberrno < 0)
return io_xlate(fd_sys, dberrno, "EB FIND1");
if (i_lockrec(fd_sys, buffer) == IOGOOD)
return(eb2buff(fd_sys, buffer, "EB FIND2"));
return(IOERROR);
}
/*
* Find first record in the file
*/
static int i_firstkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ck;
fd[fd_sys].exact = 0;
ck = fd[fd_sys].cur_key;
if ((dberrno = DbFirst(fd[fd_sys].fd_num, efd[fd_sys].fdkey[ck+1].ix_num)) < 0)
return(io_xlate(fd_sys, dberrno, "EB FRST1"));
if (i_lockrec(fd_sys, buffer) == IOGOOD)
return(eb2buff(fd_sys, buffer, "EB FRST2"));
return(IOERROR);
}
/*
* Find last physical record in the file
*/
static int i_lastkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ck;
ck = fd[fd_sys].cur_key;
if ((dberrno = DbLast(fd[fd_sys].fd_num, efd[fd_sys].fdkey[ck+1].ix_num)) < 0)
{
if (dberrno == -1) /* IOEOF return if file is empty */
return(IOEOF);
return(io_xlate(fd_sys, dberrno, "EB LAST1"));
}
if (i_lockrec(fd_sys, buffer) == IOGOOD)
return(eb2buff(fd_sys, buffer, "EB LAST2"));
return(IOERROR);
}
/*
* Find next record in the file
* - uses Emerald Bay's DbKeyCheck function in exact matches to determine
* if the new key matches the retained earlier record's key
*/
static int i_nextrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ck, klen;
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
i_unlock_rec(fd_sys, buffer); /* unlock current record */
ck = fptr->cur_key;
setupkey(fd_sys, buffer, keybuff, &klen); /* former key for check */
if ((dberrno = DbNext(fptr->fd_num, eptr->fdkey[ck+1].ix_num)) < 0)
{
if (dberrno == -1)
return(IOEOF);
return(io_xlate(fd_sys, dberrno, "EB NEXT1"));
}
if (fptr->exact && (DbKeyCheck(fptr->fd_num, eptr->fdkey[ck+1].ix_num, keybuff, klen) != 0))
return(IONONEXT); /* next record does not match exactly */
if (i_lockrec(fd_sys, buffer) == IOGOOD)
return(eb2buff(fd_sys, buffer, "EB NEXT2"));
return(IOERROR);
}
/*
* Find previous record in the file
* - uses Emerald Bay's DbKeyCheck function in exact matches to determine
* if the new key matches the retained earlier record's key
*/
static int i_prevrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ck, klen;
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
i_unlock_rec(fd_sys, buffer); /* unlock current record */
ck = fptr->cur_key;
setupkey(fd_sys, buffer, keybuff, &klen); /* former key for check */
if ((dberrno = DbPrev(fptr->fd_num, eptr->fdkey[ck+1].ix_num)) < 0)
{
if (dberrno == -1)
return(IOTOF);
return(io_xlate(fd_sys, dberrno, "EB PREV1"));
}
if (fptr->exact && (DbKeyCheck(fptr->fd_num, eptr->fdkey[ck+1].ix_num, keybuff, klen) != 0))
return(IONONEXT); /* prev record does not match exactly */
if (i_lockrec(fd_sys, buffer) == IOGOOD)
return(eb2buff(fd_sys, buffer, "EB PREV2"));
return(IOERROR);
}
/*
* Re-read/reposition record pointer function - if required
*/
static int i_rereadrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* Sets up a key string for record retrieval on current index
* - calls Emerald Bay's DbMakeSearchKey function to set up target keys
* packed to match the index data storage; multiple segments are
* incorporated into the function call, if applicable
* - to accommodate different key types, an array of unions of the
* available field types is used, using NULL for unused key segments
* - key pattern string also passed to DbMakeSearchKey sorts out the
* arguments to this varargs function
* - Emerald Bay allows up to six segments per key
*/
static void setupkey(fd_sys, buff, kbuff, klen)
int fd_sys;
char *buff, *kbuff;
int *klen;
{
int j, ck, toff, tlen, fx, tkey;
float ftmp;
double dtmp;
char keypat[7];
struct fd_def *fptr = &fd[fd_sys];
union {
char *stmp;
int itmp;
long ltmp;
double dtmp;
} v[MAXNDX];
ck = fptr->cur_key;
keypat[0] = '\0';
for (j = 0; j < MAXNDX; j++) /* blank out longest union member type */
v[j].dtmp = (double)0;
for (j = 0; j < fptr->keys[ck].segcount; j++)
{
toff = fptr->keys[ck].segstart[j];
tlen = fptr->keys[ck].seglen[j];
fx = fptr->keys[ck].fldindex[j];
tkey = fptr->flds[fx].fldtype;
if (tkey == FLTTYP)
{
bytecpy(&ftmp, &buff[toff], tlen);
dtmp = (double)ftmp;
tlen = sizeof(double);
}
if (tkey == DATTYP) /* stored as julian date (long int) */
tlen = sizeof(long);
switch(tkey) /* get key values from PRO-C buffer */
{
case CHRTYP :
v[j].stmp = alloc(tlen+1);
strncpy(v[j].stmp, &buff[toff], tlen);
v[j].stmp[tlen] = '\0';
strcat(keypat, "s");
break;
case INTTYP :
bytecpy(&v[j].itmp, &buff[toff], tlen);
strcat(keypat, "i");
break;
case DATTYP :
case LNGTYP :
bytecpy(&v[j].ltmp, &buff[toff], tlen);
strcat(keypat, "l");
break;
case DBLTYP :
bytecpy(&dtmp, &buff[toff], tlen);
case FLTTYP :
v[j].dtmp = dtmp;
strcat(keypat, "d");
break;
}
} /* key components not used have NULL value */
*klen = DbMakeSearchKey(kbuff, keypat, v[0], v[1], v[2], v[3], v[4], v[5]);
for (j = 0; j < fptr->keys[ck].segcount; j++)
{
fx = fptr->keys[ck].fldindex[j];
tkey = fptr->flds[fx].fldtype;
if (tkey == CHRTYP)
if (v[j].stmp)
free(v[j].stmp);
}
}
/*
* Stores Emerald Bay local buffer contents to PRO-C buffer
* - EB array index is one higher than PRO-C's because 1st field is recno
* - EB buffers are not visible to programmer but defined internally only
*/
static int eb2buff(fd_sys, buff, emsg)
int fd_sys;
char *buff;
char *emsg;
{
char tbuff[EB_FLDLEN+1], ercode[14];
int tftyp, tfoff, tflen, i, len, k;
int dy, mo, yr;
int itmp;
long ltmp;
float ftmp;
double dtmp;
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
strcpy(ercode, "GET/");
strcat(ercode, emsg);
zerorec(buff, fptr->rec_len);
for (i = 0; i < fptr->fld_cnt; i++)
{
tftyp = fptr->flds[i].fldtype;
tfoff = fptr->flds[i].fldstart;
tflen = fptr->flds[i].fldlen;
zerorec(tbuff, EB_FLDLEN+1);
if (tftyp == MEMTYP)
{
DbTextReset(eptr->txtfld[i+1]);
itmp = 0;
len = tflen;
while (itmp < tflen)
{
k = (len < EB_FLDLEN) ? len : EB_FLDLEN;
zerorec(tbuff, EB_FLDLEN+1);
DbTextRead(eptr->txtfld[i+1], tbuff, k);
strncpy(&buff[tfoff+itmp], tbuff, k);
itmp += k;
len -= EB_FLDLEN;
}
continue;
}
if (tftyp == CHRTYP)
dberrno = DbFetchLtd(fptr->fd_num, eptr->flddesc[i+1].fldid, tbuff, tflen);
else
dberrno = DbFetchNum(fptr->fd_num, eptr->flddesc[i+1].fldid, tbuff);
if (dberrno < 0)
return io_xlate(fd_sys, dberrno, ercode);
if (tftyp == FLTTYP)
{
bytecpy(&dtmp, tbuff, sizeof(double));
ftmp = (float)dtmp;
bytecpy(&buff[tfoff], &ftmp, sizeof(float));
}
else if ((tftyp == DATTYP) && (tflen == 6))
{
bytecpy(<mp, tbuff, sizeof(long));
julcal(ltmp, &dy, &mo, &yr);
sprintf(tbuff, "%02d%02d%02d", yr-1900, mo, dy);
bytecpy(&buff[tfoff], tbuff, tflen);
}
else if (tftyp == LOGTYP) /* more fully implemented once "official" */
{
bytecpy(&itmp, tbuff, sizeof(int));
buff[tfoff] = itmp ? 'y' : 'n';
}
else
bytecpy(&buff[tfoff], tbuff, tflen);
}
return(IOGOOD);
}
/*
* Add a new record.
* - DbClearRecord function ensures that the new record goes into a
* cleared buffer, before values are stored
* (Not sure if DbFirst needs to be called before starting the add process.)
*/
static int i_addrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
if ((dberrno = DbFirst(fptr->fd_num, eptr->fdkey[0].ix_num)) < -1)
return(io_xlate(fd_sys, dberrno, "EB ADD0"));
if ((dberrno = DbClearRecord(fptr->fd_num)) < 0)
return(io_xlate(fd_sys, dberrno, "EB ADD1"));
if (buff2eb(fd_sys, buffer) != IOGOOD)
return(IOERROR);
if ((dberrno = DbAdd(fptr->fd_num)) < 0)
return(io_xlate(fd_sys, dberrno, "EB ADD2"));
return(IOGOOD);
}
/*
* Update the current record.
* - DbUpdate function will not work with Personal Engine if files
* are opened in SHARE mode
*/
static int i_updrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if (buff2eb(fd_sys, buffer) != IOGOOD)
return(IOERROR);
if ((dberrno = DbUpdate(fd[fd_sys].fd_num)) < 0)
return(io_xlate(fd_sys, dberrno, "EB UPD"));
return(IOGOOD);
}
/*
* Stores PRO-C buffer contents to Emerald Bay local buffer
* - EB array index is one higher than PRO-C's because 1st field is recno
* - EB buffers are not visible to programmer but defined internally only
*/
static int buff2eb(fd_sys, buff)
int fd_sys;
char *buff;
{
int tftyp, tfoff, tflen, i, itmp, k, len;
int dy, mo, yr;
long ltmp;
float ftmp;
double dtmp;
char tbuff[EB_FLDLEN+1], tstr[3];
struct fd_def *fptr = &fd[fd_sys];
struct emb_def *eptr = &efd[fd_sys];
for (i = 0; i < fptr->fld_cnt; i++)
{
tftyp = fptr->flds[i].fldtype;
tfoff = fptr->flds[i].fldstart;
tflen = fptr->flds[i].fldlen;
zerorec(tbuff, 100);
switch(tftyp)
{
case DATTYP :
if (tflen == 6) /* date stored as character string */
{
strncpy(tbuff, &buff[tfoff], tflen);
if (!tbuff[0])
strcpy(tbuff, "000101");
tstr[2] = '\0';
strncpy(tstr, tbuff, 2); yr = atoi(tstr) + 1900;
strncpy(tstr, &tbuff[2], 2); mo = atoi(tstr);
strncpy(tstr, &tbuff[4], 2); dy = atoi(tstr);
ltmp = caljul(dy, mo, yr);
dberrno = DbStoreNum(fptr->fd_num, eptr->flddesc[i+1].fldid, ltmp);
break;
} /* else fall through to LNGTYP for long int date */
case LNGTYP : /* don't move this */
bytecpy(<mp, &buff[tfoff], tflen);
dberrno = DbStoreNum(fptr->fd_num, eptr->flddesc[i+1].fldid, ltmp);
break;
case CHRTYP :
bytecpy(tbuff, &buff[tfoff], tflen);
tbuff[tflen] = '\0';
dberrno = DbStore(fptr->fd_num, eptr->flddesc[i+1].fldid, tbuff);
break;
case INTTYP :
bytecpy(&itmp, &buff[tfoff], tflen);
dberrno = DbStoreNum(fptr->fd_num, eptr->flddesc[i+1].fldid, itmp);
break;
case FLTTYP :
bytecpy(&ftmp, &buff[tfoff], tflen);
dtmp = (double)ftmp;
dberrno = DbStoreNum(fptr->fd_num, eptr->flddesc[i+1].fldid, dtmp);
break;
case DBLTYP :
bytecpy(&dtmp, &buff[tfoff], tflen);
dberrno = DbStoreNum(fptr->fd_num, eptr->flddesc[i+1].fldid, dtmp);
break;
case MEMTYP :
DbTextReset(eptr->txtfld[i+1]);
itmp = 0;
len = tflen;
while (itmp < tflen)
{
k = (len < EB_FLDLEN) ? len : EB_FLDLEN;
zerorec(tbuff, EB_FLDLEN+1);
strncpy(tbuff, &buff[tfoff+itmp], k);
DbTextWrite(eptr->txtfld[i+1], tbuff);
itmp += k;
len -= EB_FLDLEN;
}
break;
case LOGTYP : /* more fully implemented once "official" */
itmp = (buff[tfoff] == 'y') ? 1 : 0;
dberrno = DbStoreNum(fptr->fd_num, eptr->flddesc[i+1].fldid, itmp);
break;
}
if (dberrno < 0)
return io_xlate(fd_sys, dberrno, "BUFF2EB");
}
return(IOGOOD);
}
/*
* Delete the current record.
* - DbDel function will not work with Personal Engine if files are
* opened in SHARE mode (error code -600, user is locked out)
*/
static int i_delrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if (i_lockrec(fd_sys, buffer) == IOGOOD)
if ((dberrno = DbDelete(fd[fd_sys].fd_num)) < 0)
return(io_xlate(fd_sys, dberrno, "EB DEL"));
return(IOGOOD);
}
/*
* Lock Record (handled automatically by Emerald Bay)
* - Calls to DbLock requesting EXCLUSIVE use, when open mode for tables
is set to SHARE, return an error code of -1
*/
static int i_lockrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if (fd[fd_sys].lockmode != NOLOCK)
if ((dberrno = DbLock(fd[fd_sys].fd_num, EXCLUSIVE)) < 0)
return(io_xlate(fd_sys, dberrno, "EB LOCK"));
return(IOGOOD);
}
/*
* Unlock Record
* - unlocks are handled automatically by Emerald Bay when transaction is
* finished
* - this explicit unlock requires that no transaction be active
*/
static int i_unlock_rec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
/*
* DbUnlockTable is described in the manual but DOES NOT exist in
* the M5EBL.LIB library! (unresolved extern on link)
*
if (fd[fd_sys].lockmode != NOLOCK)
if ((dberrno = DbUnlockTable(fd[fd_sys].fd_num)) < 0)
return(io_xlate(fd_sys, dberrno, "EB UNLOCK"));
*/
return(IOGOOD);
}
/*
* Login
* - Emerald Bay DbInit function serves as an initial log-in and checks
* if the TSR Emerald Bay engine has been started
*/
static int i_login(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if (!*buffer || (buffer == NULL))
strcpy(usrname, "OWNER");
else
{
strncpy(usrname, buffer, 20);
strncpy(pasword, &buffer[20], 20);
}
if ((dberrno = DbInit(usrname)) <= 0) /* check for Emerald Bay engine */
{
if (!dberrno)
{
errmsg("EMERALD BAY DATABASE MANAGER ENGINE NOT STARTED");
return(IOERROR);
}
return(io_xlate(fd_sys, dberrno, "EB LOGIN"));
}
return(IOGOOD);
}
/*
* Logoff
*/
static int i_logoff(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* End (Commit) transaction
*/
static int i_commit(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int stat;
if (stat = DbCommitTransaction())
{
errmsg(FileTrnsCommit);
return(io_xlate(fd_sys, stat, "EB ETRN"));
}
return(IOGOOD);
}
/*
* Rollback transaction
*/
static int i_rollback(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int stat;
if (stat = DbAbortTransaction())
{
errmsg(FileTrnsRlback);
return(io_xlate(fd_sys, stat, "EB ATRN"));
}
return(IOGOOD);
}
/*
* Start transaction
*/
static int i_transact(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int stat;
if (stat = DbBeginTransaction())
{
errmsg(FileTrnsBegin);
return(io_xlate(fd_sys, stat, "EB BTRN"));
}
return(IOGOOD);
}
/*
* This routine translates Emerald Bay Error codes into PRO-C error codes.
* If no PRO-C equivalent, displays the error number.
*/
static int io_xlate(fd_sys, ernum, rtnname)
int fd_sys;
int ernum;
char *rtnname;
{
switch(ernum)
{
case DBOPEN :
return IOBADOPEN;
case DBNODB :
return IONOFILE;
case -1 :
return IONOKEY;
case DBNDXDUP :
return IODUP;
case DBLOCKOUT :
return IOLOCKED;
case DBNOXACT :
case DBACTIVE :
return IONOTRANS;
}
if (fd_sys >= 0)
errmsg(FileDbgError_sdss, "Emerald Bay", ernum, fd[fd_sys].filname, rtnname);
else /* if routines called from generated apps without valid fd_sys */
errmsg(FileDbgError_sds, "Emerald Bay", ernum, rtnname);
return(IOERROR);
}
/*
* Assign section
*/
void assign_IO_EB(dbnum)
int dbnum;
{
Fntab[dbnum - 1][0] = (int(*)())0; /* Empty */
Fntab[dbnum - 1][1] = i_init_file;
Fntab[dbnum - 1][2] = i_open_file;
Fntab[dbnum - 1][3] = i_close_file;
Fntab[dbnum - 1][4] = i_addrec;
Fntab[dbnum - 1][5] = i_delrec;
Fntab[dbnum - 1][6] = i_findkey;
Fntab[dbnum - 1][7] = i_firstkey;
Fntab[dbnum - 1][8] = i_lastkey;
Fntab[dbnum - 1][9] = i_lockrec;
Fntab[dbnum - 1][10] = i_nextrec;
Fntab[dbnum - 1][11] = i_prevrec;
Fntab[dbnum - 1][12] = i_unlock_rec;
Fntab[dbnum - 1][13] = i_updrec;
Fntab[dbnum - 1][14] = i_commit;
Fntab[dbnum - 1][15] = i_login;
Fntab[dbnum - 1][16] = i_logoff;
Fntab[dbnum - 1][17] = i_rollback;
Fntab[dbnum - 1][18] = i_transact;
Fntab[dbnum - 1][19] = i_selectinx;
Fntab[dbnum - 1][20] = i_rereadrec;
Fntab[dbnum - 1][21] = i_filename;
}