Column Layout Matcher
When performing a the comparison or conversion of a table column containing a binary layout, Ianus must be aware of the record layout of the files being compared.
There are cases where a column may have more than one layout and programs decides what layout to use depending on data contained on the record.
The following example shows a case where a column may have two layouts depending on the content of one or more fields:
01 SYS053-TXT.
03 FIELD01 PIC X(2).
03 FIELD02 PIC X(4).
01 SYS053-COMPS.
03 FIELD01 PIC S9(4) COMP.
03 FIELD02 PIC S9(8) COMP.
Together with the layouts, the rules for the layout identification must be provided. Those rules will be invoked for all records, providing the current record data for the rules to determine the layout to be used in the process.
The rules are coded in a .NET class implementing the HPE.Ianus.Scripting.IColumnLayoutMatch
interface:
namespace HPE.Ianus.Scripting
{
public interface IColumnLayoutMatch
{
Layout Match(AbstractDatabaseTask task,
LoggerFacade log,
Side side,
Dictionary<string, Layout> layouts,
Record record,
EncodingType encoding);
}
}
Therefore the class must implement at least the method Match which purpose is to return the selected layout.
The method Match receives the following input parameters:
Parameter | Description |
---|---|
task | The task object invoking the matcher |
log | LoggerFacade object to write entries in the job log |
side | Side from which data is read |
layouts | Layouts dictionary |
record | Column data as record |
encoding | Default encoding of the repository containing the file (ASCII or EBCDIC) |
The script can examine the value of the fields defined in the different layouts to determine the layout to use. Those fields can be accessed directly through the layouts dictionary.
Also, it can access the task members to obtain additional information, for example:
- the
Reader
property oftablecopy
ortablecompare
tasks, to test the value of the other columns being read - the
IOFile
orHostVariablesDictionary
properties oftableload
to test the content of other fields on the file record.
For example, to access the value of field RECORD-TYPE in the layout CUSTOMER-ID, the script can access the layout dictionary as follows:
Layout l = layouts["CUSTOMER-ID"];
if ((string)(l["RECORD-TYPE"].Value == “I”)
Note
Match classed can also be used for dynamic field enablement. See example 2 in Record Layouts.
Example
The following example shows the layouts and match definition for some columns:
The Layout
<tablecopy name="copy" source="DB2" target="SQLSRV" truncate="true" mode="hybrid">
<source layoutencoding="ebcdic">IANUS.CHAR_BINARIES_A</source>
<target>IANUS.CHAR_BINARIES_B</target>
<layouts>
<layout type="cobol" format="free" length="auto">
01 SYS053-DESCR.
03 FIELD01 PIC S9(4) COMP.
03 FIELD02 PIC X(4).
</layout>
<layout type="cobol" format="free" length="auto">
01 SYS053-BINS.
@ianus*type=binary
03 FIELD01 PIC X(2).
@ianus*type=binary
03 FIELD02 PIC X(4).
</layout>
<match assembly="%IANUS_HOME%\Samples\LayoutMatchers\bin\Debug\%IANUS_DOTNET_VERSION%\LayoutMatchers.dll"
class="LayoutMatchers.ExampleColumnLayoutMatcher"/>
</layouts>
<convert mode="multilayout" sourcename="LAYOUTV" />
<convert mode="multilayout" sourcename="LAYOUTF" />
</tablecopy>
The Match class
using HPE.Ianus;
using HPE.Ianus.File;
using HPE.Ianus.Log;
using HPE.Ianus.RDBMS;
namespace LayoutMatchers
{
public class ExampleColumnLayoutMatcher : HPE.Ianus.Scripting.IColumnLayoutMatch
{
public Layout Match(AbstractDatabaseTask task,
LoggerFacade log,
Side side,
Dictionary<string, Layout> layouts,
Record columnContent,
EncodingType encoding)
{
log.Info("The column content: {0}",
BitConverter.ToString(columnContent.Bytes, 0, columnContent.Length));
log.Info("The field values according to layouts:");
foreach (var l in layouts.Values)
{
foreach (var f in l.Fields)
{
log.Info("{0}.{1}={2}", l.Name, f.Name, f.Value);
}
}
if (task is TableLoadTask)
{
TableLoadTask load = (TableLoadTask)task;
Record rowContent = load.IOFile.Record;
log.Info("The whole record content: {0}", BitConverter.ToString(rowContent.Bytes, 0, rowContent.Length));
log.Info("HOST VARIABLE PK1={0}", load.HostVarsDictionary["PK1"].Field.Value);
if (load.HostVarsDictionary["PK1"].Field.Value.ToString() == "AAAA")
{
return layouts["SYS053-BINS"];
}
else
{
return layouts["SYS053-DESCR"];
}
}
else
{
ReadableDatabaseObject SourceTable = ((DualDatabaseTask)task).LeftDbObject;
log.Info("From reader PK1={0} ", SourceTable.Reader["PK1"]);
if (SourceTable.Reader["PK1"].ToString() == "AAAA")
{
return layouts["SYS053-BINS"];
}
else
{
return layouts["SYS053-DESCR"];
}
}
}
}
}