/*******************************************************************************
**
** Source File Name = fillsrv.sqC   1.7
**
** Licensed Materials - Property of IBM
**
** (C) COPYRIGHT International Business Machines Corp. 1995, 1997
** All Rights Reserved.
**
** US Government Users Restricted Rights - Use, duplication or
** disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**
**    PURPOSE :
**       The server procedure from which is called by "fillcli".
**       Input parameters passed through a SQLDA are deciphered, resulting
**       in the desired action on the specified table (random data filling).
**
**
**    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.
**
*******************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sql.h>
#include <sqlca.h>
#include <sqlda.h>
#include <sqlenv.h>
#include "util.h"

EXEC SQL INCLUDE SQLCA ;

extern "C"
int SQL_API_FN fillsrv( void *, void *, struct sqlda *, struct sqlca * ) ;

class FillServer {

    EXEC SQL BEGIN DECLARE SECTION ;
      char sql_buffer[255] ;
    EXEC SQL END DECLARE SECTION ;

    struct sqlda * local_sqlda ;
    short org_columns, org_rows ;
    char char_value[65] ;

    int GetRandomID( short * ) ;
    int GetRandomString( char *, int ) ;

  public:

    FillServer( struct sqlda * ) ;
    ~FillServer() ;
    int ExecTrans( struct sqlda * ) ;

} ;

FillServer::FillServer( struct sqlda * inout_sqlda ) {

  memset( ( void * ) char_value, 0, 65 ) ;
  strcpy( char_value,
          "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz_-"
        ) ;

  org_rows = * ( ( short * ) ( inout_sqlda->sqlvar[1].sqldata ) ) ;

  org_columns = 5 ;
  init_da( &local_sqlda, org_columns ) ;
  local_sqlda->sqld = org_columns ;

  local_sqlda->sqlvar[0].sqltype = SQL_TYP_NSMALL ;
  local_sqlda->sqlvar[0].sqllen = sizeof( short ) ;
  local_sqlda->sqlvar[1].sqltype = SQL_TYP_NCSTR ;
  local_sqlda->sqlvar[1].sqllen = 14 ;
  local_sqlda->sqlvar[2].sqltype = SQL_TYP_NSMALL ;
  local_sqlda->sqlvar[2].sqllen = sizeof( short ) ;
  local_sqlda->sqlvar[3].sqltype = SQL_TYP_NCSTR ;
  local_sqlda->sqlvar[3].sqllen = 10 ;
  local_sqlda->sqlvar[4].sqltype = SQL_TYP_NCSTR ;
  local_sqlda->sqlvar[4].sqllen = 13 ;

  alloc_host_vars( local_sqlda ) ;

  strcpy( ( char * ) local_sqlda->sqlvar[4].sqldata,
          ( char * ) inout_sqlda->sqlvar[2].sqldata
        ) ;

  srand( ( unsigned int ) time( NULL ) ) ;
  short lv_value = 100 ;
  memcpy( ( void * ) local_sqlda->sqlvar[0].sqldata, &lv_value, sizeof( short ) ) ;
  lv_value = 300 ;
  memcpy( ( void * ) local_sqlda->sqlvar[2].sqldata, &lv_value, sizeof( short ) ) ;

}

FillServer::~FillServer() {

  free_da( local_sqlda ) ;

}

int FillServer::ExecTrans( struct sqlda * inout_sqlda ) {

  if ( strcmp( ( char * ) inout_sqlda->sqlvar[0].sqldata, "INSERT" ) == 0 ) {

    memset( ( void * ) sql_buffer, 0, 255 ) ;
    strcpy( sql_buffer, "INSERT INTO ORG VALUES (?,?,?,?,?)" ) ;

    EXEC SQL PREPARE st FROM :sql_buffer ;

    int i = 0 ;
    while ( i++ < org_rows ) {
      GetRandomID( ( short * ) local_sqlda->sqlvar[0].sqldata ) ;
      GetRandomString( ( char * ) local_sqlda->sqlvar[1].sqldata, 14 ) ;
      GetRandomID( ( short * ) local_sqlda->sqlvar[2].sqldata ) ;
      GetRandomString( ( char * ) local_sqlda->sqlvar[3].sqldata, 10 ) ;
      EXEC SQL EXECUTE st USING DESCRIPTOR :*local_sqlda ;
    }

  }

  else if ( strcmp( ( char * ) inout_sqlda->sqlvar[0].sqldata, "DELETE" ) == 0 ) {

    memset( ( void * ) sql_buffer, 0, 255 ) ;
    strcpy( sql_buffer, ( char * ) inout_sqlda->sqlvar[2].sqldata ) ;

    EXEC SQL DELETE FROM ORG WHERE LOCATION = :sql_buffer ;

  }

  return( 0 ) ;

}

int FillServer::GetRandomID( short * random_ID ) {

  int   random_value ;
  short short_value ;

  short_value = *random_ID ;
  random_value = rand() ;
  random_value &= 0x0F ;
  if ( random_value < 16 ) short_value += random_value ;
  short_value++ ;

  memcpy( ( void * ) random_ID, ( void * ) &short_value, sizeof( short ) ) ;

  return( 0 ) ;

}

int FillServer::GetRandomString( char * random_string, int random_len ) {

  memset( ( void * ) random_string, 0, random_len ) ;
  random_len-- ;
  int i = 0 ;
  while ( i < random_len ) {
    int random_value = rand() ;
    random_value &= 0x3F ;
    if ( random_value < 64 ) random_string[i] = char_value[random_value] ;
    else random_string[i] = '-' ;
    i++ ;
  }

  return( 0 ) ;

}

int SQL_API_FN fillsrv( void         * reserved1,
                        void         * reserved2,
                        struct sqlda * inout_sqlda,
                        struct sqlca * inout_sqlca
                      ) {

  FillServer server( inout_sqlda ) ;
  server.ExecTrans( inout_sqlda ) ;

  return( SQLZ_DISCONNECT_PROC ) ;

}