home *** CD-ROM | disk | FTP | other *** search
- /* ==( io/src/idbc3.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 12-Apr-90 See comments below */
- /* ----------------------------------------------- */
- /* %W% (%H% %T%) */
-
- /*
- * Modifications
- *
- * 12-Apr-90 VvA - corrections to next/prev fn for EOF/TOF
- * 28-Mar-90 VvA - adjustments for locking modes, transactions
- * 14-Mar-90 VvA - fixed blank dBASE field bug
- * 01-Feb-90 VvA - fld_cnt now in iogen.c, fd[] struct
- * 01-Feb-90 VvA - Enabled openmode in open_file()
- * 14-Dec-89 VvA - V.2 modifications
- * 01-Sep_89 VvA - Modified for generic I/O interface
- * 01-Sep_88 VvA - Adapted from existing IO modules
- */
-
- /* dBC III+ I/O calls via general IOGEN.C interface */
-
-
- # include <stdio.h>
- # include <dbc3plus.h>
- # include <iodef.h>
- # include <iomsg.h>
- # include <proc.io>
- # include <bench.h>
- # include <iosup.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, char *);
- static int load_memos(int, int);
- static int load_keys(int, int);
- static int length_check(int);
- static int get_record(int, char *, int);
- static int update_keys(int, char *, int);
- static int lock_sizebyte(int, char *);
- static int lock_ndx(int);
- static int unlock_ndx(int, char *);
- static int lock_mem(int);
- static int io_xlate(int, int, char *);
- static void unlock_mem(int);
- static void unlock_sizebyte(int);
- static void setupkey(int, char *, char *);
- static void buff2db(int, char *, char *);
- static void db2buff(int, char *, 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_memos();
- static int load_keys();
- static int length_check();
- static int get_record();
- static int update_keys();
- static int lock_sizebyte();
- static int lock_ndx();
- static int unlock_ndx();
- static int lock_mem();
- static int io_xlate();
- static void unlock_mem();
- static void unlock_sizebyte();
- static void setupkey();
- static void buff2db();
- static void db2buff();
- # endif
-
-
- extern RECNUM _appnded; /* allows use of APPEND in dBputr function */
- extern int _dlock;
-
-
- /*
- * structure for dBC III+ specific values
- */
- struct dbc_def
- {
- char *dbf_num; /* data file descriptor */
- char *mm_num; /* memo file descriptor */
- char *ix_num[MAX_KEYS]; /* index file descriptors */
- int dbrec_len; /* record length seen by dBC file */
- };
-
- static struct dbc_def fdbf[MAX_FILES];
-
- static char keybuff[MAX_FLDLEN * MAX_SEGS + MAX_SEGS];
- static char xkeybuff[MAX_FLDLEN * MAX_SEGS + MAX_SEGS];
- static char oldbuff[MAX_RECLEN];
- static char storbuff[MAX_RECLEN];
- static char memobuff[5000];
-
- static int dberrno; /* dBC III error code */
- static RECNUM recnum; /* record number in dBC III form */
- static int DBCMODE; /* file open mode, shared or exclusive */
-
-
- /*
- *
- * Interface Functions
- *
- */
-
-
- /*
- * Sets up File Name extension.
- */
- static int i_filename(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- for ( ; (*buffer != '.') && (*buffer != NULL); buffer++)
- ;
- *buffer = NULL;
-
- return(IOGOOD);
- }
-
- /*
- * File initialization
- */
- static int i_init_file(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- return(IOGOOD);
- }
-
- /*
- * File open function
- */
- static int i_open_file(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int n;
- char *dbfdesc;
- char dbfname[FILENAME_LEN];
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- strcpy(dbfname, fptr->filname);
- strcat(dbfname, ".DBF"); /* dBASE III type filename from filname */
-
- dptr->mm_num = NULL;
-
- _dlock = d_TLOCK; /* dBC3+ no-wait locking */
-
- if (fptr->openmode & OUTPUT_FLAG)
- create_file(fd_sys, dbfname); /* if OUTPUT, delete existing files */
-
- DBCMODE = (fptr->openmode & P_SHARED) ? d_SHARED : d_SINGLE;
-
- if ((dberrno = dBopen(dbfname, DBCMODE | d_MINBUF, &dbfdesc)) != SUCCESS)
- {
- if ((DBCMODE == d_SHARED) && (dberrno == d_LOCKED))
- {
- errmsg(FileShareReqd); /* unconditional exit if SHARE not run */
- return(IOERROR);
- }
- /* exit if file to be read-only OR already exists */
- if ((fptr->openmode & INPUT_FLAG) || !access(dbfname, 00))
- return(io_xlate(fd_sys, dberrno, "dBC OPEN1"));
-
- if (create_file(fd_sys, dbfname) != IOGOOD)
- return(IOERROR);
-
- if ((dberrno = dBopen(dbfname, DBCMODE | d_MINBUF, &dbfdesc)) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC OPEN2"));
- }
- /* file has been opened successfully */
- dptr->dbf_num = dbfdesc;
-
- if (length_check(fd_sys) != IOGOOD)
- {
- i_close_file(fd_sys, buffer);
- return(IOERROR);
- }
-
- return(IOGOOD);
- }
-
- /*
- * dBC III+ create file function - file will be opened by the create call
- */
- static int create_file(fd_sys, dfname)
- int fd_sys; /* index into fd table */
- char *dfname;
- {
- int j;
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
- dBFIELD *fldtmp;
-
- fldtmp = (dBFIELD *)alloc(sizeof(dBFIELD) * fptr->fld_cnt);
-
- for (j = 0; j < fptr->fld_cnt; j++) /* load field descriptions */
- {
- strcpy(fldtmp[j].fieldnm, cvt_upper(fptr->flds[j].fldname));
- fldtmp[j].dec = (FLDDEC)0;
- switch(fptr->flds[j].fldtype)
- {
- case CHRTYP :
- fldtmp[j].type = 'C';
- fldtmp[j].width = (FLDWIDTH)fptr->flds[j].fldlen;
- break;
- case INTTYP :
- case LNGTYP :
- case FLTTYP :
- case DBLTYP :
- fldtmp[j].type = 'N';
- fldtmp[j].width = (FLDWIDTH)nummasklen(fptr->flds[j].fldmask);
- fldtmp[j].dec = (FLDDEC)decmasklen(fptr->flds[j].fldmask);
- break;
- case DATTYP :
- if (fptr->flds[j].fldlen == 6)
- {
- fldtmp[j].type = 'D';
- fldtmp[j].width = (FLDWIDTH)8;
- }
- else
- {
- fldtmp[j].type = 'N';
- fldtmp[j].width = (FLDWIDTH)10;
- fldtmp[j].dec = (FLDDEC)0;
- }
- break;
- case LOGTYP :
- fldtmp[j].type = 'L';
- fldtmp[j].width = (FLDWIDTH)1;
- break;
- case MEMTYP :
- fldtmp[j].type = 'M';
- fldtmp[j].width = (FLDWIDTH)10;
- break;
- }
- }
-
- if ((dberrno = dBcreat(dfname, (FLDNUM)fptr->fld_cnt, fldtmp)) != SUCCESS)
- {
- free(fldtmp);
- return(io_xlate(fd_sys, dberrno, "dBC CRT"));
- }
- free(fldtmp);
-
- if (load_memos(fd_sys, TRUE) != IOGOOD)
- return(IOERROR);
-
- return((load_keys(fd_sys, TRUE) > 0) ? IOGOOD : IOERROR);
- }
-
- /*
- * dBC III+ memo load function - creates or opens memo files
- * - if creatmemo is TRUE, file will be created, otherwise it is opened
- * - one memo file will do for all memo fields
- */
- static int load_memos(fd_sys, creatmemo)
- int fd_sys, creatmemo;
- {
- int j;
- char *memdesc, memname[FILENAME_LEN];
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- strcpy(memname, fptr->filname); /* memo names match their file names */
- strcat(memname, ".DBT");
-
- for (j = 0; j < fptr->fld_cnt; j++) /* load field descriptions */
- if (fptr->flds[j].fldtype == MEMTYP)
- {
- if (creatmemo)
- {
- if ((dberrno = dBmcreat(memname)) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC MEMCRTE"));
- }
-
- if ((dberrno = dBmopen(memname, DBCMODE, &memdesc)) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC MEMOPEN"));
-
- fdbf[fd_sys].mm_num = memdesc;
- break;
- }
-
- return(IOGOOD);
- }
-
- /*
- * dBC III+ key load function - creates or opens indexes for new files
- * - if creatndx is TRUE, index will be created, otherwise it is opened
- */
- static int load_keys(fd_sys, creatndx)
- int fd_sys, creatndx;
- {
- int ndxid, n, m, fx;
- char keytype, *ndxdesc;
- char ndxname[FILENAME_LEN], keyname[FLDNAME_LEN * MAX_SEGS * 3], fmtstr[12];
- struct fd_def *fptr = &fd[fd_sys];
- KEYLEN keylen;
-
- strcpy(ndxname, fptr->filname); /* index names match their file names */
- if ((ndxid = strlen(ndxname)) > 7) /* ndxid is index id offset */
- ndxid = 7;
- ndxname[ndxid] = '\0';
- strcat(ndxname, "0.NDX");
-
- n = 0;
- while (fptr->keys[n].segcount != -1)
- {
- ndxname[ndxid] = (char)(n + 49); /* sequential index name suffix */
-
- if (creatndx) /* create the indexes */
- {
- keyname[0] = '\0';
- keylen = (KEYLEN)0;
- keytype = 'C';
- for (m = 0; m < fptr->keys[n].segcount; m++)
- { /* requires conversions for mixed type keys !!! */
- fx = fptr->keys[n].fldindex[m];
- if (m > 0)
- strcat(keyname, "+");
- if ((fptr->keys[n].segcount == 1) || (fptr->flds[fx].fldtype == CHRTYP))
- {
- if ((fptr->flds[fx].fldtype == CHRTYP) &&
- (fptr->flds[fx].fldlen != fptr->keys[n].seglen[m]))
- {
- strcat(keyname, "SUBSTR(");
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- zerorec(fmtstr, 12);
- sprintf(fmtstr, ",%d,%d)",
- (fptr->keys[n].segstart[m]+1 - fptr->flds[fx].fldstart),
- fptr->keys[n].seglen[m]);
- strcat(keyname, fmtstr);
- }
- else
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- keylen += (KEYLEN)fptr->keys[n].seglen[m];
- }
- else if (fptr->flds[fx].fldtype == DATTYP)
- {
- if (fptr->flds[fx].fldlen == 6)
- {
- strcat(keyname, "DTOC(");
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- strcat(keyname, ")");
- keylen += (KEYLEN)8;
- }
- else
- {
- strcat(keyname, "STR(");
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- strcat(keyname, ",10,0)");
- keylen += (KEYLEN)10;
- }
- }
- else
- {
- zerorec(fmtstr, 12);
- sprintf(fmtstr, ",%d,%d)", nummasklen(fptr->flds[fx].fldmask), decmasklen(fptr->flds[fx].fldmask));
- strcat(keyname, "STR(");
- strcat(keyname, cvt_upper(fptr->flds[fx].fldname));
- strcat(keyname, fmtstr);
- keylen += (KEYLEN)nummasklen(fptr->flds[fx].fldmask);
- }
- }
-
- if (fptr->keys[n].segcount == 1) /* compound keys all type 'C' */
- {
- fx = fptr->keys[n].fldindex[0];
- switch(fptr->flds[fx].fldtype)
- {
- case CHRTYP :
- keytype = 'C';
- break;
- case DATTYP :
- if (fptr->flds[fx].fldlen == 6)
- {
- keytype = 'D';
- break;
- } /* long int dates fall through to 'N' type */
- case INTTYP :
- case LNGTYP :
- case FLTTYP :
- case DBLTYP :
- keytype = 'N';
- break;
- }
- }
- if ((dberrno = dBicreat(ndxname, keyname, keylen, keytype)) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC IXCRTE"));
- }
- else /* just open the indexes */
- {
- if ((dberrno = dBiopen(ndxname, DBCMODE, &ndxdesc)) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC IXOPEN"));
-
- fdbf[fd_sys].ix_num[n] = ndxdesc;
- }
- n++;
- }
- return(n); /* value returned is the number of keys */
- }
-
- /*
- * Length check function
- * - checks record length against that expected by PRO-C
- */
- static int length_check(fd_sys)
- int fd_sys;
- {
- int i;
- RECLEN chkreclen;
- FLDNUM chkfldcnt;
- char cm, cd, cy;
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
- dBFIELD *flds;
-
- flds = (dBFIELD *)alloc(sizeof(dBFIELD) * fptr->fld_cnt);
-
- dptr->dbrec_len = 0; /* what PRO-C thinks DBF record length is... */
-
- for (i = 0; i < fptr->fld_cnt; i++)
- {
- switch (fptr->flds[i].fldtype)
- {
- case DATTYP :
- if (fptr->flds[i].fldlen == 6)
- dptr->dbrec_len += 8;
- else
- dptr->dbrec_len += 10;
- break;
- case INTTYP :
- case LNGTYP :
- case FLTTYP :
- case DBLTYP :
- dptr->dbrec_len += nummasklen(fptr->flds[i].fldmask);
- break;
- case CHRTYP :
- dptr->dbrec_len += fptr->flds[i].fldlen;
- break;
- case LOGTYP :
- dptr->dbrec_len += 1;
- break;
- case MEMTYP :
- dptr->dbrec_len += 10;
- break;
- }
- } /* dbrec_len is field length as defined in application */
-
- if ((dberrno = dBgetf(dptr->dbf_num, &chkreclen, &cm, &cd, &cy, &chkfldcnt, flds)) != SUCCESS)
- {
- free(flds);
- return(io_xlate(fd_sys, dberrno, "dBC LCHK"));
- }
-
- free(flds);
-
- if (dptr->dbrec_len != (int)chkreclen)
- { /* if file length has been changed... */
- errmsg(FileRecLenChg_s, fptr->filname);
- return(IOERROR);
- }
-
- if (load_memos(fd_sys, FALSE) != IOGOOD)
- return(IOERROR);
-
- return((load_keys(fd_sys, FALSE) > 0) ? IOGOOD : IOERROR);
- }
-
- /*
- * File close function - including index files
- * - with manual locking, files must be locked, flushed and unlocked
- * before closing
- */
- static int i_close_file(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int n;
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- n = 0;
- while (fd[fd_sys].keys[n].segcount != -1)
- {
- if ((dberrno = dBiclose(dptr->ix_num[n])) != SUCCESS)
- io_xlate(fd_sys, dberrno, "dBC ICLS");
- n++;
- }
-
- if (dptr->mm_num) /* close the memo file */
- if ((dberrno = dBmclose(dptr->mm_num)) != SUCCESS)
- io_xlate(fd_sys, dberrno, "dBC MCLS");
-
- if ((dberrno = dBclose(dptr->dbf_num)) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC DCLS"));
-
- fd[fd_sys].active = NO;
- return(IOGOOD);
- }
-
- /*
- * Select an index to perform processing on - already done in IOGEN.C
- */
- 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 errcode;
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- setupkey(fd_sys, buffer, keybuff);
-
- dberrno = dBtkey(dptr->ix_num[fptr->cur_key], keybuff, &recnum);
- if ((dberrno != SUCCESS) && (fptr->exact || (dberrno != d_MAYBE)))
- return(io_xlate(fd_sys, dberrno, "dBC FIND"));
-
- errcode = get_record(fd_sys, buffer, NEXT);
- return((fptr->exact && (errcode == IOEOF)) ? IONOKEY : errcode);
- }
-
- /*
- * Find first record in the file
- */
- static int i_firstkey(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- if ((dberrno = dBrewind(dptr->ix_num[fptr->cur_key])) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC FRST1"));
-
- if ((dberrno = dBnkey(dptr->ix_num[fptr->cur_key], keybuff, &recnum)) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC FRST2"));
-
- return(get_record(fd_sys, buffer, NEXT));
- }
-
- /*
- * Find last physical record in the file
- */
- static int i_lastkey(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- if ((dberrno = dBfwd(dptr->ix_num[fptr->cur_key])) != SUCCESS)
- return(io_xlate(fd_sys, dberrno, "dBC LAST1"));
-
- if ((dberrno = dBpkey(dptr->ix_num[fptr->cur_key], keybuff, &recnum)) != SUCCESS)
- {
- if ((dberrno == d_NOKEY) || (dberrno == d_TOPKEY))
- return(IOEOF);
- return(io_xlate(fd_sys, dberrno, "dBC LAST2"));
- }
-
- return(get_record(fd_sys, buffer, PREV));
- }
-
- /*
- * Find next record in the file
- */
- static int i_nextrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- i_unlock_rec(fd_sys, buffer); /* unlock current rec before proceeding */
-
- if ((dberrno = dBnkey(dptr->ix_num[fptr->cur_key], xkeybuff, &recnum)) != SUCCESS)
- {
- if (dberrno == d_ENDKEY)
- return(IOEOF);
- return(io_xlate(fd_sys, dberrno, "dBC NEXT"));
- }
-
- return(get_record(fd_sys, buffer, NEXT));
- }
-
- /*
- * Find previous record in the file
- */
- static int i_prevrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- i_unlock_rec(fd_sys, buffer); /* unlock current rec before proceeding */
-
- if ((dberrno = dBpkey(dptr->ix_num[fptr->cur_key], xkeybuff, &recnum)) != SUCCESS)
- {
- if (dberrno == d_TOPKEY)
- return(IOTOF);
- return(io_xlate(fd_sys, dberrno, "dBC PREV"));
- }
-
- return(get_record(fd_sys, buffer, PREV));
- }
-
- /*
- * Retrieve a record
- * - record locking is taken care of here
- * - if nextone is TRUE, will try next record when passing over a deleted
- * record; otherwise will try previous record
- */
- static int get_record(fd_sys, buffer, nextone)
- int fd_sys, nextone;
- char *buffer;
- {
- char stat;
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- if (i_lockrec(fd_sys, buffer) != IOGOOD)
- return(IOERROR);
-
- if ((dberrno = dBflush(dptr->dbf_num)) != SUCCESS)
- {
- i_unlock_rec(fd_sys, buffer);
- return(io_xlate(fd_sys, dberrno, "dBC GETREC1"));
- }
- if ((dberrno = dBgetr(dptr->dbf_num, recnum, storbuff, &stat)) != SUCCESS)
- {
- i_unlock_rec(fd_sys, buffer);
- return(io_xlate(fd_sys, dberrno, "dBC GETREC2"));
- }
-
- if (stat == INACTIVE) /* skip over record if flagged as deleted */
- return(nextone ? i_nextrec(fd_sys, buffer) : i_prevrec(fd_sys, buffer));
-
- db2buff(fd_sys, storbuff, buffer); /* back to PRO-C form */
- bytecpy(oldbuff, buffer, fd[fd_sys].rec_len); /* copy original rec */
- 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;
- {
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- buff2db(fd_sys, buffer, storbuff);
-
- if (!lock_sizebyte(fd_sys, buffer)) /* append only if sizebyte locked */
- return(IOERROR);
- if (!lock_ndx(fd_sys)) /* index lock failure */
- {
- unlock_sizebyte(fd_sys);
- return(IOERROR);
- }
- if (!lock_mem(fd_sys))
- {
- unlock_sizebyte(fd_sys);
- unlock_ndx(fd_sys, buffer);
- return(IOERROR);
- }
-
- if ((dberrno = dBputr(dptr->dbf_num, APPEND, storbuff)) != SUCCESS)
- {
- unlock_sizebyte(fd_sys);
- unlock_ndx(fd_sys, buffer); /* also unlocks record */
- return(io_xlate(fd_sys, dberrno, "dBC ADD1"));
- }
- if ((dberrno = dBflush(dptr->dbf_num)) != SUCCESS)
- {
- unlock_sizebyte(fd_sys);
- unlock_ndx(fd_sys, buffer);
- return(io_xlate(fd_sys, dberrno, "dBC ADD2"));
- }
- unlock_sizebyte(fd_sys);
- recnum = _appnded; /* external dBC variable rec number */
-
- return(update_keys(fd_sys, buffer, FALSE)); /* now add key to indexes */
- }
-
- /*
- * Update the current record.
- */
- static int i_updrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- if (i_lockrec(fd_sys, buffer) == IOGOOD)
- {
- if ((dberrno = dBckey(dptr->ix_num[fptr->cur_key], xkeybuff, &recnum)) != SUCCESS)
- {
- i_unlock_rec(fd_sys, buffer);
- return(io_xlate(fd_sys, dberrno, "dBC UPD1"));
- }
-
- if (!lock_ndx(fd_sys)) /* index lock failure */
- i_unlock_rec(fd_sys, buffer);
- else /* update only if indexes locked successfully */
- {
- if (!lock_mem(fd_sys))
- {
- unlock_ndx(fd_sys, buffer);
- return(IOERROR);
- }
-
- buff2db(fd_sys, buffer, storbuff);
-
- if ((dberrno = dBupdr(dptr->dbf_num, recnum, storbuff)) != SUCCESS)
- {
- unlock_ndx(fd_sys, buffer); /* also unlocks record */
- return(io_xlate(fd_sys, dberrno, "dBC UPD2"));
- }
- if ((dberrno = dBflush(dptr->dbf_num)) != SUCCESS)
- {
- unlock_ndx(fd_sys, buffer);
- return(io_xlate(fd_sys, dberrno, "dBC UPD3"));
- }
-
- return(update_keys(fd_sys, buffer, TRUE)); /* now update indexes */
- }
- }
- return(IOERROR);
- }
-
- /*
- * Index key update function
- * - if updating argument = TRUE, old key occurrences are removed first
- */
- static int update_keys(fd_sys, buffer, updating)
- int fd_sys, updating;
- char *buffer;
- {
- int ck, j = 0, result = IOGOOD;
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- ck = fd[fd_sys].cur_key;
-
- while (fd[fd_sys].keys[j].segcount != -1)
- {
- fd[fd_sys].cur_key = j;
-
- if (updating) /* removes old key values from the indexes */
- {
- setupkey(fd_sys, oldbuff, xkeybuff); /* old key value */
- if ((dberrno = dBrmvkey(dptr->ix_num[j], xkeybuff, recnum)) != SUCCESS)
- {
- result = io_xlate(fd_sys, dberrno, "dBC KEYRMV");
- break;
- }
- }
-
- setupkey(fd_sys, buffer, keybuff); /* new key value */
- if ((dberrno = dBakey(dptr->ix_num[j], keybuff, recnum)) != SUCCESS)
- {
- result = io_xlate(fd_sys, dberrno, "dBC KEYADD1");
- break;
- }
- if ((dberrno = dBiflsh(dptr->ix_num[j])) != SUCCESS)
- {
- result = io_xlate(fd_sys, dberrno, "dBC KEYADD2");
- break;
- }
- j++;
- }
-
- unlock_ndx(fd_sys, buffer); /* also unlocks data record */
- fd[fd_sys].cur_key = ck;
- return(result);
- }
-
-
- /*
- * dBC III delete record function
- * - this only marks records inactive; no PACK is available with dBC III+
- * - indexes are not changed; relies on detection of inactive flag to skip
- * deleted records in retrievals
- */
- static int i_delrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- if (i_lockrec(fd_sys, buffer) != IOGOOD)
- return(IOERROR);
-
- if ((dberrno = dBckey(dptr->ix_num[fptr->cur_key], keybuff, &recnum)) != SUCCESS)
- {
- i_unlock_rec(fd_sys, buffer);
- return(io_xlate(fd_sys, dberrno, "dBC DEL1"));
- }
-
- if ((dBdelete(dptr->dbf_num, recnum)) != SUCCESS)
- {
- i_unlock_rec(fd_sys, buffer);
- return(io_xlate(fd_sys, dberrno, "dBC DEL2"));
- }
-
- if ((dberrno = dBflush(dptr->dbf_num)) != SUCCESS)
- {
- i_unlock_rec(fd_sys, buffer);
- return(io_xlate(fd_sys, dberrno, "dBC DEL3"));
- }
-
- i_unlock_rec(fd_sys, buffer);
- return(IOGOOD);
- }
-
-
- /*
- * Lock Record - gets number of current record first
- */
- static int i_lockrec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- struct fd_def *fptr = &fd[fd_sys];
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- if ((DBCMODE == d_SINGLE) || (fd[fd_sys].lockmode == NOLOCK))
- return(IOGOOD);
-
- if ((dberrno = dBckey(dptr->ix_num[fptr->cur_key], xkeybuff, &recnum)) != SUCCESS)
- {
- if ((dberrno == d_TOPKEY) || (dberrno == d_ENDKEY))
- return(IOGOOD); /* bypass retry count if EOF/TOF */
- return(io_xlate(fd_sys, dberrno, "dBC LOCK1"));
- }
-
- dberrno = dBlockr(dptr->dbf_num, recnum, (RECNUM)1, d_TLOCK);
- if ((dberrno != SUCCESS) && (dberrno != d_SELFLK))
- return(io_xlate(fd_sys, dberrno, "dBC LOCK2"));
-
- return(IOGOOD);
- }
-
- /*
- * Unlock Record
- */
- static int i_unlock_rec(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- if ((DBCMODE == d_SINGLE) || (fd[fd_sys].lockmode == NOLOCK))
- return(IOGOOD);
-
- dberrno = dBlockr(fdbf[fd_sys].dbf_num, recnum, (RECNUM)1, d_TEST);
- if (dberrno == d_FREE)
- return(IOGOOD);
-
- dberrno = dBlockr(fdbf[fd_sys].dbf_num, recnum, (RECNUM)1, d_ULOCK);
- if ((dberrno != SUCCESS) && (dberrno != d_FREE))
- return(io_xlate(fd_sys, dberrno, "dBC ULOCK"));
-
- return(IOGOOD);
- }
-
- /*
- * Lock Size Bytes of .DBF file for record append
- */
- static int lock_sizebyte(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int timeout;
-
- if ((DBCMODE == d_SINGLE) || (fd[fd_sys].lockmode == NOLOCK))
- return(TRUE);
-
- timeout = fd[fd_sys].lockmode;
- do
- {
- dberrno = dBlocksz(fdbf[fd_sys].dbf_num, d_TLOCK);
- if ((dberrno == SUCCESS) || (dberrno == d_SELFLK))
- return(TRUE);
- }
- while (--timeout > 0);
-
- i_unlock_rec(fd_sys, buffer); /* no add if sizebyte unavailable */
- io_xlate(fd_sys, dberrno, "dBC LCKSIZ");
- return(FALSE);
- }
-
- /*
- * Unlock Size Bytes of .DBF file for record append
- */
- static void unlock_sizebyte(fd_sys)
- int fd_sys;
- {
- if ((DBCMODE == d_SINGLE) || (fd[fd_sys].lockmode == NOLOCK))
- return;
-
- dberrno = dBlocksz(fdbf[fd_sys].dbf_num, d_TEST);
- if (dberrno == d_FREE)
- return;
-
- dberrno = dBlocksz(fdbf[fd_sys].dbf_num, d_ULOCK);
- if ((dberrno != SUCCESS) && (dberrno != d_FREE))
- io_xlate(fd_sys, dberrno, "dBC ULCKSIZ");
- }
-
- /*
- * Lock all indexes associated with a file for append/update
- */
- static int lock_ndx(fd_sys)
- int fd_sys;
- {
- int j = 0, k, timeout;
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- if ((DBCMODE == d_SINGLE) || (fd[fd_sys].lockmode == NOLOCK))
- return(TRUE);
-
- while (fd[fd_sys].keys[j].segcount != -1)
- {
- timeout = fd[fd_sys].lockmode;
- do
- {
- dberrno = dBlocki(dptr->ix_num[j], d_TLOCK);
- if ((dberrno == SUCCESS) || (dberrno == d_SELFLK))
- break;
- }
- while (--timeout > 0);
-
- if ((dberrno != SUCCESS) && (dberrno != d_SELFLK))
- {
- io_xlate(fd_sys, dberrno, "dBC LCKNDX");
- for (k = 0; k < j; k++) /* unlock any already locked */
- dBlocki(dptr->ix_num[k], d_ULOCK);
- return(FALSE);
- }
- j++;
- }
- return(TRUE);
- }
-
- /*
- * Unlock all index files associated with a datafile
- * - calls record unlock function afterwards
- */
- static int unlock_ndx(fd_sys, buffer)
- int fd_sys;
- char *buffer;
- {
- int j = 0;
-
- if ((DBCMODE == d_SINGLE) || (fd[fd_sys].lockmode == NOLOCK))
- return(IOGOOD);
-
- while (fd[fd_sys].keys[j].segcount != -1)
- {
- dberrno = dBlocki(fdbf[fd_sys].ix_num[j], d_TEST);
- if (dberrno != d_FREE)
- {
- dberrno = dBlocki(fdbf[fd_sys].ix_num[j], d_ULOCK);
- if ((dberrno != SUCCESS) && (dberrno != d_FREE))
- io_xlate(fd_sys, dberrno, "dBC ULCKNDX");
- }
- j++;
- }
- unlock_mem(fd_sys);
- return(i_unlock_rec(fd_sys, buffer));
- }
-
- /*
- * Lock memo file associated with a file for append/update
- */
- static int lock_mem(fd_sys)
- int fd_sys;
- {
- int timeout;
- struct dbc_def *dptr = &fdbf[fd_sys];
-
- if ((DBCMODE == d_SINGLE) || (fd[fd_sys].lockmode == NOLOCK))
- return(TRUE);
-
- if (!dptr->mm_num) /* no memos */
- return(TRUE);
-
- timeout = fd[fd_sys].lockmode;
- do
- {
- dberrno = dBlockm(dptr->mm_num, d_TLOCK);
- if ((dberrno == SUCCESS) || (dberrno == d_SELFLK))
- break;
- }
- while (--timeout > 0);
-
- if ((dberrno != SUCCESS) && (dberrno != d_SELFLK))
- {
- io_xlate(fd_sys, dberrno, "dBC LCKMEM");
- return(FALSE);
- }
- return(TRUE);
- }
-
- /*
- * Unlock memo file associated with a datafile
- */
- static void unlock_mem(fd_sys)
- int fd_sys;
- {
- if ((DBCMODE == d_SINGLE) || (fd[fd_sys].lockmode == NOLOCK))
- return;
-
- if (!fdbf[fd_sys].mm_num)
- return;
-
- dberrno = dBlockm(fdbf[fd_sys].mm_num, d_TEST);
- if (dberrno == d_FREE)
- return;
-
- dberrno = dBlockm(fdbf[fd_sys].mm_num, d_ULOCK);
- if ((dberrno != SUCCESS) && (dberrno != d_FREE))
- io_xlate(fd_sys, dberrno, "dBC ULCKMEM");
- }
-
-
- /*
- * Set up target key
- * - sets up a key string for record retrieval on current index
- * - compound keys allowed only for character field types, so numerical
- * segments are converted to strings and set up according to fmt mask
- */
- static void setupkey(fd_sys, recbuf, keybuf)
- int fd_sys;
- char *recbuf, *keybuf;
- {
- int i, ofs, tlen, len, fx, so = 0, nnum, ndec;
- int itmp;
- long ltmp;
- float ftmp;
- double dtmp;
- char tbuff[MAX_FLDLEN], *tptr;
- struct fd_def *fptr = &fd[fd_sys];
- struct keyinfo *kptr = &fd[fd_sys].keys[fd[fd_sys].cur_key];
-
- memset(keybuf, (int)' ', MAX_FLDLEN * MAX_SEGS);
- keybuf[0] = '\0';
-
- for (i = 0; i < kptr->segcount; i++)
- {
- ofs = kptr->segstart[i];
- tlen = kptr->seglen[i];
- fx = kptr->fldindex[i];
-
- if (fptr->flds[fx].fldtype == CHRTYP)
- {
- dBstrcpy(&keybuf[so], 'L', tlen, &recbuf[ofs]);
- so += tlen;
- }
- else /* numerical or date keys conversion */
- {
- zerorec(tbuff, MAX_FLDLEN);
- keybuf[so] = 'N';
- switch(fptr->flds[fx].fldtype)
- {
- case DATTYP :
- if (tlen == 6)
- {
- strncpy(tbuff, "19", 2);
- strncpy(&tbuff[2], &recbuf[ofs], tlen);
- keybuf[so] = 'D';
- break;
- } /* else fall through to LNGTYP for long int dates */
- case LNGTYP : /* don't move this */
- bytecpy(<mp, &recbuf[ofs], tlen);
- ltoa(ltmp, tbuff, 10);
- strcat(tbuff,".");
- break;
- case INTTYP :
- bytecpy(&itmp, &recbuf[ofs], tlen);
- itoa(itmp, tbuff, 10);
- break;
- case FLTTYP:
- bytecpy(&ftmp, &recbuf[ofs], tlen);
- gcvt((double)ftmp, 15, tbuff);
- break;
- case DBLTYP :
- bytecpy(&dtmp, &recbuf[ofs], tlen);
- gcvt(dtmp, 15, tbuff);
- break;
- }
- if (kptr->segcount == 1)
- {
- dBatokey(tbuff, &keybuf[so]);
- so += 8;
- }
- else /* part of compound key, so keep in string form */
- {
- if ((fptr->flds[fx].fldtype == DATTYP) && (fptr->flds[fx].fldlen == 6))
- {
- dBstrcpy(&keybuf[so], 'L', 8, tbuff);
- so += 8;
- }
- else /* store value as ASCII using length/decimals of field */
- {
- if (fptr->flds[fx].fldtype == DATTYP) /* long int date */
- {
- nnum = 10;
- ndec = 0;
- }
- else
- {
- nnum = nummasklen(fptr->flds[fx].fldmask);
- ndec = decmasklen(fptr->flds[fx].fldmask);
- }
-
- /* now format number string using mask lengths */
- if ((tptr = strchr(tbuff, (int)'.')) == NULL)
- {
- strcat(tbuff, ".00000");
- tptr = strchr(tbuff, (int)'.');
- }
- len = strlen(tbuff) - strlen(tptr);
- if (ndec > 0)
- tbuff[len + ndec + 1] = '\0';
- else
- tbuff[len] = '\0';
-
- memset(&keybuf[so], (int)' ', nnum);
- if (nnum >= strlen(tbuff))
- {
- so += nnum - strlen(tbuff);
- bytecpy(&keybuf[so], tbuff, strlen(tbuff));
- so += strlen(tbuff);
- }
- else
- so += nnum; /* if reaches this, does not store key */
- }
- }
- }
- }
- }
-
-
- /*
- * Convert record to dBC III+ form from PRO-C buffer format before storing
- */
- static void buff2db(fd_sys, P_buff, DB_buff)
- int fd_sys;
- char *P_buff, *DB_buff;
- {
- int ofst, ftyp, flen, lnum, ldec, i, so = 0, k = 0;
- int itmp;
- long ltmp;
- float ftmp;
- double dtmp;
- char tstr[50];
- struct fd_def *fptr = &fd[fd_sys];
-
- memset(DB_buff, (int)' ', fdbf[fd_sys].dbrec_len);
-
- for (i = 0; i < fd[fd_sys].fld_cnt; i++)
- {
- ftyp = fptr->flds[i].fldtype;
- ofst = fptr->flds[i].fldstart;
- flen = fptr->flds[i].fldlen;
- lnum = nummasklen(fptr->flds[i].fldmask);
- ldec = decmasklen(fptr->flds[i].fldmask);
-
- if (ftyp == CHRTYP)
- {
- dBstrcpy(&DB_buff[so], 'L', flen, &P_buff[ofst]);
- so += flen; /* offset for next field */
- }
- else if ((ftyp == DATTYP) && (flen == 6))
- {
- strncpy(&DB_buff[so], "19", 2); /* dBASE date format */
- so += 2;
- dBstrcpy(&DB_buff[so], 'L', flen, &P_buff[ofst]);
- so += flen; /* offset for next field */
- }
- else if (ftyp == LOGTYP)
- {
- DB_buff[so] = P_buff[ofst];
- so++;
- }
- else if (ftyp == MEMTYP)
- {
- if (P_buff[ofst]) /* write memo only if one exists */
- {
- zerorec(memobuff, 5000);
- strncpy(memobuff, &P_buff[ofst], flen);
- if (dBputm(fdbf[fd_sys].mm_num, memobuff, &DB_buff[so]) != SUCCESS)
- errmsg(FileMemoNoWrite_ss, fptr->flds[i].fldname, fptr->filname);
- }
- k++; /* uses memo files in original field order */
- so += 10;
- }
- else
- {
- switch(ftyp)
- {
- case INTTYP :
- bytecpy(&itmp, &P_buff[ofst], flen);
- itoa(itmp, tstr, 10);
- strcat(tstr,".");
- break;
- case DATTYP : /* long int date type */
- lnum = 10;
- ldec = 0;
- case LNGTYP : /* don't move this - long int date falls thru */
- bytecpy(<mp, &P_buff[ofst], flen);
- ltoa(ltmp, tstr, 10);
- strcat(tstr,".");
- break;
- case FLTTYP :
- bytecpy(&ftmp, &P_buff[ofst], flen);
- gcvt((double)ftmp, lnum, tstr);
- break;
- case DBLTYP :
- bytecpy(&dtmp, &P_buff[ofst], flen);
- gcvt(dtmp, lnum, tstr);
- break;
- }
- dBatofld(tstr, lnum, ldec, &DB_buff[so]);
- so += lnum;
- }
- }
- }
-
- /*
- * Convert record to PRO-C buffer format from dBC III+ form before returning
- */
- static void db2buff(fd_sys, DB_buff, P_buff)
- int fd_sys;
- char *DB_buff, *P_buff;
- {
- int ftyp, ofst, flen, lnum, i, so = 0, k = 0;
- int itmp;
- long ltmp;
- float ftmp;
- double dtmp;
- char tstr[50];
- struct fd_def *fptr = &fd[fd_sys];
-
- zerorec(P_buff, fptr->rec_len);
-
- for (i = 0; i < fd[fd_sys].fld_cnt; i++)
- {
- ftyp = fptr->flds[i].fldtype;
- ofst = fptr->flds[i].fldstart;
- flen = fptr->flds[i].fldlen;
- lnum = nummasklen(fptr->flds[i].fldmask);
-
- if (ftyp == CHRTYP)
- {
- strncpy(&P_buff[ofst], &DB_buff[so], flen);
- stripright(&P_buff[ofst], flen);
- so += flen; /* offset for next field */
- }
- else if ((ftyp == DATTYP) && (flen == 6))
- {
- so += 2; /* ignore the "19" in the date */
- strncpy(&P_buff[ofst], &DB_buff[so], flen);
- stripright(&P_buff[ofst], flen);
- so += flen; /* offset for next field */
- }
- else if (ftyp == LOGTYP)
- {
- P_buff[ofst] = DB_buff[so];
- so++;
- }
- else if (ftyp == MEMTYP)
- {
- zerorec(memobuff, 5000);
- if (dBgetm(fdbf[fd_sys].mm_num, &DB_buff[so], memobuff) != SUCCESS)
- errmsg(FileMemoNoRead_ss, fptr->flds[i].fldname, fptr->filname);
- strncpy(&P_buff[ofst], memobuff, flen);
- k++;
- so += 10;
- }
- else
- {
- if (ftyp == DATTYP) /* special case for long int date type */
- lnum = 10;
- zerorec(tstr, 50);
- dBfldtoa(&DB_buff[so], lnum, tstr);
- switch(ftyp)
- {
- case INTTYP :
- itmp = atoi(tstr);
- bytecpy(&P_buff[ofst], &itmp, flen);
- break;
- case DATTYP :
- case LNGTYP :
- ltmp = atol(tstr);
- bytecpy(&P_buff[ofst], <mp, flen);
- break;
- case FLTTYP :
- ftmp = (float)atof(tstr);
- bytecpy(&P_buff[ofst], &ftmp, flen);
- break;
- case DBLTYP :
- dtmp = atof(tstr);
- bytecpy(&P_buff[ofst], &dtmp, flen);
- break;
- }
- so += lnum;
- }
- }
- }
-
-
-
- /*
- * 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 dBC III+ 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 d_WTFAIL :
- return IOBADOPEN;
- case d_NODBF :
- case d_NONDX :
- return IONOFILE;
- case d_MAYBE :
- case d_NOTFND :
- case d_TOPKEY :
- case d_ENDKEY :
- case d_NOKEY :
- return IONOKEY;
- case d_LOCKED :
- return IOLOCKED;
- case d_FREE :
- return IONOLOCK;
- }
-
- if (fd_sys >= 0)
- errmsg(FileDbgError_sdss, "dBC III Plus", ernum, fd[fd_sys].filname, rtnname);
- else /* if routines called from generated apps without valid fd_sys */
- errmsg(FileDbgError_sds, "dBC III Plus", ernum, rtnname);
- errmsg(FileDbgError_sds, "dBC III Internal", _dbcerr, rtnname);
-
- return(IOERROR);
- }
-
-
- /*
- * Assign section
- */
-
- void assign_IO_DB(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;
- }
-