|
|
DataMuseum.dkPresents historical artifacts from the history of: CP/M |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about CP/M Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 30464 (0x7700)
Types: TextFile
Names: »DATABASE.SRC«
└─⟦57f0389e8⟧ Bits:30005761 SW1611 Access Manager v. 1.0
└─⟦this⟧ »DATABASE.SRC«
PROGRAM DATABASE;
(* ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DATABASE EXAMPLE VERSION 1.0 9/14/82 0935
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
(*$E-*)
CONST
MAX_KEY = 2;
MAX_FIELD = 7;
MAX_KEY_LEN = 20;
MAX_FLD_LEN = 20;
NAME_LEN = 14;
FLD_NAME_LEN = 18;
ACTION_LEN = 4;
NEW_MODE = 1;
OLD_MODE = 2;
YES = 1;
NO = 0;
SAVE = 1;
DELT = 2;
BACK = 3;
CONT = 4;
STOP = 5;
TYPE
BYTEPTR = ^BYTE;
KEYSTR = STRINGÆMAX_KEY_LENÅ;
FLDSTR = STRINGÆMAX_FLD_LENÅ;
FLD_REC = RECORD;
LENBYTE : BYTE;
FLDCHR : ARRAYÆ1..MAX_FLD_LENÅ OF CHAR;
END;
CUST_REC = RECORD;
CDF : CHAR;
FLD : ARRAYÆ1..99Å OF CHAR;
END;
(*
WORKING VARIABLES
*)
VAR
KEY,TERMINAL,TRAP_ERRORS,TIME_OUT_TEST_DELAY,NO_BUFFERS : INTEGER;
NO_NODE_SECTORS,NO_DATA_FILES,NO_KEYZ,FILE_NO : INTEGER;
RECORD_LENGTH : INTEGER;
SET_LENGTH,IDX_KEY,SPACE : KEYSTR;
OLD_ACTION : INTEGER;
FILNAME : STRINGÆNAME_LENÅ;
NULL_BYT : BYTE;
NULL_CHR : CHAR;
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DATABASE FIELD & KEY DESCRIPTORS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
DATBUF : CUST_REC;
DATBUF_PTR : ^CUST_REC;
FLD_NAME,KEY_NAME : ARRAYÆ0..MAX_FIELDÅ OF STRINGÆFLD_NAME_LENÅ;
FLD_LEN : ARRAYÆ0..MAX_FIELDÅ OF BYTE;
OLD_FLD,NEW_FLD : ARRAYÆ0..MAX_FIELDÅ OF FLDSTR;
NO_FIELDS : INTEGER;
IDX_NAME : ARRAYÆ0..MAX_KEYÅ OF STRINGÆNAME_LENÅ;
KEY_LEN,KEY_MAP,KEY_TYPE,KEY_NUM,KEY_DUP : ARRAYÆ0..MAX_KEYÅ OF
INTEGER;
FOR_EVER : BOOLEAN;
UNIQ_KEY,NLOCK,SLOCK,XLOCK,SFILE,XFILE,RLOCK : INTEGER;
(*
INTERFACE TO ACCESS MANAGER(tm)
AM86EXTR.PSC CONTAINS THE EXTERNAL DEFINITIONS OF THE ACCESS MANAGER
ROUTINES
*)
æ$I AM86EXTR.PSCå
EXTERNAL FUNCTION @BDOS86(FUNC:INTEGER; PARM:BYTEPTR) : INTEGER;
PROCEDURE GO_OP_SYS;
VAR
DUMMY : INTEGER;
DPARM : BYTEPTR;
BEGIN
DUMMY := @BDOS86(0,DPARM);
END;æGO_OP_SYSå
PROCEDURE DATA_BASE;
BEGIN
CLRSCR;
CASE MAIN_MENU OF
1: DBNEW;
2: DBSCAN;
3: DBLIST;
4: DBSTAT;
5: DBSAVE;
6: DBTERM;
END;æOF CASEå
END;æDATA_BASEå
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ENTER NEW CUSTOMERS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE DBNEW;
VAR
KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
SAVE_KEY,LDRN,NO_LISTED : INTEGER;
ROUTE : CHAR;
CONTINUE,STAYPUT : BOOLEAN;
L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
ACTION : INTEGER;
BEGIN
ACTION := SAVE;
WHILE (ACTION = SAVE) DO
BEGIN
ACTION := NEWDAT;
LOCK_CODE := 0;
IF ACTION = SAVE THEN
BEGIN
NDRN := UPDATE(0);
LOCK_CODE := FRELOK(FILE_NO,XLOCK,NDRN);
END;
IF LOCK_CODE <> 0 THEN
LOCK_TYPE(8);
END;
END;æDBNEWå
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SCAN/UPDATE/DELETE CUSTOMERS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE DBSCAN;
VAR
KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
SAVE_KEY,LDRN,NO_LISTED : INTEGER;
ROUTE : CHAR;
CONTINUE,STAYPUT : BOOLEAN;
L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
ACTION : INTEGER;
BEGIN
KEY := SEARCH_KEY;
WRITELN;
WRITELN ('Enter target value for ',KEY_NAMEÆKEYÅ,',');
WRITE(' or enter a period (.) to see main menu>>');
READLN(TARGET);
IF TARGET <> '.' THEN
BEGIN
CONV_TARGET := TARGET;
KEY_FORMAT(KEY,CONV_TARGET);
STAYPUT := TRUE;
WHILE (STAYPUT) DO
BEGIN
DRN := SERKEY(KEY_NUMÆKEYÅ,FILE_NO,SLOCK,
CONV_TARGET,IDX_KEY);
IF ERRCOD <> 0 THEN
ERROR_TYPE(KEY,2);
IF LOKCOD <> 0 THEN
STAYPUT := CHECK_LOCK(KEY,DRN)
ELSE
STAYPUT :=FALSE;
END;
OLD_ACTION := CONT;
CONTINUE := TRUE;
WHILE (CONTINUE) AND (DRN <> 0) DO
BEGIN
LDRN := DRN;
READ_CUST(DRN);
ACTION := OLDDAT(DRN);
SAVE_KEY := KEY;
IF ACTION = SAVE THEN
DRN := UPDATE(DRN);
IF ACTION = DELT THEN
DELETE(DRN);
IF (ACTION <> DELT) AND (FRELOK(FILE_NO,RLOCK,LDRN) <> 0)
THEN LOCK_TYPE(2);
IF (ACTION = SAVE) OR (ACTION = DELT) THEN
BEGIN
KEY := SAVE_KEY;
ACTION := OLD_ACTION;
END;
OLD_ACTION := ACTION;
CONV_TARGET := COPY(IDX_KEY,1,KEY_LENÆKEYÅ);
IDX_KEY := SET_LENGTH;
LOCK_CODE := 0;
STAYPUT := TRUE;
WHILE (STAYPUT) DO
BEGIN
IF ACTION = CONT THEN
BEGIN
DRN := AFTKEY(KEY_NUMÆKEYÅ,FILE_NO,
SLOCK, CONV_TARGET,IDX_KEY);
LOCK_CODE := LOKCOD;
END;
IF ACTION = BACK THEN
BEGIN
DRN := BEFKEY(KEY_NUMÆKEYÅ,FILE_NO,
SLOCK, CONV_TARGET,IDX_KEY);
LOCK_CODE := LOKCOD;
END;
IF LOCK_CODE <> 0 THEN
STAYPUT := CHECK_LOCK(KEY,DRN)
ELSE
STAYPUT := FALSE;
END;
IF ACTION = STOP THEN
CONTINUE := FALSE;
END;
WRITELN;
WRITELN('SCAN ENDED');
PAUSE;
END;
END;æDBSCANå
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
LIST CUSTOMERS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE DBLIST;
VAR
KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
SAVE_KEY,LDRN,NO_LISTED : INTEGER;
ROUTE : CHAR;
CONTINUE,STAYPUT : BOOLEAN;
L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
ACTION : INTEGER;
BEGIN
KEY := SEARCH_KEY;
WRITELN;
WRITE('Do you want listing routed to printer (Y/N) >>');
READLN(ROUTE);
IF ROUTE = 'y' THEN ROUTE := 'Y';
WRITELN;
WRITELN;
WRITELN(
'Enter lower and upper limits for ',KEY_NAMEÆKEYÅ,' listing;');
WRITE(' place values on separate lines >>') ;
READLN(L_VALUE);
READLN(U_VALUE);
KEY_FORMAT(KEY,L_VALUE);
KEY_FORMAT(KEY,U_VALUE);
DRN := SERKEY(KEY_NUMÆKEYÅ,FILE_NO,SLOCK,
L_VALUE,IDX_KEY);
IF LOKCOD <> 0 THEN
SKIP_LOCK(KEY,DRN);
NO_LISTED := 0;
WHILE (DRN <> 0) AND (COMPARE(KEY,IDX_KEY,U_VALUE) <= 0) DO
BEGIN
READ_CUST(DRN);
PRINT_CUST(ROUTE);
NO_LISTED := NO_LISTED + 1;
IF FRELOK(FILE_NO,SLOCK,DRN) <> 0 THEN
LOCK_TYPE(4);
L_VALUE := COPY(IDX_KEY,1,KEY_LENÆKEYÅ);
IDX_KEY := SET_LENGTH;
DRN := AFTKEY(KEY_NUMÆKEYÅ,FILE_NO,SLOCK,
L_VALUE,IDX_KEY);
IF LOKCOD <> 0 THEN
SKIP_LOCK(KEY,DRN);
END;
IF DRN <> 0 THEN
LOCK_CODE := FRELOK(FILE_NO,SLOCK,DRN)
ELSE
LOCK_CODE := 0;
IF LOCK_CODE <> 0 THEN
LOCK_TYPE(5);
WRITELN;
WRITELN(NO_LISTED,' records listed.');
PAUSE;
END;æDBLISTå
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DATABASE STATISTICS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE DBSTAT;
VAR
KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
SAVE_KEY,LDRN,NO_LISTED : INTEGER;
ROUTE : CHAR;
CONTINUE,STAYPUT : BOOLEAN;
L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
ACTION : INTEGER;
BEGIN
CLRSCR;
WRITELN(FILNAME,' has ',GETDFS(FILE_NO),
' records; currently, ',GETDFU(FILE_NO),
' of them are in use.');
WRITELN;
WRITELN;
WRITELN(' INDEX','ENTRIES':30);
WRITELN ('-----------------','-------':22);
FOR KEY := 0 TO MAX_KEY DO
WRITELN(KEY_NAMEÆKEYÅ:16,' ':16,NOKEYS(KEY):7);
WRITELN;
WRITELN;
PAUSE;
END;æDBSTATå
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SAVE DATABASE UPDATES & RESTART
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE DBSAVE;
VAR
KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
SAVE_KEY,LDRN,NO_LISTED : INTEGER;
ROUTE : CHAR;
CONTINUE,STAYPUT : BOOLEAN;
L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
ACTION : INTEGER;
BEGIN
IF SAVDAT(FILE_NO) <> 0 THEN
ERROR_TYPE(0,7);
FOR KEY := 0 TO MAX_KEY DO
IF SAVIDX(KEY_NUMÆKEYÅ) <> 0 THEN
ERROR_TYPE(KEY,3);
END;æDBSAVEå
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SAVE DATABASE UPDATES & TERMINATE
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE DBTERM;
VAR
KEY,LOCK_CODE,NDRN,DRN,CHOICE : INTEGER;
SAVE_KEY,LDRN,NO_LISTED : INTEGER;
ROUTE : CHAR;
CONTINUE,STAYPUT : BOOLEAN;
L_VALUE,U_VALUE,CONV_TARGET,TARGET : KEYSTR;
ACTION : INTEGER;
BEGIN
IF FRELOK(FILE_NO,SFILE,0) <> 0 THEN
ERROR_TYPE(0,13);
IF CLSDAT(FILE_NO) <> 0 THEN
ERROR_TYPE(0,15);
FOR KEY := 0 TO MAX_KEY DO
IF CLSIDX(KEY_NUMÆKEYÅ) <> 0 THEN
ERROR_TYPE(KEY,16);
WRITELN;
WRITELN(' *** SUCCESSFUL TERMINATION ***');
FOR_EVER := FALSE;
END;æDBTERMå
(*
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
BEGINNING OF UTILITY FUNCTIONS
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CLEAR SCREEN ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE CLRSCR;
VAR
DUMMY : INTEGER;
BEGIN
FOR DUMMY := 1 TO 24 DO
WRITELN;
END;æCLRSCRå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
MAIN MENU ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
FUNCTION MAIN_MENU : INTEGER;
VAR
OP : INTEGER;
BEGIN
WRITELN(' ':19,' ACCESS MANAGER(tm) DEMONSTRATION');
WRITELN;
WRITELN(' ':19,' Customer Database Operations') ;
WRITELN(' ':19,' Terminal ',TERMINAL);
WRITELN(' ':19,' ****************************');
WRITELN;
WRITELN;
WRITELN(' 1. Enter New Customers');
WRITELN(' 2. Scan/Update/Delete Customer Records');
WRITELN(' 3. List Customer Records');
WRITELN(' 4. Database Statistics');
WRITELN(' 5. Save All Files & Restart Operations');
WRITELN(' 6. Terminate Operations');
OP := 0;
WHILE (OP < 1) OR (OP > 6) DO
BEGIN
WRITELN;
WRITE('Enter desired operation number>>');
READLN(OP);
END;
MAIN_MENU := OP;
END;æMAIN_MENUå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SELECT SEARCH KEY ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
FUNCTION SEARCH_KEY : INTEGER;
VAR
KEY,KEY_NO : INTEGER;
BEGIN
CLRSCR;
WRITELN(' ':24,'Customer Database Search Keys');
WRITELN;
WRITELN;
WRITELN;
FOR KEY := 0 TO MAX_KEY DO
BEGIN
KEY_NO := KEY + 1;
WRITELN(KEY_NO,' - ',KEY_NAMEÆKEYÅ)
END;
KEY := 0;
WHILE (KEY < 1) OR (KEY > NO_KEYZ) DO
BEGIN
WRITELN;
WRITELN;
WRITE('Enter desired key number>>');
READLN(KEY);
END;
SEARCH_KEY := KEY-1;
END;æSEARCH_KEYå
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ERROR HANDLING
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE ERROR_TYPE(INFO,LOCALE : INTEGER);
VAR
DUMMY : INTEGER;
PROCEDURE ET_CLOSE;
VAR
T_KEY : INTEGER;
BEGIN
DUMMY := CLSDAT(FILE_NO);
FOR T_KEY := 0 TO MAX_KEY DO
IF T_KEY <> INFO THEN DUMMY := CLSIDX(KEY_NUMÆT_KEYÅ);
ET_STOP;
END;
PROCEDURE ET_PCLOSE;
VAR
L_KEY,T_KEY : INTEGER;
BEGIN
L_KEY := INFO + 1;
IF L_KEY > MAX_KEY THEN GO_OP_SYS;
FOR T_KEY := L_KEY TO MAX_KEY DO
DUMMY := CLSIDX(KEY_NUMÆT_KEYÅ);
END;
PROCEDURE ET_STOP;
BEGIN
WRITELN;
WRITELN('DATABASE TERMINATING WITH ERROR CODE #',ERRCOD);
GO_OP_SYS;
END;
BEGIN
WRITELN;
WRITELN;
WRITE('User Error #',ERRCOD,' occurred while trying to ');
CASE LOCALE OF
1: WRITELN('open ',IDX_NAMEÆINFOÅ);
2: WRITELN('search ',KEY_NAMEÆINFOÅ,' Index File');
3: WRITELN('save ',IDX_NAMEÆINFOÅ);
4: WRITELN('remove old key from ',IDX_NAMEÆINFOÅ);
5: WRITELN('enter key into ',IDX_NAMEÆINFOÅ);
6: WRITELN('delete key from ',IDX_NAMEÆINFOÅ);
7: BEGIN
WRITELN('save ',FILNAME);
INFO := -1;
END;
8: WRITELN('get a new data record',' (',FILE_NO,')');
9: WRITELN('delete data record #',INFO);
10: WRITELN('open ',FILNAME,' (',FILE_NO,')');
11: WRITELN('read data record #',INFO);
12: WRITELN('write data record #',INFO);
13: WRITELN('release shared file lock on ',FILNAME);
14: BEGIN
WRITELN('initialize user.');
GO_OP_SYS;
END;
15: BEGIN
WRITELN('close ',FILNAME);
INFO := -1;
END;
16: WRITELN('close ',IDX_NAMEÆINFOÅ);
END;æOF CASEå
IF (LOCALE = 1) OR ((LOCALE > 7) AND (LOCALE < 13)) THEN
ET_STOP
ELSE IF (LOCALE = 2) OR ((LOCALE > 3) AND (LOCALE < 7)) OR
(LOCALE = 13) THEN
ET_CLOSE
ELSE
ET_PCLOSE;
END;æERROR_TYPEå
PROCEDURE LOCK_TYPE(LOCALE : INTEGER);
VAR
T_KEY,DUMMY : INTEGER;
BEGIN
WRITELN('Lock Type: ',LOCALE,' Lock Code:',LOKCOD);
DUMMY := CLSDAT(FILE_NO);
FOR T_KEY := 0 TO MAX_KEY DO
DUMMY := CLSIDX(KEY_NUMÆT_KEYÅ);
GO_OP_SYS;
END;æLOCK_TYPEå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
READ DATA RECORD ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE READ_CUST(DRN : INTEGER);
VAR
FLD,CHR,POS_PTR : INTEGER;
TMP_FLD : FLDSTR;
FLDPTR : ^FLD_REC;
BEGIN
IF READAT(FILE_NO,DRN,DATBUF_PTR) <> 0 THEN
ERROR_TYPE(DRN,11);
FLDPTR := ADDR(TMP_FLD); (* PTR TO STRING *)
POS_PTR := 0;
FOR FLD := 0 TO MAX_FIELD DO
BEGIN
FLDPTR^.LENBYTE := FLD_LENÆFLDÅ;
FOR CHR := 1 TO FLDPTR^.LENBYTE DO
FLDPTR^.FLDCHRÆCHRÅ := DATBUF.FLDÆPOS_PTR + CHRÅ;
WHILE (FLDPTR^.FLDCHRÆFLDPTR^.LENBYTEÅ = ' ') AND
(FLDPTR^.LENBYTE > 0) DO
FLDPTR^.LENBYTE := FLDPTR^.LENBYTE - 1;
OLD_FLDÆFLDÅ := TMP_FLD;
POS_PTR := POS_PTR + FLD_LENÆFLDÅ;
END;
END;æREAD_CUSTå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
LIST CUSTOMER RECORD ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE PRINT_CUST(ROUTE : CHAR);
VAR
DUMMY : INTEGER;
LIST_FILE : TEXT;
BEGIN
IF ROUTE = 'Y' THEN
ASSIGN(LIST_FILE,'LST:')
ELSE
ASSIGN(LIST_FILE,'CON:');
RESET(LIST_FILE);
WRITELN(LIST_FILE);
WRITELN(LIST_FILE,' ':4,OLD_FLDÆ0Å:10,' ',OLD_FLDÆ7Å);
WRITELN(LIST_FILE,' ':24,OLD_FLDÆ1Å,' ',OLD_FLDÆ2Å);
WRITELN(LIST_FILE,' ':24,OLD_FLDÆ3Å);
WRITELN(LIST_FILE,' ':24,OLD_FLDÆ4Å,', ',OLD_FLDÆ5Å,' ',OLD_FLDÆ6Å);
WRITELN(LIST_FILE);
CLOSE(LIST_FILE,DUMMY);
END;æPRINT_CUSTå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
PAUSE ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE PAUSE;
VAR
NULL : CHAR;
BEGIN
WRITE('Press "RETURN" to continue ---');
READLN(NULL);
END;æPAUSEå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CONVERT TARGET VALUE TO KEY FORMAT ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE KEY_FORMAT(KEY : INTEGER;VAR TARGET : KEYSTR);
VAR
TEMP : STRINGÆ40Å;
BEGIN
IF UNIQ_KEY = KEY THEN
EXIT
ELSE
BEGIN
TEMP := CONCAT(TARGET,SPACE);
TEMP :=COPY(TEMP,1,KEY_LENÆKEYÅ-2);
TARGET := CONCAT(TEMP,NULL_CHR,NULL_CHR);
END;
END;æKEY_FORMATå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
COMPARE IDX_KEY & U_VALUE ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
FUNCTION COMPARE(KEY : INTEGER; IDXVAL,UPVAL : KEYSTR) : INTEGER;
VAR
KL : INTEGER;
C1,C2 : STRINGÆ40Å;
BEGIN
IF KEY = UNIQ_KEY THEN
KL := KEY_LENÆKEYÅ
ELSE
KL := KEY_LENÆKEYÅ-2;
C1 := CONCAT(IDXVAL,SPACE);
C1 := COPY(C1,1,KL);
C2 := CONCAT(UPVAL,SPACE);
C2 := COPY(C2,1,KL);
IF C1<C2 THEN
COMPARE := -1
ELSE IF C1>C2 THEN
COMPARE := 1
ELSE
COMPARE := 0;
END;æCOMPAREå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CHECK LOCK ROUTINES
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE SKIP_LOCK(KEY,DRN : INTEGER);
VAR
L_VALUE : KEYSTR;
BEGIN
WHILE (DRN <> 0) AND (LOKCOD <> 0) DO
BEGIN
L_VALUE := COPY(IDX_KEY,1,KEY_LENÆKEYÅ);
IDX_KEY := SET_LENGTH;
DRN := AFTKEY(KEY_NUMÆKEYÅ,FILE_NO,SLOCK,
L_VALUE,IDX_KEY);
END;
END;æSKIP_LOCKå
FUNCTION CHECK_LOCK(KEY,DRN : INTEGER) : BOOLEAN;
VAR
CONV_TARGET : KEYSTR;
DUMMY : CHAR;
BEGIN
WRITELN;
WRITE(
'Enter a "W" if you wish to wait for locked record(s)>>');
READLN(DUMMY);
IF (DUMMY = 'W') OR (DUMMY = 'w') THEN
BEGIN
CHECK_LOCK := TRUE;
EXIT;
END;
WHILE (DRN <> 0) AND (LOKCOD <> 0) DO
BEGIN
CONV_TARGET := COPY(IDX_KEY,1,KEY_LENÆKEYÅ);
IDX_KEY := SET_LENGTH;
IF OLD_ACTION = CONT THEN
DRN := AFTKEY(KEY_NUMÆKEYÅ,FILE_NO,
SLOCK, CONV_TARGET,IDX_KEY)
ELSE
DRN := BEFKEY(KEY_NUMÆKEYÅ,FILE_NO,
SLOCK, CONV_TARGET,IDX_KEY);
END;
CHECK_LOCK := FALSE;
END;æCHECK_LOCKå
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
WARNING MESSAGES
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE WARNING_TYPE(KEY,LOCALE,RET_CODE : INTEGER);
BEGIN
WRITELN;
WRITE('WARNING...Return Code #',RET_CODE,
' occurred while trying to ');
CASE LOCALE OF
1: WRITELN('remove old key from ',IDX_NAMEÆKEYÅ);
2: WRITELN('enter key into ',IDX_NAMEÆKEYÅ);
3: WRITELN('delete key from ',IDX_NAMEÆKEYÅ);
END; æOF CASEå
PAUSE;
END;æWARNING_TYPEå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
ADD NEW KEY VALUE ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE ADD_A_KEY(KEY,DRN : INTEGER);
VAR
RET_CODE,K_FLD : INTEGER;
BEGIN
K_FLD := KEY_MAPÆKEYÅ;
(*
REMOVE OLD KEY VALUE
*)
RET_CODE := DELKEY(KEY_NUMÆKEYÅ,FILE_NO,
XLOCK,OLD_FLDÆK_FLDÅ,DRN);
IF ERRCOD <> 0 THEN
ERROR_TYPE(KEY,4);
IF LOKCOD <> 0 THEN
LOCK_TYPE(6);
IF RET_CODE <> 1 THEN
WARNING_TYPE(KEY,1,RET_CODE);
(*
ADD NEW KEY VALUE
*)
RET_CODE := ADDKEY(KEY_NUMÆKEYÅ,FILE_NO,
XLOCK,NEW_FLDÆK_FLDÅ,DRN);
IF ERRCOD <> 0 THEN
ERROR_TYPE(KEY,5);
IF LOKCOD <> 0 THEN
LOCK_TYPE(7);
IF RET_CODE <> 1 THEN
WARNING_TYPE(KEY,2,RET_CODE);
END;æADD_A_KEYå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
WRITE NEW DATA RECORD ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE WRITE_CUST(DRN : INTEGER);
VAR
FLD,CHR,POS_PTR : INTEGER;
TMP_FLD : FLDSTR;
FLDPTR : ^FLD_REC;
BEGIN
DATBUF.CDF := NULL_CHR;
FLDPTR := ADDR(TMP_FLD); (* PTR TO STRING *)
POS_PTR := 0;
FOR FLD := 0 TO MAX_FIELD DO
BEGIN
TMP_FLD := NEW_FLDÆFLDÅ;
FOR CHR := 1 TO FLDPTR^.LENBYTE DO
DATBUF.FLDÆPOS_PTR + CHRÅ :=
FLDPTR^.FLDCHRÆCHRÅ;
WHILE (FLDPTR^.LENBYTE < FLD_LENÆFLDÅ) DO
BEGIN
FLDPTR^.LENBYTE := FLDPTR^.LENBYTE + 1;
DATBUF.FLDÆPOS_PTR + FLDPTR^.LENBYTEÅ := ' ';
END;
POS_PTR := POS_PTR + FLD_LENÆFLDÅ;
END;
IF WRTDAT(FILE_NO,DRN,DATBUF_PTR) <> 0 THEN
ERROR_TYPE(DRN,12);
END;æWRITE_CUSTå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DELETE KEY VALUE FROM INDEX ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE DEL_A_KEY(KEY,DRN : INTEGER);
VAR
RET_CODE,K_FLD : INTEGER;
BEGIN
K_FLD := KEY_MAPÆKEYÅ;
RET_CODE := DELKEY(KEY_NUMÆKEYÅ,FILE_NO,
XLOCK,OLD_FLDÆK_FLDÅ,DRN);
IF ERRCOD <> 0 THEN
ERROR_TYPE(KEY,6);
IF LOKCOD <> 0 THEN
LOCK_TYPE(10);
IF RET_CODE <> 1 THEN
WARNING_TYPE(KEY,3,RET_CODE);
END;æDEL_A_KEYå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
UPDATE INDICES & DATA FILE ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
FUNCTION UPDATE(DATA_RECORD : INTEGER) : INTEGER;
VAR
FLD,KEY : INTEGER;
BEGIN
IF DATA_RECORD = 0 THEN
BEGIN
DATA_RECORD := NEWREC(FILE_NO,XLOCK);
IF ERRCOD <> 0 THEN
ERROR_TYPE(0,8);
IF LOKCOD <> 0 THEN
LOCK_TYPE(3) ;
END;
UPDATE := DATA_RECORD;
FOR KEY := 0 TO MAX_KEY DO
BEGIN
FLD := KEY_MAPÆKEYÅ;
IF OLD_FLDÆFLDÅ <> NEW_FLDÆFLDÅ THEN
ADD_A_KEY(KEY,DATA_RECORD);
END;
FOR FLD := 0 TO MAX_FIELD DO
IF OLD_FLDÆFLDÅ <> NEW_FLDÆFLDÅ THEN
BEGIN
WRITE_CUST(DATA_RECORD);
EXIT;
END;
END;æUPDATEå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
DELETE INDEX & DATA FILE ENTRY ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE DELETE(DATA_RECORD : INTEGER);
VAR
FLD,KEY : INTEGER;
BEGIN
FOR KEY := 0 TO MAX_KEY DO
BEGIN
FLD := KEY_MAPÆKEYÅ;
IF OLD_FLDÆFLDÅ <> '' THEN
DEL_A_KEY(KEY,DATA_RECORD);
END;
IF RETREC(FILE_NO,XLOCK,DATA_RECORD) <> 0 THEN
ERROR_TYPE(DATA_RECORD,9);
IF LOKCOD <> 0 THEN
LOCK_TYPE(9);
END;æDELETEå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
NEW DATA ENTRY ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
FUNCTION NEWDAT : INTEGER;
VAR
TMPFLD : STRINGÆ40Å;
UNIQUE : BOOLEAN;
TMPDAT : INTEGER;
FLD,OP_VAL,FLD_NO : INTEGER;
OP1 : CHAR;
OP1_BYT : BYTE;
LABEL
111;
BEGIN
FOR FLD := 0 TO MAX_FIELD DO
OLD_FLDÆFLDÅ := '';
CLRSCR;
WRITELN(' ':19,'Enter New Customer Information');
WRITELN(' ':19,'******************************');
WRITELN;
WRITELN;
WRITELN(
' ÆPress "RETURN" for customer # to see main menu.Å');
WRITELN;
FOR FLD := 0 TO MAX_FIELD DO
BEGIN
FLD_NO := FLD + 1;
111:
WRITE(FLD_NO:6,' - ',FLD_NAMEÆFLDÅ:20,
'(',FLD_LENÆFLDÅ:2,') >>');
READLN(NEW_FLDÆFLDÅ);
IF (FLD = KEY_MAPÆUNIQ_KEYÅ) AND (NEW_FLDÆFLDÅ = '')
THEN BEGIN
NEWDAT := STOP;
EXIT;
END;
IF FLD = KEY_MAPÆUNIQ_KEYÅ THEN
BEGIN
NEW_FLDÆFLDÅ := CONCAT('0000',NEW_FLDÆFLDÅ);
RIGHT(NEW_FLDÆFLDÅ,FLD_LENÆFLDÅ);
UNIQUE := TEST_UNIQUENESS;
END
ELSE
BEGIN
TMPFLD := CONCAT(NEW_FLDÆFLDÅ,
' ');
NEW_FLDÆFLDÅ := COPY(TMPFLD,1,FLD_LENÆFLDÅ);
UNIQUE := TRUE;
END;
IF üUNIQUE THEN GOTO 111;
END;
WHILE (FOR_EVER) DO
BEGIN
WRITELN;
WRITELN;
WRITELN;
WRITELN(' ':19,'Current customer information');
WRITELN;
FOR FLD := 0 TO MAX_FIELD DO
BEGIN
FLD_NO := FLD + 1;
WRITELN(FLD_NO:6,' - ',FLD_NAMEÆFLDÅ:20,' ',
NEW_FLDÆFLDÅ);
END;
OP_VAL := 0;
WHILE (OP_VAL < 1) OR (OP_VAL > NO_FIELDS) DO
BEGIN
WRITELN;
WRITELN;
WRITELN(
'Enter S to save data, Field # to change data,');
WRITE(
'D to delete data, or E to end input >>') ;
READLN(OP1);
TMPDAT := 0;
IF (OP1 = 'S') OR (OP1 = 's') THEN
TMPDAT := SAVE;
IF (OP1 = 'D') OR (OP1 = 'd') THEN
TMPDAT := DELT;
IF (OP1 = 'E') OR (OP1 = 'e') THEN
TMPDAT := STOP;
IF TMPDAT <> 0 THEN
BEGIN
NEWDAT := TMPDAT;
EXIT;
END;
OP1_BYT := OP1;
OP_VAL := OP1_BYT - 48;
END;
UPDATE_FIELD(OP_VAL);
END;
END;æNEWDATå
FUNCTION OLDDAT(DRN: INTEGER) : INTEGER;
VAR
UNIQUE : BOOLEAN;
TMPDAT : INTEGER;
FLD,OP_VAL,FLD_NO : INTEGER;
OP1 : CHAR;
OP1_BYT : BYTE;
BEGIN
FOR FLD := 0 TO MAX_FIELD DO
NEW_FLDÆFLDÅ := OLD_FLDÆFLDÅ;
CLRSCR;
WHILE (FOR_EVER) DO
BEGIN
WRITELN;
WRITELN;
WRITELN;
WRITELN(' ':19,'Current customer information');
WRITELN;
FOR FLD := 0 TO MAX_FIELD DO
BEGIN
FLD_NO := FLD + 1;
WRITELN(FLD_NO:6,' - ',FLD_NAMEÆFLDÅ:20,' ',
NEW_FLDÆFLDÅ);
END;
OP_VAL := 0;
WHILE (OP_VAL < 1) OR (OP_VAL > NO_FIELDS) DO
BEGIN
WRITELN;
WRITELN;
WRITELN(
'Enter C to continue scan, Field # to change data, S to save changes,');
WRITE(
'D to delete data, B for back scan, or E to end scan >>');
READLN(OP1);
TMPDAT := 0;
IF (OP1 = 'C') OR (OP1 = 'c') THEN
TMPDAT := CONT;
IF (OP1 = 'S') OR (OP1 = 's') THEN
TMPDAT := SAVE;
IF (OP1 = 'D') OR (OP1 = 'd') THEN
TMPDAT := SET_XLOCK(OP1,DRN);
IF (OP1 = 'B') OR (OP1 = 'b') THEN
TMPDAT := BACK;
IF (OP1 = 'E') OR (OP1 = 'e') THEN
TMPDAT := STOP;
IF TMPDAT <> 0 THEN
BEGIN
OLDDAT := TMPDAT;
EXIT;
END;
OP1_BYT := OP1;
OP_VAL := OP1_BYT - 48;
END;
UPDATE_FIELD(OP_VAL);
END;
END;æOLDDATå
FUNCTION SET_XLOCK(OP : CHAR; DRN : INTEGER) : INTEGER;
VAR
DUMMY : CHAR;
BEGIN
DUMMY := 'W';
WHILE (DUMMY = 'W') AND (SETLOK(FILE_NO,XLOCK,DRN) <> 0) DO
BEGIN
WRITELN;
WRITELN('Customer update on hold due to record lock');
WRITE(
'Enter W if you wish to wait or any other key to cancel update>>');
READLN(DUMMY);
IF DUMMY = 'w' THEN DUMMY := 'W';
END;
IF DUMMY = 'W' THEN
BEGIN
IF OP = 'S' THEN
SET_XLOCK := SAVE
ELSE
SET_XLOCK := DELT;
END
ELSE
SET_XLOCK := OLD_ACTION;
END;æSET_XLOCKå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
UPDATE DATA FIELD ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE UPDATE_FIELD(FLD_NO : INTEGER);
VAR
TMPFLD : STRINGÆ40Å;
TEST : BOOLEAN;
FIELD_NO : INTEGER;
BEGIN
FIELD_NO := FLD_NO-1;
TEST := FALSE;
WHILE (üTEST) DO
BEGIN
WRITELN;
WRITE('Input new ',FLD_NAMEÆFIELD_NOÅ,'>>');
READLN(NEW_FLDÆFIELD_NOÅ);
IF FIELD_NO = KEY_MAPÆUNIQ_KEYÅ THEN
BEGIN
NEW_FLDÆFIELD_NOÅ := CONCAT('0000',NEW_FLDÆFIELD_NOÅ);
RIGHT(NEW_FLDÆFIELD_NOÅ,FLD_LENÆFIELD_NOÅ);
END
ELSE
BEGIN
TMPFLD := CONCAT(NEW_FLDÆFIELD_NOÅ,
' ');
NEW_FLDÆFIELD_NOÅ := COPY(TMPFLD,1,FLD_LENÆFIELD_NOÅ);
END;
IF (FIELD_NO = KEY_MAPÆUNIQ_KEYÅ) AND (NEW_FLDÆFIELD_NOÅ <>
OLD_FLDÆFIELD_NOÅ) THEN
TEST := TEST_UNIQUENESS
ELSE
TEST := TRUE;
END;
END;æUPDATE_FIELDå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CUST # UNIQUENESS TEST ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
FUNCTION TEST_UNIQUENESS : BOOLEAN;
VAR
TEMP : INTEGER;
TEST : FLDSTR;
BEGIN
TEST := NEW_FLDÆKEY_MAPÆUNIQ_KEYÅÅ;
TEMP := GETKEY(UNIQ_KEY,0,NLOCK,TEST);
IF LOKCOD <> 0 THEN
LOCK_TYPE(12);
IF TEMP = 0 THEN
TEST_UNIQUENESS := TRUE
ELSE
BEGIN
WRITELN;
WRITELN(' *** Already Assigned ***');
WRITELN;
TEST_UNIQUENESS := FALSE;
END;
END;æTEST_UNIQUENESSå
(*
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
RIGHT STRING ROUTINE
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
PROCEDURE RIGHT(VAR FLDVAL : FLDSTR; FLDLEN : INTEGER);
BEGIN
FLDVAL := COPY(FLDVAL,LENGTH(FLDVAL)-FLDLEN+1,FLDLEN);
END;æRIGHTå
(*
END OF UTILITY FUNCTIONS
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*)
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SET-UP DATABASE FIELD & KEY DESCRIPTORS
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
BEGIN
NO_FIELDS := MAX_FIELD + 1;
FLD_NAMEÆ0Å := 'Customer Number';
FLD_LENÆ0Å := 4;
FLD_NAMEÆ1Å := 'First Name';
FLD_LENÆ1Å := 16;
FLD_NAMEÆ2Å := 'Last Name';
FLD_LENÆ2Å := 20;
FLD_NAMEÆ3Å := 'Street Address';
FLD_LENÆ3Å := 20;
FLD_NAMEÆ4Å := 'City';
FLD_LENÆ4Å := 20;
FLD_NAMEÆ5Å := 'State';
FLD_LENÆ5Å := 2;
FLD_NAMEÆ6Å := 'Zipcode';
FLD_LENÆ6Å := 9;
FLD_NAMEÆ7Å := 'Customer Status';
FLD_LENÆ7Å := 8;
KEY_LENÆ0Å:=10;
KEY_TYPEÆ0Å:=0;
KEY_MAPÆ0Å:=2 ; (* KEY 0 = LAST NAME *)
KEY_LENÆ1Å:=11;
KEY_TYPEÆ1Å:=0;
KEY_MAPÆ1Å:=6 ; (* KEY 1 = ZIPCODE *)
KEY_LENÆ2Å:=4 ;
KEY_TYPEÆ2Å:=0;
KEY_MAPÆ2Å:=0 ; (* KEY 2 = CUST NUMBER *)
UNIQ_KEY := 2 ; (* USED IN TEST OF UNIQUENESS *)
FOR KEY := 0 TO MAX_KEY DO
BEGIN
IF KEY = UNIQ_KEY THEN
KEY_DUPÆKEYÅ := NO
ELSE
KEY_DUPÆKEYÅ := YES;
KEY_NAMEÆKEYÅ := FLD_NAMEÆKEY_MAPÆKEYÅÅ;
END;
IDX_NAMEÆ0Å := 'NAME.IDX';
IDX_NAMEÆ1Å := 'ZIPC.IDX';
IDX_NAMEÆ2Å := 'NUMB.IDX';
NLOCK := 0; (* IGNORE LOCKS *)
SLOCK := 1; (* SHARED RECORD LOCK *)
XLOCK := 2; (* EXCLUSIVE RECORD LOCK *)
SFILE := 3; (* SHARED FILE LOCK *)
XFILE := 4; (* EXCLUSIVE FILE LOCK *)
RLOCK := 5; (* RELEASE SLOCK) OR (XLOCK *)
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
INITIALIZE INDEX FILES
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
SET_LENGTH := '12345678901';
IDX_KEY := SET_LENGTH;
SPACE := ' ';
(*
SET TERMINAL TO -1 FOR AUTOMATIC ASSIGNMENT BY ACCESS MANAGER
*)
TERMINAL := -1;
TRAP_ERRORS := YES;
TIME_OUT_TEST_DELAY := 2; (* APPROXIMATELY 2 SECONDS *)
TERMINAL := INTUSR(TERMINAL,TRAP_ERRORS,TIME_OUT_TEST_DELAY);
IF ERRCOD <> 0 THEN
ERROR_TYPE(0,14);
NO_BUFFERS := 5;
NO_NODE_SECTORS := 4;
NO_DATA_FILES := 1;
NO_KEYZ := MAX_KEY + 1;
IF SETUP(NO_BUFFERS,NO_KEYZ,NO_NODE_SECTORS,NO_DATA_FILES) <> 0 THEN
BEGIN
WRITELN('Illegal SETUP Parameters');
EXIT;
END;
FOR KEY := 0 TO MAX_KEY DO
BEGIN
KEY_NUMÆKEYÅ := OPNIDX(-1,IDX_NAMEÆKEYÅ,
KEY_LENÆKEYÅ, KEY_TYPEÆKEYÅ,KEY_DUPÆKEYÅ);
IF ERRCOD <> 0 THEN
ERROR_TYPE(KEY,1);
END;
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
INITIALIZE DATA FILE
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
FILE_NO := -1;
RECORD_LENGTH := 100;
FILNAME := 'CUSTOMER.DAT';
FILE_NO := OPNDAT(FILE_NO,SFILE,FILNAME,RECORD_LENGTH);
IF ERRCOD <> 0 THEN
ERROR_TYPE(0,10);
IF LOKCOD <> 0 THEN
LOCK_TYPE(1);
(*
CUST_REC IS THE DATA FILE BUFFER AREA
*)
DATBUF_PTR := ADDR(DATBUF);
(*
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
BEGIN DATABASE OPERATION
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
*)
NULL_BYT := 0;
NULL_CHR := NULL_BYT;
FOR_EVER := TRUE;
WHILE (FOR_EVER) DO
DATA_BASE;
EXIT;
END.
«eof»