⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statement.c

📁 postgresql-odbc,跨平台应用
💻 C
📖 第 1 页 / 共 5 页
字号:
/*------- * Module:			statement.c * * Description:		This module contains functions related to creating *					and manipulating a statement. * * Classes:			StatementClass (Functions prefix: "SC_") * * API functions:	SQLAllocStmt, SQLFreeStmt * * Comments:		See "notice.txt" for copyright and license information. *------- */#ifndef	_WIN32_WINNT#define	_WIN32_WINNT	0x0400#endif /* _WIN32_WINNT */#include "statement.h"#include "bind.h"#include "connection.h"#include "multibyte.h"#include "qresult.h"#include "convert.h"#include "environ.h"#include <stdio.h>#include <string.h>#include <ctype.h>#include "pgapifunc.h"#define PRN_NULLCHECK/*	Map sql commands to statement types */static struct{	int			type;	char	   *s;}	Statement_Type[] ={	{		STMT_TYPE_SELECT, "SELECT"	}	,{		STMT_TYPE_INSERT, "INSERT"	}	,{		STMT_TYPE_UPDATE, "UPDATE"	}	,{		STMT_TYPE_DELETE, "DELETE"	}	,{		STMT_TYPE_PROCCALL, "{"	}	,{		STMT_TYPE_SET, "SET"	}	,{		STMT_TYPE_RESET, "RESET"	}	,{		STMT_TYPE_CREATE, "CREATE"	}	,{		STMT_TYPE_DECLARE, "DECLARE"	}	,{		STMT_TYPE_FETCH, "FETCH"	}	,{		STMT_TYPE_MOVE, "MOVE"	}	,{		STMT_TYPE_CLOSE, "CLOSE"	}	,{		STMT_TYPE_PREPARE, "PREPARE"	}	,{		STMT_TYPE_EXECUTE, "EXECUTE"	}	,{		STMT_TYPE_DEALLOCATE, "DEALLOCATE"	}	,{		STMT_TYPE_DROP, "DROP"	}	,{		STMT_TYPE_START, "BEGIN"	}	,{		STMT_TYPE_START, "START"	}	,{		STMT_TYPE_TRANSACTION, "SAVEPOINT"	}	,{		STMT_TYPE_TRANSACTION, "RELEASE"	}	,{		STMT_TYPE_TRANSACTION, "COMMIT"	}	,{		STMT_TYPE_TRANSACTION, "END"	}	,{		STMT_TYPE_TRANSACTION, "ROLLBACK"	}	,{		STMT_TYPE_TRANSACTION, "ABORT"	}	,{		STMT_TYPE_LOCK, "LOCK"	}	,{		STMT_TYPE_ALTER, "ALTER"	}	,{		STMT_TYPE_GRANT, "GRANT"	}	,{		STMT_TYPE_REVOKE, "REVOKE"	}	,{		STMT_TYPE_COPY, "COPY"	}	,{		STMT_TYPE_ANALYZE, "ANALYZE"	}	,{		STMT_TYPE_NOTIFY, "NOTIFY"	}	,{		STMT_TYPE_EXPLAIN, "EXPLAIN"	}	,{		STMT_TYPE_SPECIAL, "VACUUM"	}	,{		STMT_TYPE_SPECIAL, "REINDEX"	}	,{		STMT_TYPE_SPECIAL, "CLUSTER"	}	,{		STMT_TYPE_SPECIAL, "CHECKPOINT"	}	,{		0, NULL	}};RETCODE		SQL_APIPGAPI_AllocStmt(HDBC hdbc,				HSTMT FAR * phstmt){	CSTR func = "PGAPI_AllocStmt";	ConnectionClass *conn = (ConnectionClass *) hdbc;	StatementClass *stmt;	ARDFields	*ardopts;	BindInfoClass	*bookmark;	mylog("%s: entering...\n", func);	if (!conn)	{		CC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}	stmt = SC_Constructor(conn);	mylog("**** PGAPI_AllocStmt: hdbc = %p, stmt = %p\n", hdbc, stmt);	if (!stmt)	{		CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "No more memory to allocate a further SQL-statement", func);		*phstmt = SQL_NULL_HSTMT;		return SQL_ERROR;	}	if (!CC_add_statement(conn, stmt))	{		CC_set_error(conn, CONN_STMT_ALLOC_ERROR, "Maximum number of statements exceeded.", func);		SC_Destructor(stmt);		*phstmt = SQL_NULL_HSTMT;		return SQL_ERROR;	}	*phstmt = (HSTMT) stmt;	/* Copy default statement options based from Connection options */	stmt->options = stmt->options_orig = conn->stmtOptions;	stmt->ardi.ardopts = conn->ardOptions;	ardopts = SC_get_ARDF(stmt);	bookmark = ARD_AllocBookmark(ardopts);	stmt->stmt_size_limit = CC_get_max_query_len(conn);	/* Save the handle for later */	stmt->phstmt = phstmt;	return SQL_SUCCESS;}RETCODE		SQL_APIPGAPI_FreeStmt(HSTMT hstmt,			   SQLUSMALLINT fOption){	CSTR func = "PGAPI_FreeStmt";	StatementClass *stmt = (StatementClass *) hstmt;	mylog("%s: entering...hstmt=%p, fOption=%hi\n", func, hstmt, fOption);	if (!stmt)	{		SC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}	SC_clear_error(stmt);	if (fOption == SQL_DROP)	{		ConnectionClass *conn = stmt->hdbc;		/* Remove the statement from the connection's statement list */		if (conn)		{			QResultClass	*res;			if (!CC_remove_statement(conn, stmt))			{				SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction.", func);				return SQL_ERROR;		/* stmt may be executing a										 * transaction */			}			/* Free any cursors and discard any result info */			res = SC_get_Result(stmt);			QR_Destructor(res);			SC_init_Result(stmt);		}		if (stmt->execute_delegate)		{			PGAPI_FreeStmt(stmt->execute_delegate, SQL_DROP);			stmt->execute_delegate = NULL;		}		if (stmt->execute_parent)			stmt->execute_parent->execute_delegate = NULL;		/* Destroy the statement and free any results, cursors, etc. */		SC_Destructor(stmt);	}	else if (fOption == SQL_UNBIND)		SC_unbind_cols(stmt);	else if (fOption == SQL_CLOSE)	{		/*		 * this should discard all the results, but leave the statement		 * itself in place (it can be executed again)		 */		stmt->transition_status = 0;		if (stmt->execute_delegate)		{			PGAPI_FreeStmt(stmt->execute_delegate, SQL_DROP);			stmt->execute_delegate = NULL;		}		if (!SC_recycle_statement(stmt))		{			return SQL_ERROR;		}	}	else if (fOption == SQL_RESET_PARAMS)		SC_free_params(stmt, STMT_FREE_PARAMS_ALL);	else	{		SC_set_error(stmt, STMT_OPTION_OUT_OF_RANGE_ERROR, "Invalid option passed to PGAPI_FreeStmt.", func);		return SQL_ERROR;	}	return SQL_SUCCESS;}/* * StatementClass implementation */voidInitializeStatementOptions(StatementOptions *opt){	memset(opt, 0, sizeof(StatementOptions));	opt->maxRows = 0;		/* driver returns all rows */	opt->maxLength = 0;		/* driver returns all data for char/binary */	opt->keyset_size = 0;		/* fully keyset driven is the default */	opt->scroll_concurrency = SQL_CONCUR_READ_ONLY;	opt->cursor_type = SQL_CURSOR_FORWARD_ONLY;	opt->retrieve_data = SQL_RD_ON;	opt->use_bookmarks = SQL_UB_OFF;#if (ODBCVER >= 0x0300)	opt->metadata_id = SQL_FALSE;#endif /* ODBCVER */}static void SC_clear_parse_status(StatementClass *self, ConnectionClass *conn){	self->parse_status = STMT_PARSE_NONE;	if (PG_VERSION_LT(conn, 7.2))	{		SC_set_checked_hasoids(self, TRUE);		self->num_key_fields = PG_NUM_NORMAL_KEYS;	}}static void SC_init_discard_output_params(StatementClass *self){	ConnectionClass	*conn = SC_get_conn(self);	if (!conn)	return;	self->discard_output_params = 0;	if (!conn->connInfo.use_server_side_prepare)		self->discard_output_params = 1;}static void SC_init_parse_method(StatementClass *self){	ConnectionClass	*conn = SC_get_conn(self);	self->parse_method = 0;	if (!conn)	return;	if (self->catalog_result) return;	if (conn->connInfo.drivers.parse)		SC_set_parse_forced(self);	if (self->multi_statement <= 0 && conn->connInfo.disallow_premature)		SC_set_parse_tricky(self);}StatementClass *SC_Constructor(ConnectionClass *conn){	StatementClass *rv;	rv = (StatementClass *) malloc(sizeof(StatementClass));	if (rv)	{		rv->hdbc = conn;		rv->phstmt = NULL;		rv->result = NULL;		rv->curres = NULL;		rv->catalog_result = FALSE;		rv->prepare = NON_PREPARE_STATEMENT;		rv->prepared = NOT_YET_PREPARED;		rv->status = STMT_ALLOCATED;		rv->internal = FALSE;		rv->plan_name = NULL;		rv->transition_status = 0;		rv->multi_statement = -1; /* unknown */		rv->num_params = -1; /* unknown */		rv->__error_message = NULL;		rv->__error_number = 0;		rv->pgerror = NULL;		rv->statement = NULL;		rv->stmt_with_params = NULL;		rv->load_statement = NULL;		rv->execute_statement = NULL;		rv->stmt_size_limit = -1;		rv->statement_type = STMT_TYPE_UNKNOWN;		rv->currTuple = -1;		SC_set_rowset_start(rv, -1, FALSE);		rv->current_col = -1;		rv->bind_row = 0;		rv->last_fetch_count = rv->last_fetch_count_include_ommitted = 0;		rv->save_rowset_size = -1;		rv->data_at_exec = -1;		rv->current_exec_param = -1;		rv->exec_start_row = -1;		rv->exec_end_row = -1;		rv->exec_current_row = -1;		rv->put_data = FALSE;		rv->ref_CC_error = FALSE;		rv->lock_CC_for_rb = 0;		rv->join_info = 0;		SC_init_parse_method(rv);		rv->lobj_fd = -1;		INIT_NAME(rv->cursor_name);		/* Parse Stuff */		rv->ti = NULL;		rv->ntab = 0;		rv->num_key_fields = -1; /* unknown */		SC_clear_parse_status(rv, conn);		rv->proc_return = -1;		SC_init_discard_output_params(rv);		rv->cancel_info = 0;		/* Clear Statement Options -- defaults will be set in AllocStmt */		memset(&rv->options, 0, sizeof(StatementOptions));		InitializeEmbeddedDescriptor((DescriptorClass *)&(rv->ardi),				rv, SQL_ATTR_APP_ROW_DESC);		InitializeEmbeddedDescriptor((DescriptorClass *)&(rv->apdi),				rv, SQL_ATTR_APP_PARAM_DESC);		InitializeEmbeddedDescriptor((DescriptorClass *)&(rv->irdi),				rv, SQL_ATTR_IMP_ROW_DESC);		InitializeEmbeddedDescriptor((DescriptorClass *)&(rv->ipdi),				rv, SQL_ATTR_IMP_PARAM_DESC);		rv->pre_executing = FALSE;		rv->inaccurate_result = FALSE;		rv->miscinfo = 0;		rv->rbonerr = 0;		rv->updatable = FALSE;		rv->diag_row_count = 0;		rv->stmt_time = 0;		rv->execute_delegate = NULL;		rv->execute_parent = NULL;		rv->allocated_callbacks = 0;		rv->num_callbacks = 0;		rv->callbacks = NULL;		GetDataInfoInitialize(SC_get_GDTI(rv));		PutDataInfoInitialize(SC_get_PDTI(rv));		INIT_STMT_CS(rv);	}	return rv;}charSC_Destructor(StatementClass *self){	CSTR func	= "SC_Destrcutor";	QResultClass	*res = SC_get_Result(self);	if (!self)	return FALSE;	mylog("SC_Destructor: self=%p, self->result=%p, self->hdbc=%p\n", self, res, self->hdbc);	SC_clear_error(self);	if (STMT_EXECUTING == self->status)	{		SC_set_error(self, STMT_SEQUENCE_ERROR, "Statement is currently executing a transaction.", func);		return FALSE;	}	if (res)	{		if (!self->hdbc)			res->conn = NULL;	/* prevent any dbase activity */		QR_Destructor(res);	}	SC_initialize_stmts(self, TRUE);        /* Free the parsed table information */	SC_initialize_cols_info(self, FALSE, TRUE);	NULL_THE_NAME(self->cursor_name);	/* Free the parsed field information */	DC_Destructor((DescriptorClass *) SC_get_ARDi(self));	DC_Destructor((DescriptorClass *) SC_get_APDi(self));	DC_Destructor((DescriptorClass *) SC_get_IRDi(self));	DC_Destructor((DescriptorClass *) SC_get_IPDi(self));	GDATA_unbind_cols(SC_get_GDTI(self), TRUE);	PDATA_free_params(SC_get_PDTI(self), STMT_FREE_PARAMS_ALL);		if (self->__error_message)		free(self->__error_message);	if (self->pgerror)		ER_Destructor(self->pgerror);	cancelNeedDataState(self);	if (self->callbacks)		free(self->callbacks);	DELETE_STMT_CS(self);	free(self);	mylog("SC_Destructor: EXIT\n");	return TRUE;}/* *	Free parameters and free the memory from the *	data-at-execution parameters that was allocated in SQLPutData. */voidSC_free_params(StatementClass *self, char option){	if (option != STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY)	{		APD_free_params(SC_get_APDF(self), option);		IPD_free_params(SC_get_IPDF(self), option);	}	PDATA_free_params(SC_get_PDTI(self), option);	self->data_at_exec = -1;	self->current_exec_param = -1;	self->put_data = FALSE;

⌨️ 快捷键说明

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