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

📄 token.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
	tds_free_all_results(tds);	tds->rows_affected = TDS_NO_COUNT;	if ((info = tds_alloc_results(num_names)) != NULL) {		tds->current_results = tds->res_info = info;		cur = head;		for (col = 0; col < num_names; ++col) {			curcol = info->columns[col];			tds_strlcpy(curcol->column_name, cur->name, sizeof(curcol->column_name));			curcol->column_namelen = strlen(curcol->column_name);			prev = cur;			cur = cur->next;			free(prev->name);			free(prev);		}		return TDS_SUCCEED;	}	tds_free_namelist(head);	return TDS_FAIL;}/** * tds_process_col_fmt() is the other half of result set processing * under TDS 4.2. It follows tds_process_col_name(). It contains all the  * column type and size information. * This is a 4.2 only function */static inttds_process_col_fmt(TDSSOCKET * tds){	int col, hdrsize;	TDSCOLUMN *curcol;	TDSRESULTINFO *info;	TDS_SMALLINT tabnamesize;	int bytes_read = 0;	int rest;	TDS_SMALLINT flags;	CHECK_TDS_EXTRA(tds);	hdrsize = tds_get_smallint(tds);	/* TODO use current_results instead of res_info ?? */	info = tds->res_info;	for (col = 0; col < info->num_cols; col++) {		curcol = info->columns[col];		/* In Sybase all 4 byte are used for usertype, while mssql place 2 byte as usertype and 2 byte as flags */		if (TDS_IS_MSSQL(tds)) {			curcol->column_usertype = tds_get_smallint(tds);			flags = tds_get_smallint(tds);			curcol->column_nullable = flags & 0x01;			curcol->column_writeable = (flags & 0x08) > 0;			curcol->column_identity = (flags & 0x10) > 0;		} else {			curcol->column_usertype = tds_get_int(tds);		}		/* on with our regularly scheduled code (mlilback, 11/7/01) */		tds_set_column_type(tds, curcol, tds_get_byte(tds));		tdsdump_log(TDS_DBG_INFO1, "processing result. type = %d(%s), varint_size %d\n",			    curcol->column_type, tds_prtype(curcol->column_type), curcol->column_varint_size);		switch (curcol->column_varint_size) {		case 4:			curcol->column_size = tds_get_int(tds);			/* junk the table name -- for now */			tabnamesize = tds_get_smallint(tds);			tds_get_n(tds, NULL, tabnamesize);			bytes_read += 5 + 4 + 2 + tabnamesize;			break;		case 1:			curcol->column_size = tds_get_byte(tds);			bytes_read += 5 + 1;			break;		case 0:			bytes_read += 5 + 0;			break;		}		/* Adjust column size according to client's encoding */		curcol->on_server.column_size = curcol->column_size;		adjust_character_column_size(tds, curcol);	}	/* get the rest of the bytes */	rest = hdrsize - bytes_read;	if (rest > 0) {		tdsdump_log(TDS_DBG_INFO1, "NOTE:tds_process_col_fmt: draining %d bytes\n", rest);		tds_get_n(tds, NULL, rest);	}	return tds_alloc_row(info);}static inttds8_read_table_names(TDSSOCKET *tds, int remainder, struct namelist **p_head){	struct namelist *head = NULL, *cur = NULL, *prev;	int num_names = 0;	/*	 * this is a little messy...TDS 5.0 gives the number of columns	 * upfront, while in TDS 4.2, you're expected to figure it out	 * by the size of the message. So, I use a link list to get the	 * colum names and then allocate the result structure, copy	 * and delete the linked list	 */	while (remainder > 0) {		int namelen, elements, i, len;		char *partials[4], *p;		prev = cur;		if (!(cur = (struct namelist *) malloc(sizeof(struct namelist)))) {			tds_free_namelist(head);			return -1;		}		cur->name = NULL;		cur->next = NULL;		if (prev)			prev->next = cur;		else			head = cur;		elements = tds_get_byte(tds);		--remainder;		if (elements <= 0 || elements > 4) {			tds_free_namelist(head);			return -1;		}		/* read partials IDs and compute full length */		len = 0;		for (i = 0; i < elements; ++i) {			namelen = tds_get_smallint(tds);			remainder -= 2 + 2 * namelen;			if (tds_alloc_get_string(tds, &partials[i], namelen) < 0) {				while (i > 0)					free(partials[--i]);				tds_free_namelist(head);				return -1;			}			len += tds_quote_id(tds, NULL, partials[i], -1) + 1;		}		/* allocate full name */		p = (char *) malloc(len);		if (!p) {			i = elements;			while (i > 0)				free(partials[--i]);			tds_free_namelist(head);			return -1;		}		/* compose names */		cur->name = p;		for (i = 0; i < elements; ++i) {			p += tds_quote_id(tds, p, partials[i], -1);			*p++ = '.';			free(partials[i]);		}		*--p = 0;		num_names++;	}	*p_head = head;	return num_names;}static inttds_process_tabname(TDSSOCKET *tds){	struct namelist *head, *cur;	int num_names, hdrsize, i;	char **names;	unsigned char marker;	int rc;	hdrsize = tds_get_smallint(tds);	/* different structure for tds8 */	if (IS_TDS8_PLUS(tds))		num_names = tds8_read_table_names(tds, hdrsize, &head);	else		num_names = tds_read_namelist(tds, hdrsize, &head, 1);	if (num_names < 0)		return TDS_FAIL;	/* put in an array */	names = (char **) malloc(num_names * sizeof(char*));	if (!names) {		tds_free_namelist(head);		return TDS_FAIL;	}	for (cur = head, i = 0; i < num_names; ++i, cur = cur->next)		names[i] = cur->name;	rc = TDS_SUCCEED;	marker = tds_get_byte(tds);	if (marker != TDS_COLINFO_TOKEN)		tds_unget_byte(tds);	else		rc = tds_process_colinfo(tds, names, num_names);	free(names);	tds_free_namelist(head);	return rc;}static inttds_process_colinfo(TDSSOCKET * tds, char **names, int num_names){	int hdrsize;	TDSCOLUMN *curcol;	TDSRESULTINFO *info;	int bytes_read = 0;	unsigned char col_info[3], l;	CHECK_TDS_EXTRA(tds);	hdrsize = tds_get_smallint(tds);	info = tds->current_results;	while (bytes_read < hdrsize) {		tds_get_n(tds, col_info, 3);		bytes_read += 3;		curcol = NULL;		if (info && col_info[0] > 0 && col_info[0] <= info->num_cols)			curcol = info->columns[col_info[0] - 1];		if (curcol) {			curcol->column_writeable = (col_info[2] & 0x4) == 0;			curcol->column_key = (col_info[2] & 0x8) > 0;			curcol->column_hidden = (col_info[2] & 0x10) > 0;			if (names && col_info[1] > 0 && col_info[1] <= num_names) {				tds_strlcpy(curcol->table_name, names[col_info[1] - 1], sizeof(curcol->table_name));				curcol->table_namelen = strlen(curcol->table_name);			}		}		/* read real column name */		if (col_info[2] & 0x20) {			l = tds_get_byte(tds);			if (curcol) {				if (curcol->table_column_name)					TDS_ZERO_FREE(curcol->table_column_name);				tds_alloc_get_string(tds, &curcol->table_column_name, l);				if (IS_TDS7_PLUS(tds))					l *= 2;			} else {				if (IS_TDS7_PLUS(tds))					l *= 2;				/* discard silently */				tds_get_n(tds, NULL, l);			}			bytes_read += l + 1;		}	}	return TDS_SUCCEED;}/** * process output parameters of a stored  * procedure. This differs from regular row/compute results in that there * is no total number of parameters given, they just show up singly. */static inttds_process_param_result(TDSSOCKET * tds, TDSPARAMINFO ** pinfo){	int hdrsize;	TDSCOLUMN *curparam;	TDSPARAMINFO *info;	int token;	tdsdump_log(TDS_DBG_FUNC, "tds_process_param_result(%p, %p)\n", tds, pinfo);	CHECK_TDS_EXTRA(tds);	if (*pinfo)		CHECK_PARAMINFO_EXTRA(*pinfo);	/* TODO check if current_results is a param result */	/* limited to 64K but possible types are always smaller (not TEXT/IMAGE) */	hdrsize = tds_get_smallint(tds);	if ((info = tds_alloc_param_result(*pinfo)) == NULL)		return TDS_FAIL;	*pinfo = info;	curparam = info->columns[info->num_cols - 1];	/*	 * FIXME check support for tds7+ (seem to use same format of tds5 for data...)	 * perhaps varint_size can be 2 or collation can be specified ??	 */	tds_get_data_info(tds, curparam, 1);	curparam->column_cur_size = curparam->column_size;	/* needed ?? */	if (tds_alloc_param_data(curparam) == NULL)		return TDS_FAIL;	token = tds_get_data(tds, curparam);	/*	 * Real output parameters will either be unnamed or will have a valid	 * parameter name beginning with '@'. Ignore any other Spurious parameters	 * such as those returned from calls to writetext in the proc.	 */	if (curparam->column_namelen > 0 && curparam->column_name[0] != '@')		tds_free_param_result(*pinfo);	return token;}static inttds_process_param_result_tokens(TDSSOCKET * tds){	int marker;	TDSPARAMINFO **pinfo;	CHECK_TDS_EXTRA(tds);	if (tds->cur_dyn)		pinfo = &(tds->cur_dyn->res_info);	else		pinfo = &(tds->param_info);	while ((marker = tds_get_byte(tds)) == TDS_PARAM_TOKEN) {		tds_process_param_result(tds, pinfo);	}	if (!marker) {		tdsdump_log(TDS_DBG_FUNC, "error: tds_process_param_result() returned TDS_FAIL\n");		return TDS_FAIL;	}	tds->current_results = *pinfo;	tds_unget_byte(tds);	return TDS_SUCCEED;}/** * tds_process_params_result_token() processes params on TDS5. */static inttds_process_params_result_token(TDSSOCKET * tds){	int i;	TDSCOLUMN *curcol;	TDSPARAMINFO *info;	CHECK_TDS_EXTRA(tds);	/* TODO check if current_results is a param result */	info = tds->current_results;	if (!info)		return TDS_FAIL;	for (i = 0; i < info->num_cols; i++) {		curcol = info->columns[i];		if (tds_get_data(tds, curcol) != TDS_SUCCEED)			return TDS_FAIL;	}	return TDS_SUCCEED;}/** * tds_process_compute_result() processes compute result sets.  These functions * need work but since they get little use, nobody has complained! * It is very similar to normal result sets. */static inttds_process_compute_result(TDSSOCKET * tds){	int hdrsize;	int col, num_cols;	TDS_TINYINT by_cols = 0;	TDS_SMALLINT *cur_by_col;	TDS_SMALLINT compute_id = 0;	TDSCOLUMN *curcol;	TDSCOMPUTEINFO *info;	int i;	CHECK_TDS_EXTRA(tds);	hdrsize = tds_get_smallint(tds);	/*	 * compute statement id which this relates	 * to. You can have more than one compute	 * statement in a SQL statement	 */	compute_id = tds_get_smallint(tds);	tdsdump_log(TDS_DBG_INFO1, "processing tds7 compute result. compute_id = %d\n", compute_id);	/*	 * number of compute columns returned - so	 * COMPUTE SUM(x), AVG(x)... would return	 * num_cols = 2	 */	num_cols = tds_get_byte(tds);	for (i = 0;; ++i) {		if (i >= tds->num_comp_info)			return TDS_FAIL;		info = tds->comp_info[i];		tdsdump_log(TDS_DBG_FUNC, "in dbaltcolid() found computeid = %d\n", info->computeid);		if (info->computeid == compute_id)			break;	}	tdsdump_log(TDS_DBG_INFO1, "processing tds7 compute result. num_cols = %d\n", num_cols);	for (col = 0; col < num_cols; col++) {		tdsdump_log(TDS_DBG_INFO1, "processing tds7 compute result. point 2\n");		curcol = info->columns[col];		curcol->column_operator = tds_get_byte(tds);		curcol->column_operand = tds_get_byte(tds);		/*		 * if no name has been defined for the compute column,		 * put in "max", "avg" etc.		 */		if (curcol->column_namelen == 0) {			strcpy(curcol->column_name, tds_pr_op(curcol->column_operator));			curcol->column_namelen = strlen(curcol->column_name);		}		/*  User defined data type of the column */		curcol->column_usertype = tds_get_int(tds);		tds_set_column_type(tds, curcol, tds_get_byte(tds));		switch (curcol->column_varint_size) {		case 4:			curcol->column_size = tds_get_int(tds);			break;		case 2:			curcol->column_size = tds_get_smallint(tds);			break;		case 1:			curcol->column_size = tds_get_byte(tds);			break;		case 0:

⌨️ 快捷键说明

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