home *** CD-ROM | disk | FTP | other *** search
- /* ==( 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;
- }
-