options.c

来自「postgresql-odbc,跨平台应用」· C语言 代码 · 共 812 行 · 第 1/2 页

C
812
字号
/*-------- * Module:			options.c * * Description:		This module contains routines for getting/setting *					connection and statement options. * * Classes:			n/a * * API functions:	SQLSetConnectOption, SQLSetStmtOption, SQLGetConnectOption, *					SQLGetStmtOption * * Comments:		See "notice.txt" for copyright and license information. *-------- */#include "psqlodbc.h"#include <string.h>#include "environ.h"#include "connection.h"#include "statement.h"#include "qresult.h"#include "pgapifunc.h"RETCODEset_statement_option(ConnectionClass *conn,					 StatementClass *stmt,					 SQLUSMALLINT fOption,					 SQLULEN vParam){	CSTR func = "set_statement_option";	char		changed = FALSE;	ConnInfo   *ci = NULL;	SQLULEN		setval;	if (conn)		ci = &(conn->connInfo);	else if (stmt)		ci = &(SC_get_conn(stmt)->connInfo);	switch (fOption)	{		case SQL_ASYNC_ENABLE:	/* ignored */			break;		case SQL_BIND_TYPE:			/* now support multi-column and multi-row binding */			if (conn)				conn->ardOptions.bind_size = (SQLUINTEGER) vParam;			if (stmt)				SC_get_ARDF(stmt)->bind_size = (SQLUINTEGER) vParam;			break;		case SQL_CONCURRENCY:			/*			 * positioned update isn't supported so cursor concurrency is			 * read-only			 */			mylog("SetStmtOption(): SQL_CONCURRENCY = %d ", vParam);			setval = SQL_CONCUR_READ_ONLY;			if (SQL_CONCUR_READ_ONLY == vParam)				;			else if (ci->drivers.lie)				setval = vParam;			else if (0 != ci->updatable_cursors)				setval = SQL_CONCUR_ROWVER;			if (conn)				conn->stmtOptions.scroll_concurrency = (SQLUINTEGER) setval;			else if (stmt)			{				if (SC_get_Result(stmt))				{					SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.", func);					return SQL_ERROR;				}				stmt->options.scroll_concurrency =				stmt->options_orig.scroll_concurrency = (SQLUINTEGER) setval;			}			if (setval != vParam)				changed = TRUE;			mylog("-> %d\n", setval);			break;		case SQL_CURSOR_TYPE:			/*			 * if declare/fetch, then type can only be forward. otherwise,			 * it can only be forward or static.			 */			mylog("SetStmtOption(): SQL_CURSOR_TYPE = %d ", vParam);			setval = SQL_CURSOR_FORWARD_ONLY;			if (ci->drivers.lie)				setval = vParam;			else if (SQL_CURSOR_STATIC == vParam)				setval = vParam;			else if (SQL_CURSOR_KEYSET_DRIVEN == vParam ||				 SQL_CURSOR_DYNAMIC == vParam)			{				if (0 != (ci->updatable_cursors & ALLOW_KEYSET_DRIVEN_CURSORS)) 					setval = vParam;				else					setval = SQL_CURSOR_STATIC; /* at least scrollable */			}			if (conn)				conn->stmtOptions.cursor_type = (SQLUINTEGER) setval;			else if (stmt)			{				if (SC_get_Result(stmt))				{					SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "The attr can't be changed because the cursor is open.", func);					return SQL_ERROR;				}				stmt->options_orig.cursor_type =				stmt->options.cursor_type = (SQLUINTEGER) setval;			}			if (setval != vParam)				changed = TRUE;			mylog("-> %d\n", setval);			break;		case SQL_KEYSET_SIZE:	/* ignored, but saved and returned	*/			mylog("SetStmtOption(): SQL_KEYSET_SIZE, vParam = %d\n", vParam);			if (conn)				conn->stmtOptions.keyset_size = vParam;			if (stmt)			{				stmt->options_orig.keyset_size = vParam;				if (!SC_get_Result(stmt)) 					stmt->options.keyset_size = vParam;				if (stmt->options.keyset_size != (int)vParam)					changed = TRUE;			}			break;		case SQL_MAX_LENGTH:	/* ignored, but saved */			mylog("SetStmtOption(): SQL_MAX_LENGTH, vParam = %d\n", vParam);			if (conn)				conn->stmtOptions.maxLength = vParam;			if (stmt)			{				stmt->options_orig.maxLength = vParam;				if (!SC_get_Result(stmt)) 					stmt->options.maxLength = vParam;				if (stmt->options.maxLength != (int)vParam)					changed = TRUE;			}			break;		case SQL_MAX_ROWS:		/* ignored, but saved */			mylog("SetStmtOption(): SQL_MAX_ROWS, vParam = %d\n", vParam);			if (conn)				conn->stmtOptions.maxRows = vParam;			if (stmt)			{				stmt->options_orig.maxRows = vParam;				if (!SC_get_Result(stmt)) 					stmt->options.maxRows = vParam;				if (stmt->options.maxRows != (int)vParam)					changed = TRUE;			}			break;		case SQL_NOSCAN:		/* ignored */			mylog("SetStmtOption: SQL_NOSCAN, vParam = %d\n", vParam);			break;		case SQL_QUERY_TIMEOUT:	/* ignored */			mylog("SetStmtOption: SQL_QUERY_TIMEOUT, vParam = %d\n", vParam);			/* "0" returned in SQLGetStmtOption */			break;		case SQL_RETRIEVE_DATA:			mylog("SetStmtOption(): SQL_RETRIEVE_DATA, vParam = %d\n", vParam);			if (conn)				conn->stmtOptions.retrieve_data = (SQLUINTEGER) vParam;			if (stmt)				stmt->options.retrieve_data = (SQLUINTEGER) vParam;			break;		case SQL_ROWSET_SIZE:			mylog("SetStmtOption(): SQL_ROWSET_SIZE, vParam = %d\n", vParam);			/*			 * Save old rowset size for SQLExtendedFetch purposes If the			 * rowset_size is being changed since the last call to fetch			 * rows.			 */			if (stmt && stmt->save_rowset_size <= 0 && stmt->last_fetch_count > 0)				stmt->save_rowset_size = SC_get_ARDF(stmt)->size_of_rowset_odbc2;			if (vParam < 1)			{				vParam = 1;				changed = TRUE;			}			if (conn)				conn->ardOptions.size_of_rowset_odbc2 = vParam;			if (stmt)				SC_get_ARDF(stmt)->size_of_rowset_odbc2 = vParam;			break;		case SQL_SIMULATE_CURSOR:		/* NOT SUPPORTED */			if (stmt)			{				SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported.  Use the cursor library.", func);			}			if (conn)			{				CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Simulated positioned update/delete not supported.  Use the cursor library.", func);			}			return SQL_ERROR;		case SQL_USE_BOOKMARKS:			if (stmt)			{#if (ODBCVER >= 0x0300)				mylog("USE_BOOKMARKS %s\n", (vParam == SQL_UB_OFF) ? "off" : ((vParam == SQL_UB_VARIABLE) ? "variable" : "fixed"));#endif /* ODBCVER */				setval = vParam;				stmt->options.use_bookmarks = (SQLUINTEGER) setval;			}			if (conn)				conn->stmtOptions.use_bookmarks = (SQLUINTEGER) vParam;			break;		case 1204: /* SQL_COPT_SS_PRESERVE_CURSORS ? */			if (stmt)			{				SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);			}			else if (conn)			{				CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);			}			return SQL_ERROR;		case 1227: /* SQL_SOPT_SS_HIDDEN_COLUMNS ? */		case 1228: /* SQL_SOPT_SS_NOBROWSETABLE ? */			if (stmt)			{#ifndef	NOT_USED				if (0 != vParam)					changed = TRUE;				break;#endif /* NOT_USED */				SC_set_error(stmt, STMT_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);			}			else if (conn)			{				CC_set_error(conn, CONN_OPTION_NOT_FOR_THE_DRIVER, "The option may be for MS SQL Server(Set)", func);			}			return SQL_ERROR;		default:			{				char		option[64];				if (stmt)				{					SC_set_error(stmt, STMT_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)", NULL);					sprintf(option, "fOption=%d, vParam=" FORMAT_LEN, fOption, vParam);					SC_log_error(func, option, stmt);				}				if (conn)				{					CC_set_error(conn, CONN_NOT_IMPLEMENTED_ERROR, "Unknown statement option (Set)", func);					sprintf(option, "fOption=%d, vParam=" FORMAT_LEN, fOption, vParam);					CC_log_error(func, option, conn);				}				return SQL_ERROR;			}	}	if (changed)	{		if (stmt)		{			SC_set_error(stmt, STMT_OPTION_VALUE_CHANGED, "Requested value changed.", func);		}		if (conn)		{			CC_set_error(conn, CONN_OPTION_VALUE_CHANGED, "Requested value changed.", func);		}		return SQL_SUCCESS_WITH_INFO;	}	else		return SQL_SUCCESS;}/* Implements only SQL_AUTOCOMMIT */RETCODE		SQL_APIPGAPI_SetConnectOption(					   HDBC hdbc,					   SQLUSMALLINT fOption,					   SQLULEN vParam){	CSTR func = "PGAPI_SetConnectOption";	ConnectionClass *conn = (ConnectionClass *) hdbc;	ConnInfo   *ci = &(conn->connInfo);	char		changed = FALSE;	RETCODE		retval;	BOOL		autocomm_on;	mylog("%s: entering fOption = %d vParam = %d\n", func, fOption, vParam);	if (!conn)	{		CC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}	switch (fOption)	{			/*			 * Statement Options (apply to all stmts on the connection and			 * become defaults for new stmts)			 */		case SQL_ASYNC_ENABLE:		case SQL_BIND_TYPE:		case SQL_CONCURRENCY:		case SQL_CURSOR_TYPE:		case SQL_KEYSET_SIZE:		case SQL_MAX_LENGTH:		case SQL_MAX_ROWS:		case SQL_NOSCAN:		case SQL_QUERY_TIMEOUT:		case SQL_RETRIEVE_DATA:		case SQL_ROWSET_SIZE:		case SQL_SIMULATE_CURSOR:		case SQL_USE_BOOKMARKS:#if (ODBCVER < 0x0300)			{				int	i;				/* Affect all current Statements */				for (i = 0; i < conn->num_stmts; i++)				{					if (conn->stmts[i])						set_statement_option(NULL, conn->stmts[i], fOption, vParam);				}			}#endif /* ODBCVER */			/*			 * Become the default for all future statements on this			 * connection			 */			retval = set_statement_option(conn, NULL, fOption, vParam);			if (retval == SQL_SUCCESS_WITH_INFO)				changed = TRUE;			else if (retval == SQL_ERROR)				return SQL_ERROR;			break;			/*			 * Connection Options			 */		case SQL_ACCESS_MODE:	/* ignored */			break;		case SQL_AUTOCOMMIT:			switch (vParam)			{				case SQL_AUTOCOMMIT_ON:					autocomm_on = TRUE;					break;				case SQL_AUTOCOMMIT_OFF:					autocomm_on = FALSE;					break;				default:					CC_set_error(conn, CONN_INVALID_ARGUMENT_NO, "Illegal parameter value for SQL_AUTOCOMMIT", func);					return SQL_ERROR;			}			if (autocomm_on && SQL_AUTOCOMMIT_OFF != ci->autocommit_public)				break;			else if (!autocomm_on && SQL_AUTOCOMMIT_OFF == ci->autocommit_public)				break;			ci->autocommit_public = (autocomm_on ? SQL_AUTOCOMMIT_ON : SQL_AUTOCOMMIT_OFF);			mylog("%s: AUTOCOMMIT: transact_status=%d, vparam=%d\n", func, conn->transact_status, vParam);#ifdef	_HANDLE_ENLIST_IN_DTC_			if (NULL != conn->asdum)			{				mylog("%s: Ignored AUTOCOMMIT in a distributed transaction, OK ?");				break;			}#endif	/* _HANDLE_ENLIST_IN_DTC_ */			CC_set_autocommit(conn, autocomm_on);			break;		case SQL_CURRENT_QUALIFIER:		/* ignored */			break;		case SQL_LOGIN_TIMEOUT:			conn->login_timeout = (SQLUINTEGER) vParam;			break;		case SQL_PACKET_SIZE:	/* ignored */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?