/******************************************************************************
**
** Source File Name = tspace.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 :
**       an example showing how to use TABLESPACE and TABLESPACE CONTAINER
**       APIs in order to:
**          - obtain tablespace information using lower level service
**            APIs (OPEN, FETCH, CLOSE)
**          - obtain tablespace information using a higher level
**            APIs (TABLESPACE QUERY, SINGLE TABLESPACE QUERY)
**          - obtain tablespace container information using lower level
**            service APIs (OPEN, FETCH, CLOSE)
**          - obtain tablespace container information using a higher level
**            API (QUERY).
**
**    APIs USED :
**        TABLESPACE QUERY                       sqlbmtsq
**        SINGLE TABLESPACE QUERY                sqlbstpq
**        OPEN TABLESPACE QUERY                  sqlbotsq
**        FETCH TABLESPACE QUERY                 sqlbftpq
**        GET TABLESPACE STATISTICS              sqlbgtss
**        CLOSE TABLESPACE QUERY                 sqlbctsq
**        TABLESPACE CONTAINER QUERY             sqlbtcq
**        OPEN TABLESPACE CONTAINER QUERY        sqlbotcq
**        FETCH TABLESPACE CONTAINER QUERY       sqlbftcq
**        CLOSE TABLESPACE CONTAINER QUERY       sqlbctcq
**        SET TABLESPACE CONTAINERS              sqlbstsc
**        FREE MEMORY                            sqlefmem
**
**    STRUCTURES USED :
**       sqlca
**
**    OTHER FUNCTIONS DECLARED :
**       'C' COMPILER LIBRARY :
**          stdio.h  -  printf
**
**       internal :
**          tabspaceInfo :     Displays information on the tablespace passed
**                             through.
**          tabspaceContInfo : Displays information on the tablespace
**                             container that is passed through.
**
**       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 DEPENDANCIES :
**       - 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.
**
** 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 <malloc.h>
#include <sqlutil.h>
#include <sqlenv.h>
#include "util.h"

EXEC SQL INCLUDE SQLCA ;

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

int tabspaceInfo( struct SQLB_TBSPQRY_DATA *, unsigned long ) ;
int tabspaceContInfo( struct SQLB_TBSCONTQRY_DATA *, unsigned long ) ;

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

   struct SQLB_TBSPQRY_DATA *dataP, **dataPP ;
   struct SQLB_TBSCONTQRY_DATA *dataTSCP ;
   unsigned long numTS, maxTS, numT, index ;
   unsigned long numTSC, tableID, nCont ;
   unsigned long i ;

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

   if ( argc != 4 ) {
      printf( "\nUSAGE: tspace databasename userid passwd\n\n" ) ;
      return 1 ;
   }  /* endif */

   printf( "this is sample program: tspace.c\n\n" ) ;

   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" ) ;

   printf( "Using the following APIs:\n"
           "   OPEN TABLESPACE QUERY\n"
           "   FETCH TABLESPACE QUERY\n"
           "   CLOSE TABLESPACE QUERY\n"
           "=========================\n\n"
         ) ;

   /**********************************\
   * OPEN TABLESPACE QUERY API called *
   \**********************************/
   sqlbotsq( &sqlca, SQLB_OPEN_TBS_ALL, &numTS ) ;
   CHECKERR( "OPEN TABLESPACE QUERY" ) ;
   maxTS = numTS ;
   dataP = ( struct SQLB_TBSPQRY_DATA * )
           malloc( numTS * sizeof( struct SQLB_TBSPQRY_DATA ) ) ;
   strcpy( dataP->tbspqver, SQLB_TBSPQRY_DATA_ID ) ;

   /***********************************\
   * FETCH TABLESPACE QUERY API called *
   \***********************************/
   sqlbftpq( &sqlca, maxTS, dataP, &numTS ) ;
   CHECKERR( "FETCH TABLESPACE QUERY" ) ;
   tabspaceInfo( dataP, numTS ) ;

   /************************************\
   * CLOSE TABLESPACE QUERY API called *
   \************************************/
   sqlbctsq( &sqlca ) ;
   CHECKERR( "CLOSE TABLESPACE QUERY" ) ;

   printf( "Using the following APIs:\n"
           "   OPEN TABLESPACE CONTAINER QUERY\n"
           "   FETCH TABLESPACE CONTAINER QUERY\n"
           "   CLOSE TABLESPACE QUERY\n"
           "===================================\n\n"
         ) ;

   /********************************************\
   * OPEN TABLESPACE CONTAINER QUERY API called *
   \********************************************/
   sqlbotcq( &sqlca, SQLB_ALL_TABLESPACES, &numTSC ) ;
   CHECKERR( "OPEN TABLESPACE CONTAINER QUERY" ) ;
   dataTSCP = ( struct SQLB_TBSCONTQRY_DATA * )
              malloc( numTSC * sizeof( struct SQLB_TBSCONTQRY_DATA ) ) ;

   /*********************************************\
   * FETCH TABLESPACE CONTAINER QUERY API called *
   \*********************************************/
   sqlbftcq( &sqlca, numTSC , dataTSCP, &nCont ) ;
   CHECKERR( "FETCH TABLESPACE CONTAINER QUERY" ) ;

   tableID = dataTSCP->id ;
   tabspaceContInfo( dataTSCP, numTSC ) ;

   /*********************************************\
   * CLOSE TABLESPACE CONTAINER QUERY API called *
   \*********************************************/
   sqlbctcq( &sqlca ) ;
   CHECKERR( "CLOSE TABLESPACE CONTAINER QUERY" ) ;

   printf( "Using the SINGLE TABLESPACE QUERY API for table ID : 1\n" ) ;
   printf( "======================================================\n\n" ) ;

   /************************************\
   * SINGLE TABLESPACE QUERY API called *
   \************************************/
   sqlbstpq( &sqlca, 1, dataP, SQLB_RESERVED1 ) ;
   CHECKERR( "SINGLE TABLESPACE QUERY" ) ;
   tabspaceInfo( dataP, 1 ) ;

   printf( "Using the TABLESPACE QUERY API\n"
           "==============================\n\n"
         ) ;

   /*****************************\
   * TABLESPACE QUERY API called *
   \*****************************/
   sqlbmtsq( &sqlca, &numTS, &( dataPP ), SQLB_RESERVED1, SQLB_RESERVED2 ) ;
   CHECKERR( "TABLESPACE QUERY" ) ;
   for ( i=0; i < numTS; i++ ) tabspaceInfo( dataPP[i], 1 ) ;

   printf( "Using the TABLESPACE CONTAINER QUERY API\n"
           "========================================\n\n"
         ) ;

   /***************************************\
   * TABLESPACE CONTAINER QUERY API called *
   \***************************************/
   sqlbtcq( &sqlca, tableID, &numTSC, &( dataTSCP ) ) ;
   CHECKERR( "TABLESPACE CONTAINER QUERY" ) ;
   tabspaceContInfo( dataTSCP, numTSC ) ;

   /************************\
   * FREE MEMORY API called *
   \************************/
   sqlefmem( &sqlca, dataPP ) ;
   CHECKERR( "FREE MEMORY" ) ;

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

   return 0 ;

}

int tabspaceInfo( struct SQLB_TBSPQRY_DATA * dataP,
                  unsigned long              num
                ) {

   struct SQLB_TBS_STATS tbs_stats ;

   unsigned long idx ;
   for ( idx=0; idx < num; idx++, dataP++ ) {

      printf( "Tablespace ID                   = %ld\n", dataP->id ) ;
      printf( "Tablespace Name                 = %s\n", dataP->name ) ;

      /* "Type" and "Content" are stored bitwise in the flag field */
      printf( "Type                            = " ) ;
      switch ( dataP->flags & 0xF ) {

         case SQLB_TBS_SMS:
            printf( "System managed space\n" ) ;
            break ;

         case SQLB_TBS_DMS:
            printf( "Database managed space\n" ) ;
            break ;

         default:
            printf( "UNKNOWN\n" ) ;
            break ;

      }  /* endswitch */

      printf( "Contents                        = " ) ;
      switch ( dataP->flags & 0xF0 ) {

         case SQLB_TBS_ANY:
            printf( "regular contents\n" ) ;
            break ;

         case SQLB_TBS_LONG:
            printf( "long field data\n" ) ;
            break ;

         case SQLB_TBS_TMP:
            printf( "temp data\n" ) ;
            break ;

         default:
            printf( "UNKNOWN :%d:\n", dataP->flags & 0xF0 ) ;
            break ;

      }  /* endswitch */

      printf( "State                           = " ) ;
      switch ( dataP->tbsState ) {
         case SQLB_NORMAL:
            printf( "Normal\n" ) ;
            break ;

         case SQLB_QUIESCED_SHARE:
            printf( "Quiesced: SHARE\n" ) ;
            break ;

         case SQLB_QUIESCED_UPDATE:
            printf( "Quiesced: UPDATE\n" ) ;
            break ;

         case SQLB_QUIESCED_EXCLUSIVE:
            printf( "Quiesced: EXCLUSIVE\n" ) ;
            break ;

         case SQLB_LOAD_PENDING:
            printf( "Load pending\n" ) ;
            break ;

         case SQLB_DELETE_PENDING:
            printf( "Delete pending\n" ) ;
            break ;

         case SQLB_BACKUP_PENDING:
            printf( "Backup pending\n" ) ;
            break ;

         case SQLB_ROLLFORWARD_IN_PROGRESS:
            printf( "Roll forward in progress\n" ) ;
            break ;

         case SQLB_ROLLFORWARD_PENDING:
            printf( "Roll forward pending\n" ) ;
            break ;

         case SQLB_RESTORE_PENDING:
            printf( "Restore pending\n" ) ;
            break ;

         case SQLB_DISABLE_PENDING:
            printf( "Disable pending\n" ) ;
            break ;

         case SQLB_REORG_IN_PROGRESS:
            printf( "Reorg in progress\n" ) ;
            break ;

         case SQLB_BACKUP_IN_PROGRESS:
            printf( "Backup in progress\n" ) ;
            break ;

         case SQLB_STORDEF_PENDING:
            printf( "storage must be defined\n" ) ;
            break ;

         case SQLB_RESTORE_IN_PROGRESS:
            printf( "Restore in progress\n" ) ;
            break ;

         case SQLB_STORDEF_ALLOWED:
            printf( "storage may be defined\n" ) ;
            break ;

         case SQLB_STORDEF_FINAL_VERSION:
            printf( "storDef is in 'final' state\n" ) ;
            break ;

         case SQLB_STORDEF_CHANGED:
            printf( "storDef was changed prior to rollforward\n" ) ;
            break ;

         case SQLB_REBAL_IN_PROGRESS:
            printf( "dms rebalancer is active\n" ) ;
            break ;

         case SQLB_PSTAT_DELETION:
            printf( "TBS deletion in progress\n" ) ;
            break ;

         case SQLB_PSTAT_CREATION:
            printf( "TBS creation in progress\n" ) ;
            break ;

         default:
            printf( "UNKNOWN\n" ) ;
            break ;

      }  /* endswitch */

      /***************************\
      * GET TABLESPACE STATISTICS *
      \***************************/
      sqlbgtss( &sqlca, dataP->id, &tbs_stats ) ;
      CHECKERR( "GET TBS STAT" ) ;

      printf( "Tablespace Statistics\n" ) ;
      printf( "total pages                     = %ld\n",
              tbs_stats.totalPages
            ) ;
      printf( "useable pages                   = %ld\n",
              tbs_stats.useablePages
            ) ;
      printf( "used pages                      = %ld\n",
              tbs_stats.usedPages
            ) ;
      printf( "free pages                      = %ld\n",
              tbs_stats.freePages
            ) ;
      printf( "high water mark                 = %ld\n",
              tbs_stats.highWaterMark
            ) ;

      printf( "\n" ) ;

   }  /* endfor */

   return 0 ;

}

int tabspaceContInfo( struct SQLB_TBSCONTQRY_DATA * dataTSCP,
                      unsigned long                 num
                    ) {

   unsigned long idx ;

   for ( idx = 0; idx < num; idx++, dataTSCP++ ) {
      printf( "Tablespace Containers for Tablespace %d\n\n",
              dataTSCP->tbsID
            ) ;

      printf( "Container ID                    = %ld\n",
              dataTSCP->id
            ) ;
      printf( "Name                            = %s\n",
              dataTSCP->name
            ) ;
      printf( "Type                            = " ) ;
      switch ( dataTSCP->contType ) {
         case SQLB_CONT_PATH:
            printf( "path\n" ) ;
            break ;
         case SQLB_CONT_DISK:
            printf( "disk\n" ) ;
            break ;
         case SQLB_CONT_FILE:
            printf( "file\n" ) ;
            break ;
         default:
            printf( "unknown\n" ) ;
            break ;
      } /* endswitch */

      printf( "\n" ) ;
   }  /* endfor */

   return 0 ;

}