home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Jason Aller Floppy Collection
/
125.img
/
PRO-C4.ZIP
/
BENCH1.ZIP
/
BENCH
/
IPARADOX.C
< prev
next >
Wrap
C/C++ Source or Header
|
1990-05-28
|
30KB
|
1,048 lines
/* ==( io/src/iparadox.c )== */
/* ----------------------------------------------- */
/* Pro-C Copyright (C) 1988 - 1990 Vestronix Inc. */
/* Modification to this source is not supported */
/* by Vestronix Inc. */
/* All Rights Reserved */
/* ----------------------------------------------- */
/* Written NA 24-Feb-88 */
/* Modified VV 06-Apr-90 See comments below */
/* ----------------------------------------------- */
/* %W% (%H% %T%) */
/*
* Modifications
*
* 06-Apr-90 VvA - make internal fieldname buffer long enough
* 28-Mar-90 VvA - adjustments for locking modes, transactions
* 01-Feb-90 VvA - fld_cnt now in iogen.c, fd[] struct
* 01-Feb-90 VvA - Enabled openmode in open_file()
* 15-Dec-89 VvA - V.2 modifications
* 01-Dec-89 VvA - Adapted for Paradox
*/
/* PARADOX specific calls to general IOGEN.C interface */
/*
1. Paradox Engine requires that the primary key be or start at the first
field of the record. If a compound key, the fields must be contiguous.
This is not enforced by PRO-C, thus the user must be made aware of this.
If a compound key, the user should ensure the required fields making it
up are the first ones in the table, in order, even though the specifi-
cation will be made in a SegKey record in TABMOD. A Unique key should
not be specified on the first field, since this module would pick that
up instead, which is not the intention when specifying a compound key.
2. To use this interface on a network, the call to PCNetInit in the open
function, and the body of the lock/unlock functions, should be enabled
and the library remade. PCNetInit requires parameters not generated
by PRO-C, thus some code customization will be needed to pass the
network information needed.
3. Paradox restricts field lengths to 255 characters. A MEMTYP field is
truncated within this module to 255 characters, and returned as a 255
character string.
*/
# include <iodef.h>
# include <iomsg.h>
# include <proc.io>
# include <bench.h>
# include <iosup.h>
# include <pxengine.h>
# define SAVE_IMMEDIATE FALSE /* FALSE : buffered I/O (faster) */
/* 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 load_keys(int, int);
static int field_handles(int);
static int setupkey(int, char *);
static int get_record(int, char *);
static int put_record(int, char *);
static int io_xlate(int, int, char *);
# 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 load_keys();
static int field_handles();
static int setupkey();
static int get_record();
static int put_record();
static int io_xlate();
# endif
struct ixinfo
{
TABLEHANDLE fd_key; /* Paradox table handle for this index */
FIELDHANDLE khdl[MAX_SEGS];
};
struct pdx_def
{
TABLEHANDLE fd_hdl; /* Paradox table handle */
RECORDHANDLE rec_hdl;
LOCKHANDLE lck_hdl;
FIELDHANDLE fhdl[MAX_FLDS];
struct ixinfo fdkey[MAX_KEYS];
};
static struct pdx_def fpx[MAX_FILES];
static char tempbuff[MAX_RECLEN];
static char oldkey[MAX_FLDLEN * MAX_SEGS];
static char newkey[MAX_FLDLEN * MAX_SEGS];
static int zerokey; /* set if blank field is search target */
int pxErr;
/*
*
* Interface Functions
*
*/
/*
* Sets up File Name extension.
*/
static int i_filename(fd_sys, buffer)
int fd_sys;
char *buffer;
{
char *f1;
f1 = buffer; /* strip file extension if any; default .DB assumed */
for( ; *f1 != '.' && *f1 != NULL; f1++)
;
*f1 = NULL;
return(IOGOOD);
}
/*
* File initialization
*/
static int i_init_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if ((pxErr = PXSetDefaults(DEFSWAPSIZE, 8, DEFRECORDHANDLES, DEFLOCKHANDLES, DEFFILEHANDLES, SortOrderAscii)) != IOGOOD)
return(io_xlate(-1, pxErr, "PDX INIT1"));
/*
* IF RUNNING ON A NETWORK: REPLACE PXInit() CALL WITH
* if ((pxErr = PXNetInit(param1, param2, param3)) != IOGOOD)
* WHERE:
* param1 = location of PARADOX.NET file
* param2 = type of network (see Paradox Engine manual for codes)
* param3 = network user name from PARADOX.NET
*/
if ((pxErr = PXInit()) != IOGOOD)
return(io_xlate(-1, pxErr, "PDX INIT2"));
return(IOGOOD);
}
/*
* File open function
*/
static int i_open_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int tbex = FALSE; /* flag for table's existence */
int i = 0, fid;
struct fd_def *fptr = &fd[fd_sys];
struct pdx_def *pptr = &fpx[fd_sys];
TABLEHANDLE tblptr;
RECORDHANDLE recptr;
if ((pxErr = PXTblExist(fptr->filname, &tbex)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX TEST")); /* test table existence */
if (!tbex || (fptr->openmode & OUTPUT_FLAG))
{ /* OUTPUT mode or table not found */
if (fptr->openmode & INPUT_FLAG)
return(IONOFILE); /* no create attempt for read only */
if (create_file(fd_sys) != IOGOOD) /* also creates keys */
return(IOERROR);
}
/* table exists, now open it */
if ((pxErr = PXTblOpen(fptr->filname, &tblptr, 0, SAVE_IMMEDIATE)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX OPEN1"));
pptr->fd_hdl = tblptr; /* save the table handle */
if (load_keys(fd_sys, FALSE) <= 0) /* key info */
return(IOERROR);
pptr->fdkey[0].fd_key = pptr->fd_hdl; /* primary key handle */
for (i = 1; i < fptr->key_cnt; i++) /* handles for secondary keys */
{
fid = pptr->fdkey[i].khdl[0];
if (fid)
{
if ((pxErr = PXTblOpen(fptr->filname, &tblptr, fid, SAVE_IMMEDIATE)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX OPEN2"));
pptr->fdkey[i].fd_key = tblptr;
}
else /* does not attempt open on sec keys that could not be created */
pptr->fdkey[i].fd_key = 999; /* arbitrarily high value */
}
if ((pxErr = PXRecBufOpen(pptr->fd_hdl, &recptr)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX OPEN3"));
pptr->rec_hdl = recptr; /* save the local record buffer */
return(IOGOOD);
}
/*
* Create files
*/
static int create_file(fd_sys)
int fd_sys;
{
int j, sl;
char *rfields[MAX_FLDS];
char *rtypes[MAX_FLDS];
struct fd_def *fptr = &fd[fd_sys];
struct pdx_def *pptr = &fpx[fd_sys];
for (j = 0; j < fptr->fld_cnt; j++) /* info arrays for Paradox */
{
rfields[j] = alloc(FLDNAME_LEN+1);
strcpy(rfields[j], fptr->flds[j].fldname);
rtypes[j] = alloc(10);
sl = fptr->flds[j].fldlen;
switch(fptr->flds[j].fldtype)
{
case (MEMTYP) :
sl = 255; /* Paradox restricts field length to 255, no memos */
case (CHRTYP) :
sprintf(rtypes[j], "A%d", sl);
break;
case (INTTYP) :
strcpy(rtypes[j], "S");
break;
case (LNGTYP) :
case (FLTTYP) :
case (DBLTYP) :
strcpy(rtypes[j], "N");
break;
case (DATTYP) :
if (sl == 6)
strcpy(rtypes[j], "D");
else
strcpy(rtypes[j], "N");
break;
}
}
pxErr = PXTblCreate(fptr->filname, fptr->fld_cnt, rfields, rtypes);
for (j = 0; j < fptr->fld_cnt; j++)
{
free(rfields[j]);
free(rtypes[j]);
}
if (pxErr != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX CREAT"));
if (load_keys(fd_sys, TRUE) > 0) /* create indexes */
return(IOGOOD);
else
return(IOERROR);
}
/*
* Load keys and and set up indexes
* This routine will open table temporarily to get field handles, if
* creatix TRUE; else it should be called with table already open
* PARADOX LIMITATION: the first field(s) in the record must be used
* for the primary index, and if more than one, must be contiguous
* (a warning is issued if the PRO-C spec does not provide for this)
*/
static int load_keys(fd_sys, creatix)
int fd_sys, creatix;
{
int nkeys = 0, nsegs = 0, fix, n;
struct fd_def *fptr = &fd[fd_sys];
struct pdx_def *pptr = &fpx[fd_sys];
TABLEHANDLE tblptr;
if (creatix)
{
if ((pxErr = PXTblOpen(fptr->filname, &tblptr, 0, SAVE_IMMEDIATE)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX KEYS1"));
pptr->fd_hdl = tblptr;
}
n = field_handles(fd_sys);
if (creatix) /* table is closed if creating indexes */
PXTblClose(pptr->fd_hdl);
if (n != IOGOOD) /* failure to assign field handles */
return(IOERROR);
while (fptr->keys[nkeys].segcount != -1)
{
for (nsegs = 0; nsegs < fptr->keys[nkeys].segcount; nsegs++)
{
if ((nkeys == 0) || (fptr->keys[nkeys].segcount == 1))
{
fix = fptr->keys[nkeys].fldindex[nsegs];
pptr->fdkey[nkeys].khdl[nsegs] = pptr->fhdl[fix];
}
else /* blocks out unsupported secondary compound keys */
pptr->fdkey[nkeys].khdl[nsegs] = 0;
}
nkeys++; /* & increment key number */
}
if (creatix)
{ /* first set up primary index */
if ((fptr->keys[0].keytype == KEY_UNIQUE) &&
(pptr->fdkey[0].khdl[0] == pptr->fhdl[0]))
{
nsegs = fptr->keys[0].segcount;
if ((pxErr = PXKeyAdd(fptr->filname, nsegs, pptr->fdkey[0].khdl, PRIMARY)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX KEYS2"));
}
else
{
errmsg(FileFirstKeyFld_s, fptr->filname);
return(IOERROR);
}
for (n = 1; n < nkeys; n++) /* now pick up any other indexes */
{
if (fptr->keys[n].segcount > 1) /* no seg keys on secondary ix */
{
errmsg("Paradox does not support secondary compound keys");
pptr->fdkey[n].khdl[0] = 0;
}
else if ((pxErr = PXKeyAdd(fptr->filname, 1, pptr->fdkey[n].khdl, INCSECONDARY)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX KEYS3"));
}
}
fptr->key_cnt = nkeys;
return(nkeys);
}
/*
* Assign Paradox field handles
*/
static int field_handles(fd_sys)
int fd_sys;
{
int j;
for (j = 0; j < fd[fd_sys].fld_cnt; j++)
if ((pxErr = PXFldHandle(fpx[fd_sys].fd_hdl, fd[fd_sys].flds[j].fldname, &fpx[fd_sys].fhdl[j])) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "FLDS"));
return(IOGOOD);
}
/*
* File close function
* - All table handles for all indexes in each table are closed;
* - PXExit is called when no more files are marked active.
*/
static int i_close_file(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int j, opnfils = 0;
for (j = 0; j < fd[fd_sys].key_cnt; j++)
{
if (fpx[fd_sys].fdkey[j].fd_key < 999)
if ((pxErr = PXTblClose(fpx[fd_sys].fdkey[j].fd_key)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX CLOSE"));
}
fd[fd_sys].active = FALSE;
for (j = 0; j < MAX_FILES; j++)
if (fd[j].active == TRUE)
opnfils++;
if (!opnfils) /* exit Paradox Engine if all files now inactive */
PXExit();
return(IOGOOD);
}
/*
* Select an index to perform processing on - already done in IOGEN.C
* - if unsupported key chosen, default to primary key
*/
static int i_selectinx(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if (fpx[fd_sys].fdkey[fd[fd_sys].cur_key].fd_key == 999)
fd[fd_sys].cur_key = 0; /* represents unsupported key type */
fpx[fd_sys].fd_hdl = fpx[fd_sys].fdkey[fd[fd_sys].cur_key].fd_key;
return(IOGOOD);
}
/*
* Find a record by key value
* - To do a partial match on a blank or zero field, firstkey() is used.
* Otherwise partial match is enabled by the CLOSESTRECORD parameter in
* the calls to Paradox search functions. In order to handle a partial
* search that goes beyond the last record, old and new key values are
* compared: if new key is less than old, the record pointer location
* returned is meaningless and this function returns IOEOF.
*/
static int i_findkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ck, stat, klen;
struct fd_def *fptr = &fd[fd_sys];
struct pdx_def *pptr = &fpx[fd_sys];
if ((stat = setupkey(fd_sys, buffer)) != IOGOOD)
return(stat);
ck = fptr->cur_key;
PXNetTblRefresh(pptr->fd_hdl);
if (fptr->exact)
{
if (ck == 0) /* search on 1st seg of primary key */
pxErr = PXSrchKey(pptr->fd_hdl, pptr->rec_hdl, 1, SEARCHFIRST);
else
pxErr = PXSrchFld(pptr->fd_hdl, pptr->rec_hdl, pptr->fdkey[ck].khdl[0], SEARCHFIRST);
if (pxErr != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX EXACT"));
}
else
{
klen = extract_key(fd_sys, buffer, oldkey); /* retain key value */
if (zerokey) /* if key is blank or zero, go to top of file */
return(i_firstkey(fd_sys, buffer));
if (ck == 0) /* search on 1st seg of primary key */
pxErr = PXSrchKey(pptr->fd_hdl, pptr->rec_hdl, 1, SEARCHFIRST | CLOSESTRECORD);
else
pxErr = PXSrchFld(pptr->fd_hdl, pptr->rec_hdl, pptr->fdkey[ck].khdl[0], SEARCHFIRST | CLOSESTRECORD);
if ((pxErr != IOGOOD) && (pxErr != PXERR_RECNOTFOUND))
return(io_xlate(fd_sys, pxErr, "PDX PART"));
}
stat = get_record(fd_sys, buffer);
if (!fptr->exact)
{
klen = extract_key(fd_sys, buffer, newkey);
if (memcmp(oldkey, newkey, klen) > 0) /* no higher keyval found */
{ /* so new record position meaningless */
i_unlock_rec(fd_sys, buffer);
zerorec(buffer, fptr->rec_len);
return(IOEOF);
}
}
return(stat);
}
/*
* This routine sets up fields for current key in Paradox buffer
*/
static int setupkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int ck, n, so, sl, fix, ty, tm, td;
short itmp;
long ltmp;
float ftmp;
double dtmp;
char tstr[MAX_FLDLEN], nstr[4];
struct fd_def *fptr = &fd[fd_sys];
struct pdx_def *pptr = &fpx[fd_sys];
zerokey = FALSE;
ck = fptr->cur_key;
if ((pxErr = PXRecBufEmpty(pptr->rec_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX KEYSETUP1"));
for (n = 0; n < fptr->keys[ck].segcount; n++)
{
so = fptr->keys[ck].segstart[n];
sl = fptr->keys[ck].seglen[n];
fix = fptr->keys[ck].fldindex[n];
switch(fptr->flds[fix].fldtype)
{
case CHRTYP :
strncpy(tstr, &buffer[so], sl); tstr[sl] = '\0';
pxErr = PXPutAlpha(pptr->rec_hdl, pptr->fdkey[ck].khdl[n], tstr);
zerokey = (tstr[0] ? FALSE : TRUE);
break;
case DATTYP :
if (fptr->flds[fix].fldlen == 6)
{
strncpy(tstr, &buffer[so], sl); tstr[sl] = '\0';
zerokey = FALSE;
if (!tstr[0])
{
strcpy(tstr, "000101");
zerokey = TRUE;
}
nstr[2] = '\0';
strncpy(nstr, tstr, 2);
ty = atoi(nstr) + 1900;
strncpy(nstr, &tstr[2], 2);
tm = atoi(nstr);
strncpy(nstr, &tstr[4], 2);
td = atoi(nstr);
if ((pxErr = PXDateEncode(tm, td, ty, <mp)) == IOGOOD)
pxErr = PXPutDate(pptr->rec_hdl, pptr->fdkey[ck].khdl[n], ltmp);
break;
} /* fall through to LNGTYP for long int date */
case LNGTYP : /* don't move this */
memcpy((char *)<mp, &buffer[so], sl);
pxErr = PXPutLong(pptr->rec_hdl, pptr->fdkey[ck].khdl[n], ltmp);
zerokey = (ltmp == 0L);
break;
case INTTYP :
memcpy((char *)&itmp, &buffer[so], sl);
pxErr = PXPutShort(pptr->rec_hdl, pptr->fdkey[ck].khdl[n], itmp);
zerokey = (itmp ? FALSE : TRUE);
break;
case FLTTYP :
memcpy((char *)&ftmp, &buffer[so], sl);
dtmp = (double)ftmp;
pxErr = PXPutDoub(pptr->rec_hdl, pptr->fdkey[ck].khdl[n], dtmp);
zerokey = ((int)dtmp == 0);
break;
case DBLTYP :
memcpy((char *)&dtmp, &buffer[so], sl);
pxErr = PXPutDoub(pptr->rec_hdl, pptr->fdkey[ck].khdl[n], dtmp);
zerokey = ((int)dtmp == 0);
break;
}
}
if (pxErr != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX KEYSETUP2"));
return(IOGOOD);
}
/*
* Find first record in the file
*/
static int i_firstkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
fd[fd_sys].exact = 0;
PXNetTblRefresh(fpx[fd_sys].fd_hdl);
if ((pxErr = PXRecFirst(fpx[fd_sys].fd_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX FIRST"));
return(get_record(fd_sys, buffer));
}
/*
* Find last physical record in the file
*/
static int i_lastkey(fd_sys, buffer)
int fd_sys;
char *buffer;
{
fd[fd_sys].exact = 0;
PXNetTblRefresh(fpx[fd_sys].fd_hdl);
if ((pxErr = PXRecLast(fpx[fd_sys].fd_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX LAST"));
return(get_record(fd_sys, buffer));
}
/*
* Find next record in the file
*/
static int i_nextrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
i_unlock_rec(fd_sys, buffer);
PXNetTblRefresh(fpx[fd_sys].fd_hdl);
if ((pxErr = PXRecNext(fpx[fd_sys].fd_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "NEXT"));
return(get_record(fd_sys, buffer));
}
/*
* Find previous record in the file
*/
static int i_prevrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
i_unlock_rec(fd_sys, buffer);
PXNetTblRefresh(fpx[fd_sys].fd_hdl);
if ((pxErr = PXRecPrev(fpx[fd_sys].fd_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PREV"));
return(get_record(fd_sys, buffer));
}
/*
* This routine retrieves the current record from Paradox file and
* converts fields to PRO-C buffer form
* - This routine locks the record before retrieving and returns with
* the record still locked if operations successful - inquire mode
* in PRO-C applications will issue the unlock call
*/
static int get_record(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int n, so, sl, ty, tm, td, stat;
short itmp;
long ltmp;
float ftmp;
double dtmp;
char tstr[MAX_FLDLEN];
struct fd_def *fptr = &fd[fd_sys];
struct pdx_def *pptr = &fpx[fd_sys];
if ((pxErr = PXRecBufEmpty(pptr->rec_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX GETREC1"));
if (stat = i_lockrec(fd_sys, buffer)) /* lock record before retrieving */
return(stat);
if ((pxErr = PXRecGet(pptr->fd_hdl, pptr->rec_hdl)) != IOGOOD)
{
i_unlock_rec(fd_sys, buffer);
return(io_xlate(fd_sys, pxErr, "PDX GETREC2"));
}
zerorec(buffer, fptr->rec_len);
for (n = 0; n < fptr->fld_cnt; n++) /* now convert to PRO-C form */
{
so = fptr->flds[n].fldstart;
sl = fptr->flds[n].fldlen;
switch(fptr->flds[n].fldtype)
{
case MEMTYP :
sl = 255;
case CHRTYP :
pxErr = PXGetAlpha(pptr->rec_hdl, pptr->fhdl[n], sl+1, tstr);
strncpy(&buffer[so], tstr, sl);
break;
case INTTYP :
pxErr = PXGetShort(pptr->rec_hdl, pptr->fhdl[n], &itmp);
memcpy(&buffer[so], (char *)&itmp, sl);
break;
case LNGTYP :
pxErr = PXGetLong(pptr->rec_hdl, pptr->fhdl[n], <mp);
memcpy(&buffer[so], (char *)<mp, sl);
break;
case FLTTYP :
pxErr = PXGetDoub(pptr->rec_hdl, pptr->fhdl[n], &dtmp);
ftmp = (float)dtmp;
memcpy(&buffer[so], (char *)&ftmp, sl);
break;
case DBLTYP :
pxErr = PXGetDoub(pptr->rec_hdl, pptr->fhdl[n], &dtmp);
memcpy(&buffer[so], (char *)&dtmp, sl);
break;
case DATTYP :
if (sl == 6)
{
if ((pxErr = PXGetDate(pptr->rec_hdl, pptr->fhdl[n], <mp)) == IOGOOD)
{
pxErr = PXDateDecode(ltmp, &tm, &td, &ty);
if ((ty >= 1900) && (ty < 2000))
ty -= 1900;
sprintf(tstr, "%02d%02d%02d", ty, tm, td);
memcpy(&buffer[so], tstr, sl);
}
}
else
{
pxErr = PXGetLong(pptr->rec_hdl, pptr->fhdl[n], <mp);
memcpy(&buffer[so], (char *)<mp, sl);
}
break;
}
}
if (pxErr != IOGOOD)
{
i_unlock_rec(fd_sys, buffer);
zerorec(buffer, fptr->rec_len);
return(io_xlate(fd_sys, pxErr, "PDX GETREC3"));
}
return(IOGOOD);
}
/*
* Re-read/reposition record pointer function - if required
*/
static int i_rereadrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(i_findkey(fd_sys, buffer));
}
/*
* Add a new record.
*/
static int i_addrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if (put_record(fd_sys, buffer) != IOGOOD)
return(IOERROR);
if ((pxErr = PXRecAppend(fpx[fd_sys].fd_hdl, fpx[fd_sys].rec_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX ADD"));
return(IOGOOD);
}
/*
* Update the current record.
*/
static int i_updrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if (put_record(fd_sys, buffer) != IOGOOD)
return(IOERROR);
if ((pxErr = PXRecUpdate(fpx[fd_sys].fd_hdl, fpx[fd_sys].rec_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX UPD"));
return(IOGOOD);
}
/*
* Delete the current record.
*/
static int i_delrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
if ((pxErr = PXRecDelete(fpx[fd_sys].fd_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX DEL"));
return(IOGOOD);
}
/*
* Sets up a Paradox record from PRO-C buffer
*/
static int put_record(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int n, so, sl, ty, tm, td;
short itmp;
long ltmp;
float ftmp;
double dtmp;
char tstr[MAX_FLDLEN], stmp[20];
struct fd_def *fptr = &fd[fd_sys];
struct pdx_def *pptr = &fpx[fd_sys];
if ((pxErr = PXRecBufEmpty(pptr->rec_hdl)) != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX PUTREC1"));
for (n = 0; n < fptr->fld_cnt; n++)
{
so = fptr->flds[n].fldstart;
sl = fptr->flds[n].fldlen;
switch(fptr->flds[n].fldtype)
{
case MEMTYP :
sl = 255;
case CHRTYP :
strncpy(tstr, &buffer[so], sl); tstr[sl] = '\0';
pxErr = PXPutAlpha(pptr->rec_hdl, pptr->fhdl[n], tstr);
break;
case INTTYP :
memcpy((char *)&itmp, &buffer[so], sl);
pxErr = PXPutShort(pptr->rec_hdl, pptr->fhdl[n], itmp);
break;
case LNGTYP :
memcpy((char *)<mp, &buffer[so], sl);
pxErr = PXPutLong(pptr->rec_hdl, pptr->fhdl[n], ltmp);
break;
case FLTTYP :
memcpy((char *)&ftmp, &buffer[so], sl);
dtmp = (double)ftmp;
pxErr = PXPutDoub(pptr->rec_hdl, pptr->fhdl[n], dtmp);
break;
case DBLTYP :
memcpy((char *)&dtmp, &buffer[so], sl);
pxErr = PXPutDoub(pptr->rec_hdl, pptr->fhdl[n], dtmp);
break;
case DATTYP :
if (sl == 6) /* date stored as character string */
{
strncpy(stmp, &buffer[so], 6);
if (!stmp[0])
strcpy(stmp, "000101");
tstr[2] = '\0';
strncpy(tstr, stmp, 2);
ty = atoi(tstr) + 1900;
strncpy(tstr, &stmp[2], 2);
tm = atoi(tstr);
strncpy(tstr, &stmp[4], 2);
td = atoi(tstr);
if ((pxErr = PXDateEncode(tm, td, ty, <mp)) == IOGOOD)
pxErr = PXPutDate(pptr->rec_hdl, pptr->fhdl[n], ltmp);
}
else
{
memcpy((char *)<mp, &buffer[so], sl);
pxErr = PXPutLong(pptr->rec_hdl, pptr->fhdl[n], ltmp);
}
break;
}
if (pxErr != IOGOOD)
break;
}
if (pxErr != IOGOOD)
return(io_xlate(fd_sys, pxErr, "PDX PUTREC2"));
return(IOGOOD);
}
/*
* Lock Record
*/
static int i_lockrec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int tpxErr;
if (fd[fd_sys].lockmode == NOLOCK)
return(IOGOOD);
if ((tpxErr = PXNetRecLock(fpx[fd_sys].rec_hdl, &fpx[fd_sys].lck_hdl)) != IOGOOD)
return(io_xlate(fd_sys, tpxErr, "LOCK"));
return(IOGOOD);
}
/*
* Unlock Record
*/
static int i_unlock_rec(fd_sys, buffer)
int fd_sys;
char *buffer;
{
int tpxErr;
if (fd[fd_sys].lockmode == NOLOCK)
return(IOGOOD);
if ((tpxErr = PXNetRecUnlock(fpx[fd_sys].rec_hdl, fpx[fd_sys].lck_hdl)) != IOGOOD)
return(io_xlate(fd_sys, tpxErr, "UNLOCK"));
return(IOGOOD);
}
/*
* Login
*/
static int i_login(fd_sys, buffer)
int fd_sys;
char *buffer;
{
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;
{
return(IOGOOD);
}
/*
* Rollback transaction
*/
static int i_rollback(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* Start transaction
*/
static int i_transact(fd_sys, buffer)
int fd_sys;
char *buffer;
{
return(IOGOOD);
}
/*
* This routine translates Paradox Engine error codes into PRO-C 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 PXERR_TABLEOPEN :
return IOBADOPEN;
case PXERR_RECNOTFOUND :
return IONOKEY;
case PXERR_ENDOFTABLE :
case PXERR_TABLEEMPTY :
return IOEOF;
case PXERR_STARTOFTABLE :
return IOTOF;
case PXERR_INVTABLENAME :
case PXERR_TABLENOTFOUND :
return IONOFILE;
case PXERR_TABLELOCKED :
case PXERR_TABLEBUSY :
case PXERR_RECLOCKED :
return IOLOCKED;
case PXERR_NONETINIT : /* harmless return for nonnetwork use */
return IOGOOD;
}
if (fd_sys >= 0)
errmsg(FileDbgError_sdss, "Paradox Engine", ernum, fd[fd_sys].filname, rtnname);
else
errmsg(FileDbgError_sds, "Paradox Engine", ernum, rtnname);
return(IOERROR);
}
/*
* Assign section
*/
void assign_IO_PX(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;
}