/*
** sqberrt.c
** testprogram for various fetch errors
**
** Klaus Thiele (kth@oblib.teuto.de) - June '95
**
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sql.h>
#include <errsql.h>

#ifndef HOST
#define HOST NULL
#endif

void failure( SQLTCUR cur, char *msg );

int main( void ) {

SQLTCUR       cur;
SQLTRCD       rcd;
SQLTDAP       stmt;
SQLTDDT       ddt[5];
SQLTPDL       pdl[5];
SQLTCDL       cvl[5];
SQLTFSC       flag[5];
SQLTROW       nrr;
SQLTNSI       nsi;
char          errmsg[SQLMERR];
unsigned char param;

int           xnr;
char          xstr[21];
unsigned int  xint;
double        xnum;
char          xchr;

int           i;
char          col[5][21];
char          *fe[8] = { "Ok.",
                         "data truncated",
                         "signed number fetched",
                         "data is not numeric",
                         "numeric overflow",
                         "data type not supported",
                         "data is not in date format",
                         "data is null" };
                         
   /*
   ** connect cursor to database
   */
#ifdef __MSDOS__
   if( (rcd = sqlcnc( &cur, (SQLTDAP)"LOGAKTH/L2001/L2001", 0)) ) {
#else
   if( (rcd = sqlcnc( &cur, (SQLTDAP)"SQLBASE", 0, (SQLTDAP)HOST)) ) {
#endif
         sqlerr(rcd, (SQLTDAP)&errmsg);
         printf("%d: %s\n", rcd, errmsg);
         return( 1 );
   }

   /*
   ** Frontend result sets
   */
   param = 1;
   if(sqlset( cur, SQLPFRS, (SQLTDAP)&param, 0 ) != 0) {
      failure( cur, "sqlset" );
   } else printf("using Frontend result sets.\n");

   /*
   ** set the null indicator to get FETRNUL in the fetchflag when
   ** fetching a null column
   */
   param = 1;
   if(sqlset( cur, SQLPNIE, (SQLTDAP)&param, 0 ) != 0) {
      failure( cur, "sqlset" );
   } else printf("Null indicator set to 1.\n");


   stmt = (SQLTDAP)"SELECT XNR,XSTR,XINT,XNUM,XCHR FROM TEST ORDER BY XNR";

   /*
   ** set result set mode
   */
   if( sqlsrs( cur ) ) {
      failure( cur, "sqlsrs" );
   } else printf("Result set mode set.\n");

   /*
   ** compile and execute
   */
   if( sqlcex( cur, stmt, 0 ) )
      failure( cur, "sqlcex" );

   /*
   ** set select buffers
   */
   memset( flag, '\0', sizeof(flag) );
   memset( cvl,  '\0', sizeof(cvl) );
   if( sqlssb( cur, 1, SQLPSIN, (SQLTDAP)&xnr,  sizeof(xnr),    0, &cvl[0], &flag[0] ) ||
       sqlssb( cur, 2, SQLPBUF, (SQLTDAP)xstr,  8,              0, &cvl[1], &flag[1] ) ||
       sqlssb( cur, 3, SQLPUIN, (SQLTDAP)&xint, sizeof(xint),   0, &cvl[2], &flag[2] ) ||
       sqlssb( cur, 4, SQLPDOU, (SQLTDAP)&xnum, sizeof(xnum),   0, &cvl[3], &flag[3] ) ||
       sqlssb( cur, 5, SQLPBUF, (SQLTDAP)&xchr, sizeof(xchr),   0, &cvl[4], &flag[4] ) )
      failure( cur, "sqlssb" );

   /*
   ** get data types and column headings
   */
   memset( col, '\0', sizeof(col) );
   memset( ddt, '\0', sizeof(ddt) );
   memset( pdl, '\0', sizeof(pdl) );
   if( sqldes(cur, 1, &ddt[0], &pdl[0], (SQLTCHP)&col[0], SQLNPTR, SQLNPTR, SQLNPTR) ||
       sqldes(cur, 2, &ddt[1], &pdl[1], (SQLTCHP)&col[1], SQLNPTR, SQLNPTR, SQLNPTR) ||
       sqldes(cur, 3, &ddt[2], &pdl[2], (SQLTCHP)&col[2], SQLNPTR, SQLNPTR, SQLNPTR) ||
       sqldes(cur, 4, &ddt[3], &pdl[3], (SQLTCHP)&col[3], SQLNPTR, SQLNPTR, SQLNPTR) ||
       sqldes(cur, 5, &ddt[4], &pdl[4], (SQLTCHP)&col[4], SQLNPTR, SQLNPTR, SQLNPTR) )
      failure( cur, "sqldes" );


   if( sqlnsi( cur, &nsi ) )
      failure( cur, "sqlnsi" );
   else printf("Number of select items: %d\n", nsi);

   if( sqlnrr( cur, &nrr ) )
      failure( cur, "sqlnrr" );
   else printf("Number of rows fetched: %ld\n", nrr);


   /*
   ** fetch rows
   */
   while( 1 ) {

      xnr = 0; xint = 0; xnum = 0.0; xchr = '\0';
      memset( xstr, '\0', sizeof(xstr) );
      memset( flag, '\0', sizeof(flag) );

      printf( "Row? " );
      scanf( "%d", &i );
      if( sqlprs(cur, (SQLTROW)i) )
         failure( cur, "sqlprs" );

      rcd = sqlfet( cur );
      if( rcd == FETEEOF || rcd == SQLEIRN )
         break;

         printf( "%6s: %d (%s, %d)\n", col[0], xnr,  fe[(int)flag[0]], (int)cvl[0] );
         printf( "%6s: %s (%s, %d)\n", col[1], xstr, fe[(int)flag[1]], (int)cvl[1] );
         printf( "%6s: %d (%s, %d)\n", col[2], xint, fe[(int)flag[2]], (int)cvl[2] );
         printf( "%6s: %f (%s, %d)\n", col[3], xnum, fe[(int)flag[3]], (int)cvl[3] );
         printf( "%6s: %c (%s, %d)\n", col[4], xchr, fe[(int)flag[4]], (int)cvl[4] );
         printf( "--[%d]----------------------------------------------\n",rcd);

   }

   /*
   ** disconnect cursor
   */
   sqldis( cur );

   return(0);
}


void failure( SQLTCUR cur, char *msg ) {

SQLTRCD rcd;
char    errmsg[SQLMERR];

   sqlrcd(cur, &rcd);
   sqlerr(rcd, (SQLTDAP)errmsg);
   printf("Failure on %s\n", msg);
   printf("[%d]: %s\n", rcd, errmsg);
   sqldis(cur);

   exit( 1 );
}

