#include <iostream>
#include <windows.h>
#include <sql.h>
#include <sqlext.h>
#include <stdio.h>

#ifndef TRUE
#define TRUE 1
#endif

#define MAXCOLS 100
#define MAX_DATA_LEN 255

SQLHENV  henv;
SQLHDBC  hdbc;
SQLHSTMT hstmt;

SQLINTEGER PrintError(SQLSMALLINT handleType, SQLHANDLE handle, SQLRETURN rcode)
{

    SQLRETURN rc = SQL_ERROR;
    SQLCHAR sqlState[6];
    SQLCHAR eMsg[SQL_MAX_MESSAGE_LENGTH];
    SQLINTEGER nError;
    SQLSMALLINT msgLen;
    
    if (rcode == SQL_NO_DATA)
    {
        std::cout << "NO DATA .. .. .." << std::endl;
        return(SQL_NO_DATA);
    }
    else
    {
        rc = SQLGetDiagRec(handleType, handle, 1, sqlState, &nError, eMsg, sizeof(eMsg), &msgLen);
        if (rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
        {
            std::cout << " Error: " << eMsg << std::endl;
        }
        return (SQL_ERROR);
    }
}

int main(int argc, char * argv[])
{

   SQLRETURN rc;
   SQLCHAR connString[255] = "DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;PORT=3306;UID=root;PWD=;Database=test;OPTION=3"; //95
   SQLCHAR     connOut[255], Val[255], Rez[8]; /* buffer for connection output */
   SQLSMALLINT szConnOut; /* num bytes returned in connOut */

	argv[1] = "myodbc1";
	argv[2] = "root";
	argv[3] = "";

    rc = SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_ENV, henv, rc));

    rc = SQLSetEnvAttr(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_NTS);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_ENV, henv, rc));
        
    rc = SQLAllocHandle(SQL_HANDLE_DBC, henv, &hdbc);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_ENV, henv, rc));
        
    std::cout << "Connecting to " << argv[1] << std::endl;

    //rc = SQLConnect(hdbc, (SQLCHAR *)argv[1], SQL_NTS, 
    //              (SQLCHAR *)argv[2], SQL_NTS, 
    //              (SQLCHAR *)argv[3], SQL_NTS);

   rc = SQLDriverConnect(hdbc, NULL, (SQLCHAR *)"DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;PORT=3306;UID=root;PWD=;Database=test;OPTION=512",
	   _countof("DRIVER={MySQL ODBC 3.51 Driver};SERVER=localhost;PORT=3306;UID=root;PWD=;Database=test;OPTION=512"), connOut, 255, &szConnOut, SQL_DRIVER_NOPROMPT);

   //rc = SQLDriverConnect(hdbc, NULL, (SQLCHAR *)"DRIVER={MySQL connector/ODBC v5};SERVER=localhost;PORT=3306;UID=root;PWD=;Database=test;",
	  // _countof("DRIVER={MySQL connector/ODBC v5};SERVER=localhost;PORT=3306;UID=root;PWD=;Database=test;"), connOut, 255, &szConnOut, SQL_DRIVER_NOPROMPT);


    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_DBC, hdbc, rc));
        
    rc = SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_DBC, hdbc, rc));
        
    /*************************************************************************************/
       
    rc = SQLExecDirect(hstmt, (SQLCHAR *)"USE test", SQL_NTS);

    rc = SQLExecDirect(hstmt, (SQLCHAR *)"SELECT CONCAT(Str1, Str2) AS FullDesc FROM bug27862", SQL_NTS);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_STMT, hstmt, rc));

    SQLINTEGER rs;
	SQLCHAR buf[255];

    rc = SQLColAttribute(hstmt, 1, SQL_DESC_BASE_COLUMN_NAME, &buf, 255, 0, 0);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_STMT, hstmt, rc));
    std::cout << "SQL_DESC_BASE_COLUMN_NAME -> " << buf << std::endl;

    rc = SQLColAttribute(hstmt, 1, SQL_DESC_LABEL, &buf, 255, 0, 0);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_STMT, hstmt, rc));
    std::cout << "SQL_DESC_LABEL -> " << buf << std::endl;

    rc = SQLColAttribute(hstmt, 1, SQL_DESC_TYPE_NAME, &buf, 255, 0, 0);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_STMT, hstmt, rc));
    std::cout << "SQL_DESC_TYPE_NAME -> " << buf << std::endl;

    rc = SQLColAttribute(hstmt, 1, SQL_DESC_DISPLAY_SIZE, 0, 0, 0, &rs);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_STMT, hstmt, rc));
    std::cout << "SQL_DESC_DISPLAY_SIZE  -> " << rs << std::endl;

    rc = SQLColAttribute(hstmt, 1, SQL_DESC_LENGTH, 0, 0, 0, &rs);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_STMT, hstmt, rc));
    std::cout << "SQL_DESC_LENGTH  -> " << rs << std::endl;

    rc = SQLColAttribute(hstmt, 1, SQL_DESC_OCTET_LENGTH , 0, 0, 0, &rs);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
        return(PrintError(SQL_HANDLE_STMT, hstmt, rc));
    std::cout << "SQL_DESC_OCTET_LENGTH   -> " << rs << std::endl;

    /*************************************************************************************/
    
    rc = SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
            return(PrintError(SQL_HANDLE_STMT, hstmt, rc));
    
    rc = SQLDisconnect(hdbc);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
            return(PrintError(SQL_HANDLE_DBC, hdbc, rc));
    
    rc = SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
            return(PrintError(SQL_HANDLE_DBC, hdbc, rc));
                    
    rc = SQLFreeHandle(SQL_HANDLE_ENV, henv);
    if (rc != SQL_SUCCESS && rc != SQL_SUCCESS_WITH_INFO)
            return(PrintError(SQL_HANDLE_ENV, henv, rc));
    
    return(0);
}   
