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 + -
显示快捷键?