+ All Categories
Home > Documents > EGL and IMS Support

EGL and IMS Support

Date post: 31-Dec-2015
Category:
Upload: mansour-jalil
View: 38 times
Download: 1 times
Share this document with a friend
Description:
EGL and IMS Support. A short, high-level introduction to the language and tooling features For more information, please contact Jon Sayles: [email protected]. From 10,000 Feet. Support for: IMS TM Formatted and un-formatted 3270 screens Alternate IO-PCB IMS BMP - PowerPoint PPT Presentation
18
® IBM Software Group © 2006 IBM Corporation EGL and IMS Support A short, high-level introduction to the language and tooling features For more information, please contact Jon Sayles: [email protected]
Transcript

®

IBM Software Group

© 2006 IBM Corporation

EGL and IMS Support

A short, high-level introduction to the language and tooling features

For more information, please contact Jon Sayles: [email protected]

2Last update: 12/04/2007

From 10,000 Feet

Support for: IMS TM

Formatted and un-formatted 3270 screens Alternate IO-PCB

IMS BMP zOS – IMS Batch (DL/I programs) DL/I Database

All databases and access methods supported HDAM/HIDAM Secondary Index Logical Relationships GSAM

Complete DL/I language support Different levels of abstraction – use of consistent vocabulary Ability to support custom/complex requirements through #dli{

Special records that provide abstracted and simplified coding – AND learning IMS

3Last update: 12/04/2007

EGL - IMS Run-Time Architecture

zSeries – IMS/VS – DB2zSeries – IMS/VS – DB2

EGLCOBOLGEN

Program

EGLCatcherProgram

MSG Queue

DL/IDL/IDatabaseDatabase

WAS - AIXWAS - AIX

Web ServicesWeb Services

4Last update: 12/04/2007

From 10,000 Feet – Development Architecture

Support for: TUI/MFS Interface – tooling and form editors available to produce Pagehandlers – generated to Java Services – generated to Java IMS Programs – generated to COBOL

Buildfile entries for lots of things Build Server – COBUCL

Call: ELAISVN EGL “catcher program” that is called by IMS Connect Transaction:

ELAISVN Is defined to AIB – with aliases for all user program PSB Scans the iopcb message queue for requests for said PSBs Gets scheduled Handles data mapping and Linkage Parms:

– Unformatted 3270 data streams (IMS Message data, passed to your called program)

Invokes custom IMS/VS programs (your generated EGL code – or Native COBOL !) Handles passing returned data/parms to caller client programs

– Pages/Services/MFS

5Last update: 12/04/2007

Record subtypes are used to associate meta data with a data type definition

Record CustomerRecordPart type DLISegment

{ segmentName="STSCCST", keyItem="customerNo" } 10 customerNo char(6) { dliFieldName = "STQCCNO" }; //key

10 customerName char(25) { dliFieldName = "STUCCNM" };

10 customerAddr1 char(25){ dliFieldName = "STQCCA1" };

10 customerAddr2 char(25){ dliFieldName = "STQCCA2" };

10 customerAddr3 char(25){ dliFieldName = "STQCCA3" };

end

You define records to match segments in DL/I database

The above record provides developers with the following kinds of coding/productivity constructs:Move in_cust_no to customerNo;

Get CustomerRecord;

DLISegment Record

6Last update: 12/04/2007

EGL provides predefined records for the I/O PCB, alternate PCB, database PCB, and GSAM PCB structures.

Record CustomerPSB type PSBRecord { defaultPSBName="STBICLG" }

// three PCBs required for CBLTDLI on IMS

{ @PCB { pcbType = TP } };

elaalt ALT_PCBRecord { @PCB { pcbType = TP } };

elaexp ALT_PCBRecord { @PCB { pcbType = TP } };

// database PCB defining four segment levels

customerPCB DB_PCBRecord

{ @PCB { pcbType = DB, pcbName = "STDCDBL", hierarchy = [

@Relationship

{ segmentRecord = "CustomerRecordPart" },

@Relationship

{ segmentRecord = "LocationRecordPart", parentRecord = "CustomerRecordPart" },

@Relationship

{ segmentRecord = "OrderRecordPart", parentRecord = "LocationRecordPart" },

@Relationship

{ segmentRecord = "ItemRecordPart", parentRecord = "OrderRecordPart" },

@Relationship

{ segmentRecord = "CreditRecordPart", parentRecord = "CustomerRecordPart" },

@Relationship

{ segmentRecord = "HistoryRecordPart", parentRecord = "CustomerRecordPart" }

]}};

PSBRecord

7Last update: 12/04/2007

EGL provides different layers of abstraction for your DL/I programming

Function FLSCOMP_MAIN()

// 1. Implicit DL/I -- retrieves the segment based on the key and DLISegent properties

get STORESEG;

// 2. Explicit DL/I -- with specific SSA for just the root segment – over-rides DLISegment

// use : to indicate a host variable (not a DLI term), but like SQL

get STORESEG usingPCB psb.STORE_dbPCB

with #dli{GU STORESEG(STORE# = :inputStore & COMPFLAG = "Y") } ;

//3. Custom DL/I -- multiple segments and the D (path call) command code

get COURSE, STUDENT usingPCB psb.COURSE_dbPCB get COURSE, STUDENT usingPCB psb.COURSE_dbPCB

with #dli{ GUwith #dli{ GU

COURSE*D (COURSE# = :COURSE.COURSE#) COURSE*D (COURSE# = :COURSE.COURSE#)

OFFERING (LOCATION = :OFFERING.LOCATIONOFFERING (LOCATION = :OFFERING.LOCATION

& CITY = :MYDBPRG_WS.MYCITY) & CITY = :MYDBPRG_WS.MYCITY)

STUDENT (EMPNO = :STUDENT.EMPNO)STUDENT (EMPNO = :STUDENT.EMPNO)

} ;} ;

Note for the above 3 types of IMS db access EGL parses the IMS calls, ensuring that all operands are space-filled to the appropriate length, upper-case, etc.

You can also code native DL/I using DLILIB (system function library)

DL/I Data Access Calls

8Last update: 12/04/2007

DL/I Implicit and Explicit Calls

Calls generated from: 1. DLISegment record, 2. Your coding

Function FLSCOMP_MAIN()

// 1. Implicit DL/I -- retrieves the segment based on the key and DLISegent properties

CustRec CustomerRecordPart;

customerNo = inputCustNo; //Value obtained from Service or web page

get CustRec;

// 2. Explicit DL/I - over-rides DLISegment

get CustRec usingPCB psb.STORE_dbPCB

with #dli{

GU CustRec

(customerName >= :inputName &

customerAddr3 = :addr1) } ;

9Last update: 12/04/2007

Lets you modify the default DL/I calls that EGL generates from I/O keywords.

get myLocation with #dli{ GU STSCCST (STQCCNO = :myCustomer.customerNo) STSCLOC (STQCLNO = :myLocation.locationNo)

};

Can use this directive when:

- Need to add DL/I command code

- Retrieve a segment not based on key-field value

- Doing “skip sequential” processing

#dli directive

10Last update: 12/04/2007

DLILib.AIBTDLI() uses the AIBTDLI interface to invoke a DL/I function directly.

DLILib.AIBTDLI()( func CHAR(4) in, pcbName STRING in parms... ANY)

Example:

Record CustomerPSBRecordPart type PSBRecord { defaultPSBName="STBICLG" } // database PCB customerPCB DB_PCBRecord { @PCB { pcbType = DB, pcbName = "STDCDBL", hierarchy = [ @Relationship { segmentRecord = "CustomerRecordPart" }, ...]}}; end

mypsb CustomerPSBRecordPart; //variable definition of PSB

Define I/O area…define and format your SSAs. Issue the DL/I FLD call as follows:

DLILib.AIBTDLI("FLD", "STDCDBL", myIOArea, mySSA1, ... mySSAn); DLILib.AIBTDLI("FLD", "STDCDBL", myIOArea, mySSA1, ... mySSAn);

if (CustomerRec not handleIOError) // do error processing end

DLILIB – Option for customized DL/I Calls

11Last update: 12/04/2007

DL/I Program - Properties

Program FLSCOMPFLSCOMP type basicProgram (inputStore bigint, outputCompFlag char(1), outputDate char(8)) { // whatever other properties you generally use @DLI { psb = "psb", // name of variable that defines the psbRecord

callInterface = DLICallInterfaceKind.AIBTDLI //, this is the default;

// be sure IMS PSB is set up for AIBTDLI // if not, can specify separate CBLTDLI pcbs

//// You can pass the entire psb on a call into this program// psbParm = "psbData"//// Or, you pass individual pcbs on a call into this program// pcbParms = ["iopcb", "ELAALT", "", "STORE_dbPCB", "", ""] } }

12Last update: 12/04/2007

DL/I Error Handling

Can “roll your own” – or leverage built-in coding standards:

if (myRec is noRecordFound)

13Last update: 12/04/2007

Examples – Searching within a parent segment

Retrieve the items for a particular order. You can use the following to retrieve the order:

get myOrder with #dli {

GU STSCCST (STQCCNO = :myCustomer.customerNo)

STSCLOC (STQCLNO = :myLocation.locationNo)

STSOCORD (STQCODN = :myOrder.orderDateno) };

Use the following to retrieve the line segments within the order:

get next inParent myItem;

while (myItem not noRecordFound)

// process the current item get next

14Last update: 12/04/2007

Examples – Searching with a non-key field

Search on the creditBalance field (STFCSBL) in the credit segment (STSCSTA). 1. Define a variable of type decimal(12,2) (for example, ″targetBalance″)

2. Write a get next statement for the myCrStatus record.

3. Add a #dli directive to the line, modifying the default code.

4. Add a qualified SSA that looks for a segment where the amount in the creditBalance field is greater than targetBalance.

5. Include a path command code (*D) to retrieve the customer segment (STSCCST) that corresponds to the credit segment.

TargetBalance decimal(12,2);

targetBalance = 10,000.00; //or any input variable value

get next myCustomer,myCrStatus with #dli{

GU STSCCST*D STSCSTA (STFCSBL >= :targetBalance) };

15Last update: 12/04/2007

Examples – Path calls and implicit SSAs

EGL I/O statement with dependent segments

get myCustomer, myLocation, myOrder; get myCustomer, myLocation, myOrder; //Path get//This statement generatesgenerates the following DL/I pseudocode:

GU STSCCST*D (STQCCNO = :myCustomer.customerNo) STSCLOC*D (STQCLNO = :myLocation.locationNo) STPCORD (STQCDDN = :myOrder.orderDateNo)

Note that if you use the D command code on a get...forUpdate statement, the subsequent replace statement affects every segment retrieved. You can prevent replacement of a selected segment by specifying an explicit N command code in the SSA for the replace keyword, as in the following example, which replaces only the location and order segments:

get myCustomer, myLocation, myOrder forUpdate; get myCustomer, myLocation, myOrder forUpdate; //Path get

replace myOrder with #dli{ replace myOrder with #dli{

REPL REPL STSCCST*N STSCCST*N

STSCLOC*N STSCLOC*N

STPCORD }; STPCORD };

16Last update: 12/04/2007

Examples – Read all database segments

EGL I/O statement with dependent segmentsmyHistory HistoryRecord;

redefCustomer CustomerRecord {redefines=myHistory};

redefLocation LocationRecord {redefines=myHistory};

...

//read next segment, whatever type it is, into history record

while (myHistory not EOF)

get next myHistory with #dli{ GN };

//so what type was it?

case (DLIVar.segmentName)

when "STSCCST"

// it was a customer

when "STSCLOC"

// it was a location

... end

end

17Last update: 12/04/2007

®

IBM Software Group

© 2006 IBM Corporation

Getting Started with EGL


Recommended