1 /********************************************** 2 * driverextras.h 3 * 4 * Purpose: 5 * 6 * To define driver specifc extras such as structs to be included 7 * along side the common ODBC includes. 8 * 9 * Description: 10 * 11 * The short-term storage a driver requires as infrastructure varies somewhat from 12 * DBMS to DBMS. The ODBC DriverManager requires predictable storage and it is defined 13 * in drivermanager.h. The Driver also requires predictable storage and 14 * it is defined in driver.h. Storage *specific to a type of driver* is defined here. 15 * 16 * The three main storage items are the ENV, DBC, and STMT structs. These are defined 17 * as type void * in isql.h. 18 * 19 * So if your driver requires extra storage (and it probably does) then define 20 * the storage within these structs, allocate/initialize as required. Cast them 21 * to and from the standard names as required. 22 * 23 * For example; 24 * 25 * App DM |DRV 26 * (as per hdbc.h) |(as per driver.h) 27 *==================================================================== 28 * hDbc=void* hDbc=SQLHDBC hDbc=HDBCEXTRAS 29 *-------------------------------------------------------------------- 30 * 31 * DO NOT FORGET TO FREE ANY ALLOCATED MEMORY (at some point) 32 * 33 ********************************************************************** 34 * 35 * This code was created by Peter Harvey (mostly during Christmas 98/99). 36 * This code is LGPL. Please ensure that this message remains in future 37 * distributions and uses of this code (thats about all I get out of it). 38 * - Peter Harvey pharvey@codebydesign.com 39 * 40 **********************************************************************/ 41 42 #ifndef DRIVEREXTRAS_H 43 #define DRIVEREXTRAS_H 44 45 /********************************************** 46 * KEEP IT SIMPLE; PUT ALL DRIVER INCLUDES HERE THEN EACH DRIVER MODULE JUST INCLUDES THIS ONE FILE 47 **********************************************/ 48 #include <stdlib.h> 49 #include <stdio.h> 50 #include <string.h> 51 #include <ctype.h> 52 #include <time.h> 53 54 /**************************** 55 * include DBMS specific includes here and make any required defines here as well */ 56 57 58 59 60 /***************************/ 61 62 63 /********************************************** 64 * ENVIRONMENT: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS ENVIRONMENT 65 **********************************************/ 66 typedef struct tENVEXTRAS 67 { 68 /**************************** 69 * this is usually left empty 70 ***************************/ 71 int nDummy; 72 73 } ENVEXTRAS, *HENVEXTRAS; 74 75 /********************************************** 76 * CONNECTION: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS CONNECTIONS 77 **********************************************/ 78 79 typedef struct tDBCEXTRAS 80 { 81 /**************************** 82 * replace dummy with your DBMS specific stuff. This often means such things as a socket handle. 83 ***************************/ 84 int nDummy; 85 86 } DBCEXTRAS, *HDBCEXTRAS; 87 88 /********************************************** 89 * STATEMENT: DRIVER SPECIFIC STUFF THAT NEEDS TO BE STORED IN THE DRIVERS STATEMENTS 90 **********************************************/ 91 typedef struct tCOLUMNHDR /* each element of the 1st row of results is one of these (except col 0) */ 92 { 93 /* EVERYTHING YOU WOULD EVER WANT TO KNOW ABOUT THE COLUMN. INIT THIS BY CALLING */ 94 /* _NativeToSQLColumnHeader AS SOON AS YOU HAVE COLUMN INFO. THIS MAKES THE COL HDR LARGER */ 95 /* BUT GENERALIZES MORE CODE. see SQLColAttribute() */ 96 int bSQL_DESC_AUTO_UNIQUE_VALUE; /* IS AUTO INCREMENT COL? */ 97 char *pszSQL_DESC_BASE_COLUMN_NAME; /* empty string if N/A */ 98 char *pszSQL_DESC_BASE_TABLE_NAME; /* empty string if N/A */ 99 int bSQL_DESC_CASE_SENSITIVE; /* IS CASE SENSITIVE COLUMN? */ 100 char *pszSQL_DESC_CATALOG_NAME; /* empty string if N/A */ 101 int nSQL_DESC_CONCISE_TYPE; /* ie SQL_CHAR, SQL_TYPE_TIME... */ 102 int nSQL_DESC_DISPLAY_SIZE; /* max digits required to display */ 103 int bSQL_DESC_FIXED_PREC_SCALE; /* has data source specific precision? */ 104 char *pszSQL_DESC_LABEL; /* display label, col name or empty string */ 105 int nSQL_DESC_LENGTH; /* strlen or bin size */ 106 char *pszSQL_DESC_LITERAL_PREFIX; /* empty string if N/A */ 107 char *pszSQL_DESC_LITERAL_SUFFIX; /* empty string if N/A */ 108 char *pszSQL_DESC_LOCAL_TYPE_NAME; /* empty string if N/A */ 109 char *pszSQL_DESC_NAME; /* col alias, col name or empty string */ 110 int nSQL_DESC_NULLABLE; /* SQL_NULLABLE, _NO_NULLS or _UNKNOWN */ 111 int nSQL_DESC_NUM_PREC_RADIX; /* 2, 10, or if N/A... 0 */ 112 int nSQL_DESC_OCTET_LENGTH; /* max size */ 113 int nSQL_DESC_PRECISION; /* */ 114 int nSQL_DESC_SCALE; /* */ 115 char *pszSQL_DESC_SCHEMA_NAME; /* empty string if N/A */ 116 int nSQL_DESC_SEARCHABLE; /* can be in a filter ie SQL_PRED_NONE... */ 117 char *pszSQL_DESC_TABLE_NAME; /* empty string if N/A */ 118 int nSQL_DESC_TYPE; /* SQL data type ie SQL_CHAR, SQL_INTEGER.. */ 119 char *pszSQL_DESC_TYPE_NAME; /* DBMS data type ie VARCHAR, MONEY... */ 120 int nSQL_DESC_UNNAMED; /* qualifier for SQL_DESC_NAME ie SQL_NAMED */ 121 int bSQL_DESC_UNSIGNED; /* if signed FALSE else TRUE */ 122 int nSQL_DESC_UPDATABLE; /* ie SQL_ATTR_READONLY, SQL_ATTR_WRITE... */ 123 124 /* BINDING INFO */ 125 short nTargetType; /* BIND: C DATA TYPE ie SQL_C_CHAR */ 126 char *pTargetValue; /* BIND: POINTER FROM APPLICATION TO COPY TO*/ 127 long nTargetValueMax; /* BIND: MAX SPACE IN pTargetValue */ 128 long *pnLengthOrIndicator; /* BIND: TO RETURN LENGTH OR NULL INDICATOR */ 129 130 } COLUMNHDR; 131 132 typedef struct tSTMTEXTRAS 133 { 134 char **aResults; /* nRows x nCols OF CHAR POINTERS. Row 0= ptrs to COLUMNHDR. Col 0=Bookmarks */ 135 int nCols; /* # OF VALID COLUMNS IN aColumns */ 136 int nRows; /* # OF ROWS IN aResults */ 137 int nRow; /* CURRENT ROW */ 138 139 } STMTEXTRAS, *HSTMTEXTRAS; 140 141 142 /* 143 * Shadow functions 144 * 145 * There are times when a function needs to call another function to use common functionality. When the 146 * called function is part of the ODBC API (an entry point to the driver) bad things can happen. The 147 * linker will get confused and call the same-named function elsewhere in the namespace (ie the Driver 148 * Manager). To get around this you create a shadow function - a function with a slightly different name 149 * that will not be confused with others - and then put most if not all of the functionality in there for 150 * common use. 151 * 152 */ 153 SQLRETURN SQLGetDiagRec_( SQLSMALLINT nHandleType, 154 SQLHANDLE hHandle, 155 SQLSMALLINT nRecordNumber, 156 SQLCHAR * pszState, 157 SQLINTEGER * pnNativeError, 158 SQLCHAR * pszMessageText, 159 SQLSMALLINT nBufferLength, 160 SQLSMALLINT * pnStringLength 161 ); 162 163 SQLRETURN _GetData( SQLHSTMT hDrvStmt, 164 SQLUSMALLINT nCol, 165 SQLSMALLINT nTargetType, 166 SQLPOINTER pTarget, 167 SQLLEN nTargetLength, 168 SQLLEN *pnLengthOrIndicator ); 169 170 /* 171 * Internal Support Functions 172 */ 173 SQLRETURN _NativeToSQLColumnHeader( COLUMNHDR *pColumnHeader, 174 void *pNativeColumnHeader ); 175 int _NativeToSQLType( void *pNativeColumnHeader ); 176 char *_NativeTypeDesc( char *pszTypeName, 177 int nType ); 178 int _NativeTypeLength( void *pNativeColumnHeader ); 179 int _NativeTypePrecision( void *pNativeColumnHeader ); 180 181 SQLRETURN template_SQLPrepare( SQLHSTMT hDrvStmt, 182 SQLCHAR *szSqlStr, 183 SQLINTEGER nSqlStrLength ); 184 185 #endif 186 187 188