Sample Notify Exit Routine
Following is the listing of the mlnotf.c sample notify exit routine that is provided with Teradata MultiLoad software:
/**********************************************************************/
/* */
/* mlnotf.c - Sample Notify Exit for MulitLoad. */
/* */
/* Copyright 1998-2014 by Teradata Corporation. */
/* ALL RIGHTS RESERVED. */
/* TERADATA CONFIDENTIAL AND TRADE SECRET */
/* */
/* Purpose - This is a sample notify exit for MultiLoad. */
/* */
/* Execute - Build Notify on a Unix system */
/* compile and link into shared object */
/* cc -G mlnotf.c -o mlnotf.so */
/* */
/* - Build Notify on a Win32 system */
/* compile and link into dynamic link library */
/* cl /DWIN32 /LD mlnotf.c */
/* */
/**********************************************************************/
#include <stdio.h>
typedef unsigned long UInt32;
typedef enum {
NMEventInitialize = 0,
NMEventFileInmodOpen = 1,
NMEventPhaseIBegin = 2,
NMEventCheckPoint = 3,
NMEventPhaseIEnd = 4,
NMEventPhaseIIBegin = 5,
NMEventPhaseIIEnd = 6,
NMEventErrorTableI = 7,
NMEventErrorTableII = 8,
NMEventDBSRestart = 9,
NMEventCLIError = 10,
NMEventDBSError = 11,
NMEventExit = 12,
NMEventAmpsDown = 21,
NMEventImportBegin = 22,
NMEventImportEnd = 23,
NMEventDeleteInit = 24,
NMEventDeleteBegin = 25,
NMEventDeleteEnd = 26,
NMEventDeleteExit = 27,
NMEventPhaseIEnd64 = 28,
NMEventImportEnd64 = 29,
NMEventInitializeEON = 30,
NMEventPhaseIBeginEON = 31,
NMEventCheckPoint64 = 32,
NMEventPhaseIIEnd64 = 33,
NMEventErrorTableI64 = 34,
NMEventErrorTableII64 = 35,
NMEventDeleteInitEON = 36,
NMEventDeleteBeginEON = 37,
NMEventDeleteEnd64 = 38
} NfyMLDEvent;
#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 MAXTABLENAMELEN 128
#define MAXFILENAMELEN 256
#define MAXDBASENAMELEN 62
#define MAXUINT64LEN 24
typedef struct _MLNotifyExitParm {
UInt32 Event; /* should be NfyMLDEvent values */
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 FileNameLen;
char FileOrInmodName[MAXFILENAMELEN];
UInt32 ImportNo;
} FileInmodOpen ;
struct {
UInt32 TableNameLen;
char TableName[MAXTABLENAMELEN];
UInt32 TableNo;
char DBaseName[MAXDBASENAMELEN];
} PhaseIBegin;
struct {
UInt32 RecordCount;
} CheckPoint;
struct {
UInt32 RecsRead;
UInt32 RecsSkipped;
UInt32 RecsRejected;
UInt32 RecsSent;
} PhaseIEnd ;
struct {
UInt32 dummy;
} PhaseIIBegin;
struct {
UInt32 Inserts;
UInt32 Updates;
UInt32 Deletes;
UInt32 TableNo;
} PhaseIIEnd;
struct {
UInt32 Rows;
UInt32 TableNo;
} ErrorTableI;
struct {
UInt32 Rows;
UInt32 TableNo;
} ErrorTableII ;
struct {
UInt32 dummy;
} DBSRestart;
struct {
UInt32 ErrorCode;
} CLIError;
struct {
UInt32 ErrorCode;
} DBSError;
struct {
UInt32 ReturnCode;
} Exit;
struct {
UInt32 dummy;
} AmpsDown;
struct {
UInt32 ImportNo;
} ImportBegin ;
struct {
UInt32 RecsRead;
UInt32 RecsSkipped;
UInt32 RecsRejected;
UInt32 RecsSent;
UInt32 ImportNo;
} ImportEnd ;
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char UserName[MAXUSERNAMELEN];
UInt32 UserStringLen;
char UserString[MAXUSERSTRLEN];
} DeleteInit;
struct {
UInt32 TableNameLen;
char TableName[MAXTABLENAMELEN];
UInt32 TableNo;
char DBaseName[MAXDBASENAMELEN];
} DeleteBegin;
struct {
UInt32 Deletes;
UInt32 TableNo;
} DeleteEnd;
struct {
UInt32 ReturnCode;
} DeleteExit;
struct {
char RecsRead[MAXUINT64LEN];
char RecsSkipped[MAXUINT64LEN];
char RecsRejected[MAXUINT64LEN];
char RecsSent[MAXUINT64LEN];
} PhaseIEnd64 ;
struct {
char RecsRead[MAXUINT64LEN];
char RecsSkipped[MAXUINT64LEN];
char RecsRejected[MAXUINT64LEN];
char RecsSent[MAXUINT64LEN];
UInt32 ImportNo;
} ImportEnd64 ;
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char *UserName;
UInt32 UserStringLen;
char *UserString;
} InitializeEON;
struct {
UInt32 TableNameLen;
char *TableName;
UInt32 TableNo;
char *DBaseName;
} PhaseIBeginEON;
struct {
char RecordCount[MAXUINT64LEN];
} CheckPoint64;
struct {
char Inserts[MAXUINT64LEN];
char Updates[MAXUINT64LEN];
char Deletes[MAXUINT64LEN];
UInt32 TableNo;
} PhaseIIEnd64;
struct {
char Rows[MAXUINT64LEN];
UInt32 TableNo;
} ErrorTableI64;
struct {
char Rows[MAXUINT64LEN];
UInt32 TableNo;
} ErrorTableII64 ;
struct {
UInt32 VersionLen;
char VersionId[MAXVERSIONIDLEN];
UInt32 UtilityId;
UInt32 UtilityNameLen;
char UtilityName[MAXUTILITYNAMELEN];
UInt32 UserNameLen;
char *UserName;
UInt32 UserStringLen;
char *UserString;
} DeleteInitEON;
struct {
UInt32 TableNameLen;
char *TableName;
UInt32 TableNo;
char *DBaseName;
} DeleteBeginEON;
struct {
char Deletes[MAXUINT64LEN];
UInt32 TableNo;
} DeleteEnd64;
} Vals;
} MLNotifyExitParm;
#ifdef I370
#define MLNfyExit MLNfEx
#endif
extern long MLNfyExit(
#ifdef __STDC__
MLNotifyExitParm *Parms
#endif
);
#ifdef WIN32
__declspec(dllexport) long _dynamn(MLNotifyExitParm *P)
#else
long _dynamn( MLNotifyExitParm *P)
#endif
{
FILE *fp;
if (!(fp = fopen("NFYEXIT.OUT", "a")))
return(1);
switch(P->Event) {
case NMEventInitialize :
fprintf(fp, "exit called @ mload 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 NMEventFileInmodOpen:
fprintf(fp, "exit called @ file open: import[%d]: %s\n",
P->Vals.FileInmodOpen.ImportNo,
P->Vals.FileInmodOpen.FileOrInmodName);
break;
case NMEventPhaseIBegin :
fprintf(fp, "exit called @ acquistion start: Database Name : %s.\n",
P->Vals.PhaseIBegin.DBaseName); /* RFC 112037 */
fprintf(fp, "exit called @ acquistion start: tablename[%d] : %s.\n",
P->Vals.PhaseIBegin.TableNo,
P->Vals.PhaseIBegin.TableName);
break;
case NMEventCheckPoint :
fprintf(fp, "exit called @ checkpoint : %d records loaded.\n",
P->Vals.CheckPoint.RecordCount);
break;
case NMEventPhaseIEnd :
fprintf(fp, "exit called @ acquistion end.\n");
fprintf(fp, "Records Read: %d\n", P->Vals.PhaseIEnd.RecsRead);
fprintf(fp, "Records Skipped: %d\n", P->Vals.PhaseIEnd.RecsSkipped);
fprintf(fp, "Records Rejected: %d\n", P->Vals.PhaseIEnd.RecsRejected);
fprintf(fp, "Records Sent: %d\n", P->Vals.PhaseIEnd.RecsSent);
break;
case NMEventPhaseIIBegin :
fprintf(fp, "exit called @ application start\n");
break;
case NMEventPhaseIIEnd :
fprintf(fp, "exit called @ application complete for table %d.\n",
P->Vals.PhaseIIEnd.TableNo);
fprintf(fp, "%d updates, %d inserts, %d deletes\n",
P->Vals.PhaseIIEnd.Updates,
P->Vals.PhaseIIEnd.Inserts,
P->Vals.PhaseIIEnd.Deletes);
break;
case NMEventErrorTableI :
fprintf(fp,
"exit called @ ET Table[%d] Drop : %d records in table.\n",
P->Vals.ErrorTableI.TableNo, P->Vals.ErrorTableI.Rows);
break;
case NMEventErrorTableII :
fprintf(fp,
"exit called @ UV Table[%d] Drop : %d records in table.\n",
P->Vals.ErrorTableII.TableNo, P->Vals.ErrorTableII.Rows);
break;
case NMEventDBSRestart :
fprintf(fp, "exit called @ RDBMS restarted\n");
break;
case NMEventCLIError :
fprintf(fp, "exit called @ CLI error %d\n",
P->Vals.CLIError.ErrorCode);
break;
case NMEventDBSError :
fprintf(fp, "exit called @ DBS error %d\n",
P->Vals.DBSError.ErrorCode);
break;
case NMEventExit :
fprintf(fp, "exit called @ mload notify out of scope: return code %d.\n",
P->Vals.Exit.ReturnCode);
break;
case NMEventAmpsDown :
fprintf(fp, "exit called @ down amps have been detected\n");
break;
case NMEventImportBegin :
fprintf(fp, "exit called @ import %d starting\n",
P->Vals.ImportBegin.ImportNo);
break;
case NMEventImportEnd :
fprintf(fp, "exit called @ import %d ending.\n",
P->Vals.ImportEnd.ImportNo);
fprintf(fp, "Records Read: %d\n", P->Vals.ImportEnd.RecsRead);
fprintf(fp, "Records Skipped: %d\n", P->Vals.ImportEnd.RecsSkipped);
fprintf(fp, "Records Rejected: %d\n", P->Vals.ImportEnd.RecsRejected);
fprintf(fp, "Records Sent: %d\n", P->Vals.ImportEnd.RecsSent);
break;
case NMEventDeleteInit :
fprintf(fp, "exit called @ mload delete init.\n");
fprintf(fp, "Version: %s\n", P->Vals.DeleteInit.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.DeleteInit.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.DeleteInit.UserName);
if (P->Vals.DeleteInit.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.DeleteInit.UserString);
break;
case NMEventDeleteBegin :
fprintf(fp, "exit called @ delete app start: Databasename : %s.\n",
P->Vals.DeleteBegin.DBaseName);
fprintf(fp, "exit called @ delete app start for table[%d]: %s.\n",
P->Vals.DeleteBegin.TableNo, P->Vals.DeleteBegin.TableName);
break;
case NMEventDeleteEnd :
fprintf(fp, "exit called @ delete app done for table[%d]: %d rows.\n",
P->Vals.DeleteEnd.TableNo, P->Vals.DeleteEnd.Deletes);
break;
case NMEventDeleteExit :
fprintf(fp, "exit called @ mload delete notify out of scope: return code %d.\n",
P->Vals.DeleteExit.ReturnCode);
break;
case NMEventInitializeEON : /* Nothing */
fprintf(fp, "exit called @ mload 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 NMEventPhaseIBeginEON :
fprintf(fp, "exit called @ acquistion start: Databasename : %s.\n",
P->Vals.PhaseIBeginEON.DBaseName);
fprintf(fp, "exit called @ acquistion start: tablename[%d] : %s.\n",
P->Vals.PhaseIBeginEON.TableNo,
P->Vals.PhaseIBeginEON.TableName);
break;
case NMEventCheckPoint64 :
fprintf(fp, "exit called @ checkpoint : %s records loaded.\n",
P->Vals.CheckPoint64.RecordCount);
break;
case NMEventPhaseIEnd64 :
fprintf(fp, "exit called @ acquistion end.\n");
fprintf(fp, "Records Read: %s\n", P->Vals.PhaseIEnd64.RecsRead);
fprintf(fp, "Records Skipped: %s\n", P->Vals.PhaseIEnd64.RecsSkipped);
fprintf(fp, "Records Rejected: %s\n", P->Vals.PhaseIEnd64.RecsRejected);
fprintf(fp, "Records Sent: %s\n", P->Vals.PhaseIEnd64.RecsSent);
break;
case NMEventPhaseIIEnd64 :
fprintf(fp, "exit called @ application complete for table %d.\n",
P->Vals.PhaseIIEnd64.TableNo);
fprintf(fp, "%s updates, %s inserts, %s deletes\n",
P->Vals.PhaseIIEnd64.Updates,
P->Vals.PhaseIIEnd64.Inserts,
P->Vals.PhaseIIEnd64.Deletes);
break;
case NMEventErrorTableI64 :
fprintf(fp,
"exit called @ ET Table[%d] Drop : %s records in table.\n",
P->Vals.ErrorTableI64.TableNo, P->Vals.ErrorTableI64.Rows);
break;
case NMEventErrorTableII64 :
fprintf(fp,
"exit called @ UV Table[%d] Drop : %s records in table.\n",
P->Vals.ErrorTableII64.TableNo, P->Vals.ErrorTableII64.Rows);
break;
case NMEventImportEnd64 :
fprintf(fp, "exit called @ import %d ending.\n",
P->Vals.ImportEnd64.ImportNo);
fprintf(fp, "Records Read: %s\n", P->Vals.ImportEnd64.RecsRead);
fprintf(fp, "Records Skipped: %s\n", P->Vals.ImportEnd64.RecsSkipped);
fprintf(fp, "Records Rejected: %s\n", P->Vals.ImportEnd64.RecsRejected);
fprintf(fp, "Records Sent: %s\n", P->Vals.ImportEnd64.RecsSent);
break;
case NMEventDeleteInitEON :
fprintf(fp, "exit called @ mload delete init.\n");
fprintf(fp, "Version: %s\n", P->Vals.DeleteInitEON.VersionId);
fprintf(fp, "Utility: %s\n", P->Vals.DeleteInitEON.UtilityName);
fprintf(fp, "User: %s\n", P->Vals.DeleteInitEON.UserName);
if (P->Vals.DeleteInitEON.UserStringLen)
fprintf(fp, "UserString: %s\n", P->Vals.DeleteInitEON.UserString);
break;
case NMEventDeleteBeginEON :
fprintf(fp, "exit called @ delete app start: Databasename : %s.\n",
P->Vals.DeleteBeginEON.DBaseName);
fprintf(fp, "exit called @ delete app start for table[%d]: %s.\n",
P->Vals.DeleteBeginEON.TableNo, P->Vals.DeleteBeginEON.TableName);
break;
case NMEventDeleteEnd64 :
fprintf(fp, "exit called @ delete app done for table[%d]: %s rows.\n",
P->Vals.DeleteEnd64.TableNo, P->Vals.DeleteEnd64.Deletes);
break;
}
fclose(fp);
return(0);
}