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

📄 ct.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
				cursor->status.declare = _CS_CURS_TYPE_SENT; /* Cursor is declared */				if (something_to_send == 0) {					cmd->results_state = _CS_RES_END_RESULTS;				}			}			else {				tdsdump_log(TDS_DBG_WARN, "ct_send(): cursor declare failed \n");				return CS_FAIL;			}		}		if (cursor->status.cursor_row == _CS_CURS_TYPE_REQUESTED &&			cursor->status.declare == _CS_CURS_TYPE_SENT) { 			ret = tds_cursor_setrows(tds, cursor, &something_to_send);			if (ret == CS_SUCCEED){				cursor->status.cursor_row = _CS_CURS_TYPE_SENT; /* Cursor rows set */				if (something_to_send == 0) {					cmd->results_state = _CS_RES_END_RESULTS;				}			}			else {				tdsdump_log(TDS_DBG_WARN, "ct_send(): cursor set rows failed\n");				return CS_FAIL;			}		}		if (cursor->status.open == _CS_CURS_TYPE_REQUESTED &&			cursor->status.declare == _CS_CURS_TYPE_SENT) {			ret = tds_cursor_open(tds, cursor, NULL, &something_to_send); 			if (ret == CS_SUCCEED){				cursor->status.open = _CS_CURS_TYPE_SENT;				cmd->results_state = _CS_RES_INIT;			}			else {				tdsdump_log(TDS_DBG_WARN, "ct_send(): cursor open failed\n");				return CS_FAIL;			}		}		if (something_to_send) {			tdsdump_log(TDS_DBG_WARN, "ct_send(): sending cursor commands\n");			tds_flush_packet(tds);			tds_set_state(tds, TDS_PENDING);			something_to_send = 0;			ct_set_command_state(cmd, _CS_COMMAND_SENT);			return CS_SUCCEED;		}		if (cursor->status.close == _CS_CURS_TYPE_REQUESTED){			if (cursor->status.dealloc == TDS_CURSOR_STATE_REQUESTED) {				/* FIXME what happen if tds_cursor_dealloc return TDS_FAIL ?? */				ret = tds_cursor_close(tds, cursor);				tds_release_cursor(tds, cursor);				cmd->cursor = cursor = NULL;			} else {				ret = tds_cursor_close(tds, cursor);				cursor->status.close = _CS_CURS_TYPE_SENT;			}		}		if (cursor && cursor->status.dealloc == _CS_CURS_TYPE_REQUESTED) {			/* FIXME what happen if tds_cursor_dealloc return TDS_FAIL ?? */			ret = tds_cursor_dealloc(tds, cursor);			cmd->cursor = NULL;			tds_free_all_results(tds);		}		ct_set_command_state(cmd, _CS_COMMAND_SENT);		return CS_SUCCEED;	}	if (cmd->command_type == CS_SEND_DATA_CMD) {		tds_flush_packet(tds);		tds_set_state(tds, TDS_PENDING);		ct_set_command_state(cmd, _CS_COMMAND_SENT);	}	return CS_SUCCEED;}CS_RETCODEct_results(CS_COMMAND * cmd, CS_INT * result_type){	TDSSOCKET *tds;	CS_CONTEXT *context;	int tdsret;	CS_INT res_type;	CS_INT done_flags;	tdsdump_log(TDS_DBG_FUNC, "ct_results()\n");	if (cmd->cancel_state == _CS_CANCEL_PENDING) {		_ct_cancel_cleanup(cmd);		return CS_CANCELED;	}	if (!cmd->con || !cmd->con->tds_socket)		return CS_FAIL;	cmd->bind_count = CS_UNUSED;	context = cmd->con->ctx;	tds = cmd->con->tds_socket;	cmd->row_prefetched = 0;	/*	 * depending on the current results state, we may	 * not need to call tds_process_tokens...	 */	switch (cmd->results_state) {	case _CS_RES_CMD_SUCCEED:		*result_type = CS_CMD_SUCCEED;		cmd->results_state = _CS_RES_CMD_DONE;		return CS_SUCCEED;	case _CS_RES_CMD_DONE:		*result_type = CS_CMD_DONE;		cmd->results_state = _CS_RES_INIT;		return CS_SUCCEED;	case _CS_RES_END_RESULTS:		*result_type = CS_CMD_DONE;		cmd->results_state = _CS_RES_INIT;		return CS_END_RESULTS;	case _CS_RES_DESCRIBE_RESULT:		*result_type = CS_DESCRIBE_RESULT;		cmd->results_state = _CS_RES_CMD_DONE;		return CS_SUCCEED;	case _CS_RES_NONE:				/* first time in after ct_send */		cmd->results_state = _CS_RES_INIT;		break;	default:		break;	}	/*	 * see what "result" tokens we have. a "result" in ct-lib terms also	 * includes row data. Some result types always get reported back  to	 * the calling program, others are only reported back if the relevant	 * config flag is set.	 */	for (;;) {		tdsret = tds_process_tokens(tds, &res_type, &done_flags, TDS_TOKEN_RESULTS);		tdsdump_log(TDS_DBG_FUNC, "ct_results() process_result_tokens returned %d (type %d) \n",			    tdsret, res_type);		switch (tdsret) {		case TDS_SUCCEED:			cmd->curr_result_type = res_type;			switch (res_type) {			case CS_COMPUTEFMT_RESULT:			case CS_ROWFMT_RESULT:				/*				 * set results state to indicate that we				 * have a result set (empty for the moment)				 * If the CS_EXPOSE_FMTS  property has been				 * set in ct_config(), we need to return an				 * appropraite format result, otherwise just				 * carry on and get the next token.....				 */				cmd->results_state = _CS_RES_RESULTSET_EMPTY;				if (context->config.cs_expose_formats) {					*result_type = res_type;					return CS_SUCCEED;				}				break;			case CS_ROW_RESULT:				/*				 * we've hit a data row. pass back that fact				 * to the calling program. set results state				 * to show that the result set has rows...				 */				cmd->results_state = _CS_RES_RESULTSET_ROWS;				if (cmd->command_type == CS_CUR_CMD) {					*result_type = CS_CURSOR_RESULT;				} else {					*result_type = CS_ROW_RESULT;				}				return CS_SUCCEED;				break;			case CS_COMPUTE_RESULT:				/*				 * we've hit a compute data row. We have to get hold of this				 * data now, as it's necessary  to tie this data back to its				 * result format...the user may call ct_res_info() & friends				 * after getting back a compute "result".				 *				 * but first, if we've hit this compute row without having				 * hit a data row first, we need to return a  CS_ROW_RESULT				 * before letting them have the compute row...				 */				if (cmd->results_state == _CS_RES_RESULTSET_EMPTY) {					*result_type = CS_ROW_RESULT;					tds->current_results = tds->res_info;					cmd->results_state = _CS_RES_RESULTSET_ROWS;					return CS_SUCCEED;				}				tdsret = tds_process_tokens(tds, &res_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE);				/* set results state to show that the result set has rows... */				cmd->results_state = _CS_RES_RESULTSET_ROWS;				*result_type = res_type;				if (tdsret == TDS_SUCCEED && (res_type == TDS_ROW_RESULT || res_type == TDS_COMPUTE_RESULT)) {					if (res_type == TDS_COMPUTE_RESULT) {						cmd->row_prefetched = 1;						return CS_SUCCEED;					} else {						/* this couldn't really happen, but... */						return CS_FAIL;					}				} else					return CS_FAIL;				break;			case TDS_DONE_RESULT:				/*				 * A done token signifies the end of a logical				 * command. There are three possibilities...				 * 1. Simple command with no result set, i.e.				 *    update, delete, insert				 * 2. Command with result set but no rows				 * 3. Command with result set and rows				 * in these cases we need to:				 * 1. return CS_CMD_FAIL/SUCCED depending on				 *    the status returned in done_flags				 * 2. "manufacture" a CS_ROW_RESULT return,				 *    and set the results state to DONE				 * 3. return with CS_CMD_DONE and reset the				 *    results_state				 */				tdsdump_log(TDS_DBG_FUNC, "ct_results() results state = %d\n",cmd->results_state);				tdsdump_log(TDS_DBG_FUNC, "ct_results() command type  = %d\n",cmd->command_type);				tdsdump_log(TDS_DBG_FUNC, "ct_results() dynamic cmd   = %d\n",cmd->dynamic_cmd);				if ((cmd->command_type == CS_DYNAMIC_CMD) &&					(cmd->dynamic_cmd == CS_PREPARE || cmd->dynamic_cmd == CS_DEALLOC)) {					*result_type = CS_CMD_SUCCEED;					cmd->results_state = _CS_RES_CMD_DONE;					return CS_SUCCEED;				}				switch (cmd->results_state) {				case _CS_RES_INIT:				case _CS_RES_STATUS:					if (done_flags & TDS_DONE_ERROR)						*result_type = CS_CMD_FAIL;					else						*result_type = CS_CMD_SUCCEED;					cmd->results_state = _CS_RES_CMD_DONE;					break;				case _CS_RES_RESULTSET_EMPTY:					if (cmd->command_type == CS_CUR_CMD) {						*result_type = CS_CURSOR_RESULT;						cmd->results_state = _CS_RES_RESULTSET_ROWS;					} else {						*result_type = CS_ROW_RESULT;						cmd->results_state = _CS_RES_CMD_DONE;					}					break;				case _CS_RES_RESULTSET_ROWS:					*result_type = CS_CMD_DONE;					cmd->results_state = _CS_RES_INIT;					break;				}				return CS_SUCCEED;				break;			case TDS_DONEINPROC_RESULT:				/*				 * A doneinproc token may signify the end of a				 * logical command if the command had a result				 * set. Otherwise it is ignored....				 */				switch (cmd->results_state) {				case _CS_RES_INIT:   /* command had no result set */					break;				case _CS_RES_RESULTSET_EMPTY:					if (cmd->command_type == CS_CUR_CMD) {						*result_type = CS_CURSOR_RESULT;					} else {						*result_type = CS_ROW_RESULT;					}					cmd->results_state = _CS_RES_CMD_DONE;					return CS_SUCCEED;					break;				case _CS_RES_RESULTSET_ROWS:					*result_type = CS_CMD_DONE;					cmd->results_state = _CS_RES_INIT;					return CS_SUCCEED;					break;				}				break;			case TDS_DONEPROC_RESULT:				/*				 * A DONEPROC result means the end of a logical				 * command only if it was one of the commands				 * directly sent from ct_send, not as a result				 * of a nested stored procedure call. We know				 * if this is the case if a STATUS_RESULT was				 * received immediately prior to the DONE_PROC				 */				if (cmd->results_state == _CS_RES_STATUS) {					if (done_flags & TDS_DONE_ERROR)						*result_type = CS_CMD_FAIL;					else						*result_type = CS_CMD_SUCCEED;					cmd->results_state = _CS_RES_CMD_DONE;					return CS_SUCCEED;				} else {					if (cmd->command_type == CS_DYNAMIC_CMD) {						*result_type = CS_CMD_SUCCEED;						cmd->results_state = _CS_RES_CMD_DONE;						return CS_SUCCEED;					}				}				break;			case TDS_PARAM_RESULT:				cmd->row_prefetched = 1;				*result_type = res_type;				return CS_SUCCEED;				break;			case TDS_STATUS_RESULT:				_ct_process_return_status(tds);				cmd->row_prefetched = 1;				*result_type = res_type;				cmd->results_state = _CS_RES_STATUS;				return CS_SUCCEED;				break;			case TDS_DESCRIBE_RESULT:				if (cmd->dynamic_cmd == CS_DESCRIBE_INPUT ||					cmd->dynamic_cmd == CS_DESCRIBE_OUTPUT) {					*result_type = res_type;					return CS_SUCCEED;				}				break;			default:				*result_type = res_type;				return CS_SUCCEED;				break;			}			break;		case TDS_NO_MORE_RESULTS:			/* some commands can be re-sent once completed */			/* so mark the command state as 'ready'...     */			if (cmd->command_type == CS_LANG_CMD ||				cmd->command_type == CS_RPC_CMD ||				cmd->command_type == CS_CUR_CMD ||				cmd->command_type == CS_DYNAMIC_CMD) {				ct_set_command_state(cmd, _CS_COMMAND_READY);			}			/* if we have just completed processing a dynamic deallocate */			/* get rid of our dynamic statement structure...             */			if (cmd->command_type == CS_DYNAMIC_CMD &&				cmd->dynamic_cmd  == CS_DEALLOC) {				_ct_deallocate_dynamic(cmd->con, cmd->dyn);				cmd->dyn = NULL;			}			return CS_END_RESULTS;			break;		case TDS_CANCELLED:			cmd->cancel_state = _CS_CANCEL_NOCANCEL;			return CS_CANCELED;			break;		case TDS_FAIL:		default:			return CS_FAIL;			break;		}  /* switch (tdsret) */	}      /* for (;;)        */}CS_RETCODEct_bind(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buffer, CS_INT * copied, CS_SMALLINT * indicator){	TDSCOLUMN *colinfo;	TDSRESULTINFO *resinfo;	TDSSOCKET *tds;	CS_CONNECTION *con = cmd->con;	CS_INT bind_count;	tdsdump_log(TDS_DBG_FUNC, "ct_bind() datafmt count = %d column_number = %d\n", datafmt->count, item);	if (!con || !con->tds_socket)		return CS_FAIL;	tds = con->tds_socket;	resinfo = tds->current_results;	/* check item value */	if (!resinfo || item <= 0 || item > resinfo->num_cols)		return CS_FAIL;	colinfo = resinfo->columns[item - 1];	/* check whether the request is for array binding and ensure that user */	/* supplies the same datafmt->count to the subsequent ct_bind calls    */	bind_count = (datafmt->count == 0) ? 1 : datafmt->count;	/* first bind for this result set */	if (cmd->bind_count == CS_UNUSED) {		cmd->bind_count = bind_count;	} else {		/* all subsequent binds for this result set - the bind counts must be the same */		if (cmd->bind_count != bind_count) {			_ctclient_msg(con, "ct_bind", 1, 1, 1, 137, "%d, %d", bind_count, cmd->bind_count);			return CS_FAIL;		}	}	/* bind the column_varaddr to the address of the buffer */	colinfo = resinfo->columns[item - 1];	colinfo->column_varaddr = (char *) buffer;	colinfo->column_bindtype = datafmt->datatype;	colinfo->column_bindfmt = datafmt->format;	colinfo->column_bindlen = datafmt->maxlength;	if (indicator) {		colinfo->column_nullbind = indicator;	}	if (copied) {		colinfo->column_lenbind = copied;	}	return CS_SUCCEED;}CS_RETCODEct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * rows_read){	TDS_INT ret_type;	TDS_INT ret;	TDS_INT marker;	TDS_INT temp_count;	TDSSOCKET *tds;	tdsdump_log(TDS_DBG_FUNC, "ct_fetch()\n");	if (!cmd->con || !cmd->con->tds_socket)		return CS_FAIL;	if (cmd->command_state == _CS_COMMAND_IDLE) {		_ctclient_msg(cmd->con, "ct_fetch", 1, 1, 1, 16843163, "");		return CS_FAIL;	}	if (cmd->cancel_state == _CS_CANCEL_PENDING) {		_ct_cancel_cleanup(cmd);		return CS_CANCELED;	}	tds = cmd->con->tds_socket;

⌨️ 快捷键说明

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