📄 herr.c
字号:
/* * herr.c * * $Id: herr.c,v 1.9 2001/06/04 14:01:25 source Exp $ * * 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 <iodbc.h>#include <sql.h>#include <sqlext.h>#include <dlproc.h>#include <herr.h>#if (ODBCVER >= 0x0300)#include <hdesc.h>#endif#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 = herrlist; while (list != SQL_NULL_HERR) { 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) /* overwrite 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; int perr_code; if (herr == SQL_NULL_HERR || tab == NULL) { return (char FAR *) NULL; } perr_code = perr->code;#if (ODBCVER >= 0x0300) switch (perr_code) { case en_S1009 : perr_code = en_HY009; break; }#endif 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;}SQLRETURN SQL_API _iodbcdm_sqlerror ( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlstate, SQLINTEGER FAR * pfNativeError, SQLCHAR FAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg, int bDelete){ GENV (genv, henv); CONN (pdbc, hdbc); STMT (pstmt, hstmt); HDBC thdbc = SQL_NULL_HDBC; 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;#if (ODBCVER >= 0x0300) HPROC hproc1 = SQL_NULL_HPROC; SQLINTEGER handleType; SQLHANDLE handle3; SQLHANDLE dhandle3;#endif char FAR *errmsg = NULL; char FAR *ststr = NULL; int handle = 0; SQLRETURN 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);#if (ODBCVER >= 0x0300) hproc1 = _iodbcdm_getproc (thdbc, en_GetDiagRec); handleType = SQL_HANDLE_STMT; handle3 = hstmt; dhandle3 = pstmt->dhstmt;#endif dhstmt = pstmt->dhstmt; handle = 3; } else if (hdbc != SQL_NULL_HDBC) /* retrive dbc err */ { herr = pdbc->herr; thdbc = pdbc; if (thdbc == SQL_NULL_HDBC) { return SQL_INVALID_HANDLE; } hproc = _iodbcdm_getproc (thdbc, en_Error);#if (ODBCVER >= 0x0300) hproc1 = _iodbcdm_getproc (thdbc, en_GetDiagRec); handleType = SQL_HANDLE_STMT; handle3 = hdbc; dhandle3 = pdbc->dhdbc;#endif 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 (ODBCVER >= 0x0300) if (hproc == SQL_NULL_HPROC && hproc1 == SQL_NULL_HPROC)#else if (hproc == SQL_NULL_HPROC)#endif { return SQL_ERROR; } if (hproc != SQL_NULL_HPROC) { CALL_DRIVER (thdbc, NULL, retcode, hproc, en_Error, (dhenv, dhdbc, dhstmt, szSqlstate, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg)); return retcode; }/* #if (ODBCVER >= 0x0300) else if (hproc1 != SQL_NULL_HPROC) { CALL_DRIVER (thdbc, handle3, retcode, hproc1, en_GetDiagRec, (handleType, dhandle3, 1, szSqlstate, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg)); } else retcode = SQL_NO_DATA_FOUND;#endif */ } 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; } } if (bDelete) 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;}SQLRETURN SQL_API SQLError ( SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlstate, SQLINTEGER FAR * pfNativeError, SQLCHAR FAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg){ SQLRETURN retcode; ODBC_LOCK (); retcode = _iodbcdm_sqlerror (henv, hdbc, hstmt, szSqlstate, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg, 1); ODBC_UNLOCK (); return retcode;}#if (ODBCVER >= 0x0300)static interror_rec_count (HERR herr){ sqlerr_t *err = (sqlerr_t *)herr; if (err) return err->idx + 1; else return 0;}static sqlerr_t *get_nth_error(HERR herr, int nIndex){ sqlerr_t *err = herr; while (err && err->idx != nIndex) err = err->next; return err;}RETCODE SQL_APISQLGetDiagRec (SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR * Sqlstate, UNALIGNED SQLINTEGER * NativeErrorPtr, SQLCHAR * MessageText, SQLSMALLINT BufferLength, UNALIGNED SQLSMALLINT * TextLengthPtr){ sqlerr_t *curr_err = NULL; HERR err = NULL; HERR saved; int nRecs; HPROC hproc = SQL_NULL_HPROC; HDBC hdbc = SQL_NULL_HDBC; RETCODE retcode; SQLHANDLE dhandle = SQL_NULL_HANDLE; if (RecNumber < 1) return SQL_ERROR; if (BufferLength < 0) return SQL_ERROR; ODBC_LOCK (); switch (HandleType) { case SQL_HANDLE_ENV: if (!IS_VALID_HENV (Handle)) { ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } err = ((GENV_t *) Handle)->herr; break; case SQL_HANDLE_DBC: if (!IS_VALID_HDBC (Handle)) { ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } err = ((DBC_t *) Handle)->herr; dhandle = ((DBC_t *) Handle)->dhdbc; hdbc = Handle; break; case SQL_HANDLE_STMT: if (!IS_VALID_HSTMT (Handle)) { ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } err = ((STMT_t *) Handle)->herr; dhandle = ((STMT_t *) Handle)->dhstmt; hdbc = ((STMT_t *) Handle)->hdbc; break; case SQL_HANDLE_DESC: if (!IS_VALID_HDESC (Handle)) { ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } err = ((DESC_t *) Handle)->herr; dhandle = ((DESC_t *) Handle)->dhdesc; hdbc = ((DESC_t *) Handle)->hdbc; break; default: ODBC_UNLOCK (); return SQL_INVALID_HANDLE; } nRecs = error_rec_count (err); if (nRecs >= RecNumber) { /* DM error range */ curr_err = get_nth_error (err, RecNumber - 1); if (!curr_err) { ODBC_UNLOCK (); return (SQL_NO_DATA_FOUND); } retcode = SQL_SUCCESS; if (Sqlstate != NULL) { int len; char *ststr = (char FAR *) _iodbcdm_getsqlstate (curr_err, (void FAR *) sqlerrmsg_tab); if (ststr == NULL) { len = 0; } else { len = (int) STRLEN (ststr); } STRNCPY (Sqlstate, ststr, len); Sqlstate[len] = 0; /* buffer size of szSqlstate is not checked. Applications * suppose provide enough ( not less than 6 bytes ) buffer * or NULL for it. */ } if (MessageText == NULL || BufferLength == 0) { if (TextLengthPtr != NULL) { *TextLengthPtr = (SWORD) 0; } } else { int len; char msgbuf[256] = { '\0' };
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -