Tuesday, April 8, 2008

V6R1 RPG Enhancements:

Following are the enhancements made by IBM to its all new V6R1 RPG. - This is downright intriguing.

Ø Increased Sizes

The maximum amount of storage that can be occupied by a data structure, array, or stand-alone field is now 16M. Yes, the maximum size of a character field has increased from 64K to 16M (16,773,104 bytes to be exact). This enhancement means that a whole lot of dynamic memory management procedures and pointer/user space procedures are about to disappear. It also means that operations such as XML-INTO are now more functional and less cumbersome to use.

D LongFld S a Len(25000000)
D BigDS DS a Len(60000000)
D BigArray1 S a Len(10000000)
D Dim(6)
D BigArray2 S 1a Dim(50000000)
D BigVarying S a Len(25000000) Varying(4)
D DummyPtr S *

DummyPtr = %Addr(BigVarying : *Data);

You can use the LEN keyword to define a large length.

· Since only seven positions are available to specify the length of a field in the D spec, you use the LEN keyword to specify a length greater than 9,999,999.
· The LEN keyword may also be applied to a data structure.
· The LEN keyword may also be applied to an array.
· Larger variable sizes also mean you can have a larger number of elements in an array as long as the total storage for the array does not exceed 16M. The same applies to multiple-occurrence data structures.
· Varying-length fields now require 2 or 4 bytes to store the actual length of the field. A size of 2 is assumed if the specified length is between 1 and 65535; otherwise, a size of 4 is assumed. You can specify either VARYING(2) or VARYING(4) for definitions whose length is between 1 and 65535. For definitions whose length is greater than 65535, VARYING(4) is required.
· The %ADDR BIF has also been enhanced. The optional *DATA parameter may be specified so that %ADDR returns the address of the data portion of a variable-length field.

UCS-2 and Graphic fields can have a maximum length of 8M.
The maximum size of literals has also increased:
· Character literals can now have a length of up to 16380 characters.
· UCS-2 literals can now have a length of up to 8190 UCS-2 characters.
· Graphic literals can now have a length of up to 16379 DBCS characters.

UCS-2 variables can now be initialized with character or graphic literals without using the %UCS2 built-in function. UCS-2 enhancements are available as PTFs back to V5R3.


Ø Files Defined in Subprocedures
Subprocedures have F-specs. This means that a file defined in a subprocedure is local to the subprocedure.

P GetName B

FCustomer IP E K Disk
D GetName PI 50a
D CusNo 10a
D GetCustRec Ds LikeRec(CustomerR)

/Free
Chain Cusno Customer GetCustRec;
Return GetCustRec.CustName;
/End-free

P E

A few points are worth noting:

· Input and output specifications are not generated for local files; therefore, all input and output must be done with result data structures.
· By default, files are automatically opened when the subprocedure is called and automatically closed when the subprocedure ends (either normally or abnormally). Of course, USROPN may be specified for a file so the opening and closing of the file are under your control in the subprocedure.
· You can change the default opening and closing of the file by specifying the STATIC keyword on the F-spec. This means that the storage associated with the file is static and all invocations of the subprocedure will use the same file. If the file is open when the procedure returns, it will remain open for the next call to the procedure.

Ø Templates

The TEMPLATE keyword allows you to define template data structures, stand-alone fields, and files.

· Templates for Data Structures
The concept of a template for data structures is not new. Below is the traditional way of defining and using a virtual template.


D Phone DS Based(DummyPtr) Qualified
D CountryCode 5i 0
D NDDPrefix 5
D AreaCode 5
D Number 9
D Extension 4
D IDDPrefix 5

D HomePhone DS LikeDS(Phone)
D CellPhone DS LikeDS(Phone)
D WorkPhone DS LikeDS(Phone)

/Free

HomePhone.CountryCode = 353;
CellPhone.CountryCode = 353;
WorkPhone.CountryCode = 353;


The new comparable structure being defined with the new TEMPLATE keyword. At first glance, they are fairly similar, the major difference being the use of the INT keyword on the DS definition of PHONE and the INZ(353) for the CountryCode subfield in Phone. The use of the INZ keyword with the template data structure means the same initialization may be applied to any dependent data structures (defined using LIKEDS) by specifying INZ(*LIKEDS).

D Phone DS Template Inz
D CountryCode 5i 0 Inz(353)
D NDDPrefix 5
D AreaCode 5
D Number 9
D Extension 4
D IDDPrefix 5
D HomePhone DS LikeDS(Phone)
D Inz(*LikeDS)
D CellPhone DS LikeDS(Phone)
D Inz(*LikeDS)
D WorkPhone DS LikeDS(Phone)
D Inz(*LikeDS)

· The TEMPLATE keyword may also be applied to a stand-alone field.
A definition defined with a TEMPLATE keyword may only be used as a parameter for the LIKE or LIKEDS keywords or the %SIZE, %LEN, %ELEM, or %DECPOS BIFs; it may not be used as a normal data structure or field.

· Templates for Files
The TEMPLATE keyword may be specified for files. Files defined with the TEMPLATE keyword are not included in the program; the file definition is used only at compile time. The template file can only be used as a basis for defining other files later in the program using the new LIKEFILE keyword. The LIKEFILE keyword also allows you to pass a file as a parameter.

· FCustomer IF E K Disk Template
P GetCustomer B
D GetCustomer PI N

· D customerFile LikeFile(Customer)
· D customerData LikeRec(CustomerR)
D customerKey Like(customerData.CustNo)
D Const
Chain customerKey customerFile customerData;
If %Found(customerFile);
If customerData.Status <> 'D';
Return *On;
EndIf;
EndIf;
Return *Off;
P E

The above shows a portion of a member containing a subprocedure (GetCustomer) that retrieves customer data. This member is compiled and placed in a service program. The main points to note are these (refer to the numbers above):

1. The TEMPLATE keyword is specified for the customer file. This means that the File specification is for reference purposes only, and the file definition may not be used for processing.
2. The LIKEFILE keyword identifies the first parameter as a file with the same characteristics as the Customer file.
3. The second parameter is the customer record that will be returned by the subprocedure.
4. The file parameter name is used to identify the file to be processed (i.e., customerFile not Customer). Since Input and Output specs are not generated for a template file or a file identified by LIKEFILE, you must use a result data structure for the CHAIN operation.

How do you call the GetCustomer subprocedure? The below snippet of a program shows a typical call: The file to be processed (CustFile) is simply passed as the first parameter. The format of the file CustFile must be the same as the Customer file.

FCustFile IF E K Disk
D custData DS LikeRec(CustFileR)

/Free
If GetCustomer(CustFile: CustFileR: 'THISCUST');
// DO cool things with data
EndIf;

The LIKEFILE keyword may also be used on the F-specs. The example below shows two files (CurrCust and OldCust) being defined like the Customer file. The processing options (file type, record addition, record address type, device, etc.) and most (but not all) of the keywords are inherited.

FCustomer IF E K Disk Template Block(*YES)
FCurrCust LikeFile(Customer)
F ExtFile('CURRLIB/CUSTFILE')
FOldCust LikeFile(Customer)
F ExtFile('OLDLIB/CUSTFILE')

There are a few items to bear in mind when using LIKEFILE:
• The parent file must be externally defined.
• Files are implicitly qualified; therefore, resulting data structures are required for input and output operations.
• The parent file must define any blocking requirements.
• Not all keywords are inherited. These are keywords that must be unique for each file (e.g., INDDS, INFDS, INFSR, OFLIND).
• Although the SFILE keyword may be inherited, you still need to define it for dependent files in order to specify a unique RRN field.

Ø Other File Enhancements

There are a few other file related enhancements worth having a look at.

(1) FCustomer IP E K Disk ExtDesc('MYLIB/CUSTFILE')
(2) F ExtFile(*ExtDesc)
(3) F Qualified
FScreens CF E WorkStn
D GetCustRec Ds LikeRec(CustomerR)

(4) D GetDetails E Ds ExtName('MYLIB/SCREENS' :
D Screen1 : *ALL)

/Free
(5) Read Customer.CustomerR GetCustRec;
If GetCustRec.Type = 1;
Eval-Corr GetDetails = GetCustRec;
(6) ExFmt Screen1 GetDetails;
EndIf;

1. You are aware that the EXTFILE keyword allows you to specify the file to be used when a program is called (a built-in override), but EXTFILE does not have any effect at compile time. The EXTDESC keyword allows you to specify the file definition to be referenced at compile time. This provides a means of handling SQL defined tables (where the file and format name are the same) other than renaming the record format.

2. The EXTFILE keyword allows a special value of *EXTDESC, which means that the value specified for the EXTDESC keyword should be used by the EXTFILE. Basically, you are specifying the same value for both the EXTDESC (compile time) and EXTFILE (run time) keywords.

3. The QUALIFIED keyword may be specified for files. This means that all references (except for the RENAME, INCLUDE, IGNORE, and SFILE file keywords) to record format names must be qualified with the file name.

4. The file name specified on the EXTNAME keyword may be a character literal in any of the forms 'LIBRARY/FILE', 'FILE', or '*LIBL/FILE'.

5. As with file specifications in subprocedures, Input and Output specifications are not generated for a qualified file (i.e., external fields from the file are not automatically defined as fields in the program and all I/O to the file must be done with result data structures).

6. A data structure name may be specified as the result for an EXFMT operation. This eases the use of qualified data structures with display files. The *ALL value must be specified on the LIKREC or EXTNAME keyword for the data structure.


Ø No Cycle RPG

If you have delved into the wonderful world of ILE, you are almost certain to have coded a module with the NOMAIN keyword in the control specifications. This means that the module only contains global definitions (F- and D-specs) and subprocedures and that the compiler does not place any RPG cycle code in the module since there is no mainline (a linear module). Since a NOMAIN module does not contain a Program Entry Procedure (PEP), it cannot be compiled as a callable program.

The introduction of the MAIN keyword on the control specification allows you to code a module that may be created as a program but does not contain the RPG cycle. The MAIN keyword allows you to specify the name of the subprocedure to be used as the PEP for the program. The below snippet shows the code in a member named CUST001, the member is compiled using the CRTBNDRPG command. The MAIN keyword identifies the MaintainCustomer subprocedure as the PEP for the program.

H Main(MaintainCustomer)


P MaintainCustomer...
P B
D MaintainCustomer...
D PI
/Free
// Lots of cool code
/End-Free
P E

These are a few of the many other enhancements made in V6R1 RPG.

1 comment:

Unknown said...

This post was copied directly from Paul Tuohy's article in MC Press Online. The post should have at least referenced the originator of the article.

http://www.mcpressonline.com/programming/rpg/v6r1-rpg-enhancements.html