Example IMS™ program code
These excerpts from EGL programs show interaction with IMS™ terminals, message queues, and serial files.
Example of output to a serial file associated with a message queue
- Requests input from a terminal using a form.
- Reads the response.
- Updates a serial record with information based on the user input.
- Outputs the serial record to another transaction for later batch processing.
- IMS™ transaction code MYTRXCD1 is associated with a PSB named MYTRXCD1.
- IMS™ transaction code NEXTTRX is associated with a PSB named MYTRXCD2.
//define PSB
Record addToQueue type PSBRecord { defaultPSBName="MYTRXCD1" }
// three PCBs required for CBLTDLI on IMS
iopcb IO_PCBRecord { @PCB { pcbType = TP } };
elaalt ALT_PCBRecord { @PCB { pcbType = TP } };
elaexp ALT_PCBRecord { @PCB { pcbType = TP } };
// other database PCBs
...
end
Record myTransactionPart type serialRecord
{ fileName="MYMSGQUE" }
...
end
program addtrans type textUIProgram
{ alias = "MYTRXCD1", // IMS requires pgm to match PSB name
segmented = yes,
@DLI { psb = "mypsb" }}
use MYFORMS; // MYFORMS is a formGroup containing FORM1
// declare variables
myTransaction myTransactionPart; // serial record for message queue
mypsb addToQueue; // psb
function main()
...
converse FORM1;
// do whatever processing is necessary
move FORM1 to myTransaction byName;
add myTransaction;
...
end
end
<ResourceAssociations name="IMS_RESOURCE_ASSOCIATION">
<association fileName="MYMSGQUE">
<imsvs>
<smsgq systemName="NEXTTRX" pcbName="elaalt"/>
</imsvs>
</association>
<association fileName="MYINQUE">
<imsvs>
<smsgq systemName="NEXTTRX" pcbName="iopcb"/>
</imsvs>
</association>
</ResourceAssociations>Because addtrans is a textUI program, EGL generates control logic to interface to the IMS™ environment. IMS™ programs are expected to read the input message queue until the queue is empty. Therefore, EGL generates logic into the program so that once the program responds to the current user (using a converse or show statement) or transfers the responsibility for responding (using a transfer to transaction statement), the program loops to read the next input message from the queue. For an overview, see Interacting with terminals in IMS; for more information, see "Multiple users and message queues" in this topic.
Example of IMS™ batch processing
You can also create a program to process the messages that program addtrans writes to the message queue. The program must be a basic program that gets records from a serial file and associates the serial file with the I/O PCB.
//define PSB
Record getFromQueue type PSBRecord { defaultPSBName="MYTRXCD2" }
// three PCBs required for CBLTDLI on IMS
iopcb IO_PCBRecord { @PCB { pcbType = TP } }
elaalt ALT_PCBRecord { @PCB { pcbType = TP } };
elaexp ALT_PCBRecord { @PCB { pcbType = TP } };
// other database PCBs
end
program gettrans type basicProgram
{ alias = "MYTRXCD2"
@DLI { psb = "mypsb" }}
// declare variables
myTransaction myTransactionPart // serial record for message queue
{fileName="MYINQUE"};
mypsb getFromQueue; // psb
function main()
while (myTransaction not endOfFile)
get next myTransaction;
// do whatever processing is necessary
end
end
end
When you generate the program for either the IMS/VS or the IMS™ BMP environments, you must also specify a resource association part that associates the serial file with a message queue, as well as the name of the PCB to use. In this case, the I/O PCB is used for input, as shown in the ResourceAssociations part in the previous section. The systemName property is optional. The program reads the message queue associated with the transaction that started the program, based on the IMS™ system definition. EGL sets sysVar.transactionID based on the IMS™ transaction id in the input message.
Mutliple users and message queues
- IMS™ schedules the PSB associated with the transaction code MYTRXCD1. That PSB happens to be named MYTRXCD1 as well, though it does not have to be. The program associated with the PSB, however, must have the same name as the PSB in IMS™. Therefore IMS™ loads the program MYTRXCD1 (known as addtrans to EGL).
- The EGL-generated control logic in program MYTRXCD1 determines that this is the first time the program has been invoked for USER1, so processing begins at the top.
- Eventually the program reaches the converse statement
and performs the following actions:
- Saves the data for all records and forms the program is using
- Saves information about where in the program the converse statement occurred
- Performs the ISRT command with the specified form
- Following the logic that EGL added, the program loops back to the beginning and finds USER2 waiting on the message queue. The program follows the same steps for USER2 that it did for USER1, reaching the converse statement, sending the form, then looping back to check the message queue again.
- Here the program is likely to find USER1's response to the converse statement.
The EGL-generated control logic determines that this response is a
continuation of USER1's processing, and does the following:
- Restores USER1's data (including the location of the converse statement)
- Refreshes a number of system variables
- Runs any validation checks that FORM1 requested
- Assuming no input errors, resumes processing at the statement after the converse statement
- Eventually, the program reaches another converse statement, saves all data, and sends a response to USER1. The program then loops back to check the message queue again.
- Assume that USER2 has gone to lunch and there is nothing left on the message queue associated with the transaction code MYTRXCD1. Program MYTRXCD1 ends.
- Later, if USER1 responds to the most recent console message, IMS™ will once again have a message on the queue associated with transaction code MYTRXCD1 and will start the program MYTRXCD1 again. The EGL-generated control logic determines that this response is a continuation of USER1's processing, restores all data, and continues processing.