freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
- From: "Mark J. Lilback" <mark AT lilback.com>
- To: freetds mailing list <freetds AT franklin.oit.unc.edu>
- Subject: some patches to 0.53pre1
- Date: Tue, 6 Nov 2001 21:51:11 -0500
Since strlen's been mentioned recently... does anyone else have problems compiling because strlen is being passed unsigned chars? The same goes for all the other str functions.
The Metrowerks compiler complains about this, and I've manually added casts all over the place. This doesn't cause warnings or errors for anyone else?
Here's a number of patches for changes I've made that fix bugs and add missing features.
*** /Users/mlilback/ftds/src/tds/convert.c Tue Nov 6 21:00:12 2001
--- convert.c Thu Jul 12 19:16:10 2001
***************
*** 209,215 ****
memcpy(varbin->array, src, cplen);
return sizeof(TDS_VARBINARY);
}
- return TDS_FAIL;
}
TDS_INT tds_convert_char(int srctype,unsigned char *src,
--- 209,214 ----
***************
*** 492,498 ****
dmoney = (TDS_FLOAT)high * 65536 * 65536 + (TDS_FLOAT)low;
dmoney = dmoney / 10000;
*(TDS_FLOAT *)dest = dmoney;
- return sizeof(TDS_FLOAT); /* added by mlilback -- why returning fail? */
break;
case SYBMONEY:
memcpy(dest, src, sizeof(TDS_MONEY));
--- 491,496 ----
*** /Users/mlilback/ftds/src/tds/numeric.c Wed May 16 21:07:24 2001
--- numeric.c Thu Jun 21 14:56:33 2001
***************
*** 190,193 ****
--- 190,194 ----
s[j++]=array[i]+'0';
}
s[j]='\0';
+ return s;
}
*** /Users/mlilback/ftds/include/tds.h Thu Sep 27 08:09:41 2001
--- include/tds.h Fri Aug 31 08:02:36 2001
***************
*** 410,415 ****
--- 375,384 ----
TDS_CHAR column_textptr[16];
TDS_CHAR column_timestamp[8];
TDS_CHAR *column_textvalue;
+ TDS_TINYINT column_nullable;
+ TDS_TINYINT column_writeable;
+ TDS_TINYINT column_identity;
+ TDS_INT cur_row_size; /* size of this col in the current row */
} TDSCOLINFO;
typedef struct tds_result_info {
*** /Users/mlilback/ftds/src/tds/token.c Sun Sep 23 09:20:45 2001
--- token.c Fri Aug 31 08:01:07 2001
***************
*** 26,36 ****
/*
** All these functions process the input from the wire so it
** may be used by the upper level functions.
*/
! int (*g_tds_msg_handler)() = NULL;
! int (*g_tds_err_handler)() = NULL;
static int tds_process_msg(TDSSOCKET *tds,int marker);
--- 26,36 ----
/*
** All these functions process the input from the wire so it
** may be used by the upper level functions.
*/
! int (*g_tds_msg_handler)(void*) = NULL;
! int (*g_tds_err_handler)(void*) = NULL;
static int tds_process_msg(TDSSOCKET *tds,int marker);
***************
*** 436,442 ****
/* XXX this 4 should be a machine dependent #define */
int align = 4;
int remainder;
!
hdrsize = tds_get_smallint(tds);
--- 424,430 ----
/* XXX this 4 should be a machine dependent #define */
int align = 4;
int remainder;
! char ci_flags[4];
hdrsize = tds_get_smallint(tds);
***************
*** 444,450 ****
for (col=0; col<info->num_cols; col++)
{
curcol=info->columns[col];
! tds_get_n(tds, NULL, 4);
curcol->column_type = tds_get_byte(tds);
if (is_blob_type(curcol->column_type)) {
curcol->column_size = tds_get_int(tds);
--- 432,444 ----
for (col=0; col<info->num_cols; col++)
{
curcol=info->columns[col];
! /* mlilback -- used to ignore next 4 bytes, now we'll
actually
! parse the data in them (or some of it) */
! tds_get_n(tds, ci_flags, 4);
! curcol->column_nullable = ci_flags[3] & 0x01;
! curcol->column_writeable = (ci_flags[3] & 0x08) > 0;
! curcol->column_identity = (ci_flags[3] & 0x10) > 0;
! /* on with our regularly scheduled code */
curcol->column_type = tds_get_byte(tds);
if (is_blob_type(curcol->column_type)) {
curcol->column_size = tds_get_int(tds);
***************
*** 903,908 ****
--- 897,904 ----
tdsdump_log(TDS_DBG_INFO1, "%L datetime4 %d %d %d %d\n", dest[0], dest[1], dest[2], dest[3]);
}
+ //added by mlilback -- used to properly know value in dbdatlen
+ curcol->cur_row_size = colsize;
#ifdef WORDS_BIGENDIAN
/* MS SQL Server 7.0 has broken date types from big endian
** machines, this swaps the low and high halves of the
***************
*** 919,926 ****
curcol->column_type == SYBDATETIMN ||
curcol->column_type == SYBMONEY ||
curcol->column_type == SYBMONEY4 ||
! curcol->column_type == SYBMONEYN)) {
memcpy(temp_buf,dest,colsize/2);
memcpy(dest,&dest[colsize/2],colsize/2);
memcpy(&dest[colsize/2],temp_buf,colsize/2);
}
--- 915,925 ----
curcol->column_type == SYBDATETIMN ||
curcol->column_type == SYBMONEY ||
curcol->column_type == SYBMONEY4 ||
! (curcol->column_type == SYBMONEYN && curcol->column_size > 4)))
! /* above line changed by mlilback -- don't want this for 4 byte SYBMONEYN values */
! {
memcpy(temp_buf,dest,colsize/2);
memcpy(dest,&dest[colsize/2],colsize/2);
memcpy(&dest[colsize/2],temp_buf,colsize/2);
}
***************
*** 1113,1119 ****
len = tds_get_smallint(tds);
/* message number */
! tds->msg_info->msg_number = tds_get_int(tds);
/* msg state */
tds->msg_info->msg_state = tds_get_byte(tds);
--- 1164,1174 ----
len = tds_get_smallint(tds);
/* message number */
! rc = tds_get_int(tds);
! #ifdef WORDS_BIGENDIAN
! tds_swap_bytes(&rc, 4);
! #endif
! tds->msg_info->msg_number = rc;
/* msg state */
tds->msg_info->msg_state = tds_get_byte(tds);
*** /Users/mlilback/ftds/include/sybdb.h Sun Jul 1 20:57:40 2001
--- include/sybdb.h Sun Apr 8 20:00:34 2001
***************
*** 142,147 ****
--- 142,153 ----
TDS_TINYINT db_scale;
} BCP_COLINFO;
+ typedef struct dbtypeinfo
+ {
+ DBINT precision;
+ DBINT scale;
+ } DBTYPEINFO;
+
typedef struct {
TDSSOCKET *tds_socket ;
***************
*** 161,166 ****
--- 167,173 ----
TDS_INT bcp_direction;
TDS_INT bcp_colcount;
BCP_COLINFO **bcp_columns;
+ DBTYPEINFO typeinfo;
} DBPROCESS;
typedef struct dbdaterec
***************
*** 190,201 ****
#endif
} DBDATEREC;
- typedef struct dbtypeinfo
- {
- DBINT precision;
- DBINT scale;
- } DBTYPEINFO;
-
typedef int (*EHANDLEFUNC) (DBPROCESS *dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
typedef int (*MHANDLEFUNC) (DBPROCESS *dbproc, int msgno, int msgstate, int severity, char *msgtext, char *srvname, char *proc, int line);
--- 197,202 ----
***************
*** 459,464 ****
--- 459,465 ----
extern RETCODE dbsqlexec(DBPROCESS *dbproc);
extern int dbnumcols(DBPROCESS *dbproc);
extern DBINT dbcollen(DBPROCESS *dbproc, int column);
+ extern DBTYPEINFO *dbcoltypeinfo(DBPROCESS *dbproc, int column);
extern char *dbprtype(int token);
extern RETCODE dbbind(DBPROCESS *dbproc, int column, int vartype,
DBINT varlen, BYTE *varaddr);
***************
*** 479,484 ****
--- 480,494 ----
extern RETCODE dbsprhead(DBPROCESS *dbproc,char *buffer, DBINT buf_len);
extern char *dbversion();
extern RETCODE dbcanquery(DBPROCESS *dbproc);
+
+ /* added by mlilback to allow propery error handling */
+ typedef int (*dberrhandle_func)(DBPROCESS *dbproc, int severity, int dberr,
+ int oserr, char *dberrstr, char *oserrstr);
+ typedef int (*dbmsghandle_func)(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severity,
+ char *msgtext, char *srvname, char *procname, int line);
+
+ extern dberrhandle_func dberrhandler(dberrhandle_func
handler);
+ extern dbmsghandle_func dbmsghandler(dbmsghandle_func
handler);
*** /Users/mlilback/ftds/src/dblib/dblib.c Sat Jun 9 19:48:48 2001
--- dblib.c Fri Aug 31 07:59:23 2001
***************
*** 41,48 ****
int (*g_dblib_msg_handler)() = NULL;
int (*g_dblib_err_handler)() = NULL;
TDSCONTEXT *g_tds_context = NULL;
! extern int (*g_tds_msg_handler)();
! extern int (*g_tds_err_handler)();
#ifdef TDS42
int g_dblib_version = DBVERSION_42;
#endif
--- 44,51 ----
int (*g_dblib_msg_handler)() = NULL;
int (*g_dblib_err_handler)() = NULL;
TDSCONTEXT *g_tds_context = NULL;
! extern int (*g_tds_msg_handler)(void*);
! extern int (*g_tds_err_handler)(void*);
#ifdef TDS42
int g_dblib_version = DBVERSION_42;
#endif
***************
*** 401,406 ****
--- 404,410 ----
RETCODE DBSETLCHARSET(LOGINREC *login, char *charset)
{
tds_set_charset(login->tds_login,charset);
+ return SUCCEED;
}
RETCODE DBSETLPACKET(LOGINREC *login, short packet_size)
{
***************
*** 450,455 ****
--- 454,460 ----
tds_add_connection(g_tds_context, dbproc->tds_socket);
} else {
fprintf(stderr,"DB-Library: Login incorrect.\n");
+ free(dbproc); /* mlilback -- memory leak fix */
return NULL;
}
***************
*** 983,989 ****
else if (colinfo->column_size==4)
return SYBDATETIME4;
case SYBMONEYN:
! return SYBMONEY;
case SYBFLTN:
if (colinfo->column_size==8)
return SYBFLT8;
--- 988,998 ----
else if (colinfo->column_size==4)
return SYBDATETIME4;
case SYBMONEYN:
! //patch by mlilback -- need to be based on size of column
! if (colinfo->column_size==4)
! return SYBMONEY4;
! else
! return SYBMONEY;
case SYBFLTN:
if (colinfo->column_size==8)
return SYBFLT8;
***************
*** 1003,1012 ****
}
DBTYPEINFO *dbcoltypeinfo(DBPROCESS *dbproc, int column)
{
! /* FIXME -- this is not thread safe, we would need to move typeinfo into
! ** the dbproc structure, however that seems a waste for such a little used
! ** function...maybe malloc it when used, cleanup on dbclose() */
! static DBTYPEINFO typeinfo;
TDSCOLINFO * colinfo;
TDSRESULTINFO * resinfo;
TDSSOCKET * tds;
--- 1012,1018 ----
}
DBTYPEINFO *dbcoltypeinfo(DBPROCESS *dbproc, int column)
{
! /** mlilback -- moved typeinfo from static into dbproc to make thread safe
*/
TDSCOLINFO * colinfo;
TDSRESULTINFO * resinfo;
TDSSOCKET * tds;
***************
*** 1014,1022 ****
tds = (TDSSOCKET *) dbproc->tds_socket;
resinfo = tds->res_info;
colinfo = resinfo->columns[column-1];
! typeinfo.precision = colinfo->column_prec;
! typeinfo.scale = colinfo->column_scale;
! return &typeinfo;
}
char *dbcolsource(DBPROCESS *dbproc,int colnum)
{
--- 1020,1028 ----
tds = (TDSSOCKET *) dbproc->tds_socket;
resinfo = tds->res_info;
colinfo = resinfo->columns[column-1];
! dbproc->typeinfo.precision = colinfo->column_prec;
! dbproc->typeinfo.scale = colinfo->column_scale;
! return &dbproc->typeinfo;
}
char *dbcolsource(DBPROCESS *dbproc,int colnum)
{
***************
*** 1048,1061 ****
TDSSOCKET * tds;
DBINT ret;
! /* FIX ME -- this is the columns info, need per row info */
tds = (TDSSOCKET *) dbproc->tds_socket;
resinfo = tds->res_info;
if (column<1 || column>resinfo->num_cols) return -1;
colinfo = resinfo->columns[column-1];
tdsdump_log(TDS_DBG_INFO1, "%L dbdatlen() type = %d\n",colinfo->column_type);
! if (tds_get_null(resinfo->current_row,column-1)) {
tdsdump_log(TDS_DBG_FUNC, "%L leaving dbdatlen() returning 0\n");
return 0;
} else if (colinfo->column_type==SYBVARCHAR) {
--- 1054,1073 ----
TDSSOCKET * tds;
DBINT ret;
! /* FIX ME -- this is the columns info, need per row info
! 3/4/01 -- mlilback -- I think I fixed this. Added cur_row_size field to colinfo,
! and it gets filled in by process_row in token.c
! */
tds = (TDSSOCKET *) dbproc->tds_socket;
resinfo = tds->res_info;
if (column<1 || column>resinfo->num_cols) return -1;
colinfo = resinfo->columns[column-1];
tdsdump_log(TDS_DBG_INFO1, "%L dbdatlen() type = %d\n",colinfo->column_type);
! if (tds_get_null(resinfo->current_row,column-1))
! return 0;
! return colinfo->cur_row_size;
! /* if (tds_get_null(resinfo->current_row,column-1)) {
tdsdump_log(TDS_DBG_FUNC, "%L leaving dbdatlen() returning 0\n");
return 0;
} else if (colinfo->column_type==SYBVARCHAR) {
***************
*** 1071,1077 ****
tdsdump_log(TDS_DBG_FUNC, "%L leaving dbdatlen() returning %d\n",ret);
return ret;
}
! }
BYTE *dbdata(DBPROCESS *dbproc, int column)
{
TDSCOLINFO * colinfo;
--- 1083,1089 ----
tdsdump_log(TDS_DBG_FUNC, "%L leaving dbdatlen() returning %d\n",ret);
return ret;
}
! */}
BYTE *dbdata(DBPROCESS *dbproc, int column)
{
TDSCOLINFO * colinfo;
***************
*** 1542,1547 ****
--- 1554,1567 ----
return TRUE;
}
+ dberrhandle_func
+ dberrhandler(dberrhandle_func inHandler)
+ {
+ dberrhandle_func old = (dberrhandle_func)g_dblib_err_handler;
+ g_dblib_err_handler = (int(*)())inHandler;
+ return old;
+ }
+
int (*dberrhandle(int (*handler)())) ()
{
int (*retFun)() = g_dblib_err_handler;
***************
*** 1550,1555 ****
--- 1570,1583 ----
return retFun;
}
+ dbmsghandle_func
+ dbmsghandler(dbmsghandle_func inHandler)
+ {
+ dbmsghandle_func old = (dbmsghandle_func)g_dblib_msg_handler;
+ g_dblib_msg_handler = (int(*)())inHandler;
+ return old;
+ }
+
int (*dbmsghandle(int (*handler)()))()
{
int (*retFun)() = g_dblib_msg_handler;
***************
*** 1657,1662 ****
--- 1685,1694 ----
int millis;
secs_from_epoch = ((dt->dtdays - 25567)*24*60*60) + (dt->dttime/300);
+ /* GUSI2 (networking kit on Mac OS 8/9) uses Jan 1, 1904 as the epoch (like OS does). */
+ #ifdef GUSI2
+ secs_from_epoch += ((365L * 66L) + 17) * 24L * 60L * 60L;
+ #endif
millis = dt->dttime%300;
t = (struct tm *) gmtime(&secs_from_epoch);
#ifndef MSDBLIB
--
__________________________________________________________________________
"They that can give up essential liberty
Mark J. Lilback to obtain a little temporary safety
<mark AT lilback.com> deserve neither liberty or safety."
http://www.lilback.com/ -- Benjamin Franklin
-
some patches to 0.53pre1,
Mark J. Lilback, 11/06/2001
- <Possible follow-up(s)>
- Re: some patches to 0.53pre1, Brian Bruns, 11/06/2001
- Re: some patches to 0.53pre1, Norman Palardy, 11/06/2001
- Re: some patches to 0.53pre1, Mark J. Lilback, 11/07/2001
Archive powered by MHonArc 2.6.24.