LIBRARY CROSS-REFERENCING SYSTEM Sample Description of the system: This system allows the user to store references to journal articles and books, along with a list of keywords (subjects) for each reference. It automatically maintains a "history" of all the keywords that are in the database. New additions to the database, and changes to the database, automatically update the keywords database. The user can display a list of all available keywords, and can also search for references that contain any given keyword, or group of keywords. Databases and Index Files: The main database is called LIBRARY.DAT, and it has this structure: STRUCTURE FOR FILE: B:LIBRARY .DBF NUMBER OF RECORDS: 00005 DATE OF LAST UPDATE: 00/00/00 PRIMARY USE DATABASE FLD NAME TYPE WIDTH DEC 001 AUTHOR C 040 002 TITLE C 040 003 PUB C 030 004 DATE C 008 005 PAGES C 008 006 ABSTRACT C 254 007 KEYWORDS C 080 ** TOTAL ** 00461 Two index files are maintained at all times. The first maintains an alphabetical listing by author and title. This index was created with the command: INDEX ON AUTHOR+TITLE TO AUTHORS The second index maintains a chronological order. Since the DATE is stored in MM/DD/YY fashion, the index file was created such that the year is of greater importance than the month and date. Hence, this index was created with the command: INDEX ON $(DATE,7,2)+$(DATE,1,5) TO DATES The second database maintains a history of all keywords used in the main database, as well as a counter of how many records in the main database use each keyword. The file is called KEYWORDS.DBF, and it has this structure: STRUCTURE FOR FILE: B:KEYWORDS.DBF NUMBER OF RECORDS: 00010 DATE OF LAST UPDATE: 00/00/00 PRIMARY USE DATABASE FLD NAME TYPE WIDTH DEC 001 KEYWORD C 020 002 KEYNO N 004 ** TOTAL ** 00025 This file is indexed on the keywords field, using the command: INDEX ON KEYWORD TO KEYWORDS Software Structure The command files are structured as follows: _______________ | LIBRARY.CMD | | | | Main Menu | |_____________| | ------------------------------------------- ______|________ __________|_________ ________|______ | LIBADD.CMD | | LREPORTS.CMD | |LIBEDIT.CMD | | Add new data| | Present sort, | | Allow edits,| | and update | | search, and | | and update | | keyword list| | report options, | | the keyword | _______________ | and print report | | file. | |__________________| |_____________| | | __________|_________ ________|______ | LIBFIND.CMD | | LIBED2.CMD | | Search for and | | Display Edit| | display references| | screen and | | by subject. | | allow edits | |___________________| |_____________| User-Interface When to user calls up the LIBRARY system, it first presents the Main Menu, as below: Library System Main Menu 1. Add new references 2. Print Reports 3. Edit References 4. Exit Enter choice (1-4) If the user wishes to Add new references, he is presented with a custom "APPEND" screen, as below: Record No. 1 Enter new Data, ^Q to Quit ---------------------------------------------------------- Author: : Title : : Pub. : : Date : : : Pages : : Abstract: : Keyword 1 : : Keyword 2 : : Keyword 3 : : Keyword 4 : : Keyword 5 : : Keyword 6 : : Keyword 7 : : --------------------------------------------------------- If the user wants to Print Reports, the screen asks if he wishes to print keywords or references. If the user select keywords, then the keyword file is displayed, alphabetically, in two columns, as below: BANK PERFORMANCE DBASE II PRIMARY DISK DRIVES ROBBERS DOG BISCUITS SECONDARY MULTIPLE FILES UPDATE If the user wishes to see references, the screen first asks: How do you want references sorted? 1. Alphabetically by Author 2. Chronologically by Date 3. Original Order Then, the user can type in the subjects he wishes to search for, in a screen as below: Keyword 1 : : Keyword 2 : : Keyword 3 : : Keyword 4 : : Keyword 5 : : Keyword 6 : : Keyword 7 : : If the user requests to search on more than one keyword, the screen asks if the user wants references with ALL or ANY keyword. Then, the appropriate references are displayed in the format below: Author: Blaine, Appy Title : Dog Biscuits in your Disk Drives Pub. : Data Based Advisor Date : 01/01/83 Pages : 12-345 Keywords : DBASE II, DISK DRIVES, DOG BISCUITS, Abstract : A complete listing of items not to put into your disk drives. Includes mention of those sticky little yellow "Post-It" pads, which tend to disable drive B on many computers. However, dog biscuits are the ultimates no-no for putting into floppy drives. Edits are handled by asking the user for the last name of the main author of the reference to edit. If there is no such author, the user is told so. If there are numerous references by this author, then those are displayed and the user is asked to select by record number. Once the reference to edit is found, the reference is displayed on the screen in exactly the same format as the APPEND format, and the user can make changes. Program Listings The programs used in the LIBRARY system are displayed below: ********************************** LIBRARY.CMD ******************** Library System Main Menu. ******************** The LIBRARY System maintains ******************** a history and count of all ******************** keywords used in the LIBRARY ******************** database. SET TALK OFF SET DEFA TO B STORE 0 TO CHOICE *************************** Display Main Menu. DO WHILE CHOICE <> 4 ERASE TEXT Library System Main Menu 1. Add new references 2. Print Reports 3. Edit References 4. Exit ENDTEXT INPUT " Enter choice (1-4) " TO CHOICE **************** Branch to appropriate procedure **************** based upon choice. DO CASE CASE CHOICE = 1 DO LIBADD CASE CHOICE = 2 DO LREPORTS CASE CHOICE = 3 DO LIBEDIT ENDCASE ENDDO (while choice # 4) Here is LIBADD.CMD, used for adding new records. *************************************** LIBADD.CMD *************************************** Add new data. ************** Open Data Files SELECT PRIMARY USE LIBRARY INDEX AUTHORS,DATES SELECT SECONDARY USE KEYWORDS INDEX KEYWORDS SET EXACT ON ************** Initialize memory variables. STORE " " TO K1,K2,K3,K4,K5,K6,K7 SELECT PRIMARY GO BOTT DO WHILE AUTHOR <> " " .OR. # <= 1 ************ Display custom APPEND screen, (which ************ was created with ZIP). ERASE APPEND BLANK @ 1, 3 SAY "Record No. "+STR(#,3)+" Enter new Data, ^Q to Quit" @ 2, 0 SAY "--------------------------------------------------" @ 2,50 SAY "------------------------------" @ 4, 3 SAY "Author" @ 4,12 GET AUTHOR @ 5, 3 SAY "Title" @ 5,12 GET TITLE @ 6, 3 SAY "Pub." @ 6,12 GET PUB @ 7, 3 SAY "Date" @ 7,12 GET DATE PICT "99/99/99" @ 7,26 SAY "Pages" @ 7,32 GET PAGES @ 9, 3 SAY "Abstract" @ 9,12 GET ABSTRACT @ 13, 3 SAY "Keyword 1" @ 13,13 GET K1 @ 14, 3 SAY "Keyword 2" @ 14,13 GET K2 @ 15, 3 SAY "Keyword 3" @ 15,13 GET K3 @ 16, 3 SAY "Keyword 4" @ 16,13 GET K4 @ 17, 3 SAY "Keyword 5" @ 17,13 GET K5 @ 18, 3 SAY "Keyword 6" @ 18,13 GET K6 @ 19, 3 SAY "Keyword 7" @ 19,13 GET K7 @ 21, 0 SAY "--------------------------------------------------" @ 21,50 SAY "------------------------------" READ ****************** ONLY perform this step if not exiting this program. IF AUTHOR <> " " ****************** Update the Keyword File. SELECT SECONDARY STORE " " TO TEMPKEY STORE 1 TO COUNT STORE STR(COUNT,1) TO MAC DO WHILE K&MAC <> " " .AND. COUNT < 8 STORE !(K&MAC) TO K&MAC FIND &K&MAC IF # > 0 REPLACE KEYNO WITH KEYNO+1 ELSE APPEND BLANK REPLACE KEYWORD WITH K&MAC REPLACE KEYNO WITH 1 ENDIF (# > 0) *** Put keyword into temporary TEMPKEY string. STORE TEMPKEY+TRIM(K&MAC)+", " TO TEMPKEY **** Clear out K&MAC memory variables, and increment count. STORE " " TO K&MAC STORE COUNT +1 TO COUNT STORE STR(COUNT,1) TO MAC ENDDO (k&mac<>" ") ENDIF [not exiting this program (author <> "")] SELECT PRIMARY *********************** Put tempkey into keywords on Primary file. REPLACE KEYWORDS WITH TEMPKEY ENDDO (while author <> " ") *********************** Get rid of any "blank" records. DELETE ALL FOR AUTHOR = " " .AND. TITLE = " " PACK *********************** Return to Main Menu. SET EXACT OFF RETURN LREPORTS, below, presents options for, and prints reports. **************************** LREPORTS.CMD ********** Asks user if they want keyword ********** listing or to search references ********** By subjects. Provides the keyword ********** listing, branches to LIBFIND for ********** search by subject. ERASE STORE " " TO RCHOICE @ 5,10 SAY " Which Report do you want " @ 7, 5 SAY "1. Keyword Listing" @ 8, 5 SAY "2. References by Subject" @ 10,8 SAY "Enter choice (1-2) " GET RCHOICE READ *********** Do appropriate report based upon user's request. DO CASE CASE RCHOICE = "1" ******* Ask about hardcopy ERASE STORE " " TO LP @ 5,10 SAY " Send Keywords to printer (Y/N) " GET LP READ IF !(LP)="Y" *SET PRINT ON ENDIF (lp=y) *********** print keywords in two alphabetized columns. ERASE USE KEYWORDS GO BOTT STORE (#+1)/2 TO MIDDLE STORE 1 TO COUNTER USE KEYWORDS INDEX KEYWORDS STORE "Y" TO OK DO WHILE COUNTER <= MIDDLE .AND. !(OK)="Y" ? KEYWORD SKIP MIDDLE IF .NOT. EOF ?? KEYWORD SKIP -1*MIDDLE-1 ENDIF (not eof) STORE COUNTER + 1 TO COUNTER ************** If keyword list going to the screen, ************** Pause every 20 lines. IF COUNTER/20 = INT(COUNTER/20) .AND. !(LP) <> "Y" ? ? ? " Continue? (Y/N) " WAIT TO OK ENDIF (counter/20 and not lp) ************* If keyword list going to the ************* printer, eject page every 60 lines. IF COUNTER/60 = INT(COUNTER/60) .AND. !(LP) = "Y" EJECT ENDIF (counter/60 and lp) ENDDO (counter and ok) ************* If keyword list going to the screen, pause ************* before returning to the main menu. IF !(LP) <> "Y" ? ? ? " Press any key to return to main menu..." WAIT ENDIF (lp <> y) CASE RCHOICE = "2" DO LIBFIND ENDCASE RETURN The LIBFIND command file fins and displays records that have subjects in common. *********************************** LIBFIND.CMD ********** Pull out records with certain subjects. ********** First, ask for sort order. ERASE STORE 1 TO ORDER ? ? " How do you want references sorted? " ? ? " 1. Alphabetically by Author " ? " 2. Chronologically by Date" ? " 3. Original Order" @ 9,4 SAY "Enter choice (1-3) " GET ORDER PICT "9" READ *********** Use appropriate index. DO CASE CASE ORDER = 1 USE LIBRARY INDEX AUTHORS CASE ORDER = 2 USE LIBRARY INDEX DATES CASE ORDER = 3 USE LIBRARY OTHERWISE RETURN ENDCASE ************************* Next, get search criteria. ERASE STORE " " TO K1,K2,K3,K4,K5,K6,K7,K8 @ 3,5 SAY "Keyword 1 " GET K1 @ 4,5 SAY "Keyword 2 " GET K2 @ 5,5 SAY "Keyword 3 " GET K3 @ 6,5 SAY "Keyword 4 " GET K4 @ 7,5 SAY "Keyword 5 " GET K5 @ 8,5 SAY "Keyword 6 " GET K6 @ 9,5 SAY "Keyword 7 " GET K7 READ *********************** Count how many keywords to search on. *********************** and store to the variable kcount. STORE 0 TO KCOUNT STORE "1" TO MAC DO WHILE K&MAC <> " " STORE KCOUNT+1 TO KCOUNT STORE STR(KCOUNT+1,1) TO MAC ENDDO ************** Now, set up search condition into ************** a memory variable called CND. ************** First, set up initial search condition. STORE CHR(34)+" "+!(TRIM(K1))+","+CHR(34)+" $KEYWORDS" TO CND ************** If many keywords to search on, ************** ask about the logic of the search. STORE "0" TO LOGIC IF KCOUNT > 1 ? @ 12,2 SAY " References with 1) ALL keywords or 2) ANY keyword " GET LOGIC READ IF LOGIC = "1" STORE " .AND. " TO LOGIC ELSE STORE " .OR. " TO LOGIC ENDIF (logic=1) *********** Then finish the 'condition' string (CND). STORE 2 TO COUNT DO WHILE COUNT <= KCOUNT STORE STR(COUNT,1) TO MAC STORE CND+LOGIC+CHR(34)+" "+!(trim(K&MAC))+","+CHR(34)+; " $KEYWORDS" TO CND STORE COUNT+1 TO COUNT ENDDO (count <=kcount) ENDIF (kcount > 1) *********** Ask about hardcopy. ERASE STORE " " TO LP @ 5,5 SAY " Send report to printer (Y/N) " GET LP READ ************ Prepare printer if necessary. IF !(LP)="Y" @ 7,5 SAY "Ready printer, then press any key..." WAIT SET PRINT ON ENDIF (LP = Y) ************ Use LF to count line-feeds for formatting ************ On the screen and printer. STORE 0 TO LF ************ Finally, print the report, listing only ************ references for whom &CND is true. ERASE DO WHILE .NOT. EOF IF &CND ? "Author:",AUTHOR ? "Title :",TITLE ? "Pub. :",PUB ? "Date :",DATE," Pages : ",PAGES ? ? "Keywords : "+KEYWORDS ? "Abstract : " STORE LF+7 TO LF ****************** Break off long abstract at space ****************** Nearest the right margin. STORE TRIM(ABSTRACT) TO STRING STORE LEN(TRIM(STRING)) TO TLEN DO WHILE TLEN > 60 **************** Find space nearest right margin STORE 60 TO SPOT DO WHILE $(STRING,SPOT,1)<>" " STORE SPOT-1 TO SPOT ENDDO (while not " ") **************** Print sub-string and break off section. ? $(STRING,1,SPOT-1) STORE LEN(TRIM(STRING))-SPOT TO TLEN STORE $(STRING,SPOT+1,TLEN) TO STRING STORE LF+1 TO LF ENDDO (while len > 60) ? STRING ? ? STORE LF+3 TO LF ************* Count line feeds, and start on ************* new page, if necessary. IF LF >= 55 EJECT STORE 0 TO LF ENDIF (lf > 55) ENDIF (cnd) SKIP ENDDO (while not eof) SET PRINT OFF USE RETURN LIBEDIT prepares for editing, and manages keyword file updates. ***************************** LIBEDIT.CMD ************* Allows user to look up a reference ************* by primary author name, and change ************* data. Automatically updates the ************* keyword history file. ************* Set up databases and memory variables. SELE PRIM USE LIBRARY INDEX AUTHORS,DATES SELE SECO USE KEYWORDS INDEX KEYWORDS SELE PRIM STORE " " TO K1,K2,K3,K4,K5,K6,K7 ************** Find out who to edit. ERASE ? ACCEPT " Enter Main Author's last name " TO SEARCH STORE !(SEARCH) TO SEARCH ERAS *************** Determine if 0, 1 or many references *************** By this author, and react accordingly. FIND &SEARCH STORE 0 TO HOWMANY COUNT WHILE !(AUTHOR) = SEARCH TO HOWMANY DO CASE CASE HOWMANY = 0 STORE 0 TO RECNO ? ? " There is no &SEARCH on the database." ? WAIT CASE HOWMANY = 1 FIND &SEARCH STORE # TO RECNO CASE HOWMANY > 1 FIND &SEARCH LIST WHILE LNAME = &SEARCH AUTHOR, TITLE, PUB ? INPUT " Which one (by number) " TO RECNO ENDCASE *********** Edit appropriate record, if recno > 0 ERASE IF RECNO > 0 GOTO RECNO *************** Peel out individual keywords from *************** the long KEYWORDS field in the *************** library database. STORE 2 TO START STORE 1 TO COUNT STORE KEYWORDS TO TEMP DO WHILE "," $(KEYWORDS) STORE STR(COUNT,1) TO SCOUNT STORE $(KEYWORDS,START,@(",",KEYWORDS)-2) TO K&SCOUNT REPLACE KEYWORDS WITH $(KEYWORDS,@(",",KEYWORDS)+1,50) STORE COUNT+1 TO COUNT ENDDO (while "," $keywords) ************* just in case user deletes any or all ************* keywords, subtract 1 from the total number ************* of references for this keyword from ************* The keywords file. SELE SECO STORE 1 TO X STORE "1" TO MAC DO WHILE K&MAC <> " " FIND &K&MAC REPLACE KEYNO WITH KEYNO-1 STORE X+1 TO X STORE STR(X,1) TO MAC ENDDO ****** Now branch to LIBED2 to do the edit. ****** (LIBED2 is stolen from the LIBADD command file.) SELE PRIM DO LIBED2 ENDIF (recno > 0) **************** Before returning to main menu, **************** Eliminate any keywords for which there **************** are no references ERASE ? " Updating keyword file.........." SELE SECO DELE ALL FOR KEYNO=0 PACK RETURN LIBED2 is an extension of LIBED, and handles the actual screen display in editing data. It is mostly a clone of LIBADD. **************************************** LIBED2.CMD **************************** Allow user to edit reference, **************************** then re-update keywords file. *************** (This command file was created by "borrowing" *************** a portin of LIBADD.CMD, and modifying). ERASE @ 1, 3 SAY "Record No. "+STR(#,3) @ 2, 0 SAY "--------------------------------------------------" @ 2,50 SAY "------------------------------" @ 4, 3 SAY "Author" @ 4,12 GET AUTHOR @ 5, 3 SAY "Title" @ 5,12 GET TITLE @ 6, 3 SAY "Pub." @ 6,12 GET PUB @ 7, 3 SAY "Date" @ 7,12 GET DATE PICT "99/99/99" @ 7,26 SAY "Pages" @ 7,32 GET PAGES @ 9, 3 SAY "Abstract" @ 9,12 GET ABSTRACT @ 13, 3 SAY "Keyword 1" @ 13,13 GET K1 @ 14, 3 SAY "Keyword 2" @ 14,13 GET K2 @ 15, 3 SAY "Keyword 3" @ 15,13 GET K3 @ 16, 3 SAY "Keyword 4" @ 16,13 GET K4 @ 17, 3 SAY "Keyword 5" @ 17,13 GET K5 @ 18, 3 SAY "Keyword 6" @ 18,13 GET K6 @ 19, 3 SAY "Keyword 7" @ 19,13 GET K7 @ 21, 0 SAY "--------------------------------------------------" @ 21,50 SAY "------------------------------" READ ****************** Update Keyword File. SELECT SECONDARY STORE " " TO TEMPKEY STORE 1 TO COUNT STORE STR(COUNT,1) TO MAC DO WHILE K&MAC <> " " .AND. COUNT < 8 STORE !(K&MAC) TO K&MAC FIND &K&MAC IF # > 0 REPLACE KEYNO WITH KEYNO+1 ELSE APPEND BLANK REPLACE KEYWORD WITH K&MAC REPLACE KEYNO WITH 1 ENDIF (# > 0) *** Now, concatentate K&MAC into temporary KEYWORDS string. STORE TEMPKEY+TRIM(K&MAC)+", " TO TEMPKEY STORE COUNT +1 TO COUNT STORE STR(COUNT,1) TO MAC ENDDO (k&mac<>" ") *********************** Put tempkey into keywords SELECT PRIMARY REPLACE KEYWORDS WITH TEMPKEY RETURN