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;
}