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.
If a key loop is encountered while processing a structure that does not have any keys defined, the key loop is ignored.
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 that surround the template code to be inserted for each key.
Key loop tokens are tokens that can only be used within a key loop:
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:
<KEY_LOOP>
code
</KEY_LOOP>
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:
<KEY_LOOP> code </KEY_LOOP>
In-line key loops generate code into the current output line only.
Foreign keys are ignored when processing key loops.
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 except structure loops.
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, and foreign keys are also ignored). As with key loops, CodeGen supports both multi-line and in-line alternate key loops.
A multi-line alternate key loop looks like this:
<ALTERNATE_KEY_LOOP>
code
</ALTERNATE_KEY_LOOP>
And an in-line alternate key loop looks like this:
<ALTERNATE_KEY_LOOP> code </ALTERNATE_KEY_LOOP>
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.
Unique Key Loops
A unique key loop is similar to a regular key loop; except that in addition to excluding foreign keys, it excludes any keys that use the exact same segments as a key that has already been processed.
A multi-line unique key loop looks like this:
<KEY_LOOP_UNIQUE>
code
</KEY_LOOP_UNIQUE>
And an in-line unique key loop looks like this:
[code] <KEY_LOOP_UNIQUE> code </KEY_LOOP_UNIQUE> [code]
Multi-line unique key loops generate one or more lines of output code for each key that is processed, whereas in-line unique key loops generate code into the current output line only.
Unique Alternate Key Loops
A unique alternate key loop is similar to a regular key loop; except that in addition to excluding the primary key and any foreign keys, it also excludes any keys that have the exact same segments as either the primary key, or an earlier alternate key.
A multi-line unique alternate key loop looks like this:
<ALTERNATE_KEY_LOOP_UNIQUE>
code
</ALTERNATE_KEY_LOOP_UNIQUE>
And an in-line unique alternate key loop looks like this:
<ALTERNATE_KEY_LOOP_UNIQUE> code </ALTERNATE_KEY_LOOP_UNIQUE>
Multi-line unique alternate key loops generate one or more lines of output code for each key that is processed, whereas in-line unique alternate key loops generate code into the current output line only.
Primary Key Blocks
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:
<PRIMARY_KEY>
code
</PRIMARY_KEY>
And an in-line primary key block looks like this:
<PRIMARY_KEY> code </PRIMARY_KEY>
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.
Unique Key Blocks
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:
<UNIQUE_KEY>
code
</UNIQUE_KEY>
And an in-line unique key block looks like this:
<UNIQUE_KEY> code </UNIQUE_KEY>
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.
Foreign Key Loops
A foreign key loop is a key loop where ONLY foreign keys are processed. CodeGen supports both multi-line and in-line alternate key loops.
A multi-line foreign key loop looks like this:
<FOREIGN_KEY_LOOP>
code
</FOREIGN_KEY_LOOP>
And an in-line foreign key loop looks like this:
<FOREIGN_KEY_LOOP> code </FOREIGN_KEY_LOOP>
Multi-line foreign key loops generate one or more lines of output code for each key that is processed, whereas in-line foreign key loops generate code into the current output line only.
Partial Key Loop
A partial key loop is a loop that allows you to process subsets of the segments of multi-segment access keys that have a corresponding CODEGEN_PARTIAL_KEY_n token present in the structures long description, like this:
CODEGEN_PARTIAL_KEY_n[=x[,x…];]
Where n represents the access key number, and x represents the number of segments to be processed.
There are two types of partial key loop, a multi-line partial key loop:
<PARTIAL_KEY_LOOP>
code
</PARTIAL_KEY_LOOP>
And an in-line partial key loop:
<PARTIAL_KEY_LOOP> code </PARTIAL_KEY_LOOP>
Processing Rules
•Access keys that only have a single segment will not be processed by a partial key loop.
•Access keys that do not have a matching CODEGEN_PARTIAL_KEY_n token will not be processed by a partial key loop.
•Access keys that have a matching CODEGEN_PARTIAL_KEY_n token but without segment numbers specified, will be processed for each number of segments except all segments.
•If the structure has no access keys, or no keys are selected for processing, partial key loops are ignored, no output is produced, and no error is generated.
•When using a partial key loop, key segments should only be iterated by using a Key Segment Loop (<SEGMENT_LOOP>). Other types of segment loop such as Key Segment Filter Loops, First Segment Restrictions and Second Segment Restrictions do not honor CODEGEN_PARTIAL_KEY_n processing rules.
Examples
For example, if a file has an access key number 2 that has 5 segments, and the following token is used:
CODEGEN_PARTIAL_KEY_2=3,4;
Then the partial key loop will process that key two times. The first time the key is processed, the key segment loop will expose only the first three segments, and the second time the key segment loop will expose 4 segments.
To be clear, the token above does NOT say process key 2 with only segments 3 and 4, it says process the key twice, once with three segments and once with 4.
If the following token is used with the same 5-segment key:
CODEGEN_PARTIAL_KEY_2
The key will be processed four times, once with only the first segment, once with the first two segments, once with the first three segments, and once with the first four segments.
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 © 2021 Synergex International, Inc.