#include "dpiImpl.h"
#include "dpiErrorMessages.h"
int dpiError__getInfo(dpiError *error, dpiErrorInfo *info)
{
if (!info)
return DPI_FAILURE;
info->code = error->buffer->code;
info->offset = error->buffer->offset;
info->message = error->buffer->message;
info->messageLength = error->buffer->messageLength;
info->fnName = error->buffer->fnName;
info->action = error->buffer->action;
info->isRecoverable = error->buffer->isRecoverable;
info->encoding = error->buffer->encoding;
switch(info->code) {
case 12154: info->sqlState = "42S02";
break;
case 22: case 378: case 602: case 603: case 604: case 609: case 1012: case 1033: case 1041: case 1043: case 1089: case 1090: case 1092: case 3113: case 3114: case 3122: case 3135: case 12153: case 27146: case 28511: info->sqlState = "01002";
break;
default:
if (error->buffer->code == 0 &&
error->buffer->errorNum == (dpiErrorNum) 0)
info->sqlState = "00000";
else info->sqlState = "HY000";
break;
}
return DPI_FAILURE;
}
int dpiError__initHandle(dpiError *error)
{
if (dpiHandlePool__acquire(error->env->errorHandles, &error->handle,
error) < 0)
return DPI_FAILURE;
if (!error->handle) {
if (dpiOci__handleAlloc(error->env->handle, &error->handle,
DPI_OCI_HTYPE_ERROR, "allocate OCI error", error) < 0)
return DPI_FAILURE;
}
return DPI_SUCCESS;
}
int dpiError__set(dpiError *error, const char *action, dpiErrorNum errorNum,
...)
{
va_list varArgs;
if (error) {
error->buffer->code = 0;
error->buffer->isRecoverable = 0;
error->buffer->offset = 0;
strcpy(error->buffer->encoding, DPI_CHARSET_NAME_UTF8);
error->buffer->action = action;
error->buffer->errorNum = errorNum;
va_start(varArgs, errorNum);
error->buffer->messageLength =
(uint32_t) vsnprintf(error->buffer->message,
sizeof(error->buffer->message),
dpiErrorMessages[errorNum - DPI_ERR_NO_ERR], varArgs);
va_end(varArgs);
if (dpiDebugLevel & DPI_DEBUG_LEVEL_ERRORS)
dpiDebug__print("internal error %.*s (%s / %s)\n",
error->buffer->messageLength, error->buffer->message,
error->buffer->fnName, action);
}
return DPI_FAILURE;
}
int dpiError__setFromOCI(dpiError *error, int status, dpiConn *conn,
const char *action)
{
uint32_t callTimeout;
if (status == DPI_OCI_INVALID_HANDLE)
return dpiError__set(error, action, DPI_ERR_INVALID_HANDLE, "OCI");
else if (!error)
return DPI_FAILURE;
else if (!error->handle)
return dpiError__set(error, action, DPI_ERR_ERR_NOT_INITIALIZED);
else if (status != DPI_OCI_ERROR && status != DPI_OCI_NO_DATA)
return dpiError__set(error, action,
DPI_ERR_UNEXPECTED_OCI_RETURN_VALUE, status,
error->buffer->fnName);
error->buffer->action = action;
strcpy(error->buffer->encoding, error->env->encoding);
if (dpiOci__errorGet(error->handle, DPI_OCI_HTYPE_ERROR,
error->env->charsetId, action, error) < 0)
return DPI_FAILURE;
if (dpiDebugLevel & DPI_DEBUG_LEVEL_ERRORS)
dpiDebug__print("OCI error %.*s (%s / %s)\n",
error->buffer->messageLength, error->buffer->message,
error->buffer->fnName, action);
error->buffer->isRecoverable = 0;
dpiOci__attrGet(error->handle, DPI_OCI_HTYPE_ERROR,
(void*) &error->buffer->isRecoverable, 0,
DPI_OCI_ATTR_ERROR_IS_RECOVERABLE, NULL, error);
if (conn && !conn->deadSession) {
switch (error->buffer->code) {
case 22: case 28: case 31: case 45: case 378: case 602: case 603: case 609: case 1012: case 1041: case 1043: case 1089: case 1092: case 2396: case 3113: case 3114: case 3122: case 3135: case 12153: case 12537: case 12547: case 12570: case 12583: case 27146: case 28511: case 56600: conn->deadSession = 1;
break;
case 3136: case 12161: callTimeout = 0;
if (conn->env->versionInfo->versionNum >= 18)
dpiOci__attrGet(conn->handle, DPI_OCI_HTYPE_SVCCTX,
(void*) &callTimeout, 0, DPI_OCI_ATTR_CALL_TIMEOUT,
NULL, error);
if (callTimeout > 0) {
dpiError__set(error, action, DPI_ERR_CALL_TIMEOUT,
callTimeout, error->buffer->code);
error->buffer->code = 0;
}
break;
}
}
return DPI_FAILURE;
}