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

📄 blk.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998-2004, 2005  Brian Bruns, Bill Thompson * * 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#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 "bkpublic.h"#include "ctpublic.h"#include "ctlib.h"#include "replacements.h"typedef struct _pbcb{	char *pb;	unsigned int cb;} TDS_PBCB;TDS_RCSID(var, "$Id: blk.c,v 1.43 2007/12/31 10:06:49 freddy77 Exp $");static CS_RETCODE _blk_get_col_data(CS_BLKDESC *, TDSCOLUMN *, int );static int _blk_add_variable_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuffer, int start, int *var_cols);static CS_RETCODE _blk_add_fixed_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuffer, int start);static CS_RETCODE _blk_build_bcp_record(CS_BLKDESC *blkdesc, CS_INT offset);static CS_RETCODE _blk_send_colmetadata(CS_BLKDESC * blkdesc);static CS_RETCODE _blk_build_bulk_insert_stmt(TDS_PBCB * clause, TDSCOLUMN * bcpcol, int first);static CS_RETCODE _rowxfer_in_init(CS_BLKDESC * blkdesc);static CS_RETCODE _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);static CS_RETCODE _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);CS_RETCODEblk_alloc(CS_CONNECTION * connection, CS_INT version, CS_BLKDESC ** blk_pointer){	tdsdump_log(TDS_DBG_FUNC, "blk_alloc()\n");	*blk_pointer = (CS_BLKDESC *) malloc(sizeof(CS_BLKDESC));	memset(*blk_pointer, '\0', sizeof(CS_BLKDESC));	/* so we know who we belong to */	(*blk_pointer)->con = connection;	return CS_SUCCEED;}CS_RETCODEblk_bind(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buffer, CS_INT * datalen, CS_SMALLINT * indicator){	TDSCOLUMN *colinfo;	CS_CONNECTION *con;	CS_INT bind_count;	int i;	tdsdump_log(TDS_DBG_FUNC, "blk_bind()\n");	if (!blkdesc) {		return CS_FAIL;	}	con = blkdesc->con;	if (item == CS_UNUSED) {		/* clear all bindings */		if (datafmt == NULL && buffer == NULL && datalen == NULL && indicator == NULL ) { 			blkdesc->bind_count = CS_UNUSED;			for (i = 0; i < blkdesc->bindinfo->num_cols; i++ ) {				colinfo = blkdesc->bindinfo->columns[i];				colinfo->column_varaddr  = NULL;				colinfo->column_bindtype = 0;				colinfo->column_bindfmt  = 0;				colinfo->column_bindlen  = 0;				colinfo->column_nullbind = NULL;				colinfo->column_lenbind  = NULL;			}		}		return CS_SUCCEED;	}	/* check item value */	if (item < 1 || item > blkdesc->bindinfo->num_cols) {		_ctclient_msg(con, "blk_bind", 2, 5, 1, 141, "%s, %d", "colnum", item);		return CS_FAIL;	}	/* clear bindings for this column */	if (datafmt == NULL && buffer == NULL && datalen == NULL && indicator == NULL ) { 		colinfo = blkdesc->bindinfo->columns[item - 1];		colinfo->column_varaddr  = NULL;		colinfo->column_bindtype = 0;		colinfo->column_bindfmt  = 0;		colinfo->column_bindlen  = 0;		colinfo->column_nullbind = NULL;		colinfo->column_lenbind  = NULL;		return CS_SUCCEED;	}	/*	 * 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 (blkdesc->bind_count == CS_UNUSED) {		blkdesc->bind_count = bind_count;	} else {		/* all subsequent binds for this result set - the bind counts must be the same */		if (blkdesc->bind_count != bind_count) {			_ctclient_msg(con, "blk_bind", 1, 1, 1, 137, "%d, %d", bind_count, blkdesc->bind_count);			return CS_FAIL;		}	}	/* bind the column_varaddr to the address of the buffer */	colinfo = blkdesc->bindinfo->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 (datalen) {		colinfo->column_lenbind = datalen;	}	return CS_SUCCEED;}CS_RETCODEblk_colval(SRV_PROC * srvproc, CS_BLKDESC * blkdescp, CS_BLK_ROW * rowp, CS_INT colnum, CS_VOID * valuep, CS_INT valuelen,	   CS_INT * outlenp){	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_colval()\n");	return CS_FAIL;}CS_RETCODEblk_default(CS_BLKDESC * blkdesc, CS_INT colnum, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen){	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_default()\n");	return CS_FAIL;}CS_RETCODEblk_describe(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt){	TDSCOLUMN *curcol;	int len;	tdsdump_log(TDS_DBG_FUNC, "blk_describe()\n");	if (item < 1 || item > blkdesc->bindinfo->num_cols) {		_ctclient_msg(blkdesc->con, "blk_describe", 2, 5, 1, 141, "%s, %d", "colnum", item);		return CS_FAIL;	}	curcol = blkdesc->bindinfo->columns[item - 1];	len = curcol->column_namelen;	if (len >= CS_MAX_NAME)		len = CS_MAX_NAME - 1;	strncpy(datafmt->name, curcol->column_name, len);	/* name is always null terminated */	datafmt->name[len] = 0;	datafmt->namelen = len;	/* need to turn the SYBxxx into a CS_xxx_TYPE */	datafmt->datatype = _ct_get_client_type(curcol->column_type, curcol->column_usertype, curcol->column_size);	tdsdump_log(TDS_DBG_INFO1, "blk_describe() datafmt->datatype = %d server type %d\n", datafmt->datatype,			curcol->column_type);	/* FIXME is ok this value for numeric/decimal? */	datafmt->maxlength = curcol->column_size;	datafmt->usertype = curcol->column_usertype;	datafmt->precision = curcol->column_prec;	datafmt->scale = curcol->column_scale;	/*	 * There are other options that can be returned, but these are the	 * only two being noted via the TDS layer.	 */	datafmt->status = 0;	if (curcol->column_nullable)		datafmt->status |= CS_CANBENULL;	if (curcol->column_identity)		datafmt->status |= CS_IDENTITY;	datafmt->count = 1;	datafmt->locale = NULL;	return CS_SUCCEED;}CS_RETCODEblk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow){	TDSSOCKET *tds;	tdsdump_log(TDS_DBG_FUNC, "blk_done()\n");	tds = blkdesc->con->tds_socket;	switch (type) {	case CS_BLK_BATCH:		tds_flush_packet(tds);		/* TODO correct ?? */		tds_set_state(tds, TDS_PENDING);		if (tds_process_simple_query(tds) != TDS_SUCCEED) {			_ctclient_msg(blkdesc->con, "blk_done", 2, 5, 1, 140, "");			return CS_FAIL;		}				if (outrow) 			*outrow = tds->rows_affected;				tds_submit_query(tds, blkdesc->insert_stmt);		if (tds_process_simple_query(tds) != TDS_SUCCEED) {			_ctclient_msg(blkdesc->con, "blk_done", 2, 5, 1, 140, "");			return CS_FAIL;		}		tds->out_flag = TDS_BULK;		if (IS_TDS7_PLUS(tds)) {			_blk_send_colmetadata(blkdesc);		}		break;			case CS_BLK_ALL:		tds_flush_packet(tds);		/* TODO correct ?? */		tds_set_state(tds, TDS_PENDING);		if (tds_process_simple_query(tds) != TDS_SUCCEED) {			_ctclient_msg(blkdesc->con, "blk_done", 2, 5, 1, 140, "");			return CS_FAIL;		}				if (outrow) 			*outrow = tds->rows_affected;				/* free allocated storage in blkdesc & initialise flags, etc. */			if (blkdesc->tablename)			TDS_ZERO_FREE(blkdesc->tablename);			if (blkdesc->insert_stmt)			TDS_ZERO_FREE(blkdesc->insert_stmt);			if (blkdesc->bindinfo) {			tds_free_results(blkdesc->bindinfo);			blkdesc->bindinfo = NULL;		}			blkdesc->direction = 0;		blkdesc->bind_count = CS_UNUSED;		blkdesc->xfer_init = 0;		blkdesc->var_cols = 0;		break;	}	return CS_SUCCEED;}CS_RETCODEblk_drop(CS_BLKDESC * blkdesc){	if (!blkdesc)		return CS_SUCCEED;	free(blkdesc->tablename);	free(blkdesc->insert_stmt);	tds_free_results(blkdesc->bindinfo);	free(blkdesc);	return CS_SUCCEED;}CS_RETCODEblk_getrow(SRV_PROC * srvproc, CS_BLKDESC * blkdescp, CS_BLK_ROW * rowp){	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_getrow()\n");	return CS_FAIL;}CS_RETCODEblk_gettext(SRV_PROC * srvproc, CS_BLKDESC * blkdescp, CS_BLK_ROW * rowp, CS_INT bufsize, CS_INT * outlenp){	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_gettext()\n");	return CS_FAIL;}CS_RETCODEblk_init(CS_BLKDESC * blkdesc, CS_INT direction, CS_CHAR * tablename, CS_INT tnamelen){	TDSCOLUMN *curcol;	TDSSOCKET *tds;	TDSRESULTINFO *resinfo;	TDSRESULTINFO *bindinfo;	TDS_INT result_type;	int i, rc;	tdsdump_log(TDS_DBG_FUNC, "blk_init()\n");	if (!blkdesc) {		return CS_FAIL;	}	if (direction != CS_BLK_IN && direction != CS_BLK_OUT ) {		_ctclient_msg(blkdesc->con, "blk_init", 2, 6, 1, 138, "");		return CS_FAIL;	}	if (!tablename) {		_ctclient_msg(blkdesc->con, "blk_init", 2, 6, 1, 139, "");		return CS_FAIL;	}	if (tnamelen == CS_NULLTERM)		tnamelen = strlen(tablename);	/* free allocated storage in blkdesc & initialise flags, etc. */	if (blkdesc->tablename) {		tdsdump_log(TDS_DBG_FUNC, "blk_init() freeing tablename\n");		free(blkdesc->tablename);	}	if (blkdesc->insert_stmt) {		tdsdump_log(TDS_DBG_FUNC, "blk_init() freeing insert_stmt\n");		TDS_ZERO_FREE(blkdesc->insert_stmt);	}	if (blkdesc->bindinfo) {		tdsdump_log(TDS_DBG_FUNC, "blk_init() freeing results\n");		tds_free_results(blkdesc->bindinfo);		blkdesc->bindinfo = NULL;	}	/* string can be no-nul terminated so copy with memcpy */	blkdesc->tablename = (char *) malloc(tnamelen + 1);	/* FIXME malloc can fail */	memcpy(blkdesc->tablename, tablename, tnamelen);	blkdesc->tablename[tnamelen] = 0;	blkdesc->direction = direction;	blkdesc->bind_count = CS_UNUSED;	blkdesc->xfer_init = 0;	blkdesc->var_cols = 0;	tds = blkdesc->con->tds_socket;	/* TODO quote tablename if needed */	if (tds_submit_queryf(tds, "select * from %s where 0 = 1", blkdesc->tablename) == TDS_FAIL) {		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");		return CS_FAIL;	}	while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))		   == TDS_SUCCEED) {	}	if (rc != TDS_NO_MORE_RESULTS) {		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");		return CS_FAIL;	}	/* copy the results info from the TDS socket into CS_BLKDESC structure */	if (!tds->res_info) {		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");		return CS_FAIL;	}	resinfo = tds->res_info;	if ((bindinfo = tds_alloc_results(resinfo->num_cols)) == NULL) {		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");		return CS_FAIL;	}	bindinfo->row_size = resinfo->row_size;	for (i = 0; i < bindinfo->num_cols; i++) {		curcol = bindinfo->columns[i];		curcol->column_type = resinfo->columns[i]->column_type;		curcol->column_usertype = resinfo->columns[i]->column_usertype;		curcol->column_flags = resinfo->columns[i]->column_flags;		curcol->column_size = resinfo->columns[i]->column_size;		curcol->column_varint_size = resinfo->columns[i]->column_varint_size;		curcol->column_prec = resinfo->columns[i]->column_prec;		curcol->column_scale = resinfo->columns[i]->column_scale;		curcol->column_namelen = resinfo->columns[i]->column_namelen;		curcol->on_server.column_type = resinfo->columns[i]->on_server.column_type;		curcol->on_server.column_size = resinfo->columns[i]->on_server.column_size;		curcol->char_conv = resinfo->columns[i]->char_conv;		memcpy(curcol->column_name, resinfo->columns[i]->column_name, resinfo->columns[i]->column_namelen);		if (curcol->table_column_name)			TDS_ZERO_FREE(curcol->table_column_name);		if (resinfo->columns[i]->table_column_name)			curcol->table_column_name = strdup(resinfo->columns[i]->table_column_name);		curcol->column_nullable = resinfo->columns[i]->column_nullable;		curcol->column_identity = resinfo->columns[i]->column_identity;		curcol->column_timestamp = resinfo->columns[i]->column_timestamp;		memcpy(curcol->column_collation, resinfo->columns[i]->column_collation, 5);		if (is_numeric_type(curcol->column_type)) {			curcol->bcp_column_data = tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC));			((TDS_NUMERIC *) curcol->bcp_column_data->data)->precision = curcol->column_prec;			((TDS_NUMERIC *) curcol->bcp_column_data->data)->scale = curcol->column_scale;		} else {			curcol->bcp_column_data = tds_alloc_bcp_column_data(curcol->on_server.column_size);		}	}	/* TODO check */	tds_alloc_row(bindinfo);	blkdesc->bindinfo = bindinfo;	blkdesc->bind_count = CS_UNUSED;	if (blkdesc->identity_insert_on) {		if (tds_submit_queryf(tds, "set identity_insert %s on", blkdesc->tablename) == TDS_FAIL) {			_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");			return CS_FAIL;		}			while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))			   == TDS_SUCCEED) {		}		if (rc != TDS_NO_MORE_RESULTS) {			_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");			return CS_FAIL;		}	}	return CS_SUCCEED;}CS_RETCODEblk_props(CS_BLKDESC * blkdesc, CS_INT action, CS_INT property, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen){	int retval;	int intval;	switch (property) {	case BLK_IDENTITY: 		switch (action) {		case CS_SET: 			if (buffer) {				memcpy(&intval, buffer, sizeof(intval));				if (intval == CS_TRUE)					blkdesc->identity_insert_on = 1;				if (intval == CS_FALSE)					blkdesc->identity_insert_on = 0;			}			return CS_SUCCEED;			break;		case CS_GET:			retval = blkdesc->identity_insert_on == 1 ? CS_TRUE : CS_FALSE ;			if (buffer) {				memcpy (buffer, &retval, sizeof(retval));				if (outlen)					*outlen = sizeof(retval);			}			return CS_SUCCEED;			break;		default:			_ctclient_msg(blkdesc->con, "blk_props", 2, 5, 1, 141, "%s, %d", "action", action);			break;		}		break;	default:		_ctclient_msg(blkdesc->con, "blk_props", 2, 5, 1, 141, "%s, %d", "property", property);		break;	}	return CS_FAIL;}CS_RETCODEblk_rowalloc(SRV_PROC * srvproc, CS_BLK_ROW ** row){	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_rowalloc()\n");	return CS_FAIL;}CS_RETCODEblk_rowdrop(SRV_PROC * srvproc, CS_BLK_ROW * row){	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_rowdrop()\n");	return CS_FAIL;}CS_RETCODEblk_rowxfer(CS_BLKDESC * blkdesc){	CS_INT row_count = 1;

⌨️ 快捷键说明

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