/******************************************************************************
**
** Source File Name = expsamp.sqc  1.5
**
** 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 to a DRDA database.
**       The order of the program is as follows:
**          - export a table to an IXF file format
**          - import the IXF file to a DB2 DRDA database 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.
**
**       For DRDA database imports, the data file format MUST be of the IXF
**       form.  The IMPORT command must be issued an "INSERT" statement.
**
**    EXTERNAL DEPENDENCIES :
**       - Ensure existence of database 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.
**
*****************************************************************************
** !!!!! NOTE !!!!!
** the proper node and database need to be available in order for this to
** work with a DRDA datbase.
** However, if you wish to EXPORT and IMPORT between the SAMPLE database
** and some other database, that already exists, this program will work
** appropriately.
*****************************************************************************
**
**    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 "xlc" compiler.
**
*******************************************************************************/
#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;
#define  STMTLEN 80

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[] = "EXPTABL1.IXF";
   char datafile2[] = "EXPTABL2.IXF";
   char statement[STMTLEN] = "select * from staff";
   char impStatement[STMTLEN] = "create into impstaff";
   char statement2[STMTLEN] = "select * from org";
   char impStatement2[STMTLEN] = "create into imporg";
   char msgfile_x[] = "EXPMSG.TXT";
   char msgfile_m[] = "IMPMSG.TXT";
   char fileFormat[] = "IXF";

   EXEC SQL BEGIN DECLARE SECTION;
      char username[9];
      char passwd[19];
      char database[9];
      char sqlStatement[256];
   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

   if (argc < 6) {
      printf ("\nUSAGE: expsamp username passwd DRDA_database DRDA_username "
	 "DRDA_passwd\n\n");
      return 1;
   }

   /* 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(STMTLEN
      + sizeof (struct sqlchar));

   /* DELimited format can not have specified names, therefore the
      column method is 'D'efault */
   columnData.dcolmeth = 'D';

   strcpy (username, argv[1]);
   strcpy (passwd, argv[2]);
					
   printf ("Connecting to SAMPLE database\n");
   /* CONNECTing to the 'sample' database */
   EXEC SQL CONNECT TO sample USER :username USING :passwd;
   CHECKERR ("CONNECT TO database");

   columnStringPointer->length = strlen(statement);
   strncpy (columnStringPointer->data, statement, strlen(statement));
   printf ("Exporting 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);

   columnStringPointer->length = strlen(statement2);
   strncpy (columnStringPointer->data, statement2, strlen(statement2));
   printf ("Exporting ORG table into file '%s'\n", datafile2);
   /*******************\
   * EXPORT API called *
   \*******************/
   sqluexpr (datafile2, NULL, NULL, &columnData, columnStringPointer,
      fileFormat, NULL, msgfile_x, 0, &outputInfo, NULL, &sqlca);
   CHECKERR ("exporting table");
   printf ("Rows exported %d\n", outputInfo.rowsExported);

   strcpy (database, argv[3]);
   strcpy (username, argv[4]);
   strcpy (passwd, argv[5]);
   printf ("Connect to DRDA database\n");
   EXEC SQL CONNECT TO :database USER :username USING :passwd;
   CHECKERR ("CONNECT TO DRDA DATABASE");
   
   columnStringPointer->length = strlen(impStatement);
   strncpy (columnStringPointer->data, impStatement, strlen(impStatement));
   printf ("Importing the file '%s' into 'impstaff'\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);

   columnStringPointer->length = strlen(impStatement2);
   strncpy (columnStringPointer->data, impStatement2, strlen(impStatement2));
   printf ("importing the file '%s' into 'imporg'\n", datafile2);
   /*******************\
   * IMPORT API called *
   \*******************/
   sqluimpr (datafile2, 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 tables and index */
   strcpy (sqlStatement, "drop table impstaff");
   EXEC SQL EXECUTE IMMEDIATE :sqlStatement;
   strcpy (sqlStatement, "drop table imporg");
   EXEC SQL EXECUTE IMMEDIATE :sqlStatement;
   strcpy (sqlStatement, "drop index SAMPLE.TESTIND");
   EXEC SQL EXECUTE IMMEDIATE :sqlStatement;
   EXEC SQL COMMIT;
   CHECKERR ("COMMIT the DROP TABLE");
   
   EXEC SQL CONNECT RESET;
   CHECKERR ("CONNECT RESET");
}
/* end of program : expsamp.sqc */