📄 error.c
字号:
tds_strlcpy(errs->errs[n].state3, sqlstate, 6); odbc_get_v2state(errs->errs[n].state3, errs->errs[n].state2); /* TODO why driver ?? -- freddy77 */ errs->errs[n].server = strdup("DRIVER"); errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3); ++errs->num_errors;}/* TODO check if TDS_UINT is correct for native error */voidodbc_errs_add_rdbms(struct _sql_errors *errs, TDS_UINT native, const char *sqlstate, const char *msg, int linenum, int msgstate, const char *server){ struct _sql_error *p; int n = errs->num_errors; if (errs->errs) p = (struct _sql_error *) realloc(errs->errs, sizeof(struct _sql_error) * (n + 1)); else p = (struct _sql_error *) malloc(sizeof(struct _sql_error)); if (!p) return; errs->errs = p; memset(&errs->errs[n], 0, sizeof(struct _sql_error)); errs->errs[n].native = native; if (sqlstate) tds_strlcpy(errs->errs[n].state2, sqlstate, 6); else errs->errs[n].state2[0] = '\0'; strcpy(errs->errs[n].state3, errs->errs[n].state2); sqlstate2to3(errs->errs[n].state3); /* TODO why driver ?? -- freddy77 */ errs->errs[n].server = (server) ? strdup(server) : strdup("DRIVER"); errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3); errs->errs[n].linenum = linenum; errs->errs[n].msgstate = msgstate; ++errs->num_errors;}#define SQLS_MAP(v2,v3) if (strcmp(p,v2) == 0) {strcpy(p,v3); return;}static voidsqlstate2to3(char *state){ char *p = state; if (p[0] == 'S' && p[1] == '0' && p[2] == '0') { p[0] = '4'; p[1] = '2'; p[2] = 'S'; return; } /* TODO optimize with a switch */ SQLS_MAP("01S03", "01001"); SQLS_MAP("01S04", "01001"); SQLS_MAP("22003", "HY019"); SQLS_MAP("22008", "22007"); SQLS_MAP("22005", "22018"); SQLS_MAP("24000", "07005"); SQLS_MAP("37000", "42000"); SQLS_MAP("70100", "HY018"); SQLS_MAP("S1000", "HY000"); SQLS_MAP("S1001", "HY001"); SQLS_MAP("S1002", "07009"); SQLS_MAP("S1003", "HY003"); SQLS_MAP("S1004", "HY004"); SQLS_MAP("S1008", "HY008"); SQLS_MAP("S1009", "HY009"); SQLS_MAP("S1010", "HY007"); SQLS_MAP("S1011", "HY011"); SQLS_MAP("S1012", "HY012"); SQLS_MAP("S1090", "HY090"); SQLS_MAP("S1091", "HY091"); SQLS_MAP("S1092", "HY092"); SQLS_MAP("S1093", "07009"); SQLS_MAP("S1096", "HY096"); SQLS_MAP("S1097", "HY097"); SQLS_MAP("S1098", "HY098"); SQLS_MAP("S1099", "HY099"); SQLS_MAP("S1100", "HY100"); SQLS_MAP("S1101", "HY101"); SQLS_MAP("S1103", "HY103"); SQLS_MAP("S1104", "HY104"); SQLS_MAP("S1105", "HY105"); SQLS_MAP("S1106", "HY106"); SQLS_MAP("S1107", "HY107"); SQLS_MAP("S1108", "HY108"); SQLS_MAP("S1109", "HY109"); SQLS_MAP("S1110", "HY110"); SQLS_MAP("S1111", "HY111"); SQLS_MAP("S1C00", "HYC00"); SQLS_MAP("S1T00", "HYT00");}static SQLRETURN_SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLCHAR FAR * szSqlState, SQLINTEGER FAR * pfNativeError, SQLCHAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg){ SQLRETURN result; struct _sql_errors *errs = NULL; const char *msg; char *p; static const char msgprefix[] = "[FreeTDS][SQL Server]"; SQLINTEGER odbc_ver = SQL_OV_ODBC2; tdsdump_log(TDS_DBG_FUNC, "_SQLGetDiagRec(%d, %p, %d, %p, %p, %p, %d, %p)\n", handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg); if (numRecord <= 0 || cbErrorMsgMax < 0) return SQL_ERROR; if (!handle) return SQL_INVALID_HANDLE; switch (handleType) { case SQL_HANDLE_STMT: odbc_ver = ((TDS_STMT *) handle)->dbc->env->attr.odbc_version; errs = &((TDS_STMT *) handle)->errs; break; case SQL_HANDLE_DBC: odbc_ver = ((TDS_DBC *) handle)->env->attr.odbc_version; errs = &((TDS_DBC *) handle)->errs; break; case SQL_HANDLE_ENV: odbc_ver = ((TDS_ENV *) handle)->attr.odbc_version; errs = &((TDS_ENV *) handle)->errs; break; default: return SQL_INVALID_HANDLE; } if (numRecord > errs->num_errors) return SQL_NO_DATA_FOUND; --numRecord; rank_errors(errs); if (szSqlState) { if (odbc_ver == SQL_OV_ODBC3) strcpy((char *) szSqlState, errs->errs[numRecord].state3); else strcpy((char *) szSqlState, errs->errs[numRecord].state2); } msg = errs->errs[numRecord].msg; if (asprintf(&p, "%s%s", msgprefix, msg) < 0) return SQL_ERROR; result = odbc_set_string(szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1); free(p); if (pfNativeError) *pfNativeError = errs->errs[numRecord].native; return result;}SQLRETURN ODBC_APISQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlState, SQLINTEGER FAR * pfNativeError, SQLCHAR FAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg){ SQLRETURN result; struct _sql_errors *errs = NULL; SQLSMALLINT type; SQLHANDLE handle; tdsdump_log(TDS_DBG_FUNC, "SQLError(%p, %p, %p, %p, %p, %p, %d, %p)\n", henv, hdbc, hstmt, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg); if (hstmt) { errs = &((TDS_STMT *) hstmt)->errs; handle = hstmt; type = SQL_HANDLE_STMT; } else if (hdbc) { errs = &((TDS_DBC *) hdbc)->errs; handle = hdbc; type = SQL_HANDLE_DBC; } else if (henv) { errs = &((TDS_ENV *) henv)->errs; handle = henv; type = SQL_HANDLE_ENV; } else return SQL_INVALID_HANDLE; rank_errors(errs); result = _SQLGetDiagRec(type, handle, 1, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg); if (result == SQL_SUCCESS) { /* remove first error */ odbc_errs_pop(errs); } return result;}#if (ODBCVER >= 0x0300)SQLRETURN ODBC_APISQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLCHAR FAR * szSqlState, SQLINTEGER FAR * pfNativeError, SQLCHAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg){ tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec(%d, %p, %d, %p, %p, %p, %d, %p)\n", handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg); return _SQLGetDiagRec(handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);}SQLRETURN ODBC_APISQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLSMALLINT diagIdentifier, SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer){ SQLRETURN result = SQL_SUCCESS; struct _sql_errors *errs = NULL; const char *msg; SQLINTEGER odbc_ver = SQL_OV_ODBC2; int cplen; TDS_STMT *stmt = NULL; TDS_DBC *dbc = NULL; TDS_ENV *env = NULL; char tmp[16]; tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagField(%d, %p, %d, %d, %p, %d, %p)\n", handleType, handle, numRecord, diagIdentifier, buffer, cbBuffer, pcbBuffer); if (cbBuffer < 0) return SQL_ERROR; if (!handle) return SQL_INVALID_HANDLE; switch (handleType) { case SQL_HANDLE_STMT: stmt = ((TDS_STMT *) handle); dbc = stmt->dbc; env = dbc->env; errs = &stmt->errs; break; case SQL_HANDLE_DBC: dbc = ((TDS_DBC *) handle); env = dbc->env; errs = &dbc->errs; break; case SQL_HANDLE_ENV: env = ((TDS_ENV *) handle); errs = &env->errs; break; default: return SQL_INVALID_HANDLE; } odbc_ver = env->attr.odbc_version; /* header (numRecord ignored) */ switch (diagIdentifier) { case SQL_DIAG_DYNAMIC_FUNCTION: if (handleType != SQL_HANDLE_STMT) return SQL_ERROR; /* TODO */ return odbc_set_string(buffer, cbBuffer, pcbBuffer, "", 0); case SQL_DIAG_DYNAMIC_FUNCTION_CODE: *(SQLINTEGER *) buffer = 0; return SQL_SUCCESS; case SQL_DIAG_NUMBER: *(SQLINTEGER *) buffer = errs->num_errors; return SQL_SUCCESS; case SQL_DIAG_RETURNCODE: *(SQLRETURN *) buffer = errs->lastrc; return SQL_SUCCESS; case SQL_DIAG_CURSOR_ROW_COUNT: if (handleType != SQL_HANDLE_STMT) return SQL_ERROR; /* TODO */ *(SQLINTEGER *) buffer = 0; return SQL_SUCCESS; case SQL_DIAG_ROW_COUNT: if (handleType != SQL_HANDLE_STMT) return SQL_ERROR; return _SQLRowCount((SQLHSTMT) handle, (SQLLEN FAR *) buffer); } if (numRecord > errs->num_errors) return SQL_NO_DATA_FOUND; if (numRecord <= 0) return SQL_ERROR; --numRecord; switch (diagIdentifier) { case SQL_DIAG_ROW_NUMBER: *(SQLINTEGER *) buffer = SQL_ROW_NUMBER_UNKNOWN; break; case SQL_DIAG_CLASS_ORIGIN: case SQL_DIAG_SUBCLASS_ORIGIN: if (odbc_ver == SQL_OV_ODBC2) result = odbc_set_string(buffer, cbBuffer, pcbBuffer, "ISO 9075", -1); else result = odbc_set_string(buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1); break; case SQL_DIAG_COLUMN_NUMBER: *(SQLINTEGER *) buffer = SQL_COLUMN_NUMBER_UNKNOWN; break;#ifdef SQL_DIAG_SS_MSGSTATE case SQL_DIAG_SS_MSGSTATE: if (errs->errs[numRecord].msgstate == 0) return SQL_ERROR; else *(SQLINTEGER *) buffer = errs->errs[numRecord].msgstate; break;#endif#ifdef SQL_DIAG_SS_LINE case SQL_DIAG_SS_LINE: if (errs->errs[numRecord].linenum == 0) return SQL_ERROR; else *(SQLUSMALLINT *) buffer = errs->errs[numRecord].linenum; break;#endif case SQL_DIAG_CONNECTION_NAME: if (dbc && dbc->tds_socket && dbc->tds_socket->spid > 0) cplen = sprintf(tmp, "%d", dbc->tds_socket->spid); else cplen = 0; result = odbc_set_string(buffer, cbBuffer, pcbBuffer, tmp, cplen); break; case SQL_DIAG_MESSAGE_TEXT: msg = errs->errs[numRecord].msg; result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, -1); break; case SQL_DIAG_NATIVE: *(SQLINTEGER *) buffer = errs->errs[numRecord].native; break; case SQL_DIAG_SERVER_NAME: msg = ""; switch (handleType) { case SQL_HANDLE_ENV: break; case SQL_HANDLE_DBC: msg = tds_dstr_cstr(&dbc->server); break; case SQL_HANDLE_STMT: msg = tds_dstr_cstr(&stmt->dbc->server); /* * if dbc->server is not initialized, init it * from the errs structure */ if (!msg[0] && errs->errs[numRecord].server) { tds_dstr_copy(&stmt->dbc->server, errs->errs[numRecord].server); msg = errs->errs[numRecord].server; } break; } result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, -1); break; case SQL_DIAG_SQLSTATE: if (odbc_ver == SQL_OV_ODBC3) msg = errs->errs[numRecord].state3; else msg = errs->errs[numRecord].state2; result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, 5); break; default: return SQL_ERROR; } return result;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -