/*******************************************************************************
**
** Source File Name = dbconf.c  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
**       CREATE a DATABASE and then GET the CONFIGURATION information from
**       it, then UPDATE the CONFIGURATION, RESET the CONFIGURATION, then
**       DROP the DATABASE.
**
**    APIs USED :
**       INSTANCE ATTACH                  sqleatin()
**       CREATE DATABASE                  sqlecrea()
**       DROP DATABASE                    sqledrpd()
**       GET DATABASE CONFIGURATION       sqlfxdb()
**       UPDATE DATABASE CONFIGURATION    sqlfudb()
**       RESET DATABASE CONFIGURATION     sqlfrdb()
**
**
**    STRUCTURES USED :
**       sqlfupd
**       sqledbdesc
**       sqledbcountryinfo
**       sqlca
**
**    OTHER FUNCTIONS USED :
**       'C' COMPILER LIBRARY :
**          stdio.h  -  printf
**
**       internal :
**          print_info :      Displays a directory of databases
**          alloc_mem :       Allocates the proper amount of memory for the
**                            GET DATABASE CONFIGURATION API to fill with
**                            data.
**
**       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.
**       - a database by the name of "DBCONF" does not exist.
**
** 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;
#define  LISTNUMBER 4
#define  MAXLENGTH 242

int alloc_mem (struct sqlfupd *);
int print_info (struct sqlfupd *);

int main (int argc, char* argv[]) {
   struct sqlfupd itemList[LISTNUMBER];
   struct sqlca sqlca;
   struct sqledbdesc db_desc;
   struct sqledbcountryinfo dbCountry;
   short value_locklist, value_maxfilop, value_softmax;
   int value_buff_page ;

   char userid[9];
   char passwd[19];
   char nodename[9];

   if (argc == 4) {
       strcpy (userid, argv[1]);
       strcpy (passwd, argv[2]);
       strcpy (nodename, argv[3]);
       
      /*************************/
      /* ATTACH API called     */
      /*************************/
       sqleatin (nodename, userid, passwd, &sqlca);
   }
   else if (argc != 1) {
       printf("\nUSAGE: dbconf [userid password remote_nodename]\n");
       return 1;
   }

   strcpy(db_desc.sqldbdid, SQLE_DBDESC_2);
   db_desc.sqldbccp = 0;
   db_desc.sqldbcss = 0;
   db_desc.sqldbsgp = 0;
   db_desc.sqldbnsg = 10;
   db_desc.sqltsext = -1;
   db_desc.sqlcatts = NULL;
   db_desc.sqlusrts = NULL;
   db_desc.sqltmpts = NULL;


   strcpy(dbCountry.sqldbcodeset, "IBM-850");
   strcpy(dbCountry.sqldblocale, "En_US");

   printf ("CREATing the temporary database DBCONF...\n");
   printf ("please wait... this will take a while...\n");
   /****************************\
   * CREATE DATABASE API called *
   \****************************/
   sqlecrea ("DBCONF", "DBCONF", "", &db_desc, &dbCountry, '\0', NULL, &sqlca);
   CHECKERR("creating the database");
   printf ("database DBCONF created\n");

   alloc_mem (itemList);

   printf ("getting the database configuration for DBCONF\n");
   /***************************************\
   * GET DATABASE CONFIGURATION API called *
   \***************************************/
   sqlfxdb ("DBCONF", LISTNUMBER, itemList, &sqlca);
   CHECKERR("get database config");

   printf ("listing the database configuration\n");
   print_info (itemList);

   /* Altering the default Database Configuration */
   value_locklist = 4 ;
   value_buff_page = 2000 ;
   value_maxfilop = 3 ;
   value_softmax = 1 ;
 
   memcpy( ( void * ) (itemList[0].ptrvalue), (void *) &value_locklist, sizeof(short) ) ;
   memcpy( ( void * ) (itemList[1].ptrvalue), (void *) &value_buff_page, sizeof(int) ) ;
   memcpy( ( void * ) (itemList[2].ptrvalue), (void *) &value_maxfilop, sizeof(short) ) ;
   memcpy( ( void * ) (itemList[3].ptrvalue), (void *) &value_softmax, sizeof(short) ) ;

   printf ("UPDATing the database configuration\n");
   /******************************************\
   * UPDATE DATABASE CONFIGURATION API called *
   \******************************************/
   sqlfudb("DBCONF", LISTNUMBER, itemList, &sqlca); 
   /* This API will always return a warning concerning the risk of changing buffer page size. */
   /* To receive this warning uncomment the following CHECKERR statement.                     */
   /* CHECKERR("updating the database configuration");                                                */

   /***************************************\
   * GET DATABASE CONFIGURATION API called *
   \***************************************/
   sqlfxdb ("DBCONF", LISTNUMBER, itemList, &sqlca);
   CHECKERR("get database config");

   printf ("listing the UPDATEd database configuration\n");
   print_info (itemList);

   printf ("RESETting the database configuration\n");
   /*****************************************\
   * RESET DATABASE CONFIGURATION API called *
   \*****************************************/
   sqlfrdb("DBCONF", &sqlca);

   /***************************************\
   * GET DATABASE CONFIGURATION API called *
   \***************************************/
   sqlfxdb ("DBCONF", LISTNUMBER, itemList, &sqlca);
   CHECKERR("get database config");

   printf ("printing the database configuration after the RESET\n");
   print_info (itemList);

   printf ("DROPping the database DBCONF\n");
   /**************************\
   * DROP DATABASE API called *
   \**************************/
   sqledrpd ("DBCONF", &sqlca);
   CHECKERR("dropping the database");

   return 0;
}

/*******************************************************************************
* this procedure allocates the required memory to each section of the array.
* Each member of the array must be appointed to a specific field in regards
* to the output of the GET DATABASE CONFIGURATION API call
*******************************************************************************/
int alloc_mem (struct sqlfupd *itemList) {
   itemList[0].token = SQLF_DBTN_LOCKLIST;
   itemList[0].ptrvalue = (char *)malloc(sizeof(short));

   itemList[1].token = SQLF_DBTN_BUFF_PAGE;
   itemList[1].ptrvalue = (char *)malloc(sizeof(int));

   itemList[2].token = SQLF_DBTN_MAXFILOP;
   itemList[2].ptrvalue = (char *)malloc(sizeof(short));

   itemList[3].token = SQLF_DBTN_SOFTMAX;
   itemList[3].ptrvalue = (char *)malloc(sizeof(short));

   return 0;
}

int print_info (struct sqlfupd *itemList) {
   printf ("Max. storage for lost lists (4kb)             : %d\n",
      *(short *)itemList[0].ptrvalue);
   printf ("Buffer pool size (4kb)                        : %d\n",
      *(int *)itemList[1].ptrvalue);
   printf ("Max. DB files open per appl.                  : %d\n",
      *(short *)itemList[2].ptrvalue);
   printf ("percent log reclaimed before soft checkpoint  : %d\n",
      *(short *)itemList[3].ptrvalue);
   printf ("\n");

   return 0;
}