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

Here are some code excerpts from an EGL program that accesses message queues. The program carries out the following tasks:
  1. Requests input from a terminal using a form.
  2. Reads the response.
  3. Updates a serial record with information based on the user input.
  4. Outputs the serial record to another transaction for later batch processing.
The program assumes the following associations in your IMS environment:
  • 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
When you generate, you must specify a resource association part that associates the serial file with a message queue and that provides the name of the transaction to which it is to be sent, along with the name of the PCB to use. Consider the following example, which also includes an association element that makes possible the input of the message-queue data by a batch program, as described later:
<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.

The program can use the same serial record that addtrans used, but with a new file name because a different PCB name is required. Key changes show in bold in the example below:
//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

When you write an EGL program, you only need to consider the processing that must occur for a single user at a single terminal. EGL generates control logic into the program to handle the complex situation on IMS when you have multiple users in contention for the resources. Assume USER1 and USER2 both enter MYTRXCD1 on their terminals at the same time. Assume that USER1's transaction code ends up first on the message queue associated with MYTRXCD1.
  1. 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).
  2. 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.
  3. 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
  4. 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.
  5. 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
  6. 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.
  7. 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.
  8. 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.

Feedback