Generating Routines - FastExport

Teradata FastExport Reference

Product
FastExport
Release Number
15.00
Language
English (United States)
Last Update
2018-09-28
dita:id
B035-2410
lifecycle
previous
Product Category
Teradata Tools and Utilities

Generating Routines

Three sample program files are provided with the FastExport utility software to help generate and use INMOD, OUTMOD and notify exit routines in the FastExport job scripts on network‑attached Windows client systems. The listings of these sample files are presented later in this appendix:

 

Sample File

Description

feimod.c

Source file for an INMOD routine

feomod.c

Source file for an OUTMOD routine

fenotf.c

Source file for a notify exit routine

Note: Though they are presented as Windows examples, the three sample files are valid for UNIX systems, when compiled and linked into a shared object file as indicated in the comment banner of each file.

To generate and use an INMOD, OUTMOD, or notify exit routine in a FastExport job

Refer to the referenced sample file listings and use this procedure for generating and using an INMOD, OUTMOD, or notify exit routine.

1 Edit the routine source file and ensure that the dynamn name is a _declspec

2 See the listing of the sample routine files later in this appendix:

  • feimod.c
  • feomod.c
  • fenotf.c
  • 3 Use the following command to create a DLL:

    cl /DWIN32 /LD sourcefilename

    where sourcefilename is the name of the INMOD, OUTMOD, or notify exit routine source file.

    Successful command execution produces a file with the same name as the source file with the .dll extension:

    sourcefilename.dll

    4 Use the sourcefilename.dll in the FastExport job script as follows:

     

    Routine Type

    Use the sourcefilename.dll File as

    INMOD

    INMOD modulename in the IMPORT command

    OUTMOD

    OUTMOD modulename in the EXPORT command

    Notify Exit

    EXIT name specification of the NOTIFY option in the BEGIN EXPORT command

    Sample INMOD Routine

    Following is the listing of the feimod.c sample INMOD routine that is provided with the FastExport utility software:

       
       #include <stdio.h>
       #include <stdlib.h>
       
       /**********************************************************************/
       /*                                                                    */
       /* feimod.c   - Sample Inmod for FastExport.                          */
       /*                                                                    */
       /* Purpose    - This inmod generates two integers per record.  The    */
       /*              first is even and the second number is odd.           */
       /*                                                                    */
       /* Note       - The number of records per file is determined by the   */
       /*              variable NUM_RECORDS                                  */
       /*                                                                    */
       /* Execute    - Build Inmod on a UNIX operating system                */
       /*                compile and link into shared object                 */
       /*                    cc -G feimod.c - o feimod.so                    */
       /*                                                                    */
       /*            - Build Inmod on a Win32 system                         */
       /*                compile and link into dynamic link library          */
       /*                    cl /DWIN32 /LD feimod.c                         */
       /*                                                                    */
    	/*  Copyright (C) 1996-2012 by Teradata Corporation.                  */
    	/*  All Rights Reserved.                                              */
    	/*  Teradata Corporation CONFIDENTIAL AND TRADE SECRET                */
    	/*                                                                    		*/
       /**********************************************************************/   
       
       static int msg_cnt = 0;
       
       typedef struct {
       long   ioseq;
       short  len;
       char   param[2000];
       } param_type;
       
       /* This structure is used to pass an odd and an even integer  */
       /* back to multiload                                          */
       
       typedef struct {
       long   code;
       long   len;
       char   data[32768];
       } data_type;
       
       #ifdef WIN32                                          /* Change for WIN32 */
       __declspec(dllexport) void _dynamn(data_type *data_buf , param_type    *parm_buf)
       #else
       void _dynamn(data_buf, parm_buf)
       data_type  *data_buf;
       param_type *parm_buf;
       #endif 
       {
       	char *myptr;
       	int  i;
       
       	static long RECNUM = 0;       /* number of records to load */
       	static int odd_counter = 0;  /* odd integer counter */
       	static int even_counter = 0; /* even integer counter */
       
       #ifdef DEBUG
       	printf("\n");
       	printf("jmod2: on input:\n");
       	printf("jmod2:    message code:   %d\n", data_buf->code);
       	printf("jmod2:      data bytes:   %d\n", data_buf->len);
       	if (data_buf->len)
       		printf("jmod2:            data:   *%s*\n", data_buf->data);
       	printf("jmod2:     param ioseq:   %d\n", parm_buf->ioseq);
       	printf("jmod2:     param bytes:   %d\n", parm_buf->len);
       	if (parm_buf->len)
       		printf("jmod2:       param str:   %s\n", parm_buf->param);
       	printf("jmod2:     message cnt:   %d\n", ++msg_cnt);
       #endif
       
       	switch (data_buf->code)
       	{
       	case 0: printf("jmod2: initializing and returning 1st record:\n");
       		RECNUM = 6;                     
       
       		printf("jmod2: Records requested = %ld\n", RECNUM);
       		if ( RECNUM <= 0 ) {
       			printf("jmod2: numbers of records is <= 0 [%ld]\n", RECNUM);
       		}
       
       		/* initialize the counters */
       		odd_counter = 1;
       		even_counter = 2;
       
       		/* copy the counters to the data buffer */
       		myptr = (char *) &odd_counter;
       		for (i=0; i<4; ++i, ++myptr) {
       			data_buf->data[i] = *myptr;
       		}
       
       		myptr = (char *) &even_counter;
       		for (i=4; i<8; ++i, ++myptr) {
       			data_buf->data[i] = *myptr;
       		}
       
       		/* go to next values and increment the counters */
       		odd_counter += 2;
       		even_counter +=2;
       		--RECNUM;
       		/* return  the results */
       		data_buf->code = 0;
       		data_buf->len  = 8;
       		break;
     
       	case 1: 
       #ifdef DEBUG
       		printf("jmod2: returning a record:\n");
       #endif
       		if (RECNUM) {
       
       			/* copy the counters to the data buffer */
       			myptr = (char *) &odd_counter;
       			for (i=0; i<4; ++i, ++myptr) {
       				data_buf->data[i] = *myptr;
       			}
       
       			myptr = (char *) &even_counter;
       			for (i=4; i<8; ++i, ++myptr) {
       				data_buf->data[i] = *myptr;
       			}
       
       			/* increment to next values and decrement record counter */
       			odd_counter  += 2;
       			even_counter += 2;
       			--RECNUM;
       
       			/* return  the results */
       			data_buf->code = 0;
       			data_buf->len  = 8;
       			break;
       
       		} else {
       
       			/* done sending records, return non-zero result */
       			printf("jmod2: all records sent\n");
       			data_buf->code = 1;
       			break;
       		}
       
       	 case 2: printf("jmod2: repositioning to last checkpoint (HOST)\n");
       		 data_buf->code = 0;
       		 data_buf->len  = 0;
       		 break;
       	 case 3: printf("jmod2: taking a checkpoint\n");
       		 data_buf->code = 0;
       		 data_buf->len  = 0;
       		 break;
       	 case 4: printf("jmod2: repositioning to last checkpoint (DBC)\n");
       		 data_buf->code = 0;
       		 data_buf->len  = 0;
       		 break;
       	 case 5: printf("jmod2: terminating:\n");
       		 data_buf->code = 0;
       		 data_buf->len  = 0;
       		 break;
       	 case 6: printf("jmod2: initializing and receiving 1st record:\n");
       		 data_buf->data[1] = ’%’;
       		 data_buf->code = 0;
       		 break;
       	 case 7: printf("jmod2: receiving a record:\n");
       		 data_buf->data[1] = ’%’;
       		 data_buf->code = 0;
       		 break;
            }
       
       #ifdef DEBUG
       	printf("jmod2: on output:\n");
       	printf("jmod2:    message code:   %d\n", data_buf->code);
       	printf("jmod2:      data bytes:   %d\n", data_buf->len);
       	if (data_buf->len)
       		printf("jmod2:            data:   *%s*\n", data_buf->data);
       	printf("\n");
       #endif
       }
       
       

    Sample OUTMOD Routine

    Following is the listing of the feomod.c sample OUTMOD routine that is provided with the FastExport utility software:

       
       #include <stdio.h>
       #include <stdlib.h>
       
       /**********************************************************************/
       /*                                                                    */
       /* feomod.c   - Sample Outmod for FastExport.                         */
       /*                                                                    */
       /* Purpose    - This outmod deletes the data passed to it.            */
       /*                                                                    */
       /* Execute    - Build Outmod on a UNIX operating system               */
       /*                compile and link into shared object                 */
       /*                    cc -G feomod.c - o feomod.so                    */
       /*                                                                    */
       /*            - Build Outmod on a Win32 system                        */
       /*                compile and link into dynamic link library          */
       /*                    cl /DWIN32 /LD feomod.c                         */
    	/*                                                                    		*/
    	/*  Copyright (C) 1996-2012 by Teradata Corporation.                  */
    	/*  All Rights Reserved.                                              */
    	/*  Teradata Corporation CONFIDENTIAL AND TRADE SECRET                */
    	/*                                                                    		*/
       /**********************************************************************/
        
       typedef unsigned short     Int16;
       typedef unsigned char      Int8;
       typedef unsigned long int  Int32;
       #ifdef WIN32                                         /* Change for WIN32 */
       __declspec(dllexport) Int32 _dynamn( int     *code,
                                            int     *stmno,
                                            int     *InLen,
                                            char    *InBuf,
                                            int     *OutLen,
                                            char    *OutBuf
                                      )
       #else
       Int32 _dynamn(code, stmno, InLen, InBuf, OutLen, OutBuf)
       int     *code;
       int     *stmno;
       int     *InLen;
       char    *InBuf;
       int     *OutLen;
       char    *OutBuf;
       #endif 
       
        
       {
       /* case on entry code
       */
       switch (*code) {
        
        case 1:  /* Initialization, no other values */
          printf ("OUTMOD Initial Entry\n"); 
          break;
        case 2:  /* Cleanup call, no other values */
          printf ("OUTMOD End of Responses Entry\n");
          break;
        case 3:  /* Process response record */
          *InLen=0;
          *OutLen=0;
          break;
        case 4:
          /* Checkpoint, no other values */
          printf ("OUTMOD Checkpoint Entry\n");
          break;
        case 5:
          /* DBC restart - close and reopen the output files */
          printf ("OUTMOD DBC Restart Entry\n");
          break;
        case 6:
          /* Host restart  */
          printf ("OUTMOD Host Restart Entry\n");
          break;
        default:
          printf ("OUTMOD Invalid Entry code\n");
          break;
        
         }
        return (0);
       }

    Sample Notify Exit Routine

    Following is the listing of the fenotf.c sample notify exit routine that is provided with the FastExport utility software:


    /**********************************************************************/
    /*                                                                    */
    /* fenotf.c  - Sample Notify Exit for FastExport.                     */
    /*                                                                    */
    /*  Copyright1996-2013 by Teradata Corporation.                       */
    /*  All Rights Reserved.                                              */
    /*  TERADATA CONFIDENTIAL AND TRADE SECRET                            */
    /*                                                                    */
    /* Purpose    - This is a sample notify exit for FastExport.          */
    /*                                                                    */
    /*                                                                    */
    /* Execute    - Build Notify on a Unix system                         */
    /*                compile and link into shared object                 */
    /*                    cc -G fenotf.c - o fenotf.so                    */
    /*                                                                    */
    /*            - Build Notify on a Win32 system                        */
    /*                compile and link into dynamic link library          */
    /*                    cl /DWIN32 /LD fenotf.c                         */
    /* History :  Updated with new events.                                */
    /*                                                                    */
    /* Revision    Date     JIRA     DID     Comments                     */
    /* ----------- -------- -------- ------- -----------------------------*/
    /* 15.00.00.00 03212013 SA-29980 NT185003 Support EXIT64 and EXITEON  */
    /* 15.00.00.00 03212013 SA-29928 NT185003 Change MAXUSERNAMELEN to 64 */
    /*                                                                    */
    /* Revision    Date     DR    DID      Comments                       */
    /* ----------  -------- ----- -------- -------------------------------*/
    /* 14.00.00.01 11012009 112036 SV185048 Added database name to notify */
    /* 13.01.00.00 04092009 124562 YY151001 FEXP w/o Spooling support     */
    /* 13.00.00.00 09102007 114415 NT185003 Teradata Corporation Copyright*/
    /* 07.07.00.02 06212004 68860 XX151000 Back out branding changes      */
    /* 07.07.00.01 01132004 68860 XX151000 Teradata Branding              */
    /*                                                                    */
    /**********************************************************************/
    #include <stdio.h>
    typedef unsigned long UInt32;
    #define NOTIFYID_FASTLOAD      1
    #define NOTIFYID_MULTILOAD     2
    #define NOTIFYID_FASTEXPORT    3
    #define NOTIFYID_BTEQ          4
    #define NOTIFYID_TPUMP         5
     
    #define MAXVERSIONIDLEN       32
    #define MAXUTILITYNAMELEN     32
    #define MAXUSERNAMELEN        64
    #define MAXUSERSTRLEN         80
    #define MAXFILENAMELEN       256
    #define MAXREQUESTLEN      32000
    #define MAXDBNAMELEN          62
     
    #define MAXUINT64             24
     
    typedef enum {
        NXEventInitialize     = 0,
        NXEventFileInmodOpen  = 1,
        NXEventDBSRestart     = 9,
        NXEventCLIError       = 10,
        NXEventDBSError       = 11,
        NXEventExit           = 12,
        NXEventExportBegin    = 31,
        NXEventReqSubmitBegin = 32,
        NXEventReqSubmitEnd   = 33,
        NXEventReqFetchBegin  = 34,
        NXEventFileOutmodOpen = 35,
        NXEventStmtFetchBegin = 36,
        NXEventStmtFetchEnd   = 37,
        NXEventReqFetchEnd    = 38,
        NXEventExportEnd      = 39,
        NXEventBlockCount     = 40,
        NXEventExportEnd64    = 41,
        NXEventInitializeEON  = 42,
        NXEventReqSubmitBeginEON  = 43,
        NXEventExportBeginEON     = 44
    } NfyExpEvent;
     
    typedef struct _FXNotifyExitParm {
       UInt32 Event;
       union {
          struct {
             UInt32 VersionLen;
             char   VersionId[MAXVERSIONIDLEN];
             UInt32 UtilityId;
             UInt32 UtilityNameLen;
             char   UtilityName[MAXUTILITYNAMELEN];
             UInt32 UserNameLen;
             char   UserName[MAXUSERNAMELEN];
             UInt32 UserStringLen;
             char   UserString[MAXUSERSTRLEN];
          }Initialize;
          struct {
             UInt32 VersionLen;
             char   VersionId[MAXVERSIONIDLEN];
             UInt32 UtilityId;
             UInt32 UtilityNameLen;
             char   UtilityName[MAXUTILITYNAMELEN];
             UInt32 UserNameLen;
             char   *UserName;
             UInt32 UserStringLen;
             char   UserString[MAXUSERSTRLEN];
          } InitializeEON;
          struct {
             UInt32 FileNameLen;
             char   FileOrInmodName[MAXFILENAMELEN];
             UInt32 dummy;
          } FileInmodOpen ;
          struct {
             UInt32 dummy;
          } DBSRestart;
          struct {
             UInt32 ErrorCode;
          } CLIError;
          struct {
             UInt32 ErrorCode;
          } DBSError;
          struct {
             UInt32 ReturnCode;
          } Exit;
          struct {
             UInt32 dummy;
             char DatabaseName[MAXDBNAMELEN];
          } ExportBegin;
          struct {
             UInt32 dummy;
             char *DatabaseName;
          } ExportBeginEON;
          struct {
             UInt32 RequestLen;
             char Request[MAXREQUESTLEN];
          } ReqSubmitBegin;
          struct {
             UInt32 RequestLen;
             char *Request;
          } ReqSubmitBeginEON;
          struct {
             UInt32 StatementCnt;
             UInt32 BlockCnt;
          } ReqSubmitEnd;
          struct {
             UInt32 dummy;
          } ReqFetchBegin;
          struct {
             UInt32 FileNameLen;
             char   FileOrOutmodName[MAXFILENAMELEN];
          } FileOutmodOpen;
          struct {
             UInt32 StatementNo;
             UInt32 BlockCnt;
          } StmtFetchBegin;
          struct {
             UInt32 Records;
          } StmtFetchEnd;
          struct {
             UInt32 RecsExported;
             UInt32 RecsRejected;
          } ReqFetchEnd;
          struct {
             UInt32 RecsExported;
             UInt32 RecsRejected;
          } ExportEnd;
          struct {
             char RecsExported[MAXUINT64];
             UInt32 RecsRejected;
          }ExportEnd64;
          struct {
             UInt32 BlockCount;
          } BlockCount;
       } Vals;
    } FXNotifyExitParm;
     
    extern long FXNotifyExit(
    #ifdef __STDC__
                             FXNotifyExitParm *Parms
    #endif
    );
     
    #ifdef WIN32
    __declspec(dllexport) long _dynamn(FXNotifyExitParm *P)
    #else
    long _dynamn( FXNotifyExitParm *P)
    #endif
    {
        FILE *fp;
     
        if (!(fp = fopen("NFYEXIT.OUT", "a")))
            return(1);
     
        switch(P->Event) {
        case NXEventInitialize :   /* Nothing */
            fprintf(fp, "exit called @ fexp init.\n");
            fprintf(fp, "Version: %s\n", P->Vals.Initialize.VersionId);
            fprintf(fp, "Utility: %s\n", P->Vals.Initialize.UtilityName);
            fprintf(fp, "User: %s\n", P->Vals.Initialize.UserName);
            if (P->Vals.Initialize.UserStringLen)
               fprintf(fp, "UserString: %s\n", P->Vals.Initialize.UserString);
            break;
     
        case NXEventInitializeEON :
            fprintf(fp, "exiteon called @ fexp init.\n");
            fprintf(fp, "Version: %s\n", P->Vals.InitializeEON.VersionId);
            fprintf(fp, "Utility: %s\n", P->Vals.InitializeEON.UtilityName);
            fprintf(fp, "User: %s\n", P->Vals.InitializeEON.UserName);
            if (P->Vals.InitializeEON.UserStringLen)
               fprintf(fp, "UserString: %s\n", P->Vals.InitializeEON.UserString);
            break;
     
        case NXEventFileInmodOpen:
            fprintf(fp, "exit called @ input file open: %s\n",
                    P->Vals.FileInmodOpen.FileOrInmodName);
            break;
     
        case NXEventDBSRestart :
            fprintf(fp, "exit called @ RDBMS restart detected\n");
            break;
     
        case NXEventCLIError :
            fprintf(fp, "exit called @ CLI error %d\n",
                    P->Vals.CLIError.ErrorCode);
            break;
     
        case NXEventDBSError :
            fprintf(fp, "exit called @ DBS error %d\n",
                    P->Vals.DBSError.ErrorCode);
            break;
     
        case NXEventExit :
            fprintf(fp,
               "exit called @ fexp notify out of scope: return code %d.\n",
                P->Vals.Exit.ReturnCode);
            break;
     
        case NXEventExportBegin :
            fprintf(fp, "exit called @ export beginning.\n");
            fprintf(fp, "exit called @ export beginning - Database Name : %s\n",P->V
    als.ExportBegin.DatabaseName);
            break;
     
        case NXEventExportBeginEON :
            fprintf(fp, "exiteon called @ export beginning.\n");
            fprintf(fp, "exit called @ export beginning - Database Name : %s\n",
                         P->Vals.ExportBeginEON.DatabaseName);
            break;
     
        case NXEventReqSubmitBegin :
            fprintf(fp, "exit called @ request submitted: '%s'.\n",
                P->Vals.ReqSubmitBegin.Request);
            break;
     
        case NXEventReqSubmitBeginEON :
            fprintf(fp, "exiteon called @ request submitted: '%s'.\n",
                P->Vals.ReqSubmitBeginEON.Request);
            break;
     
        case NXEventReqSubmitEnd :
            fprintf(fp, "exit called @ request done: %d statement(s), \
    %d blocks.\n",
                P->Vals.ReqSubmitEnd.StatementCnt,
                P->Vals.ReqSubmitEnd.BlockCnt);
            break;
     
        case NXEventReqFetchBegin :
            fprintf(fp, "exit called @ request fetch beginning.\n");
            break;
     
        case NXEventFileOutmodOpen:
            fprintf(fp, "exit called @ output file open: %s\n",
                    P->Vals.FileOutmodOpen.FileOrOutmodName);
            break;
     
        case NXEventStmtFetchBegin :
            fprintf(fp, "exit called @ statement fetch beginning: stmt #%d, \
    %d blocks.\n",
                P->Vals.StmtFetchBegin.StatementNo,
                P->Vals.StmtFetchBegin.BlockCnt);
            break;
     
        case NXEventStmtFetchEnd :
            fprintf(fp, "exit called @ statement fetch end: %d records.\n",
                P->Vals.StmtFetchEnd.Records);
            break;
     
        case NXEventReqFetchEnd :
            fprintf(fp, "exit called @ request fetch ends: \
    Records exported: %d, Records rejected: %d\n",
                P->Vals.ReqFetchEnd.RecsExported,
                P->Vals.ReqFetchEnd.RecsRejected);
            break;
     
        case NXEventExportEnd :
            fprintf(fp, "exit called @ export ends: \
    Records exported: %d, Records rejected: %d\n",
                P->Vals.ExportEnd.RecsExported,
                P->Vals.ExportEnd.RecsRejected);
            break;
     
        case NXEventExportEnd64 :
            fprintf(fp, "exit64 called @ export ends: \
    Records exported: %s, Records rejected: %d\n",
                P->Vals.ExportEnd64.RecsExported,
                P->Vals.ExportEnd64.RecsRejected);
            break;
     
        case NXEventBlockCount :
            fprintf(fp, "exit called @ request done in Nospool mode: %d \
    blocks.\n", P->Vals.BlockCount.BlockCount);
            break;
        }
        fclose(fp);
        return(0);
    }