pgapi30.c
来自「postgresql-odbc,跨平台应用」· C语言 代码 · 共 2,004 行 · 第 1/4 页
C
2,004 行
/*------- * Module: pgapi30.c * * Description: This module contains routines related to ODBC 3.0 * most of their implementations are temporary * and must be rewritten properly. * 2001/07/23 inoue * * Classes: n/a * * API functions: PGAPI_ColAttribute, PGAPI_GetDiagRec, PGAPI_GetConnectAttr, PGAPI_GetStmtAttr, PGAPI_SetConnectAttr, PGAPI_SetStmtAttr *------- */#include "psqlodbc.h"#include "misc.h"#if (ODBCVER >= 0x0300)#include <stdio.h>#include <string.h>#include "environ.h"#include "connection.h"#include "statement.h"#include "descriptor.h"#include "qresult.h"#include "pgapifunc.h"#include "loadlib.h"/* SQLError -> SQLDiagRec */RETCODE SQL_APIPGAPI_GetDiagRec(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLCHAR *Sqlstate, SQLINTEGER *NativeError, SQLCHAR *MessageText, SQLSMALLINT BufferLength, SQLSMALLINT *TextLength){ RETCODE ret; CSTR func = "PGAPI_GetDiagRec"; mylog("%s entering type=%d rec=%d\n", func, HandleType, RecNumber); switch (HandleType) { case SQL_HANDLE_ENV: ret = PGAPI_EnvError(Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength, 0); break; case SQL_HANDLE_DBC: ret = PGAPI_ConnectError(Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength, 0); break; case SQL_HANDLE_STMT: ret = PGAPI_StmtError(Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength, 0); break; case SQL_HANDLE_DESC: ret = PGAPI_DescError(Handle, RecNumber, Sqlstate, NativeError, MessageText, BufferLength, TextLength, 0); break; default: ret = SQL_ERROR; } mylog("%s exiting %d\n", func, ret); return ret;}/* * Minimal implementation. * */RETCODE SQL_APIPGAPI_GetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLSMALLINT RecNumber, SQLSMALLINT DiagIdentifier, PTR DiagInfoPtr, SQLSMALLINT BufferLength, SQLSMALLINT *StringLengthPtr){ RETCODE ret = SQL_ERROR, rtn; ConnectionClass *conn; StatementClass *stmt; SQLLEN rc; SQLSMALLINT pcbErrm; ssize_t rtnlen = -1; int rtnctype = SQL_C_CHAR; CSTR func = "PGAPI_GetDiagField"; mylog("%s entering rec=%d", func, RecNumber); switch (HandleType) { case SQL_HANDLE_ENV: switch (DiagIdentifier) { case SQL_DIAG_CLASS_ORIGIN: case SQL_DIAG_SUBCLASS_ORIGIN: case SQL_DIAG_CONNECTION_NAME: case SQL_DIAG_SERVER_NAME: rtnlen = 0; if (DiagInfoPtr && BufferLength > rtnlen) { ret = SQL_SUCCESS; *((char *) DiagInfoPtr) = '\0'; } else ret = SQL_SUCCESS_WITH_INFO; break; case SQL_DIAG_MESSAGE_TEXT: ret = PGAPI_EnvError(Handle, RecNumber, NULL, NULL, DiagInfoPtr, BufferLength, StringLengthPtr, 0); break; case SQL_DIAG_NATIVE: rtnctype = SQL_C_LONG; ret = PGAPI_EnvError(Handle, RecNumber, NULL, (SQLINTEGER *) DiagInfoPtr, NULL, 0, NULL, 0); break; case SQL_DIAG_NUMBER: rtnctype = SQL_C_LONG; ret = PGAPI_EnvError(Handle, RecNumber, NULL, NULL, NULL, 0, NULL, 0); if (SQL_SUCCEEDED(ret)) { *((SQLINTEGER *) DiagInfoPtr) = 1; } break; case SQL_DIAG_SQLSTATE: rtnlen = 5; ret = PGAPI_EnvError(Handle, RecNumber, DiagInfoPtr, NULL, NULL, 0, NULL, 0); if (SQL_SUCCESS_WITH_INFO == ret) ret = SQL_SUCCESS; break; case SQL_DIAG_RETURNCODE: /* driver manager returns */ break; case SQL_DIAG_CURSOR_ROW_COUNT: case SQL_DIAG_ROW_COUNT: case SQL_DIAG_DYNAMIC_FUNCTION: case SQL_DIAG_DYNAMIC_FUNCTION_CODE: /* options for statement type only */ break; } break; case SQL_HANDLE_DBC: conn = (ConnectionClass *) Handle; switch (DiagIdentifier) { case SQL_DIAG_CLASS_ORIGIN: case SQL_DIAG_SUBCLASS_ORIGIN: case SQL_DIAG_CONNECTION_NAME: rtnlen = 0; if (DiagInfoPtr && BufferLength > rtnlen) { ret = SQL_SUCCESS; *((char *) DiagInfoPtr) = '\0'; } else ret = SQL_SUCCESS_WITH_INFO; break; case SQL_DIAG_SERVER_NAME: rtnlen = strlen(CC_get_DSN(conn)); if (DiagInfoPtr) { strncpy_null((SQLCHAR *) DiagInfoPtr, CC_get_DSN(conn), BufferLength); ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO); } else ret = SQL_SUCCESS_WITH_INFO; break; case SQL_DIAG_MESSAGE_TEXT: ret = PGAPI_ConnectError(Handle, RecNumber, NULL, NULL, DiagInfoPtr, BufferLength, StringLengthPtr, 0); break; case SQL_DIAG_NATIVE: rtnctype = SQL_C_LONG; ret = PGAPI_ConnectError(Handle, RecNumber, NULL, (SQLINTEGER *) DiagInfoPtr, NULL, 0, NULL, 0); break; case SQL_DIAG_NUMBER: rtnctype = SQL_C_LONG; ret = PGAPI_ConnectError(Handle, RecNumber, NULL, NULL, NULL, 0, NULL, 0); if (SQL_SUCCEEDED(ret)) { *((SQLINTEGER *) DiagInfoPtr) = 1; } break; case SQL_DIAG_SQLSTATE: rtnlen = 5; ret = PGAPI_ConnectError(Handle, RecNumber, DiagInfoPtr, NULL, NULL, 0, NULL, 0); if (SQL_SUCCESS_WITH_INFO == ret) ret = SQL_SUCCESS; break; case SQL_DIAG_RETURNCODE: /* driver manager returns */ break; case SQL_DIAG_CURSOR_ROW_COUNT: case SQL_DIAG_ROW_COUNT: case SQL_DIAG_DYNAMIC_FUNCTION: case SQL_DIAG_DYNAMIC_FUNCTION_CODE: /* options for statement type only */ break; } break; case SQL_HANDLE_STMT: conn = (ConnectionClass *) SC_get_conn(((StatementClass *) Handle)); switch (DiagIdentifier) { case SQL_DIAG_CLASS_ORIGIN: case SQL_DIAG_SUBCLASS_ORIGIN: case SQL_DIAG_CONNECTION_NAME: rtnlen = 0; if (DiagInfoPtr && BufferLength > rtnlen) { ret = SQL_SUCCESS; *((char *) DiagInfoPtr) = '\0'; } else ret = SQL_SUCCESS_WITH_INFO; break; case SQL_DIAG_SERVER_NAME: rtnlen = strlen(CC_get_DSN(conn)); if (DiagInfoPtr) { strncpy_null((SQLCHAR *) DiagInfoPtr, CC_get_DSN(conn), BufferLength); ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO); } else ret = SQL_SUCCESS_WITH_INFO; break; case SQL_DIAG_MESSAGE_TEXT: ret = PGAPI_StmtError(Handle, RecNumber, NULL, NULL, DiagInfoPtr, BufferLength, StringLengthPtr, 0); break; case SQL_DIAG_NATIVE: rtnctype = SQL_C_LONG; ret = PGAPI_StmtError(Handle, RecNumber, NULL, (SQLINTEGER *) DiagInfoPtr, NULL, 0, NULL, 0); break; case SQL_DIAG_NUMBER: rtnctype = SQL_C_LONG; *((SQLINTEGER *) DiagInfoPtr) = 0; ret = SQL_NO_DATA_FOUND; stmt = (StatementClass *) Handle; rtn = PGAPI_StmtError(Handle, -1, NULL, NULL, NULL, 0, &pcbErrm, 0); switch (rtn) { case SQL_SUCCESS: case SQL_SUCCESS_WITH_INFO: ret = SQL_SUCCESS; if (pcbErrm > 0 && stmt->pgerror) *((SQLINTEGER *) DiagInfoPtr) = (pcbErrm - 1)/ stmt->pgerror->recsize + 1; break; default: break; } break; case SQL_DIAG_SQLSTATE: rtnlen = 5; ret = PGAPI_StmtError(Handle, RecNumber, DiagInfoPtr, NULL, NULL, 0, NULL, 0); if (SQL_SUCCESS_WITH_INFO == ret) ret = SQL_SUCCESS; break; case SQL_DIAG_CURSOR_ROW_COUNT: rtnctype = SQL_C_LONG; stmt = (StatementClass *) Handle; rc = -1; if (stmt->status == STMT_FINISHED) { QResultClass *res = SC_get_Curres(stmt); /*if (!res) return SQL_ERROR;*/ if (stmt->proc_return > 0) rc = 0; else if (res && QR_NumResultCols(res) > 0 && !SC_is_fetchcursor(stmt)) rc = QR_get_num_total_tuples(res) - res->dl_count; } *((SQLLEN *) DiagInfoPtr) = rc;inolog("rc=%d\n", rc); ret = SQL_SUCCESS; break; case SQL_DIAG_ROW_COUNT: rtnctype = SQL_C_LONG; stmt = (StatementClass *) Handle; *((SQLLEN *) DiagInfoPtr) = stmt->diag_row_count; ret = SQL_SUCCESS; break; case SQL_DIAG_ROW_NUMBER: rtnctype = SQL_C_LONG; *((SQLLEN *) DiagInfoPtr) = SQL_ROW_NUMBER_UNKNOWN; ret = SQL_SUCCESS; break; case SQL_DIAG_COLUMN_NUMBER: rtnctype = SQL_C_LONG; *((SQLINTEGER *) DiagInfoPtr) = SQL_COLUMN_NUMBER_UNKNOWN; ret = SQL_SUCCESS; break; case SQL_DIAG_RETURNCODE: /* driver manager returns */ break; } break; case SQL_HANDLE_DESC: conn = DC_get_conn(((DescriptorClass *) Handle)); switch (DiagIdentifier) { case SQL_DIAG_CLASS_ORIGIN: case SQL_DIAG_SUBCLASS_ORIGIN: case SQL_DIAG_CONNECTION_NAME: rtnlen = 0; if (DiagInfoPtr && BufferLength > rtnlen) { ret = SQL_SUCCESS; *((char *) DiagInfoPtr) = '\0'; } else ret = SQL_SUCCESS_WITH_INFO; break; case SQL_DIAG_SERVER_NAME: rtnlen = strlen(CC_get_DSN(conn)); if (DiagInfoPtr) { strncpy_null((SQLCHAR *) DiagInfoPtr, CC_get_DSN(conn), BufferLength); ret = (BufferLength > rtnlen ? SQL_SUCCESS : SQL_SUCCESS_WITH_INFO); } else ret = SQL_SUCCESS_WITH_INFO; break; case SQL_DIAG_MESSAGE_TEXT: case SQL_DIAG_NATIVE: case SQL_DIAG_NUMBER: break; case SQL_DIAG_SQLSTATE: rtnlen = 5; ret = PGAPI_DescError(Handle, RecNumber, DiagInfoPtr, NULL, NULL, 0, NULL, 0); if (SQL_SUCCESS_WITH_INFO == ret) ret = SQL_SUCCESS; break; case SQL_DIAG_RETURNCODE: /* driver manager returns */ break; case SQL_DIAG_CURSOR_ROW_COUNT: case SQL_DIAG_ROW_COUNT: case SQL_DIAG_DYNAMIC_FUNCTION: case SQL_DIAG_DYNAMIC_FUNCTION_CODE: rtnctype = SQL_C_LONG; /* options for statement type only */ break; } break; default: ret = SQL_ERROR; } if (SQL_C_LONG == rtnctype) { if (SQL_SUCCESS_WITH_INFO == ret) ret = SQL_SUCCESS; if (StringLengthPtr) *StringLengthPtr = sizeof(SQLINTEGER); } else if (rtnlen >= 0) { if (rtnlen >= BufferLength) { if (SQL_SUCCESS == ret) ret = SQL_SUCCESS_WITH_INFO; if (BufferLength > 0) ((char *) DiagInfoPtr) [BufferLength - 1] = '\0'; } if (StringLengthPtr) *StringLengthPtr = (SQLSMALLINT) rtnlen; } mylog("%s exiting %d\n", func, ret); return ret;}/* SQLGetConnectOption -> SQLGetconnectAttr */RETCODE SQL_APIPGAPI_GetConnectAttr(HDBC ConnectionHandle, SQLINTEGER Attribute, PTR Value, SQLINTEGER BufferLength, SQLINTEGER *StringLength){ CSTR func = "PGAPI_GetConnectAttr"; ConnectionClass *conn = (ConnectionClass *) ConnectionHandle; RETCODE ret = SQL_SUCCESS; SQLINTEGER len = 4; mylog("PGAPI_GetConnectAttr %d\n", Attribute); switch (Attribute) { case SQL_ATTR_ASYNC_ENABLE: *((SQLINTEGER *) Value) = SQL_ASYNC_ENABLE_OFF; break; case SQL_ATTR_AUTO_IPD: *((SQLINTEGER *) Value) = SQL_FALSE; break; case SQL_ATTR_CONNECTION_DEAD: *((SQLUINTEGER *) Value) = (conn->status == CONN_NOT_CONNECTED || conn->status == CONN_DOWN); break; case SQL_ATTR_CONNECTION_TIMEOUT: *((SQLUINTEGER *) Value) = 0; break; case SQL_ATTR_METADATA_ID: *((SQLUINTEGER *) Value) = conn->stmtOptions.metadata_id; break; default: ret = PGAPI_GetConnectOption(ConnectionHandle, (UWORD) Attribute, Value, &len, BufferLength); } if (StringLength) *StringLength = len; return ret;}static SQLHDESCdescHandleFromStatementHandle(HSTMT StatementHandle, SQLINTEGER descType) { StatementClass *stmt = (StatementClass *) StatementHandle; switch (descType) { case SQL_ATTR_APP_ROW_DESC: /* 10010 */ return (HSTMT) stmt->ard; case SQL_ATTR_APP_PARAM_DESC: /* 10011 */ return (HSTMT) stmt->apd; case SQL_ATTR_IMP_ROW_DESC: /* 10012 */ return (HSTMT) stmt->ird; case SQL_ATTR_IMP_PARAM_DESC: /* 10013 */ return (HSTMT) stmt->ipd; } return (HSTMT) 0;}static void column_bindings_set(ARDFields *opts, int cols, BOOL maxset){ int i; if (cols == opts->allocated) return; if (cols > opts->allocated) { extend_column_bindings(opts, cols); return; } if (maxset) return; for (i = opts->allocated; i > cols; i--) reset_a_column_binding(opts, i); opts->allocated = cols; if (0 == cols) { free(opts->bindings); opts->bindings = NULL; }}static RETCODE SQL_APIARDSetField(DescriptorClass *desc, SQLSMALLINT RecNumber, SQLSMALLINT FieldIdentifier, PTR Value, SQLINTEGER BufferLength){ RETCODE ret = SQL_SUCCESS; ARDFields *opts = (ARDFields *) (desc + 1); SQLSMALLINT row_idx; BOOL unbind = TRUE; switch (FieldIdentifier) { case SQL_DESC_ARRAY_SIZE: opts->size_of_rowset = CAST_UPTR(SQLULEN, Value); return ret; case SQL_DESC_ARRAY_STATUS_PTR: opts->row_operation_ptr = Value; return ret; case SQL_DESC_BIND_OFFSET_PTR: opts->row_offset_ptr = Value; return ret; case SQL_DESC_BIND_TYPE: opts->bind_size = CAST_UPTR(SQLUINTEGER, Value); return ret; case SQL_DESC_COUNT: column_bindings_set(opts, CAST_PTR(SQLSMALLINT, Value), FALSE); return ret; case SQL_DESC_TYPE:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?