Home | Table of Contents | Mapping | CloverETL 4.6.1
--- | --- | ---
Prev | Language Reference | Next

## Mapping

Mapping is a part of each transformation defined in some of the CloverETL components.

Calculated or generated values or values of input fields are assigned (mapped) to output fields.

1. Mapping assigns a value to an output field.

2. Mapping operator is the following:

   `=`

3. Mapping must always be defined inside a function.

4. Mapping may be defined in any place inside a function.

   | Important
   In CTL2, mapping may be in any place of the transformation code and may be followed by any code. This is one of the differences between the two versions of CloverETL Transformation Language. (In CTL1, mapping had to be at the end of the function and could only be followed by one `return` statement.) In CTL2, mapping operator is simply the equal sign.

5. Remember that you can also wrap a mapping in a user-defined function which would be subsequently used inside another function.

6. You can also map different input metadata to different output metadata by field names or by field positions. See examples below.

#### Mapping of Different Metadata (by Name)

When you map input to output like this:

`$out.0.* = $in.0.*;`

input metadata may even differ from those on the output.

In the expression above, fields of the input are mapped to the fields of the output that have the same name and type as those of the input. The order in which they are contained in respective metadata and the number of all fields in either metadata is of no importance.

When you have input metadata in which the first two fields are `firstname` and `lastname`, each of these two fields is mapped to its counterpart on the output. Such output `firstname` field may even be the fifth and `lastname` field be the third, but those two fields of the input will be mapped to these two output fields.

Even if input metadata had more fields and output metadata had more fields, such fields would not be mapped to each other if there did not exist an output field with the same name as one of the input (independently on the mutual position of the fields in corresponding metadata).

In addition to the simple mapping as shown above (`$out.0.* = $in.0.*;`) you can also use the following function:

`void copyByName(`record to, record from`)`;

Example 59.22. Mapping of Metadata by Name (using the copyByName() function)

    recordName2 myOutputRecord;
    copyByName(myOutputRecord.*,$in.0.*);
    $in.0.* = myOutputRecord.*;

| Important
Metadata fields are mapped from input to output by name and data type independently on their order and on the number of all fields! Following syntax may also be used: `myOutputRecord.copyByName($in.0.*);`

#### Mapping of Different Metadata (by Position)

Sometimes you need to map input to output, but names of input fields are different from those of output fields. In such a case, you can map input to output by position.

To achieve this, you must use the following function:

`void copyByPosition(`record to, record from`)`;

Example 59.23. Mapping of Metadata by Position

    recordName2 myOutputRecord;
    copyByPosition(myOutputRecord,$in.0.*);
    $out.0.* = myOutputRecord.*;

| Important
Metadata fields may be mapped from input to output by position (as shown in the example above)! Following syntax may also be used: `myOutputRecord.copyByPosition($in.0.*);`

#### Use Case 1 - One String Field to Upper Case

To show in more details how mapping works, we provide here a few examples of mappings.

We have a graph with a Reformat component. Metadata on its input and output are identical. First two fields (`field1` and `field2`) are of string data type, the third (`field3`) is of integer data type.

1. We want to change the letters of `field1` values to upper case while passing the other two fields unchanged to the output.

2. We also want to distribute records according to the value of `field3`. Those records in which the value of `field3` is less than 5 should be sent to the output port 0, the others to the output port 1.

#### Examples of Mapping

As the first possibility, we have the mapping for both ports and all fields defined inside the `transform()` function of CTL template.

Example 59.24. Example of Mapping with Individual Fields

Note that the mappings will be performed for all records. In other words, even when the record will go to the output port 1, the mapping for output port 0 will be performed, and vice versa.

Moreover, mapping consists of individual fields, which may be complex in case there are many fields in a record. In the next examples, we will see how this can be solved in a better way.

    	function integer transform() {

    	     // mapping input port records to output port records
    	     // each field is mapped separately
    	     $out.0.field1 = upperCase($in.0.field1);
    	     $out.0.field2 = $in.0.field2;
    	     $out.0.field3 = $in.0.field3;
    	     $out.1.field1 = upperCase($in.0.field1);
    	     $out.1.field2 = $in.0.field2;
    	     $out.1.field3 = $in.0.field3;

    	     // output port number returned
    	     if ($out.0.field3 < 5) return 0; else return 1;
    	}

| Note
As CTL2 allows to use any code after the mapping, here we have used the `if` statement with two `return` statements after the mapping. In CTL2, mapping may be in any place of the transformation code and may be followed by any code!

As the second possibility, we also have the mapping for both ports and all fields defined inside the `transform()` function of CTL template. But now there are wild cards used in the mapping. These pass the records unchanged to the outputs and, after this wildcard mapping, the fields that should be changed are specified.

Example 59.25. Example of Mapping with Wild Cards

Note that mappings will be performed for all records. In other words, even when the record will go to the output port 1, the mapping for output port 0 will be performed, and vice versa.

However, now the mapping uses wild cards at first, which passes the records unchanged to the output, but the first field is changed below the mapping with wild cards.

This is useful when there are many unchanged fields and a few that will be changed.

    	function integer transform() {

    	     // mapping input port records to output port records
    	     // wild cards for mapping unchanged records
    	     // transformed records mapped additionally
    	     $out.0.* = $in.0.*;
    	     $out.0.field1 = upperCase($in.0.field1);
    	     $out.1.* = $in.0.*;
    	     $out.1.field1 = upperCase($in.0.field1);

    	     // return the number of output port
    	     if ($out.0.field3 < 5) return 0; else return 1;
    	}

| Note
As CTL2 allows to use any code after the mapping, here we have used the `if` statement with two `return` statements after the mapping. In CTL2, mapping may be in any place of the transformation code and may be followed by any code!

As the third possibility, we have the mapping for both ports and all fields defined outside the `transform()` function of CTL template. Each output port has its own mapping.

Wild cards are used here as well.

The mapping that is defined in a separate function for each output port allows the following improvements:

- Mapping is performed only for a respective output port! In other words, now there is no need to map the record to the port 1 when it will go to the port 0, and vice versa.

Example 59.26. Example of Mapping with Wild Cards in Separate User-Defined Functions

Moreover, mapping uses wild cards at first, which pass the records unchanged to the output. The first field is changed below the mapping with wild card. This is useful when there are many unchanged fields and a few that will be changed.

    	// mapping input port records to output port records
    	// inside separate functions
    	// wild cards for mapping unchanged records
    	// transformed records mapped additionally
    	function void mapToPort0 () {
    	     $out.0.* = $in.0.*;
    	     $out.0.field1 = upperCase($in.0.field1);
    	}

    	function void mapToPort1 () {
    	     $out.1.* = $in.0.*;
    	     $out.1.field1 = upperCase($in.0.field1);
    	}

    	// use mapping functions for all ports in the if statement
    	function integer transform() {
    	     if ($in.0.field3 < 5) {
    		  mapToPort0();
    		  return 0;
    	     }
    	     else {
    		  mapToPort1();
    		  return 1;
    	     }
    	}

Prev | Up | Next
Accessing Data Records and Fields | Home | Table of Contents | Parameters