UNIX OS | BLKEXITR.C Sample INMOD | Teradata FastLoad - 17.10 - BLKEXITR.C Sample INMOD - FastLoad

Teradata® FastLoad Reference

Product
FastLoad
Release Number
17.10
Published
June 2021
Last Update
2021-07-01
Content Type
Programming Reference
Publication ID
B035-2411-061K
Language
English (United States)

Following is the listing of the BLKEXITR.C sample INMOD routine that is provided with the Teradata FastLoad utility software:

/*************************************************************************
*
* Title: BLKEXITR  -  sample INMOD routine
*
* 	Copyright (C) 2005-2014 by Teradata Corporation.                 
*  All Rights Reserved.
*  Teradata Corporation CONFIDENTIAL AND TRADE SECRET                
*
* This copyrighted material is the Confidential, Unpublished
* Property of the Teradata Corporation.  This copyright notice and
* any other copyright notices included in machine readable
* copies must be reproduced on all authorized copies.
*
*
* Description  This file contains a sample INMOD, written in C.
*              This file supports DBS restarts.
*
*
* History Information
*
* Revision    Date     DCR   DID     Comments
* ----------- -------- ----- ------- ---------------------------------------
* 13.00.00.01 09072007 114414 NT185003 Teradata Corporation Copyright
* 13.00.00.00 09012007 100894 SV185048 Visual Studio 8.0 build
* 07.07.00.01 06/23/05 96206 CSG     Port to HPUX-11.23 on Itanium
* 07.01.00.01 11/12/98 44120 SF3     Release for FastLoad 7.1
* 06.00.00.00 07/18/96 34208 SF3     Release for FastLoad 6.0
*
*
* How to build this INMOD on a UNIX operating system:
*
*    Compile and link it into a shared object:
*
*       cc -G -KPIC <inmod-name>.c -o <shared-object-name>
*
*
* How to use this program:
*
*   This INMOD routine will generate 2 columns of data:
*
*      4-byte integer counter for the Unique Primary Index
*      10-byte character string
*
* This sample INMOD will generate 100,000 rows, if no RECORD
* statement is used in the FastLoad job script.
*
* A sample of the job script for this INMOD would be as follows:
*
*
* use your own system, account and password here.
*
LOGON tdpid/user,password;

DROP TABLE Error_1;
DROP TABLE Error_2;
DROP TABLE TestTable;

CREATE TABLE TestTable AS (
   Counter Integer,
   text    char(10) )
UNIQUE PRIMARY INDEX(Counter);

BEGIN LOADING TestTable ErrorFiles Error_1, Error_2;

DEFINE
   Counter (Integer),
   text    (char(10))
INMOD=<shared-object-name>;

INSERT INTO TestTable
   (Counter, text)

VALUES
   (:Counter, :text);

END LOADING;
LOGOFF;

*************************************************************************/

#include <stdio.h>
#include <string.h>

#define FILEOF     401
#define EM_OK      0

#define NUMROWS    100000
#define ROWSIZE    64000

typedef int Int32; /* */
typedef unsigned int UInt32; /* */
typedef short Int16;

typedef struct inmod_struct {
   Int32 ReturnCode;
   Int32 Length;
   char  Body[ROWSIZE];
} inmdtyp,*inmdptr;

inmdptr inmodptr;

char *str = "123test890";
char *fname = "chkpoint.dat";

FILE *fp = NULL;

Int32 reccnt = 0;
Int32 chkpnt;

/*************************************************************************
*
* MakeRecord - Generate a record
*
*    This module creates the data record
*
*    In this example, we are just generating dummy records
*    with canned data, only we change the first column,
*    essentially a record number, so that each row is unique.
*
*************************************************************************/
Int32 MakeRecord()
{
   char *p;

   /* have we reached EOF yet? */

   if (reccnt >= NUMROWS)
      return(FILEOF);

   /* nope. get start of buffer */

   p = inmodptr->Body;

   /* place column 1, a unique primary index */

   memcpy(p, &reccnt, (UInt32)sizeof(reccnt));
   p += sizeof(reccnt);

   /* place column 2, a string */

   memcpy(p, str, strlen(str));
   p += strlen(str);

   inmodptr->ReturnCode = 0;
   inmodptr->Length = p - inmodptr->Body;

   reccnt++;

   return(EM_OK);
}

/*************************************************************************
*
* HostRestart - Host restarted
*
*    Retrieve the checkpoint information from the checkpoint file.
*    Reset record counter to checkpoint value
*
*************************************************************************/
Int32 HostRestart()
{
   Int32 result;

   /* see if the file is already open */

   if (!fp) {
      fp = fopen(fname, "r+");
      if (!fp)
         return(!EM_OK);
   }

   rewind(fp);
   result = fread(&chkpnt, sizeof(chkpnt), 1, fp);
   if (result != 1) {
      fprintf(stderr, "INMOD: ERROR READING CHECKPOINT FILE\n");
      fprintf(stderr, "INMOD: %d ELEMENTS WERE READ\n", result);
      perror("INMOD");
      return(!EM_OK);
   }

   fprintf(stderr, "INMOD: HOST RESTARTED. CHECKPOINT: %d\n", chkpnt);

   reccnt = chkpnt;

   return(EM_OK);
}

/*************************************************************************
*
* CheckPoint - Save checkpoint
*
*************************************************************************/
Int32 CheckPoint()
{
   Int32 result;

   chkpnt = reccnt;

   rewind(fp);
   result = fwrite(&chkpnt, sizeof(chkpnt), 1, fp);
   if (result != 1) {
      fprintf(stderr, "INMOD: ERROR WRITING TO CHECKPOINT FILE\n");
      fprintf(stderr, "INMOD: %d ELEMENTS WERE WRITTEN\n", result);
      perror("INMOD");
      return(!EM_OK);
   }

   fprintf(stderr, "INMOD: CHECKPOINT AT ROW: %d\n", chkpnt);

   return(EM_OK);
}

/*************************************************************************
*
* DBSRestart - DBS restarted
*
*    Retrieve the checkpoint information from the checkpoint file.
*    Reset record counter to checkpoint value
*
*************************************************************************/
Int32 DBSRestart()
{
   Int32 result;

   /* see if the file is already open */

   if (!fp) {
      fp = fopen(fname, "r+");
      if (!fp)
         return(!EM_OK);
   }

   rewind(fp);
   result = fread(&chkpnt, sizeof(chkpnt), 1, fp);
   if (result != 1) {
      fprintf(stderr, "INMOD: ERROR READING CHECKPOINT FILE\n");
      fprintf(stderr, "INMOD: %d ELEMENTS WERE READ\n", result);
      perror("INMOD");
      return(!EM_OK);
   }

   fprintf(stderr, "INMOD: DBS RESTARTED. CHECKPOINT: %d\n", chkpnt);

   reccnt = chkpnt;

   return(EM_OK);
}

/*************************************************************************
*
* CleanUp - Do cleanup.
*
*    Here we close the file and then remove it.
*
*************************************************************************/
Int32 CleanUp()
{
   fclose(fp);
   remove(fname);
   return(EM_OK);
}

/*************************************************************************
*
* InvalidCode - Invalid INMOD code returned.
*
*************************************************************************/
Int32 InvalidCode()
{
   fprintf(stderr, "**** Invalid code received by INMOD\n");
   return(EM_OK);
}

/*************************************************************************
*
* Init - initialize some stuff
*
*    Do any initialization necessary
*
*    For this example, we will open a disk file to hold
*    the checkpoint information. For this example, we
*    will just store the row number. If this INMOD was
*    reading data from a file, then the file position
*    would need to be stored.
*
*************************************************************************/
Int32 Init()
{
   fp = fopen(fname, "w");
   if (!fp)
      return(!EM_OK);

   return(EM_OK);
}

/*************************************************************************
*
* BLKEXIT - Start processing
*
*    This is the main module which contains the checks for
*    number of records generated and buffer filling.  This
*    module also sends the filled buffer to the DBS.
*
*************************************************************************/
#if defined WIN32
__declspec(dllexport) Int32 BLKEXIT(tblptr)
#elif defined I370
Int32 _dynamn(tblptr)
#else
Int32 BLKEXIT(tblptr)
#endif
char *tblptr;
{
   Int32 result;

   inmodptr = (struct inmod_struct *)tblptr;

   /* process the function passed to the INMOD */

   switch (inmodptr->ReturnCode) {
      case 0:  result = Init();
               if (result)
                  break;
               result = MakeRecord();
               break;
      case 1:  result = MakeRecord();
               break;
      case 2:  result = HostRestart();
               break;
      case 3:  result = CheckPoint();
               break;
      case 4:  result = DBSRestart();
               break;
      case 5:  result = CleanUp();
               break;
      default: result = InvalidCode();
   }

   /* see if we have reached EOF condition */

   if (result == FILEOF) {
      inmodptr->Length = 0;
      result = EM_OK;
   }

   return(result);
}