Some applications need to use data not stored in tableBASE tables—perhaps the data is stored in a VSAM file or a database. Conversion exits operating at either table or row level can support editing non-table data with tablesONLINE/CICS. This can be done with either table-level or row-level exits.
At the table level, you can write a TOB exit to load the data into a tableBASE table and a TSB exit to move it back. Both should set the BYPASS indicator to Y to indicate that they have taken care of the action themselves and tablesONLINE/CICS should bypass it. A TCB or TCA exit may not be needed, since tablesONLINE/CICS can delete a table from memory without the assistance of an exit program. One of these exits might be used for housekeeping functions, as is done in the example on the next few pages.
Performing the same function at the item (row) level is more difficult, since there are more cases to be handled—new row, update, delete, move — and some cases may not map well onto the external data representation. It will also typically involve higher overheads, since every operation requires access to the external data. It is possible and might be necessary if, for example, there were other applications using the data and having tablesONLINE/CICS working on a private copy was not acceptable. Again, all the exit programs should be invoked before the action and should set the BYPASS indicator.
Interfacing to other processes as well as to external data is also possible through exit programs. You might, for example, have a TSA exit append the name of the stored table to a list which some batch backup process would use.
Process interfacing often involves constructing a transaction table to record changes on the main Data Table. Consider an application where, when an employee is added to the employee table, one or more messages need to be sent (for example, notes to his or her supervisor, to the systems person who will need to set up an account for him or her, and to the editor of the company newsletter). An incorrect method of implementing this would be to have an INA exit send the messages, because this can result in the messages being sent at the wrong time. If a user creates a row in the in-memory copy of the table, then exits with the <PF12> key so that the table is not stored to disk, it is too late to call back a message already sent.
One way to code this is with a TOA exit that creates a dynamic table for messaging information, an INA exit that adds a row to that table whenever a new row is added to the employee table, a TSA exit that sends messages and clears the associated rows from the dynamic table after the employee table has been stored, and a TCA exit that closes the dynamic table when the employee table is closed. The dynamic table records transactions against the employee table, and its records drive the messaging application.
*
* TEST FOR SPECIFIC TABLES
*
IF T-TBLX-TABLE = 'table1 '
GO TO table1-CONTROLLER.
IF T-TBLX-TABLE = 'table2 '
GO TO table2-CONTROLLER.
*
* ERROR IN CALLING EXIT PROGRAM - INVALID TABLE
*
MOVE your key TO T-MSGX-KEY.
MOVE 8 TO T-MSGX-INSERT1-LENGTH.
MOVE T-TBLX-TABLE TO T-MSGX-INSERT1-VALUE.
MOVE ZERO TO T-MSGX-INSERT2-LENGTH.
GO TO Y100-NORMAL-EXIT.
*
******************************************************************
This code either branches to a label associated with a particular table or, if called for an unrecognized table name, sets up a message and branches to the exit routine that will handle the message and return control to tablesONLINE/CICS.
The NORMAL-EXIT routine will search the message table (normally TBOLMSGS, but this name may be tailored via the TBOLACT entries for the application) using the key stored at T-MSGX-KEY. A successful search will give it message TEXT, OFFSET information, and a single-character message TYPE, that in this case should be E. It then builds the actual message by inserting INSERT-VALUE text into the retrieved message TEXT according to the OFFSET and INSERT-LENGTH information it has, puts the results on a queue, and puts message TYPE into BYPASS-ACTION-IND.
On regaining control, tablesONLINE/CICS sees a BYPASS-ACTION-IND of E which causes it to treat the action as failed and return to the same screen. It also finds the message on the queue and delivers it.
This branching structure can accommodate any number of table names, and can either give each table its own label and code or send several branches to the same destination if several tables need similar handling.
*
table-CONTROLLER.
*
IF T-TBLX-EXIT-INDICATORS = 'TOB'
GO TO TOB-CREATE-DYNAMIC-TABLE
ELSE
IF T-TBLX-EXIT-INDICATORS = 'TSB'
GO TO TSB-SUBMIT-JOB
ELSE
IF T-TBLX-EXIT-INDICATORS = 'TCA'
GO TO TCA-DELETE-WORK-TABLES
ELSE
GO TO Y200-INVALID-CALL.
*
This code tests the three indicator bytes looking for valid combinations. The cases it handles are listed in Table 84.
Indicators |
Called at level |
Operation |
Timing |
---|---|---|---|
TOB |
Table |
Open |
Before |
TSB |
Table |
Store |
Before |
TCA |
Table |
Close |
After |
*
TOB-CREATE-DYNAMIC-TABLE.
user code to create a table in memory and fetch non-table data
on success, set BYPASS-IND to 'Y'
on failure, set BYPASS-IND to 'E' and set up message
GO TO Y100-NORMAL-EXIT.
TSB-SUBMIT-JOB.
user code to store table data to external medium
(and/or submit a job based on it)
on success, set BYPASS-IND to 'Y'
on failure, set BYPASS-IND to 'E' and set up message
GO TO Y100-NORMAL-EXIT.
TCA-DELETE-WORK-TABLES.
user code for housekeeping functions
tablesONLINE has already closed the in-memory table
GO TO Y100-NORMAL-EXIT.
*
The three labels have the code beneath them to do the actual work of this exit program.