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

📄 query.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998-2004  Brian Bruns * * 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 */#include <assert.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#include "tds.h"#include "tdssrv.h"static char software_version[] = "$Id: query.c,v 1.17 2007/09/24 10:02:14 freddy77 Exp $";static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };static char *query;static size_t query_buflen = 0;/** * Read a TDS5 tokenized query. */char *tds_get_query(TDSSOCKET * tds){	int len;	if (query_buflen == 0) {		query_buflen = 1024;		query = (char *) malloc(query_buflen);	}	tds_get_byte(tds);	/* 33 */	len = tds_get_int(tds);	/* query size +1 */	tds_get_byte(tds);	/* has args, ignored TODO */	assert(len >= 1);	/* TODO handle correctly */	if (len > query_buflen) {		query_buflen = len;		query = (char *) realloc(query, query_buflen);	}	--len;	tds_get_n(tds, query, len);	query[len] = 0;	return query;}/** * Read a query, and return it as an ASCII string with a \0 terminator.  This * should work for TDS4, TDS5, and TDS7+ connections.  Also, it converts RPC * calls into stored procedure queries, and it skips CANCEL packets.  The query * string is returned in a static buffer which is overwritten each time this * function is called. * \param tds  The socket to read from. * \return A query string if successful, or NULL if we either can't read from * the socket or we read something that we can't handle. */char *tds_get_generic_query(TDSSOCKET * tds){ 	int token, byte;	int len, more, i, j;	for (;;) {		/*		 * Read a new packet.  We must explicitly read it,		 * instead of letting functions such as tds_get_byte()		 * to read it for us, so that we can examine the packet		 * type via tds->in_flag.		 */		if (tds_read_packet(tds) < 0) {			return NULL;		}		/* Queries can arrive in a couple different formats. */		switch (tds->in_flag) {		case TDS_RPC:			/* TODO */		case TDS_NORMAL: /* TDS5 query packet */			/* get the token */			token = tds_get_byte(tds);			switch (token) {			case TDS_LANGUAGE_TOKEN:				/* SQL query */				len = tds_get_int(tds); /* query size +1 */				assert(len >= 1);	/* TODO handle */				tds_get_byte(tds);	/* has args, ignored TODO */				if (len > query_buflen) {					query_buflen = len;					query = (char *) realloc(query, query_buflen);				}				--len;				tds_get_n(tds, query, len);				query[len] = 0;				return query;			case TDS_DBRPC_TOKEN:				/* RPC call -- make it look like a query */				/* skip the overall length */				(void)tds_get_smallint(tds);				/* get the length of the stored procedure's name */				len = tds_get_byte(tds) + 1;/* sproc name size +1 */				if (len > query_buflen) {					query_buflen = len;					query = (char *) realloc(query, query_buflen);				}				/*				 * Read the chars of the name.  Skip NUL				 * bytes, as a cheap way to convert				 * Unicode to ASCII.  (For TDS7+, the				 * name is sent in Unicode.)				 */				for (i = j  = 0; i < len - 1; i++) {					byte = tds_get_byte(tds);					if (byte != '\0')						query[j++] = byte;				}				query[j] = '\0';				/* TODO: WE DON'T HANDLE PARAMETERS YET! */				/* eat the rest of the packet */				while (!tds->last_packet && tds_read_packet(tds) > 0) {				}				return query;			default:				/* unexpected token */				/* eat the rest of the packet */				while (!tds->last_packet && tds_read_packet(tds) > 0) {				}				return NULL;			}			break;		case TDS_QUERY:			/* TDS4 and TDS7+ fill the whole packet with a query */			len = 0;			for (;;) {				const char *src;				/* If buffer needs to grow, then grow */				more = tds->in_len - tds->in_pos;				src = (char *) (tds->in_buf + tds->in_pos);				if ((size_t)(len + more + 1) > query_buflen)				{					query_buflen = len + more + 1024u;					query_buflen -= query_buflen % 1024u;					query = (char *)realloc(query, query_buflen);				}				/*				 * Pull new data into the query buffer.				 * Ignore NUL bytes -- this is a cheap way				 * to convert Unicode to Latin-1/ASCII.				 */				while (--more >= 0)				{					query[len] = *src++;					if (query[len] != '\0')						len++;				}				/* if more then read it */				if (tds->last_packet)					break;				if (tds_read_packet(tds) < 0)					return NULL;			}			/* add a NUL to mark the end */			query[len] = '\0';			return query;		case TDS_CANCEL:			/*			 * ignore cancel requests -- if we're waiting			 * for the next query then it's obviously too			 * late to cancel the previous query.			 */			/* TODO it's not too late -- freddy77 */			break;		default:			/* not a query packet */			return NULL;		}	}}

⌨️ 快捷键说明

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