// Pro*C Cursor Tutorial at RJM Programming 29/6/2013 Copyright RJM Programming (c) 2013
// Pro-C_Cursor.c

#include <stdio.h> //accesses the printf() function
#include <conio.h> //accesses the getch() funtion


// Thanks to http://www.ehow.com/how_6943222_run-program-visual-studio.html


//#include <sqlca.h>
//#include <sqlcpr.h>
//#include <oraca.h>
//#include <sqlda.h>

//#ifndef ORATYPES
//#include <oratypes.h>
//#endif

//#ifndef OCI_ORACLE
//#include <oci.h>
//#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#ifndef OCISC_ORACLE
//# define OCISC_ORACLE

// Thanks heaps to https://forums.oracle.com/message/11049975?tstart=0

#ifndef OCISC_ORACLE  
#include "Pro-C_Cursor.h"  
#endif 

static OCIError    *errhp;  
static OCIEnv      *envhp;  
static  OCIServer   *svrhp = (OCIServer *)0;  
static  OCISession  *sesnhp = (OCISession *)0;  
static  OCISvcCtx   *svchp = (OCISvcCtx *)0;  
static  OCIStmt     *stmthp = (OCIStmt *)0;  

static OCIEnv *p_env;

static OCIError *p_err;

static OCISvcCtx *p_svc;

static OCIStmt *p_sql;

static OCIDefine *p_dfn = (OCIDefine *) 0;

static OCIBind *p_bnd = (OCIBind *) 0;

  
static CONST OraText *database = (OraText *)"";  
static CONST OraText *username = (OraText *)"SYSTEM";  
static CONST OraText *password = (OraText *)"..........";   

   
void main(void)  
{  
  int i = 0;  
  sword lstat;  
  
  //OCIEnvCreate ((OCIEnv **)&envhp, (ub4)OCI_THREADED, (dvoid *)0,  
  //  (dvoid * (*) (dvoid *, size_t))0, (dvoid * (*)(dvoid *, dvoid *, size_t))0,  
  //  (void (*)(dvoid *, dvoid *))0, (size_t)0, (dvoid **)0);  
  OCIEnvCreate ((OCIEnv **)&p_env, (ub4)OCI_THREADED, (dvoid *)0,  
    (dvoid * (*) (dvoid *, size_t))0, (dvoid * (*)(dvoid *, dvoid *, size_t))0,  
    (void (*)(dvoid *, dvoid *))0, (size_t)0, (dvoid **)0);  

  //(void) OCIHandleAlloc((dvoid *) envhp, (dvoid **) &errhp, OCI_HTYPE_ERROR,  (size_t) 0, (dvoid **) 0);  
  (void) OCIHandleAlloc( (dvoid *)p_env, (dvoid **) &p_err, OCI_HTYPE_ERROR, (size_t) 0, (dvoid **) 0); 
  (void) OCIHandleAlloc( (dvoid *) p_env, (dvoid **) &p_sql, OCI_HTYPE_STMT, (size_t) 0, (dvoid **) 0); 
   
  //lstat = OCILogon2(envhp, errhp, &svchp, username, (ub4)strlen ((char *)username),password, (ub4)strlen ((char *)password), database, (ub4)strlen((char *)database),OCI_DEFAULT);  
  lstat = OCILogon2(p_env, p_err, &svchp, username, (ub4)strlen ((char *)username),password, (ub4)strlen ((char *)password), database, (ub4)strlen((char *)database),OCI_DEFAULT);  
  
  //if (lstat)  
  //   checkerr(errhp, lstat);  
  if (lstat)  
     checkerr(p_err, lstat);  
  
  queryRows(svchp);  
  
  /* close connection */  
  //lstat = OCILogoff(svchp, errhp);  
  //if (lstat)  
  //    checkerr(errhp, lstat);  
  lstat = OCILogoff(svchp, p_err);  
  if (lstat)  
      checkerr(p_err, lstat);  
  
  //checkerr(errhp, OCIHandleFree((dvoid *)errhp, OCI_HTYPE_ERROR));  
  checkerr(p_err, OCIHandleFree((dvoid *)p_err, OCI_HTYPE_ERROR));  
  getch();
  return 0;  
} /* end of main () */  


  
/* Displays the contents of EMP table */  
static void queryRows(OCISvcCtx *svchp)   
{  
  //sword status = 0;  
  //int status = 0;
  //static text *upd=(text *)  
  //      "update employees set salary = 20000 WHERE employee_id = 10";  
  static text *selt=(text *)  
      "select (RTRIM(table_name) || ':' || RTRIM(column_name)) from all_tab_columns where table_name like '%'";  
  
  static CONST text *tag = (text *)"tagA";  
  static CONST text *tag1 =(text *)"tagB";  
  OCIType *addr_tdo = (OCIType *) 0;
  OCIDefine *defn1p = (OCIDefine *) 0, *defn2p = (OCIDefine *) 0;
  char addr[21];
  char tablecol[250];
  int i = 0;
  OCIRef *addrref = (OCIRef *) 0;
  OCIRef *type_ref = (OCIRef *) 0;
  sb4 status;
  OCIDescribe *dschp = (OCIDescribe *) 0;
  OCIParam *parmp;
  ub4     ref_len;
  
  /* Calling OCIStmtPrepare2 with a SQLtext specified */  
  
  //status= OCIStmtPrepare2 ((OCISvcCtx *)svchp,(OCIStmt **)&stmthp,   
  //          (OCIError *)errhp, (text *)upd, (ub4)strlen((char *)upd),   
  //          NULL,0,OCI_NTV_SYNTAX,OCI_DEFAULT);  


  status = OCIStmtPrepare(p_sql, p_err, (text *)selt,
				(ub4) 104, (ub4) OCI_NTV_SYNTAX, (ub4) OCI_DEFAULT); 
  
  if (status != OCI_SUCCESS )  
  {  
     //printf("OCIStmtPrepare2 Failure...\n");  
     //checkerr(errhp, status);  
     printf("OCIStmtPrepare Failure...\n");  
     checkerr(p_err, status);  
  }  
  else  
  {  
     //printf("OCIStmtPrepare2 Success...\n");  
     printf("OCIStmtPrepare Success...\n");  
  }  

   
  checkerr(p_err, OCIDefineByPos(p_sql, &defn1p, p_err, (ub4) 1, (dvoid *) 
               &tablecol, (sb4) 250, SQLT_STR, (dvoid *) 0, (ub2 *)0,
               (ub2 *)0, (ub4) OCI_DEFAULT));


  
  checkerr(p_err, OCIStmtExecute(svchp, p_sql, p_err, (ub4) 1, (ub4) 0, 
               (OCISnapshot *) NULL, (OCISnapshot *) NULL, (ub4) OCI_DEFAULT));
  
  do
  {
    printf("Table:Column = %s\n", tablecol);
    
    //if ( addrref )
    //{
    //  pin_display_addr(envhp, p_err, addrref);
    //}
    //else
    //  printf("Address ref is NULL\n");
    
  }
  while ((status = OCIStmtFetch(p_sql, p_err, (ub4) 1,  (ub4) OCI_FETCH_NEXT,
                               (ub4) OCI_DEFAULT)) == OCI_SUCCESS ||
                                status == OCI_SUCCESS_WITH_INFO);
  
  
  if ( status != OCI_NO_DATA ) {
    checkerr(p_err, status);
  
    printf("\n\n");
    OCIHandleFree((dvoid *) defn1p, (ub4) OCI_HTYPE_DEFINE);
    //checkerr(p_err, OCIHandleFree((dvoid *) defn2p, (ub4) OCI_HTYPE_DEFINE));
  
    OCIHandleFree((dvoid *) p_sql, OCI_HTYPE_STMT); /* Free handles */

    OCIHandleFree((dvoid *) p_err, OCI_HTYPE_ERROR);
  } else {
	printf("End of records ... thanks for watching this tutorial\n");

  }



  
  /*Tag the statement prepared*/  
  //OCIStmtRelease ((OCIStmt *)stmthp, (OCIError *)errhp,tag ,  
  //   (ub4)strlen((char *)tag),OCI_DEFAULT);  
  /*
  status = OCIStmtRelease ((OCIStmt *)p_sql, (OCIError *)p_err,tag,  
     (ub4)strlen((char *)tag),OCI_DEFAULT);  
  
  if ( status != OCI_SUCCESS )  
  {  
     printf("OCIStmtRelease Failure...\n");  
     //checkerr(errhp, status);  
     checkerr(p_err, status);  
  }  
  else  
  {  
     printf("OCIStmtRelease Success...\n");  
  }  
    */
  
} /* end of queryRows() */  
  
  
/* This function prints the error */  
void checkerr(OCIError *errhp,sword  status)  
{  
    text errbuf[512];  
    sb4 errcode = 0;  
  
    switch (status)  
    {  
    case OCI_SUCCESS:  
      break;  
    case OCI_SUCCESS_WITH_INFO:  
      (void) printf("Error - OCI_SUCCESS_WITH_INFO\n");  
      break;  
    case OCI_NEED_DATA:  
      (void) printf("Error - OCI_NEED_DATA\n");  
      break;  
    case OCI_NO_DATA:  
      (void) printf("Error - OCI_NODATA\n");  
      break;  
    case OCI_ERROR:  
      (void) OCIErrorGet((dvoid *)errhp, (ub4) 1, (text *) NULL, &errcode,  
                          errbuf, (ub4) sizeof(errbuf), OCI_HTYPE_ERROR);  
      (void) printf("Error - %.*s\n", 512, errbuf);  
      break;  
    case OCI_INVALID_HANDLE:  
      (void) printf("Error - OCI_INVALID_HANDLE\n");  
      break;  
    case OCI_STILL_EXECUTING:  
      (void) printf("Error - OCI_STILL_EXECUTE\n");  
      break;  
    case OCI_CONTINUE:  
      (void) printf("Error - OCI_CONTINUE\n");  
      break;  
  
    default:  
      break;  
    }  
}  
//#endif                                              /* OCISC_ORACLE */
