home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) Walter L. Peacock 1984-1988. All rights reserved */
- /* U S E R B T R . C 7/26/84 */
-
- /* userbtr: 7/26/84 user application program that uses cbtree calls */
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /* This program illustrates how to invoke CBTREE from an application */
- /* program. The program stores patient data in a data file and provides*/
- /* online access by last name concatenated with first name and middle */
- /* initial, or access by the patient's SSN. Two CBTREE index files are */
- /* maintained by the program: btpatnme is the btree for the name index */
- /* and btpatssn is the btree for the SSN index. The btrees are stored */
-
- /* patient data is stored in patient.dat. */
- /* */
- /* The search is invoked by keying the patient's name in the designated */
- /* fields on the screen or by keying in the patient's SSN in the */
- /* Last Name field. A numeric character as the first character in the */
- /* last name search field indicates to the program that the search */
- /* key is the SSN and the program automatically invokes the proper */
- /* btree. */
- /* */
- /* The calltype is entered in the space provided and should be 1 - 18, */
- /* or 99 to exit. If no value is entered for calltype then the */
- /* default type 2 (GETNXT) will be used by the program. This feature */
- /* allows the user to step through the records in key sequence. */
- /* */
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- #include <stdio.h>
- #include "cbtree.h"
- /* btfio.h *must* be included when bt_open() is used */
- #include "btfio.h"
- #include "patrec.str"
-
- #define SINGLE 1 /* both trees in a SINGLE file */
-
- #if CI | DC
- #else
- #include <ctype.h>
- #endif
-
- #if EC | DC
- extern void free_gtkey();
- #endif
-
- #if AmigaDOS & LC
- #define printf iprintf /* use fast integer printf routine */
- #endif
-
- struct btcommo btnme; /* one for each btree key to be accessed */
- struct btcommo btssn;
-
- int svoptype;
-
- char srchtree = 'N'; /* tracks tree to search on GETNXT & GETPRV */
-
- char *srchkey;
-
- void main(argc, argv)
- int argc;
- char *argv[];
- {
- extern long atol(), getnewloc();
- extern char *strcpy(), *strnncpy(), *calloc();
- extern uword patvar();
- extern int open(), selrec(), close();
- extern void displrtn(), displerr(), free(), input();
- PATREC pr;
- char varlenpr[sizeof(PATREC)];
- char dummy[7], *nam_btdat, *nam_btnme, *nam_btssn;
- int fdnme, fdssn, fddat;
- int btretcd, calltype, varlen;
-
- varlen = (argc > 1 && strcmp(argv[1], "-v") == 0);
-
- if (varlen)
- {
- nam_btdat = "patient.var"; /* run BLD2KEYS.EXE */
- nam_btnme = "btvarnme"; /* set B+tree names for var len recs */
- nam_btssn = "btvarssn";
- }
- else
- {
- nam_btdat = "patient.dat"; /* run BLD2KEYS.EXE -v */
- nam_btnme = "btpatnme"; /* fixed length records */
- nam_btssn = "btpatssn";
- }
-
- wopen("CON:0/0/640/200/Userbtr"); /* Open Amiga Window */
-
- #if EC
- #else
- scr_clr(); /* clear screen */
-
- printf("\nThis program illustrates how to invoke CBTREE from an application ");
- printf("\nprogram. The program stores patient data in a data file and provides");
- printf("\nonline access by last name concatenated with first name and middle ");
- printf("\ninitial, or access by the patient's SSN. Two CBTREE index files are");
- printf("\nmaintained by the program: btpatnme is the btree for the name index");
- printf("\nand btpatssn is the btree for the SSN index. The btrees are stored");
- printf("\nin the disk files btpatnme.idx and btpatssn.idx respectively. The");
- printf("\npatient data is stored in patient.dat. ");
- printf("\n\nThe search is invoked by keying the patient's name in the designated");
- printf("\nfields on the screen or by keying in the patient's SSN in the ");
- printf("\nLast Name field. A numeric character as the first character in the");
- printf("\nlast name search field indicates to the program that the search ");
- printf("\nkey is the SSN and the program automatically invokes the proper ");
- printf("\nbtree. ");
- printf("\n\nThe calltype is entered in the space provided and should be one of");
- printf("\nthe selections listed on the screen. The default opertaion is ");
- printf("\nGETNXT, which allows you to step through the records in key ");
- printf("\nsequence. To exit from the system, type 'EXIT' in the type field. ");
- printf("\n\n Press <RETURN> to continue... ");
-
- gets(dummy);
- #endif
-
- scr_clr(); /* clear screen */
-
- printf("\nCBTREE OP DESCRIPTION \n");
- printf("\n GETFRST Get the first key in the B-tree.");
- printf("\n GETLAST Get the last key in the B-tree.");
- printf("\n GETPRV Get the previous record from current position.");
- printf("\n GETNXT Get the next record from current position.");
- printf("\n GETSEQ Get blocks of records sequentially (up to btmax).");
- printf("\n GETREC Get the first record with exact key match.");
- printf("\n GETPAR Get the first record matching the partial key.");
- printf("\n GETALL Get all records that match the key (up to btmax).");
- printf("\n GETKEYS Get a list of keys and their record numbers.");
- printf("\n GETLT Get first key less than given key.");
- printf("\n GETLE Get first key less than or equal to given key.");
- printf("\n GETGT Get first key greater than given key.");
- printf("\n GETGE Get first key greater than or equal to given key.");
- printf("\n INSERT Insert a new key and data record.");
- printf("\n ISRTKY Insert a key but not the data record.");
- printf("\n DELETE Delete a key and data record. ");
- printf("\n DELTKY Delete a key but not the data record.");
- printf("\n NEWLOC Change the record location only of a given key.");
- printf("\n\n Press <RETURN> to continue... ");
- gets(dummy);
-
- if( (btrinit(nam_btnme, &btnme) ) == ERR)
- ckerror(- CK_BTRIN, "userbtr: btnme");
-
- if( (btrinit(nam_btssn, &btssn) ) == ERR)
- ckerror(- CK_BTRIN, "userbtr: btssn");
-
- /* open PRIMARY INDEX FILE */
- if( (fdnme = bt_open(btnme.idxname,O_RDWR) ) == ERR)
- {
- puts("\n\n*** CAN'T OPEN INDEX FILE, RUN BLD2KEYS.EXE. ***\n");
- ckerror(- CK_OPEN, "userbtr: btnme.idx");
- }
-
- /* open SECONDARY INDEX FILE */
- if (strcmp(btssn.idxname, btnme.idxname) == 0)
- fdssn = fdnme; /* same file */
- else if( (fdssn = bt_open(btssn.idxname,O_RDWR) ) == ERR)
- {
- puts("Can't open btpatssn.idx. Run bld2keys.");
- ckerror(- CK_OPEN, "userbtr: btssn.idx");
- }
-
- /* open DATA FILE */
- if( (fddat = bt_open(nam_btdat, O_RDWR) ) == ERR)
- ckerror(- CK_OPEN, "userbtr: patient.dat");
-
- if( !(srchkey = calloc(btnme.btkeylen + 1, 1) ))
- ckerror(- CK_NOMEM, "userbtr: srchkey");
-
- svoptype = 0;
-
- /* M A I N C O N T R O L P R O G R A M */
-
- /* selrec: user routine to build search key */
-
- while ( (calltype = selrec(&pr) ) != 99){
-
- /* check for previous block retrieval calls */
- if (svoptype == GETALL || svoptype == GETKEYS || svoptype == GETPAR){
- if (svoptype != calltype){
- if (svoptype == GETKEYS){
- if (srchtree == 'N')
- free_gtkey(&btnme); /* free get key array */
- else
- free_gtkey(&btssn); /* free get key array */
- }
- else{
- if (srchtree == 'N')
- free_svkey(&btnme); /* in case this isn't the first pass*/
- else
- free_svkey(&btssn); /* free get key array */
- }
- }
- }
-
- /* btxxxxxx.btloc will contain record location returned from btree */
-
- if ( isalpha(*pr.lname) )
- { /* Name search */
- srchtree = 'N';
-
- bldkey(srchkey, btnme.btkeylen, &pr); /* build concatenated key */
- strcpy(btnme.btkey, srchkey);
-
- if (calltype == DELETE) /* first GET the record */
- {
- btnme.btoptype = GETREC; /* type of cbtree call */
- btnme.btloc = 0L; /* no continuation */
-
- /* issue cbtree call */
- if( (btretcd = cbtree(fddat, fdnme, &btnme) ) != BTCALLOK)
- {
- displerr(btretcd, &btnme);
- continue;
- }
-
- /* read record into structure */
- if (varlen)
- getfpatv(&pr, fddat, &btnme);
- else
- getfpat(&pr, fddat, btnme.btloc);
- }
-
- btnme.btoptype = calltype; /* type of cbtree call */
-
- if (calltype == GETALL || calltype == GETKEYS || calltype == GETPAR)
- btnme.btloc = 0L; /* no continuation */
- else if (calltype == NEWLOC)
- *btnme.btrecnum = getnewloc(btnme.btloc); /* prompt user */
-
- if (calltype == INSERT)
- {
- input(&pr);
- if (varlen)
- btnme.btdtalen = patvar(varlenpr, &pr); /* reckon rec len */
- }
-
- /* issue cbtree call */
- if( (btretcd = cbtree(fddat, fdnme, &btnme) ) == BTCALLOK)
- displrtn(fddat, &btnme, fdnme, fdssn, &pr, varlenpr);
- else
- displerr(btretcd, &btnme);
- }
-
- /*** SSN search ***/
- else if ( isdigit(*pr.lname) )
- {
- srchtree = 'S';
-
- strcpy(srchkey, pr.lname); /* contains SSN ! */
- strcpy(btssn.btkey, pr.lname);
-
- if (calltype == DELETE) /* first GET the record */
- {
- btssn.btoptype = GETREC; /* type of cbtree call */
- btssn.btloc = 0L; /* no continuation */
-
- /* issue cbtree call */
- if( (btretcd = cbtree(fddat, fdssn, &btssn) ) != BTCALLOK)
- {
- displerr(btretcd, &btssn);
- continue;
- }
-
- /* read record into structure */
- if (varlen)
- getfpatv(&pr, fddat, &btssn);
- else
- getfpat(&pr, fddat, btssn.btloc);
- }
-
- btssn.btoptype = calltype; /* type of cbtree call */
-
- if (calltype == GETALL || calltype == GETKEYS || calltype == GETPAR)
- btssn.btloc = 0L; /* no cont to find */
- else if (calltype == NEWLOC)
- *btssn.btrecnum = getnewloc(btssn.btloc); /* prompt user */
-
- if (calltype == INSERT)
- {
- input(&pr);
- if (varlen)
- btnme.btdtalen = patvar(varlenpr, &pr); /* reckon rec len */
- }
-
- /* issue cbtree call */
- if ((btretcd = cbtree(fddat, fdssn, &btssn)) == BTCALLOK)
- displrtn(fddat, &btssn, fdnme, fdssn, &pr, varlenpr);
- else
- displerr(btretcd, &btssn);
- }
- else /* no new key: search b-tree from last established position */
- {
- if (srchtree == 'N')
- { /* btpatnme btree */
-
- *pr.lname = *btnme.btkey;
- if (calltype == GETALL || calltype == GETKEYS)
- {
- if ((calltype == GETALL && btnme.btoptype != GETALL) ||
- (calltype == GETKEYS && btnme.btoptype != GETKEYS))
- btnme.btloc = 0L; /* only on first time through */
- }
- else if (calltype == NEWLOC)
- *btnme.btrecnum = getnewloc(btnme.btloc); /* prompt user */
- btnme.btoptype = calltype;
-
- if (calltype == INSERT)
- {
- input(&pr);
- if (varlen)
- btnme.btdtalen = patvar(varlenpr, &pr); /* set rec len */
- }
-
- /* issue cbtree call */
- if ((btretcd = cbtree(fddat, fdnme, &btnme)) == BTCALLOK)
- displrtn(fddat, &btnme, fdnme, fdssn, &pr, varlenpr);
- else
- displerr(btretcd, &btnme);
- }
- else /* searchtree == SSN */
- {
- *pr.lname = *btssn.btkey;
- if (calltype == GETALL || calltype == GETKEYS)
- {
- if ((calltype == GETALL && btssn.btoptype != GETALL) ||
- (calltype == GETKEYS && btssn.btoptype != GETKEYS))
- btssn.btloc = 0L;
- }
- btssn.btoptype = calltype;
-
- if (calltype == INSERT)
- {
- input(&pr);
- if (varlen)
- btnme.btdtalen = patvar(varlenpr, &pr); /* set rec len */
- }
-
- /* issue cbtree call */
- if ((btretcd = cbtree(fddat,fdssn,&btssn)) == BTCALLOK)
- displrtn(fddat, &btssn, fdnme, fdssn, &pr, varlenpr);
- else
- displerr(btretcd, &btssn);
- }
- }
-
- svoptype = calltype;
- }
-
-
- wclose(); /* close Amiga window */
-
- free( (char *) srchkey);
- close(fdnme);
- close(fddat);
- close(fdssn);
- btrterm(&btnme);
- btrterm(&btssn);
- puts("");
- }
-
- long getnewloc(recnum)
- long recnum;
- {
- long atol();
- char input[18];
-
- printf("\n\n Enter new record number for this record <%lu>: ___\b\b\b",
- recnum);
- *input = '\0'; /* safety */
- gets(input);
- if (*input == '\0')
- return (recnum);
- return (atol(input));
- }
-
- /* build the search key */
- selrec(prp)
- PATREC *prp;
- {
- extern long atol();
- #if CI
- #else
- extern int atoi();
- #endif
- extern int strcmp();
- extern int strlen();
- extern BTOPTYPE optypes[];
- extern int noptypes;
- int calltype;
- char callchar[8];
- char *cp;
- int i;
-
- scr_clr(); /* clear screen */
-
- scr_curs(1, 0);
- printf(" GETFRST GETLAST GETPRV GETNXT GETSEQ GETREC\n");
- printf(" GETPAR GETALL GETKEYS GETLT GETLE GETGT \n");
- printf(" GETGE INSERT ISRTKY DELETE DELTKY NEWLOC EXIT\n");
- printf("\nCurrently active key <%s>, data record location <%lu>",
- (srchtree == 'N') ? btnme.btkey : btssn.btkey,
- (srchtree == 'N') ? btnme.btloc : btssn.btloc);
-
- scr_curs(7, 0);
- printf("Last Name:___________________ First:____________ MI:_ Type:GETNXT_ ");
-
- scr_curs(7, 10);
- gets(prp->lname);
-
- for (cp = prp->lname; *cp != '\0'; ++cp)
- *cp = toupper(*cp);
-
- if (prp->lname[0] != '\0') /* if last name GIVEN, request first name */
- {
-
- scr_curs(7, 38);
- gets(prp->fname);
-
- for (cp = prp->fname; *cp != '\0'; ++cp)
- *cp = toupper(*cp);
-
- scr_curs(7, 56);
- gets(prp->minit);
-
- *prp->minit = toupper(*prp->minit);
- }
-
- /*** always get an optype ***/
-
- repeat
- {
- scr_curs(7, 65);
- printf("GETNXT_\b\b\b\b\b\b\b");
- gets(callchar);
- scr_curs(7, 65 + strlen(callchar));
-
- /* force to upper for match */
- cp = callchar;
- while ((*cp = toupper(*cp)) != '\0')
- ++cp;
-
- /* cleanup the residue on entry line */
- if (*callchar != '\0') /* if something was entered */
- {
- printf(" \r"); /* left overs */
- if (*callchar == 'X')
- {
- calltype = 99;
- break;
- }
- }
- else
- {
- printf("GETNXT \r"); /* refresh */
- calltype = 2; /* default to GETNXT */
- break;
- }
-
- for (i = 0; i < noptypes; ++i)
- {
- if (strcmp(callchar, optypes[i].op_name) == 0)
- break;
- }
-
- if (i < noptypes)
- calltype = optypes[i].op_value;
- else
- {
- calltype = 0;
- continue; /* error try again */
- }
-
- if (calltype == 99) /* exit */
- break;
- }
- until( calltype >= 1 && calltype <= GETLE );
-
- return(calltype);
- }
-
- void displrtn(fddat, btparmst, fdnme, fdssn, prp, varlenpr)
- int fddat, fdnme, fdssn;
- struct btcommo *btparmst;
- PATREC *prp;
- char *varlenpr; /* variable length patient record */
- {
- extern char *strnncpy();
- extern void displerr();
- extern void free_gtkey();
- register int i, j;
- int btretcd;
- char dummy[25];
- struct btidx **btidxpp;
-
- switch (btparmst->btoptype)
- {
- case GETREC :
- case GETNXT :
- case GETPRV :
- case GETPAR :
- case GETFRST:
- case GETLAST:
- case GETGT :
- case GETGE :
- case GETLT :
- case GETLE :
-
- /* read record into structure */
- if (btparmst->btvarlen)
- getfpatv(prp, fddat, btparmst);
- else
- getfpat(prp, fddat, btparmst->btloc);
-
- /* display record retrieved */
- scr_curs(10, 1);
- printf("%s, %s %s ", prp->lname, prp->fname, prp->minit);
- scr_curs(10, 27);
- printf("%-9.9s %-12.12s %-.35s", prp->ssn, prp->hphone, prp->addr);
- break;
-
- case DELETE :
-
- /* display record retrieved */
- scr_curs(10, 1);
- printf("%s, %s %s ", prp->lname, prp->fname, prp->minit);
- scr_curs(10, 27);
- printf("%-9.9s %-12.12s %-.35s", prp->ssn, prp->hphone, prp->addr);
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /* CBTREE has marked record as deleted and placed */
- /* the record on the free space chain. in so doing, the */
- /* first 7 bytes of the last name field was overwritten. */
- /* if file layout were designed such that the key did not */
- /* occupy the first 7 bytes, then the key could be built */
- /* by reading in the record and then issuing a DELTKY */
- /* call to the btree for the key. */
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- if (srchtree == 'N')
- {
- /* delete key from other btree */
- strnncpy(btssn.btkey, prp->ssn, btssn.btkeylen); /* mk key */
- btssn.btoptype = DELTKY;
- btssn.btloc = btparmst->btloc; /* patrec location */
-
- /* issue cbtree call */
- if ((btretcd = cbtree(fddat, fdssn, &btssn)) != BTCALLOK)
- displerr(btretcd, &btssn);
- }
- else if (srchtree == 'S')
- {
- /* delete key from other btree */
- bldkey(btnme.btkey, btnme.btkeylen, prp); /* make key */
- btnme.btoptype = DELTKY;
- btnme.btloc = btparmst->btloc; /* patrec location */
-
- /* issue cbtree call */
- if ((btretcd = cbtree(fddat, fdnme, &btnme)) != BTCALLOK)
- displerr(btretcd, &btnme);
- }
- break;
-
- case GETALL:
- case GETSEQ:
-
- /* process records whose locations are stored */
- /* in btparmst->btrecnum[]. */
- j = 10; /* start on screen line 11 */
- i = 0;
- while (btparmst->btrecnum[i] > 0L)
- {
- /* read record into structure */
- if (btparmst->btvarlen)
- {
- btparmst->btloc = btparmst->btrecnum[i++];
- getfpatv(prp, fddat, btparmst);
- }
- else
- getfpat(prp, fddat, btparmst->btrecnum[i++]);
-
- /* process records retrieved */
- scr_curs(j, 1);
- printf("%s, %s %s ", prp->lname, prp->fname, prp->minit);
- scr_curs(j, 28);
- printf("%-9.9s %-12.12s %-.35s", prp->ssn,prp->hphone,prp->addr);
-
- if (++j > 20)
- {
- printf("\nPress <RETURN> to continue...");
- gets(dummy);
-
- scr_clr();
- j = 0;
- }
- }
- break;
-
- case GETKEYS:
-
- /* process records whose keys and locations are stored */
- /* in btparmst->btrecnum[]. */
- j = 10; /* first time through start on line line */
- i = 0;
- btidxpp = (struct btidx **)btparmst->btrecnum; /* cast it */
- while (*btidxpp != NULL)
- {
- /* read record into structure */
- if (btparmst->btvarlen)
- {
- btparmst->btloc = (*btidxpp)->btptr; /* read up the record */
- getfpatv(prp, fddat, btparmst);
- }
- else
- getfpat(prp, fddat, (*btidxpp)->btptr); /* read up the record */
-
- /* process records retrieved */
- scr_curs(j, 0);
- printf("key: \"%s\"", (*btidxpp)->skeynme);
- scr_curs(j, 27);
- printf("location: %03lu, %.19s, %s %s",
- (*btidxpp)->btptr, prp->lname, prp->fname, prp->minit);
-
- /* finish up with this record */
- ++btidxpp;
-
- if (++j > 20)
- {
- printf("\nPress <RETURN> to continue...");
- gets(dummy); /* CI C86 style */
- scr_clr(); /* clear screen */
- j = 0;
- }
- }
- free_gtkey(btparmst);
- break;
-
- case INSERT:
-
- if (srchtree == 'N')
- {
- /* insert key into other btree */
- strnncpy(btssn.btkey, prp->ssn, btssn.btkeylen); /* make key */
- btssn.btoptype = ISRTKY;
- btssn.btloc = btparmst->btloc; /* patrec location */
-
- /* issue cbtree call */
- if ((btretcd = cbtree(fddat, fdssn, &btssn)) != BTCALLOK)
- displerr(btretcd, &btssn);
- }
- else /* (srctree == 'S') */
- {
- /* insert key into other btree */
- bldkey(btnme.btkey, btnme.btkeylen, prp);
- btnme.btoptype = ISRTKY;
- btnme.btloc = btparmst->btloc; /* patrec location */
-
- /* issue cbtree call */
- if( (btretcd = cbtree(fddat, fdnme, &btnme) ) != BTCALLOK)
- displerr(btretcd, &btnme);
- }
-
- /* write DATA record to disk */
- if (btparmst->btvarlen)
- putfpatv(fddat, btparmst, varlenpr);
- else
- putfpat(fddat, btparmst->btloc, prp);
-
- /* print new record */
- scr_curs(16, 1);
- printf("%s, %s %s ", prp->lname,prp->fname,prp->minit);
- scr_curs(16, 27);
- printf("%-9.9s %-12.12s %-.35s", prp->ssn,prp->hphone, prp->addr);
- break;
-
- default:
- break;
-
- } /* end switch */
-
- printf("\n\nPress <RETURN> to continue...");
- gets(dummy);
- }
-
- void input(prp)
- PATREC *prp;
- {
- char *cp;
-
- if (srchtree == 'N')
- {
- scr_curs(10, 0);
- printf("Soc Sec# :_________");
- scr_curs(10, 10);
- gets(prp->ssn);
- }
- else /* (srctree == 'S') */
- {
- scr_curs(10, 0);
- printf("Last Name:___________________ First:____________ MI:_ Type:__ ");
- scr_curs(10, 10);
- gets(prp->lname);
- for (cp = prp->lname; *cp != '\0'; ++cp)
- *cp = toupper(*cp);
-
- scr_curs(10, 38);
- gets(prp->fname);
- for (cp = prp->fname; *cp != '\0'; ++cp)
- *cp = toupper(*cp);
-
- scr_curs(10, 56);
- gets(prp->minit);
- for (cp = prp->minit; *cp != '\0'; ++cp)
- *cp = toupper(*cp);
- }
-
- scr_curs(12, 0);
- printf("Phone No.:____________");
- scr_curs(12, 10);
- gets(prp->hphone);
-
- scr_curs(14, 0);
- printf("Address :___________________________________");
- scr_curs(14, 10);
- gets(prp->addr);
- }
-
- void displerr(errcode, btcp)
- int errcode;
- struct btcommo *btcp;
- {
- char dummy[2];
-
- puts("\n");
- cberror(errcode, "Userbtr", btcp);
- printf("\nPress <RETURN> to continue...");
- gets(dummy);
- }
-