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

📄 tds_checks.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 2004, 2005 Frediano Ziglio * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#if HAVE_CONFIG_H#include <config.h>#endif /* HAVE_CONFIG_H */#undef NDEBUG#include <stdarg.h>#include <stdio.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#if HAVE_STRING_H#include <string.h>#endif /* HAVE_STRING_H */#include <assert.h>#include "tds.h"#include "tdsconvert.h"#include "tdsstring.h"#include "tds_checks.h"#ifdef DMALLOC#include <dmalloc.h>#endifTDS_RCSID(var, "$Id: tds_checks.c,v 1.20 2007/06/21 07:21:21 freddy77 Exp $");#if ENABLE_EXTRA_CHECKSvoidtds_check_tds_extra(const TDSSOCKET * tds){	const int invalid_state = 0;	int found, i;	int result_found = 0;	TDSDYNAMIC *cur_dyn = NULL;	TDSCURSOR *cur_cursor = NULL;	assert(tds);	/* teset state and connection */	switch (tds->state) {	case TDS_DEAD:	case TDS_QUERYING:	case TDS_PENDING:	case TDS_IDLE:	case TDS_READING:		break;	default:		assert(invalid_state);	}	assert(tds->state == TDS_DEAD || !TDS_IS_SOCKET_INVALID(tds->s));	assert(tds->state != TDS_DEAD || TDS_IS_SOCKET_INVALID(tds->s));	/* test env */	tds_check_env_extra(&tds->env);	/* test buffers and positions */	assert(tds->in_pos <= tds->in_len && tds->in_len <= tds->in_buf_max);	/* TODO remove blocksize from env and use out_len ?? *//*	assert(tds->out_pos <= tds->out_len); *//* 	assert(tds->out_len == 0 || tds->out_buf != NULL); */	assert(tds->out_pos <= tds->env.block_size);	assert(tds->env.block_size == 0 || tds->out_buf != NULL);	assert(tds->in_buf_max == 0 || tds->in_buf != NULL);	/* test res_info */	if (tds->res_info) {		tds_check_resultinfo_extra(tds->res_info);		if (tds->current_results == tds->res_info)			result_found = 1;	}	/* test num_comp_info, comp_info */	assert(tds->num_comp_info >= 0);	for (i = 0; i < tds->num_comp_info; ++i) {		assert(tds->comp_info);		tds_check_resultinfo_extra(tds->comp_info[i]);		if (tds->current_results == tds->comp_info[i])			result_found = 1;	}	/* param_info */	if (tds->param_info) {		tds_check_resultinfo_extra(tds->param_info);		if (tds->current_results == tds->param_info)			result_found = 1;	}	/* test cursors */	found = 0;	for (cur_cursor = tds->cursors; cur_cursor != NULL; cur_cursor = cur_cursor->next) {		tds_check_cursor_extra(cur_cursor);		if (tds->current_results == cur_cursor->res_info)			result_found = 1;		if (cur_cursor == tds->cur_cursor)			found = 1;	}	assert(found || tds->cur_cursor == NULL);	/* test num_dyms, cur_dyn, dyns */	found = 0;	for (cur_dyn = tds->dyns; cur_dyn != NULL; cur_dyn = cur_dyn->next) {		if (cur_dyn == tds->cur_dyn)			found = 1;		tds_check_dynamic_extra(cur_dyn);		if (tds->current_results == cur_dyn->res_info)			result_found = 1;	}	assert(found || tds->cur_dyn == NULL);	/* test tds_ctx */	tds_check_context_extra(tds->tds_ctx);	/* TODO test char_conv_count, char_convs */	/* current_results should be one of res_info, comp_info, param_info or dynamic */	/*	 * TODO this test was here to check that current_results was an alias	 * but with cursor and reference counting current_results can point	 * to a cursor result available on upper layer	 * Perhaps we should free results on deallocate and enable	 * assert again?	 */	/* assert(result_found || tds->current_results == NULL); */	/* we can't have compute and no results */	assert(tds->num_comp_info == 0 || tds->res_info != NULL);	/* we can't have normal and parameters results */	/* TODO too strict ?? *//*	assert(tds->param_info == NULL || tds->res_info == NULL); */}voidtds_check_context_extra(const TDSCONTEXT * ctx){	assert(ctx);}voidtds_check_env_extra(const TDSENV * env){	assert(env);	assert(env->block_size >= 0 && env->block_size <= 65536);}voidtds_check_column_extra(const TDSCOLUMN * column){	int size;	TDSSOCKET tds;	int varint_ok;	assert(column);	assert(column->column_varint_size <= 5 && column->column_varint_size != 3);	assert(column->column_scale <= column->column_prec);	assert(column->column_prec <= 77);	/* I don't like this that much... freddy77 */	if (column->column_type == 0)		return;	assert(strlen(column->table_name) < sizeof(column->table_name));	assert(strlen(column->column_name) < sizeof(column->column_name));	/* check type and server type same or SQLNCHAR -> SQLCHAR */	assert(tds_get_cardinal_type(column->on_server.column_type) == column->column_type		|| (tds_get_null_type(column->column_type) == column->on_server.column_type 		&& column->column_varint_size == 1 && is_fixed_type(column->column_type)));	tds.minor_version = 0;	tds.major_version = 5;	varint_ok = tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;	tds.major_version = 7;	varint_ok = varint_ok || tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;	assert(varint_ok);	/* check current size <= size */	if (is_numeric_type(column->column_type)) {		/* I don't like that much this difference between numeric and not numeric - freddy77 */		/* TODO what should be the size ?? */		assert(column->column_prec >= 1 && column->column_prec <= 77);		assert(column->column_scale <= column->column_prec);/*		assert(column->column_cur_size == tds_numeric_bytes_per_prec[column->column_prec] + 2 || column->column_cur_size == -1); */	} else {		assert(column->column_cur_size <= column->column_size);	}	/* check size of fixed type correct */	size = tds_get_size_by_type(column->column_type);	assert(size != 0 || column->column_type == SYBVOID);	if (size >= 0 && column->column_type != SYBBITN) {		/* check macro */		assert(is_fixed_type(column->column_type));		/* check current size */		assert(size == column->column_size);		/* check cases where server need nullable types */		if (column->column_type != column->on_server.column_type && (column->column_type != SYBINT8 || column->on_server.column_type != SYB5INT8)) {			assert(!is_fixed_type(column->on_server.column_type));			assert(column->column_varint_size == 1);			assert(column->column_size == column->column_cur_size || column->column_cur_size == -1);		} else {			assert(column->column_varint_size == 0 || (column->column_type == SYBUNIQUE && column->column_varint_size == 1));			assert(column->column_size == column->column_cur_size || 				(column->column_type == SYBUNIQUE && column->column_cur_size == -1));		}		assert(column->column_size == column->on_server.column_size);	} else {		assert(!is_fixed_type(column->column_type));		assert(column->char_conv || (column->on_server.column_size == column->column_size || column->on_server.column_size == 0));		assert(column->column_varint_size != 0);	}	/* check size of nullable types (ie intN) it's supported */	if (tds_get_conversion_type(column->column_type, 4) != column->column_type) {		/* check macro */		assert(is_nullable_type(column->column_type));		/* check that size it's correct for this type of nullable */		assert(tds_get_conversion_type(column->column_type, column->column_size) != column->column_type);		/* check current size */		assert(column->column_size >= column->column_cur_size || column->column_cur_size == -1);		/* check same type and size on server */		assert(column->column_type == column->on_server.column_type);		assert(column->column_size == column->on_server.column_size);	}}voidtds_check_resultinfo_extra(const TDSRESULTINFO * res_info){	int i;	assert(res_info);	assert(res_info->num_cols >= 0);	assert(res_info->ref_count > 0);	for (i = 0; i < res_info->num_cols; ++i) {		assert(res_info->columns);		tds_check_column_extra(res_info->columns[i]);		assert(res_info->columns[i]->column_data != NULL || res_info->row_size == 0);	}	assert(res_info->row_size >= 0);	assert(res_info->computeid >= 0);	assert(res_info->by_cols >= 0);	assert(res_info->by_cols == 0 || res_info->bycolumns);}voidtds_check_cursor_extra(const TDSCURSOR * cursor){}voidtds_check_dynamic_extra(const TDSDYNAMIC * dyn){	assert(dyn);	if (dyn->res_info)		tds_check_resultinfo_extra(dyn->res_info);	if (dyn->params)		tds_check_resultinfo_extra(dyn->params);	assert(!dyn->emulated || dyn->query);}#endif /* ENABLE_EXTRA_CHECKS */

⌨️ 快捷键说明

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