QUIKTEST.H
//**************************************************************************** 
//|   Title:   quiktest.h 
//|  
//|   (c) Copyright 1991, 1992, 1993, 1994, 1995 
//|       by Microsoft Corp. 
//|  
//****************************************************************************** 
#ifndef quiktest_defs 
#define quiktest_defs 
 
 
/*-----------------------------------------------------------------------------------*/ 
/*constants defines */ 
/*-----------------------------------------------------------------------------------*/ 
#define MAX_QUERY_SIZE2048 
#define MAX_BIND_ELEMENTS100 
#define MAX_BIND_ARRAY_ELEMENTMAX_QUERY_SIZE / MAX_BIND_ELEMENTS 
#define MAX_STRING_SIZE350  // Increased from 255 due to overwrite 
#define MAX_PARAM_SIZE129 
#define MAX_DATA_SIZE45 
#define MAX_COLUMN_LIST_SIZE200 
#define MAX_COLUMN_NAME_SIZE100 
#define MAX_INSERT_VALUES_SIZE200 
#define MAX_TYPES_SUPPORTED25 
#define MAX_TYPE_NAME129 
#define MAX_FIELD40 
#define MAX_PREFIX129 
#define MAX_SUFFIX129 
#define MAX_TABLE_NAME60 
#define MAX_NUM_BUFFER60 
#define MAX_ERROR_SIZE200 
#define MAX_ROW_ITEM_LIMIT4 
 
#define PREFIX_SIZE3 
#define IGNORED999 
#define TEST_CONNECT_OPTION15 
#define TEST_STMT_OPTION300 
#define SCALEDIFF4 
#define ABORT-1 
#define TYPE_PORTION4 
#define MAXUDWORD((UDWORD)(-1)) 
#define MINSDWORD(-(SDWORD)((MAXUDWORD / 2) + 1)) 
#define MAXSDWORD((SDWORD)(MAXUDWORD / 2)) 
 
#define SMALLBUFF100 
#define MEDBUFF200 
#define LARGEBUFF300 
#define XLARGEBUFF1024 
#define STATE_SIZE6 
#define COMBINED_SIZEMAX_ERROR_SIZE + 30 
 
// Descriptor type defines 
#define DESC_NONE0// No descriptor type 
#define DESC_APD1// APD only 
#define DESC_IPD2// IPD only 
#define DESC_ARD4// ARD only 
#define DESC_IRD8// IRD only 
#define DESC_PDDESC_APD|DESC_IPD//Parameter descriptors 
#define DESC_RDDESC_ARD|DESC_IRD// Row descriptors 
#define DESC_IDDESC_IPD|DESC_IRD// Implementation descriptors 
#define DESC_ADDESC_APD|DESC_ARD// Application descriptors 
#define DESC_MOSTDESC_AD|DESC_IPD// This is the most common settable combination 
#define DESC_ALLDESC_APD|DESC_IPD|DESC_ARD|DESC_IRD// All descriptor types 
 
#define STATUS_ARRAY_SIZE5// Array size to use for row and param arrays 
#define BIND_SIZE12// Bind type size value 
 
/* NUM_THREAD is the number of threads that will be created for multi-thread test */ 
#define NUM_THREAD5 
#define NUM_QUIKREBIND_ROWSETS6 
 
/* BIND_PARM_OFFSET specifies the parameter base for DAE bindings. Either 0 */ 
/* or 1 based.  */ 
#define BIND_PARM_OFFSET0 
 
// COLNAME_START specifies the beginning number used in colnames, i.e. c00bit  
// vs. c01bit. 
#define COLNAME_START1 
 
/*constants for Descriptor tests */ 
#define MAX_DESC_BUF200 
#define DESC_UPDATE_MODE_READ0 
#define DESC_UPDATE_MODE_WRITE1 
#define REC_COUNT_UNK-1// Unkown record count 
// #define DESC_LOCATE_FAIL-1 
 
/* constants for TestBindParam */ 
#define INSERT_FAIL  -1 
 
#define UNTOUCHED 0xCA 
 
/*------------------------------------------------------------------------------------*/ 
/*macros                                                                             */ 
/*------------------------------------------------------------------------------------*/ 
 
#define RC_SUCCESSFUL(rc)((rc) == SQL_SUCCESS || \ 
    (rc) == SQL_SUCCESS_WITH_INFO) 
 
#define RC_NOTSUCCESSFUL(rc) (!(RC_SUCCESSFUL(rc))) 
 
#define RETCHECK(exp, rec, buf) ReturnCheck(exp, rec, buf, TEXT(__FILE__), __LINE__,FALSE) 
 
#define ERRSHANDLE(type, handle, exp, rec, buf) ErrsHandle(type, handle, exp, rec, buf, TEXT(__FILE__), __LINE__,FALSE) 
 
#define DIAGRETCHECK(exp, rec, buf) ReturnCheck(exp, rec, buf, TEXT(__FILE__), __LINE__,TRUE) 
 
#define DISPLAYERROR(func, string) qtDisplayError(func, string, TEXT(__FILE__), __LINE__) 
 
/*--------------------------------------------------------------------------------------*/ 
/*Structure definitions    */ 
/*--------------------------------------------------------------------------------------*/ 
 
/* Number of Cols in result set of a query: */ 
UWORD cNumResSetCols; 
 
/* used to store information from GetTypeInfo for table creation */ 
typedef struct FieldInfo { 
int iField; 
TCHAR szType[MAX_TYPE_NAME]; 
TCHAR szFieldName[MAX_FIELD]; 
SWORD  wSQLType; 
TCHAR szParams[MAX_PARAM_SIZE]; 
TCHAR szLength[MAX_FIELD]; 
TCHAR szPrefix[MAX_PREFIX]; 
TCHAR szSuffix[MAX_SUFFIX]; 
SDWORD precision; 
SWORD scale; 
SWORD nullable; 
UDWORD length; 
int   fAutoUpdate; 
SWORD fSearchable; 
SDWORD fUnsigned; 
SWORD autoinc; 
} FIELDINFO; 
 
 
 
/* large buffers allocated as a global used for queries and other*/ 
/* returned information                                          */ 
typedef struct  tagQtStruct { 
TCHARbuf[MAX_STRING_SIZE]; 
TCHARsz[MAX_QUERY_SIZE]; 
TCHARszParamQuery[MAX_QUERY_SIZE]; 
TCHARszParam[MAX_PARAM_SIZE]; 
TCHARszDataItem[MAX_DATA_SIZE]; 
TCHARszTableName[MAX_TABLE_NAME]; 
TCHARszColNames[MAX_COLUMN_LIST_SIZE]; 
TCHARszColName[MAX_COLUMN_NAME_SIZE]; 
TCHARszValues[MAX_INSERT_VALUES_SIZE]; 
}       QTSTRUCT; 
 
/* the storage used for data retreived using bind/fetch sequence  */ 
/* and data for BindParameter                                     */ 
/* only cb and one of the types will be used for each entry       */ 
typedef struct tagDataStruct { 
SDWORD cb; 
TCHAR data[MAX_STRING_SIZE]; 
SDWORD sdword; 
UDWORD udword; 
SWORD sword; 
UWORD uword; 
TCHARsChar; 
SQLTCHAR uChar; 
SDOUBLE sdouble; 
SFLOAT sfloat; 
TIME_STRUCT time; 
DATE_STRUCT date; 
TIMESTAMP_STRUCT timestamp; 
} DSTRUCT; 
 
/* These declarations used to reside locally, but the structures didn't get initialized correctly */ 
typedef struct SupportOptList { 
UDWORD Support; 
SDWORD Option; 
} SUPPORTOPTINFO; 
 
typedef struct SupportConcurList { 
UDWORD Support; 
UWORD Option; 
} SUPPORTCONCURINFO; 
 
 
 
/* Each thread will contain the following information */ 
typedef struct { 
HENVhenv; 
HDBChdbc; 
TCHARszTableName[MAX_TABLE_NAME]; 
FIELDINFO rgFieldInfo; 
 
} THREAD_STRUCT; 
 
 
static union 
{ 
BYTE rgb[max(max(max(sizeof (HENV),sizeof (HDBC)), 
max(sizeof (HSTMT), sizeof (SQLHDESC))),sizeof (UDWORD))]; 
SWORD sw; 
UWORD uw; 
SDWORD sdw; 
UDWORD udw; 
HENV henv; 
HDBC hdbc; 
HSTMT hstmt; 
SQLHDESC hdesc; 
} Untouched = {UNTOUCHED, UNTOUCHED, UNTOUCHED, UNTOUCHED}; 
  
 
 
int  PASCAL ReturnCheck(RETCODE retExpected, RETCODE retReceived, LPTSTR szFunction,  
LPTSTR szFile, int iLine,BOOL fDiag); 
void PASCAL qtDisplayError(LPTSTR szFunction, LPTSTR buf, LPTSTR szFile, int iLine); 
LPTSTR PASCAL qtMakeData(int row, int col,FIELDINFO * rgField, LPTSTR buf); 
 
BOOL PASCAL CmpODBCtoCHAR(DSTRUCT * rgTestValue, TCHAR * szTrueValue, 
SWORD fSqlType, SWORD iResSetCol); 
 
void* PASCAL CvtCHARtoODBC(void * odbcValue, TCHAR * buf, SWORD fSqlType) 
{ 
if(!buf) 
return NULL; 
 
switch (fSqlType) { 
case SQL_DATE:  
case SQL_TYPE_DATE:  
{ 
TCHAR szDATEDELIM[] = TEXT("d{}'- "); 
TCHAR szTempBuff[30]; 
LPTSTR   tmpstr=szTempBuff; 
_tcscpy((LPTSTR) szTempBuff, buf); 
 
((DATE_STRUCT *)odbcValue)->year = _ttoi(_tcstok(tmpstr, szDATEDELIM)); 
((DATE_STRUCT *)odbcValue)->month = _ttoi(_tcstok(NULL, szDATEDELIM)); 
((DATE_STRUCT *)odbcValue)->day = _ttoi(_tcstok(NULL, szDATEDELIM)); 
break; 
} 
 
 
case SQL_TIME:  
case SQL_TYPE_TIME:  
{ 
TCHAR szTIMEDELIM[] = TEXT("t{}': "); 
TCHAR szTempBuff[30]; 
LPTSTR   tmpstr=szTempBuff; 
_tcscpy((LPTSTR) szTempBuff, buf); 
 
((TIME_STRUCT *)odbcValue)->hour = _ttoi(_tcstok(tmpstr, szTIMEDELIM)); 
((TIME_STRUCT *)odbcValue)->minute = _ttoi(_tcstok(NULL, szTIMEDELIM)); 
((TIME_STRUCT *)odbcValue)->second = _ttoi(_tcstok(NULL, szTIMEDELIM)); 
 
break; 
} 
 
case SQL_TIMESTAMP: 
case SQL_TYPE_TIMESTAMP: 
{ 
TCHAR szDATETIMEDELIM[] = TEXT("ts'{}-:. "); 
TCHAR szTempBuff[30]; 
LPTSTR   tmpstr=szTempBuff; 
LPTSTRendstr, frstr; 
_tcscpy((LPTSTR) szTempBuff, buf); 
 
/* First the date */ 
((TIMESTAMP_STRUCT *)odbcValue)->year = _ttoi(_tcstok(tmpstr, szDATETIMEDELIM)); 
((TIMESTAMP_STRUCT *)odbcValue)->month = _ttoi(_tcstok(NULL, szDATETIMEDELIM)); 
((TIMESTAMP_STRUCT *)odbcValue)->day = _ttoi(_tcstok(NULL, szDATETIMEDELIM)); 
/* Then the complete time */ 
((TIMESTAMP_STRUCT *)odbcValue)->hour = _ttoi(_tcstok(NULL, szDATETIMEDELIM)); 
((TIMESTAMP_STRUCT *)odbcValue)->minute = _ttoi(_tcstok(NULL, szDATETIMEDELIM)); 
((TIMESTAMP_STRUCT *)odbcValue)->second = _ttoi(_tcstok(NULL, szDATETIMEDELIM)); 
if(frstr = _tcstok(NULL, szDATETIMEDELIM)) 
((TIMESTAMP_STRUCT *)odbcValue)->fraction = (_tcstoul(frstr, &endstr, 10) * 1000000); 
else 
((TIMESTAMP_STRUCT *)odbcValue)->fraction = 0; 
 
break; 
} 
 
} 
return odbcValue; 
} 
 
 
/* Compares the value stored at location (row,col) in the array of  
 * DSTRUCT's with the value created by qtMakeData*/ 
BOOL PASCAL CmpODBCtoCHAR(DSTRUCT * rgTestValue, TCHAR * szTrueValue, 
SWORD fSqlType, SWORD iCol) 
{ 
BOOL fTestPass=TRUE; 
SWORD test1,test2; 
TCHAR*pStop=NULL; 
 
switch (fSqlType) { 
case SQL_BIGINT: 
case SQL_INTEGER: 
if(_ttoi(szTrueValue) == (int)rgTestValue[iCol].sdword)  
return TRUE; 
return FALSE; 
 
case SQL_DECIMAL: 
case SQL_NUMERIC: 
return  (_tcstod(szTrueValue,&pStop) ==  
(float)_tcstod(rgTestValue[iCol].data,&pStop)); 
case SQL_TINYINT: 
case SQL_SMALLINT: 
if(_ttoi(szTrueValue) == (int)rgTestValue[iCol].sword) 
return TRUE; 
return FALSE; 
 
case SQL_FLOAT: 
case SQL_DOUBLE:  
return  (_tcstod(szTrueValue,&pStop) == (float)rgTestValue[iCol].sdouble); 
 
case SQL_REAL: 
/* Need to account for round-off errors in _tcstod conversions: */ 
test1 = (SWORD)(1000*_tcstod(szTrueValue,&pStop)); 
test1 = (SWORD)((test1>0) ? (test1+5)/10 : (test1-5)/10); 
test2 = (SWORD)(1000*rgTestValue[iCol].sfloat); 
test2 = (SWORD)((test2>0) ? (test2+5)/10 : (test2-5)/10); 
return  (test1 == test2); 
 
case SQL_TIMESTAMP:  
case SQL_TYPE_TIMESTAMP:  
{ 
TIMESTAMP_STRUCT tss; 
CvtCHARtoODBC(&tss, szTrueValue, SQL_TYPE_TIMESTAMP); 
 
fTestPass= ((rgTestValue[iCol].timestamp.month == tss.month) 
&& (rgTestValue[iCol].timestamp.day == tss.day) 
&& (rgTestValue[iCol].timestamp.year == tss.year) 
&& (rgTestValue[iCol].timestamp.hour == tss.hour) 
&& (rgTestValue[iCol].timestamp.minute == tss.minute) 
&& (rgTestValue[iCol].timestamp.fraction == 
tss.fraction)); 
/* Seconds value is zero for small timestamp, so to keep it from always failing... */ 
if(0 != rgTestValue[iCol].timestamp.second) 
fTestPass= (fTestPass && rgTestValue[iCol].timestamp.second == tss.second); 
return fTestPass; 
} 
 
case SQL_TIME:  
case SQL_TYPE_TIME:  
{ 
TIME_STRUCT tss; 
 
CvtCHARtoODBC(&tss, szTrueValue, SQL_TYPE_TIME); 
fTestPass=  ((rgTestValue[iCol].time.hour == tss.hour) 
&& (rgTestValue[iCol].time.minute == tss.minute)); 
/* Seconds value is zero for small timestamp, so to keep it from always failing... */ 
if(0 != rgTestValue[iCol].time.second) 
fTestPass= (fTestPass && rgTestValue[iCol].time.second == tss.second); 
return fTestPass; 
} 
 
case SQL_DATE:  
case SQL_TYPE_DATE:  
{ 
DATE_STRUCT tss; 
CvtCHARtoODBC(&tss, szTrueValue, SQL_TYPE_DATE); 
 
return ((rgTestValue[iCol].date.month == tss.month) 
&& (rgTestValue[iCol].date.day == tss.day) 
&& (rgTestValue[iCol].date.year == tss.year)); 
} 
 
 case SQL_BIT:  
 case SQL_CHAR:  
case SQL_VARCHAR: 
case SQL_LONGVARCHAR: 
case SQL_BINARY:   
case SQL_VARBINARY:   
case SQL_LONGVARBINARY:  
default: 
return !(_tcsncmp(szTrueValue, rgTestValue[iCol].data,  
_tcslen(szTrueValue))); 
 
} 
} 
 
 
#endif