SQLRETURN SQL_API RsError::RS_SQLGetDiagField()

in src/odbc/rsodbc/rserror.cpp [425:819]


SQLRETURN  SQL_API RsError::RS_SQLGetDiagField(SQLSMALLINT HandleType,
                                        SQLHANDLE Handle,
                                        SQLSMALLINT hRecNumber, 
                                        SQLSMALLINT hDiagIdentifier,
                                        SQLPOINTER  pDiagInfo, 
                                        SQLSMALLINT cbLen,
                                        SQLSMALLINT *pcbLen,
                                        int *piRetType)
{
    SQLRETURN rc = SQL_SUCCESS;
    size_t     cbRetLen = -1;
    int         iRetType = SQL_C_CHAR;
    SQLHENV phenv = NULL;
    SQLHDBC phdbc = NULL; 
    SQLHSTMT phstmt = NULL;
    SQLHDESC phdesc = NULL;
    RS_CONN_INFO *pConn = NULL;
    RS_STMT_INFO *pStmt = NULL;
    RS_DESC_INFO *pDesc = NULL;
    int        iIsHeaderField;

    // Check handle type
    if(HandleType == SQL_HANDLE_ENV)
        phenv = Handle;
    else
    if(HandleType == SQL_HANDLE_DBC)
    {
        phdbc = Handle;
        pConn = (RS_CONN_INFO *)phdbc;
    }
    else
    if(HandleType == SQL_HANDLE_STMT)
    {
        phstmt = Handle;
        pStmt  = (RS_STMT_INFO *)phstmt;
        if(pStmt)
            pConn = pStmt->phdbc;
    }
    else
    if(HandleType == SQL_HANDLE_DESC)
    {
        phdesc = Handle;
        pDesc = (RS_DESC_INFO *)phdesc;
        if(pDesc)
            pConn = pDesc->phdbc;
    }
    else
    {
        rc = SQL_INVALID_HANDLE;
    }

    if(!phenv && !phdbc && !phstmt && !phdesc)
    {
        rc = (rc == SQL_SUCCESS) ? SQL_INVALID_HANDLE : rc;
    }

    if(rc == SQL_SUCCESS)
    {
        // Check for header field
        if(hDiagIdentifier == SQL_DIAG_CURSOR_ROW_COUNT
            || hDiagIdentifier == SQL_DIAG_DYNAMIC_FUNCTION
            || hDiagIdentifier == SQL_DIAG_DYNAMIC_FUNCTION_CODE
            || hDiagIdentifier == SQL_DIAG_RETURNCODE
            || hDiagIdentifier == SQL_DIAG_NUMBER
            || hDiagIdentifier == SQL_DIAG_ROW_COUNT)
            iIsHeaderField = TRUE;
        else
            iIsHeaderField = FALSE;

        // Header field ignores the record number
        if(!iIsHeaderField && hRecNumber <= 0)
        {
            rc = SQL_ERROR;
        }
    }

    if(rc == SQL_SUCCESS)
    {
        switch(hDiagIdentifier)
        {
            //
            // Header fields.
            //
            case SQL_DIAG_CURSOR_ROW_COUNT:
            {
                iRetType = SQL_C_LONG;

                if(HandleType == SQL_HANDLE_STMT && pStmt)
                {
                    if(pDiagInfo)
                    {
                        RS_RESULT_INFO *pResult = pStmt->pResultHead;

                        if(pResult && (pResult->iNumberOfCols > 0))
                            *(SQLINTEGER *)pDiagInfo = pResult->iNumberOfRowsInMem;
                        else
                            *(SQLINTEGER *)pDiagInfo = 0;
                    }
                }
                else
                    rc = SQL_ERROR;

                break;
            }

            case SQL_DIAG_DYNAMIC_FUNCTION:
            case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
            case SQL_DIAG_RETURNCODE:
            {
                rc = SQL_NO_DATA;
                break;
            }

            case SQL_DIAG_NUMBER:
            {
                iRetType = SQL_C_LONG;

                if(pDiagInfo)
                {
                    RS_ERROR_INFO *pErrorList;
                    
                    *(SQLINTEGER *)pDiagInfo = 0;

                    if(phstmt != NULL)
                    {
                        RS_STMT_INFO *pStmt = (RS_STMT_INFO *)phstmt;

                        pErrorList = pStmt->pErrorList;
                    }
                    else
                    if(phdbc != NULL)
                    {
                        RS_CONN_INFO *pConn = (RS_CONN_INFO *)phdbc;

                        pErrorList = pConn->pErrorList;
                    }
                    else
                    if(phenv != NULL)
                    {
                        RS_ENV_INFO *pEnv = (RS_ENV_INFO *)phenv;

                        pErrorList = pEnv->pErrorList;
                    }
                    else
                    if(phdesc != NULL)
                    {
                        RS_DESC_INFO *pDesc = (RS_DESC_INFO *)phdesc;

                        pErrorList = pDesc->pErrorList;
                    }
                    else
                        pErrorList = NULL;

                    if(pErrorList)
                        *(SQLINTEGER *)pDiagInfo = getTotalErrors(pErrorList);
                } 

                break;
            }

            case SQL_DIAG_ROW_COUNT:
            {
                iRetType = SQL_C_LONG;

                if(HandleType == SQL_HANDLE_STMT && pStmt)
                {
                    if(pDiagInfo)
                    {
                        RS_RESULT_INFO *pResult = pStmt->pResultHead;

                        if(pResult && (pResult->iNumberOfCols == 0))
                            *(SQLINTEGER *)pDiagInfo = pResult->lRowsUpdated;
                        else
                            *(SQLINTEGER *)pDiagInfo = 0;
                    }
                }
                else
                    rc = SQL_ERROR;

                break;
            }

            //
            // Record fields
            //
            case SQL_DIAG_CLASS_ORIGIN:
            case SQL_DIAG_SUBCLASS_ORIGIN:
            {
                char szSqlState[MAX_SQL_STATE_LEN];
                char *pVal = NULL;

                szSqlState[0] = '\0';
                RsError::RS_SQLError(phenv, phdbc, phstmt, phdesc, (SQLCHAR *)szSqlState, NULL , NULL, 0,
                                    NULL, hRecNumber, FALSE); 

                if(szSqlState[0] == 'I' && szSqlState[1] == 'M')
                    pVal = "ODBC 3.51";
                else
                    pVal = "ISO 9075";
            
                cbRetLen = (pVal) ? strlen(pVal) : 0;

                if(pDiagInfo &&(cbLen > (short) cbRetLen))
                {
                    if(pVal)
                        rs_strncpy((char *)pDiagInfo, pVal,cbLen);
                    else
                        *((char *) pDiagInfo) = '\0';
                }
                else
                {
                    if(pDiagInfo && cbLen > 0)
                    {
                        if(pVal)
                        {
                            strncpy((char *)pDiagInfo, pVal, cbLen - 1);
                            ((char *)pDiagInfo)[cbLen - 1] = '\0';
                        }
                        else
                            *((char *) pDiagInfo) = '\0';
                    }

                    rc = SQL_SUCCESS_WITH_INFO;
                }


                break;
            }

            case SQL_DIAG_CONNECTION_NAME:
            {
                cbRetLen = 0;

                if(pDiagInfo &&(cbLen > (short) cbRetLen))
                {
                    *((char *) pDiagInfo) = '\0';
                }
                else
                {
                    if(pDiagInfo && cbLen > 0)
                        *((char *) pDiagInfo) = '\0';

                    rc = SQL_SUCCESS_WITH_INFO;
                }

                break;
            }

            case SQL_DIAG_SERVER_NAME:
            {
                char *pVal = NULL;

                if(pConn)
                    pVal = (char *)((pConn->pConnectProps) ? pConn->pConnectProps->szDSN : "");

                cbRetLen = (pVal) ? strlen(pVal) : 0;

                if(pDiagInfo &&(cbLen > (short) cbRetLen))
                {
                    if(pVal)
                        rs_strncpy((char *)pDiagInfo, pVal,cbLen);
                    else
                        *((char *) pDiagInfo) = '\0';
                }
                else
                {
                    if(pDiagInfo && cbLen > 0)
                    {
                        if(pVal)
                        {
                            strncpy((char *)pDiagInfo, pVal, cbLen - 1);
                            ((char *)pDiagInfo)[cbLen - 1] = '\0';
                        }
                        else
                            *((char *) pDiagInfo) = '\0';
                    }

                    rc = SQL_SUCCESS_WITH_INFO;
                }

                break;
            }

            case SQL_DIAG_MESSAGE_TEXT:
            {
                cbRetLen = 0;
                rc = RsError::RS_SQLError(phenv, phdbc, phstmt, phdesc, NULL, NULL, (SQLCHAR *)pDiagInfo, cbLen,
                                    (SQLSMALLINT *)((pcbLen) ? pcbLen : (SQLSMALLINT *)(void *)(&cbRetLen)), hRecNumber, FALSE);

                cbRetLen = (pcbLen) ? *pcbLen : cbRetLen;

                break;
            }

            case SQL_DIAG_NATIVE:
            {
                iRetType = SQL_C_LONG;

                rc = RsError::RS_SQLError(phenv, phdbc, phstmt, phdesc, NULL, (SQLINTEGER *) pDiagInfo, NULL, 0,
                                    NULL, hRecNumber, FALSE); 

                break;
            }

            case SQL_DIAG_SQLSTATE:
            {
                cbRetLen = MAX_SQL_STATE_LEN - 1;

                rc = RsError::RS_SQLError(phenv, phdbc, phstmt, phdesc, (SQLCHAR *)pDiagInfo, NULL , NULL, 0,
                                    NULL, hRecNumber, FALSE); 

                if (rc == SQL_SUCCESS_WITH_INFO)  
                    rc = SQL_SUCCESS;

                break;
            }


            case SQL_DIAG_COLUMN_NUMBER:
            {
                iRetType = SQL_C_LONG;

                if(HandleType == SQL_HANDLE_STMT)
                {
                    if(pDiagInfo)
                        *(SQLINTEGER *)pDiagInfo = SQL_COLUMN_NUMBER_UNKNOWN;
                }
                else
                    rc = SQL_ERROR;

                break;
            }

            case SQL_DIAG_ROW_NUMBER:
            {
                iRetType = SQL_C_LONG;

                if(HandleType == SQL_HANDLE_STMT)
                {
                    if(pDiagInfo)
                        *(SQLINTEGER *)pDiagInfo = SQL_ROW_NUMBER_UNKNOWN;
                }
                else
                    rc = SQL_ERROR;

                break;
            }

            default:
            {
                rc = SQL_NO_DATA;
                break;
            }
        } // Diag Iden type switch

        // Check return type
        switch(iRetType)
        {
            case SQL_C_CHAR:
            {
                if (cbRetLen >= 0)
                {
                    if ((short)cbRetLen >= cbLen)
                    {
                        if (rc == SQL_SUCCESS)
                            rc = SQL_SUCCESS_WITH_INFO;

                        if (cbLen > 0)
                            ((char *) pDiagInfo)[cbLen - 1] = '\0';
                    }

                    if (pcbLen)  
                        *pcbLen = (SQLSMALLINT) cbRetLen;
                }
                break;
            }

            case SQL_C_LONG:
            {
                if(rc == SQL_SUCCESS_WITH_INFO)
                    rc = SQL_SUCCESS;

                if (pcbLen)  
                    *pcbLen = sizeof(SQLINTEGER);

                break;
            }
        }
    }

    if(piRetType)
        *piRetType = iRetType;

    return rc;
}