Previous | Contents | Index |
As with the Review Car Rates task, the block step in the Review Reservation task uses DECforms to interface with the terminal user. Therefore, you need to assign the FORM I/O attribute to the block.
Although the Review Reservation task has just one processing step, that step can be repeated many times. You need to consider whether or not the task needs to have the same server process each time it runs that processing step; you decide to retain or release server context.
Suppose the REVIEW_RESERVATION_PROC procedure reads the first five records, and the form displays those records. For the user to look at the next five records, REVIEW_RESERVATION_PROC must keep a pointer in the file to keep track of which record was last read. You need some way to save this pointer so that the procedure can use it if the user wants to see more records.
You can choose one of two ways to retain pointers between steps in a task:
To retain pointers in a workspace, the procedure must write those pointers to the workspace. Pointers are part of the context associated with a server process. Therefore, if you retain server context, you retain the file pointers and do not have to write those pointers to a workspace. However, in a task such as Review Reservation, retaining server context means retaining a process until the user looks at all the records the user wants to see.
The least expensive choice in terms of system resources is to write the file pointer to a workspace rather than retain server context. In the Review Reservation task, the procedure writes this file pointer to the WK_SAVE_NUMBER field of CO_RESERVE_WKSP and releases server context. Compaq ACMS for OpenVMS Concepts and Design Guidelines explains server context in more detail.
In addition to considering the general characteristics of the block step, consider the actions you want to take as a result of the work done in that block. Suppose that you want to take the same actions as those defined in the action part of the block step for the Review Car Rates task: repeat the task unless the user presses the PF4 key in the final exchange step. You use the REPEAT TASK clause in the action part of the block step definition.
. . . END BLOCK WORK; ACTION REPEAT TASK; |
Finally, use the WORKSPACE clause to name the workspaces that you define (CO_RESERVE_WKSP, QUIT_CTRL_WKSP, and MSG_WKSP) for the Review Reservation task. Example 2-7 shows the complete definition for the Review Reservation task.
Example 2-7 Complete Definition of Review Reservation Task |
---|
REPLACE TASK REVIEW_RESERVATION_TASK /LIST=RVRSV.LIS WORKSPACES ARE CO_RESERVE_WKSP, QUIT_CTRL_WKSP, MSG_WKSP; BLOCK WORK WITH FORM I/O GET_COMPANY_ID: EXCHANGE TRANSCEIVE FROM RECORD CO_RESERVE_FORM_REC, CO_RESERVE_FORM_REC_LIS SENDING CO_RESERVE_WKSP RECEIVING CO_RESERVE_WKSP, QUIT_CTRL_WKSP; ACTION IS CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY "QUIT" : EXIT TASK; END CONTROL FIELD; GET_FIVE_RESERVATIONS: PROCESSING CALL REVIEW_RESERVATION_PROC IN RESERVATION_SERVER USING CO_RESERVE_WKSP; ACTION IS IF (ACMS$STATUS_TYPE EQ "B") THEN GET ERROR MESSAGE; MOVE ACMS$T_STATUS_MESSAGE TO MSG_WKSP.MESSAGE_PANEL; GOTO NEXT EXCHANGE; ELSE GOTO STEP DISPLAY_RESERVATIONS; END IF; DISPLAY_ERROR: EXCHANGE TRANSCEIVE FORM RECORD MSG_FORM_REC, QUIT_CTRL_FORM_REC SENDING MSG_WKSP RECEIVING QUIT_CTRL_WKSP; ACTION IF (QUIT_CTRL_WKSP.QUIT_KEY EQ "QUIT") THEN EXIT TASK; ELSE GOTO STEP GET_COMPANY_ID; END IF; DISPLAY_RESERVATION: EXCHANGE TRANSCEIVE FORM RECORD CO_RESERVE_FORM_REC, QUIT_CTRL_FORM_REC SENDING CO_RESERVE_WKSP RECEIVING QUIT_CTRL_WKSP; ACTION IS CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY "QUIT" : EXIT TASK; "MORE" : GOTO PREVIOUS PROCESSING; END CONTROL FIELD; END BLOCK WORK; ACTION REPEAT TASK; END DEFINITION; |
This section presents an update task, the Review Update task, that lets the terminal user review an existing reservation record and change information in the record. Table 2-4 describes the steps of an update task.
Step | Type |
---|---|
Display a panel to get information | Exchange step |
Read information from a file | Processing step |
Display an error message, if necessary | Exchange step |
Display a panel with information | Exchange step |
Update file and display message, if necessary | Nested Block step |
The steps of an update task apply to the Review Update task in the following manner:
To get information from the terminal user, you display a panel. Here is the first exchange step of the Review Update task:
GET_CUSTOMER_NAME: EXCHANGE TRANSCEIVE FORM RECORD RESERVE_FORM_REC, RESERVE_FORM_REC_LIS SENDING RESERVE_WKSP RECEIVING RESERVE_WKSP, QUIT_CTRL_WKSP; ACTION CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY "QUIT" : EXIT TASK; END CONTROL FIELD; |
This step is very similar to the first step in the inquiry task, Review Reservation. Both steps do the following:
As a result, the record definition for the workspace that you use to pass reservation data between the application and the form is very similar to the one in the Review Reservation task. Example 2-8 shows the record description of RESERVE_WKSP.
Example 2-8 Definition for RESERVE_WKSP Workspace |
---|
Definition of record RESERVE_WKSP | Contains field CUST_NAME | | Datatype text size is 30 characters | Contains field CUST_STREET_ADDRESS | | Datatype text size is 30 characters | Contains field CUST_CITY | | Datatype text size is 20 characters | Contains field CUST_STATE | | Datatype text size is 2 characters | Contains field CUST_ZIP | | Datatype text size is 5 characters | Contains field CUST_PHONE | | Datatype text size is 10 characters | Contains field CAR_TYPE | | Datatype text size is 3 characters | Contains field RENTAL_DATE | | Datatype text size is 6 characters | Contains field RETURN_DATE | | Datatype text size is 6 characters |
As shown in the data entry and inquiry tasks, reading from or writing to a file requires a processing step. Here is the processing step for the Review Update task:
FIND_RESERVATION: PROCESSING CALL FIND_RESERVE_PROC IN RESERVE_SERVER USING RESERVE_WKSP; ACTION IF (ACMS$T_STATUS_TYPE EQ "B") THEN GET ERROR MESSAGE; MOVE ACMS$T_STATUS_MESSAGE TO MSG_WKSP.MESSAGE_PANEL; GOTO NEXT EXCHANGE; ELSE GOTO STEP DISPLAY_RESERVATION; END IF; |
When you update information, it is important that the contents of a record do not change from the time those contents are displayed to the user for update until the time you write the changed record back to the file. This is especially important in a multiuser application in which another user might update the record while it is being displayed on the terminal screen for the first user.
One way of ensuring the integrity of the record you are updating is to have the procedure lock the record and then retain server context between processing steps. However, it is much more efficient to release server context between processing steps. When you update a record, to ensure the integrity of the record without locking the record and retaining server context, you need to check whether the record was updated by someone else before writing the first user's changes to the file. See Compaq ACMS for OpenVMS Writing Server Procedures for further discussion on releasing server context.
As in the inquiry and data entry tasks, you must consider errors that can occur when the procedure tries to read from the file. If the reservation record for the customer name provided by the terminal user does not exist or is locked by another user, ACMS stores the value B in the ACMS$T_STATUS_TYPE field of the ACMS$PROCESSING_STATUS workspace. The processing step checks that field and, if the field contains B, retrieves the error message and stores it in the MSG_WKSP workspace. ACMS then passes control to the DISPLAY_ERROR exchange step:
DISPLAY_ERROR: EXCHANGE TRANSCEIVE FORM RECORD MSG_FORM_REC, QUIT_CTRL_FORM_REC SENDING MSG_WKSP RECEIVING QUIT_CTRL_WKSP; ACTION IF (QUIT_CTRL_WKSP.QUIT_KEY EQ "QUIT") THEN EXIT TASK; ELSE GOTO STEP GET_CUSTOMER_NAME; END IF; |
This exchange step sends the error message stored in MSG_WKSP to the
MSG_FORM_REC form record for display to the terminal screen. The action
part of this step tests the QUIT_KEY field of the QUIT_CTRL_WKSP
workspace to see whether or not the terminal user wants to exit from
the task. If the user presses the PF4 key, DECforms returns the value
"QUIT" to the workspace, and ACMS ends the task and returns
the user to the menu. Otherwise, ACMS passes control to the first step
in the task definition.
2.4.3 Letting the User Update the Information
Once a procedure has read information from a file, you can display that information to the terminal user. The user can then supply information, in the form of changes, to be written back to the file. You use an exchange step to call a form record to display information to the user and to accept changes.
Here is the exchange step that displays information for the Review Update task:
DISPLAY_RESERVATION: EXCHANGE TRANSCEIVE FORM RECORD RESERVE_FORM_REC, RESERVE_FORM_REC_LIS SENDING RESERVE_WKSP RECEIVING RESERVE_WKSP, QUIT_CTRL_WKSP SHADOW IS RESERVE_SHADOW_WKSP; ACTION CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY "QUIT" : EXIT TASK; END CONTROL FIELD; |
For an inquiry task, such as Review Reservation, this second exchange step is the final step in the task. However, in an update task, the user can make changes to the information displayed.
The DISPLAY_RESERVATION step uses RESERVE_WKSP to send the information read by the FIND_RESERVE_PROC procedure to the form for display. The step also uses RESERVE_WKSP to store the information that the terminal user returns.
Unlike exchange steps in the data entry and inquiry tasks, this step uses a shadow workspace to determine whether or not the terminal user changed any information in the reservation record. When you declare a shadow workspace, DECforms returns a value to that workspace that indicates whether or not the user changed any data in the record. In this exchange step, RESERVE_SHADOW_WKSP is the shadow workspace for the RESERVE_WKSP workspace.
The record description for RESERVE_SHADOW_WKSP is the same as for RESERVE_WKSP, except that you must add a field to store the value that DECforms returns. Example 2-9 shows the definition.
Example 2-9 Record Description for RESERVE_SHADOW_WKSP Workspace |
---|
Definition of record RESERVE_SHADOW_WKSP | Contains field REC_STATUS | | Datatype text size is 1 character | Contains field CUST_NAME_SHADOW | | Datatype text size is 1 character | Contains field CUST_STREET_ADDRESS_SHADOW | | Datatype text size is 1 character | Contains field CUST_CITY_SHADOW | | Datatype text size is 1 character | Contains field CUST_STATE_SHADOW | | Datatype text size is 1 character | Contains field CUST_ZIP_SHADOW | | Datatype text size is 1 character | Contains field CUST_PHONE_SHADOW | | Datatype text size is 1 character | Contains field CAR_TYPE_SHADOW | | Datatype text size is 1 character | Contains field RENTAL_DATE_SHADOW | | Datatype text size is 1 character | Contains field RETURN_DATE_SHADOW | | Datatype text size is 1 character |
If the terminal user changed any data in RESERVE_WKSP, ACMS stores a 1 in the REC_STATUS field of RESERVE_SHADOW_WKSP when the transceive operation completes. The status field in the shadow workspace must be the first field in your record definition. In your DECforms IFDL code, you must assign the TRACKED attribute to the fields of shadow workspaces. See the DECforms documentation for information on using this attribute.
After the DISPLAY_RESERVATION step ends, you need to check the shadow
workspace to see whether or not the reservation record has changed. If
it has, write the new record to the Reservation file and display a
message on the terminal screen confirming the update.
2.4.4 Writing the New Information to the File
The CHECK_RESERVE_CHANGES step is a nested block step that includes the following parts:
By using a nested block step, you can group processing and exchange steps and have ACMS process them only if a certain condition is met. You introduce a nested block the same way you introduce a block, with the BLOCK WORK keywords. As with other steps, you can assign a label to a nested block and refer to it from elsewhere in the task definition.
A block conditional clause is one of the four ADU conditional clauses (CONTROL FIELD, IF THEN ELSE, SELECT FIRST, or WHILE DO) used at the block step level. You can use it to start an exchange step, a processing step, or another block step. However, you can use a block conditional clause only at the start of a block step. You cannot use it between steps within the block. Here is the definition for the CHECK_RESERVE_CHANGES nested block step:
CHECK_RESERVE_CHANGES: BLOCK WORK IF (RESERVE_SHADOW_WKSP.REC_STATUS EQ "1") THEN PROCESSING CALL WRITE_RESERVE_PROC IN RESERVE_SERVER USING RESERVE_WKSP; ACTION MOVE "RESERVATION RECORD UPDATED" TO MSG_WKSP.MESSAGE_PANEL; EXCHANGE SEND FORM RECORD MSG_FORM_REC SENDING MSG_WKSP; END IF; END BLOCK; |
In the CHECK_RESERVE_CHANGES step, an IF THEN ELSE block conditional clause tests the shadow workspace. If the REC_STATUS field equals 1, ACMS processes the processing and exchange steps that follow the THEN keyword. The processing step calls the WRITE_RESERVE_PROC procedure, which writes the new reservation record to the Reservation file.
The action part of the processing step moves the message "RESERVATION RECORD UPDATED" to the MSG_WKSP workspace, and the exchange step then sends that message to DECforms for display.
If the shadow record indicates that the terminal user did not change
any data in the reservation record, ACMS does not perform the
processing and exchange steps in the CHECK_RESERVE_CHANGES block step.
Note that you do not need to include the ELSE keyword in the IF THEN
ELSE clause. ACMS passes control to the clause following the END IF
keywords. Be sure to end the nested block with the END BLOCK keywords.
2.4.5 Completing the Task Definition
The Review Update task uses DECforms to interface with the terminal; therefore, you need to assign the FORM I/O attribute to the block. Nested blocks inherit the attributes that you assign to their parent blocks; so, you do not need to include the FORM I/O keywords with the CHECK_RESERVE_CHANGES step.
Because you want to repeat this task automatically rather than make the terminal user choose the task again from the menu, include the REPEAT TASK clause in the action part of the parent block.
Finally, you must name the workspaces used by the steps in the task. In the Review Update task these are RESERVE_WKSP, RESERVE_SHADOW_WKSP, QUIT_CTRL_WKSP, and MSG_WKSP. Declare these workspaces using the WORKSPACES ARE clause in the task definition.
WORKSPACES ARE RESERVE_WKSP, RESERVE_SHADOW_WKSP, QUIT_CTRL_WKSP, MSG_WKSP; |
Example 2-10 shows the complete definition for the Review Update task.
Example 2-10 Complete Definition of Review Update Task |
---|
REPLACE TASK REVIEW_UPDATE_TASK /LIST=RVSCHED.LIS WORKSPACES ARE RESERVE_WKSP, QUIT_CTRL_WKSP, MSG_WKSP, RESERVE_SHADOW_WKSP; BLOCK WORK WITH FORM I/O GET_CUSTOMER_NAME: EXCHANGE TRANSCEIVE FORM RECORD RESERVE_FORM_REC, RESERVE_FORM_REC_LIS SENDING RESERVE_WKSP RECEIVING RESERVE_WKSP, QUIT_CTRL_WKSP; ACTION CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY "QUIT" : EXIT TASK; END CONTROL FIELD; FIND_RESERVATION: PROCESSING CALL FIND_RESERVE_PROC IN RESERVE_SERVER USING RESERVE_WKSP; ACTION IF (ACMS$T_STATUS_TYPE EQ "B") THEN GET ERROR MESSAGE; MOVE ACMS$T_STATUS_MESSAGE TO MSG_WKSP.MESSAGE_PANEL; GOTO NEXT EXCHANGE; ELSE GOTO STEP DISPLAY_RESERVATION; END IF; DISPLAY_ERROR: EXCHANGE TRANSCEIVE FORM RECORD MSG_FORM_REC, QUIT_CTRL_FORM_REC SENDING MSG_WKSP RECEIVING QUIT_CTRL_WKSP; ACTION IF (QUIT_CTRL_WKSP.QUIT_KEY EQ "QUIT") THEN EXIT TASK; ELSE GOTO STEP GET_CUSTOMER_NAME; END IF; DISPLAY_RESERVATION: EXCHANGE TRANSCEIVE FORM RECORD RESERVE_FORM_REC, RESERVE_FORM_REC_LIS SENDING RESERVE_WKSP RECEIVING RESERVE_WKSP, QUIT_CTRL_WKSP SHADOW IS RESERVE_SHADOW_WKSP; ACTION CONTROL FIELD IS QUIT_CTRL_WKSP.QUIT_KEY "QUIT" : EXIT TASK; END CONTROL FIELD; CHECK_RESERVE_CHANGES: BLOCK WORK IF (RESERVE_SHADOW_WKSP.REC_STATUS EQ "1") THEN PROCESSING CALL WRITE_RESERVE_PROC IN RESERVE_SERVER USING RESERVE_WKSP; ACTION MOVE "RESERVATION RECORD UPDATED" TO MSG_WKSP.MESSAGE_PANEL; EXCHANGE SEND FORM RECORD MSG_FORM_REC SENDING MSG_WKSP; END IF; END BLOCK; END BLOCK; ACTION REPEAT TASK; END DEFINITION; |
Previous | Next | Contents | Index |