module d module b module c module a service program a

41

Upload: jeffery-pruiett

Post on 30-Mar-2015

223 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Module D Module B Module C Module A Service Program A
Page 2: Module D Module B Module C Module A Service Program A

Module D

Module B

Module C

Module A

Service Program A

Page 3: Module D Module B Module C Module A Service Program A

Key Information Regarding Module Creation

Header Specification Most modules are created with the NOMAIN keyword.

Prototype Definition These are placed in the global “D” Specs define how the parameters are expected in the procedure.

Exported procedures Exported procedures are “callable” entry points. Which means that external programs can use the procedure. Non-exported procedures can be used by other procedures in the module but cannot be called by external programs.

Page 4: Module D Module B Module C Module A Service Program A

Creating Modules

To create modules in PDM, use option 15. From the command line, use the CRTxxxMOD commands. A module can consist of a single procedure or many procedures. Generally a module is created in a single source member and procedures that need to access each other or otherwise related should be in the same module. Modules can be accessed by other independent modules by using the IMPORT keyword on the prototype for the procedure calls. I recommend having a single module for interrelated procedures instead of using IMPORT.

Module creation does not allow you to specify activation group attributes like programs. Modules inherit the attributes from the program or service program it is bound to.

Modules do not have to be part of a service program. They can be added to programs individually by using the CRTPGM command or by adding them using the CRTBNDxxx command.

Page 5: Module D Module B Module C Module A Service Program A

Module A

Displayed above is the “Module A” module. As stated previously, this module can be used to create program or service program objects. One or more modules can be created & bound together to form a service program. To use the module for a program, a MAIN module must be created. The difference between a program object and a service program is that with a program there is only one point of entry, with a service program there can be many points of entry. So then “Module A, B, C and D” can be used to create a service program by “binding” them together using the CRTSRVPGM command.

Page 6: Module D Module B Module C Module A Service Program A

BindingBinding can be performed 2 different ways. By specifying them individually on the CRTPGM or CRTSRVPGM command or by using binding directories.

Specifying the modules individually makes the objects harder to maintain, since each time you have to recompile you have to remember to add all the modules on the CRTxxxx commands.

Using binding directories makes the process much less prone to error. The binding directory contains a list of modules or service programs. A binding directory works much like a library list. The compiler looks through the service programs & modules for the defined procedures. To use the binding directory, you can add the BNDDIR keyword to the “H” spec of your program like so:

BNDDIR(‘MYBNDDIR’)

You can also specify the binding directory to use on the CRTBNDxxx command at compile time, however, this brings back the issue of human error to the equation.

Page 7: Module D Module B Module C Module A Service Program A

Creating A Binding Directory

To properly construct a binding directory, you will have to create the directory & add the entries to the directory. Binding directories are created using the CRTBNDDIR command.

After you have created the binding directory, you can add directory entries by using the ADDBNDDIRE command. As mentioned before, you can add individual modules or service programs. I prefer using service programs since they are, in essence, a collection of modules bound together, meaning easier access to your programs & easier maintenance.

Page 8: Module D Module B Module C Module A Service Program A

Service Program Creation

Service Program Name Name desired for service program

Modules Modules to include in the object

Export Type *ALL will export all procedures defined with the EXPORT keyword, or specify a source file & member for export definitions

Bind Service Program Allows you to bind other service programs to the one you are creating

Binding Directory Can be used instead of specifying the service programs & modules to bind in the service program

Activation Group You can specify a named activation group or use *CALLER (preferred)

Page 9: Module D Module B Module C Module A Service Program A

Service Program Creation (cont’d)Modules can be specifically listed or added by using a binding directory.

Export type can be either *ALL, or from a source member of type BND. Using a source member is preferred, since you can specify your own signature for the service program & include only the procedures you need exported from the module. Also using export *ALL will place the procedures in whatever order it wants to. Since the service program uses a numeric ordinal position to determine where a procedure is in the service program, this makes adding exported procedures more difficult since the service program ordinal positions can change. Using export source members, you tell the compiler what order the procedures are defined.

Activation group can be either a named activation group or *CALLER. *CALLER is preferred with service programs, since you don’t know when you create the service program where the service program might be called from. This prevents issues with open data paths trying to span multiple activation groups.

Page 10: Module D Module B Module C Module A Service Program A

Export Binder Source

To create an export binder source, create a source member of type BND. Edit the source member using SEU, EDTF or WDSC. A sample binder source is shown below:

The first line is always STRPGMEXP (start program export list). This is where you define your signature. If no signature is specified, the compiler will generate a generic signature. Generic signatures can cause issues with adding modules, etc. and is not recommended. The EXPORT keyword defines the exported procedures in the service program you are creating. The source is always terminated by the ENDPGMEXP (end program export list) keyword.

Page 11: Module D Module B Module C Module A Service Program A

Putting It All Together

Page 12: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service ProgramThe KRCONTROL processing service program is named CONTROLSP. Currently the service program consists of one module, RTVCTLVAL. This module contains a non-exported procedure & 3 exported procedures. This module will retrieve control values from the control file & update control file values. The reason I chose to name the service program is due to the fact that other modules may be necessary & will have to be bound to the service program at some future date.

Below is the header specification for the RTVCTLVAL module.

Notice that this is a NOMAIN module, meaning that this module alone cannot be compiled into a program by itself. It must be bound to a program either individually or as a service program in order to be used. OPTION(*NODEBUGIO) is a standard I use to make debugging less painful.

Page 13: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service ProgramThe File specification is displayed below. Notice that the file is defined as user open.

The file opening is controlled by the Initialize_SP procedure which we’ll look at later on in the module.

Next, we define our non-exported prototype:

This procedure can be used only in this module & cannot be used by external programs.

Page 14: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service ProgramNext we’ll define our global variables which can be used in all procedures in the module.

Our exported prototypes reside in copybooks that can be referenced by our calling programs to ensure parameter consistency.

The contents of the copybook are presented on the next few slides.

Page 15: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

This prototype defines the parameters that are necessary to successfully call the RTVCTLVAL procedure in the module. When calling this procedure the CONST parameters can be passed as a constant value since the procedure will use them as read-only parameters & cannot be changed by the procedure. Later we’ll illustrate this using a program which calls this procedure.

Page 16: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

This prototype defines the parameters that are necessary to successfully call the UPDCTLVAL procedure in the module. This procedure only receives CONST type parameters. None of these values will be modified by the procedure.

Page 17: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

This prototype defines the parameters that are necessary to successfully call the CLOSE_CONTROL_FILES procedure. This procedure accepts no parameters but returns an indicator value. Use of this will be shown in the calling program we’ll cover later.

Page 18: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

All procedures begin with a “P”rocedure Specification and must contain the procedure name and EXPORT/IMPORT keywords, if needed, as shown below:

All procedures end with a “P”rocedure Specification as shown below:

The procedure name is not necessary on the ending P specification, but makes it clearer which procedure is ending.

Page 19: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

After the beginning Procedure specification, the prototype interface must be defined. A prototype interface is basically defining the parameters that are to be received from the calling program or procedure.

With prototype interfaces, the variable names are required, whereas on the prototype definition, the names are for description only.

Page 20: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

The next item is to define any local variables, if any are needed. The local variables are only usable by the procedure they are defined in.

Now that the Definition specifications are complete for this procedure, it’s time to look at the executable code.

Page 21: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

First, the procedure checks to see if the control file has been opened. If not, it calls the INITIALIZE_SP procedure to open it. The OPENED variable is our globally defined indicator field. In the INITIALIZE_SP procedure, the indicator will be set to *ON after the file has been opened to prevent additional calls to the RTVCTLVAL procedure from trying to open the file again.

Page 22: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service ProgramNext, the procedure looks for the values to retrieve. If no matching values are found, *NONE is placed in the first element of the return values array. If values are found, they are loaded into the arrays for return to the calling program.

Page 23: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service ProgramThe begin procedure, prototype interface, local variables & key list section of the UPDCTLVAL procedure is shown below.

Page 24: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service ProgramLike the RTVCTLVAL procedure, the UPDCTLVAL checks to determine if the control file is opened. If the file hasn’t been opened yet, a call is placed to the INITIALIZE_SP procedure to open the file.

Page 25: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service ProgramThe received parameters are then used to chain to the control file. If the record doesn’t exist, the new record is written to the control file. If the record already exists, the record is updated with the new value.

Page 26: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service ProgramThis is the INITIALIZE_SP procedure, which returns an indicator value to let the calling procedures know if the file was successfully opened.

Page 27: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

Below is the CLOSE_CONTROL_FILES procedure. This procedure should be called from your program to close the control file at the end of processing.

Page 28: Module D Module B Module C Module A Service Program A

KRCONTROL Processing Service Program

Now that we have finished coding our module, the next step is to compile the module & create the service program.

With our service program completed, we’ll create our binding directory for the service program, so it will be there for our calling programs to bind with.

Ok, now that we have our service program & binding directory, the module is no longer needed and can be deleted if you so desire. Next, we’ll see how to leverage the service program’s functionality within our calling programs.

Page 29: Module D Module B Module C Module A Service Program A

Accessing The Service Program Procedures

We’ll be looking at the KRPPCSEQ program which is used to retrieve the punch porter file sequence number for combined databases. Below is the Header specification, prototype & prototype interface:

Notice that we have our binding directory & activation group attributes defined in the Header. This makes accurate compilation of the program much easier.

This program receives a 10 byte character field called Combine.

Page 30: Module D Module B Module C Module A Service Program A

Accessing The Service Program Procedures

We’ll use our copybook to get our prototypes for the service program & define our variables for the program.

Page 31: Module D Module B Module C Module A Service Program A

Accessing The Service Program Procedures

Below is the call to the service program’s RTVCTLVAL procedure. Since the CONST keyword is defined for the record type parameter we can simply pass the constant ‘PPCOMBSEQ#’. The Value & Desc fields are defined as arrays & are returned from the procedure. The RTNCOUNT is also returned & will contain the number of array elements populated by the procedure.

Page 32: Module D Module B Module C Module A Service Program A

Accessing The Service Program Procedures

Now that we have retrieved the values from the service program we can process the entries by using a loop until we reach the RTNCOUNT value.

Page 33: Module D Module B Module C Module A Service Program A

Accessing The Service Program Procedures

Let’s take a closer look at the call to the UPDCTLVAL procedure. Since all the parameters for this procedure are defined as CONST, we could simply pass all constants to the procedure. For this program, we will pass the value of Combine, the ‘PPCOMBSEQ#’ constant, the original value & description retrieved from the RTVCTLVAL procedure & the HldSeq value for updating the control file value.

Page 34: Module D Module B Module C Module A Service Program A

Accessing The Service Program Procedures

Last, but not least, we load the Combine parameter to return to the program which called KRPPCSEQ & we terminate the process. Notice that we call the CLOSE_CONTROL_FILES procedure to close the control file prior to setting on the last record indicator.

Page 35: Module D Module B Module C Module A Service Program A

Additional Information

Page 36: Module D Module B Module C Module A Service Program A

One MAJOR Gotcha To Avoid!!!

Using OPTIONS(*VARSIZE)

In the above prototype interface the RETURNDATA parameter is defined as 32767 Character with OPTIONS(*VARSIZE). While the options(*varsize) allows you to pass or receive data up to 32767a in most cases this procedure will be called using actual variables with a much smaller length.

Page 37: Module D Module B Module C Module A Service Program A

One MAJOR Gotcha To Avoid!!!

For instance, the calling program is passing a named data structure into the procedure. The data structure is defined as below.

Page 38: Module D Module B Module C Module A Service Program A

One MAJOR Gotcha To Avoid!!!

Since the DS is only 99 bytes long. The RETURNDATA should not access more than 99 bytes of memory. In the procedure, if you reference the entire RETURNDATA variables like this:

You have just wiped out 32668 bytes of memory that may belong to this process & possibly others!!! The way to prevent this is to pass a RETURNLENGTH to the procedure as shown in the prototype interface & use it to determine how much of the RETURNDATA to populate like this:

This will ensure that when you load the data to pass back to the calling program that only the memory you wanted to use is accessed & does not corrupt memory that you shouldn’t have touched.

Page 39: Module D Module B Module C Module A Service Program A

Downloads

This powerpoint presentation & other tidbits are available for download at http://tommyholden.com under the “My i” link.

Other places to obtain assistance, information & just great insight:

http://systeminetwork.com

Join the mailing lists at Midrange.com

http://midrange.com/lists.htm

Page 40: Module D Module B Module C Module A Service Program A

Works In Progress

ILEDOCS – The iSeries answer to “javadocs”

Join the official forum at

http://tommyholden.com/phpbb2

the official mailing list (big thanks ti David Gibbs for allowing us to setup this mailing list…)

http://lists.midrange.com/mailman/listinfo/iledocs

WRKSPL

Just something I’ve wanted for years. The ability to repeat options on a list of spooled files, etc.

DBFINFO – Database Information Tool

Uses APIs & other system goodies to retrieve all information about files on your system, no nightly refreshes of DSPxxx to

outfile required. Everything is done dynamically & current. Not every shop can afford big money tools (like HAWKEYE, etc.) so

this is a handy alternative.

Page 41: Module D Module B Module C Module A Service Program A

Ain’t you glad this is over???