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

📄 qresult.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 (see "qresult.h" to *                  see which functions/macros are for manual or backend results. *                  For manually built results, the QResultClass simply points to  *                  TupleList and ColumnInfo structures, which actually hold the data. * * Classes:         QResultClass (Functions prefix: "QR_") * * API functions:   none * * Comments:        See "notice.txt" for copyright and license information. * */#include "qresult.h"#include "misc.h"#include <stdio.h>#include <string.h>#ifndef TRUE#define TRUE	(BOOL)1#endif#ifndef FALSE#define FALSE	(BOOL)0#endifextern GLOBAL_VALUES globals;/*  Used for building a Manual Result only *//*	All info functions call this function to create the manual result set. */void QR_set_num_fields(QResultClass *self, int new_num_fields){	mylog("in QR_set_num_fields\n");    CI_set_num_fields(self->fields, new_num_fields);    if(self->manual_tuples)         TL_Destructor(self->manual_tuples);    self->manual_tuples = TL_Constructor(new_num_fields);	mylog("exit QR_set_num_fields\n");}void QR_set_position(QResultClass *self, int pos){	self->tupleField = self->backend_tuples + ((self->base + pos) * self->num_fields);}voidQR_set_cache_size(QResultClass *self, int cache_size){	self->cache_size = cache_size;}void QR_set_rowset_size(QResultClass *self, int rowset_size){	self->rowset_size = rowset_size;}voidQR_inc_base(QResultClass *self, int base_inc){	self->base += base_inc;}/************************************//* CLASS QResult                    *//************************************/QResultClass *QR_Constructor(void){QResultClass *rv;	mylog("in QR_Constructor\n");	rv = (QResultClass *) malloc(sizeof(QResultClass));	if (rv != NULL) {		rv->status = PGRES_EMPTY_QUERY;		/* construct the column info */		if ( ! (rv->fields = CI_Constructor())) {			free(rv);			return NULL;		}		rv->manual_tuples = NULL;			rv->backend_tuples = NULL;			rv->message = NULL;		rv->command = NULL;		rv->notice = NULL;		rv->conn = NULL;		rv->inTuples = FALSE;		rv->fcount = 0;		rv->fetch_count = 0;		rv->base = 0;		rv->currTuple = -1;		rv->num_fields = 0;		rv->tupleField = NULL;		rv->cursor = NULL;		rv->cache_size = globals.fetch_max;		rv->rowset_size = 1;	}	mylog("exit QR_Constructor\n");	return rv;}voidQR_Destructor(QResultClass *self){	mylog("QResult: in DESTRUCTOR\n");	/* manual result set tuples */	if (self->manual_tuples)		TL_Destructor(self->manual_tuples);	//	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 (self->conn && self->conn->sock && CC_is_in_trans(self->conn))		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...	if (self->cursor)		free(self->cursor);	/*	Free up column info */	if (self->fields)		CI_Destructor(self->fields);	/*	Free command info (this is from strdup()) */	if (self->command)		free(self->command);	/*	Free notice info (this is from strdup()) */	if (self->notice)		free(self->notice);	free(self);	mylog("QResult: exit DESTRUCTOR\n");}voidQR_set_command(QResultClass *self, char *msg){	if (self->command)		free(self->command);	self->command = msg ? strdup(msg) : NULL;}void QR_set_notice(QResultClass *self, char *msg){	if (self->notice)		free(self->notice);	self->notice = msg ? strdup(msg) : NULL;}void QR_free_memory(QResultClass *self){register int lf, row;register TupleField *tuple = self->backend_tuples;int fcount = self->fcount;int num_fields = self->num_fields;	mylog("QResult: free memory in, fcount=%d\n", fcount);	if ( self->backend_tuples) {		for (row = 0; row < fcount; row++) {			mylog("row = %d, num_fields = %d\n", row, num_fields);			for (lf=0; lf < num_fields; lf++) {				if (tuple[lf].value != NULL) {					mylog("free [lf=%d] %u\n", lf, tuple[lf].value);					free(tuple[lf].value);				}			}			tuple += num_fields;  // next row		}		free(self->backend_tuples);		self->backend_tuples = NULL;	}	self->fcount = 0;	mylog("QResult: free memory out\n");}//	This function is called by send_query()charQR_fetch_tuples(QResultClass *self, ConnectionClass *conn, char *cursor){int 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 more rows so don't call next_tuple again!	if (conn != NULL) {		self->conn = conn;		mylog("QR_fetch_tuples: cursor = '%s', self->cursor=%u\n",  (cursor==NULL)?"":cursor, self->cursor);		if (self->cursor)			free(self->cursor);		if ( globals.use_declarefetch) {			if (! cursor || cursor[0] == '\0') {				self->status = PGRES_INTERNAL_ERROR;				QR_set_message(self, "Internal Error -- no cursor for fetch");				return FALSE;			}			self->cursor = strdup(cursor);		} 		//	Read the field attributes.		//	$$$$ Should do some error control HERE! $$$$		if ( CI_read_fields(self->fields, self->conn)) {			self->status = PGRES_FIELDS_OK;			self->num_fields = CI_get_num_fields(self->fields);		}		else {			self->status = PGRES_BAD_RESPONSE;			QR_set_message(self, "Error reading field information");			return FALSE;		}		mylog("QR_fetch_tuples: past CI_read_fields: num_fields = %d\n", self->num_fields);		if (globals.use_declarefetch) 			tuple_size = self->cache_size;		else			tuple_size = TUPLE_MALLOC_INC;		/* allocate memory for the tuple cache */		mylog("MALLOC: tuple_size = %d, size = %d\n", tuple_size, self->num_fields * sizeof(TupleField) * tuple_size);		self->backend_tuples = (TupleField *) malloc(self->num_fields * sizeof(TupleField) * tuple_size);		if ( ! self->backend_tuples) {			self->status = PGRES_FATAL_ERROR; 			QR_set_message(self, "Could not get memory for tuple cache.");			return FALSE;		}		self->inTuples = TRUE;		/*  Force a read to occur in next_tuple */		self->fcount = tuple_size+1;		self->fetch_count = tuple_size+1;		self->base = 0;		return QR_next_tuple(self);	}	else {		//	Always have to read the field attributes.		//	But we dont have to reallocate memory for them!		if ( ! CI_read_fields(NULL, self->conn)) {			self->status = PGRES_BAD_RESPONSE;			QR_set_message(self, "Error reading field information");			return FALSE;		}		return TRUE;	}}//	Close the cursor and end the transaction (if no cursors left)//	We only close cursor/end the transaction if a cursor was used.intQR_close(QResultClass *self){QResultClass *res;	if (globals.use_declarefetch && self->conn && self->cursor) {		char buf[64];		sprintf(buf, "close %s", self->cursor);		mylog("QResult: closing cursor: '%s'\n", buf);		res = CC_send_query(self->conn, buf, NULL);		self->inTuples = FALSE;		self->currTuple = -1;		free(self->cursor);		self->cursor = NULL;		if (res == NULL) {			self->status = PGRES_FATAL_ERROR;			QR_set_message(self, "Error closing cursor.");			return FALSE;

⌨️ 快捷键说明

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