📄 odbcapi.c
字号:
/*------- * Module: odbcapi.c * * Description: This module contains routines related to * preparing and executing an SQL statement. * * Classes: n/a * * API functions: SQLAllocConnect, SQLAllocEnv, SQLAllocStmt, SQLBindCol, SQLCancel, SQLColumns, SQLConnect, SQLDataSources, SQLDescribeCol, SQLDisconnect, SQLError, SQLExecDirect, SQLExecute, SQLFetch, SQLFreeConnect, SQLFreeEnv, SQLFreeStmt, SQLGetConnectOption, SQLGetCursorName, SQLGetData, SQLGetFunctions, SQLGetInfo, SQLGetStmtOption, SQLGetTypeInfo, SQLNumResultCols, SQLParamData, SQLPrepare, SQLPutData, SQLRowCount, SQLSetConnectOption, SQLSetCursorName, SQLSetParam, SQLSetStmtOption, SQLSpecialColumns, SQLStatistics, SQLTables, SQLTransact, SQLColAttributes, SQLColumnPrivileges, SQLDescribeParam, SQLExtendedFetch, SQLForeignKeys, SQLMoreResults, SQLNativeSql, SQLNumParams, SQLParamOptions, SQLPrimaryKeys, SQLProcedureColumns, SQLProcedures, SQLSetPos, SQLTablePrivileges, SQLBindParameter *------- */#include "psqlodbc.h"#include <stdio.h>#include <string.h>#include "pgapifunc.h"#include "environ.h"#include "connection.h"#include "statement.h"#include "qresult.h"#include "loadlib.h"#if (ODBCVER < 0x0300)RETCODE SQL_APISQLAllocConnect(HENV EnvironmentHandle, HDBC FAR * ConnectionHandle){ RETCODE ret; EnvironmentClass *env = (EnvironmentClass *) EnvironmentHandle; mylog("[SQLAllocConnect]"); ENTER_ENV_CS(env); ret = PGAPI_AllocConnect(EnvironmentHandle, ConnectionHandle); LEAVE_ENV_CS(env); return ret;}RETCODE SQL_APISQLAllocEnv(HENV FAR * EnvironmentHandle){ RETCODE ret; mylog("[SQLAllocEnv]"); ret = PGAPI_AllocEnv(EnvironmentHandle); return ret;}RETCODE SQL_APISQLAllocStmt(HDBC ConnectionHandle, HSTMT *StatementHandle){ RETCODE ret; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; mylog("[SQLAllocStmt]"); ENTER_CONN_CS(conn); CC_clear_error(conn); ret = PGAPI_AllocStmt(ConnectionHandle, StatementHandle); LEAVE_CONN_CS(conn); return ret;}#endif /* ODBCVER */RETCODE SQL_APISQLBindCol(HSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, PTR TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind){ RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[SQLBindCol]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_BindCol(StatementHandle, ColumnNumber, TargetType, TargetValue, BufferLength, StrLen_or_Ind); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret;}RETCODE SQL_APISQLCancel(HSTMT StatementHandle){ RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[SQLCancel]"); /* Not that neither ENTER_STMT_CS nor StartRollbackState is called */ /* SC_clear_error((StatementClass *) StatementHandle); maybe this neither */ ret = PGAPI_Cancel(StatementHandle); return DiscardStatementSvp(stmt, ret, FALSE);}RETCODE SQL_APISQLColumns(HSTMT StatementHandle, SQLCHAR *CatalogName, SQLSMALLINT NameLength1, SQLCHAR *SchemaName, SQLSMALLINT NameLength2, SQLCHAR *TableName, SQLSMALLINT NameLength3, SQLCHAR *ColumnName, SQLSMALLINT NameLength4){ CSTR func = "SQLColumns"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; SQLCHAR *ctName = CatalogName, *scName = SchemaName, *tbName = TableName, *clName = ColumnName; UWORD flag = PODBC_SEARCH_PUBLIC_SCHEMA; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt);#if (ODBCVER >= 0x0300) if (stmt->options.metadata_id) flag |= PODBC_NOT_SEARCH_PATTERN;#endif if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else ret = PGAPI_Columns(StatementHandle, ctName, NameLength1, scName, NameLength2, tbName, NameLength3, clName, NameLength4, flag, 0, 0); if (SQL_SUCCESS == ret && 0 == QR_get_num_total_tuples(SC_get_Result(stmt))) { BOOL ifallupper = TRUE, reexec = FALSE; char *newCt = NULL, *newSc = NULL, *newTb = NULL, *newCl = NULL; ConnectionClass *conn = SC_get_conn(stmt); if (SC_is_lower_case(stmt, conn)) /* case-insensitive identifier */ ifallupper = FALSE; if (newCt = make_lstring_ifneeded(conn, CatalogName, NameLength1, ifallupper), NULL != newCt) { ctName = newCt; reexec = TRUE; } if (newSc = make_lstring_ifneeded(conn, SchemaName, NameLength2, ifallupper), NULL != newSc) { scName = newSc; reexec = TRUE; } if (newTb = make_lstring_ifneeded(conn, TableName, NameLength3, ifallupper), NULL != newTb) { tbName = newTb; reexec = TRUE; } if (newCl = make_lstring_ifneeded(conn, ColumnName, NameLength4, ifallupper), NULL != newCl) { clName = newCl; reexec = TRUE; } if (reexec) { ret = PGAPI_Columns(StatementHandle, ctName, NameLength1, scName, NameLength2, tbName, NameLength3, clName, NameLength4, flag, 0, 0); if (newCt) free(newCt); if (newSc) free(newSc); if (newTb) free(newTb); if (newCl) free(newCl); } } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret;}RETCODE SQL_APISQLConnect(HDBC ConnectionHandle, SQLCHAR *ServerName, SQLSMALLINT NameLength1, SQLCHAR *UserName, SQLSMALLINT NameLength2, SQLCHAR *Authentication, SQLSMALLINT NameLength3){ RETCODE ret; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; mylog("[SQLConnect]"); ENTER_CONN_CS(conn); CC_clear_error(conn); ret = PGAPI_Connect(ConnectionHandle, ServerName, NameLength1, UserName, NameLength2, Authentication, NameLength3); LEAVE_CONN_CS(conn); return ret;}RETCODE SQL_APISQLDriverConnect(HDBC hdbc, HWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR FAR * szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT FAR * pcbConnStrOut, SQLUSMALLINT fDriverCompletion){ RETCODE ret; ConnectionClass *conn = (ConnectionClass *) hdbc; mylog("[SQLDriverConnect]"); ENTER_CONN_CS(conn); CC_clear_error(conn); ret = PGAPI_DriverConnect(hdbc, hwnd, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, fDriverCompletion); LEAVE_CONN_CS(conn); return ret;}RETCODE SQL_APISQLBrowseConnect( HDBC hdbc, SQLCHAR *szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR *szConnStrOut, SQLSMALLINT cbConnStrOutMax, SQLSMALLINT *pcbConnStrOut){ RETCODE ret; ConnectionClass *conn = (ConnectionClass *) hdbc; mylog("[SQLBrowseConnect]"); ENTER_CONN_CS(conn); CC_clear_error(conn); ret = PGAPI_BrowseConnect(hdbc, szConnStrIn, cbConnStrIn, szConnStrOut, cbConnStrOutMax, pcbConnStrOut); LEAVE_CONN_CS(conn); return ret;}RETCODE SQL_APISQLDataSources(HENV EnvironmentHandle, SQLUSMALLINT Direction, SQLCHAR *ServerName, SQLSMALLINT BufferLength1, SQLSMALLINT *NameLength1, SQLCHAR *Description, SQLSMALLINT BufferLength2, SQLSMALLINT *NameLength2){ mylog("[SQLDataSources]"); /* * return PGAPI_DataSources(EnvironmentHandle, Direction, ServerName, * BufferLength1, NameLength1, Description, BufferLength2, * NameLength2); */ return SQL_ERROR;}RETCODE SQL_APISQLDescribeCol(HSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLCHAR *ColumnName, SQLSMALLINT BufferLength, SQLSMALLINT *NameLength, SQLSMALLINT *DataType, SQLULEN *ColumnSize, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable){ RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[SQLDescribeCol]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_DescribeCol(StatementHandle, ColumnNumber, ColumnName, BufferLength, NameLength, DataType, ColumnSize, DecimalDigits, Nullable); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret;}RETCODE SQL_APISQLDisconnect(HDBC ConnectionHandle){ CSTR func = "SQLDisconnect"; RETCODE ret; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; mylog("[%s for %p]", func, ConnectionHandle);#ifdef _HANDLE_ENLIST_IN_DTC_ CALL_DtcOnDisconnect(conn); /* must be called without holding the connection lock */#endif /* _HANDLE_ENLIST_IN_DTC_ */ ENTER_CONN_CS(conn); CC_clear_error(conn); ret = PGAPI_Disconnect(ConnectionHandle); LEAVE_CONN_CS(conn); return ret;}#if (ODBCVER < 0x0300)RETCODE SQL_APISQLError(HENV EnvironmentHandle, HDBC ConnectionHandle, HSTMT StatementHandle, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength){ RETCODE ret; mylog("[SQLError]"); if (NULL != EnvironmentHandle) ENTER_ENV_CS((EnvironmentClass *) EnvironmentHandle); ret = PGAPI_Error(EnvironmentHandle, ConnectionHandle, StatementHandle, Sqlstate, NativeError, MessageText, BufferLength, TextLength); if (NULL != EnvironmentHandle) LEAVE_ENV_CS((EnvironmentClass *) EnvironmentHandle); return ret;}#endif /* ODBCVER */RETCODE SQL_APISQLExecDirect(HSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength){ CSTR func = "SQLExecDirect"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; UWORD flag = 0; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); if (PG_VERSION_GE(SC_get_conn(stmt), 7.4)) flag |= PODBC_WITH_HOLD; if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else { StartRollbackState(stmt); ret = PGAPI_ExecDirect(StatementHandle, StatementText, TextLength, flag); ret = DiscardStatementSvp(stmt, ret, FALSE); } LEAVE_STMT_CS(stmt); return ret;}RETCODE SQL_APISQLExecute(HSTMT StatementHandle){ CSTR func = "SQLExecute"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; UWORD flag = 0; mylog("[%s]", func); ENTER_STMT_CS(stmt); SC_clear_error(stmt); if (PG_VERSION_GE(SC_get_conn(stmt), 7.4)) flag |= PODBC_WITH_HOLD; if (SC_opencheck(stmt, func)) ret = SQL_ERROR; else { StartRollbackState(stmt); ret = PGAPI_Execute(StatementHandle, flag); ret = DiscardStatementSvp(stmt, ret, FALSE); } LEAVE_STMT_CS(stmt); return ret;}RETCODE SQL_APISQLFetch(HSTMT StatementHandle){ CSTR func = "SQLFetch"; RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt);#if (ODBCVER >= 0x0300) if (SC_get_conn(stmt)->driver_version >= 0x0300) { IRDFields *irdopts = SC_get_IRDF(stmt); ARDFields *ardopts = SC_get_ARDF(stmt); SQLUSMALLINT *rowStatusArray = irdopts->rowStatusArray; SQLLEN *pcRow = irdopts->rowsFetched; mylog("[[%s]]", func); ret = PGAPI_ExtendedFetch(StatementHandle, SQL_FETCH_NEXT, 0, pcRow, rowStatusArray, 0, ardopts->size_of_rowset); stmt->transition_status = 6; } else#endif { mylog("[%s]", func); ret = PGAPI_Fetch(StatementHandle); } ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret;}#if (ODBCVER < 0x0300) RETCODE SQL_APISQLFreeConnect(HDBC ConnectionHandle){ RETCODE ret; mylog("[SQLFreeConnect]"); ret = PGAPI_FreeConnect(ConnectionHandle); return ret;}RETCODE SQL_APISQLFreeEnv(HENV EnvironmentHandle){ RETCODE ret; mylog("[SQLFreeEnv]"); ret = PGAPI_FreeEnv(EnvironmentHandle); return ret;}#endif /* ODBCVER */ RETCODE SQL_APISQLFreeStmt(HSTMT StatementHandle, SQLUSMALLINT Option){ RETCODE ret; mylog("[SQLFreeStmt]"); ret = PGAPI_FreeStmt(StatementHandle, Option); return ret;}#if (ODBCVER < 0x0300)RETCODE SQL_APISQLGetConnectOption(HDBC ConnectionHandle, SQLUSMALLINT Option, PTR Value){ RETCODE ret; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; mylog("[SQLGetConnectOption]"); ENTER_CONN_CS(conn); CC_clear_error(conn); ret = PGAPI_GetConnectOption(ConnectionHandle, Option, Value, NULL, 64); LEAVE_CONN_CS(conn); return ret;}#endif /* ODBCVER */RETCODE SQL_APISQLGetCursorName(HSTMT StatementHandle, SQLCHAR *CursorName, SQLSMALLINT BufferLength, SQLSMALLINT *NameLength){ RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[SQLGetCursorName]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_GetCursorName(StatementHandle, CursorName, BufferLength, NameLength); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret;}RETCODE SQL_APISQLGetData(HSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, PTR TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind){ RETCODE ret; StatementClass *stmt = (StatementClass *) StatementHandle; mylog("[SQLGetData]"); ENTER_STMT_CS(stmt); SC_clear_error(stmt); StartRollbackState(stmt); ret = PGAPI_GetData(StatementHandle, ColumnNumber, TargetType, TargetValue, BufferLength, StrLen_or_Ind); ret = DiscardStatementSvp(stmt, ret, FALSE); LEAVE_STMT_CS(stmt); return ret;}RETCODE SQL_APISQLGetFunctions(HDBC ConnectionHandle, SQLUSMALLINT FunctionId, SQLUSMALLINT *Supported){ RETCODE ret; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; mylog("[SQLGetFunctions]"); ENTER_CONN_CS(conn); CC_clear_error(conn);#if (ODBCVER >= 0x0300) if (FunctionId == SQL_API_ODBC3_ALL_FUNCTIONS) ret = PGAPI_GetFunctions30(ConnectionHandle, FunctionId, Supported); else#endif { ret = PGAPI_GetFunctions(ConnectionHandle, FunctionId, Supported); } LEAVE_CONN_CS(conn); return ret;}RETCODE SQL_APISQLGetInfo(HDBC ConnectionHandle, SQLUSMALLINT InfoType, PTR InfoValue, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength){ CSTR func = "SQLGetInfo"; RETCODE ret; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; ENTER_CONN_CS(conn); CC_clear_error(conn);#if (ODBCVER >= 0x0300) mylog("[SQLGetInfo(30)]"); if ((ret = PGAPI_GetInfo(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength)) == SQL_ERROR) { if (conn->driver_version >= 0x0300) { CC_clear_error(conn); ret = PGAPI_GetInfo30(ConnectionHandle, InfoType, InfoValue, BufferLength, StringLength); goto cleanup; } } if (SQL_ERROR == ret)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -