wxWidgets/src/iodbc/herr.c
Vadim Zeitlin 88ac883a0d new makefiles (part I)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@2613 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
1999-06-01 15:32:12 +00:00

379 lines
6.8 KiB
C

/*
* herr.c
*
* $Id$
*
* Error stack management functions
*
* The iODBC driver manager.
*
* Copyright (C) 1995 by Ke Jin <kejin@empress.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "config.h"
#include "isql.h"
#include "isqlext.h"
#include "dlproc.h"
#include "herr.h"
#include "henv.h"
#include "hdbc.h"
#include "hstmt.h"
#include "itrace.h"
#include "herr.ci"
static HERR
_iodbcdm_popsqlerr (HERR herr)
{
sqlerr_t *list = (sqlerr_t *) herr;
sqlerr_t *next;
if (herr == SQL_NULL_HERR)
{
return herr;
}
next = list->next;
MEM_FREE (list);
return next;
}
void
_iodbcdm_freesqlerrlist (HERR herrlist)
{
HERR list;
for (list = herrlist; list != 0;)
{
list = _iodbcdm_popsqlerr (list);
}
}
HERR
_iodbcdm_pushsqlerr (
HERR herr,
sqlstcode_t code,
char *msg)
{
sqlerr_t *ebuf;
sqlerr_t *perr = (sqlerr_t *) herr;
int idx = 0;
if (herr != SQL_NULL_HERR)
{
idx = perr->idx + 1;
}
if (idx == 64)
/* over wirte the top entry to prevent error stack blow out */
{
perr->code = code;
perr->msg = msg;
return herr;
}
ebuf = (sqlerr_t *) MEM_ALLOC (sizeof (sqlerr_t));
if (ebuf == NULL)
{
return NULL;
}
ebuf->msg = msg;
ebuf->code = code;
ebuf->idx = idx;
ebuf->next = (sqlerr_t *) herr;
return (HERR) ebuf;
}
static char FAR *
_iodbcdm_getsqlstate (
HERR herr,
void FAR * tab)
{
sqlerr_t *perr = (sqlerr_t *) herr;
sqlerrmsg_t *ptr;
if (herr == SQL_NULL_HERR || tab == NULL)
{
return (char FAR *) NULL;
}
for (ptr = tab;
ptr->code != en_sqlstat_total;
ptr++)
{
if (ptr->code == perr->code)
{
return (char FAR *) (ptr->stat);
}
}
return (char FAR *) NULL;
}
static char FAR *
_iodbcdm_getsqlerrmsg (
HERR herr,
void FAR * errtab)
{
sqlerr_t *perr = (sqlerr_t *) herr;
sqlerrmsg_t *ptr;
if (herr == SQL_NULL_HERR)
{
return NULL;
}
if (perr->msg == NULL && errtab == NULL)
{
return NULL;
}
if (perr->msg != NULL)
{
return perr->msg;
}
for (ptr = (sqlerrmsg_t *) errtab;
ptr->code != en_sqlstat_total;
ptr++)
{
if (ptr->code == perr->code)
{
return (char FAR *) ptr->msg;
}
}
return (char FAR *) NULL;
}
RETCODE SQL_API
SQLError (
HENV henv,
HDBC hdbc,
HSTMT hstmt,
UCHAR FAR * szSqlstate,
SDWORD FAR * pfNativeError,
UCHAR FAR * szErrorMsg,
SWORD cbErrorMsgMax,
SWORD FAR * pcbErrorMsg)
{
GENV_t FAR *genv = (GENV_t FAR *) henv;
DBC_t FAR *pdbc = (DBC_t FAR *) hdbc;
STMT_t FAR *pstmt = (STMT_t FAR *) hstmt;
HDBC thdbc;
HENV dhenv = SQL_NULL_HENV;
HDBC dhdbc = SQL_NULL_HDBC;
HSTMT dhstmt = SQL_NULL_HSTMT;
HERR herr = SQL_NULL_HERR;
HPROC hproc = SQL_NULL_HPROC;
char FAR *errmsg = NULL;
char FAR *ststr = NULL;
int handle = 0;
RETCODE retcode = SQL_SUCCESS;
if (hstmt != SQL_NULL_HSTMT) /* retrive stmt err */
{
herr = pstmt->herr;
thdbc = pstmt->hdbc;
if (thdbc == SQL_NULL_HDBC)
{
return SQL_INVALID_HANDLE;
}
hproc = _iodbcdm_getproc (thdbc, en_Error);
dhstmt = pstmt->dhstmt;
handle = 3;
}
else if (hdbc != SQL_NULL_HDBC) /* retrive dbc err */
{
herr = pdbc->herr;
thdbc = hdbc;
if (thdbc == SQL_NULL_HDBC)
{
return SQL_INVALID_HANDLE;
}
hproc = _iodbcdm_getproc (thdbc, en_Error);
dhdbc = pdbc->dhdbc;
handle = 2;
if (herr == SQL_NULL_HERR
&& pdbc->henv == SQL_NULL_HENV)
{
return SQL_NO_DATA_FOUND;
}
}
else if (henv != SQL_NULL_HENV) /* retrive env err */
{
herr = genv->herr;
/* Drivers shouldn't push error message
* on envoriment handle */
if (herr == SQL_NULL_HERR)
{
return SQL_NO_DATA_FOUND;
}
handle = 1;
}
else
{
return SQL_INVALID_HANDLE;
}
if (szErrorMsg != NULL)
{
if (cbErrorMsgMax < 0
|| cbErrorMsgMax > SQL_MAX_MESSAGE_LENGTH - 1)
{
return SQL_ERROR;
/* SQLError() doesn't post error for itself */
}
}
if (herr == SQL_NULL_HERR) /* no err on drv mng */
{
/* call driver */
if (hproc == SQL_NULL_HPROC)
{
PUSHSQLERR (herr, en_IM001);
return SQL_ERROR;
}
CALL_DRIVER (thdbc, retcode, hproc, en_Error,
(dhenv, dhdbc, dhstmt, szSqlstate, pfNativeError, szErrorMsg,
cbErrorMsgMax, pcbErrorMsg))
return retcode;
}
if (szSqlstate != NULL)
{
int len;
/* get sql state string */
ststr = (char FAR *) _iodbcdm_getsqlstate (herr,
(void FAR *) sqlerrmsg_tab);
if (ststr == NULL)
{
len = 0;
}
else
{
len = (int) STRLEN (ststr);
}
STRNCPY (szSqlstate, ststr, len);
szSqlstate[len] = 0;
/* buffer size of szSqlstate is not checked. Applications
* suppose provide enough ( not less than 6 bytes ) buffer
* or NULL for it.
*/
}
if (pfNativeError != NULL)
{
/* native error code is specific to data source */
*pfNativeError = (SDWORD) 0L;
}
if (szErrorMsg == NULL || cbErrorMsgMax == 0)
{
if (pcbErrorMsg != NULL)
{
*pcbErrorMsg = (SWORD) 0;
}
}
else
{
int len;
char msgbuf[256] = {'\0'};
/* get sql state message */
errmsg = _iodbcdm_getsqlerrmsg (herr, (void FAR *) sqlerrmsg_tab);
if (errmsg == NULL)
{
errmsg = (char FAR *) "";
}
sprintf (msgbuf, "%s%s", sqlerrhd, errmsg);
len = STRLEN (msgbuf);
if (len < cbErrorMsgMax - 1)
{
retcode = SQL_SUCCESS;
}
else
{
len = cbErrorMsgMax - 1;
retcode = SQL_SUCCESS_WITH_INFO;
/* and not posts error for itself */
}
STRNCPY ((char *) szErrorMsg, msgbuf, len);
szErrorMsg[len] = 0;
if (pcbErrorMsg != NULL)
{
*pcbErrorMsg = (SWORD) len;
}
}
switch (handle) /* free this err */
{
case 1:
genv->herr = _iodbcdm_popsqlerr (genv->herr);
break;
case 2:
pdbc->herr = _iodbcdm_popsqlerr (pdbc->herr);
break;
case 3:
pstmt->herr = _iodbcdm_popsqlerr (pstmt->herr);
break;
default:
break;
}
return retcode;
}