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

📄 results.c

📁 postgresql-odbc,跨平台应用
💻 C
📖 第 1 页 / 共 5 页
字号:
		/* it's a SOCKET result (backend data) */		if (stmt->currTuple == -1 || !res || !res->tupleField)		{			SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Not positioned on a valid row for GetData.", func);			result = SQL_ERROR;			goto cleanup;		}		if (!get_bookmark)		{			/** value = QR_get_value_backend(res, icol); maybe thiw doesn't work */			SQLLEN	curt = GIdx2CacheIdx(stmt->currTuple, stmt, res);			value = QR_get_value_backend_row(res, curt, icol);		}		mylog("  socket: value = '%s'\n", value ? value : "(null)");	}	if (get_bookmark)	{		BOOL	contents_get = FALSE;		if (rgbValue)		{			if (SQL_C_BOOKMARK == target_type || 4 <= cbValueMax)			{				contents_get = TRUE; 				*((SQLULEN *) rgbValue) = SC_get_bookmark(stmt);			}		}		if (pcbValue)			*pcbValue = sizeof(SQLULEN);		if (contents_get)			result = SQL_SUCCESS;		else		{			SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the GetData.", func);			result = SQL_SUCCESS_WITH_INFO;		}		goto cleanup;	}	field_type = QR_get_field_type(res, icol);	mylog("**** %s: icol = %d, target_type = %d, field_type = %d, value = '%s'\n", func, icol, target_type, field_type, value ? value : "(null)");	SC_set_current_col(stmt, icol);	result = copy_and_convert_field(stmt, field_type, value,				target_type, rgbValue, cbValueMax, pcbValue, pcbValue);	switch (result)	{		case COPY_OK:			result = SQL_SUCCESS;			break;		case COPY_UNSUPPORTED_TYPE:			SC_set_error(stmt, STMT_RESTRICTED_DATA_TYPE_ERROR, "Received an unsupported type from Postgres.", func);			result = SQL_ERROR;			break;		case COPY_UNSUPPORTED_CONVERSION:			SC_set_error(stmt, STMT_RESTRICTED_DATA_TYPE_ERROR, "Couldn't handle the necessary data type conversion.", func);			result = SQL_ERROR;			break;		case COPY_RESULT_TRUNCATED:			SC_set_error(stmt, STMT_TRUNCATED, "The buffer was too small for the GetData.", func);			result = SQL_SUCCESS_WITH_INFO;			break;		case COPY_GENERAL_ERROR:		/* error msg already filled in */			result = SQL_ERROR;			break;		case COPY_NO_DATA_FOUND:			/* SC_log_error(func, "no data found", stmt); */			result = SQL_NO_DATA_FOUND;			break;		default:			SC_set_error(stmt, STMT_INTERNAL_ERROR, "Unrecognized return value from copy_and_convert_field.", func);			result = SQL_ERROR;			break;	}cleanup:#undef	return	if (stmt->internal)		result = DiscardStatementSvp(stmt, result, FALSE);	return result;}/* *		Returns data for bound columns in the current row ("hstmt->iCursor"), *		advances the cursor. */RETCODE		SQL_APIPGAPI_Fetch(			HSTMT hstmt){	CSTR func = "PGAPI_Fetch";	StatementClass *stmt = (StatementClass *) hstmt;	ARDFields	*opts;	QResultClass *res;	BindInfoClass	*bookmark;	RETCODE		retval = SQL_SUCCESS;	mylog("%s: stmt = %p, stmt->result= %p\n", func, stmt, stmt ? SC_get_Curres(stmt) : NULL);	if (!stmt)	{		SC_log_error(func, NULL_STRING, NULL);		return SQL_INVALID_HANDLE;	}	SC_clear_error(stmt);	if (!(res = SC_get_Curres(stmt)))	{		SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in PGAPI_Fetch.", func);		return SQL_ERROR;	}	/* Not allowed to bind a bookmark column when using SQLFetch. */	opts = SC_get_ARDF(stmt);	if ((bookmark = opts->bookmark) && bookmark->buffer)	{		SC_set_error(stmt, STMT_COLNUM_ERROR, "Not allowed to bind a bookmark column when using PGAPI_Fetch", func);		return SQL_ERROR;	}	if (stmt->status == STMT_EXECUTING)	{		SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't fetch while statement is still executing.", func);		return SQL_ERROR;	}	if (stmt->status != STMT_FINISHED)	{		SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Fetch can only be called after the successful execution on a SQL statement", func);		return SQL_ERROR;	}	if (opts->bindings == NULL)	{		if (stmt->statement_type != STMT_TYPE_SELECT)			return SQL_NO_DATA_FOUND;		/* just to avoid a crash if the user insists on calling this */		/* function even if SQL_ExecDirect has reported an Error */		SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Bindings were not allocated properly.", func);		return SQL_ERROR;	}#define	return	DONT_CALL_RETURN_FROM_HERE???	/* StartRollbackState(stmt); */	if (stmt->rowset_start < 0)		SC_set_rowset_start(stmt, 0, TRUE);	QR_set_rowset_size(res, 1);	/* QR_inc_rowstart_in_cache(res, stmt->last_fetch_count_include_ommitted); */	SC_inc_rowset_start(stmt, stmt->last_fetch_count_include_ommitted);	retval = SC_fetch(stmt);#undef	return	if (stmt->internal)		retval = DiscardStatementSvp(stmt, retval, FALSE);	return retval;}static RETCODE SQL_APISC_pos_reload_needed(StatementClass *stmt, SQLULEN req_size, UDWORD flag);SQLLENgetNthValid(const QResultClass *res, SQLLEN sta, UWORD orientation, SQLULEN nth, SQLLEN *nearest){	SQLLEN	i, num_tuples = QR_get_num_total_tuples(res), nearp;	SQLULEN count;	KeySet	*keyset;	if (!QR_once_reached_eof(res))		num_tuples = INT_MAX;	/* Note that the parameter nth is 1-based */inolog("get %dth Valid data from %d to %s [dlt=%d]", nth, sta, orientation == SQL_FETCH_PRIOR ? "backward" : "forward", res->dl_count);	if (0 == res->dl_count)	{		if (SQL_FETCH_PRIOR == orientation)		{				if (sta + 1 >= (SQLLEN) nth)			{				*nearest = sta + 1 - nth;				return nth;			}			*nearest = -1;			return -(SQLLEN)(sta + 1);		}		else		{				nearp = sta - 1 + nth;			if (nearp < num_tuples)			{				*nearest = nearp;				return nth;			}			*nearest = num_tuples;			return -(SQLLEN)(num_tuples - sta);		}	}	count = 0;	if (QR_get_cursor(res))	{		SQLLEN	*deleted = res->deleted;		*nearest = sta - 1 + nth;		if (SQL_FETCH_PRIOR == orientation)		{			for (i = res->dl_count - 1; i >=0 && *nearest <= (SQLLEN) deleted[i]; i--)			{inolog("deleted[%d]=%d\n", i, deleted[i]);				if (sta >= (SQLLEN)deleted[i])					(*nearest)--;			}inolog("nearest=%d\n", *nearest);			if (*nearest < 0)			{				*nearest = -1;				count = sta + 1;			}			else				return nth;		}		else		{			if (!QR_once_reached_eof(res))				num_tuples = INT_MAX;			for (i = 0; i < res->dl_count && *nearest >= (SQLLEN)deleted[i]; i++)			{				if (sta <= (SQLLEN)deleted[i])					(*nearest)++;			}			if (*nearest >= num_tuples)			{				*nearest = num_tuples;				count = *nearest - sta;			}			else				return nth;		}	}	else if (SQL_FETCH_PRIOR == orientation)	{		for (i = sta, keyset = res->keyset + sta;			i >= 0; i--, keyset--)		{			if (0 == (keyset->status & (CURS_SELF_DELETING | CURS_SELF_DELETED | CURS_OTHER_DELETED)))			{				*nearest = i;inolog(" nearest=%d\n", *nearest);				if (++count == nth)					return count;			}		}		*nearest = -1; 	}	else	{		for (i = sta, keyset = res->keyset + sta;			i < num_tuples; i++, keyset++)		{			if (0 == (keyset->status & (CURS_SELF_DELETING | CURS_SELF_DELETED | CURS_OTHER_DELETED)))			{				*nearest = i;inolog(" nearest=%d\n", *nearest);				if (++count == nth)					return count;			}		}		*nearest = num_tuples; 	}inolog(" nearest not found\n");	return -(SQLLEN)count;}static voidmove_cursor_position_if_needed(StatementClass *self, QResultClass *res){	SQLLEN	move_offset;		/*	 * The move direction must be initialized to is_not_moving or	 * is_moving_from_the_last in advance.	 */	if (!QR_get_cursor(res))	{		QR_stop_movement(res); /* for safety */		res->move_offset = 0;		return;	}inolog("BASE=%d numb=%d curr=%d cursT=%d\n", QR_get_rowstart_in_cache(res), res->num_cached_rows, self->currTuple, res->cursTuple);	/* retrieve "move from the last" case first */	if (QR_is_moving_from_the_last(res))	{		mylog("must MOVE from the last\n");		if (QR_once_reached_eof(res) || self->rowset_start <= QR_get_num_total_tuples(res)) /* this shouldn't happen */			mylog("strange situation in move from the last\n");		if (0 == res->move_offset)			res->move_offset = INT_MAX - self->rowset_start;else{inolog("!!move_offset=%d calc=%d\n", res->move_offset, INT_MAX - self->rowset_start);}		return;	}	/* normal case */	res->move_offset = 0;	move_offset = self->currTuple - res->cursTuple;	if (QR_get_rowstart_in_cache(res) >= 0 &&	     QR_get_rowstart_in_cache(res) <= res->num_cached_rows)	{		QR_set_next_in_cache(res, (QR_get_rowstart_in_cache(res) < 0) ? 0 : QR_get_rowstart_in_cache(res));		return;	}	if (0 == move_offset) 		return;	if (move_offset > 0)	{		QR_set_move_forward(res);		res->move_offset = move_offset;	}	else	{		QR_set_move_backward(res);		res->move_offset = -move_offset;	}}/* *	return NO_DATA_FOUND macros *	  save_rowset_start or num_tuples must be defined  */#define	EXTFETCH_RETURN_BOF(stmt, res) \{ \inolog("RETURN_BOF\n"); \	SC_set_rowset_start(stmt, -1, TRUE); \	stmt->currTuple = -1; \	/* move_cursor_position_if_needed(stmt, res); */ \	return SQL_NO_DATA_FOUND; \}#define	EXTFETCH_RETURN_EOF(stmt, res) \{ \inolog("RETURN_EOF\n"); \	SC_set_rowset_start(stmt, num_tuples, TRUE); \	stmt->currTuple = -1; \	/* move_cursor_position_if_needed(stmt, res); */ \	return SQL_NO_DATA_FOUND; \}	/*	This fetchs a block of data (rowset). */RETCODE		SQL_APIPGAPI_ExtendedFetch(					HSTMT hstmt,					SQLUSMALLINT fFetchType,					SQLLEN irow,					SQLULEN FAR * pcrow,					SQLUSMALLINT FAR * rgfRowStatus,					SQLLEN bookmark_offset,					SQLLEN rowsetSize){	CSTR func = "PGAPI_ExtendedFetch";	StatementClass *stmt = (StatementClass *) hstmt;	ARDFields	*opts;	QResultClass *res;	BindInfoClass	*bookmark;	SQLLEN		num_tuples, i, fc_io;	SQLLEN		save_rowset_size, progress_size;	SQLLEN		 save_rowset_start,			rowset_start;	RETCODE		result = SQL_SUCCESS;	char		truncated, error, should_set_rowset_start = FALSE; 	ConnInfo   *ci;	SQLLEN		currp;	UWORD		pstatus;	BOOL		currp_is_valid, reached_eof;	mylog("%s: stmt=%p rowsetSize=%d\n", func, stmt, rowsetSize);	if (!stmt)	{		SC_log_error(func, NULL_STRING, NULL);		return SQL_INVALID_HANDLE;	}	ci = &(SC_get_conn(stmt)->connInfo);	/* if (SC_is_fetchcursor(stmt) && !stmt->manual_result) */	if (SQL_CURSOR_FORWARD_ONLY == stmt->options.cursor_type)	{		if (fFetchType != SQL_FETCH_NEXT)		{			SC_set_error(stmt, STMT_FETCH_OUT_OF_RANGE, "The fetch type for PGAPI_ExtendedFetch isn't allowed with ForwardOnly cursor.", func);			return SQL_ERROR;		}	}	SC_clear_error(stmt);	if (!(res = SC_get_Curres(stmt)))	{		SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Null statement result in PGAPI_ExtendedFetch.", func);		return SQL_ERROR;	}	opts = SC_get_ARDF(stmt);	/*	 * If a bookmark colunmn is bound but bookmark usage is off, then	 * error	 */	if ((bookmark = opts->bookmark) && bookmark->buffer && stmt->options.use_bookmarks == SQL_UB_OFF)	{		SC_set_error(stmt, STMT_COLNUM_ERROR, "Attempt to retrieve bookmark with bookmark usage disabled", func);		return SQL_ERROR;	}	if (stmt->status == STMT_EXECUTING)	{		SC_set_error(stmt, STMT_SEQUENCE_ERROR, "Can't fetch while statement is still executing.", func);		return SQL_ERROR;	}	if (stmt->status != STMT_FINISHED)	{		SC_set_error(stmt, STMT_STATUS_ERROR, "ExtendedFetch can only be called after the successful execution on a SQL statement", func);		return SQL_ERROR;	}	if (opts->bindings == NULL)	{		if (stmt->statement_type != STMT_TYPE_SELECT)			return SQL_NO_DATA_FOUND;		/* just to avoid a crash if the user insists on calling this */		/* function even if SQL_ExecDirect has reported an Error */		SC_set_error(stmt, STMT_INVALID_CURSOR_STATE_ERROR, "Bindings were not allocated properly.", func);		return SQL_ERROR;	}	/* Initialize to no rows fetched */	if (rgfRowStatus)		for (i = 0; i < rowsetSize; i++)			*(rgfRowStatus + i) = SQL_ROW_NOROW;	if (pcrow)		*pcrow = 0;	num_tuples = QR_get_num_total_tuples(res);	reached_eof = QR_once_reached_eof(res) && QR_get_cursor(res);	if (SC_is_fetchcursor(stmt) && !reached_eof)		num_tuples = INT_MAX;inolog("num_tuples=%d\n", num_tuples);	/* Save and discard the saved rowset size */	save_rowset_start = SC_get_rowset_start(stmt);	save_rowset_size = stmt->save_rowset_size;	stmt->save_rowset_size = -1;	rowset_start = SC_get_rowset_start(stmt);	QR_stop_movement(res);	res->move_offset = 0;	switch (fFetchType)	{		case SQL_FETCH_NEXT:			/*			 * From the odbc spec... If positioned before the start of the			 * RESULT SET, then this should be equivalent to			 * SQL_FETCH_FIRST.			 */			progress_size = (save_rowset_size > 0 ? save_rowset_size : rowsetSize);			if (rowset_start < 0)				SC_set_rowset_start(stmt, 0, TRUE);			else if (res->keyset)			{				if (stmt->last_fetch_count <= progress_size)				{					SC_inc_rowset_start(stmt, stmt->last_fetch_count_include_ommitted);					progress_size -= stmt->last_fetch_count;				}				if (progress_size > 0)				{					if (getNthValid(res, SC_get_rowset_start(stmt),						SQL_FETCH_NEXT, progress_size + 1,						&rowset_start) <= 0)					{						EXTFETCH_RETURN_EOF(stmt, res)					}					else						should_set_rowset_start =TRUE;				}			}			else				SC_inc_rowset_start(stmt, progress_size);			mylog("SQL_FETCH_NEXT: num_tuples=%d, currtuple=%d, rowst=%d\n", num_tuples, stmt->currTuple, rowset_start);			break;		case SQL_FETCH_PRIOR:			mylog("SQL_FETCH_PRIOR: num_tuples=%d, currtuple=%d\n", num_tuples, stmt->currTuple);

⌨️ 快捷键说明

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