tdbc::odbc

Check-in [fba03660d1]
Login
Bounty program for improvements to Tcl and certain Tcl packages.

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

Overview
Comment:Make compile warning-free using -Wall -Wextra
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: fba03660d181178bccd5218020851a3e5b70a694fda449c8c2e7dcab32bfac82
User & Date: jan.nijtmans 2020-02-12 12:38:18
Context
2020-02-12
12:41
Version 1.1.1 -> 1.1.2 Leaf check-in: 298d5737a7 user: jan.nijtmans tags: trunk
12:38
Make compile warning-free using -Wall -Wextra check-in: fba03660d1 user: jan.nijtmans tags: trunk
2019-12-15
17:19
Fix typo (__WIN64 -> _WIN64). Make tdbcodbc ready for the 9.0 era, in which string lengths can be >32bit check-in: 78e0a63cc6 user: jan.nijtmans tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tdbcodbc.c.

2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053

2054
2055
2056
2057
2058
2059
2060
....
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121

2122
2123
2124
2125
2126
2127
2128
....
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235

2236
2237
2238
2239
2240
2241
2242
....
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287

2288
2289
2290
2291
2292
2293
2294
....
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382



2383
2384
2385
2386
2387
2388
2389
....
2447
2448
2449
2450
2451
2452
2453



2454
2455
2456
2457
2458
2459
2460
....
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
....
2537
2538
2539
2540
2541
2542
2543

2544
2545
2546
2547
2548
2549
2550
....
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
....
2734
2735
2736
2737
2738
2739
2740



2741
2742
2743
2744
2745
2746
2747
....
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782



2783
2784
2785
2786
2787
2788
2789
....
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
....
2843
2844
2845
2846
2847
2848
2849


2850
2851
2852
2853
2854
2855
2856
....
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
....
2963
2964
2965
2966
2967
2968
2969

2970
2971
2972
2973
2974
2975
2976
....
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
....
3063
3064
3065
3066
3067
3068
3069

3070
3071
3072
3073
3074
3075
3076
....
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
....
3166
3167
3168
3169
3170
3171
3172

3173
3174
3175
3176
3177
3178
3179
....
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
....
3268
3269
3270
3271
3272
3273
3274

3275
3276
3277
3278
3279
3280
3281
....
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
....
3411
3412
3413
3414
3415
3416
3417

3418
3419
3420
3421
3422
3423
3424
....
3540
3541
3542
3543
3544
3545
3546



3547
3548
3549
3550
3551
3552
3553
....
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
....
3604
3605
3606
3607
3608
3609
3610

3611
3612
3613
3614
3615
3616
3617
....
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976

3977
3978
3979
3980
3981
3982
3983
....
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
....
4033
4034
4035
4036
4037
4038
4039



4040
4041
4042
4043
4044
4045
4046
....
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518

4519
4520
4521
4522
4523
4524
4525
....
4596
4597
4598
4599
4600
4601
4602



4603
4604
4605
4606
4607
4608
4609
....
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
....
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
4997
4998
4999
....
5005
5006
5007
5008
5009
5010
5011

5012
5013
5014
5015
5016
5017
5018
....
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
....
5187
5188
5189
5190
5191
5192
5193

5194
5195
5196
5197
5198
5199
5200
 *	Returns an empty result if successful, and throws an error otherwise.
 *
 *-----------------------------------------------------------------------------
*/

static int
ConnectionBeginTransactionMethod(
    ClientData clientData,	/* Unused */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);


    /* Check parameters */

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }
................................................................................
 *	options to the given values.
 *
 *-----------------------------------------------------------------------------
 */

static int
ConnectionConfigureMethod(
    ClientData clientData,	/* Completion type */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */


    /* Check parameters */

    if (objc != 2 && objc != 3 && (objc%2) != 0) {
	Tcl_WrongNumArgs(interp, 2, objv,
			 "?" "?-option? value? ?-option value?...");
	return TCL_ERROR;
................................................................................
 *	Returns an empty Tcl result.
 *
 *-----------------------------------------------------------------------------
 */

static int
ConnectionHasBigintMethod(
    ClientData clientData,	/* Completion type */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    int flag;


    /* Check parameters */

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "flag");
	return TCL_ERROR;
    }
................................................................................
 *	Returns an empty Tcl result.
 *
 *-----------------------------------------------------------------------------
 */

static int
ConnectionHasWvarcharMethod(
    ClientData clientData,	/* Completion type */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    int flag;


    /* Check parameters */

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "flag");
	return TCL_ERROR;
    }
................................................................................
 *	refcounts accurate
 *
 *-----------------------------------------------------------------------------
 */

static int
CloneCmd(
    Tcl_Interp* interp,		/* Tcl interpreter */
    ClientData oldClientData,	/* Environment handle to be discarded */
    ClientData* newClientData	/* New environment handle to be used */
) {



    *newClientData = GetHEnv(NULL);
    return TCL_OK;
}
 
/*
 *-----------------------------------------------------------------------------
 *
................................................................................

static int
CloneConnection(
    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
    ClientData metadata,	/* Metadata to be cloned */
    ClientData* newMetaData	/* Where to put the cloned metadata */
) {



    Tcl_SetObjResult(interp,
		     Tcl_NewStringObj("ODBC connections are not clonable", -1));
    return TCL_ERROR;
}
 
/*
 *-----------------------------------------------------------------------------
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
StatementConstructor(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current statement object */
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of args to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
................................................................................
    Tcl_Obj** tokenv;		/* Exploded tokens from the list */
    Tcl_Obj* nativeSql;		/* SQL statement mapped to ODBC form */
    char* tokenStr;		/* Token string */
    size_t tokenLen;		/* Length of a token */
    RETCODE rc;			/* Return code from ODBC */
    SQLSMALLINT nParams;	/* Number of parameters in the ODBC statement */
    int i, j;


    /* Find the connection object, and get its data. */

    if (objc != skip+2) {
	Tcl_WrongNumArgs(interp, skip, objv, "connection statementText");
	return TCL_ERROR;
    }
................................................................................
 *	Returns the connection handle
 *
 *-----------------------------------------------------------------------------
 */

static int
StatementConnectionMethod(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current statement object */
................................................................................
    StatementData* sdata;	/* The current statement */
    Tcl_Object connectionObject;
				/* The object representing the connection */
    Tcl_Command connectionCommand;
				/* The command representing the object */
    Tcl_Obj* retval = Tcl_NewObj();
				/* The command name */




    sdata = (StatementData*) Tcl_ObjectGetMetadata(thisObject,
						   &statementDataType);
    connectionObject = sdata->connectionObject;
    connectionCommand = Tcl_GetObjectCommand(connectionObject);
    Tcl_GetCommandFullName(interp, connectionCommand, retval);
    Tcl_SetObjResult(interp, retval);
................................................................................
 *	elements: paramName flags typeNumber precision scale nullable
 *
 *-----------------------------------------------------------------------------
 */

static int
StatementParamListMethod(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current statement object */
    StatementData* sdata;	/* The current statement */
    Tcl_Obj **paramNames;	/* Parameter list to the current statement */
    int nParams;		/* Parameter count for the current statement */
    int i;			/* Current parameter index */
    Tcl_Obj* retval;		/* Return value from this command */




    sdata = (StatementData*) Tcl_ObjectGetMetadata(thisObject,
						   &statementDataType);

    retval = Tcl_NewObj();
    if (sdata->subVars != NULL) {
	Tcl_ListObjGetElements(NULL, sdata->subVars, &nParams, &paramNames);
................................................................................
 *	Updates the description of the given parameter.
 *
 *-----------------------------------------------------------------------------
 */

static int
StatementParamtypeMethod(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current statement object */
................................................................................
    int i;
    SQLSMALLINT dir = PARAM_IN | PARAM_KNOWN;
				/* Direction of parameter transmssion */
    SQLSMALLINT odbcType = SQL_VARCHAR;
				/* ODBC type of the parameter */
    int precision = 0;		/* Length of the parameter */
    int scale = 0;		/* Precision of the parameter */


    sdata = (StatementData*) Tcl_ObjectGetMetadata(thisObject,
						   &statementDataType);
    /* Check parameters */

    if (objc < 4) {
	goto wrongNumArgs;
    }
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
TablesStatementConstructor(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of initial args to this call */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */


    /* Find the connection object, and get its data. */

    if (objc != skip+2) {
	Tcl_WrongNumArgs(interp, skip, objv, "connection pattern");
	return TCL_ERROR;
    }
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
ColumnsStatementConstructor(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of parameters to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */



    /* Check param count */

    if (objc != skip+3) {
	Tcl_WrongNumArgs(interp, skip, objv, "connection tableName pattern");
	return TCL_ERROR;
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
PrimarykeysStatementConstructor(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of parameters to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */



    /* Check param count */

    if (objc != skip+2) {
	Tcl_WrongNumArgs(interp, skip, objv, "connection tableName");
	return TCL_ERROR;
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
ForeignkeysStatementConstructor(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of parameters to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */


    static const char* options[] = {	/* Option table */
	"-foreign",
	"-primary",
	NULL
    };
    enum {
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
TypesStatementConstructor(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
				/* The number of leading args to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */
    int typeNum;		/* Data type number */


    /* Parse args */

    if (objc == skip+1) {
	typeNum = SQL_ALL_TYPES;
    } else if (objc == skip+2) {
	if (Tcl_GetIntFromObj(interp, objv[skip+1], &typeNum) != TCL_OK) {
................................................................................

static int
CloneStatement(
    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
    ClientData metadata,	/* Metadata to be cloned */
    ClientData* newMetaData	/* Where to put the cloned metadata */
) {



    Tcl_SetObjResult(interp,
		     Tcl_NewStringObj("ODBC statements are not clonable", -1));
    return TCL_ERROR;
}
 
/*
 *-----------------------------------------------------------------------------
................................................................................
 *	contains an appropriate message.
 *
 *-----------------------------------------------------------------------------
 */

static int
ResultSetConstructor(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
				 * system encoding */
    int paramExternalLen;	/* Length of the substituted parameter
				 * after conversion */
    SQLRETURN rc;		/* Return code from ODBC calls */
    unsigned char* byteArrayPtr; /* Pointer to a BINARY or VARBINARY
				 * parameter, expressed as a byte array.*/
    int i;


    /* Check parameter count */

    if (objc != skip+1 && objc != skip+2) {
	Tcl_WrongNumArgs(interp, skip, objv, "statement ?dictionary?");
	return TCL_ERROR;
    }
................................................................................
 *	Returns the count of columns
 *
 *-----------------------------------------------------------------------------
 */

static int
ResultSetColumnsMethod(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

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


    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    /* Extract the column information for the result set. */
................................................................................
 *	of failure, the result is a Tcl error message describing the problem.
 *
 *-----------------------------------------------------------------------------
 */

static int
ResultSetNextresultsMethod(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current result set object */
................................................................................
    ConnectionData* cdata = (ConnectionData*) sdata->cdata;
				/* Connection that opened the statement */
    PerInterpData* pidata = (PerInterpData*) cdata->pidata;
				/* Per interpreter data */
    Tcl_Obj** literals = pidata->literals;
				/* Literal pool */
    SQLRETURN rc;		/* Return code from ODBC operations */




    /*
     * Once we are advancing the results, any data that we think we know
     * about the columns in the result set are incorrect. Discard them.
     */

    DeleteResultSetDescription(rdata);
................................................................................
 *	Returns a standard Tcl result giving the number of affected rows.
 *
 *-----------------------------------------------------------------------------
 */

static int
ResultSetRowcountMethod(
    ClientData clientData,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

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


    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(rdata->rowCount));
    return TCL_OK;
................................................................................

static int
CloneResultSet(
    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
    ClientData metadata,	/* Metadata to be cloned */
    ClientData* newMetaData	/* Where to put the cloned metadata */
) {



    Tcl_SetObjResult(interp,
		     Tcl_NewStringObj("ODBC result sets are not clonable", -1));
    return TCL_ERROR;
}
 
/*
 *-----------------------------------------------------------------------------
................................................................................
 *	is successful.
 *
 *-----------------------------------------------------------------------------
 */

static int
DatasourceObjCmdW(
    ClientData clientData,	/* Unused */
    Tcl_Interp* interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    static const struct flag {
	const char* name;
	WORD value;
................................................................................
	{ "configure",		ODBC_CONFIG_DSN },
	{ "configure_system",	ODBC_CONFIG_SYS_DSN },
	{ "remove",		ODBC_REMOVE_DSN },
	{ "remove_system", 	ODBC_REMOVE_SYS_DSN },
	{ NULL,			0 }
    };
    int flagIndex;		/* Index of the subcommand */

    WCHAR* driverName;		/* Name of the ODBC driver */
    WCHAR* attributes;		/* NULL-delimited attribute values */
    char errorMessage[SQL_MAX_MESSAGE_LENGTH+1];
				/* Error message from ODBC operations */
    size_t driverNameLen;		/* Length of the driver name */
    Tcl_Obj* attrObj;		/* NULL-delimited attribute values */
    size_t attrLen;		/* Length of the attribute values */
................................................................................
    Tcl_DString errorMessageDS;	/* DString to convert error message
				 * from system encoding */
    Tcl_Obj* errorCodeObj;	/* Tcl error code */
    int i, j;
    BOOL ok;
    int status = TCL_OK;
    int finished = 0;


    /* Check args */

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 1, objv,
			 "operation driver ?keyword=value?...");
	return TCL_ERROR;
................................................................................
 *	is successful.
 *
 *-----------------------------------------------------------------------------
 */

static int
DatasourceObjCmdA(
    ClientData clientData,	/* Unused */
    Tcl_Interp* interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    static const struct flag {
	const char* name;
	WORD value;
................................................................................
    RETCODE errorMessageStatus;	/* Status of the error message formatting */
    Tcl_DString retvalDS;	/* Return value */
    Tcl_Obj* errorCodeObj;	/* Tcl error code */
    int i, j;
    BOOL ok;
    int status = TCL_OK;
    int finished = 0;


    /* Check args */

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 1, objv,
			 "operation driver ?keyword=value?...");
	return TCL_ERROR;






|









>







 







|










>







 







|











>







 







|











>







 







|



>
>
>







 







>
>
>







 







|





<







 







>







 







|







 







>
>
>







 







|












>
>
>







 







|







 







>
>







 







|







 







>







 







|







 







>







 







|







 







>







 







|







 







>







 







|







 







>







 







>
>
>







 







|







 







>







 







|





<




>







 







|







 







>
>
>







 







|





<





>







 







>
>
>







 







|







 







<







 







>







 







|







 







>







2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
....
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
....
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
....
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
....
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
....
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
....
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535

2536
2537
2538
2539
2540
2541
2542
....
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
....
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
....
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
....
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
....
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
....
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
....
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
....
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
....
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
....
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
....
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
....
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
....
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
....
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
....
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
....
3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
....
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
....
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
....
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
3643
3644
....
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998

3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
....
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
....
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
....
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542

4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
....
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
....
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
....
5018
5019
5020
5021
5022
5023
5024

5025
5026
5027
5028
5029
5030
5031
....
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
....
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
....
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
 *	Returns an empty result if successful, and throws an error otherwise.
 *
 *-----------------------------------------------------------------------------
*/

static int
ConnectionBeginTransactionMethod(
    ClientData dummy,	/* Unused */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
    (void)dummy;

    /* Check parameters */

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }
................................................................................
 *	options to the given values.
 *
 *-----------------------------------------------------------------------------
 */

static int
ConnectionConfigureMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    (void)dummy;

    /* Check parameters */

    if (objc != 2 && objc != 3 && (objc%2) != 0) {
	Tcl_WrongNumArgs(interp, 2, objv,
			 "?" "?-option? value? ?-option value?...");
	return TCL_ERROR;
................................................................................
 *	Returns an empty Tcl result.
 *
 *-----------------------------------------------------------------------------
 */

static int
ConnectionHasBigintMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    int flag;
    (void)dummy;

    /* Check parameters */

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "flag");
	return TCL_ERROR;
    }
................................................................................
 *	Returns an empty Tcl result.
 *
 *-----------------------------------------------------------------------------
 */

static int
ConnectionHasWvarcharMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext objectContext, /* Object context */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(objectContext);
				/* The current connection object */
    ConnectionData* cdata = (ConnectionData*)
	Tcl_ObjectGetMetadata(thisObject, &connectionDataType);
				/* Instance data */
    int flag;
    (void)dummy;

    /* Check parameters */

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "flag");
	return TCL_ERROR;
    }
................................................................................
 *	refcounts accurate
 *
 *-----------------------------------------------------------------------------
 */

static int
CloneCmd(
    Tcl_Interp* dummy,		/* Tcl interpreter */
    ClientData oldClientData,	/* Environment handle to be discarded */
    ClientData* newClientData	/* New environment handle to be used */
) {
    (void)dummy;
    (void)oldClientData;

    *newClientData = GetHEnv(NULL);
    return TCL_OK;
}
 
/*
 *-----------------------------------------------------------------------------
 *
................................................................................

static int
CloneConnection(
    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
    ClientData metadata,	/* Metadata to be cloned */
    ClientData* newMetaData	/* Where to put the cloned metadata */
) {
    (void)metadata;
    (void)newMetaData;

    Tcl_SetObjResult(interp,
		     Tcl_NewStringObj("ODBC connections are not clonable", -1));
    return TCL_ERROR;
}
 
/*
 *-----------------------------------------------------------------------------
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
StatementConstructor(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current statement object */
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of args to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
................................................................................
    Tcl_Obj** tokenv;		/* Exploded tokens from the list */
    Tcl_Obj* nativeSql;		/* SQL statement mapped to ODBC form */
    char* tokenStr;		/* Token string */
    size_t tokenLen;		/* Length of a token */
    RETCODE rc;			/* Return code from ODBC */
    SQLSMALLINT nParams;	/* Number of parameters in the ODBC statement */
    int i, j;
    (void)dummy;

    /* Find the connection object, and get its data. */

    if (objc != skip+2) {
	Tcl_WrongNumArgs(interp, skip, objv, "connection statementText");
	return TCL_ERROR;
    }
................................................................................
 *	Returns the connection handle
 *
 *-----------------------------------------------------------------------------
 */

static int
StatementConnectionMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current statement object */
................................................................................
    StatementData* sdata;	/* The current statement */
    Tcl_Object connectionObject;
				/* The object representing the connection */
    Tcl_Command connectionCommand;
				/* The command representing the object */
    Tcl_Obj* retval = Tcl_NewObj();
				/* The command name */
    (void)dummy;
    (void)objc;
    (void)objv;

    sdata = (StatementData*) Tcl_ObjectGetMetadata(thisObject,
						   &statementDataType);
    connectionObject = sdata->connectionObject;
    connectionCommand = Tcl_GetObjectCommand(connectionObject);
    Tcl_GetCommandFullName(interp, connectionCommand, retval);
    Tcl_SetObjResult(interp, retval);
................................................................................
 *	elements: paramName flags typeNumber precision scale nullable
 *
 *-----------------------------------------------------------------------------
 */

static int
StatementParamListMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current statement object */
    StatementData* sdata;	/* The current statement */
    Tcl_Obj **paramNames;	/* Parameter list to the current statement */
    int nParams;		/* Parameter count for the current statement */
    int i;			/* Current parameter index */
    Tcl_Obj* retval;		/* Return value from this command */
    (void)dummy;
    (void)objc;
    (void)objv;

    sdata = (StatementData*) Tcl_ObjectGetMetadata(thisObject,
						   &statementDataType);

    retval = Tcl_NewObj();
    if (sdata->subVars != NULL) {
	Tcl_ListObjGetElements(NULL, sdata->subVars, &nParams, &paramNames);
................................................................................
 *	Updates the description of the given parameter.
 *
 *-----------------------------------------------------------------------------
 */

static int
StatementParamtypeMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current statement object */
................................................................................
    int i;
    SQLSMALLINT dir = PARAM_IN | PARAM_KNOWN;
				/* Direction of parameter transmssion */
    SQLSMALLINT odbcType = SQL_VARCHAR;
				/* ODBC type of the parameter */
    int precision = 0;		/* Length of the parameter */
    int scale = 0;		/* Precision of the parameter */
    (void)dummy;

    sdata = (StatementData*) Tcl_ObjectGetMetadata(thisObject,
						   &statementDataType);
    /* Check parameters */

    if (objc < 4) {
	goto wrongNumArgs;
    }
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
TablesStatementConstructor(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of initial args to this call */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */
    (void)dummy;

    /* Find the connection object, and get its data. */

    if (objc != skip+2) {
	Tcl_WrongNumArgs(interp, skip, objv, "connection pattern");
	return TCL_ERROR;
    }
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
ColumnsStatementConstructor(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of parameters to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */
    (void)dummy;


    /* Check param count */

    if (objc != skip+3) {
	Tcl_WrongNumArgs(interp, skip, objv, "connection tableName pattern");
	return TCL_ERROR;
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
PrimarykeysStatementConstructor(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of parameters to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */
    (void)dummy;


    /* Check param count */

    if (objc != skip+2) {
	Tcl_WrongNumArgs(interp, skip, objv, "connection tableName");
	return TCL_ERROR;
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
ForeignkeysStatementConstructor(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
    int skip = Tcl_ObjectContextSkippedArgs(context);
				/* The number of parameters to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */
    (void)dummy;

    static const char* options[] = {	/* Option table */
	"-foreign",
	"-primary",
	NULL
    };
    enum {
................................................................................
 *	connection) in instance metadata.
 *
 *-----------------------------------------------------------------------------
 */

static int
TypesStatementConstructor(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
				/* The number of leading args to skip */
    Tcl_Object connectionObject;
				/* The database connection as a Tcl_Object */
    ConnectionData* cdata;	/* The connection object's data */
    StatementData* sdata;	/* The statement's object data */
    RETCODE rc;			/* Return code from ODBC */
    int typeNum;		/* Data type number */
    (void)dummy;

    /* Parse args */

    if (objc == skip+1) {
	typeNum = SQL_ALL_TYPES;
    } else if (objc == skip+2) {
	if (Tcl_GetIntFromObj(interp, objv[skip+1], &typeNum) != TCL_OK) {
................................................................................

static int
CloneStatement(
    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
    ClientData metadata,	/* Metadata to be cloned */
    ClientData* newMetaData	/* Where to put the cloned metadata */
) {
    (void)metadata;
    (void)newMetaData;

    Tcl_SetObjResult(interp,
		     Tcl_NewStringObj("ODBC statements are not clonable", -1));
    return TCL_ERROR;
}
 
/*
 *-----------------------------------------------------------------------------
................................................................................
 *	contains an appropriate message.
 *
 *-----------------------------------------------------------------------------
 */

static int
ResultSetConstructor(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
................................................................................
				 * system encoding */
    int paramExternalLen;	/* Length of the substituted parameter
				 * after conversion */
    SQLRETURN rc;		/* Return code from ODBC calls */
    unsigned char* byteArrayPtr; /* Pointer to a BINARY or VARBINARY
				 * parameter, expressed as a byte array.*/
    int i;
    (void)dummy;

    /* Check parameter count */

    if (objc != skip+1 && objc != skip+2) {
	Tcl_WrongNumArgs(interp, skip, objv, "statement ?dictionary?");
	return TCL_ERROR;
    }
................................................................................
 *	Returns the count of columns
 *
 *-----------------------------------------------------------------------------
 */

static int
ResultSetColumnsMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

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

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }

    /* Extract the column information for the result set. */
................................................................................
 *	of failure, the result is a Tcl error message describing the problem.
 *
 *-----------------------------------------------------------------------------
 */

static int
ResultSetNextresultsMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current result set object */
................................................................................
    ConnectionData* cdata = (ConnectionData*) sdata->cdata;
				/* Connection that opened the statement */
    PerInterpData* pidata = (PerInterpData*) cdata->pidata;
				/* Per interpreter data */
    Tcl_Obj** literals = pidata->literals;
				/* Literal pool */
    SQLRETURN rc;		/* Return code from ODBC operations */
    (void)dummy;
    (void)objc;
    (void)objv;

    /*
     * Once we are advancing the results, any data that we think we know
     * about the columns in the result set are incorrect. Discard them.
     */

    DeleteResultSetDescription(rdata);
................................................................................
 *	Returns a standard Tcl result giving the number of affected rows.
 *
 *-----------------------------------------------------------------------------
 */

static int
ResultSetRowcountMethod(
    ClientData dummy,	/* Not used */
    Tcl_Interp* interp,		/* Tcl interpreter */
    Tcl_ObjectContext context,	/* Object context  */
    int objc, 			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {

    Tcl_Object thisObject = Tcl_ObjectContextObject(context);
				/* The current result set object */
    ResultSetData* rdata = (ResultSetData*)
	Tcl_ObjectGetMetadata(thisObject, &resultSetDataType);
				/* Data pertaining to the current result set */
    (void)dummy;

    if (objc != 2) {
	Tcl_WrongNumArgs(interp, 2, objv, "");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(rdata->rowCount));
    return TCL_OK;
................................................................................

static int
CloneResultSet(
    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
    ClientData metadata,	/* Metadata to be cloned */
    ClientData* newMetaData	/* Where to put the cloned metadata */
) {
    (void)metadata;
    (void)newMetaData;

    Tcl_SetObjResult(interp,
		     Tcl_NewStringObj("ODBC result sets are not clonable", -1));
    return TCL_ERROR;
}
 
/*
 *-----------------------------------------------------------------------------
................................................................................
 *	is successful.
 *
 *-----------------------------------------------------------------------------
 */

static int
DatasourceObjCmdW(
    ClientData dummy,	/* Unused */
    Tcl_Interp* interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    static const struct flag {
	const char* name;
	WORD value;
................................................................................
	{ "configure",		ODBC_CONFIG_DSN },
	{ "configure_system",	ODBC_CONFIG_SYS_DSN },
	{ "remove",		ODBC_REMOVE_DSN },
	{ "remove_system", 	ODBC_REMOVE_SYS_DSN },
	{ NULL,			0 }
    };
    int flagIndex;		/* Index of the subcommand */

    WCHAR* driverName;		/* Name of the ODBC driver */
    WCHAR* attributes;		/* NULL-delimited attribute values */
    char errorMessage[SQL_MAX_MESSAGE_LENGTH+1];
				/* Error message from ODBC operations */
    size_t driverNameLen;		/* Length of the driver name */
    Tcl_Obj* attrObj;		/* NULL-delimited attribute values */
    size_t attrLen;		/* Length of the attribute values */
................................................................................
    Tcl_DString errorMessageDS;	/* DString to convert error message
				 * from system encoding */
    Tcl_Obj* errorCodeObj;	/* Tcl error code */
    int i, j;
    BOOL ok;
    int status = TCL_OK;
    int finished = 0;
    (void)dummy;

    /* Check args */

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 1, objv,
			 "operation driver ?keyword=value?...");
	return TCL_ERROR;
................................................................................
 *	is successful.
 *
 *-----------------------------------------------------------------------------
 */

static int
DatasourceObjCmdA(
    ClientData dummy,	/* Unused */
    Tcl_Interp* interp,		/* Tcl interpreter */
    int objc,			/* Parameter count */
    Tcl_Obj *const objv[]	/* Parameter vector */
) {
    static const struct flag {
	const char* name;
	WORD value;
................................................................................
    RETCODE errorMessageStatus;	/* Status of the error message formatting */
    Tcl_DString retvalDS;	/* Return value */
    Tcl_Obj* errorCodeObj;	/* Tcl error code */
    int i, j;
    BOOL ok;
    int status = TCL_OK;
    int finished = 0;
    (void)dummy;

    /* Check args */

    if (objc < 4) {
	Tcl_WrongNumArgs(interp, 1, objv,
			 "operation driver ?keyword=value?...");
	return TCL_ERROR;