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

📄 statement.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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. * */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "statement.h"#include "bind.h"#include "connection.h"#include "qresult.h"#include "convert.h"#include "environ.h"#include <stdio.h>#include <string.h>#ifndef WIN32#include "iodbc.h"#include "isql.h"#else#include <windows.h>#include <sql.h>#endifextern GLOBAL_VALUES globals;#ifndef WIN32#ifndef HAVE_STRICMP#define stricmp(s1,s2) 		strcasecmp(s1,s2)#define strnicmp(s1,s2,n)	strncasecmp(s1,s2,n)#endif#endif/*	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_CREATE, "CREATE" },	{ STMT_TYPE_ALTER,  "ALTER"  },	{ STMT_TYPE_DROP,   "DROP"   },	{ STMT_TYPE_GRANT,  "GRANT"  },	{ STMT_TYPE_REVOKE, "REVOKE" },	{      0,            NULL    }};RETCODE SQL_API SQLAllocStmt(HDBC      hdbc,                             HSTMT FAR *phstmt){static char *func="SQLAllocStmt";ConnectionClass *conn = (ConnectionClass *) hdbc;StatementClass *stmt;	mylog("%s: entering...\n", func);	if( ! conn) {		CC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}	stmt = SC_Constructor();	mylog("**** SQLAllocStmt: hdbc = %u, stmt = %u\n", hdbc, stmt);	if ( ! stmt) {		conn->errornumber = CONN_STMT_ALLOC_ERROR;		conn->errormsg = "No more memory to allocate a further SQL-statement";		*phstmt = SQL_NULL_HSTMT;		CC_log_error(func, "", conn);		return SQL_ERROR;	}    if ( ! CC_add_statement(conn, stmt)) {        conn->errormsg = "Maximum number of connections exceeded.";        conn->errornumber = CONN_STMT_ALLOC_ERROR;		CC_log_error(func, "", conn);        SC_Destructor(stmt);		*phstmt = SQL_NULL_HSTMT;        return SQL_ERROR;    }	*phstmt = (HSTMT) stmt;	/*	Copy default statement options based from Connection options	*/	stmt->options = conn->stmtOptions;	/*	Save the handle for later */	stmt->phstmt = phstmt;    return SQL_SUCCESS;}RETCODE SQL_API SQLFreeStmt(HSTMT     hstmt,                            UWORD     fOption){static char *func="SQLFreeStmt";StatementClass *stmt = (StatementClass *) hstmt;	mylog("%s: entering...hstmt=%u, fOption=%d\n", func, hstmt, fOption);	if ( ! stmt) {		SC_log_error(func, "", NULL);		return SQL_INVALID_HANDLE;	}	if (fOption == SQL_DROP) {		ConnectionClass *conn = stmt->hdbc;		/* Remove the statement from the connection's statement list */		if ( conn) {			if ( ! CC_remove_statement(conn, stmt)) {				stmt->errornumber = STMT_SEQUENCE_ERROR;				stmt->errormsg = "Statement is currently executing a transaction.";				SC_log_error(func, "", stmt);				return SQL_ERROR;  /* stmt may be executing a transaction */			}			/*	Free any cursors and discard any result info */			if (stmt->result) {				QR_Destructor(stmt->result);				stmt->result = 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) */        if (!SC_recycle_statement(stmt)) {			//	errormsg passed in above			SC_log_error(func, "", stmt);            return SQL_ERROR;		}    } else if(fOption == SQL_RESET_PARAMS) {		SC_free_params(stmt, STMT_FREE_PARAMS_ALL);    } else {        stmt->errormsg = "Invalid option passed to SQLFreeStmt.";        stmt->errornumber = STMT_OPTION_OUT_OF_RANGE_ERROR;		SC_log_error(func, "", stmt);        return SQL_ERROR;    }        return SQL_SUCCESS;}/********************************************************************** * StatementClass implementation */voidInitializeStatementOptions(StatementOptions *opt){	opt->maxRows = 0;			// driver returns all rows	opt->maxLength = 0;			// driver returns all data for char/binary	opt->rowset_size = 1;	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->bind_size = 0;			/* default is to bind by column */	opt->retrieve_data = SQL_RD_ON;	opt->use_bookmarks = SQL_UB_OFF;}StatementClass *SC_Constructor(void){StatementClass *rv;	rv = (StatementClass *) malloc(sizeof(StatementClass));	if (rv) {		rv->hdbc = NULL;       /* no connection associated yet */		rv->phstmt = NULL;		rv->result = NULL;		rv->manual_result = FALSE;		rv->prepare = FALSE;		rv->status = STMT_ALLOCATED;		rv->internal = FALSE;		rv->errormsg = NULL;		rv->errornumber = 0;		rv->errormsg_created = FALSE;		rv->statement = NULL;		rv->stmt_with_params[0] = '\0';		rv->statement_type = STMT_TYPE_UNKNOWN;		rv->bindings = NULL;		rv->bindings_allocated = 0;		rv->bookmark.buffer = NULL;		rv->bookmark.used = NULL;		rv->parameters_allocated = 0;		rv->parameters = 0;		rv->currTuple = -1;		rv->rowset_start = -1;		rv->current_col = -1;		rv->bind_row = 0;		rv->last_fetch_count = 0;		rv->save_rowset_size = -1;		rv->data_at_exec = -1;		rv->current_exec_param = -1;		rv->put_data = FALSE;		rv->lobj_fd = -1;		rv->cursor_name[0] = '\0';		/*	Parse Stuff */		rv->ti = NULL;		rv->fi = NULL;		rv->ntab = 0;		rv->nfld = 0;		rv->parse_status = STMT_PARSE_NONE;		/*  Clear Statement Options -- defaults will be set in AllocStmt */		memset(&rv->options, 0, sizeof(StatementOptions));	}	return rv;}charSC_Destructor(StatementClass *self){	mylog("SC_Destructor: self=%u, self->result=%u, self->hdbc=%u\n", self, self->result, self->hdbc);	if (STMT_EXECUTING == self->status) {		self->errornumber = STMT_SEQUENCE_ERROR;		self->errormsg = "Statement is currently executing a transaction.";		return FALSE;	}	if (self->result) {		if ( ! self->hdbc)			self->result->conn = NULL;  /* prevent any dbase activity */		QR_Destructor(self->result);	}	if (self->statement)		free(self->statement);	SC_free_params(self, STMT_FREE_PARAMS_ALL);	/* the memory pointed to by the bindings is not deallocated by the driver */	/* by by the application that uses that driver, so we don't have to care  */	/* about that here. */	if (self->bindings)		free(self->bindings);	/*	Free the parsed table information */	if (self->ti) {		int i;		for (i = 0; i < self->ntab; i++) {			free(self->ti[i]);		}		free(self->ti);	}	/*	Free the parsed field information */	if (self->fi) {		int i;		for (i = 0; i < self->nfld; i++) {			free(self->fi[i]);		}		free(self->fi);	}	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){int i;	mylog("SC_free_params:  ENTER, self=%d\n", self);	if( ! self->parameters)		return;	for (i = 0; i < self->parameters_allocated; i++) {		if (self->parameters[i].data_at_exec == TRUE) {			if (self->parameters[i].EXEC_used) {				free(self->parameters[i].EXEC_used);				self->parameters[i].EXEC_used = NULL;			}			if (self->parameters[i].EXEC_buffer) {				free(self->parameters[i].EXEC_buffer);				self->parameters[i].EXEC_buffer = NULL;			}		}	}	self->data_at_exec = -1;	self->current_exec_param = -1;	self->put_data = FALSE;	if (option == STMT_FREE_PARAMS_ALL) {		free(self->parameters);		self->parameters = NULL;		self->parameters_allocated = 0;	}	mylog("SC_free_params:  EXIT\n");}int statement_type(char *statement){int i;	for (i = 0; Statement_Type[i].s; i++)		if ( ! strnicmp(statement, Statement_Type[i].s, strlen(Statement_Type[i].s)))			return Statement_Type[i].type;	return STMT_TYPE_OTHER;}/*	Called from SQLPrepare if STMT_PREMATURE, or	from SQLExecute if STMT_FINISHED, or	from SQLFreeStmt(SQL_CLOSE) */char SC_recycle_statement(StatementClass *self){ConnectionClass *conn;mylog("recycle statement: self= %u\n", self);	/*	This would not happen */    	if (self->status == STMT_EXECUTING) {		self->errornumber = STMT_SEQUENCE_ERROR;		self->errormsg = "Statement is currently executing a transaction.";		return FALSE;	}	self->errormsg = NULL;	self->errornumber = 0;	self->errormsg_created = FALSE;	switch (self->status) {	case STMT_ALLOCATED:		/* this statement does not need to be recycled */		return TRUE;	case STMT_READY:		break;	case STMT_PREMATURE:		/*	Premature execution of the statement might have caused the start of a transaction.			If so, we have to rollback that transaction.		*/		conn = SC_get_conn(self);		if ( ! CC_is_in_autocommit(conn) && CC_is_in_trans(conn)) {             			CC_send_query(conn, "ABORT", NULL);			CC_set_no_trans(conn);		}		break;	case STMT_FINISHED:		break;	default:		self->errormsg = "An internal error occured while recycling statements";		self->errornumber = STMT_INTERNAL_ERROR;		return FALSE;	}	/*	Free the parsed table information */	if (self->ti) {		int i;		for (i = 0; i < self->ntab; i++) {			free(self->ti[i]);		}		free(self->ti);		self->ti = NULL;		self->ntab = 0;	}	/*	Free the parsed field information */	if (self->fi) {		int i;		for (i = 0; i < self->nfld; i++) {			free(self->fi[i]);		}		free(self->fi);		self->fi = NULL;		self->nfld = 0;	}	self->parse_status = STMT_PARSE_NONE;	/*	Free any cursors */	if (self->result) {		QR_Destructor(self->result);		self->result = NULL;	}	/****************************************************************/	/*	Reset only parameters that have anything to do with results */	/****************************************************************/	self->status = STMT_READY;	self->manual_result = FALSE;	// very important	self->currTuple = -1;	self->rowset_start = -1;	self->current_col = -1;	self->bind_row = 0;	self->last_fetch_count = 0;	self->errormsg = NULL;	self->errornumber = 0;	self->errormsg_created = FALSE;	self->lobj_fd = -1;	//	Free any data at exec params before the statement is executed	//	again.  If not, then there will be a memory leak when	//	the next SQLParamData/SQLPutData is called.	SC_free_params(self, STMT_FREE_PARAMS_DATA_AT_EXEC_ONLY);	return TRUE;

⌨️ 快捷键说明

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