The sample programs provided with the Basic Web Utility can be used as learning guides as well as the basis for practical CGI programs.
A UNIX shell script to start a specific Business Basic program, demobbw.bbx, establishes the Basic Web Utility CGI environment. It then locates the CGI value of pgm to determine which sample program to run. If no pgm value is specified, a menu is presented.
The Customer Inquiry application uses the programs democlst.bbx and demoilst.bbx. These in turn use the HTML document template files democlst.txt and demoilst.txt.
The Customer Maintenance application uses the programs democent.bbx and democupd.bbx. The democent.bbx links to the customer list program presented in the Customer Inquiry application. These programs do not use HTML templates.
Source code and comments for each of the sample applications are presented on the following pages.
The shell script bbweb.sh is copied to a cgi directory and named demobbw.sh. Most servers contain a standard cgi-bin directory in the directory mapping structure defined in the server configuration files.
#!/bin/sh
# Copyright (C) 1996 by Allen Miglore. All rights reserved.
# bbweb.sh is a standard shell script that can be used to start a
# BBx/Pro5 task in a UNIX environment. This script can be copied
# to the cgi directory, given whatever name you need, or it can
# be used as is by other scripts that would set PGM and optionally
# MEM before exec'ing this script.
# Set PGM and MEM to desired values for the bbx program and start size.
# (these can be set in another script, that execs this one.)
The PGM environment variable must be set to the name of the Business Basic program (in this case, demobbw.bbx). If the program requires more or less than 512 pages, the MEM variable can also be set.
The values for ERRORLOG , CONFIG , AND BBXEXEC must also be modified to match the configuration. The file name ERRORLOG stores messages related to problems starting Business Basic. CONFIG points to the PRO/5 configuration file used by Basic Web Utility programs, and BBXEXEC is the name of the PRO/5 executable.
The CONFIG file must be edited so the PREFIX contains the Basic Web Utility installation directory.
PGM=demobbw.bbx
#MEM=512
# modify these values per your bbx configuration
MAXTRIES=5
ERRORLOG=/usr/lib/pro5/webb/error.log
CONFIG=/usr/lib/pro5/webb/bbweb.cnf
BBXEXEC=/usr/lib/pro5/pro5
MEM=${MEM:=512}
if [ "$PGM" = "" ]
then
echo "Content-type: text/plain"
echo ""
echo "Invalid pgm argument"
exit
fi
umask 0
RETRIES=0
This section starts PRO/5. If it fails, it retries, sends the user an HTML message, and records the error to the ERRORLOG file.
until [ $RETRIES -gt $MAXTRIES ]
do
$BBXEXEC -q -c$CONFIG -m$MEM $PGM - "$@" 2>/tmp/bberr.$$
if [ -s /tmp/bberr.$$ ]
then
RETRIES=`expr $RETRIES + 1`
sleep 1
read msg </tmp/bberr.$$
rm /tmp/bberr.$$ 2>/dev/null
else
RETRIES=99
rm /tmp/bberr.$$ 2>/dev/null
fi
done
if [ ! "$RETRIES" = "99" ]
then
echo `date` $msg >>$ERRORLOG 2>/dev/null
echo "Content-type: text/plain"
echo ""
echo "The database server is too busy. Sorry about that."
echo "Please try again later."
echo ""
echo "By the way, we have recorded this problem, and will add"
echo "capacity if it happens frequently."
fi
This program is started by the demobbw.sh shell script. It loads the CGI environment with a CALL to utcgi.wbb and creates the data templates used by the other sample programs.
0010 REM "demobbw.bbx - startup for Basic Web Utility demo programs
0020 REM "Copyright 1996 by Allen Miglore. All rights reserved.
0100 REM ^100 - Introduction
0110 REM "This is the startup routine used by the Basic Web Utility demo
0120 REM "program. It reads the CGI input stream, sets up the
0130 REM "data templates, loads a salesperson code table, and then runs
0140 REM "a specified program. The default program is a customer list.
0200 REM ^100 - get cgi inputs
0210 CALL "utaddr.wbb"
0220 CALL "utcgi.wbb",ENV$,CGI$,ERRMSG$;
IF ERRMSG$>""
THEN
GOTO LOADERROR
0300 REM ^100 Dim templates used by the files
0310 DIM CUST$:"cust_id:c(5*),
name:c(30*):case=upper:,
addr1:c(30):caption=Address_1 case=upper:, addr2:c(30*):caption=Address_2 case=upper:,
city:c(20*):case=upper:,
state:c(2*):case=upper:,
zip:c(5*),
phone:c(10*):mask=(000)-000-0000:,
date_last_sale:c(8):date=yymd:,
date_last_pmt:c(8*):date=yymd:,
class:c(2),
slsp:c(3):keys={stbl_$SLSPID} vals={stbl_$SLSPNM} sep=\\\ formtype=list rows=1:,
terms:c(2*),
credit_limit:n(8*):mask=###,##0-:,
ytd_sales:n(10*):mask=###,##0.00-:,
mtd_sales:n(10*):mask=###,##0.00-:,
ytd_cost:n(10*):mask=###,##0.00-:,
mtd_cost:n(10*):mask=###,##0.00-:"
0320 DIM INVOICE$:"cust_id:c(5),
invoice:c(5),
date:n(8):date=jul:,
slsp:c(3),
fill:c(2):formtype=hidden:,
amount:i(4):scale=2 mask=###,##0.00-:"
0330 DIM SLSP$:"slsp_id:c(3*),name:c(20*)"
In the CUST$ data template, a list of keys and descriptions are referred to by the global string values $SLSPID and $SLSPNM. These lists are loaded here, and when other routines generate selection lists or displays of salesperson values, the IDs and names are used.
0400 REM ^100 - load the STBL's for $SLSPID and $SLSPNM
0410 REM "The CUST$ template references keys and vals for the slsp field.
0420 REM "This facilitates the default use of a select list object for
0430 REM "entry forms, and also will cause HTML merges to use the name
0440 REM "rather than the id for display purposes. Note that placing
0450 REM "these references in the template merely serves to provide
0460 REM "default formatting, and that can be overridden in any given
0470 REM "situation.
0480 LET SLSPCHAN=UNT;
OPEN (SLSPCHAN)"GENSMPL2"
0490 LET IDS$="",NAMES$=""
0500 READ RECORD(SLSPCHAN,END=0520)SLSP$
0510 LET IDS$=IDS$+SLSP.SLSP_ID$+"\\\",NAMES$=NAMES$+SLSP.NAME$+"\\\";
GOTO 0500
0520 LET X$=STBL("$SLSPID",IDS$),X$=STBL("$SLSPNM",NAMES$),IDS$="",NAMES$=""
0530 CLOSE (SLSPCHAN)
Now that the setup is complete, the program branches to the program specified in the CGI input value pgm. If no pgm value is specified, or an invalid pgm is specified, the HTML document demomenu.txt is loaded and displayed. By using the text {include filename} and calling utmeta.wbb, a disk-based document can be loaded.
0600 REM ^100 - Run the program specified in pgm, or default to the menu.
0610 RUN FIELD(CGI$,"pgm",ERR=0620),ERR=0620
0620 LET TEXT$="{include demomenu.txt}"
0630 CALL "utmeta.wbb","",TEXT$
0640 CALL "utsend.wbb",TEXT$
0650 DONE:
RELEASE
1000 LOADERROR:
REM ^1000 - problem with utcgi - fatal problem
1010 REM "If we are here, there was a REAL BIG PROBLEM. Without
1020 REM "proper initialization, the DOS/WIN environment has no way
1030 REM "of contacting the browser of this, so the best thing is
1040 REM "just to leave gracefully but silently. On UNIX, with
1050 REM "stdout support, a notification of the error can be sent
1060 REM "to the browser.
1070 IF POS("DOS"=INFO(0,0))>0 OR POS("WIN"=INFO(0,0))>0
THEN
GOTO DONE
1080 PRINT "Content-type: text/html",$0A$
1090 PRINT "The following error message was returned by utcgi.wbb:<br>"
1100 PRINT ERRMSG$
1110 GOTO DONE
This program is used by both sample applications and is the lead program in the Customer Inquiry application in which customers are listed. Each customer has a link to a detailed invoice page. It is also used to select a customer to edit in the Customer Maintenance application.
The program reads up to 10 customer records, in name order, from the customer master file, using key chain 1 (the Name sort key). If additional records are available (there are about 30 in the file), a More records... link is provided to continue the list.
0001 SETERR ERRTRAP
0010 REM "democlst.bbx - Basic Web Utility Customer Listing Demo
0020 REM "Copyright 1996 by Allen Miglore. All rights reserved.
0030 REM "Permission to derive programs from this is hereby granted,
0040 REM "provided said programs utilize licensed copies of the Basic Web Utility.
0100 REM ^100 - If restarting this list, the CGI field "startwith"
0110 REM will contain the starting point. This can come
0120 REM either from the form contained at the end of the
0130 REM democlst.txt HTML template, or from the "more records"
0140 REM continuation link.
A CGI variable startwith is passed to this program in two cases. If the current execution is a continuation of the list, then the more records URL will contain this field In addition, at the bottom of the HTML display is a form with a startwith entry field to allow the user to restart the list at any time.
0150 LET STARTWITH$="", STARTWITH$=CVS(FIELD(CGI$,"startwith",ERR=0200),4)
These lines set the values for the uthtmfil.wbb program, identifying the key chain, records per page, and record structure. The HTML template file, democlst.txt, contains a place marker between the <ul> and </ul> (unordered list) tags. The structure includes a <li> (list element) tag so that each record becomes another bullet item in the document. The name field is treated as a link, and the link is specified in the variable LINKEXPR$, which is constructed to run a program with the CGI value, cust_id, set to the customer number of any given record. The program defaults to the sample invoice list demoilst.bbx but can be specified in the CGI value linkto. The Customer Maintenance application uses the linkto value to load and edit a customer record.
0200 REM ^100 - Initialize other values
0210 LET KNUM=1,MAXRECS=10
0220 LET STRUCTURE$="<li> [name @link] ([cust_id]), [city], [state] [zip], [phone]"
0300 REM ^100 - Construct a link expression, used to link each customer
0310 REM to a specified program for further display/edit
0320 LET LINKEXPR$=ENV.SCRIPT_NAME$+"?cust_id=[cust_id @encode]"
0330 LET LINKTO$="demoilst.bbx",LINKTO$=FIELD(CGI$,"linkto",ERR=0340)
0340 LET LINKEXPR$=LINKEXPR$+"&pgm="+LINKTO$
0400 REM ^100 - Open Customer Data File
0410 LET CUSTCHAN=UNT;
OPEN (CUSTCHAN)"GENSMPL1"
After opening the customer master file, the uthtmfil.wbb program generates a list of records in the CUSTLIST$ variable and lists up to MAXRECS records. The list starts with the value in STARTWITH$ and continues until the end of the file. If the variable CURKEY$ is returned with a value, the end of the file was not reached, and a More records URL is constructed to continue where the list ended. This URL is placed in the global string $MOREURL, which is referenced in the HTML text template democlst.txt.
0500 REM ^100 - Construct List
0510 REM uthtmfil.wbb reads from a channel, and builds list of
0520 REM records, using a particular structure, into a string
0530 CALL "uthtmfil.wbb", CUSTCHAN, STARTWITH$, "", KNUM, MAXRECS, COUNT, CURKEY$, CUST$, STRUCTURE$, CUSTLIST$,LINKEXPR$
0600 REM ^100 - If there are more records in the file, add a "more records"
0610 REM link URL to continue. curkey$ contains the key to the
0620 REM next record required. By placing this in a STBL, the
0630 REM uthtmout.wbb program that loads the HTML template can
0640 REM conditionally place it after the list.
0650 LET X$=STBL("$MOREURL","");
IF CURKEY$=""
THEN
GOTO 0680
0660 CALL "utencode.wbb",0,CURKEY$,NEXT_STARTWITH$
0670 LET MOREURL$=STBL("$MOREURL",ENV.SCRIPT_NAME$+"?pgm=democlst.bbx&startwith="+NEXT_STARTWITH$)
The HTML file, democlst.txt, is loaded and parsed into the variable HTML$. In that file is a comment <!-- List Here -->, which is substituted with the contents of the CUSTLIST$ variable, generated above. The full text of HTML$ is sent with the utsend.wbb program, and the program exits. In version 1.1, two global string values are created automatically by uthtmfil: $list contains the record list returned in custlist$, and $moreurl contains either null (if the end of file is reached), or a URL to continue the list. These can be referenced in democlst.txt as [$list] and [$moreurl], respectively.
0680 REM ^100 - Load the HTML template, and add the list to it
0690 CALL "uthtmout.wbb",CGI$,"{include democlst.txt}",HTML$,""
0700 CALL "utsub.wbb",HTML$,"<!-- List Here -->",CUSTLIST$
0800 REM ^100 - Send it to the user
0810 CALL "utsend.wbb",HTML$
1000 DONE:
REM ^1000 - Clean up and exit
1010 CALL "utexit.wbb",CGI$
1020 IF RETURN_TO_WATCH
THEN
RUN "utwatch.wbb"
1030 RELEASE
It is important to trap all errors because Basic Web Utility programs run in background mode.
2000 ERRTRAP:
REM ^1000 - generic error trap
2010 CALL "uterr.wbb",ERR,TCB(5),PGM(-2)
2020 GOTO DONE
The customer invoice history display is used by the Customer Inquiry application to show a listing of invoices associated with a given customer. The application uses the Scrolling Customer Listing program, and each customer listed is linked to this program through a URL containing the customer ID.
0001 SETERR ERRTRAP
0010 REM "demoilst.bbx - Basic Web Utility Customer Invoice Listing Demo
0020 REM "Copyright 1996 by Allen Miglore. All rights reserved.
0030 REM "Permission to derive programs from this is hereby granted,
0040 REM "provided said programs utilize licensed copies of the Basic Web Utility.
As with the scrolling customer listing, a startwith value can be supplied to begin the invoice listing at a particular point. A more records link, containing the startwith value, is specified in this program where there are more than 10 invoices to display.
0100 REM ^100 - If continuing the invoice list, the CGI field
0110 REM "startwith" is used to indicate what invoice.
0120 LET STARTWITH$="",STARTWITH$=FIELD(CGI$,"startwith",ERR=0130)
The invoices are presented in a HTML table structure, so each line from the invoices file is formatted with table row tags. In addition, the table and column heading tags are required above and below the invoice list and are stored in TABLETOP$ and TABLEBOT$.
0200 REM ^100 - Initialize other values
0210 LET KNUM=0,MAXRECS=10
0215 LET TABLETOP$="<table border><tr><th>Invoice</th><th>Date</th><th>Amount</th></tr>"
0220 LET STRUCTURE$="<tr><td>[invoice]</td> <td>[date]</td> <td align=right>[amount]<br></td></tr>"
0225 LET TABLEBOT$="</table>"
0400 REM ^100 - Open Data Files
0410 LET CUSTCHAN=UNT;
OPEN (CUSTCHAN)"GENSMPL1"
0420 LET INVCHAN=UNT;
OPEN (INVCHAN)"GENSMPL3"
The customer record is read into CUST$, and a table is built from a list of fields in the CIST$ template. The HTML text for the table is placed in CUSTINFO$.
0450 REM ^100 - Get Customer Data and Create Display
0460 READ RECORD(CUSTCHAN,KEY=FIELD(CGI$, "cust_id", ERR=NODATA), DOM=0470)CUST$
0470 CALL "uthtmgen.wbb",
CUST$,"cust_id,name,addr1,addr2,city,state,zip,phone,slsp", "", "table border", "", "", CUSTINFO$
A list of invoices (up to MAXRECS at a time) is loaded into the variable INVLIST$. The list begins with the customer ID, plus the invoice number indicated in the STARTWITH$, and continues until all invoices for the customer ID have been read. If there are more than MAXRECS invoices, the CURKEY$ contains that next one in line, after the customer ID is trimmed off. This is used to construct the global string $MOREURL, which is referenced in the HTML text file demoilst.txt to allow the user to continue the list. Note the use of the startwith value in the URL.
The CGI environment variable SCRIPT_NAME contains the name of the cgi script that launched this program. Because the same script is used for all the sample programs, it provides a convenient way of building another URL.
0500 REM ^100 - Construct Invoice List
0510 REM uthtmfil.wbb reads from a channel, and builds list of
0520 REM records, using a particular structure, into a string
0530 CALL "uthtmfil.wbb",INVCHAN,CGI.CUST_ID$+STARTWITH$,CGI.CUST_ID$,KNUM,
MAXRECS,COUNT,CURKEY$,INVOICE$,STRUCTURE$,INVLIST$,""
0540 IF CURKEY$>""
THEN
LET CURKEY$=CURKEY$(LEN(CGI.CUST_ID$)+1)
0600 REM ^100 - If there are more records in the file, add a "more records"
0610 REM link URL to continue. curkey$ contains the key to the
0620 REM next record required. By placing this in a STBL, the
0630 REM uthtmout.wbb program that loads the HTML template can
0640 REM conditionally place it after the list.
0650 LET X$=STBL("$MOREURL","");
IF CURKEY$=""
THEN
GOTO 0680
0660 CALL "utencode.wbb",0,CURKEY$,NEXT_STARTWITH$
0670 LET MOREURL$=STBL("$MOREURL",ENV.SCRIPT_NAME$+?pgm=
demoilst.bbx&startwith="+NEXT_STARTWITH$+"&cust_id="+CGI.CUST_ID$)
Both the customer information and the invoice list are substituted into the demoilst.txt file, using specific comments as place markers, with the result sent to the user, and the program exits.
0680 REM ^100 - Load the HTML template, and add the list to it
0690 CALL "uthtmout.wbb",CGI$,"{include demoilst.txt}",HTML$,""
0700 CALL "utsub.wbb",HTML$,"<!-- Customer Info -->",CUSTINFO$
0710 CALL "utsub.wbb",HTML$,"<!-- Invoice Table -->", TABLETOP$+$0A$+INVLIST$+TABLEBOT$
0800 REM ^100 - Send it to the user
0810 CALL "utsend.wbb",HTML$
1000 DONE:
REM ^1000 - Clean up and exit
1010 CALL "utexit.wbb",CGI$
1020 IF RETURN_TO_WATCH
THEN
RUN "utwatch.wbb"
1030 RELEASE
2000 ERRTRAP:
REM ^1000 - generic error trap
2010 CALL "uterr.wbb",ERR,TCB(5),PGM(-2)
2020 GOTO DONE
This program generates a customer maintenance form. By default, the form contains no customer data and can be used to create a new customer record. However, if the CGI field cust_id is filled in with a valid customer number, that customer record can be edited and updated.
Unlike the prior examples, an HTML document template is not used. Instead, the HTML text is created in the program.
0001 SETERR ERRTRAP
0010 REM "democent.bbx - Basic Web Utility demo customer entry form
0020 REM "Copyright 1996 by Allen Miglore. All rights reserved.
0030 REM "Permission to derive programs from this is hereby granted,
0040 REM "provided said programs utilize licensed copies of the Basic Web Utility.
0100 REM ^100 - Get customer record
If the CGI field, cust_id contains a valid customer number, and the customer record is loaded into the data template CUST$. Otherwise, the template is initialized from the startup program.
0110 LET CUSTCHAN=UNT;
OPEN (CUSTCHAN)"GENSMPL1"
0120 READ RECORD(CUSTCHAN, KEY=FIELD(CGI$,"cust_id",ERR=0200), ERR=0200)CUST$
An entry form is generated from the CUST$ data template. The cust_id field is hidden and cannot be edited, though it is passed to the democupd.bbx program. Fields indicated with a show option are display-only. The program utfrmgn2.wbb constructs the complete form, including Submit, Reset buttons, and a form tag to start the demobbw.sh script into the variable CUSTFORM$. The non-template field pgm is specified as a hidden field. As in URL links, this must be specified for the startup program to run the correct program. The democupd.bbx program is used to update the customer file from the contents of the form.
0200 REM ^100 - create entry form, with update link to democupd.bbx
0210 LET FLDS$=FLDS$+"cust_id hidden, name, addr1, addr2, city, state,zip, phone, slsp, date_last_sale show, date_last_pmt show, credit_limit show, mtd_sales show, ytd_sales show, <input type=hidden name=pgm value=democupd.bbx>"
0220 CALL "utfrmgn2.wbb",CUST$,FLDS$, "", "table border", "", ENV.SCRIPT_NAME$,"Update record", "Reset form", 0, CUSTFORM$
Multiple calls to uttags.wbb build the HTML$ document body. Body tags are added, a header is generated, and the complete document is generated into DOCUMENT$. The result is sent to the user, and the program exits. In addition, it is necessary to shuffle HTML$ values with a temporary variable to add surrounding tags, such as <center> and </center> and not double up the text in HTML$ because uttags.wbb always appends to the last argument.
0300 REM ^100 - Use uttags.wbb to generate the rest of the document
0310 CALL "uttags.wbb","h1","Customer Entry Form",HTML$
0320 CALL "uttags.wbb","hr","Enter new customer information, or use the Customer List link",HTML$
0330 CALL "uttags.wbb","","to select a customer record to edit.",HTML$
0340 CALL "uttags.wbb","p,href " + ENV.SCRIPT_NAME$ + "?pgm=democlst.bbx&linkto=democent.bbx", "Customer List", HTML$
0350 CALL "uttags.wbb",""," - ",HTML$
0360 CALL "uttags.wbb","href "+ENV.SCRIPT_NAME$,"Return to the Menu", HTML$
0370 REM "msg$ can be sent from democupd.bbx if there is an error
0380 IF MSG$>"" THEN CALL "uttags.wbb","h3",MSG$,HTML$
0390 LET WORK$=HTML$,HTML$="";
CALL "uttags.wbb","center",WORK$,HTML$
0400 CALL "uttags.wbb","hr",CUSTFORM$,HTML$
0410 CALL "uttags.wbb","body bgcolor=#E8E8E8",HTML$,BODY$
0420 CALL "uttags.wbb","head,title","Basic Web Utility Demo Customer Entry Form",HEADING$
0430 CALL "uttags.wbb","html",HEADING$+BODY$,DOCUMENT$
0500 REM ^100 - Send it to the user
0510 CALL "utsend.wbb",DOCUMENT$
1000 DONE:
REM ^1000 - Clean up and exit
1010 CALL "utexit.wbb",CGI$
1020 IF RETURN_TO_WATCH
THEN
RUN "utwatch.wbb"
1030 RELEASE
2000 ERRTRAP:
REM ^1000 - generic error trap
2010 CALL "uterr.wbb",ERR,TCB(5),PGM(-2)
2020 GOTO DONE
This program is launched from the Customer Maintenance form. It reads the CGI input stream for form values and adds or updates the customer record accordingly.
0001 SETERR ERRTRAP
0010 REM "democupd.bbx - Basic Web Utility demo customer update from entry form
0020 REM "Copyright 1996 by Allen Miglore. All rights reserved.
0030 REM "Permission to derive programs from this is hereby granted,
0040 REM "provided said programs utilize licensed copies of the Basic Web Utility.
0100 REM ^100 - Open customer file
0110 LET CUSTCHAN=UNT;
OPEN (CUSTCHAN)"GENSMPL1"
For a new customer entry, the CGI value cust_id contains blanks, and the program jumps to the new customer entry label. An existing customer, selected from the customer list, will have a hidden value on the form that contains the ID, and the current record is read into CUST$.
0200 REM ^100 - Get current record
0210 EXTRACT RECORD(CUSTCHAN,KEY=CGI.CUST_ID$,DOM=NEW_CUSTOMER)CUST$
On an existing record, the contents of the form are updated into the contents of the CUST$ record using the utfrmin.wbb program. The record is then updated, and the program continues.
Concurrency issues are not addressed in the sample programs because the task that loaded the maintenance form cannot retain a lock on the record. There are several methods for managing records that cannot be locked during maintenance. One method is to store a CRC value as a hidden field on the form, calculated from the record used to generate the form. When the current record is loaded in the update program, the CRC values can be compared to determine if a change was made to the record after the form was displayed, and appropriate action can be taken.
0300 REM ^100 - Fill in form data
0310 CALL "utfrmin.wbb",CGI$,CUST$
0400 REM ^100 - Update record
0410 WRITE RECORD(CUSTCHAN)CUST$
When the customer is updated or added, a message is stored in MSG$, indicating success. The customer entry program is run, which builds a new form for the customer, showing their changes, and also displays the MSG$ value so the user can see that the last update was successful.
0500 CONTINUE:
REM ^100 - redisplay form to show updated data
0510 LET MSG$="Updated "+CVS(CUST.NAME$,3)+" ("+CUST.CUST_ID$+")."
0520 DIM CUST$:FATTR(CUST$)
0530 RUN "democent.bbx"
When the CGI value cust_id does not contain a valid customer number, a new customer is added. The CUST$ data template is filled in from the form CGI data by calling utfrmin.wbb. The customer ID is generated by adding 1 to the last key in the file and formatting a new 5-digit key. Once successful, the program continues.
0600 NEW_CUSTOMER:
REM ^100 - Get new customer ID by adding 1 to highest current ID
0610 CALL "utfrmin.wbb",CGI$,CUST$
0620 LET LASTKEY$=KEYL(CUSTCHAN,KNUM=0)
0630 LET CUST.CUST_ID$=STR(NUM(LASTKEY$)+1:FILL(LEN(CUST.CUST_ID$),"0"))
0640 WRITE RECORD(CUSTCHAN,DOM=NEW_CUSTOMER)CUST$
0650 GOTO CONTINUE
Although a normal exit from this program runs utcent.bbx, the error routine may need to exit this way.
1000 DONE:
REM ^1000 - Clean up and exit
1010 CALL "utexit.wbb",CGI$
1020 IF RETURN_TO_WATCH
THEN
RUN "utwatch.wbb"
1030 RELEASE
2000 ERRTRAP:
REM ^1000 - generic error trap
2010 CALL "uterr.wbb",ERR,TCB(5),PGM(-2)
2020 GOTO DONE