#include <sqlext.h>
#include <sql.h>
#include <stdlib.h>

#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <Windows.h>
#endif

#define MAX_DATA 100
#define MYSQLSUCCESS(rc) ((rc==SQL_SUCCESS)||(rc==SQL_SUCCESS_WITH_INFO))
unsigned char szData[MAX_DATA];

BOOL Connect(char* strDB,char* strUser, char* strPassword, HENV** hEnv, HDBC** hDBC)
{
	RETCODE hRet = 0;
	hRet = SQLAllocEnv( (*hEnv) );
	
	if( SQL_ERROR == hRet )
	{
		printf("Unable to Initialize the Environment..");
		return 0;
	}
	else
	{
		printf("%s\r\n","Environment Initialized..");
		SQLAllocConnect( *(*hEnv),(*hDBC) );
		//printf("datebase check %s",strDB);
		if ( *hDBC != NULL ) 
		{
			printf("Database Name = %s\r\n",strDB);	
		}

		hRet =SQLConnect( *(*hDBC),(SQLCHAR*)strDB,SQL_NTS,(SQLCHAR*)strUser,strlen(strUser),(SQLCHAR*)strPassword,strlen(strPassword));
		if(!MYSQLSUCCESS(hRet))
		{
			SQLFreeEnv(*(*hEnv ));
			SQLFreeConnect(*( *hDBC ) );
			printf("%s\r\n","Unable to connect..");
			return 0;
		}
		else
		{
			printf("%s\r\n","Connected to the Database..");
			return 1;
		}
	}	
	return 0;
}

void Disconnect(HENV** hEnv, HDBC** hDBC, HSTMT** hStmt)
{
	SQLFreeStmt( *(*hStmt),SQL_DROP );
	SQLDisconnect( *(*hDBC) );
	SQLFreeConnect( *(*hDBC) );
	SQLFreeEnv( *(*hEnv) );
}

BOOL ExecuteSimple_Select(HSTMT** hStmt,unsigned char * cmdstr)
{
	SDWORD cbData;
	SQLSMALLINT iTotCols = 0;
	SQLINTEGER   rStatus = 0;
	int j;

	RETCODE rc=SQLExecDirect(*(*hStmt),cmdstr,SQL_NTS);
	if (!MYSQLSUCCESS(rc))	//Error
	{
		printf("Unable to execute...\r\n");
		//error_out(hStmt);
		// Deallocate handles and disconnect.
		SQLFreeStmt(hStmt,SQL_DROP);
		return 0;
	}
	else
	{
		rc=SQLFetch(*(*hStmt));
		if(SQL_NO_DATA == rc)
		{
			printf("No Data...\r\n");
			return 0;
		}
		SQLNumResultCols(*(*hStmt),&iTotCols);
		printf("No of Columns = %d\r\n",iTotCols);
	
		for (;rc == SQL_SUCCESS; rc=SQLFetch( *(*hStmt) ) )
		{		
			rStatus = SQLGetData( *(*hStmt),1,SQL_C_CHAR,szData,sizeof(szData),&cbData);
			printf("Emp No = %s\t",szData);
			printf("\r\n");
			rStatus = SQLGetData( *(*hStmt),2,SQL_C_CHAR,szData,sizeof(szData),&cbData);
			printf("Emp Name = %s\t",szData);
			printf("\r\n");
			rStatus = SQLGetData( *(*hStmt),3,SQL_C_CHAR,szData,sizeof(szData),&cbData);
			printf("Job = %s\t",szData);
			printf("\r\n");
			rStatus = SQLGetData( *(*hStmt),4,SQL_C_CHAR,szData,sizeof(szData),&cbData);
			printf("Mgr = %s\t",szData);
			printf("\r\n");
			rStatus = SQLGetData( *(*hStmt),5,SQL_C_CHAR,szData,sizeof(szData),&cbData);
			printf("Hire Date = %s\t",szData);
			printf("\r\n");
		}

		return 1;
	}
}

BOOL ExecuteUpdate(HSTMT** hStmt,unsigned char * cmdstr)
{
	SDWORD cbData;
	SQLSMALLINT iTotCols = 0;
	SQLINTEGER   rStatus = 0;
	int j;

	RETCODE rc=SQLExecDirect(*(*hStmt),cmdstr,SQL_NTS);
	if (!MYSQLSUCCESS(rc))	//Error
	{
		printf("Unable to execute...\r\n");
		//error_out(hStmt);
		// Deallocate handles and disconnect.
		SQLFreeStmt(hStmt,SQL_DROP);
		return 0;
	}
	else
	{
		rc=SQLFetch(*(*hStmt));
		if(SQL_NO_DATA == rc)
		{
			printf("No Data...\r\n");
			return 0;
		}
		SQLNumResultCols(*(*hStmt),&iTotCols);
		printf("No of Columns = %d\r\n",iTotCols);
	
		for (;rc == SQL_SUCCESS; rc=SQLFetch( *(*hStmt) ) )
		{		
			for(j=1;j<=iTotCols;j++)
			{
				rStatus = SQLGetData( *(*hStmt),j,SQL_C_CHAR,szData,sizeof(szData),&cbData);
				printf("Data = %s\t",szData);
			}
			printf("\r\n");
		}
		return 1;
	}
}


BOOL ExecuteDeletStatement(HSTMT** hStmt,unsigned char * cmdstr)
{
	SDWORD cbData;
	SQLSMALLINT iTotCols = 0;
	SQLINTEGER   rStatus = 0;
	int j;

	RETCODE rc=SQLExecDirect(*(*hStmt),cmdstr,SQL_NTS);
	if (!MYSQLSUCCESS(rc))	//Error
	{
		printf("Unable to execute...\r\n");
		//error_out(hStmt);
		// Deallocate handles and disconnect.
		SQLFreeStmt(hStmt,SQL_DROP);
		return 0;
	}
	else
	{
		rc=SQLFetch(*(*hStmt));
		if(SQL_NO_DATA == rc)
		{
			printf("No Data...\r\n");
			return 0;
		}
		SQLNumResultCols(*(*hStmt),&iTotCols);
		printf("No of Columns = %d\r\n",iTotCols);
	
		for (;rc == SQL_SUCCESS; rc=SQLFetch( *(*hStmt) ) )
		{		
			for(j=1;j<=iTotCols;j++)
			{
				rStatus = SQLGetData( *(*hStmt),j,SQL_C_CHAR,szData,sizeof(szData),&cbData);
				printf("Data = %s\t",szData);
			}
			printf("\r\n");
		}
	return 1;
	}
}

BOOL ExecuteInsertStatement(HSTMT** hStmt,unsigned char * cmdstr)
{
	SDWORD cbData;
	SQLSMALLINT iTotCols = 0;
	SQLINTEGER   rStatus = 0;
	int j;
	RETCODE rc=SQLExecDirect(*(*hStmt),cmdstr,SQL_NTS);
	if (!MYSQLSUCCESS(rc))	//Error
	{
		printf("Unable to execute...\r\n");
		//error_out(hStmt);
		// Deallocate handles and disconnect.
		SQLFreeStmt(hStmt,SQL_DROP);
		return 0;
	}
	else
	{
		rc=SQLFetch(*(*hStmt));
		if(SQL_NO_DATA == rc)
		{
			printf("No Data...\r\n");
			return 0;
		}
		SQLNumResultCols(*(*hStmt),&iTotCols);
		printf("No of Columns = %d\r\n",iTotCols);
	
		for (;rc == SQL_SUCCESS; rc=SQLFetch( *(*hStmt) ) )
		{		
			for(j=1;j<=iTotCols;j++)
			{
				rStatus = SQLGetData( *(*hStmt),j,SQL_C_CHAR,szData,sizeof(szData),&cbData);
				printf("Data = %s\t",szData);
			}
			printf("\r\n");
		}
	return 1;
	}
}

SQLCHAR* GetDBName(HDBC** hDBC)
{
	SQLSMALLINT	InfoValueLen;
	static SQLCHAR * InfoValuePtr;
	InfoValuePtr = (SQLCHAR*)malloc(50);	// Allocate InfoValuePtr.
	SQLGetInfo(*(*hDBC), SQL_PROCEDURES, (SQLPOINTER)InfoValuePtr, 50, &InfoValueLen);
	return InfoValuePtr;
}

int main(int argc, char* argv[])
{
	RETCODE rCode;
	HENV *hEnv = (HENV*)malloc(sizeof(HENV));
	HDBC *hDBC = (HDBC*)malloc(sizeof(HDBC));
	HSTMT *hStmt = (HSTMT*)malloc(sizeof(HSTMT));

	Connect("enterprisedb","enterprisedb","",&hEnv,&hDBC);
	rCode = SQLAllocStmt(*hDBC,hStmt); 
	rCode = SQLAllocHandle(SQL_HANDLE_STMT,*hDBC,hStmt);
	
	
	ExecuteInsertStatement(&hStmt,(UCHAR*) "INSERT INTO EMP(EMPNO,ENAME) VALUES((SELECT COUNT(EMPNO) FROM EMP),'JACKSON')");
	ExecuteUpdate(&hStmt,(UCHAR*) "UPDATE EMP SET ENAME='ODBC Test' WHERE EMPNO	< 100");
	ExecuteDeletStatement(&hStmt,(UCHAR*) "DELETE FROM EMP WHERE EMPNO<100");
	ExecuteSimple_Select(&hStmt,(UCHAR*) "SELECT EMPNO,ENAME,JOB,MGR,HIREDATE FROM EMP where empno = 7369");
	
	Disconnect(&hEnv,&hDBC,&hStmt);
	
	free(hEnv);
	free(hDBC);
	free(hStmt);
	
	return 0;
}
