-/** Error stack management functions
-
- Copyright (C) 1995 by Ke Jin <kejin@empress.com>
+/*
+ * 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;
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+ if (herr == SQL_NULL_HERR)
+ {
+ return herr;
+ }
- This program 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 General Public License for more details.
-**/
+ next = list->next;
-#include <../iodbc/iodbc.h>
+ MEM_FREE (list);
-#include <../iodbc/isql.h>
-#include <../iodbc/isqlext.h>
+ return next;
+}
-#include <../iodbc/dlproc.h>
-#include <../iodbc/herr.h>
-#include <../iodbc/henv.h>
-#include <../iodbc/hdbc.h>
-#include <../iodbc/hstmt.h>
+void
+_iodbcdm_freesqlerrlist (HERR herrlist)
+{
+ HERR list;
-#include <../iodbc/itrace.h>
+ for (list = herrlist; list != 0;)
+ {
+ list = _iodbcdm_popsqlerr (list);
+ }
+}
-#include "../iodbc/herr.ci"
-static HERR _iodbcdm_popsqlerr( HERR herr )
+HERR
+_iodbcdm_pushsqlerr (
+ HERR herr,
+ sqlstcode_t code,
+ char *msg)
{
- sqlerr_t* list = (sqlerr_t*)herr;
- sqlerr_t* next;
+ sqlerr_t *ebuf;
+ sqlerr_t *perr = (sqlerr_t *) herr;
+ int idx = 0;
- if( herr == SQL_NULL_HERR )
- {
- return herr;
- }
-
- next = list->next;
+ if (herr != SQL_NULL_HERR)
+ {
+ idx = perr->idx + 1;
+ }
- MEM_FREE (list);
+ if (idx == 64)
+ /* over wirte the top entry to prevent error stack blow out */
+ {
+ perr->code = code;
+ perr->msg = msg;
- return next;
-}
+ return herr;
+ }
-void _iodbcdm_freesqlerrlist( HERR herrlist )
-{
- HERR list;
+ ebuf = (sqlerr_t *) MEM_ALLOC (sizeof (sqlerr_t));
- for(list = herrlist; list!= 0; )
- {
- list = _iodbcdm_popsqlerr(list);
- }
+ if (ebuf == NULL)
+ {
+ return NULL;
+ }
+
+ ebuf->msg = msg;
+ ebuf->code = code;
+ ebuf->idx = idx;
+ ebuf->next = (sqlerr_t *) herr;
+
+ return (HERR) ebuf;
}
-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 )
+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)
{
- idx = perr->idx + 1;
+ return (char FAR *) (ptr->stat);
}
+ }
- if( idx == 64 )
- /* over wirte the top entry to prevent error stack blow out */
- {
- perr->code = code;
- perr->msg = msg;
+ return (char FAR *) NULL;
+}
- return herr;
- }
- ebuf = (sqlerr_t*)MEM_ALLOC (sizeof(sqlerr_t));
-
- if( ebuf == 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 NULL;
+ return (char FAR *) ptr->msg;
}
+ }
- ebuf->msg = msg;
- ebuf->code = code;
- ebuf->idx = idx;
- ebuf->next = (sqlerr_t*)herr;
-
- return (HERR)ebuf;
+ return (char FAR *) NULL;
}
-static char FAR* _iodbcdm_getsqlstate (
- HERR herr,
- void FAR* tab )
+
+RETCODE SQL_API
+SQLError (
+ HENV henv,
+ HDBC hdbc,
+ HSTMT hstmt,
+ UCHAR FAR * szSqlstate,
+ SDWORD FAR * pfNativeError,
+ UCHAR FAR * szErrorMsg,
+ SWORD cbErrorMsgMax,
+ SWORD FAR * pcbErrorMsg)
{
- sqlerr_t* perr = (sqlerr_t*)herr;
- sqlerrmsg_t* ptr;
+ 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;
- if( herr == SQL_NULL_HERR || tab == NULL )
- {
- return (char FAR*)NULL;
- }
+ HENV dhenv = SQL_NULL_HENV;
+ HDBC dhdbc = SQL_NULL_HDBC;
+ HSTMT dhstmt = SQL_NULL_HSTMT;
- for( ptr = tab;
- ptr->code != en_sqlstat_total;
- ptr++ )
- {
- if(ptr->code == perr->code)
- {
- return (char FAR*)(ptr->stat);
- }
- }
+ HERR herr = SQL_NULL_HERR;
+ HPROC hproc = SQL_NULL_HPROC;
- return (char FAR*)NULL;
-}
+ char FAR *errmsg = NULL;
+ char FAR *ststr = NULL;
-static char FAR* _iodbcdm_getsqlerrmsg(
- HERR herr,
- void FAR* errtab )
-{
- sqlerr_t* perr = (sqlerr_t*)herr;
- sqlerrmsg_t* ptr;
+ int handle = 0;
+ RETCODE retcode = SQL_SUCCESS;
- if( herr == SQL_NULL_HERR )
- {
- return NULL;
- }
+ if (hstmt != SQL_NULL_HSTMT) /* retrive stmt err */
+ {
+ herr = pstmt->herr;
+ thdbc = pstmt->hdbc;
- if( perr->msg == NULL && errtab == NULL )
+ if (thdbc == SQL_NULL_HDBC)
{
- return NULL;
+ return SQL_INVALID_HANDLE;
}
-
- if( perr->msg != NULL )
+ 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 perr->msg;
+ return SQL_INVALID_HANDLE;
}
+ hproc = _iodbcdm_getproc (thdbc, en_Error);
+ dhdbc = pdbc->dhdbc;
+ handle = 2;
- for( ptr = (sqlerrmsg_t*)errtab;
- ptr->code != en_sqlstat_total;
- ptr++ )
+ if (herr == SQL_NULL_HERR
+ && pdbc->henv == SQL_NULL_HENV)
{
- if( ptr->code == perr->code )
- {
- return (char FAR*)ptr->msg;
- }
+ return SQL_NO_DATA_FOUND;
}
+ }
+ else if (henv != SQL_NULL_HENV) /* retrive env err */
+ {
+ herr = genv->herr;
- 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;
+ /* Drivers shouldn't push error message
+ * on envoriment handle */
- 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 */
+ if (herr == SQL_NULL_HERR)
{
- 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;
+ return SQL_NO_DATA_FOUND;
}
- else if( hdbc != SQL_NULL_HDBC ) /* retrive dbc err */
+
+ handle = 1;
+ }
+ else
+ {
+ return SQL_INVALID_HANDLE;
+ }
+
+ if (szErrorMsg != NULL)
+ {
+ if (cbErrorMsgMax < 0
+ || cbErrorMsgMax > SQL_MAX_MESSAGE_LENGTH - 1)
{
- 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;
- }
+ return SQL_ERROR;
+ /* SQLError() doesn't post error for itself */
}
- else if( henv != SQL_NULL_HENV ) /* retrive env err */
+ }
+
+ if (herr == SQL_NULL_HERR) /* no err on drv mng */
+ {
+ /* call driver */
+ if (hproc == SQL_NULL_HPROC)
{
- herr = genv->herr;
+ PUSHSQLERR (herr, en_IM001);
- /* Drivers shouldn't push error message
- * on envoriment handle */
+ return SQL_ERROR;
+ }
- if( herr == SQL_NULL_HERR )
- {
- return SQL_NO_DATA_FOUND;
- }
+ CALL_DRIVER (thdbc, retcode, hproc, en_Error,
+ (dhenv, dhdbc, dhstmt, szSqlstate, pfNativeError, szErrorMsg,
+ cbErrorMsgMax, pcbErrorMsg))
- handle = 1;
- }
- else
- {
- return SQL_INVALID_HANDLE;
- }
+ return retcode;
+ }
+
+ if (szSqlstate != NULL)
+ {
+ int len;
- if( szErrorMsg != NULL )
+ /* get sql state string */
+ ststr = (char FAR *) _iodbcdm_getsqlstate (herr,
+ (void FAR *) sqlerrmsg_tab);
+
+ if (ststr == NULL)
{
- if( cbErrorMsgMax < 0
- || cbErrorMsgMax > SQL_MAX_MESSAGE_LENGTH - 1 )
- {
- return SQL_ERROR;
- /* SQLError() doesn't post error for itself */
- }
+ len = 0;
}
-
- if( herr == SQL_NULL_HERR ) /* no err on drv mng */
+ else
{
- /* 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) )
-
-#if 0
- retcode = hproc(dhenv, dhdbc, dhstmt,
- szSqlstate, pfNativeError,
- szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
-#endif
-
- return retcode;
+ len = (int) STRLEN (ststr);
}
- if( szSqlstate != NULL )
+ 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)
{
- 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.
- */
+ *pcbErrorMsg = (SWORD) 0;
}
+ }
+ else
+ {
+ int len;
+ char msgbuf[256] = {'\0'};
+
+ /* get sql state message */
+ errmsg = _iodbcdm_getsqlerrmsg (herr, (void FAR *) sqlerrmsg_tab);
- if( pfNativeError != NULL )
+ if (errmsg == NULL)
{
- /* native error code is specific to data source */
- *pfNativeError = (SDWORD)0L;
+ errmsg = (char FAR *) "";
}
- if( szErrorMsg == NULL || cbErrorMsgMax == 0 )
+ sprintf (msgbuf, "%s%s", sqlerrhd, errmsg);
+
+ len = STRLEN (msgbuf);
+
+ if (len < cbErrorMsgMax - 1)
{
- if( pcbErrorMsg != NULL )
- {
- *pcbErrorMsg = (SWORD)0;
- }
+ retcode = SQL_SUCCESS;
}
- else
+ 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;
- }
+ len = cbErrorMsgMax - 1;
+ retcode = SQL_SUCCESS_WITH_INFO;
+ /* and not posts error for itself */
}
- switch(handle) /* free this err */
+ STRNCPY ((char *) szErrorMsg, msgbuf, len);
+ szErrorMsg[len] = 0;
+
+ if (pcbErrorMsg != NULL)
{
- case 1:
- genv->herr = _iodbcdm_popsqlerr(genv->herr);
- break;
+ *pcbErrorMsg = (SWORD) len;
+ }
+ }
- case 2:
- pdbc->herr = _iodbcdm_popsqlerr(pdbc->herr);
- break;
+ switch (handle) /* free this err */
+ {
+ case 1:
+ genv->herr = _iodbcdm_popsqlerr (genv->herr);
+ break;
- case 3:
- pstmt->herr= _iodbcdm_popsqlerr(pstmt->herr);
- break;
+ case 2:
+ pdbc->herr = _iodbcdm_popsqlerr (pdbc->herr);
+ break;
- default:
- break;
- }
+ case 3:
+ pstmt->herr = _iodbcdm_popsqlerr (pstmt->herr);
+ break;
+
+ default:
+ break;
+ }
- return retcode;
+ return retcode;
}