Table of Contents

Search

  1. Preface
  2. Working with Transformations
  3. Aggregator Transformation
  4. Custom Transformation
  5. Custom Transformation Functions
  6. Data Masking Transformation
  7. Data Masking Examples
  8. Expression Transformation
  9. External Procedure Transformation
  10. Filter Transformation
  11. HTTP Transformation
  12. Identity Resolution Transformation
  13. Java Transformation
  14. Java Transformation API Reference
  15. Java Expressions
  16. Java Transformation Example
  17. Joiner Transformation
  18. Lookup Transformation
  19. Lookup Caches
  20. Dynamic Lookup Cache
  21. Normalizer Transformation
  22. Rank Transformation
  23. Router Transformation
  24. Sequence Generator Transformation
  25. Sorter Transformation
  26. Source Qualifier Transformation
  27. SQL Transformation
  28. Using the SQL Transformation in a Mapping
  29. Stored Procedure Transformation
  30. Transaction Control Transformation
  31. Union Transformation
  32. Unstructured Data Transformation
  33. Update Strategy Transformation
  34. XML Transformations

Transformation Guide

Transformation Guide

Step 3. Fill Out the Code with the Transformation Logic

Step 3. Fill Out the Code with the Transformation Logic

You must code the procedure C file. Optionally, you can also code the module C file. In the Union example, you fill out the procedure C file only. You do not need to fill out the module C file.
To code the procedure C file:
  1. Open p_<procedure_name>.c for the procedure.
    In the Union example, open p_Union.c.
  2. Enter the C code for the procedure.
  3. Save the modified file.
    In the Union example, use the following code:
    /**************************************************************************  * Custom Transformation p_union Procedure File  *  * This file contains code that functions that will be called by the main  * server executable.  *  * for more information on these files,  * see $(INFA_HOME)/ExtProc/include/Readme.txt  **************************************************************************/ /*  * INFORMATICA 'UNION DEMO' developed using the API for custom  * transformations.  * File Name: p_Union.c  *  * An example of a custom transformation ('Union') using PowerCenter  *  * The purpose of the 'Union' transformation is to combine pipelines with the  * same row definition into one pipeline (i.e. union of multiple pipelines).  * [ Note that it does not correspond to the mathematical definition of union  * since it does not eliminate duplicate rows.]  *  * This example union transformation allows N input pipelines ( each  * corresponding to an input group) to be combined into one pipeline.  *  * To use this transformation in a mapping, the following attributes must be  * true:  * a. The transformation must have >= 2 input groups and only one output group.  * b. In the Properties tab set the following properties:  *      i.   Module Identifier: UnionDemo  *      ii.  Function Identifier: Union  *      iii. Inputs May Block: Unchecked  *      iv.  Is Active: Checked  *      v.   Update Strategy Transformation: Unchecked *  *      vi.  Transformation Scope: All  *      vii. Generate Transaction: Unchecked *  *  *      * This version of the union transformation does not provide code for  *      changing the update strategy or for generating transactions.  * c. The input groups and the output group must have the same number of ports  *    and the same datatypes. This is verified in the initialization of the  *    module and the session is failed if this is not true.  * d. The transformation can be used in multiple number of times in a Target  *    Load Order Group and can also be contained within multiple partitions.  *  */ /**************************************************************************                                Includes  **************************************************************************/ include <stdlib.h> #include "p_union.h" /**************************************************************************                                Forward Declarations  **************************************************************************/ INFA_STATUS validateProperties(const INFA_CT_PARTITION_HANDLE* partition); /**************************************************************************                                Functions  **************************************************************************/ /**************************************************************************    Function: p_union_procInit  Description: Initialization for the procedure. Returns INFA_SUCCESS if  procedure initialization succeeds, else return INFA_FAILURE.  Input: procedure - the handle for the procedure  Output: None  Remarks: This function will get called once for the session at  initialization time. It will be called after the moduleInit function.  **************************************************************************/ INFA_STATUS p_union_procInit( INFA_CT_PROCEDURE_HANDLE procedure) {     const INFA_CT_TRANSFORMATION_HANDLE* transformation = NULL;     const INFA_CT_PARTITION_HANDLE* partition = NULL;     size_t nTransformations = 0, nPartitions = 0, i = 0;     /* Log a message indicating beginning of the procedure initialization */     INFA_CTLogMessageM( eESL_LOG,                         "union_demo: Procedure initialization started ..." );     INFA_CTChangeStringMode( procedure, eASM_MBCS );     /* Get the transformation handles */     transformation = INFA_CTGetChildrenHandles( procedure,                                                 &nTransformations,                                                 TRANSFORMATIONTYPE);     /* For each transformation verify that the 0th partition has the correct      * properties. This does not need to be done for all partitions since rest      * of the partitions have the same information */     for (i = 0; i < nTransformations; i++)     {         /* Get the partition handle */         partition = INFA_CTGetChildrenHandles(transformation[i],                                               &nPartitions, PARTITIONTYPE );         if (validateProperties(partition) != INFA_SUCCESS)         {             INFA_CTLogMessageM( eESL_ERROR,                                 "union_demo: Failed to validate attributes of "                                 "the transformation");             return INFA_FAILURE;         }     }     INFA_CTLogMessageM( eESL_LOG,                         "union_demo: Procedure initialization completed." );     return INFA_SUCCESS; } /**************************************************************************    Function: p_union_procDeinit  Description: Deinitialization for the procedure. Returns INFA_SUCCESS if  procedure deinitialization succeeds, else return INFA_FAILURE.  Input: procedure - the handle for the procedure  Output: None  Remarks: This function will get called once for the session at  deinitialization time. It will be called before the moduleDeinit  function.  **************************************************************************/ INFA_STATUS p_union_procDeinit( INFA_CT_PROCEDURE_HANDLE procedure,                                 INFA_STATUS sessionStatus ) {     /* Do nothing ... */     return INFA_SUCCESS; } /**************************************************************************    Function: p_union_partitionInit  Description: Initialization for the partition. Returns INFA_SUCCESS if  partition deinitialization succeeds, else return INFA_FAILURE.  Input: partition - the handle for the partition  Output: None  Remarks: This function will get called once for each partition for each  transformation in the session.  **************************************************************************/ INFA_STATUS p_union_partitionInit( INFA_CT_PARTITION_HANDLE partition ) {     /* Do nothing ... */     return INFA_SUCCESS; } /**************************************************************************    Function: p_union_partitionDeinit  Description: Deinitialization for the partition. Returns INFA_SUCCESS if  partition deinitialization succeeds, else return INFA_FAILURE.  Input: partition - the handle for the partition  Output: None  Remarks: This function will get called once for each partition for each  transformation in the session.  **************************************************************************/ INFA_STATUS p_union_partitionDeinit( INFA_CT_PARTITION_HANDLE partition ) {     /* Do nothing ... */     return INFA_SUCCESS; } /**************************************************************************    Function: p_union_inputRowNotification  Description: Notification that a row needs to be processed for an input  group in a transformation for the given partition. Returns INFA_ROWSUCCESS  if the input row was processed successfully, INFA_ROWFAILURE if the input  row was not processed successfully and INFA_FATALERROR if the input row  causes the session to fail.  Input: partition - the handle for the partition for the given row         group - the handle for the input group for the given row  Output: None  Remarks: This function is probably where the meat of your code will go,  as it is called for every row that gets sent into your transformation.  **************************************************************************/ INFA_ROWSTATUS p_union_inputRowNotification( INFA_CT_PARTITION_HANDLE partition,                                              INFA_CT_INPUTGROUP_HANDLE inputGroup ) {     const INFA_CT_OUTPUTGROUP_HANDLE* outputGroups = NULL;     const INFA_CT_INPUTPORT_HANDLE* inputGroupPorts = NULL;     const INFA_CT_OUTPUTPORT_HANDLE* outputGroupPorts = NULL;     size_t nNumInputPorts = 0, nNumOutputGroups = 0,            nNumPortsInOutputGroup = 0, i = 0;     /* Get the output group port handles */     outputGroups = INFA_CTGetChildrenHandles(partition,                                              &nNumOutputGroups,                                              OUTPUTGROUPTYPE);     outputGroupPorts = INFA_CTGetChildrenHandles(outputGroups[0],                                                  &nNumPortsInOutputGroup,                                                  OUTPUTPORTTYPE);     /* Get the input groups port handles */     inputGroupPorts = INFA_CTGetChildrenHandles(inputGroup,                                                 &nNumInputPorts,                                                 INPUTPORTTYPE);     /* For the union transformation, on receiving a row of input, we need to      * output that row on the output group. */     for (i = 0; i < nNumInputPorts; i++)     {         INFA_CTSetData(outputGroupPorts[i],                        INFA_CTGetDataVoid(inputGroupPorts[i]));         INFA_CTSetIndicator(outputGroupPorts[i],                             INFA_CTGetIndicator(inputGroupPorts[i]) );         INFA_CTSetLength(outputGroupPorts[i],                          INFA_CTGetLength(inputGroupPorts[i]) );     }     /* We know there is only one output group for each partition */     return INFA_CTOutputNotification(outputGroups[0]); } /**************************************************************************    Function: p_union_eofNotification  Description: Notification that the last row for an input group has already  been seen. Return INFA_FAILURE if the session should fail as a result of  seeing this notification, INFA_SUCCESS otherwise.  Input: partition - the handle for the partition for the notification         group - the handle for the input group for the notification  Output: None  **************************************************************************/ INFA_STATUS p_union_eofNotification( INFA_CT_PARTITION_HANDLE partition,                                      INFA_CT_INPUTGROUP_HANDLE group) {     INFA_CTLogMessageM( eESL_LOG,                         "union_demo: An input group received an EOF notification");     return INFA_SUCCESS; } /**************************************************************************    Function: p_union_dataBdryNotification  Description: Notification that a transaction has ended. The data  boundary type can either be commit or rollback.  Return INFA_FAILURE if the session should fail as a result of  seeing this notification, INFA_SUCCESS otherwise.  Input: partition - the handle for the partition for the notification         transactionType - commit or rollback  Output: None  **************************************************************************/ INFA_STATUS p_union_dataBdryNotification ( INFA_CT_PARTITION_HANDLE partition,                                            INFA_CT_DATABDRY_TYPE transactionType) {     /* Do nothing */     return INFA_SUCCESS; } /* Helper functions */ /**************************************************************************    Function: validateProperties  Description: Validate that the transformation has all properties expected  by a union transformation, such as at least one input group, and only  one output group. Return INFA_FAILURE if the session should fail since the  transformation was invalid, INFA_SUCCESS otherwise.  Input: partition - the handle for the partition  Output: None **************************************************************************/ INFA_STATUS validateProperties(const INFA_CT_PARTITION_HANDLE* partition) {     const INFA_CT_INPUTGROUP_HANDLE* inputGroups = NULL;     const INFA_CT_OUTPUTGROUP_HANDLE* outputGroups = NULL;     size_t nNumInputGroups = 0, nNumOutputGroups = 0;     const INFA_CT_INPUTPORT_HANDLE** allInputGroupsPorts = NULL;     const INFA_CT_OUTPUTPORT_HANDLE* outputGroupPorts = NULL;     size_t nNumPortsInOutputGroup = 0;     size_t i = 0, nTempNumInputPorts = 0;     /* Get the input and output group handles */     inputGroups = INFA_CTGetChildrenHandles(partition[0],                                             &nNumInputGroups,                                             INPUTGROUPTYPE);     outputGroups = INFA_CTGetChildrenHandles(partition[0],                                              &nNumOutputGroups,                                              OUTPUTGROUPTYPE);     /* 1. Number of input groups must be >= 2 and number of output groups must      *    be equal to one. */     if (nNumInputGroups < 1 || nNumOutputGroups != 1)     {         INFA_CTLogMessageM( eESL_ERROR,                             "UnionDemo: There must be at least two input groups "                             "and only one output group");         return INFA_FAILURE;     }     /* 2. Verify that the same number of ports are in each group (including      * output group). */     outputGroupPorts = INFA_CTGetChildrenHandles(outputGroups[0],                                                  &nNumPortsInOutputGroup,                                                  OUTPUTPORTTYPE);     /* Allocate an array for all input groups ports */     allInputGroupsPorts = malloc(sizeof(INFA_CT_INPUTPORT_HANDLE*) *                                  nNumInputGroups);     for (i = 0; i < nNumInputGroups; i++)     {         allInputGroupsPorts[i] = INFA_CTGetChildrenHandles(inputGroups[i],                                                            &nTempNumInputPorts,                                                            INPUTPORTTYPE);        if ( nNumPortsInOutputGroup != nTempNumInputPorts)        {            INFA_CTLogMessageM( eESL_ERROR,                                "UnionDemo: The number of ports in all input and "                                "the output group must be the same.");            return INFA_FAILURE;        }     }     free(allInputGroupsPorts);     /* 3. Datatypes of ports in input group 1 must match data types of all other      *    groups.     TODO:*/     return INFA_SUCCESS; }

Back to Top

0 COMMENTS

We’d like to hear from you!