Generating Routines - FastExport

Teradata® FastExport Reference

Product
FastExport
Release Number
16.20
Published
September 2020
Language
English (United States)
Last Update
2020-09-11
dita:mapPath
lki1527114222329.ditamap
dita:ditavalPath
obe1474387269547.ditaval
dita:id
B035-2410
lifecycle
previous
Product Category
Teradata Tools and Utilities

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 following sample files are provided in this section:

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
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.

Generating and using 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 section:
    • 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.dllFile as
    INMOD INMOD modulename in the IMPORT command
    OUTMOD OUTMOD modulenamein the EXPORT command
    Notify Exit EXIT namespecification 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.                          */
/*                                                                    */
/*  Copyright1996-2007, 2016 by Teradata Corporation.                 */
/*  All Rights Reserved.                                              */
/*  TERADATA CONFIDENTIAL AND TRADE SECRET                            */
/*                                                                    */
/* 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 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                         */
/*                                                                    */
/**********************************************************************/

static int msg_cnt = 0;
                                                                               
typedef struct {
int    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 {
int    code;
int    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 int 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.                         */
/*                                                                    */
/*  Copyright1996-2007, 2016 by Teradata Corporation.                 */
/*  All Rights Reserved.                                              */
/*  TERADATA CONFIDENTIAL AND TRADE SECRET                            */
/*                                                                    */
/* Purpose    - This outmod deletes the data passed to it.            */
/*                                                                    */
/* Execute    - Build Outmod on a Unix 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                         */
/*                                                                    */
/*                                                                    */
/**********************************************************************/

typedef unsigned short     Int16;
typedef unsigned char      Int8;
typedef unsigned int       UInt32;
                                                                
#ifdef WIN32                                         /* Change for WIN32 */
__declspec(dllexport) UInt32 _dynamn( int     *code,
                                     int     *stmno,
                                     int     *InLen,
                                     char    *InBuf,
                                     int     *OutLen,
                                     char    *OutBuf
                                   )
								   
#else
UInt32 _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, 2016 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                         */
/*                                                                    */
/**********************************************************************/
#include <stdio.h>
typedef unsigned int UInt32;
typedef int Int32;
#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 Int32 FXNotifyExit(
#ifdef __STDC__
                         FXNotifyExitParm *Parms
#endif
);                                                                                                
#ifdef WIN32
__declspec(dllexport) Int32 _dynamn(FXNotifyExitParm *P)
#else
Int32 _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->Vals.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);
}