File: custom.c

package info (click to toggle)
unixodbc 2.2.11-16
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 17,332 kB
  • ctags: 12,399
  • sloc: ansic: 116,624; cpp: 29,333; sh: 25,024; makefile: 3,002; lex: 241; yacc: 182; perl: 142; sed: 16; sql: 1
file content (428 lines) | stat: -rw-r--r-- 14,818 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
//*---------------------------------------------------------------------------------
//| Custom Auto Test DLL
//|
//| Title:	CUSTOM.C
//|
//| Purpose:
//|	This sample Auto Test DLL shows how an ODBC auto test may be written and
//|	subsequently run via the ODBC Test application.  To use this DLL:
//|		1) Compile the source code via the BUILD.EXE program
//|					CUSTOM.C		This shource file with test code
//|					CUSTOM.H		Include files with defines, macros, and prototypes
//|					CUSTOM.RC	Resource file for string tables
//|			(Note that .H and .RC files are optional in for an Auto Test)
//|		2) Start the ODBC Test application
//|		3) If you have not done so, choose Tools, Manage Test Sources and define
//|				a test source to run against
//|		4) Choose Tools, Manage Tests and add the CUSTOM.DLL created in step 1
//|				to the list of installed test DLLs
//|		5) Choose Tools, Run Tests and select "Custom Auto Test" and your Test Source
//|				from step #3
//|	For more details, please see the SDK documentation.
//*---------------------------------------------------------------------------------
#include "autotest.h"
#include "custom.h"


//----------------------------------------------------------------------------------
//		Defines and macros
//----------------------------------------------------------------------------------
typedef SWORD (FAR PASCAL *TESTCASEFUNC)(HENV FAR *, HDBC FAR *, HSTMT FAR *, lpSERVERINFO);

#define CHECKTEST(lps, exprc, actrc, func) 			\
{                                                  \
	if(!CheckTest(lps, exprc, actrc, (LPSTR)func))  \
		return TEST_ABORTED;                         \
}
#define CHECKERRS(sErr)										\
	if(!sErr) szLogPrintf(lpSrvr, FALSE, "\t\tPassed\r\n\r\n"); \
	else szLogPrintf(lpSrvr, FALSE, "\t\t%d errors\r\n\r\n", sErr);



//----------------------------------------------------------------------------------
//		Local function prototypes
//----------------------------------------------------------------------------------
SWORD FAR PASCAL DoHelloWorld(HENV FAR * phenv, HDBC FAR * phdbc,
				HSTMT FAR * phstmt, lpSERVERINFO lpSrvr);
SWORD FAR PASCAL DoDisplayInfoDesc(HENV FAR * phenv, HDBC FAR * phdbc,
				HSTMT FAR * phstmt, lpSERVERINFO lpSrvr);
SWORD FAR PASCAL DoSimpleConnect(HENV FAR * phenv, HDBC FAR * phdbc,
				HSTMT FAR * phstmt, lpSERVERINFO lpSrvr);
BOOL FAR PASCAL CheckTest(lpSERVERINFO lps, RETCODE exprc, RETCODE actrc,
				LPSTR	szFuncName);


//
// This structure is declared to describe the test cases and descriptions
//		that this auto test supports.  Note that the strings are stored in
//		the resource fork, but could have been hard coded.
//
struct {
	UINT					uiName;			// Test case name
	UINT					uiDesc;			// Test case description
	TESTCASEFUNC		lpTestFunc;		// Pointer to function to implement test
	} TestCases[] = {
// szName					szDesc						lpTestFunc
// --------------------	-----------------------	------------------------
	idsHelloWorld,			idsHelloWorldDesc,		DoHelloWorld,
	idsDisplayInfo,		idsDisplayInfoDesc,		DoDisplayInfoDesc,
	idsSimpleConnect,		idsSimpleConnectDesc,	DoSimpleConnect,
	};



//**************************************************************************
//***************************  External Interfaces  ************************
//*  These functions are called by ODBC Test to gather run-time information
//**************************************************************************


//*---------------------------------------------------------------------------------
//| AutoTestName:
//|	This function is called to give the name of the auto test (which cannot
//|	exceed AUTO_MAX_TEST_NAME) as well as the number of test cases which
//|	are implemented in this test DLL.
//| Parms:	
//|	szName					The name to be displayed
//|	pcbTestCases			Pointer to count of test cases
//| Returns:
//|	TRUE if successful (pcbTestCases set), FALSE for error
//*---------------------------------------------------------------------------------
BOOL EXTFUN AutoTestName(LPSTR szName, UINT FAR * pcbTestCases)
{
    strcpy( szName, "Custom Auto Test" );
	*pcbTestCases = NumItems(TestCases);

   return TRUE;
}


//*---------------------------------------------------------------------------------
//| AutoTestDesc:
//|	This function is called by ODBC Test when a description of a specific
//|	test case is required.  The returned name must be no larger than
//|	AUTO_MAX_TESTCASE_NAME including the NULL terminator.  The returned
//|	description must be no larger than AUTO_MAX_TESTDESC_NAME including the
//|	NULL.  iTest will be 1-based index of the test required.
//|
//|	Note that iTest will start at 1 and will go to the number of
//|		test cases as specified by the AutoTestName function.
//|
//| Parms:	
//|	iTest						1-based index of test case required
//|	szName					The name of the test case
//|	szDesc					A description of the test case
//| Returns:
//|	TRUE if successful, FALSE for error
//*---------------------------------------------------------------------------------
BOOL EXTFUN AutoTestDesc(UWORD iTest, LPSTR szName, LPSTR szDesc)
{
	// Extra protection should AutoTestName return invalid pcbTestCases
	if(iTest > NumItems(TestCases))
		return FALSE;
		
	// Use GetRCString to retrieve resource string directly into return
	//		values
    switch( iTest )
    {
      case 1:
        strcpy( szName, "Hello World" );
        strcpy( szDesc, "Uses szLogPrintf and szMessageBox" );
        break;
      case 2:
        strcpy( szName, "Display SERVERINFO" );
        strcpy( szDesc, "Writes the contents of SERVERINFO" );
        break;
      case 3:
        strcpy( szName, "Simple Connect" );
        strcpy( szDesc, "Do a connect using SERVERINFO" );
        break;
    }

   return TRUE;
}
 
 
//*---------------------------------------------------------------------------------
//| AutoTestFunc:
//|	This function is called to execute a test case selected by the user for
//|	execution.  The lpSrvr structure contains the information required for
//|	connected (as defined in the chosen Test Source), as well as other
//|	usefull information.  See the AUTOTEST.H file for the structure
//|	declaration.
//|
//|	Use the GETBIT macro to determine which test should be executed.
//|
//| Parms:	
//|	lpSrvr					Information required for running the test
//| Returns:
//|	Nothing
//*---------------------------------------------------------------------------------
void EXTFUN AutoTestFunc(lpSERVERINFO lpSrvr)
{
	HENV 		henv=NULL;
	HDBC 		hdbc=NULL;
	HSTMT 	hstmt0=NULL;
	int		iDex;
	SWORD		cErrCnt;										// Count errors
	char		szName[AUTO_MAX_TESTCASE_NAME+6];	// Room for NULL and \r\n


	// Sets the error count to 0
	InitTest(lpSrvr);

	// Loop through the count of test cases looking for set bits via GETBIT.
	//		When a bit is set, that test is to be run.  We've stored the
	//		function address which will implement the test, so simply call it.
	for(iDex=1;  iDex<=NumItems(TestCases);  iDex++)
		if(GETBIT(lpSrvr->rglMask, iDex)) {
			// Print out title of test
            switch( iDex )
            {
              case 1:
                strcpy( szName, "Hello World" );
                break;
              case 2:
                strcpy( szName, "Display SERVERINFO" );
                break;
              case 3:
                strcpy( szName, "Simple Connect" );
                break;
            }
			szLogPrintf(lpSrvr, FALSE, "%s:\r\n", (LPSTR)szName);

			// Call the test case and add errors
			cErrCnt = 
				(*TestCases[(iDex-1)].lpTestFunc)(&henv, &hdbc, &hstmt0, lpSrvr);
			if(cErrCnt != TEST_ABORTED)
				lpSrvr->cErrors += cErrCnt;
			else
				goto abort;
			}
	return;


	// When a test must abort, the test case should call the AbortTest
	//		macro which sets lpSrvr->cErrors to TEST_ABORTED.
abort:
	return;
}
 





//**************************************************************************
//*****************************  Test Cases  *******************************
//*  The following functions implement the tests
//**************************************************************************

//*---------------------------------------------------------------------------------
//| DoHelloWord:
//|	This is a simple test which uses the szLogPrintf and szMessageBox
//|	functions defined in GATORTST.DLL.
//|
//|	Note that this test also simulates an error by returning a count
//|	of 1.  This value is then totaled by ODBC Test and displayed as
//|	part of the grand total.
//|
//| Returns:
//|	Number of Errors or TEST_ABORTED
//*---------------------------------------------------------------------------------
SWORD FAR PASCAL DoHelloWorld(HENV FAR * phenv, HDBC FAR * phdbc,
				HSTMT FAR * phstmt, lpSERVERINFO lpSrvr)
{
	SWORD		sErr=1;						// Pretend there was 1 error

	// The szMessageBox function will display a formatted message via the
	//		Windows MessageBox function.  This function should not be used
	//		for standard testing since a good test will run unattended.
	szMessageBox(lpSrvr->hwnd, 
				MB_ICONINFORMATION | MB_OK,
				"Hello World",
				"This is a sample message.");
				
	// The szLogPrintf function is preferred for output operations.  It will
	//		format your string using wvsprintf (which has a limit of 2000 characters)
	//		and log the result both to the output window and to a file per
	//		user instructions.
	szLogPrintf(lpSrvr, FALSE, "\tHello World!!\r\n");


	// check for errors
	CHECKERRS(sErr);

	
	return sErr;
}


//*---------------------------------------------------------------------------------
//| DoDisplayInfoDesc:
//|	This test case will use the szLogPrintf function to dump the contents
//|	of the lpSrvr structure.
//|
//| Returns:
//|	Number of Errors or TEST_ABORTED
//*---------------------------------------------------------------------------------
SWORD FAR PASCAL DoDisplayInfoDesc(HENV FAR * phenv, HDBC FAR * phdbc,
				HSTMT FAR * phstmt, lpSERVERINFO lpSrvr)
{
	SWORD		sErr=0;

#ifndef WIN32
#define szAddress "%04X:%04X\r\n"
#else
#define szAddress "%08X\r\n"
#endif

	// The hwnd parameter is the window of style "edit" which is used for output.
	//	The szLogFile parameter is used for file logging of output.
	szLogPrintf(lpSrvr, FALSE,
				"\thwnd:\t\t\t\t\t\t\t%04X\r\n", lpSrvr->hwnd);
	szLogPrintf(lpSrvr, FALSE,
				"\tszLogFile:\t\t\t\t%s\r\n", (LPSTR)lpSrvr->szLogFile);

	// Print out address information.  Note that szAddress is conditionaly compiled
	//		to handle 16 and 32-bit.  It will be concatenated to the format string
	//		by the compiler to create a file platform correct string.
	szLogPrintf(lpSrvr, FALSE,
				"\thenv:\t\t\t\t\t\t\t" szAddress, 
				lpSrvr->henv);
	szLogPrintf(lpSrvr, FALSE,
				"\thdbc:\t\t\t\t\t\t\t" szAddress, 
				lpSrvr->hdbc);
	szLogPrintf(lpSrvr, FALSE,
				"\thstmt:\t\t\t\t\t\t\t" szAddress, 
				lpSrvr->hstmt);


	// The following are defined via the Tools, Manage Test Sources dialog in
	//		the ODBC Test application.
	szLogPrintf(lpSrvr, FALSE,
				"\tszSource:\t\t\t\t\t%s\r\n", (LPSTR)lpSrvr->szSource);
	szLogPrintf(lpSrvr, FALSE,
				"\tszValidServer0:\t\t\t\t\t\t%s\r\n", (LPSTR)lpSrvr->szValidServer0);
	szLogPrintf(lpSrvr, FALSE,
				"\tszValidLogin0:\t\t\t\t\t\t%s\r\n", (LPSTR)lpSrvr->szValidLogin0);
	szLogPrintf(lpSrvr, FALSE,
				"\tszValidPassword0:\t\t\t%s\r\n", (LPSTR)lpSrvr->szValidPassword0);
	szLogPrintf(lpSrvr, FALSE,
				"\tszKeywords:\t\t\t%s\r\n", (LPSTR)lpSrvr->szKeywords);

	// The following elements describe the run-time environment	
	szLogPrintf(lpSrvr, FALSE,
				"\tcErrors:\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->cErrors);
	szLogPrintf(lpSrvr, FALSE,
				"\tfDebug:\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->fDebug);
	szLogPrintf(lpSrvr, FALSE,
				"\tfScreen:\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->fScreen);
	szLogPrintf(lpSrvr, FALSE,
				"\tfLog:\t\t\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->fLog);
	szLogPrintf(lpSrvr, FALSE,
				"\tfIsolate:\t\t\t\t\t\t%d\r\n", (LPSTR)lpSrvr->fIsolate);
	szLogPrintf(lpSrvr, FALSE,
				"\tvCursorLib:\t\t\t\t%lu\r\n", (LPSTR)lpSrvr->vCursorLib);
	szLogPrintf(lpSrvr, FALSE,
				"\thLoadedInst:\t\t\t%04X\r\n", (LPSTR)lpSrvr->hLoadedInst);
	
	// check for errors
	CHECKERRS(sErr);

	return sErr;
}


//*---------------------------------------------------------------------------------
//| DoSimpleConnect:
//|	This test case will use the information in SERVERINFO to make a connection
//|		to the chosen test source.
//|
//| Returns:
//|	Number of Errors or TEST_ABORTED
//*---------------------------------------------------------------------------------
SWORD FAR PASCAL DoSimpleConnect(HENV FAR * phenv, HDBC FAR * phdbc,
				HSTMT FAR * phstmt, lpSERVERINFO lpSrvr)
{
	RETCODE			rc;
	SWORD				sErr=0;

	// This test will assume that the ODBC handles passed in
	//		are NULL.  One could have this function do a connection
	//		and pass the handles to other test functions.
	rc = SQLAllocEnv(phenv);
	CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLAllocEnv");
	
	rc = SQLAllocConnect(*phenv, phdbc);
	CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLAllocConnect");
	
	rc = SQLConnect(*phdbc, lpSrvr->szValidServer0, SQL_NTS,
									lpSrvr->szValidLogin0, SQL_NTS,
									lpSrvr->szValidPassword0, SQL_NTS);
	CHECKTEST(lpSrvr,
			(RETCODE)((rc == SQL_SUCCESS || rc == SQL_SUCCESS_WITH_INFO)
						? rc : SQL_SUCCESS),
			rc, "SQLConnect");
	
	rc = SQLAllocStmt(*phdbc, phstmt);
	CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLAllocStmt");
	
	rc = SQLFreeStmt(*phstmt, SQL_DROP);
	CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLFreeStmt");
	
	rc = SQLDisconnect(*phdbc);
	CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLDisconnect");
	
	rc = SQLFreeConnect(*phdbc);
	CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLFreeConnect");
	
	rc = SQLFreeEnv(*phenv);
	CHECKTEST(lpSrvr, SQL_SUCCESS, rc, "SQLFreeEnv");


	// check for errors
	CHECKERRS(sErr);

	
	return sErr;
}

 
 
 





//**************************************************************************
//*************************  Utility Functions  ****************************
//*  This section contains internal utility functions
//**************************************************************************




//*---------------------------------------------------------------------------------
//| CheckTest:
//|	This function will do a simple comparison of return codes and issue
//|	erros on failure.  Use the CHECKTEST macro to invoke.
//|
//| Returns:
//|	TRUE if the codes match, FALSE on error
//*---------------------------------------------------------------------------------
BOOL FAR PASCAL CheckTest(lpSERVERINFO lps, RETCODE exprc, RETCODE actrc,
				LPSTR	szFuncName)
{
	if(exprc != actrc) {
		szLogPrintf(lps, FALSE, "\t%s failed:\r\n", (LPSTR)szFuncName);
		szLogPrintf(lps, FALSE, "\t\tExpected: %d\r\n", exprc);
		szLogPrintf(lps, FALSE, "\t\tActual:   %d\r\n", actrc);
		return FALSE;
		}
	else
		return TRUE;
}