/******************************************************************************
**
** Source File Name = impexp.sqc  1.4
**
** Licensed Materials - Property of IBM
**
** (C) COPYRIGHT International Business Machines Corp. 1995, 1999 
** All Rights Reserved.
**
** US Government Users Restricted Rights - Use, duplication or
** disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**
**    PURPOSE :
**       This program is an example of how APIs are implemented in order to
**       export and import tables and table data.  The order of the program
**       is as follows:
**          - export a table to a comma-delimited text file
**          - import the comma-delimited text file to a DB2 table
**       This program needs the embedded SQL calls in order to connect to
**       an existing database, then to create a temporary table to work with.
**
**    STRUCTURES USED :
**       sqldcol
**       sqlchar
**       sqluexpt_out
**       sqluimp_in
**       sqluimp_out
**       sqlca
**
**    APIs USED :
**            IMPORT TO             sqluimpr
**            EXPORT                sqluexpr
**
**    FUNCTIONS DECLARED :
**       'C' COMPILER LIBRARY :
**          stdio.h  -  printf
**          string.h -  fgets, strncpy
**
**       DBMS LIBRARY :
**          sqlenv.h -  see "APIs USED" above
**
**       OTHER :
**          internal :
**             list_dcs :         Displays a directory of databases
**
**          external :
**             check_error :     Checks for SQLCODE error, and prints out any
**             [in util.c]       related information available.
**
**    EXTERNAL DEPENDANCIES :
**       - Ensure existence of database (SAMPLE) for precompile purposes.
**       - Precompile with the SQL precompiler (PREP in DB2)
**       - Bind to a database (BIND in DB2)
**       - Compile and link with the IBM Cset++ compiler (AIX and OS/2)
**         or the Microsoft Visual C++ compiler (Windows) 
**         or the compiler supported on your platform.
**
** For more information about these samples see the README file.
**
** For more information on programming in C, see the:
**   -  "Programming in C and C++" section of the Application Development Guide
** For more information on Building C Applications, see the:
**   -  "Building C Applications" section of the Application Building Guide.
**
** For more information on the SQL language see the SQL Reference.
**
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlenv.h>
#include <sqlutil.h>
#ifndef DB2MAC
#include <malloc.h>
#endif
#include "util.h"

#ifdef DB268K
/* Need to include ASLM for 68K applications */
#include <LibraryManager.h>
#endif

#define  CHECKERR(CE_STR)   if (check_error (CE_STR, &sqlca) != 0) return 1;

EXEC SQL INCLUDE SQLCA;
int main (int argc, char *argv[]) {
   short int            callerAction = 0;
   struct sqldcol       columnData;
   struct sqlchar       *columnStringPointer;
   struct sqluexpt_out  outputInfo;
   struct sqluimpt_in   impInput;
   struct sqluimpt_out  impOutput;

   char        datafile[] = "EXPTABLE.DEL";
   char        statement[] = "select name, id from staff";
   char        impStatement[] = "insert into imptable (name, id)";
   char        msgfile_x[] = "EXPMSG.TXT";
   char        msgfile_m[] = "IMPMSG.TXT";
   char        fileFormat[] = "DEL";

   EXEC SQL BEGIN DECLARE SECTION;
      char userid[9];
      char passwd[19];
   EXEC SQL END DECLARE SECTION;

#ifdef DB268K
   /* Before making any API calls for 68K environment,
      need to initial the Library Manager */
	InitLibraryManager(0,kCurrentZone,kNormalMemory);
	atexit(CleanupLibraryManager);
#endif
   
   /* need to preset the size of structure field and counts */
   outputInfo.sizeOfStruct = SQLUEXPT_OUT_SIZE;
   impInput.sizeOfStruct = SQLUIMPT_IN_SIZE;
   impOutput.sizeOfStruct = SQLUIMPT_OUT_SIZE;
   impInput.restartcnt = impInput.commitcnt = 0;

   /******************************************************************\
   * need to allocate the proper amount of space for the SQL statment *
   \******************************************************************/
   columnStringPointer = (struct sqlchar *)malloc(strlen(statement)
      + sizeof (struct sqlchar));
   columnStringPointer->length = strlen(statement);
   strncpy (columnStringPointer->data, statement, strlen(statement));
   /* DELimited format can not have specified names, therefore the
      column method is 'D'efault */
   columnData.dcolmeth = 'D';

   if (argc == 1) {
      EXEC SQL CONNECT TO sample;
	  CHECKERR ("CONNECT TO SAMPLE");
   }
   else if (argc == 3) { 
      strcpy (userid, argv[1]);
      strcpy (passwd, argv[2]);
      EXEC SQL CONNECT TO sample USER :userid USING :passwd;
      CHECKERR ("CONNECT TO SAMPLE");
   }
   else {
      printf ("\nUSAGE: impexp [userid passwd]\n\n");
      return 1;
   } /* endif */
   
   printf ("exporting NAME and ID from STAFF table into file '%s'\n", datafile);
   /*******************\
   * EXPORT API called *
   \*******************/
   sqluexpr (datafile, NULL, NULL, &columnData, columnStringPointer,
      fileFormat, NULL, msgfile_x, 0, &outputInfo, NULL, &sqlca);
   CHECKERR ("exporting table");
   printf ("rows exported %d\n", outputInfo.rowsExported);
   free (columnStringPointer);

   /******************************************************************\
   * need to allocate the proper amount of space for the SQL statment *
   \******************************************************************/
   columnStringPointer = (struct sqlchar *)malloc(strlen(impStatement)
      + sizeof (struct sqlchar));
   columnStringPointer->length = strlen(impStatement);
   strncpy (columnStringPointer->data, impStatement, strlen(impStatement));
   
   printf ("creating a temporary table 'imptable' to import into\n");
   /* create a temporary table to import into */
   EXEC SQL CREATE TABLE imptable (name VARCHAR(15), id INT);
   CHECKERR ("CREATE TABLE");

   printf ("importing the file '%s' into the 'imptable'\n", datafile);
   /*******************\
   * IMPORT API called *
   \*******************/
   sqluimpr (datafile, NULL, &columnData, columnStringPointer, fileFormat,
      NULL, msgfile_m, 0, &impInput, &impOutput, NULL, NULL, &sqlca);
   CHECKERR ("importing table");
   printf ("rows imported %d\nnumber of rows committed %d\n",
      impOutput.rowsInserted, impOutput.rowsCommitted);

   free (columnStringPointer);

   /* drop the table  */
   EXEC SQL DROP TABLE imptable;
   CHECKERR ("DROP TABLE");
   
   EXEC SQL CONNECT RESET;
   CHECKERR ("CONNECT RESET");
}
/* end of program : impexp.sqc */