/*******************************************************************************
**
** Source File Name = rechist.sqc 
**
** 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 :
**       an example showing how to use RECOVERY HISTORY FILE
**       SCAN APIs in order to:
**          - Update a Recovery History File
**          - List the contents of a Recovery History File
**          - Prune the Recovery History File
**
**    APIs USED :
**      BACKUP DATABASE                         sqlubkp
**      OPEN RECOVERY HISTORY FILE SCAN         sqluhops
**      GET NEXT RECOVERY HISTORY FILE ENTRY    sqluhgne
**      CLOSE RECOVERY HISTORY FILE SCAN        sqluhcls
**      UPDATE RECOVERY HISTORY FILE            sqluhupd
**      PRUNE RECOVERY HISTORY FILE             sqluhprn
**
**    STRUCTURES USED :
**       sqlu_media_list
**       sqluhinfo
**       sqluhadm
**       sqlca
**
**    OTHER FUNCTIONS DECLARED :
**       'C' COMPILER LIBRARY :
**          stdio.h  -  printf
**
**       internal :
**          list_rhf :         Displays a directory of databases
**
**       external :
**          check_error :     Checks for SQLCODE error, and prints out any
**          [in util.c]          related information available.
**                               This procedure is located in the util.c file.
**
**    EXTERNAL DEPENDENCIES :
**       - Ensure existence of database for precompile purposes.
**       - 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.
**
**       NOTE: To run this example, the DB2DBDFT environment variable
**             must be set to "sample".
**
** 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 <sqlutil.h>
#include <sqlenv.h>
#include "util.h"

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

int list_rhf (struct sqlca, char *, char *);

int main (int argc, char *argv[]) {

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

   struct sqlca sqlca;

   /* Variables for the BACKUP DATABASE API */
   struct sqlu_media_list mediaList;
   char applid[SQLU_APPLID_LEN+1];

   char timestamp[SQLU_TIME_STAMP_LEN+1];
   char objectPart[SQLU_TIME_STAMP_LEN+4];

   char location[SQLU_DB_DIR_LEN+1];
   unsigned short forceOption;

   printf( "\nEnsure environment variable DB2DBDFT is set to <db_name>.\n" );
   printf( "For example, if your database name is \"sample\":\n" );
   printf( "On UNIX: \"export DB2DBDFT=sample\"\n" );
   printf( "On Windows and OS/2: \"set DB2DBDFT=sample\"\n\n" );

   if ((argc != 2) && (argc != 4)) 
   {
      printf ("USAGE: rechist dbname [userid passwd]\n\n");
      return 1;
   } /* endif */

   printf( "Sample program: rechist.sqc\n" );

   mediaList.target.media = (struct sqlu_media_entry *) malloc (sizeof(struct sqlu_media_entry));
   mediaList.media_type = 'L';
   mediaList.sessions   = 1;

   #if defined(DB2NT) || defined(DB2OS2)
      strcpy (mediaList.target.media->media_entry, "NUL");
   #else
      strcpy (mediaList.target.media->media_entry, "/dev/null");
   #endif

   printf ("creating a history file entry ... backing up the database to null\n");
   /*****************\
   * BACKUP DATABASE *
   \*****************/
   if (argc == 2) {
   sqlubkp (argv[1], 0, 0, 0, 0, applid, timestamp, 0, NULL, &mediaList,
      NULL, NULL , NULL, 0, NULL,
      1, NULL, NULL, 
      NULL, &sqlca);
   CHECKERR ("BACKUP DATABASE");
   }	

   if (argc == 4) {
   sqlubkp (argv[1], 0, 0, 0, 0, applid, timestamp, 0, NULL, &mediaList,
      argv[2], argv[3] , NULL, 0, NULL,
      1, NULL, NULL,  
      NULL, &sqlca);
   CHECKERR ("BACKUP DATABASE");
   }	
   
   strcpy(objectPart, timestamp);
   strcat(objectPart, "001");
   printf ("object part = :%s:\n", objectPart);

   if (argc == 2) {
      strcpy( dbname, argv[1] ) ;
      EXEC SQL CONNECT TO :dbname;
          CHECKERR ("CONNECT TO DATABASE");
   }
   else if (argc == 4) {
      strcpy( dbname, argv[1]);
      strcpy (userid, argv[2]);
      strcpy (passwd, argv[3]);
      EXEC SQL CONNECT TO :dbname USER :userid USING :passwd;
          CHECKERR ("CONNECT TO DATABASE");
   }
   else {
      printf ("\nUSAGE: rechist dbname [userid passwd]\n\n");
      return 1;
   } /* endif */

   printf ("updating the recovery history file...\n");
   /******************************\
   * UPDATE RECOVERY HISTORY FILE *
   \******************************/
   sqluhupd (objectPart , NULL, NULL, "THIS IS A COMMENT", NULL, &sqlca);
   CHECKERR ("UPDATE RECOVERY HISTORY FILE");

   printf ("listing all entries to the recovery history file...\n");
   list_rhf (sqlca, timestamp, argv[1]);

   printf ("Pruning the recovery history file...\n");
   /*****************************\
   * PRUNE RECOVERY HISTORY FILE *
   \*****************************/
   sqluhprn (timestamp, 1, NULL, &sqlca);
   CHECKERR ("PRUNE RECOVERY HISTORY FILE");

   printf ("listing all entries to the recovery history file [after PRUNE]\n");
   list_rhf (sqlca, timestamp, argv[1]);

   EXEC SQL CONNECT RESET ;
   CHECKERR( "CONNECT RESET" ) ;

   return 0;
}

/*******************************************************************************
** Procedure : list_rhf
**
** Purpose :   This procedure displays the data contained in each recovery
**             history file entry.
**
*******************************************************************************/
int list_rhf (struct sqlca sqlca, char *tstamp, char *dbname) {
   unsigned short count;
   unsigned short handle;
   unsigned short callerac = 1;   /* for history */
   char *objectName = "\0";
   struct sqluhinfo * pHistoryInfo;
   struct sqluhadm *pAdminInfo;

   /*********************************\
   * OPEN RECOVERY HISTORY FILE SCAN *
   \*********************************/
   sqluhops (dbname, tstamp, objectName, &count, &handle, callerac,
      NULL, &sqlca);
   CHECKERR ("OPEN RECOVERY HISTORY FILE SCAN");
   printf ("count = %d\ntimestamp = %s\n", count, tstamp);

   pHistoryInfo = (struct sqluhinfo *) malloc (SQLUHINFOSIZE(count));
   pHistoryInfo->sqln = count;

   pAdminInfo = (struct sqluhadm *) malloc (SQLUHADMSIZE(count));

   do {
      /**************************************\
      * GET NEXT RECOVERY HISTORY FILE ENTRY *
      \**************************************/
      sqluhgne (handle, pAdminInfo, pHistoryInfo, &sqlca);
      if (sqlca.sqlcode == SQLUH_SQLUHINFO_VARS_WARNING) {

         count = pHistoryInfo->sqld;
         free (pHistoryInfo);

         pHistoryInfo = (struct sqluhinfo *) malloc (SQLUHINFOSIZE(count));
         pHistoryInfo->sqln = count;

      } else if (sqlca.sqlcode == SQLE_RC_NOMORE) {
         break;
      } else {
         printf ("need to print out the information from the sqluhinfo struct\n\n");
         /* need to print out the buffer information at this point */
         CHECKERR ("GET NEXT RECOVERY HISTORY FILE SCAN");
      } /* endif */
   } while ( 1 ); /* enddo */

   /**********************************\
   * CLOSE RECOVERY HISTORY FILE SCAN *
   \**********************************/
   sqluhcls (handle, NULL, &sqlca);
   CHECKERR ("CLOSE RECOVERY HISTORY FILE SCAN");
   return 0;
}