tdbc::odbc

Check-in [5289d1ce64]
Login
Bounty program for improvements to Tcl and certain Tcl packages.
Tcl 2019 Conference, Houston/TX, US, Nov 4-8
Send your abstracts to [email protected]
or submit via the online form by Sep 9.

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merge tdbcodbc-stwo.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 5289d1ce643e37be09810d072c676a7138912a7d
User & Date: stu 2017-05-23 19:35:31
Context
2017-05-26
14:36
Give the (U)INT2PTR / PTR2(U)INT macros .h file a more descriptive name and fully integrate them into the configure/build/dist. Remove old check for intptr types. Tidy some CPP bits to make them like the other tdbc-* modules. Fixes ticket [df3a7fd993]. check-in: 0e971d3716 user: stu tags: trunk
2017-05-23
19:35
Merge tdbcodbc-stwo. check-in: 5289d1ce64 user: stu tags: trunk
2017-05-20
01:21
Bring test env var names into alignment with the other TDBC drivers. env() -> ::env() Maybe TDBCODBC_TEST_TYPE is a bit vague? Closed-Leaf check-in: f0bb1d7449 user: stu tags: tdbcodbc-stwo
2017-05-04
19:07
TEA_INIT required bump to TEA 3.10 as well. check-in: a0030f73db user: dgp tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to configure.

2682
2683
2684
2685
2686
2687
2688

2689
2690
2691
2692
2693
2694
2695
2696
2697
....
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
....
9194
9195
9196
9197
9198
9199
9200











































9201
9202
9203
9204
9205
9206
9207
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \

			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/lib/tcl8.6 2>/dev/null` \
			`ls -d /usr/lib/tcl8.5 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
................................................................................
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
	    ;;
	OpenBSD-*)
	    arch=`arch -s`
	    case "$arch" in
	    vax)
		SHLIB_SUFFIX=""
		SHARED_LIB_SUFFIX=""
		LDFLAGS=""
		;;
	    *)
		case "$arch" in
		alpha|sparc64)
		    SHLIB_CFLAGS="-fPIC"
		    ;;
		*)
		    SHLIB_CFLAGS="-fpic"
		    ;;
		esac
		SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
		SHLIB_SUFFIX=".so"
		if test $doRpath = yes; then :

		    CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
		LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
		SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
		LDFLAGS="-Wl,-export-dynamic"
		;;
	    esac
	    case "$arch" in
	    vax)
		CFLAGS_OPTIMIZE="-O1"
		;;
	    *)
		CFLAGS_OPTIMIZE="-O2"
		;;
	    esac
	    if test "${TCL_THREADS}" = "1"; then :

		# On OpenBSD:	Compile with -pthread
		#		Don't link with -lpthread
		LIBS=`echo $LIBS | sed s/-lpthread//`
		CFLAGS="$CFLAGS -pthread"

................................................................................
$as_echo "enabled symbols mem debugging" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
$as_echo "enabled $tcl_ok debugging" >&6; }
	fi
    fi













































#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------






>

|







 







<
<
<
<
<
<
<
|
|
|
|
|
|
|
|
|
|

|

|
|
|
<
<
<
<
<
<
<
|
<
<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
....
7881
7882
7883
7884
7885
7886
7887







7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903







7904


7905
7906
7907
7908
7909
7910
7911
....
9179
9180
9181
9182
9183
9184
9185
9186
9187
9188
9189
9190
9191
9192
9193
9194
9195
9196
9197
9198
9199
9200
9201
9202
9203
9204
9205
9206
9207
9208
9209
9210
9211
9212
9213
9214
9215
9216
9217
9218
9219
9220
9221
9222
9223
9224
9225
9226
9227
9228
9229
9230
9231
9232
9233
9234
9235
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/lib/tcl8.6 2>/dev/null` \
			`ls -d /usr/lib/tcl8.5 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
................................................................................
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
		LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
	    ;;
	OpenBSD-*)
	    arch=`arch -s`
	    case "$arch" in







	    alpha|sparc64)
		SHLIB_CFLAGS="-fPIC"
		;;
	    *)
		SHLIB_CFLAGS="-fpic"
		;;
	    esac
	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
	    SHLIB_SUFFIX=".so"
	    if test $doRpath = yes; then :

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
	    LDFLAGS="-Wl,-export-dynamic"







	    CFLAGS_OPTIMIZE="-O2"


	    if test "${TCL_THREADS}" = "1"; then :

		# On OpenBSD:	Compile with -pthread
		#		Don't link with -lpthread
		LIBS=`echo $LIBS | sed s/-lpthread//`
		CFLAGS="$CFLAGS -pthread"

................................................................................
$as_echo "enabled symbols mem debugging" >&6; }
	else
	    { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
$as_echo "enabled $tcl_ok debugging" >&6; }
	fi
    fi


#--------------------------------------------------------------------
# INT2PTR  / PTR2INT  need to know about  intptr_t.
# UINT2PTR / PTR2UINT need to know about uintptr_t.
#--------------------------------------------------------------------


  ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
if test "x$ac_cv_type_intptr_t" = xyes; then :

$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h

else
  for ac_type in 'int' 'long int' 'long long int'; do
       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h.  */
$ac_includes_default
int
main ()
{
static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($ac_type))];
test_array [0] = 0;
return test_array [0];

  ;
  return 0;
}
_ACEOF
if ac_fn_c_try_compile "$LINENO"; then :

cat >>confdefs.h <<_ACEOF
#define intptr_t $ac_type
_ACEOF

	  ac_type=
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
       test -z "$ac_type" && break
     done
fi


#AC_TYPE_UINTPTR_T

#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------

Changes to configure.ac.

166
167
168
169
170
171
172








173
174
175
176
177
178
179
TEA_CONFIG_CFLAGS

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols option.
#--------------------------------------------------------------------

TEA_ENABLE_SYMBOLS









#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------






>
>
>
>
>
>
>
>







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
TEA_CONFIG_CFLAGS

#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols option.
#--------------------------------------------------------------------

TEA_ENABLE_SYMBOLS

#--------------------------------------------------------------------
# INT2PTR  / PTR2INT  need to know about  intptr_t.
# UINT2PTR / PTR2UINT need to know about uintptr_t.
#--------------------------------------------------------------------

AC_TYPE_INTPTR_T
#AC_TYPE_UINTPTR_T

#--------------------------------------------------------------------
# Everyone should be linking against the Tcl stub library.  If you
# can't for some reason, remove this definition.  If you aren't using
# stubs, you also need to modify the SHLIB_LD_LIBS setting below to
# link against the non-stubbed Tcl library.  Add Tk too if necessary.
#--------------------------------------------------------------------

Added generic/intptr_t.h.
















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * Macros used to cast between pointers and integers (e.g. when storing an int
 * in ClientData), on 64-bit architectures they avoid gcc warning about "cast
 * to/from pointer from/to integer of different size".
 */

#if !defined(INT2PTR) && !defined(PTR2INT)
#   if defined(HAVE_INTPTR_T) || defined(intptr_t)
#	define INT2PTR(p) ((void *)(intptr_t)(p))
#	define PTR2INT(p) ((int)(intptr_t)(p))
#   else
#	define INT2PTR(p) ((void *)(p))
#	define PTR2INT(p) ((int)(p))
#   endif
#endif
#if !defined(UINT2PTR) && !defined(PTR2UINT)
#   if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
#	define UINT2PTR(p) ((void *)(uintptr_t)(p))
#	define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
#   else
#	define UINT2PTR(p) ((void *)(p))
#	define PTR2UINT(p) ((unsigned int)(p))
#   endif
#endif

Changes to generic/odbcStubDefs.txt.

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# that the material in this file is not subject to copyright, under the
# doctrines of scenes a faire and of the merger of idea and expression.
# Accordingly, this file is in the public domain.
#
#-----------------------------------------------------------------------------

* STUBSTRUCT: odbcStubs
* LIBRARY: odbc32 odbc libodbc32 libodbc
* CONVENTION: SQL_API

SQLRETURN SQLAllocHandle(SQLSMALLINT,SQLHANDLE,SQLHANDLE*);
SQLRETURN SQLBindParameter(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
SQLRETURN SQLCloseCursor(SQLHSTMT);
SQLRETURN SQLColumnsW(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT ,SQLWCHAR*,SQLSMALLINT );
SQLRETURN SQLDataSourcesW(SQLHENV,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);






|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# that the material in this file is not subject to copyright, under the
# doctrines of scenes a faire and of the merger of idea and expression.
# Accordingly, this file is in the public domain.
#
#-----------------------------------------------------------------------------

* STUBSTRUCT: odbcStubs
* LIBRARY: odbc32 odbc libodbc32 libodbc libiodbc
* CONVENTION: SQL_API

SQLRETURN SQLAllocHandle(SQLSMALLINT,SQLHANDLE,SQLHANDLE*);
SQLRETURN SQLBindParameter(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
SQLRETURN SQLCloseCursor(SQLHSTMT);
SQLRETURN SQLColumnsW(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT ,SQLWCHAR*,SQLSMALLINT );
SQLRETURN SQLDataSourcesW(SQLHENV,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);

Changes to generic/odbcStubInit.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
 * odbcStubInit.c --
 *
 *	Stubs tables for the foreign ODBC libraries so that
 *	Tcl extensions can use them without the linker's knowing about them.
 *
 * @[email protected] 2015-06-26 13:54:02Z by genExtStubs.tcl from ../generic/odbcStubDefs.txt
 *
 * Copyright (c) 2010 by Kevin B. Kenny.
 *
 * Please refer to the file, 'license.terms' for the conditions on
 * redistribution of this file and for a DISCLAIMER OF ALL WARRANTIES.
 *
 *-----------------------------------------------------------------------------
................................................................................

/*
 * Names of the libraries that might contain the ODBC API
 */

static const char *const odbcStubLibNames[] = {
    /* @[email protected]: DO NOT EDIT THESE NAMES */
    "odbc32", "odbc", "libodbc32", "libodbc", NULL
    /* @[email protected] */
};
static const char *const odbcOptLibNames[] = {
    "odbccp", "odbccp32", "odbcinst",
    "libodbccp", "libodbccp32", "libodbcinst", NULL
};

/*
 * Names of the functions that we need from ODBC
 */

static const char *const odbcSymbolNames[] = {





|







 







|




|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/*
 * odbcStubInit.c --
 *
 *	Stubs tables for the foreign ODBC libraries so that
 *	Tcl extensions can use them without the linker's knowing about them.
 *
 * @[email protected] 2017-05-17 13:54:37Z by genExtStubs.tcl from ../generic/odbcStubDefs.txt
 *
 * Copyright (c) 2010 by Kevin B. Kenny.
 *
 * Please refer to the file, 'license.terms' for the conditions on
 * redistribution of this file and for a DISCLAIMER OF ALL WARRANTIES.
 *
 *-----------------------------------------------------------------------------
................................................................................

/*
 * Names of the libraries that might contain the ODBC API
 */

static const char *const odbcStubLibNames[] = {
    /* @[email protected]: DO NOT EDIT THESE NAMES */
    "odbc32", "odbc", "libodbc32", "libodbc", "libiodbc", NULL
    /* @[email protected] */
};
static const char *const odbcOptLibNames[] = {
    "odbccp", "odbccp32", "odbcinst",
    "libodbccp", "libodbccp32", "libodbcinst", "libiodbcinst", NULL
};

/*
 * Names of the functions that we need from ODBC
 */

static const char *const odbcSymbolNames[] = {

Changes to generic/odbcStubs.h.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 *-----------------------------------------------------------------------------
 *
 * ./generic/odbcStubs.h --
 *
 *	Stubs for procedures in odbcStubDefs.txt
 *
 * Generated by genExtStubs.tcl: DO NOT EDIT
 * 2015-06-26 13:54:02Z
 *
 *-----------------------------------------------------------------------------
 */

typedef struct odbcStubDefs {

    /* Functions from libraries: odbc32 odbc libodbc32 libodbc */

    SQLRETURN (SQL_API*SQLAllocHandlePtr)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*);
    SQLRETURN (SQL_API*SQLBindParameterPtr)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
    SQLRETURN (SQL_API*SQLCloseCursorPtr)(SQLHSTMT);
    SQLRETURN (SQL_API*SQLColumnsWPtr)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT ,SQLWCHAR*,SQLSMALLINT );
    SQLRETURN (SQL_API*SQLDataSourcesWPtr)(SQLHENV,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
    SQLRETURN (SQL_API*SQLDescribeColWPtr)(SQLHSTMT,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*);


|




|






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
 *-----------------------------------------------------------------------------
 *
 * ../generic/odbcStubs.h --
 *
 *	Stubs for procedures in odbcStubDefs.txt
 *
 * Generated by genExtStubs.tcl: DO NOT EDIT
 * 2017-05-17 13:54:37Z
 *
 *-----------------------------------------------------------------------------
 */

typedef struct odbcStubDefs {

    /* Functions from libraries: odbc32 odbc libodbc32 libodbc libiodbc */

    SQLRETURN (SQL_API*SQLAllocHandlePtr)(SQLSMALLINT,SQLHANDLE,SQLHANDLE*);
    SQLRETURN (SQL_API*SQLBindParameterPtr)(SQLHSTMT,SQLUSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLSMALLINT,SQLULEN,SQLSMALLINT,SQLPOINTER,SQLLEN,SQLLEN*);
    SQLRETURN (SQL_API*SQLCloseCursorPtr)(SQLHSTMT);
    SQLRETURN (SQL_API*SQLColumnsWPtr)(SQLHSTMT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLWCHAR*,SQLSMALLINT ,SQLWCHAR*,SQLSMALLINT );
    SQLRETURN (SQL_API*SQLDataSourcesWPtr)(SQLHENV,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*);
    SQLRETURN (SQL_API*SQLDescribeColWPtr)(SQLHSTMT,SQLUSMALLINT,SQLWCHAR*,SQLSMALLINT,SQLSMALLINT*,SQLSMALLINT*,SQLULEN*,SQLSMALLINT*,SQLSMALLINT*);

Changes to generic/tdbcodbc.c.

27
28
29
30
31
32
33








34
35
36
37
38
39
40
...
862
863
864
865
866
867
868


869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
....
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
....
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
....
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
....
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include "fakesql.h"









/* Static data contained in this file */

TCL_DECLARE_MUTEX(hEnvMutex);	/* Mutex protecting the environment handle
				 * and its reference count */

static Tcl_LoadHandle odbcLoadHandle = NULL;
				/* Handle to the ODBC client library */
................................................................................
    SQLSMALLINT i;		/* Loop index for going through diagnostics */
    const char* sep = "";	/* Separator string for messages */
    const char* sqlstate;	/* SQL state */
    Tcl_Obj* resultObj;		/* Result string containing error message */
    Tcl_Obj* codeObj;		/* Error code object */
    Tcl_Obj* lineObj;		/* Object holding one diagnostic */
    Tcl_DString bufferDS;	/* Buffer for transferring messages */



    resultObj = Tcl_NewObj();
    codeObj = Tcl_NewStringObj("TDBC", -1);

    /* Loop through the diagnostics */

    i = 1;
    while (SQLGetDiagRecW(handleType, handle, i, state, &nativeError,
			  msg, SQL_MAX_MESSAGE_LENGTH, &msgLen)
	   != SQL_NO_DATA) {

	/* Add the diagnostic to ::errorCode */

	Tcl_DStringInit(&bufferDS);
	DStringAppendWChars(&bufferDS, state, 5);
	sqlstate = Tcl_DStringValue(&bufferDS);
	lineObj = Tcl_NewStringObj(sqlstate, Tcl_DStringLength(&bufferDS));
................................................................................
		}

		/*
		 * Non-unique name - append a # and the number of times
		 * we've seen it before.
		 */

		count = (int) Tcl_GetHashValue(nameEntry);
		++count;
		Tcl_SetHashValue(nameEntry, (ClientData) count);
		sprintf(numbuf, "#%d", count);
		Tcl_AppendToObj(colNameObj, numbuf, -1);
	    }

	    /* Add column name to the list of column names */

	    Tcl_ListObjAppendElement(NULL, colNames, colNameObj);
................................................................................
	    Tcl_DecrRefCount(command);
	    if (status != TCL_OK) {
		Tcl_AddErrorInfo(interp,
				 "\n    (retrieving ID of parent window)");
		return status;
	    }
	    Tcl_ResetResult(interp);
	    *hParentWindowPtr = (HWND) w;
	    *connectFlagsPtr = SQL_DRIVER_COMPLETE_REQUIRED;
	    break;

	case COPTION_READONLY:
	    /* read-only indicator */

	    if (Tcl_GetBooleanFromObj(interp, objv[i+1], &j) != TCL_OK) {
................................................................................
ConnectionEndXcnMethod(
    ClientData clientData,	/* Completion type */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    SQLSMALLINT completionType = (SQLSMALLINT) (int) (clientData);
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    SQLRETURN rc;		/* Result code from ODBC operations */

................................................................................
				 * dicts are to be returned */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    int lists = (int) clientData;
				/* Flag == 1 if lists are to be returned,
				 * 0 if dicts are to be returned */

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current result set object */
    ResultSetData* rdata = (ResultSetData*)
	Tcl_ObjectGetMetadata(thisObject, &resultSetDataType);






>
>
>
>
>
>
>
>







 







>
>







|
|
|







 







|

|







 







|







 







|







 







|







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
....
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
....
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
....
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
....
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include "fakesql.h"

/*
 * PTR2INT/INT2PTR
 */
#if defined(HAVE_STDINT_H) && defined(HAVE_INTPTR_T)
#  include <stdint.h>
#  include "intptr_t.h"
#endif

/* Static data contained in this file */

TCL_DECLARE_MUTEX(hEnvMutex);	/* Mutex protecting the environment handle
				 * and its reference count */

static Tcl_LoadHandle odbcLoadHandle = NULL;
				/* Handle to the ODBC client library */
................................................................................
    SQLSMALLINT i;		/* Loop index for going through diagnostics */
    const char* sep = "";	/* Separator string for messages */
    const char* sqlstate;	/* SQL state */
    Tcl_Obj* resultObj;		/* Result string containing error message */
    Tcl_Obj* codeObj;		/* Error code object */
    Tcl_Obj* lineObj;		/* Object holding one diagnostic */
    Tcl_DString bufferDS;	/* Buffer for transferring messages */

    SQLRETURN sqlreturn;

    resultObj = Tcl_NewObj();
    codeObj = Tcl_NewStringObj("TDBC", -1);

    /* Loop through the diagnostics */

    i = 1;
    while ((sqlreturn = SQLGetDiagRecW(handleType, handle, i, state, &nativeError,
				       msg, SQL_MAX_MESSAGE_LENGTH, &msgLen))
	   != SQL_NO_DATA && sqlreturn >= 0) {

	/* Add the diagnostic to ::errorCode */

	Tcl_DStringInit(&bufferDS);
	DStringAppendWChars(&bufferDS, state, 5);
	sqlstate = Tcl_DStringValue(&bufferDS);
	lineObj = Tcl_NewStringObj(sqlstate, Tcl_DStringLength(&bufferDS));
................................................................................
		}

		/*
		 * Non-unique name - append a # and the number of times
		 * we've seen it before.
		 */

		count = PTR2INT(Tcl_GetHashValue(nameEntry));
		++count;
		Tcl_SetHashValue(nameEntry, /*(ClientData)*/ INT2PTR(count));
		sprintf(numbuf, "#%d", count);
		Tcl_AppendToObj(colNameObj, numbuf, -1);
	    }

	    /* Add column name to the list of column names */

	    Tcl_ListObjAppendElement(NULL, colNames, colNameObj);
................................................................................
	    Tcl_DecrRefCount(command);
	    if (status != TCL_OK) {
		Tcl_AddErrorInfo(interp,
				 "\n    (retrieving ID of parent window)");
		return status;
	    }
	    Tcl_ResetResult(interp);
	    *hParentWindowPtr = (HWND) INT2PTR(w);
	    *connectFlagsPtr = SQL_DRIVER_COMPLETE_REQUIRED;
	    break;

	case COPTION_READONLY:
	    /* read-only indicator */

	    if (Tcl_GetBooleanFromObj(interp, objv[i+1], &j) != TCL_OK) {
................................................................................
ConnectionEndXcnMethod(
    ClientData clientData,	/* Completion type */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    SQLSMALLINT completionType = (SQLSMALLINT) PTR2INT(clientData);
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    SQLRETURN rc;		/* Result code from ODBC operations */

................................................................................
				 * dicts are to be returned */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    int lists = PTR2INT(clientData);
				/* Flag == 1 if lists are to be returned,
				 * 0 if dicts are to be returned */

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current result set object */
    ResultSetData* rdata = (ResultSetData*)
	Tcl_ObjectGetMetadata(thisObject, &resultSetDataType);

Changes to tests/tdbcodbc.test.

14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
namespace import -force ::tcltest::*
loadTestedCommands
package require tdbc::odbc

# Test setup. Figure out what sort of database we have.  Default on Windows
# is SQL Server Express, and on Unix is SQLite3

if {![info exists env(TDBCODBC_TYPE)] || $env(TDBCODBC_TYPE) eq {default}} {
    set testdir [makeDirectory tdbctest]
    if {$tcl_platform(platform) eq {windows}} {
	set env(TDBCODBC_TYPE) sqlserver
    } else {
	set env(TDBCODBC_TYPE) sqlite
    }
}

# Jet and SQL Server are Windows-only

if {$env(TDBCODBC_TYPE) in {jet sqlserver}} {
    if {$::tcl_platform(platform) ne {windows}} {
	puts "$env(TDBCODBC_TYPE) testing is available on the\
                     Windows platform only"
	removeDirectory tdbctest
	cleanupTests
	return
    }
}

# Configure the selected database

switch -exact -- $env(TDBCODBC_TYPE) {

    jet {

	# Begin by creating an empty .MDB file

	set testdir [makeDirectory tdbctest]
	set testFileName test.mdb






|


|

|





|

|









|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
namespace import -force ::tcltest::*
loadTestedCommands
package require tdbc::odbc

# Test setup. Figure out what sort of database we have.  Default on Windows
# is SQL Server Express, and on Unix is SQLite3

if {![info exists ::env(TDBCODBC_TEST_TYPE)] || $::env(TDBCODBC_TEST_TYPE) eq {default}} {
    set testdir [makeDirectory tdbctest]
    if {$tcl_platform(platform) eq {windows}} {
	set ::env(TDBCODBC_TEST_TYPE) sqlserver
    } else {
	set ::env(TDBCODBC_TEST_TYPE) sqlite
    }
}

# Jet and SQL Server are Windows-only

if {$::env(TDBCODBC_TEST_TYPE) in {jet sqlserver}} {
    if {$::tcl_platform(platform) ne {windows}} {
	puts "$::env(TDBCODBC_TEST_TYPE) testing is available on the\
                     Windows platform only"
	removeDirectory tdbctest
	cleanupTests
	return
    }
}

# Configure the selected database

switch -exact -- $::env(TDBCODBC_TEST_TYPE) {

    jet {

	# Begin by creating an empty .MDB file

	set testdir [makeDirectory tdbctest]
	set testFileName test.mdb