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

📄 odbc_util.c

📁 在Linux/Unix下面访问WINDOWS SQLSERVER 的ODBC驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
	case SQL_VARBINARY:	case SQL_LONGVARBINARY:		size = col->column_size * 2;		break;	case SQL_BIGINT:		size = 20;		break;	case SQL_INTEGER:		size = 11;	/* -1000000000 */		break;	case SQL_SMALLINT:		size = 6;	/* -10000 */		break;	case SQL_BIT:		size = 1;		break;	case SQL_TINYINT:		size = 3;	/* 255 */		break;	case SQL_DECIMAL:	case SQL_NUMERIC:		size = col->column_prec + 2;		break;	case SQL_DATE:		/* FIXME check always yyyy-mm-dd ?? */		size = 19;		break;	case SQL_TIME:		/* FIXME check always hh:mm:ss[.fff] */		size = 19;		break;	case SQL_TYPE_TIMESTAMP:	case SQL_TIMESTAMP:		/* TODO dependent on precision (decimal second digits) */		/* we always format using yyyy-mm-dd hh:mm:ss[.fff], see convert_tds2sql.c */		size = 19;		if (col->column_type == SYBDATETIME || (col->column_type == SYBDATETIMN && col->column_size == 8))			size = 23;		break;	case SQL_FLOAT:	case SQL_REAL:	case SQL_DOUBLE:		/* TODO check REAL/FLOAT format */		if (col->column_type == SYBREAL || (col->column_type == SYBFLTN && col->column_size == 4))			size = 14;		/* TODO check money format returned by propretary ODBC, scale == 4 but we use 2 digits */		else if (col->column_type == SYBMONEY || (col->column_type == SYBMONEYN && col->column_size == 8))			size = 21;		else if (col->column_type == SYBMONEY4 || (col->column_type == SYBMONEYN && col->column_size == 4))			size = 12;		else 			size = 24;	/* FIXME -- what should the correct size be? */		break;#ifdef SQL_GUID	case SQL_GUID:		size = 36;		break;#endif	default:		/* FIXME TODO finish, should support ALL types (interval, binary) */		size = 40;		tdsdump_log(TDS_DBG_INFO1, "odbc_sql_to_displaysize: unknown sql type %d\n", (int) sqltype);		break;	}	return size;}intodbc_sql_to_c_type_default(int sql_type){	switch (sql_type) {	case SQL_CHAR:	case SQL_VARCHAR:	case SQL_LONGVARCHAR:		return SQL_C_CHAR;		/* for compatibility numeric are converted to CHAR, not to structure */	case SQL_DECIMAL:	case SQL_NUMERIC:		return SQL_C_CHAR;#ifdef SQL_GUID	case SQL_GUID:		/* TODO return SQL_C_CHAR for Sybase ?? */		return SQL_C_GUID;#endif	case SQL_BIT:		return SQL_C_BIT;	case SQL_TINYINT:		return SQL_C_UTINYINT;	case SQL_SMALLINT:		return SQL_C_SSHORT;	case SQL_INTEGER:		return SQL_C_SLONG;	case SQL_BIGINT:		return SQL_C_SBIGINT;	case SQL_REAL:		return SQL_C_FLOAT;	case SQL_FLOAT:	case SQL_DOUBLE:		return SQL_C_DOUBLE;	case SQL_DATE:	case SQL_TYPE_DATE:		return SQL_C_TYPE_DATE;	case SQL_TIME:	case SQL_TYPE_TIME:		return SQL_C_TYPE_TIME;	case SQL_TIMESTAMP:	case SQL_TYPE_TIMESTAMP:		return SQL_C_TYPE_TIMESTAMP;	case SQL_BINARY:	case SQL_VARBINARY:	case SQL_LONGVARBINARY:		return SQL_C_BINARY;		/* TODO interval types */	default:		return 0;	}}intodbc_sql_to_server_type(TDSSOCKET * tds, int sql_type){	switch (sql_type) {	case SQL_CHAR:		return SYBCHAR;	case SQL_VARCHAR:		return SYBVARCHAR;	case SQL_LONGVARCHAR:		return SYBTEXT;	case SQL_DECIMAL:		return SYBDECIMAL;	case SQL_NUMERIC:		return SYBNUMERIC;#ifdef SQL_GUID	case SQL_GUID:		if (IS_TDS7_PLUS(tds))			return SYBUNIQUE;		return 0;#endif	case SQL_BIT:		if (IS_TDS7_PLUS(tds))			return SYBBITN;		return SYBBIT;	case SQL_TINYINT:		return SYBINT1;	case SQL_SMALLINT:		return SYBINT2;	case SQL_INTEGER:		return SYBINT4;	case SQL_BIGINT:		return SYBINT8;	case SQL_REAL:		return SYBREAL;	case SQL_FLOAT:	case SQL_DOUBLE:		return SYBFLT8;		/* ODBC version 2 */	case SQL_DATE:	case SQL_TIME:	case SQL_TIMESTAMP:		/* ODBC version 3 */	case SQL_TYPE_DATE:	case SQL_TYPE_TIME:	case SQL_TYPE_TIMESTAMP:		return SYBDATETIME;	case SQL_BINARY:		return SYBBINARY;	case SQL_VARBINARY:		return SYBVARBINARY;	case SQL_LONGVARBINARY:		return SYBIMAGE;		/* TODO interval types */	default:		return 0;	}}/** * Copy a string to client setting size according to ODBC convenction * @param buffer    client buffer * @param cbBuffer  client buffer size (in bytes) * @param pcbBuffer pointer to SQLSMALLINT to hold string size * @param s         string to copy * @param len       len of string to copy. <0 null terminated */SQLRETURNodbc_set_string(SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len){	SQLRETURN result = SQL_SUCCESS;	if (len < 0)		len = strlen(s);	if (pcbBuffer)		*pcbBuffer = len;	if (len >= cbBuffer) {		len = cbBuffer - 1;		result = SQL_SUCCESS_WITH_INFO;	}	if (buffer && len >= 0) {		/* buffer can overlap, use memmove, thanks to Valgrind */		memmove((char *) buffer, s, len);		((char *) buffer)[len] = 0;	}	return result;}SQLRETURNodbc_set_string_i(SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len){	SQLRETURN result = SQL_SUCCESS;	if (len < 0)		len = strlen(s);	if (pcbBuffer)		*pcbBuffer = len;	if (len >= cbBuffer) {		len = cbBuffer - 1;		result = SQL_SUCCESS_WITH_INFO;	}	if (buffer && len >= 0) {		/* buffer can overlap, use memmove, thanks to Valgrind */		memmove((char *) buffer, s, len);		((char *) buffer)[len] = 0;	}	return result;}/** Returns the version of the RDBMS in the ODBC format */voidodbc_rdbms_version(TDSSOCKET * tds, char *pversion_string){	sprintf(pversion_string, "%.02d.%.02d.%.04d", (int) ((tds->product_version & 0x7F000000) >> 24),		(int) ((tds->product_version & 0x00FF0000) >> 16), (int) (tds->product_version & 0x0000FFFF));}/** Return length of parameter from parameter information */SQLINTEGERodbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_ixd, const TDS_DESC* axd, unsigned int n_row){	SQLINTEGER len;	int size;	TDS_INTPTR len_offset;	if (axd->header.sql_desc_bind_type != SQL_BIND_BY_COLUMN) {		len_offset = axd->header.sql_desc_bind_type * n_row;		if (axd->header.sql_desc_bind_offset_ptr)			len_offset += *axd->header.sql_desc_bind_offset_ptr;	} else {		len_offset = sizeof(SQLLEN) * n_row;	}#define LEN(ptr) *((SQLLEN*)(((char*)(ptr)) + len_offset))	if (drec_axd->sql_desc_indicator_ptr && LEN(drec_axd->sql_desc_indicator_ptr) == SQL_NULL_DATA)		len = SQL_NULL_DATA;	else if (drec_axd->sql_desc_octet_length_ptr)		len = LEN(drec_axd->sql_desc_octet_length_ptr);	else {		len = 0;		/* TODO add XML if defined */		/* FIXME, other types available */		if (drec_axd->sql_desc_concise_type == SQL_C_CHAR || drec_axd->sql_desc_concise_type == SQL_C_BINARY) {			len = SQL_NTS;		} else {			int type = drec_axd->sql_desc_concise_type;			if (type == SQL_C_DEFAULT)				type = odbc_sql_to_c_type_default(drec_ixd->sql_desc_concise_type);			type = odbc_c_to_server_type(type);			/* FIXME check what happen to DATE/TIME types */			size = tds_get_size_by_type(type);			if (size > 0)				len = size;		}	}	return len;#undef LEN}#ifdef SQL_GUID# define TYPE_NORMAL_SQL_GUID TYPE_NORMAL(SQL_GUID)#else# define TYPE_NORMAL_SQL_GUID#endif#define SQL_TYPES \	TYPE_NORMAL(SQL_BIT) \	TYPE_NORMAL(SQL_SMALLINT) \	TYPE_NORMAL(SQL_TINYINT) \	TYPE_NORMAL(SQL_INTEGER) \	TYPE_NORMAL(SQL_BIGINT) \\	TYPE_NORMAL_SQL_GUID \\	TYPE_NORMAL(SQL_BINARY) \	TYPE_NORMAL(SQL_VARBINARY) \	TYPE_NORMAL(SQL_LONGVARBINARY) \\	TYPE_NORMAL(SQL_CHAR) \	TYPE_NORMAL(SQL_VARCHAR) \	TYPE_NORMAL(SQL_LONGVARCHAR) \\	TYPE_NORMAL(SQL_DECIMAL) \	TYPE_NORMAL(SQL_NUMERIC) \\	TYPE_NORMAL(SQL_FLOAT) \	TYPE_NORMAL(SQL_REAL) \	TYPE_NORMAL(SQL_DOUBLE)\\	TYPE_VERBOSE_START(SQL_DATETIME) \	TYPE_VERBOSE_DATE(SQL_DATETIME, SQL_CODE_TIMESTAMP, SQL_TYPE_TIMESTAMP, SQL_TIMESTAMP) \	TYPE_VERBOSE_END(SQL_DATETIME)SQLSMALLINTodbc_get_concise_sql_type(SQLSMALLINT type, SQLSMALLINT interval){#define TYPE_NORMAL(t) case t: return type;#define TYPE_VERBOSE_START(t) \	case t: switch (interval) {#define TYPE_VERBOSE_DATE(t, interval, concise, old) \	case interval: return concise;#define TYPE_VERBOSE_END(t) \	}	switch (type) {		SQL_TYPES;	}	return 0;#undef TYPE_NORMAL#undef TYPE_VERBOSE_START#undef TYPE_VERBOSE_DATE#undef TYPE_VERBOSE_END}/** * Set concise type and all cascading field. * @param concise_type concise type to set * @param drec         record to set. NULL to test error without setting * @param check_only   it <>0 (true) check only, do not set type */SQLRETURNodbc_set_concise_sql_type(SQLSMALLINT concise_type, struct _drecord * drec, int check_only){	SQLSMALLINT type = concise_type, interval_code = 0;#define TYPE_NORMAL(t) case t: break;#define TYPE_VERBOSE_START(t)#define TYPE_VERBOSE_DATE(t, interval, concise, old) \	case old: concise_type = concise; \	case concise: type = t; interval_code = interval; break;#define TYPE_VERBOSE_END(t)	switch (type) {		SQL_TYPES;	default:		return SQL_ERROR;	}	if (!check_only) {		drec->sql_desc_concise_type = concise_type;		drec->sql_desc_type = type;		drec->sql_desc_datetime_interval_code = interval_code;		switch (drec->sql_desc_type) {		case SQL_NUMERIC:		case SQL_DECIMAL:			drec->sql_desc_precision = 38;			drec->sql_desc_scale = 0;			break;			/* TODO finish */		}	}	return SQL_SUCCESS;#undef TYPE_NORMAL#undef TYPE_VERBOSE_START#undef TYPE_VERBOSE_DATE#undef TYPE_VERBOSE_END}#ifdef SQL_C_GUID# define TYPE_NORMAL_SQL_C_GUID TYPE_NORMAL(SQL_C_GUID)#else# define TYPE_NORMAL_SQL_C_GUID#endif#define C_TYPES \	TYPE_NORMAL(SQL_C_BIT) \	TYPE_NORMAL(SQL_C_SHORT) \	TYPE_NORMAL(SQL_C_TINYINT) \	TYPE_NORMAL(SQL_C_UTINYINT) \	TYPE_NORMAL(SQL_C_STINYINT) \	TYPE_NORMAL(SQL_C_LONG) \	TYPE_NORMAL(SQL_C_SBIGINT) \	TYPE_NORMAL(SQL_C_UBIGINT) \	TYPE_NORMAL(SQL_C_SSHORT) \	TYPE_NORMAL(SQL_C_SLONG) \	TYPE_NORMAL(SQL_C_USHORT) \	TYPE_NORMAL(SQL_C_ULONG) \\	TYPE_NORMAL_SQL_C_GUID \	TYPE_NORMAL(SQL_C_DEFAULT) \\	TYPE_NORMAL(SQL_C_BINARY) \\	TYPE_NORMAL(SQL_C_CHAR) \\	TYPE_NORMAL(SQL_C_NUMERIC) \\	TYPE_NORMAL(SQL_C_FLOAT) \	TYPE_NORMAL(SQL_C_DOUBLE)\\	TYPE_VERBOSE_START(SQL_DATETIME) \	TYPE_VERBOSE_DATE(SQL_DATETIME, SQL_CODE_DATE, SQL_C_TYPE_DATE, SQL_C_DATE) \	TYPE_VERBOSE_DATE(SQL_DATETIME, SQL_CODE_TIME, SQL_C_TYPE_TIME, SQL_C_TIME) \	TYPE_VERBOSE_DATE(SQL_DATETIME, SQL_CODE_TIMESTAMP, SQL_C_TYPE_TIMESTAMP, SQL_C_TIMESTAMP) \	TYPE_VERBOSE_END(SQL_DATETIME) \\	TYPE_VERBOSE_START(SQL_INTERVAL) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_DAY, SQL_C_INTERVAL_DAY) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_DAY_TO_HOUR, SQL_C_INTERVAL_DAY_TO_HOUR) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_DAY_TO_MINUTE, SQL_C_INTERVAL_DAY_TO_MINUTE) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_DAY_TO_SECOND, SQL_C_INTERVAL_DAY_TO_SECOND) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_HOUR, SQL_C_INTERVAL_HOUR) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_HOUR_TO_MINUTE, SQL_C_INTERVAL_HOUR_TO_MINUTE) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_HOUR_TO_SECOND, SQL_C_INTERVAL_HOUR_TO_SECOND) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_MINUTE, SQL_C_INTERVAL_MINUTE) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_MINUTE_TO_SECOND, SQL_C_INTERVAL_MINUTE_TO_SECOND) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_MONTH, SQL_C_INTERVAL_MONTH) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_SECOND, SQL_C_INTERVAL_SECOND) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_YEAR, SQL_C_INTERVAL_YEAR) \	TYPE_VERBOSE(SQL_INTERVAL, SQL_CODE_YEAR_TO_MONTH, SQL_C_INTERVAL_YEAR_TO_MONTH) \	TYPE_VERBOSE_END(SQL_INTERVAL)SQLSMALLINTodbc_get_concise_c_type(SQLSMALLINT type, SQLSMALLINT interval){#define TYPE_NORMAL(t) case t: return type;#define TYPE_VERBOSE_START(t) \	case t: switch (interval) {#define TYPE_VERBOSE(t, interval, concise) \	case interval: return concise;#define TYPE_VERBOSE_DATE(t, interval, concise, old) \	case interval: return concise;#define TYPE_VERBOSE_END(t) \	}	switch (type) {		C_TYPES;	}	return 0;#undef TYPE_NORMAL#undef TYPE_VERBOSE_START#undef TYPE_VERBOSE#undef TYPE_VERBOSE_DATE#undef TYPE_VERBOSE_END}/** * Set concise type and all cascading field. * @param concise_type concise type to set * @param drec         record to set. NULL to test error without setting * @param check_only   it <>0 (true) check only, do not set type */SQLRETURNodbc_set_concise_c_type(SQLSMALLINT concise_type, struct _drecord * drec, int check_only){	SQLSMALLINT type = concise_type, interval_code = 0;#define TYPE_NORMAL(t) case t: break;#define TYPE_VERBOSE_START(t)#define TYPE_VERBOSE(t, interval, concise) \	case concise: type = t; interval_code = interval; break;#define TYPE_VERBOSE_DATE(t, interval, concise, old) \	case concise: type = t; interval_code = interval; break; \	case old: concise_type = concise; type = t; interval_code = interval; break;#define TYPE_VERBOSE_END(t)	switch (type) {		C_TYPES;	default:		return SQL_ERROR;	}	if (!check_only) {		drec->sql_desc_concise_type = concise_type;		drec->sql_desc_type = type;		drec->sql_desc_datetime_interval_code = interval_code;		switch (drec->sql_desc_type) {		case SQL_C_NUMERIC:			drec->sql_desc_precision = 38;			drec->sql_desc_scale = 0;			break;			/* TODO finish */		}	}	return SQL_SUCCESS;#undef TYPE_NORMAL#undef TYPE_VERBOSE_START#undef TYPE_VERBOSE#undef TYPE_VERBOSE_DATE#undef TYPE_VERBOSE_END}SQLLENodbc_get_octet_len(int c_type, const struct _drecord *drec){	SQLLEN len;	/* this shit is mine -- freddy77 */	switch (c_type) {	case SQL_C_CHAR:	case SQL_C_BINARY:		len = drec->sql_desc_octet_length;		break;	case SQL_C_DATE:	case SQL_C_TYPE_DATE:		len = sizeof(DATE_STRUCT);		break;	case SQL_C_TIME:	case SQL_C_TYPE_TIME:		len = sizeof(TIME_STRUCT);		break;	case SQL_C_TIMESTAMP:	case SQL_C_TYPE_TIMESTAMP:		len = sizeof(TIMESTAMP_STRUCT);		break;	case SQL_C_NUMERIC:		len = sizeof(SQL_NUMERIC_STRUCT);		break;	default:		len = tds_get_size_by_type(odbc_c_to_server_type(c_type));		break;	}	return len;}/** @} */

⌨️ 快捷键说明

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