/******************************************************************************
**
** Source File Name = spclient.sqC
**
** Licensed Materials - Property of IBM
**
** (C) COPYRIGHT International Business Machines Corp. 1995, 2000 
** All Rights Reserved.
**
** US Government Users Restricted Rights - Use, duplication or
** disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
**
**
** PURPOSE: This sample program demonstrates stored procedures.
**
** The file "utilemb.sqC" contains functions for error-checking and
** rolling back a transaction in case of error. This file must be
** compiled and its object file linked in to the "spclient" program.
**
**    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 loop with the compiler supported 
**         on your platform.
**
** For more information about these samples refer to the README file.
**
** For more information on programming in C++, refer to the:
**   -  "Programming in C and C++" section of the Application Development Guide
** For more information on Building C++ Applications, refer to the:
**   -  "Building C++ Applications" section of the Application Building Guide.
**
** For more information on the SQL language refer to the SQL Reference.
**
** spclient contains twelve functions that call stored procedures:
**  (1) callOutLanguage: returns language of the stored procedure library
**        Parameter types used: OUT CHAR(8)
**  (2) callOutParameter: return median salary of EMPLOYEE table
**        Parameter types used: OUT DOUBLE
**                              OUT INTEGER
**                              OUT CHAR(32)
**  (3) callInParameters: accept 3 values and update salaries in EMPLOYEE table
**      accordingly
**        Parameter types used: IN DOUBLE
**                              IN CHAR(3)
**                              OUT INTEGER
**                              OUT CHAR(32)
**  (4) callInoutParameter: accept an input value and return the median
**      salary of the EMPLOYEE table for employees who make more
**      than the input value. Demonstrates how to use null indicators
**      in a client application.
**        Parameter style (C):    GENERAL WITH NULLS
**        Parameter style (Java): JAVA
**        Parameter style (SQL):  SQL
**        Parameter types used: INOUT DOUBLE
**                              OUT INTEGER
**                              OUT CHAR(32)
**  (5) callOneResultSet: return a result set to the client application
**        Parameter types used: IN DOUBLE
**                              OUT INTEGER
**  (6) callTwoResultSets: return two result sets to the client application
**        Parameter types used: IN DOUBLE
**                              OUT INTEGER
**  (7) callClobExtract: return a sub-section of a CLOB data type
**        Parameter types used: IN CHAR(6)
**                              OUT VARCHAR(1000)
**                              OUT INTEGER
**  (8) callDecimalType: pass and receive a DECIMAL data type from a
**      stored procedure
**        Parameter types used: INOUT DECIMAL
**  (9) callAllDataTypes: use all of the common data types in a stored procedure
**        Parameter types used: INOUT SMALLINT
**                              INOUT INTEGER
**                              INOUT BIGINT
**                              INOUT REAL
**                              INOUT DOUBLE
**                              OUT CHAR(1)
**                              OUT CHAR(15)
**                              OUT VARCHAR(12)
**                              OUT DATE
**                              OUT TIME
**  (10) callDB2SQL: calls a DB2SQL parameter style stored procedure
**        Parameter style: DB2SQL
**        Parameter types used: IN CHAR(8)
**                              OUT DOUBLE
**  (11) callDBINFO: calls a stored procedure that receives a DBINFO 
**      structure and returns elements of the structure to the client
**        Parameter types used: IN CHAR(8)
**                              OUT DOUBLE
**                              OUT CHAR(128)
**                              OUT CHAR(8)
**                              OUT INTEGER
**  (12) callProgramTypeMain: calls a stored procedure implemented with
**      PROGRAM TYPE MAIN parameter passing style
**        Parameter types used: IN CHAR(8)
**                              OUT DOUBLE
*******************************************************************************/
#include <iostream.h>
#include <stdio.h>
#include <stdlib.h>
#include <sqlda.h>
#include <sqlca.h>
#include <string.h>
#include "utilemb.h"

struct sqlca sqlca;

class Spclient 
{
   public:
      Spclient();
      Spclient(char *, char *);
      Spclient(char *, char *, char *);
      int Call_StorProcs();
      int callOutLanguage(char *);
      double callOutParameter();
      int callInParameters(double, double, double, char *);
      int callInoutParameter(double);
      int callClobExtract(char *); 
      int callAllDataTypes(); 
      int callDB2SQL(char *);
      int callDBINFO(char *);
      int callProgramTypeMain(char *); 
      ~Spclient();

   private:
   EXEC SQL BEGIN DECLARE SECTION;
     /* Declare host variables for connecting to the database */
           char database[9];
           char userid[9];
           char passwd[19];

     /* Declare host variable for stored procedure name */
     char procname[254];

     /* Declare host variables for stored procedure error handling */
     sqlint32 out_sqlcode;                                                  /* :rk.4:erk. */
     char out_buffer[33];
   EXEC SQL END DECLARE SECTION;         

};

Spclient::Spclient() 
{
   printf("Connect to default database with default user ID and password\n");
   EXEC SQL CONNECT TO sample;
   EMB_SQL_CHECK("CONNECT TO");
}

Spclient::Spclient(char *user, char *pass)
{
   strcpy(userid,user);
   strcpy(passwd,pass);

   printf("Connecting to sample database\n");
   EXEC SQL CONNECT TO sample USER :userid USING :passwd;
   EMB_SQL_CHECK("CONNECT TO SAMPLE") ;
}

Spclient::Spclient(char *dbn, char *user, char *pass) 
{
   strcpy(database,dbn);
   strcpy(userid,user);
   strcpy(passwd,pass);
   printf("Connecting to database %s\n", database);
   EXEC SQL CONNECT TO :database USER :userid USING :passwd;
   EMB_SQL_CHECK("CONNECT TO :database") ;
}

int Spclient::Call_StorProcs()
{
   /* Declare constants */
   const int NO_CLIENT_SUPPORT = 1;

   /* Declare variables */
   char out_lang[9];
   int test_lang_c, test_lang_java, test_lang_sql; 
   double median;

   callOutLanguage(out_lang);
   test_lang_sql = strncmp(out_lang, "SQL", 3);
   test_lang_c = strncmp(out_lang, "C", 1);
   test_lang_java = strncmp(out_lang, "JAVA", 4);

   median = callOutParameter();
   callInParameters(15000, 20000, 25000, "E11");

   printf("\nCALL stored procedure named INOUT_PARAM\n");
   printf("using the median returned by the call to OUT_PARAM\n");
   callInoutParameter(median);

   /* Cause callInoutParameter to pass a null value to the stored procedure */
   printf("\nCALL stored procedure named INOUT_PARAM\n");
   printf("using a NULL input value\n");
   callInoutParameter(-99999);

   /* Cause callInoutParameter to return a NOT FOUND error
    * from the stored procedure
    */
   printf("\nCALL stored procedure named INOUT_PARAM\n");
   printf("using a value that returns a NOT FOUND error from the "
         "stored procedure\n");

   /* The "salary" column of the "staff" table is defined with a
      DECIMAL(7,2) data type, so 99999.99 is the maximum value.     */
   callInoutParameter(99999.99);

   if (test_lang_sql == 0) 
   {
      /* SQL procedures cannot handle LOB data types,
         so do not call the CLOB_EXTRACT stored procedure */
      printf("\nStored procedures are implemented in SQL,\n"
             "which cannot handle LOB datatypes\n"
             "Skipping the call to CLOB_EXTRACT\n");
  }
  else if (test_lang_c == 0)
  {
     /* Warn the user that the CLI stored procedure
      * requires a change to the UDF_MEM_SZ variable */
     printf("\n\n   If the CLOB EXTRACT stored procedure is implemented\n"
         "   using CLI, you must increase the value of the UDF_MEM_SZ\n"
         "   database manager configuration variable to at least two\n"
         "   pages larger than the size of the input arguments and\n"
         "   the result of the stored procedure. To do this, issue\n"
         "   the following command from the CLP:\n"
         "      db2 UPDATE DBM CFG USING UDF_MEM_SZ 2048\n"
         "   For the change to take effect, you must then stop and\n"
         "   restart the DB2 server by issuing the following\n"
         "   commands from the CLP:\n"
         "      db2stop\n"
         "      db2start\n");
     callClobExtract("000140");
   }	   
   else if (test_lang_java == 0)
   {
     callClobExtract("000140");
   }

   if (NO_CLIENT_SUPPORT)
   {
     /* Embedded SQL in C++ client applications cannot
      * accept single result sets, so do not call
      * the ONE_RESULT_SET stored procedure.
      */
   }
   
   if (NO_CLIENT_SUPPORT)
   {
     /* Embedded SQL in C++ client applications cannot
      * accept multiple result sets, so do not call
      * the TWO_RESULT_SETS stored procedure.
      */
   }

   if (test_lang_c != 0 || NO_CLIENT_SUPPORT)
   {
     /* C does not provide a native data type for decimal
      * values, so neither a C++ client application nor a
      * C stored procedure can pass DECIMAL SQL data types.
      *
      * Do not call the DECIMAL_TYPE stored procedure,
      * because this client is written in C++.
      */
   }

   callAllDataTypes();

   if (test_lang_c != 0) {
      /* Stored procedures of PARAMETER STYLE DB2SQL, DBINFO,
         or PROGRAM TYPE MAIN can only be implemented by
         LANGUAGE C stored procedures. If out_lang != "C",
         we know that those stored procedures are not
         implemented, and therefore do not call them. */
   }
   else {
     callDB2SQL("CLERK");

     /* Call DB2SQL_EXAMPLE with null input to return
        a custom SQLSTATE and diagnostic message */
     callDB2SQL("");

     callDBINFO("MANAGER");
     callProgramTypeMain("DESIGNER");
   }

   /* Roll back stored procedure actions to preserve
      the state of the database */
   EXEC SQL ROLLBACK;
   EMB_SQL_CHECK("ROLLBACK");
   printf("\nStored procedure rolled back\n\n");

   /* Disconnect from Remote Database */
   EXEC SQL CONNECT RESET;                                                /* :rk.8:erk. */
   EMB_SQL_CHECK("CONNECT RESET");
   return 0;
}

int Spclient::callOutLanguage(char * out_lang) 
{
   /********************************************************\
   * Call OUT_LANGUAGE stored procedure                     *
   \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     char language[9];
   EXEC SQL END DECLARE SECTION;

   strcpy(procname, "OUT_LANGUAGE");
   printf("CALL stored procedure named %s\n", procname);

   /* OUT_LANGUAGE is PS GENERAL, so do not pass a null indicator */
   EXEC SQL CALL :procname (:language); 
   EMB_SQL_CHECK("CALL OUT_LANGUAGE");

   /********************************************************\
   * Display the language of the stored procedures          *
   \********************************************************/

   strcpy(out_lang, language);

   printf("Stored procedures are implemented in LANGUAGE %s\n", out_lang);

  return 0;
}

double Spclient::callOutParameter() 
{
   /********************************************************\
   * Call OUT_PARAM stored procedure                        *
   \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     double out_median;
   EXEC SQL END DECLARE SECTION;

   strcpy(procname, "OUT_PARAM");
   printf("\nCALL stored procedure named %s\n", procname);

   /* OUT_PARAM is PS GENERAL, so do not pass a null indicator */
   EXEC SQL CALL :procname (:out_median, :out_sqlcode, :out_buffer);  /* :rk.5:erk. */ /* :rk.6:erk. */
   EMB_SQL_CHECK("CALL OUT_PARAM");
   /* Check that the stored procedure executed successfully */
   if (out_sqlcode == 0)                                                   /* :rk.7:erk. */
   { 
     printf("Stored procedure returned successfully\n");

     /***********************************************************\
      * Display the median salary returned as an output parameter *
      \***********************************************************/

     printf("Median salary returned from OUT_PARAM = %8.2f\n", out_median);

   }
   else
   { /* print the error message, roll back the transaction */
     printf("Stored procedure returned SQLCODE %d\n", out_sqlcode);
     printf("from procedure section labelled \"%s\"\n", out_buffer);
   }
   return out_median;
}

int Spclient::callInParameters(double lowsal, double medsal, double highsal, char * dept) 
{
   /********************************************************\
   * Call IN_PARAMS stored procedure                        *
   \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     /* Declare host variables for passing data to IN_PARAMS */
     double in_lowsal, in_medsal, in_highsal;
     char in_dept[4];
     /* Declare host variables for showing results of IN_PARAMS */
     double sum_salary;
   EXEC SQL END DECLARE SECTION;

   strcpy(procname, "IN_PARAMS");
   strcpy(in_dept, dept);
   in_lowsal = lowsal;
   in_medsal = medsal;
   in_highsal = highsal;

   EXEC SQL SELECT SUM(salary) INTO :sum_salary FROM employee WHERE workdept = :in_dept;
   EMB_SQL_CHECK("SUM BEFORE");
   printf("\nSum of salaries for dept. %s = %8.2f before calling %s\n", in_dept, sum_salary, procname);
   printf("CALL stored procedure named %s\n", procname);

   /* IN_PARAMS is PS GENERAL, so do not pass null indicators */
   EXEC SQL CALL :procname (:in_lowsal, :in_medsal, :in_highsal, :in_dept, :out_sqlcode, :out_buffer); 
   EMB_SQL_CHECK("CALL IN_PARAMS");
   /* Check that the stored procedure executed successfully */
   if (out_sqlcode == 0)
   { 
     printf("Stored procedure returned successfully\n");

     /********************************************************\
     * Display the sum salaries for the affected department   *
     \********************************************************/

     EXEC SQL SELECT SUM(salary) INTO :sum_salary FROM employee WHERE workdept = :in_dept;
     EMB_SQL_CHECK("SUM AFTER");
     printf("Sum of salaries for dept. %s = %8.2f after calling %s\n", in_dept, sum_salary, procname);
   }
   else
   { /* print the error message, roll back the transaction */
     printf("Stored procedure returned SQLCODE %d\n", out_sqlcode);
     printf("from procedure section labelled \"%s\"\n", out_buffer);
  
     EXEC SQL ROLLBACK;
     EMB_SQL_CHECK("ROLLBACK");
   }

  return 0;
}

int Spclient::callInoutParameter(double median) 
{
   /********************************************************\
   * Call INOUT_PARAM stored procedure                      *
   \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     double inout_median;
     sqlint16 medianind, codeind, bufferind;
   EXEC SQL END DECLARE SECTION;

   strcpy(procname, "INOUT_PARAM");

   if (median < 0)
   {
     /* Salary was negative, indicating a probable error,
        so pass a null value to the stored procedure instead
        by setting medianind to a negative value */

     medianind = -1;
     codeind = -1;
     bufferind = -1;
   }
   else
   {
     /* Salary was positive, so pass the value of median
        to the stored procedure by setting medianind to 0 */

     inout_median = median;
     medianind = 0;
     codeind = -1;
     bufferind = -1;
   }

   /* INOUT_PARAM is PS GENERAL WITH NULLS, so pass null indicators */
   EXEC SQL CALL :procname (:inout_median:medianind, :out_sqlcode:codeind, :out_buffer:bufferind); 
   EMB_SQL_CHECK("CALL INOUT_PARAM");
   /* Check that the stored procedure executed successfully */
   if (out_sqlcode == 0 && medianind == 0)
   { 
     printf("Stored procedure returned successfully\n");
     printf("Median salary returned from INOUT_PARAM = %8.2f\n", inout_median);
   }
   else if (medianind < 0)
   {
     printf("Stored procedure returned NULL values\n");
   }
   else
   { /* print the error message, roll back the transaction */
     printf("Stored procedure returned SQLCODE %d\n", out_sqlcode);
     printf("from procedure section labelled \"%s\"\n", out_buffer);
  
     EXEC SQL ROLLBACK;
     EMB_SQL_CHECK("ROLLBACK");
   }

  return 0;
}

int Spclient::callClobExtract(char * empno) 
{
   /********************************************************\
   * Call CLOB_EXTRACT stored procedure                     *
   \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     /* Declare host variables for passing data to CLOB_EXTRACT */
     char in_empno[7];
     char out_resume[1001];
   EXEC SQL END DECLARE SECTION;

  strcpy(in_empno, empno);

  strcpy(procname, "CLOB_EXTRACT");
  printf("\nCALL stored procedure named %s\n", procname);

  /* CLOB_EXTRACT is PS GENERAL, so do not pass a null indicator */
  EXEC SQL CALL :procname (:in_empno, :out_resume, :out_sqlcode); 
  EMB_SQL_CHECK("CALL CLOB_EXTRACT");

  /* Check that the stored procedure executed successfully */
  if (out_sqlcode == 0)
  { 
    printf("Stored procedure returned successfully\n");
    printf("Resume section returned from CLOB_EXTRACT = \n%s\n", out_resume);
  }
  else
  { /* print the error message */
    printf("Stored procedure returned SQLCODE %d\n", out_sqlcode);
    printf("from procedure section labelled \"%s\"\n", out_buffer);
  }

  return 0;
}

int Spclient::callAllDataTypes() 
{
   /********************************************************\
   * Call ALL_DATA_TYPES stored procedure                   *
   \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     sqlint16 inout_smallint;
     sqlint32 inout_integer;
     sqlint64 inout_bigint;
     float inout_real;
     double inout_double;
     char out_char;
     char out_chars[16];
     char out_varchar[13];
     char out_date[11];
     char out_time[9];
   EXEC SQL END DECLARE SECTION;

   inout_smallint = 32000;
   inout_integer = 2147483000;
   inout_bigint = 2147480000;
   /* Maximum value of BIGINT is 9223372036854775807 */
   /* but some platforms only support 32-bit integers */
   inout_real = 100000;
   inout_double = 2500000;

   strcpy(procname, "ALL_DATA_TYPES");
   printf("\nCALL stored procedure named %s\n", procname);

   /* ALL_DATA_TYPES is PS GENERAL, so do not pass null indicators */
   EXEC SQL CALL :procname (:inout_smallint, :inout_integer, :inout_bigint, :inout_real, :inout_double, :out_char, :out_chars, :out_varchar, :out_date, :out_time, :out_sqlcode, :out_buffer); 
   EMB_SQL_CHECK("CALL ALL_DATA_TYPES");

   /* Check that the stored procedure executed successfully */
   if (out_sqlcode == 0)
   { 
     printf("Stored procedure returned successfully\n");

     /********************************************************\
     * Display the sum salaries for the affected department   *
     \********************************************************/

     printf("Value of SMALLINT = %d\n", inout_smallint);
     printf("Value of INTEGER = %ld\n", inout_integer);
     printf("Value of BIGINT = %lld\n", inout_bigint);
     printf("Value of REAL = %.2f\n", inout_real);
     printf("Value of DOUBLE = %.2lf\n", inout_double);
     printf("Value of CHAR(1) = %c\n", out_char);
     printf("Value of CHAR(15) = %s\n", out_chars);
     printf("Value of VARCHAR(12) = %s\n", out_varchar);
     printf("Value of DATE = %s\n", out_date);
     printf("Value of TIME = %s\n", out_time);
   }
   else
   { /* print the error message */
     printf("Stored procedure returned SQLCODE %d\n", out_sqlcode);
     printf("from procedure section labelled \"%s\"\n", out_buffer);
   }

  return 0;
}

int Spclient::callDB2SQL(char job_name[9])
{
   char *token = "\xff";
   char *sqlmsg[3];
   char *message;

   /********************************************************\
   * Call DB2SQL_EXAMPLE stored procedure                   *
   \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     char in_job[9];
     sqlint16 in_jobind;
     double out_salary;
     sqlint16 out_salaryind;
   EXEC SQL END DECLARE SECTION;

  strcpy(procname, "DB2SQL_EXAMPLE");
  printf("\nCALL stored procedure named %s\n", procname);

  /* out_salary is an OUT parameter, so set the
     null indicator to -1 to indicate no input value */
  out_salaryind = -1;

  strcpy(in_job, job_name);

  /* in_job is an IN parameter, so check to see
     if there is any input value */
  if (strlen(in_job) == 0)
  {
     /* in_job is null, so set the null indicator
	to -1 to indicate there is no input value */
     in_jobind = -1;
     printf("with NULL input, to return a custom SQLSTATE");
     printf(" and diagnostic message\n");
  }
  else
  {
     /* in_job is not null, so set the null indicator
	to 0 to indicate there is an input value */
     in_jobind = 0;
  }

  /* DB2SQL_EXAMPLE is PS DB2SQL, so pass
     a null indicator for each parameter */
  EXEC SQL CALL :procname (:in_job:in_jobind,
      :out_salary:out_salaryind); 

  /* DB2SQL stored procedures can return a custom
     SQLSTATE and diagnostic message, so instead of
     using the EMB_SQL_CHECK macro to check the value
     of the returned SQLCODE, check the SQLCA structure
     for the value of the SQLSTATE and the diagnostic message */

  /* Check value of returned SQLSTATE */
  if (strncmp(sqlca.sqlstate, "00000", 5) == 0) {
    printf("Stored procedure returned successfully\n");
    printf("Average salary for job %s = %9.2f\n",
      in_job, out_salary);
  }
  else {
     printf("Stored procedure failed with SQLSTATE %s\n",
       sqlca.sqlstate);
     printf("Stored procedure returned the following ");
     printf("diagnostic message:\n");

     /* Allocate memory for diagnostic string */
     message = (char *) malloc(sqlca.sqlerrml);

     /* Copy diagnostic message into string for use with strtok */
     strncpy((char *)message, (char *)sqlca.sqlerrmc, sqlca.sqlerrml);

     /* First token is the procedure name */
     sqlmsg[0] = strtok(message, token);

     /* Second token is the procedure entry point */
     sqlmsg[1] = strtok(NULL, token);

     /* Third token is the diagnostic message */
     sqlmsg[2] = strtok(NULL, token);
     printf("  \"%s\"\n", sqlmsg[2]);
  }

  return 0;
}

int Spclient::callDBINFO(char * in_job) 
{
   /********************************************************\
    * Call DBINFO_EXAMPLE stored procedure                   *
    \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     char dbinfo_in_job[9];
     double dbinfo_out_salary;
     char out_dbname[129];  /* Name of database from DBINFO structure */
     char out_dbversion[9]; /* Version of database from DBINFO structure */
   EXEC SQL END DECLARE SECTION;

   strcpy(dbinfo_in_job, in_job);

   strcpy(procname, "DBINFO_EXAMPLE");
   printf("\nCALL stored procedure named %s\n", procname);

   /* DBINFO_EXAMPLE is PS GENERAL, so do not pass null indicators */
   EXEC SQL CALL :procname (:dbinfo_in_job, :dbinfo_out_salary, :out_dbname, :out_dbversion, :out_sqlcode); 
   EMB_SQL_CHECK("CALL DBINFO_EXAMPLE");

   printf("Stored procedure returned successfully with SQLCODE = %d\n", out_sqlcode);
   printf("Average salary for job %s = %9.2lf\n", dbinfo_in_job, dbinfo_out_salary);
   printf("Database name from DBINFO structure = %s\n", out_dbname);
   printf("Database version from DBINFO structure = %s\n", out_dbversion);

   return 0;
}

int Spclient::callProgramTypeMain(char * in_job) 
{
   /********************************************************\
   * Call MAIN_EXAMPLE stored procedure                     *
   \********************************************************/

   EXEC SQL BEGIN DECLARE SECTION;
     char main_in_job[9];
     double main_out_salary;
   EXEC SQL END DECLARE SECTION;

   strcpy(main_in_job, in_job);

  strcpy(procname, "MAIN_EXAMPLE");
  printf("\nCALL stored procedure named %s\n", procname);

  /* MAIN_EXAMPLE is PS DB2 GENERAL, so do not pass null indicators */
  EXEC SQL CALL :procname (:main_in_job, :main_out_salary, :out_sqlcode); 
  EMB_SQL_CHECK("CALL MAIN_EXAMPLE");

  /* Check value of returned SQLCODE */
  if (out_sqlcode == 0) {
    printf("Stored procedure returned successfully\n");
    printf("Average salary for job %s = %9.2lf\n", main_in_job, main_out_salary);
  }
  else {
     printf("Stored procedure failed with SQLCODE %d\n", out_sqlcode);
  }

return 0;
}

Spclient::~Spclient() 
{
}

int main(int argc, char *argv[]) 
{
   if (argc == 1)
   { 
      Spclient spcli;
      spcli.Call_StorProcs();
   }
   else if (argc == 3) 
   {
      Spclient spcli(argv[1], argv[2]);
      spcli.Call_StorProcs();
   }
   else if (argc == 4) 
   {
      Spclient spcli(argv[1], argv[2], argv[3]);
      spcli.Call_StorProcs();
   }
   else 
   {
      printf ("\nUSAGE: spclient [ database ] [ userID passwd ]\n\n");
      return 1;
   }
   return 0;
}

/* end of program : spclient.sqC */