CodeGen Documentation
CodeGen Documentation

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:

Key Loop Expansion Tokens

Key Loop Expression Tokens

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.