Introduction to Key Loops
A key loop is a template file construct which allows you to iterate through the collection of keys that CodeGen has information about. In order to use a key loop you must be processing a repository structure, either directly via the –s command line option, or because the structure is referenced by the UI Toolkit input window that you are processing via the –w command line option.
Note: The Synergy/DE Repository does not have an adequate mechanism to ensure that repository key definitions match the actual key definitions of the ISAM files being represented. Because of this, CodeGen considers the primary key to be the first key defined in the repository, and assumes that the alternate keys will immediately follow the primary key definition, and be in the correct sequence, as defined in the ISAM file. Any foreign keys should be defined after all of the access key definitions.
Key loops are delimited by a matching pair of <KEY_LOOP> and </KEY_LOOP> tags, which surround the template code to be inserted for each key.
There are two types of key loops, multi-line key loops and in-line key loops.
Multi-Line Key Loops
Multi-line key loops occur when the opening and closing key loop tags appear on separate lines in a template file, and delimit one or more entire lines of template code, like this:
[code]
<KEY_LOOP>code
</KEY_LOOP>
[code]
Multi-line key loops generate one or more lines of output code for each key that is processed.
In-Line Key Loops
In-line key loops exist when the opening and closing key loop tags appear on the same line in a template file, and delimit part of a line of template code, like this:
[code] <KEY_LOOP> code </KEY_LOOP> [code]
In-line key loops generate code into the current output line only.
The code between the opening and closing tags of a key loop is repeated for each key in the structure being processed.
This code within a key loop can contain other generic and structure tokens, and can also contain special key loop tokens, which are discussed later.
Key loop tokens can only be used inside a key loop, and a key loop can’t be declared within any other loop construct.
There are two additional variations on a key loop. These variations are called alternate key loops, and primary key blocks.
Alternate Key Loops
An alternate key loop is similar to a key loop; except that only alternate keys are processed (i.e. the primary key is skipped). As with key loops, CodeGen supports both multi-line and in-line alternate key loops.
A multi-line alternate key loop looks like this:
[code]
<ALTERNATE_KEY_LOOP>
code
</ALTERNATE_KEY_LOOP>
[code]
And an in-line alternate key loop looks like this:
[code] <ALTERNATE_KEY_LOOP> code </ALTERNATE_KEY_LOOP> [code]
Multi-line alternate key loops generate one or more lines of output code for each key that is processed, whereas in-line alternate key loops generate code into the current output line only.
A primary key block is similar to a key loop; except that only the primary key is processed (i.e. all alternate keys are skipped). As with key loops, CodeGen supports both multi-line and in-line primary key blocks.
A multi-line primary key block looks like this:
[code]
<PRIMARY_KEY>
code
</PRIMARY_KEY>
[code]
And an in-line primary key block looks like this:
[code] <PRIMARY_KEY> code </PRIMARY_KEY> [code]
Multi-line primary key blocks generate one or more lines of output code as the primary key is processed, whereas in-line primary key blocks generate code into the current output line only.
A unique key block is similar to a key loop; except that only the first unique key (i.e. the first key that does not allow duplicate key values) is processed. This will usually be the primary key, but could be some alternate key in the rare case that the primary key allows duplicates. As with key loops, CodeGen supports both multi-line and in-line unique key blocks.
A multi-line unique key block looks like this:
[code]
<UNIQUE_KEY>
code
</UNIQUE_KEY>
[code]
And an in-line unique key block looks like this:
[code] <UNIQUE_KEY> code </UNIQUE_KEY> [code]
Multi-line unique key blocks generate one or more lines of output code as the first unique key is processed, whereas in-line unique key blocks generate code into the current output line only.
If you attempt to use a unique key block in conjunction with a repository structure that does not have any unique keys then an error will be generated. You can avoid this by isolating the unique key block using an <IF STRUCTURE_HAS_UNIQUE_KEY> expression.
Key Loop Example
Template code like this:
<KEY_LOOP>
KEY <KEY_NUMBER>
START <SEGMENT_LOOP><SEGMENT_POSITION><:></SEGMENT_LOOP>
LENGTH <SEGMENT_LOOP><SEGMENT_LENGTH><:></SEGMENT_LOOP>
TYPE <SEGMENT_LOOP><segment_type><:></SEGMENT_LOOP>
ORDER <SEGMENT_LOOP><segment_sequence><:></SEGMENT_LOOP>|
NAME "<KEY_NAME>"
DUPLICATES <IF DUPLICATES>yes</IF><IF NODUPLICATES>no</IF>
<IF DUPLICATES>
DUPLICATE_ORDER <IF DUPLICATESATFRONT>lifo</IF><IF DUPLICATESATEND>fifo</IF>
</IF>
MODIFIABLE <IF CHANGES>yes</IF><IF NOCHANGES>no</IF>
<IF NULLKEY>
NULL <key_nulltype>
<IF NULLVALUE>
VALUE_NULL <KEY_NULLVALUE>
</IF>
</IF>
DENSITY <KEY_DENSITY>
</KEY_LOOP>
Would process each of a structures defined access keys, and generate output code like this:
KEY 0
START 23
LENGTH 8
TYPE alpha
ORDER ascending
NAME "PROJECT_KEY0"
DUPLICATES no
MODIFIABLE no
DENSITY 50
KEY 1
START 31:41:51
LENGTH 10:10:3
TYPE alpha:alpha:alpha
ORDER ascending:ascending:ascending
NAME "PROJECT_KEY1"
DUPLICATES no
MODIFIABLE no
DENSITY 50
KEY 2
START 114
LENGTH 8
TYPE alpha
ORDER ascending
NAME "PROJECT_KEY2"
DUPLICATES yes
DUPLICATE_ORDER fifo
MODIFIABLE yes
DENSITY 50
KEY 3
START 140:130
LENGTH 15:2
TYPE alpha:alpha
ORDER ascending:ascending
NAME "PROJECT_KEY3"
DUPLICATES yes
DUPLICATE_ORDER fifo
MODIFIABLE yes
DENSITY 50
KEY 4
START 934
LENGTH 20
TYPE alpha
ORDER ascending
NAME "REPLICATION_KEY"
DUPLICATES no
MODIFIABLE yes
DENSITY 50
Alternate Key Loop Example
Template file code like this:
<ALTERNATE_KEY_LOOP>
;;-------------------------------------------------------------------------
;;Create index <KEY_NUMBER> (<KEY_DESCRIPTION>)
;;
if (ok)
begin
sql = "CREATE <KEY_UNIQUE> INDEX IX_<STRUCTURE_NAME>_<KEY_NAME> "
& "ON <STRUCTURE_NAME>(<SEGMENT_LOOP><SEGMENT_NAME> <SEGMENT_ORDER><,></SEGMENT_LOOP>)"
call open_cursor
if (ok)
begin
call execute_cursor
call close_cursor
end
end
</ALTERNATE_KEY_LOOP>
Would process each of a structures defined access keys, except for the primary key, and generate output code like this:
;;-------------------------------------------------------------------------
;;Create index 1 (Projects by customer)
;;
if (ok)
begin
sql = "CREATE UNIQUE INDEX IX_PROJECT_PROJECT_KEY1 "
& "ON PROJECT(CUSTOMER_ID ASC,CONTRACT_ID ASC,CONTRACT_PROJECT_ID ASC)"
call open_cursor
if (ok)
begin
call execute_cursor
call close_cursor
end
end
;;-------------------------------------------------------------------------
;;Create index 2 (Projects by start date)
;;
if (ok)
begin
sql = "CREATE INDEX IX_PROJECT_PROJECT_KEY2 "
& "ON PROJECT(START_DATE ASC)"
call open_cursor
if (ok)
begin
call execute_cursor
call close_cursor
end
end
;;-------------------------------------------------------------------------
;;Create index 3 (Projects by consultant and status)
;;
if (ok)
begin
sql = "CREATE INDEX IX_PROJECT_PROJECT_KEY3 "
& "ON PROJECT(LEAD_CONSULTANT ASC,CURRENT_STATUS ASC)"
call open_cursor
if (ok)
begin
call execute_cursor
call close_cursor
end
end
;;-------------------------------------------------------------------------
;;Create index 4 (SQL Timestamp Key)
;;
if (ok)
begin
sql = "CREATE UNIQUE INDEX IX_PROJECT_REPLICATION_KEY "
& "ON PROJECT(REPLICATION_KEY ASC)"
call open_cursor
if (ok)
begin
call execute_cursor
call close_cursor
end
end
Primary Key Block Example
Template file code like this:
<PRIMARY_KEY>
<SEGMENT_LOOP>
{xfParameter(name="<SegmentName>")}
required in a<SegmentName>, <segment_spec>
</SEGMENT_LOOP>
</PRIMARY_KEY>
{xfParameter(name="<StructureName>",collectionType="structure",structure="<STRUCTURE_NAME>",dataTable="true")}
required out a<StructureName>s, @ArrayList
When processed for a structure with only a single segment in it's primary key, would produce output like this
{xfParameter(name="ProjectId")}
required in aProjectId, d8
{xfParameter(name="Project",collectionType="structure",structure="PROJECT",dataTable="true")}
required out aProjects, @ArrayList
When processed for a structure with multiple segments in its primary key, would produce output like this:
{xfParameter(name="TaskId")}
required in aTaskId, d3
{xfParameter(name="AttachmentId")}
required in aAttachmentId, d3
{xfParameter(name="ProjectAttachment",collectionType="structure",structure="PROJECT_ATTACHMENT",dataTable="true")}
required out aProjectAttachments, @ArrayList
Copyright © 2012 Synergex International, Inc.