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

📄 qresult.c

📁 postgresql-odbc,跨平台应用
💻 C
📖 第 1 页 / 共 3 页
字号:
/*--------- * Module:			qresult.c * * Description:		This module contains functions related to *			managing result information (i.e, fetching rows *			from the backend, managing the tuple cache, etc.) *			and retrieving it.	Depending on the situation, a *			QResultClass will hold either data from the backend *			or a manually built result. * * Classes:		QResultClass (Functions prefix: "QR_") * * API functions:	none * * Comments:		See "notice.txt" for copyright and license information. *--------- */#include "qresult.h"#include "statement.h"#include "misc.h"#include <stdio.h>#include <string.h>#include <limits.h>static char QR_read_a_tuple_from_db(QResultClass *, char);/* *	Used for building a Manual Result only *	All info functions call this function to create the manual result set. */voidQR_set_num_fields(QResultClass *self, int new_num_fields){	BOOL	allocrelatt = FALSE;	if (!self)	return;	mylog("in QR_set_num_fields\n");	CI_set_num_fields(self->fields, new_num_fields, allocrelatt);	mylog("exit QR_set_num_fields\n");}voidQR_set_position(QResultClass *self, SQLLEN pos){	self->tupleField = self->backend_tuples + ((QR_get_rowstart_in_cache(self) + pos) * self->num_fields);}voidQR_set_cache_size(QResultClass *self, SQLLEN cache_size){	self->cache_size = cache_size;}voidQR_set_rowset_size(QResultClass *self, Int4 rowset_size){	self->rowset_size_include_ommitted = rowset_size;}voidQR_set_cursor(QResultClass *self, const char *name){	ConnectionClass	*conn = QR_get_conn(self);	if (self->cursor_name)	{		free(self->cursor_name);		if (conn)		{			CONNLOCK_ACQUIRE(conn);			conn->ncursors--;			CONNLOCK_RELEASE(conn);		}		self->cursTuple = -1;		self->pstatus = 0;	}	if (name)	{		self->cursor_name = strdup(name);		if (conn)		{			CONNLOCK_ACQUIRE(conn);			conn->ncursors++;			CONNLOCK_RELEASE(conn);		}	}	else	{		self->cursor_name = NULL;		QR_set_no_cursor(self);	}}voidQR_set_num_cached_rows(QResultClass *self, SQLLEN num_rows){	self->num_cached_rows = num_rows;	if (QR_synchronize_keys(self))		self->num_cached_keys = self->num_cached_rows;}voidQR_set_rowstart_in_cache(QResultClass *self, SQLLEN start){	if (QR_synchronize_keys(self))		self->key_base = start;	self->base = start;}voidQR_inc_rowstart_in_cache(QResultClass *self, SQLLEN base_inc){	if (!QR_has_valid_base(self))		mylog("QR_inc_rowstart_in_cache called while the cache is not ready\n");	self->base += base_inc;	if (QR_synchronize_keys(self))		self->key_base = self->base;}/* * CLASS QResult */QResultClass *QR_Constructor(){	QResultClass *rv;	mylog("in QR_Constructor\n");	rv = (QResultClass *) malloc(sizeof(QResultClass));	if (rv != NULL)	{		rv->rstatus = PORES_EMPTY_QUERY;		rv->pstatus = 0;		/* construct the column info */		if (!(rv->fields = CI_Constructor()))		{			free(rv);			return NULL;		}		rv->backend_tuples = NULL;		rv->sqlstate[0] = '\0';		rv->message = NULL;		rv->command = NULL;		rv->notice = NULL;		rv->conn = NULL;		rv->next = NULL;		rv->pstatus = 0;		rv->count_backend_allocated = 0;		rv->count_keyset_allocated = 0;		rv->num_total_read = 0;		rv->num_cached_rows = 0;		rv->num_cached_keys = 0;		rv->fetch_number = 0;		QR_set_rowstart_in_cache(rv, -1);		rv->key_base = -1;		rv->recent_processed_row_count = -1;		rv->cursTuple = -1;		rv->move_offset = 0;		rv->num_fields = 0;		rv->num_key_fields = PG_NUM_NORMAL_KEYS; /* CTID + OID */		rv->tupleField = NULL;		rv->cursor_name = NULL;		rv->aborted = FALSE;		rv->cache_size = 0;		rv->rowset_size_include_ommitted = 1;		rv->flags = 0;		rv->move_direction = 0;		rv->keyset = NULL;		rv->reload_count = 0;		rv->rb_alloc = 0;		rv->rb_count = 0;		rv->rollback = NULL;		rv->ad_alloc = 0;		rv->ad_count = 0;		rv->added_keyset = NULL;		rv->added_tuples = NULL;		rv->up_alloc = 0;		rv->up_count = 0;		rv->updated = NULL;		rv->updated_keyset = NULL;		rv->updated_tuples = NULL;		rv->dl_alloc = 0;		rv->dl_count = 0;		rv->deleted = NULL;		rv->deleted_keyset = NULL;	}	mylog("exit QR_Constructor\n");	return rv;}voidQR_close_result(QResultClass *self, BOOL destroy){	ConnectionClass	*conn;	if (!self)	return;	mylog("QResult: in QR_close_result\n");	/*	 * If conn is defined, then we may have used "backend_tuples", so in	 * case we need to, free it up.  Also, close the cursor.	 */	if ((conn = QR_get_conn(self)) && conn->sock)	{		if (CC_is_in_trans(conn) ||		    QR_is_withhold(self))		{			if (!QR_close(self))	/* close the cursor if there is one */			{			}		}	}	QR_free_memory(self);		/* safe to call anyway */	/* Should have been freed in the close() but just in case... */	QR_set_cursor(self, NULL);	/* Free up column info */	if (destroy && self->fields)	{		CI_Destructor(self->fields);		self->fields = NULL;	}	/* Free command info (this is from strdup()) */	if (self->command)	{		free(self->command);		self->command = NULL;	}	/* Free message info (this is from strdup()) */	if (self->message)	{		free(self->message);		self->message = NULL;	}	/* Free notice info (this is from strdup()) */	if (self->notice)	{		free(self->notice);		self->notice = NULL;	}	/* Destruct the result object in the chain */	QR_Destructor(self->next);	self->next = NULL;	mylog("QResult: exit close_result\n");	if (destroy)	{		free(self);	}}voidQR_Destructor(QResultClass *self){	mylog("QResult: enter DESTRUCTOR\n");	if (!self)	return;	QR_close_result(self, TRUE);	mylog("QResult: exit DESTRUCTOR\n");}voidQR_set_command(QResultClass *self, const char *msg){	if (self->command)		free(self->command);	self->command = msg ? strdup(msg) : NULL;}voidQR_set_message(QResultClass *self, const char *msg){	if (self->message)		free(self->message);	self->message = msg ? strdup(msg) : NULL;}voidQR_add_message(QResultClass *self, const char *msg){	char	*message = self->message;	size_t	alsize, pos;	if (!msg || !msg[0])		return;	if (message)	{		pos = strlen(message) + 1;		alsize = pos + strlen(msg) + 1;	}	else	{		pos = 0;		alsize = strlen(msg) + 1;	}	message = realloc(message, alsize);	if (pos > 0)		message[pos - 1] = ';';	strcpy(message + pos, msg);	self->message = message;}voidQR_set_notice(QResultClass *self, const char *msg){	if (self->notice)		free(self->notice);	self->notice = msg ? strdup(msg) : NULL;}voidQR_add_notice(QResultClass *self, const char *msg){	char	*message = self->notice;	size_t	alsize, pos;	if (!msg || !msg[0])		return;	if (message)	{		pos = strlen(message) + 1;		alsize = pos + strlen(msg) + 1;	}	else	{		pos = 0;		alsize = strlen(msg) + 1;	}	message = realloc(message, alsize);	if (pos > 0)		message[pos - 1] = ';';	strcpy(message + pos, msg);	self->notice = message;}TupleField	*QR_AddNew(QResultClass *self){	size_t	alloc;	UInt4	num_fields;	if (!self)	return	NULL;inolog("QR_AddNew %dth row(%d fields) alloc=%d\n", self->num_cached_rows, QR_NumResultCols(self), self->count_backend_allocated);	if (num_fields = QR_NumResultCols(self), !num_fields)	return	NULL;	if (self->num_fields <= 0)	{		self->num_fields = num_fields;		QR_set_reached_eof(self);	}	alloc = self->count_backend_allocated;	if (!self->backend_tuples)	{		self->num_cached_rows = 0;		alloc = TUPLE_MALLOC_INC;		self->backend_tuples = malloc(alloc * sizeof(TupleField) * num_fields);	}	else if (self->num_cached_rows >= self->count_backend_allocated)	{		alloc = self->count_backend_allocated * 2;		QR_REALLOC_return_with_error(self->backend_tuples, TupleField, alloc * sizeof(TupleField) * num_fields, self, "Out of memory in QR_AddNew.", NULL);	}	self->count_backend_allocated = alloc;	if (self->backend_tuples)	{		memset(self->backend_tuples + num_fields * self->num_cached_rows, 0, num_fields * sizeof(TupleField));		self->num_cached_rows++;		self->ad_count++;	}	return self->backend_tuples + num_fields * (self->num_cached_rows - 1);}voidQR_free_memory(QResultClass *self){	SQLLEN		num_backend_rows = self->num_cached_rows;	int		num_fields = self->num_fields;	mylog("QResult: free memory in, fcount=%d\n", num_backend_rows);	if (self->backend_tuples)	{		ClearCachedRows(self->backend_tuples, num_fields, num_backend_rows);		free(self->backend_tuples);		self->count_backend_allocated = 0;		self->backend_tuples = NULL;	}	if (self->keyset)	{		ConnectionClass	*conn = QR_get_conn(self);		free(self->keyset);		self->keyset = NULL;		self->count_keyset_allocated = 0;		if (self->reload_count > 0 && conn && conn->sock)		{			char	plannm[32];			sprintf(plannm, "_KEYSET_%p", self);			if (CC_is_in_error_trans(conn))			{				CC_mark_a_object_to_discard(conn, 's',plannm);			}			else			{				QResultClass	*res;				char		cmd[64];				sprintf(cmd, "DEALLOCATE \"%s\"", plannm);				res = CC_send_query(conn, cmd, NULL, IGNORE_ABORT_ON_CONN | ROLLBACK_ON_ERROR, NULL);				QR_Destructor(res);			}		}		self->reload_count = 0;	}	if (self->rollback)	{		free(self->rollback);		self->rb_alloc = 0;		self->rb_count = 0;		self->rollback = NULL;	}	if (self->deleted)	{		free(self->deleted);		self->deleted = NULL;	}	if (self->deleted_keyset)	{		free(self->deleted_keyset);		self->deleted_keyset = NULL;	}	self->dl_alloc = 0;	self->dl_count = 0;	/* clear added info */	if (self->added_keyset)	{		free(self->added_keyset);		self->added_keyset = NULL;	}	if (self->added_tuples)	{		ClearCachedRows(self->added_tuples, num_fields, self->ad_count);		free(self->added_tuples);		self->added_tuples = NULL;	}	self->ad_alloc = 0;	self->ad_count = 0;	/* clear updated info */	if (self->updated)	{		free(self->updated);		self->updated = NULL;	}	if (self->updated_keyset)	{		free(self->updated_keyset);		self->updated_keyset = NULL;	}	if (self->updated_tuples)	{		ClearCachedRows(self->updated_tuples, num_fields, self->up_count);		free(self->updated_tuples);		self->updated_tuples = NULL;	}	self->up_alloc = 0;	self->up_count = 0;	self->num_total_read = 0;	self->num_cached_rows = 0;	self->num_cached_keys = 0;	self->cursTuple = -1;	self->pstatus = 0;	mylog("QResult: free memory out\n");}/*	This function is called by send_query() */charQR_fetch_tuples(QResultClass *self, ConnectionClass *conn, const char *cursor){	CSTR		func = "QR_fetch_tuples";	SQLLEN			tuple_size;	/*	 * If called from send_query the first time (conn != NULL), then set	 * the inTuples state, and read the tuples.  If conn is NULL, it	 * implies that we are being called from next_tuple(), like to get

⌨️ 快捷键说明

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