0

Visual Studio 2013: c++ How to make in this function if connection = false show message and close MessageBoxA(0, "Failed to connect to Database!", "Error", MB_OK); ::ExitProcess(0);

if user, password, database = false show message its ODBC connection, and even if i write User = WrongName and Password = WrongPassword still running application without error for connection to database, if i change Database = MuOnline2 Application is going on Loopssss and doesnt start even

my .h file

#ifndef _SQLCONNECT_H
#define _SQLCONNECT_H

//-- SQL
#include <sql.h>
#include <sqltypes.h>
#include <sqlext.h>
//------

void ReadySQLConnect();

#define MAX_COLUMNS 100

class SQLCONNECT
{
public:
    SQLCONNECT();
    virtual ~SQLCONNECT();

    BOOL Connect();
    BOOL Execute(LPTSTR lpszStatement, ...);
    void Close();
    void GetAsString(LPTSTR ColName, LPTSTR pOutBuffer);
    DWORD GetAsInteger(LPTSTR ColName);
    QWORD GetAsInteger64(LPTSTR ColName);
    float GetAsFloat(LPTSTR ColName);
    void Disconnect();
    int GetAsBinary(LPSTR lpszStatement, LPBYTE OUT lpszReturnBuffer);
    SQLRETURN Fetch();
    int GetResult(int iIndex);
    QWORD GetResult64(int iIndex);
    void SetAsBinary(LPTSTR lpszStatement, LPBYTE lpBinaryBuffer, SQLUINTEGER BinaryBufferSize);
    DWORD GetRowCount();

    BOOL ReConnect();

private:
    int FindIndex(LPTSTR ColName);
    void Diagnosis(char* Query);

protected:
    SQLHANDLE m_hEnviroment;
    SQLHANDLE m_hConnection;
    SQLHANDLE m_hStmt;
    TCHAR m_szUser[64];
    TCHAR m_szPassword[64];
    TCHAR m_szDatabase[64];
    SQLINTEGER m_RowCount;
    SQLSMALLINT m_ColCount;
    SQLTCHAR m_SQLColName[MAX_COLUMNS][30];
    TCHAR m_SQLData[MAX_COLUMNS][256];
    SQLINTEGER m_SQLDataLen[MAX_COLUMNS];

};
extern SQLCONNECT cSQL;

void ReadyTableInstallation();

#endif

my .cpp file

#include "StdAfx.h"

SQLCONNECT cSQL;


void ReadySQLConnect()
{
    //cSQL.Connect();
    if (cSQL.Connect() == FALSE)
    {
        MessageBoxA(0, "Failed to connect to Database!", "Error", MB_OK);
    }
}

SQLCONNECT::SQLCONNECT()
{
    this->m_ColCount = -1;
    this->m_hConnection = NULL;
    this->m_hEnviroment = NULL;
    this->m_hStmt = NULL;
    memset(this->m_SQLColName, 0, sizeof(this->m_SQLColName));
    memset(this->m_SQLData, 0, sizeof(this->m_SQLData));
    SQLAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &this->m_hEnviroment);
    SQLSetEnvAttr(this->m_hEnviroment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, SQL_NTS);
}

SQLCONNECT::~SQLCONNECT()
{
    if (this->m_hStmt != SQL_NULL_HANDLE)
        SQLFreeHandle(SQL_HANDLE_STMT, this->m_hStmt);

    if (this->m_hConnection != SQL_NULL_HANDLE)
        SQLFreeHandle(SQL_HANDLE_DBC, this->m_hConnection);

    if (this->m_hEnviroment != SQL_NULL_HANDLE)
        SQLFreeHandle(SQL_HANDLE_ENV, this->m_hEnviroment);
}


BOOL SQLCONNECT::Connect()
{
    GetPrivateProfileStringA("SQL", "User", "sa", this->m_szUser, 64, SQL_PATH);
    GetPrivateProfileStringA("SQL", "Password", "123456", this->m_szPassword, 64, SQL_PATH);
    GetPrivateProfileStringA("SQL", "Database", "MuOnline", this->m_szDatabase, 64, SQL_PATH);

    SQLHANDLE rgbValue;

    SQLAllocHandle(SQL_HANDLE_DBC, this->m_hEnviroment, &this->m_hConnection);
    SQLSetConnectAttr(this->m_hConnection, SQL_LOGIN_TIMEOUT, &rgbValue, 0);

    SQLRETURN Result = SQLConnect(this->m_hConnection, (SQLTCHAR *)this->m_szDatabase, SQL_NTS,
        (SQLTCHAR *)this->m_szUser, SQL_NTS, (SQLTCHAR *)this->m_szPassword, SQL_NTS);

    if (Result != SQL_SUCCESS && Result != SQL_SUCCESS_WITH_INFO)
    {
        SQLSMALLINT sRecord = 1, MsgLen;
        SQLTCHAR SqlState[6], SQLMsgError[SQL_MAX_MESSAGE_LENGTH];
        SQLINTEGER NativeError;

        if (SQLGetDiagRec(SQL_HANDLE_DBC, this->m_hConnection, sRecord, SqlState, &NativeError, SQLMsgError, sizeof(SQLMsgError), &MsgLen) != SQL_NO_DATA)
        {
            //cLog.ConsoleOutput("SQLSTATE:%s, Diagnosis:%s", SqlState, SQLMsgError);
        }

        return FALSE;
    }

    Result = SQLAllocHandle(SQL_HANDLE_STMT, this->m_hConnection, &this->m_hStmt);

    if (Result != SQL_SUCCESS && Result != SQL_SUCCESS_WITH_INFO)
    {
        return FALSE;
    }

    //cLog.ConsoleOutput("[SQL] Connection successfully");
    ReadyTableInstallation();
    return TRUE;
}


BOOL SQLCONNECT::ReConnect()
{
    return this->Connect();
}

BOOL SQLCONNECT::Execute(TCHAR * lpszStatement, ...)
{
    TCHAR szStatement[1024];

    va_list pArguments;
    va_start(pArguments, lpszStatement);
    //wvsprintf(szStatement, lpszStatement, pArguments);
    vsprintf(szStatement, lpszStatement, pArguments);
    va_end(pArguments);

    SQLRETURN Result = SQLExecDirect(this->m_hStmt, (SQLTCHAR *)szStatement, SQL_NTS);

    if (Result != SQL_SUCCESS && Result != SQL_SUCCESS_WITH_INFO && Result != SQL_NO_DATA)
    {
        this->Diagnosis(szStatement);
        return FALSE;
    }

    SQLRowCount(this->m_hStmt, &this->m_RowCount);
    SQLNumResultCols(this->m_hStmt, &this->m_ColCount);

    if (this->m_ColCount >= MAX_COLUMNS - 1)
    {
        //cLog.ConsoleOutput("[CQuery] ColCount >= MAX_COLUMNS-1");
        return FALSE;
    }

    // Case just EXEC
    if (this->m_ColCount == 0)
    {
        this->Close();
        return TRUE;
    }

    for (int iColPos = 0; iColPos < this->m_ColCount; iColPos++)
    {
        memset(this->m_SQLData[iColPos], 0, sizeof(this->m_SQLData[iColPos]));

        SQLBindCol(this->m_hStmt, iColPos + 1, SQL_CHAR, this->m_SQLData[iColPos],
            sizeof(this->m_SQLData[0]) - 1, &this->m_SQLDataLen[iColPos]);
        SQLDescribeCol(this->m_hStmt, iColPos + 1, this->m_SQLColName[iColPos],
            sizeof(this->m_SQLColName[iColPos]), NULL, NULL, NULL, NULL, NULL);
    }

    return TRUE;
}

void SQLCONNECT::Close()
{
    SQLCloseCursor(this->m_hStmt);
    SQLFreeStmt(this->m_hStmt, 2);
}

SQLRETURN SQLCONNECT::Fetch()
{
    return SQLFetch(this->m_hStmt);
}

DWORD SQLCONNECT::GetRowCount()
{
    return this->m_RowCount;
}

int SQLCONNECT::FindIndex(LPTSTR ColName)
{
    for (short i = 0; i<this->m_ColCount; i++)
    {
        if (this->m_SQLColName[i][0] == ColName[0])
        {
            if (lstrcmp((TCHAR *)this->m_SQLColName[i], (TCHAR *)ColName) == 0)
            {
                return i;
            }
        }
    }

    return -1;
}


void SQLCONNECT::GetAsString(LPTSTR ColName, LPTSTR pOutBuffer)
{
    int iIndex = this->FindIndex(ColName);

    if (iIndex != -1)
    {
        lstrcpy(pOutBuffer, this->m_SQLData[iIndex]);
    }
    else
    {
        pOutBuffer[0] = 0;
    }
}


DWORD SQLCONNECT::GetAsInteger(LPTSTR ColName)
{
    int iIndex = this->FindIndex(ColName);

    if (iIndex != -1)
    {
        return atoi(this->m_SQLData[iIndex]);
    }

    return -1;
}


QWORD SQLCONNECT::GetAsInteger64(LPTSTR ColName)
{
    int iIndex = this->FindIndex(ColName);

    if (iIndex != -1)
    {
        return _atoi64(this->m_SQLData[iIndex]);
    }

    return -1;
}

float SQLCONNECT::GetAsFloat(LPTSTR ColName)
{
    int iIndex = this->FindIndex(ColName);

    if (iIndex != -1)
    {
        return (float)atof(this->m_SQLData[iIndex]);
    }

    return -1;
}

void SQLCONNECT::Diagnosis(char* Query)
{
    SQLSMALLINT sRecord = 1, MsgLen;
    SQLTCHAR SqlState[6], SQLMsgError[SQL_MAX_MESSAGE_LENGTH];
    SQLINTEGER NativeError;

    while (SQLGetDiagRec(SQL_HANDLE_STMT, this->m_hStmt, sRecord,
        SqlState, &NativeError, SQLMsgError, sizeof(SQLMsgError), &MsgLen) != SQL_NO_DATA)
    {
        //cLog.ConsoleOutput("SQLSTATE:%s, Diagnosis:%s - %s", SqlState, SQLMsgError, Query);
        sRecord++;
    }

    if (!lstrcmp((TCHAR *)SqlState, "08S01"))   // Communication Link Failure
        this->ReConnect();
}


int SQLCONNECT::GetResult(int iIndex)
{
    return atoi(this->m_SQLData[iIndex]);
}


QWORD SQLCONNECT::GetResult64(int iIndex)
{
    return _atoi64(this->m_SQLData[iIndex]);
}

int SQLCONNECT::GetAsBinary(LPTSTR lpszStatement, LPBYTE OUT lpszReturnBuffer)
{
    SQLCHAR * pSQLBuf;
    SQLINTEGER BufLen;
    SQLCHAR SQLBinary[10000];
    SQLINTEGER lOfs = 0;
    SQLINTEGER SQLLen;
    SQLRETURN SQLResult;

    //SQLAllocHandle(SQL_HANDLE_STMT, this->m_hConnection, &this->m_hStmt);

    SQLResult = SQLExecDirect(this->m_hStmt, (SQLTCHAR *)lpszStatement, SQL_NTS);

    if (SQLResult != SQL_SUCCESS)
    {
        this->Diagnosis(lpszStatement);
        return -1;
    }

    while (true)
    {
        SQLResult = SQLFetch(this->m_hStmt);

        if (SQLResult == SQL_NO_DATA)
            break;

        pSQLBuf = lpszReturnBuffer;

        while (true)
        {

            SQLResult = SQLGetData(this->m_hStmt,
                1, SQL_C_BINARY, SQLBinary, sizeof(SQLBinary), &SQLLen);

            if (SQLResult == SQL_NO_DATA)
                break;

            if (SQLLen == -1)
            {
                this->Close();
                return 0;
            }

            if (SQLResult == SQL_SUCCESS)
            {
                BufLen = SQLLen;
            }
            else
            {
                BufLen = sizeof(SQLBinary);
            }

            lOfs += BufLen;
            memcpy(pSQLBuf, SQLBinary, BufLen);
            pSQLBuf = &pSQLBuf[lOfs];
        }
    }

    //SQLFreeHandle(SQL_HANDLE_STMT, this->m_hStmt);
    return BufLen;
}


void SQLCONNECT::SetAsBinary(LPTSTR lpszStatement, LPBYTE lpBinaryBuffer, SQLUINTEGER BinaryBufferSize)
{
    SQLINTEGER cbValueSize = -0x64 - BinaryBufferSize;
    SQLPOINTER pToken;
    BYTE cBUFFER[10000];
    SQLRETURN Result;

    SQLBindParameter(this->m_hStmt, 1, SQL_PARAM_INPUT,
        SQL_C_BINARY, SQL_LONGVARBINARY, BinaryBufferSize, 0, (SQLPOINTER)1, 0, &cbValueSize);

    SQLExecDirect(this->m_hStmt, (SQLTCHAR *)lpszStatement, SQL_NTS);
    Result = SQLParamData(this->m_hStmt, &pToken);

    int lOfs = 0;

    while (Result == SQL_NEED_DATA)
    {
        memcpy(cBUFFER, lpBinaryBuffer, sizeof(cBUFFER));
        Result = SQLPutData(this->m_hStmt, cBUFFER, BinaryBufferSize);
        Result = SQLParamData(this->m_hStmt, &pToken);
        lOfs += sizeof(cBUFFER);
    }

    SQLParamData(this->m_hStmt, &pToken);
    this->Close();
}

void SQLCONNECT::Disconnect()
{
    if (this->m_hStmt)
        SQLFreeHandle(SQL_HANDLE_STMT, this->m_hStmt);

    if (this->m_hConnection)
        SQLDisconnect(this->m_hConnection);

    if (this->m_hConnection)
        SQLFreeHandle(SQL_HANDLE_DBC, this->m_hConnection);

    this->m_hStmt = NULL;
    this->m_hConnection = NULL;
}
  • Why not let the caller of `SQLCONNECT` handle the `FALSE` return value in whatever way it wants to? If the caller wants to display a message box, so be it. If the caller wants to close the app down, so be it. What the app should do shouldn't be in this function that you've posted, IMO. – PaulMcKenzie Dec 26 '15 at 01:29
  • i did not understand what you mean with this if you could show me would be more easy for me to understand – Инж.Георги Петев Dec 26 '15 at 01:33
  • Who calls this function? Let the caller handle the error. Having this function assume the responsibility of handling the error is wrong, or wrong-headed. Your function returns TRUE or FALSE, and that is all it should do. – PaulMcKenzie Dec 26 '15 at 01:34
  • void ReadySQLConnect() { cSQL.Connect(); } – Инж.Георги Петев Dec 26 '15 at 01:34
  • So why isn't `ReadySQLConnect` testing for TRUE or FALSE return value, and whatever it is, `ReadySQLConnect` handles the error? – PaulMcKenzie Dec 26 '15 at 01:36
  • even if i add this in ReadySQLConnect doesnt show message: if (cSQL.Connect() == FALSE) { MessageBoxA(0, "Failed to connect to Database!", "Error", MB_OK); } – Инж.Георги Петев Dec 26 '15 at 01:38
  • So maybe there is a bug in your SQLCONNECT function? It is not returning `FALSE` when it should? – PaulMcKenzie Dec 26 '15 at 01:40
  • i guest so, even if i change User = WrongName and Password= WrongPassword it still connect and run application, but if i change Database = MuOnline2 or another Wrong Name Application is going on infinity loops and doesnt start application even its total wrong – Инж.Георги Петев Dec 26 '15 at 01:41
  • Also, **don't cast string types**. Remove those `SQLTCHAR *` casts. What compiler errors do you get? If you get errors, then there is a lot wrong with your code far beyond SQL issues. – PaulMcKenzie Dec 26 '15 at 01:48
  • i updated my main code in top with my full .cpp file, i do not get any error in compile mode – Инж.Георги Петев Dec 26 '15 at 01:49
  • You don't get any errors because you shut the compiler up with those `(SQLTCHAR *)` C-style casts. Remove them. Then recompile your code. – PaulMcKenzie Dec 26 '15 at 01:50
  • if i remove (SQLTCHAR *)this->m_szDatabase, then m_szDatabase is underlined because its TCHAR in .h file – Инж.Георги Петев Dec 26 '15 at 01:51
  • Just have `m_szDatabase` -- no casts and no *this* stuff. What compiler error do you get? If you do get a compiler error, then don't even think about casting until you know what the error is. Casting string types is a sure sign of incorrect coding. – PaulMcKenzie Dec 26 '15 at 01:53
  • so i leave it like this: SQLRETURN Result = SQLConnect(this->m_hConnection,this->m_szDatabase, SQL_NTS,this->m_szUser, SQL_NTS, this->m_szPassword, SQL_NTS); and compiler errors: 2 IntelliSense: argument of type "TCHAR *" is incompatible with parameter of type "SQLCHAR *" – Инж.Георги Петев Dec 26 '15 at 01:55
  • Post the compiler error, not the Intellisense error. Intellisense is not the compiler. Compiler errors start with `Cxxxx` where `xxxx` is some number. – PaulMcKenzie Dec 26 '15 at 01:56
  • Error 1 error C2664: 'SQLRETURN SQLConnect(SQLHDBC,SQLCHAR *,SQLSMALLINT,SQLCHAR *,SQLSMALLINT,SQLCHAR *,SQLSMALLINT)' : cannot convert argument 2 from 'TCHAR [64]' to 'SQLCHAR * – Инж.Георги Петев Dec 26 '15 at 01:57
  • Well that's a start. Your string types are messed up and you casted them to shut the compiler up. Wrong move. You should fix your code so that the string types are the same. – PaulMcKenzie Dec 26 '15 at 01:58
  • to make this : SQLCHAR m_szUser[64]; SQLCHAR m_szPassword[64]; SQLCHAR m_szDatabase[64]; – Инж.Георги Петев Dec 26 '15 at 02:00
  • You should use `SQLTCHAR`'s. You should know your project character set type (MBCS or UNICODE), so that you're using the proper string types. Bottom line is that there should be *no* casts of string types. If there are, it is an error. See this concerning the hazards of casting strings away: http://stackoverflow.com/questions/34094344/c-c2440-error-cannot-convert-from-std-string-iterator-elem-traits-alloc/34099245#34099245 http://stackoverflow.com/questions/28481428/how-to-print-array-of-lpctstr-in-c/28481576#28481576 Once you have the program compiled and build, then rerun your code. – PaulMcKenzie Dec 26 '15 at 02:05
  • i use: Use Multi-Byte Character Set so i changed in .h file to SQLCHAR but now i got another problem here: GetPrivateProfileStringA("SQL", "User", "sa", this->m_szUser, 64, SQL_PATH); GetPrivateProfileStringA("SQL", "Password", "123456", this->m_szPassword, 64, SQL_PATH); GetPrivateProfileStringA("SQL", "Database", "MuOnline", this->m_szDatabase, 64, SQL_PATH); It is underlined this->m_szDatabase Error 1 error C2664: 'DWORD GetPrivateProfileStringA(LPCSTR,LPCSTR,LPCSTR,LPSTR,DWORD,LPCSTR)' : cannot convert argument 4 from 'SQLCHAR [64]' to 'LPSTR' – Инж.Георги Петев Dec 26 '15 at 02:08
  • OK. Make sure that the error isn't one where the function is expecting a wide string, and you're giving it a non-wide string, and vice-versa. If this were the case, then yes, you would definitely need to fix the problem. However SQLCHAR is 8 bits, and LPSTR is effectively a pointer to a byte array, you can safely cast to suppress the error. – PaulMcKenzie Dec 26 '15 at 02:18
  • so how can i fix this GetPrivateProfileStringA because if i make it like this: char m_szUser[64]; Then always give return FALSE, because doesnt read the config from the GetPrivateProfileStringA – Инж.Георги Петев Dec 26 '15 at 02:20
  • But to your original issue, your class shouldn't be doing anything I/O related if an error occurs. Those function's only job is to return a value for the calling app to deal with. Also, your class should **not** be exiting the process if there is an error. Let the caller decide what to do with the error: See this: http://stackoverflow.com/questions/22843189/exit-call-inside-a-function-which-should-return-a-reference/22843464#22843464 – PaulMcKenzie Dec 26 '15 at 02:21
  • i did not understand how to fix this to read correct User,Password,Database ohh.. ;[[ – Инж.Георги Петев Dec 26 '15 at 02:23
  • I suggest you write a smaller program, and hard-code the values into a call to `GetPrivateProfileStringA`. Trying to fix something that is part of a larger program starts with writing a small, easy-to-test program. Once you see the small program reading the values correctly, then you put that into the larger program. – PaulMcKenzie Dec 26 '15 at 02:24
  • GetPrivateProfileStringA -> Reads LPSTR SQLConnect(this->m_hConnection,this->m_szDatabase -> Reads SQLCHAR , bouth are different and cant read from GetPrivateProfileInt setting what to connect , I guest for that case it was (SQLTCHAR *) infront so to make read correct – Инж.Георги Петев Dec 26 '15 at 02:26
  • Look here: http://coliru.stacked-crooked.com/a/285a947607dda4fd That is what you should start with. Add the necessary include files for the SQL constants. Compile, run, test. You can't go further unless something simple like this is working. If this is an issue with GetPrivateProfileString, then test it with a small program. – PaulMcKenzie Dec 26 '15 at 02:31
  • check this you will understand me more well http://coliru.stacked-crooked.com/a/9c1c0ac4e749a698 – Инж.Георги Петев Dec 26 '15 at 02:36
  • and again we are back in beggining http://coliru.stacked-crooked.com/a/c852f789de59c687 – Инж.Георги Петев Dec 26 '15 at 02:47
  • Please use `GetLastError` after calling the API function: https://msdn.microsoft.com/en-us/library/windows/desktop/ms724353%28v=vs.85%29.aspx That way, you will know the reason *why* the function fails, not just that it fails. The link states: **To retrieve extended error information, call GetLastError.** -- As a matter of fact, your application should have been implementing a call to `GetLastError` anyway. – PaulMcKenzie Dec 26 '15 at 03:27
  • i have them included .h and .dll – Инж.Георги Петев Dec 26 '15 at 11:31
  • one person told me that here is maybe my problem with the connection not to read correct: if (Result != SQL_SUCCESS && Result != SQL_SUCCESS_WITH_INFO) – Инж.Георги Петев Dec 26 '15 at 16:25
  • Please some professional help here to finish this – Инж.Георги Петев Dec 26 '15 at 22:43

0 Answers0