/*
 * NAME
 *     tst_num_arrays
 *
 * USAGE
 *      tst_num_arrays [-d database] [-o output_file] [-g 0|1|2] [-t] 
 *
 * ARGUMENTS
 *     -d   POSTGRES database name
 *
 *     -o   Output filename. If not set, output is sent to the screen.
 *
 *     -g   gdi degub level: 0 (off) by default
 *          1 = GDI_DEBUG_ON
 *          2 = GDI_DEBUG_VERBOSE
 *
 *     -t   turns PQtrace on
 *
 * DESCRIPTION
 *      Tests undimensioned numeric arrays.
 *
 * AUTHOR
 *     Jean T. Anderson
 */
#ifndef lint
static char     SccsId[] = "@(#)tst_num_arrays.c	1.1 8/2/93";
#endif

#include <stdio.h>
#include <stddef.h>
#include "gdi_postgres.h"
#include "gdi_turbo.h"
#include "errno.h"
#include "proto.h"

FILE      *fp, *fopen();
extern    void perror();
extern    int getopt();

Proto     (static void,     pg_cleanup, (dbConn *dbconn));
Proto     (static dbStatus, pg_arrays,  (dbconn *dbconn));

dbConstr  *constr;

char      filename[256];

#define USAGE\
"Usage:\ttst_num_arrays\t[-d database] [-o output_filename] [-g 0|1|2] [-t]"

extern char     *optarg;

/****************************************************************************/
/*  main                                                                    */
/****************************************************************************/
void
main(argc, argv)
int        argc;
char      **argv;
{
     char    *vendor="postgres";
     char    database[GDI_DBNAME_SIZE +1];

     int     c;

     dbConn  *dbconn = NULL;      /* GDI database connector */
     int     debug=0, trace=0;    /* GDI debug and trace */

     /* GDI_TURBO is the only constructor that does POSTGRES array types */
     constr = &GDI_TURBO;

     /*=====================================================*
      *========= Get command line arguments ================*
      *=====================================================*/

     database[0] = '\0';
     filename[0] = '\0';

     while ((c = getopt(argc, argv, "d:g:ho:t")) != EOF)
     {
          switch(c)
          {
          case 'd':
               (void) strncpy (database, optarg, sizeof(database) - 1);
               database[sizeof(database) - 1] = '\0';
               break;
          case 'o':
               (void) strncpy (filename, optarg, sizeof(filename) - 1);
               filename[sizeof(filename) - 1] = '\0';
               break;
          case 'g':
               debug = atoi (optarg);
               break;
          case 'h':
               fprintf(stderr, "%s\n", USAGE);
               exit(0);
          case 't':
               trace++;
               break;
          default:
               fprintf(stderr, "%s\n", USAGE);
               exit(1);
          }
     }

     /* ==============
      * Initialize GDI
      * ==============
      */

     gdi_init(argv[0]);

     /* ====================
      * Connect to Database
      * ====================
      */
     if ((dbconn = gdi_open(vendor, NULL, NULL, database, NULL, NULL))
          == (dbConn *)NULL )
     {
          fprintf (stderr, "Connect failed: %s\n", 
                    GDI_ERROR_MSG( (dbConn *)NULL) );
          exit (GDI_FAILURE);
     }

     /* ====================
      * Set Debug & Trace
      * ====================
      */
     (void) gdi_error_init(dbconn, (dbDebug) debug, GDI_WARNING, 
          GDI_NOT_USED, GDI_NOT_USED);

     if(trace)
          gdi_trace(dbconn, TRUE, "");

     /* ====================
      * Open output file
      * ====================
      */
     if(filename[0] == '\0')
          fp=stdout;
     else 
     {    fp=fopen(filename, "w");
          if(fp == NULL)
          {    perror (argv[0]);
               (void) gdi_close(dbconn);
               exit(GDI_FAILURE);
          }
     }

     if( (pg_arrays(dbconn)) != GDI_SUCCESS)
     {
          fprintf (stderr, "pg_class failed: %s\n", 
               GDI_ERROR_MSG(dbconn));
          pg_cleanup(dbconn);
          exit(GDI_FAILURE);
     }
     pg_cleanup(dbconn);
     exit(GDI_SUCCESS);
}

static
dbStatus
pg_arrays(dbconn)
dbConn  *dbconn;
{
     char     query[80];
     int      i, j, k, tuples1, col_num;

     dbObj    *result = NULL;
     turboTup *tuple1 = NULL;

     char     array_name [PG_CLASS_SIZE + 1];
     int      array_size, str_size;
  
     long     int4_test, **int4_array;
     float    flt4_test, **flt4_array;
     double   flt8_test, **flt8_array;

     int      str_length, arr_length, is_null;

     sprintf(query, "retrieve (array_num.all)");

     if(gdi_submit(dbconn, query, GDI_FETCH_ALL, constr, &result)
          != GDI_SUCCESS)
     {    result = gdi_obj_destroy (result);
          return(GDI_FAILURE);
     }

     tuples1=GDI_OBJ_NUM_TUPLES(result);
     if(tuples1 == 0 )
     {    
          fprintf(fp, "No data found.\n");
          result = gdi_obj_destroy(result);
          return(GDI_SUCCESS);
     }
     col_num = GDI_OBJ_NUM_COLUMNS(result);

     for(i=0; i < tuples1; i++)  
     {
          if ((tuple1 = gdi_obj_tuple_retrieve (result, i)) == NULL) 
          {    fprintf(fp, "\ngdi_obj_tuple_retrieve failed on tuple1 row %d\n",
                    i+1);
               result = gdi_obj_destroy(result);
               return(GDI_FAILURE);
          }

          for(j=0; j < col_num; j++)
          {
               switch(j)
               {
               case 0: /* Column 0: int4_test */

                    if( (int4_array = (long **) gdi_obj_get_data (result, j, 
                        tuple1, &is_null, &str_length, &arr_length)) == NULL)
                    {    fprintf(stderr,
                              "tst_num_arrays: could not get column %d\n", j);
                         result = gdi_obj_destroy(result);
                         return(GDI_FAILURE);
                    }

                    fprintf(fp,"\nTuple %d Column %d has %d elements.", 
                         i, j, arr_length);

                    fprintf(fp, " Values are:\n");

                    for (k=0; k < arr_length; k++)
                    {
                         int4_test = (* int4_array)[k];
                         fprintf(fp, "%d\t", int4_test);
                    }
                    fprintf(fp, "\n");
                    break;
               case 1: /* Column 1: flt4_test */
                    if( (flt4_array = (float **) gdi_obj_get_data (result, j, 
                        tuple1, &is_null, &str_length, &arr_length)) == NULL)
                    {    fprintf(stderr,
                              "tst_num_arrays: could not get column %d\n", j);
                         result = gdi_obj_destroy(result);
                         return(GDI_FAILURE);
                    }

                    fprintf(fp,"\nTuple %d Column %d has %d elements.", 
                         i, j, arr_length);

                    fprintf(fp, " Values are:\n");

                    for (k=0; k < arr_length; k++)
                    {
                         flt4_test = (* flt4_array)[k];
                         fprintf(fp, "%f\t", flt4_test);
                    }
                    fprintf(fp, "\n");
                    break;
               case 2: /* Column 2: flt8_test */
                    if( (flt8_array = (double **) gdi_obj_get_data (result, j, 
                        tuple1, &is_null, &str_length, &arr_length)) == NULL)
                    {    fprintf(stderr,
                              "tst_num_arrays: could not get column %d\n", j);
                         result = gdi_obj_destroy(result);
                         return(GDI_FAILURE);
                    }

                    fprintf(fp,"\nTuple %d Column %d has %d elements.", 
                         i, j, arr_length);

                    fprintf(fp, " Values are:\n");

                    for (k=0; k < arr_length; k++)
                    {
                         flt8_test = (* flt8_array)[k];
                         fprintf(fp, "%f\t", flt8_test);
                    }
                    fprintf(fp, "\n");
                    break;
               default:
                    fprintf(fp, "Hmmmmm, didn't know about column %d\n", j);
                    break;
                    
               } /* End switch */

          } /* End loop on columns */

     } /* End loop on tuples */ 

     result = gdi_obj_destroy(result);
     return(GDI_SUCCESS);
}

static
void
pg_cleanup(dbconn)
dbConn     *dbconn;
{
     if(gdi_close(dbconn) != GDI_SUCCESS)
     {
          fprintf (stderr, "gdi_close failed: %s\n", 
               GDI_ERROR_MSG(dbconn));
          exit(GDI_FAILURE);
     }

     if(strlen(filename) > 0)
          fclose(filename);
     return;
}
