/*******************************************************************************
**                                                                        
** Source File Name = xfetch.c  1.9.2.2                                      
**                                                                        
** 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 :
**
** A DB2 Version 2 sample that has been unchanged. See the CLI sample 
** xfetch.c for the same program updated to use the latest set of functions.
**
** - Uses ExtendedFetch, Both Row-Wise (stmt2) and Column-Wise (stmt1)
**   Fetches ROWSET_SIZE rows at a time.
**                                                                        
** For more information about these samples see the README file.
**
** For more information on programming in CLI see the:
**     - "Building CLI Applications" section of the Application Building Guide, and the
**     - CLI Guide and Reference.
**
** For more information on the SQL language see the SQL Reference.
**
*******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "sqlcli.h"
#include "sqlcli1.h"
#include "v2sutil.h"           /* Header file for CLI sample code */

/* For the Macintosh environment when generating 68K applications */
#ifdef DB268K
   /* Need to include ASLM for 68K applications */
   #include <LibraryManager.h>
#endif

#define MAX_STMT_LEN 255
#define ROWSET_SIZE  10

/* Global Variables for user id and password.
   To keep samples simple, not a recommended practice.
*/
    SQLCHAR   server[SQL_MAX_DSN_LENGTH + 1];
    SQLCHAR   uid[MAX_UID_LENGTH + 1];
    SQLCHAR   pwd[MAX_PWD_LENGTH + 1];

/*******************************************************************
** main
*******************************************************************/
int
main( int argc, char * argv[] )
{
    SQLHENV         henv;
    SQLHDBC         hdbc;
    SQLHSTMT        hstmt;
    SQLRETURN       rc;
    SQLCHAR         stmt[] =
    "SELECT deptnumb, deptname, id, name FROM staff, org \
                     WHERE dept=deptnumb AND job = 'Mgr'";

    /* Column-Wise */
    SQLINTEGER      deptnumb[ROWSET_SIZE];

    SQLCHAR         deptname[ROWSET_SIZE][15];
    SQLINTEGER      deptname_l[ROWSET_SIZE];

    SQLSMALLINT     id[ROWSET_SIZE];

    SQLCHAR         name[ROWSET_SIZE][10];
    SQLINTEGER      name_l[ROWSET_SIZE];

    /* Row-Wise (Includes buffer for both column data and length) */
    struct {
        SQLINTEGER      deptnumb_l; /* length */
        SQLINTEGER      deptnumb; /* value  */
        SQLINTEGER      deptname_l;
        SQLCHAR         deptname[15];
        SQLINTEGER      id_l;
        SQLSMALLINT     id;
        SQLINTEGER      name_l;
        SQLCHAR         name[10];
    }               R[ROWSET_SIZE];

    SQLUSMALLINT    Row_Stat[ROWSET_SIZE];
    SQLUINTEGER     pcrow;
    int             i;

/* For the Macintosh environment when generating 68K applications */
#ifdef DB268K
   /* Before making any API calls for 68K environment, need to initialize the
      Library Manager */
   InitLibraryManager(0,kCurrentZone,kNormalMemory);
   atexit(CleanupLibraryManager);
#endif


 /* macro to initalize server, uid and pwd */
    INIT_UID_PWD;

    rc = SQLAllocEnv(&henv);    /* allocate an environment handle    */
    if (rc != SQL_SUCCESS)
        return (terminate(henv, rc));

    rc = DBconnect(henv, &hdbc);/* allocate a connect handle, and connect */
    CHECK_DBC(hdbc, rc);

    /*********************************************/
    /* Column-Wise Binding               */
    /*********************************************/
    rc = SQLAllocStmt(hdbc, &hstmt);
    CHECK_DBC(hdbc, rc);

    rc = SQLSetStmtOption(hstmt, SQL_ROWSET_SIZE, ROWSET_SIZE);
    CHECK_STMT(hstmt, rc);

    rc = SQLExecDirect(hstmt, stmt, SQL_NTS);
    CHECK_STMT(hstmt, rc);

    rc = SQLBindCol(hstmt, 1, SQL_C_LONG, (SQLPOINTER) deptnumb, 0, NULL);
    CHECK_STMT(hstmt, rc);

    rc = SQLBindCol(hstmt, 2, SQL_C_CHAR, (SQLPOINTER) deptname, 15, deptname_l);
    CHECK_STMT(hstmt, rc);

    rc = SQLBindCol(hstmt, 3, SQL_C_SSHORT, (SQLPOINTER) id, 0, NULL);
    CHECK_STMT(hstmt, rc);

    rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) name, 10, name_l);
    CHECK_STMT(hstmt, rc);

    /* Fetch ROWSET_SIZE rows ast a time, and display */
    printf("\nDEPTNUMB DEPTNAME         ID       NAME\n");
    printf("-------- -------------- -------- ---------\n");
    while ((rc = SQLExtendedFetch(hstmt, SQL_FETCH_NEXT, 0, &pcrow, Row_Stat))
           == SQL_SUCCESS) {
        for (i = 0; i < pcrow; i++) {
            printf("%8ld %-14s %8d %-9s\n", deptnumb[i], deptname[i], id[i], name[i]);
        }
        if (pcrow < ROWSET_SIZE)
            break;
    }                           /* endwhile */

    if (rc != SQL_NO_DATA_FOUND && rc != SQL_SUCCESS)
        check_error(henv, hdbc, hstmt, rc, __LINE__, __FILE__);

    rc = SQLFreeStmt(hstmt, SQL_DROP);

    /*********************************************/
    /* Row-Wise Binding               */
    /*********************************************/
    rc = SQLAllocStmt(hdbc, &hstmt);
    if (rc != SQL_SUCCESS)
        check_error(henv, hdbc, SQL_NULL_HSTMT, rc, __LINE__, __FILE__);

    /* Set maximum number of rows to receive with each extended fetch */
    rc = SQLSetStmtOption(hstmt, SQL_ROWSET_SIZE, ROWSET_SIZE);
    if (rc != SQL_SUCCESS)
        check_error(henv, hdbc, hstmt, rc, __LINE__, __FILE__);

    /*
     * Set vparam to size of one row, used as offset for each bindcol
     * rgbValue
     */
    /* ie. &(R[0].deptnumb) + vparam = &(R[1].deptnum) */
    rc = SQLSetStmtOption(hstmt, SQL_BIND_TYPE, sizeof(R) / ROWSET_SIZE);
    CHECK_STMT(hstmt, rc);

    rc = SQLExecDirect(hstmt, stmt, SQL_NTS);
    CHECK_STMT(hstmt, rc);

    rc = SQLBindCol(hstmt, 1, SQL_C_LONG, (SQLPOINTER) & R[0].deptnumb, 0,
                    &R[0].deptnumb_l);
    CHECK_STMT(hstmt, rc);

    rc = SQLBindCol(hstmt, 2, SQL_C_CHAR, (SQLPOINTER) R[0].deptname, 15,
                    &R[0].deptname_l);
    CHECK_STMT(hstmt, rc);

    rc = SQLBindCol(hstmt, 3, SQL_C_SSHORT, (SQLPOINTER) & R[0].id, 0,
                    &R[0].id_l);
    CHECK_STMT(hstmt, rc);

    rc = SQLBindCol(hstmt, 4, SQL_C_CHAR, (SQLPOINTER) R[0].name, 10, &R[0].name_l);
    CHECK_STMT(hstmt, rc);

    /* Fetch ROWSET_SIZE rows at a time, and display */
    printf("\nDEPTNUMB DEPTNAME         ID       NAME\n");
    printf("-------- -------------- -------- ---------\n");
    while ((rc = SQLExtendedFetch(hstmt, SQL_FETCH_NEXT, 0, &pcrow, Row_Stat))
           == SQL_SUCCESS) {
        for (i = 0; i < pcrow; i++) {
            printf("%8ld %-14s %8d %-9s\n", R[i].deptnumb, R[i].deptname,
                   R[i].id, R[i].name);
        }
        if (pcrow < ROWSET_SIZE)
            break;
    }                           /* endwhile */

    if (rc != SQL_NO_DATA_FOUND && rc != SQL_SUCCESS)
        check_error(henv, hdbc, hstmt, rc, __LINE__, __FILE__);
    /* Free handles, commit, exit */
    rc = SQLFreeStmt(hstmt, SQL_DROP);
    CHECK_STMT(hstmt, rc);

    rc = SQLTransact(henv, hdbc, SQL_COMMIT);
    CHECK_DBC(hdbc, rc);

    printf("\n>Disconnecting .....\n");
    rc = SQLDisconnect(hdbc);
    CHECK_DBC(hdbc, rc);

    rc = SQLFreeConnect(hdbc);
    CHECK_DBC(hdbc, rc);

    rc = SQLFreeEnv(henv);
    if (rc != SQL_SUCCESS)
        return (terminate(henv, rc));

    return (SQL_SUCCESS);
}                               /* end main */