Main Page   Class Hierarchy   File List  

odbcTypeMaps.h

00001 /*
00002 
00003   odbcTypeMaps.h
00004   ==============
00005   ODBC to openField conversion and fixup.
00006 
00007 */
00008 #ifndef ODBC_TYPE_MAPS_H
00009 #define ODBC_TYPE_MAPS_H
00010 #include "fmtTime.h"
00011 const int cOL_nAMe_Len = 255;
00012 /*
00013   Helper Classes
00014   ==============
00015 */
00016 
00017 struct odbcColInfo
00018 {
00019   UCHAR  szColName [cOL_nAMe_Len] ;
00020   SWORD  cbColName;
00021   SWORD  fSqlType;
00022   UDWORD cbColDef; // Will have length, SQL_NULL_DATA if the data is NULL, or SQL_NO_TOTAL
00023   SWORD  ibScale;
00024   SWORD  fNullable;
00025   CHAR * pCharData;
00026   SDWORD length;   // Will have length, SQL_NULL_DATA if the data is NULL, or SQL_NO_TOTAL
00027   TIMESTAMP_STRUCT timeData;
00028 
00029   odbcColInfo() :cbColName(sizeof(szColName)),fSqlType(0)
00030              ,cbColDef(0),ibScale(0),fNullable(0),pCharData(NULL),length(0)
00031   {
00032     memset(szColName, 0, sizeof(szColName) );
00033   }
00034   ~odbcColInfo() { delete [] pCharData; }
00035 };
00036 // col. pos. based lookup
00037 typedef vector< odbcColInfo * > colInfoVector;
00038 
00039 struct mapItem
00040 {
00041   SWORD cType;
00042   mapItem(SWORD c):cType(c){;}
00043   virtual ~mapItem(){;}
00044   virtual basicField * createField( odbcColInfo * info, bool isClient=false ) = 0;
00045   virtual void * thingToBind( odbcColInfo * info, basicField * field ) = 0;
00046   virtual void postFetchFixup( odbcColInfo * info, basicField * field ) = 0;
00047 };
00048 // SQL type based lookup
00049 typedef map <SWORD, mapItem *> sql_to_c_types;
00050 
00051 struct mapString : public mapItem
00052 {
00053   mapString():mapItem(SQL_C_CHAR){;}
00054   virtual ~mapString(){;}
00055   virtual basicField * createField( odbcColInfo * info, bool isClient=false )
00056   {
00057     // first allocate buffer for bind op on string data.
00058     if( (SDWORD)info->cbColDef != SQL_NO_TOTAL  )
00059     {
00060       info->pCharData = new char[info->cbColDef+1];  // +1 adds the string terminator
00061     }
00062     // next create the field
00063     return new stringField( "", false, true, (char*) info->szColName, "" );
00064   }
00065   virtual void * thingToBind( odbcColInfo * info, basicField * field )
00066   {
00067     return (void*) info->pCharData;
00068   }
00069   virtual void postFetchFixup( odbcColInfo * info, basicField * field )
00070   {
00071     field->setNull(false);
00072 
00073     /* debugging
00074     cout << info->szColName
00075          << " info->length: "
00076          << info->length
00077          << " info->pCharData: "
00078          << &info->pCharData << endl;
00079     */
00080     if( info->length == SQL_NULL_DATA )
00081     {
00082       field->setNull();
00083       dynamic_cast<stringField*>(field)->set("");
00084     }
00085     else
00086     {
00087       dynamic_cast<stringField*>(field)->set(string(info->pCharData));
00088     }
00089   }
00090 };  // end of mapString class
00091 
00092 
00093 struct mapBool  : public mapItem
00094 {
00095   mapBool():mapItem(SQL_C_BIT){;}
00096   virtual ~mapBool(){;}
00097   virtual basicField * createField( odbcColInfo * info, bool isClient=false )
00098   {
00099     return new boolField( false, false, true, (char*)info->szColName, "" );
00100   }
00101   virtual void * thingToBind( odbcColInfo * info, basicField * field )
00102   {
00103     return (void*) & dynamic_cast<boolField*>(field)->get();
00104   }
00105   virtual void postFetchFixup( odbcColInfo * info, basicField * field )
00106   {
00107     field->setNull(false);
00108     if( info->length == SQL_NULL_DATA )
00109     {
00110       field->setNull();
00111       dynamic_cast<boolField*>(field)->set(false);
00112     }
00113     else if( dynamic_cast<boolField*>(field)->get() )
00114       dynamic_cast<boolField*>(field)->set(true);
00115     else
00116       dynamic_cast<boolField*>(field)->set(false);
00117   }
00118 }; // end of mapBool class
00119 
00120 struct mapShort  : public mapItem
00121 {
00122   mapShort():mapItem(SQL_C_SHORT){;}
00123   virtual ~mapShort(){;}
00124   virtual basicField * createField( odbcColInfo * info, bool isClient=false )
00125   {
00126     return new shortField( 0, false, true, (char*)info->szColName, "" );
00127   }
00128   virtual void * thingToBind( odbcColInfo * info, basicField * field )
00129   {
00130     return (void*) & dynamic_cast<shortField*>(field)->get();
00131   }
00132   virtual void postFetchFixup( odbcColInfo * info, basicField * field )
00133   {
00134     field->setNull(false);
00135     if( info->length == SQL_NULL_DATA )
00136     {
00137       field->setNull();
00138       dynamic_cast<shortField*>(field)->set(0);
00139     }
00140   }
00141 }; // end of mapShort class
00142 
00143 struct mapLong  : public mapItem
00144 {
00145   mapLong():mapItem(SQL_C_LONG){;}
00146   virtual ~mapLong(){;}
00147   virtual basicField * createField( odbcColInfo * info, bool isClient=false )
00148   {
00149     return new longField( 0, false, true, (char*)info->szColName, "" );
00150   }
00151   virtual void * thingToBind( odbcColInfo * info, basicField * field )
00152   {
00153     return (void*) & dynamic_cast<longField*>(field)->get();
00154   }
00155   virtual void postFetchFixup( odbcColInfo * info, basicField * field )
00156   {
00157     field->setNull(false);
00158     if( info->length == SQL_NULL_DATA )
00159     {
00160       field->setNull();
00161       dynamic_cast<longField*>(field)->set(0L);
00162     }
00163   }
00164 }; // end of mapLong class
00165 
00166 struct mapFloat  : public mapItem
00167 {
00168   mapFloat():mapItem(SQL_C_FLOAT){;}
00169   virtual ~mapFloat(){;}
00170   virtual basicField * createField( odbcColInfo * info, bool isClient=false )
00171   {
00172     return new floatField( 0.0, false, true, (char*)info->szColName, "" );
00173   }
00174   virtual void * thingToBind( odbcColInfo * info, basicField * field )
00175   {
00176     return (void*) & dynamic_cast<floatField*>(field)->get();
00177   }
00178   virtual void postFetchFixup( odbcColInfo * info, basicField * field )
00179   {
00180     field->setNull(false);
00181     if( info->length == SQL_NULL_DATA )
00182     {
00183       field->setNull();
00184       dynamic_cast<floatField*>(field)->set(0.0);
00185     }
00186   }
00187 }; // end of mapFloat class
00188 
00189 struct mapDouble  : public mapItem
00190 {
00191   mapDouble():mapItem(SQL_C_DOUBLE){;}
00192   virtual ~mapDouble(){;}
00193   virtual basicField * createField( odbcColInfo * info, bool isClient=false )
00194   {
00195     return new doubleField( 0.0, false, true, (char*)info->szColName, "" );
00196   }
00197   virtual void * thingToBind( odbcColInfo * info, basicField * field )
00198   {
00199     return (void*) & dynamic_cast<doubleField*>(field)->get();
00200   }
00201   virtual void postFetchFixup( odbcColInfo * info, basicField * field )
00202   {
00203     field->setNull(false);
00204     if( info->length == SQL_NULL_DATA )
00205     {
00206       field->setNull();
00207       dynamic_cast<doubleField*>(field)->set(0.0);
00208     }
00209   }
00210 };  // end of mapDouble class
00211 
00212 struct mapDateTime  : public mapItem
00213 {
00214   mapDateTime():mapItem(SQL_C_TIMESTAMP){;}
00215   virtual ~mapDateTime(){;}
00216   virtual basicField * createField( odbcColInfo * info, bool isClient=false )
00217   {
00218     tm t;
00219     currentTime(&t);
00220     return new dateTimeField( t, false, true, (char*)info->szColName, "" );
00221   }
00222   virtual void * thingToBind( odbcColInfo * info, basicField * field )
00223   {
00224     return (void*) & info->timeData;
00225   }
00226   virtual void postFetchFixup( odbcColInfo * info, basicField * field )
00227   {
00228     tm t;
00229     currentTime(&t);
00230     field->setNull(false);
00231     if( info->length == SQL_NULL_DATA )
00232     {
00233       field->setNull();
00234       dynamic_cast<dateTimeField*>(field)->set(t);
00235     }
00236     else
00237     {
00238       t.tm_min =  info->timeData.minute;
00239       t.tm_hour =  info->timeData.hour;
00240       t.tm_mday =  info->timeData.day;
00241       t.tm_year =  info->timeData.year-1900;
00242       t.tm_mon =  info->timeData.month-1;
00243       t.tm_sec =  info->timeData.second;
00244       fixTime(&t);
00245       dynamic_cast<dateTimeField*>(field)->set(t);
00246     }
00247   }
00248 }; // end of mapDateTime class
00249 
00250 struct mapNumeric : public mapItem
00251 {
00252   mapNumeric():mapItem(SQL_C_DOUBLE){;}
00253   virtual ~mapNumeric(){;}
00254   virtual basicField * createField( odbcColInfo * info, bool isClient=false )
00255   {
00256     currency temp;
00257     temp.amount=0.0;
00258     return new currencyField( temp, false, true, (char*)info->szColName, "" );
00259   }
00260   virtual void * thingToBind( odbcColInfo * info, basicField * field )
00261   {
00262     return (void*) &(dynamic_cast<currencyField*>(field)->get().amount);
00263   }
00264   virtual void postFetchFixup( odbcColInfo * info, basicField * field )
00265   {
00266     currency temp;
00267     temp.amount=0.0;
00268     field->setNull(false);
00269     if( info->length == SQL_NULL_DATA )
00270     {
00271       field->setNull();
00272       dynamic_cast<currencyField*>(field)->set(temp);
00273     }
00274   }
00275 };  // end of mapNumeric class
00276 
00277 /*
00278   Finally the point of the file, to provide helpers
00279   in the context of the ODBC return type from SQLDescribeCol():
00280   Map of SQL ODBC Type codes to Native C Types to field Objects to maps
00281   ========================================================================
00282   SQL_UNKNOWN_TYPE    0  -
00283   SQL_CHAR            1  SQL_C_CHAR          stringField       mapString
00284   SQL_NUMERIC         2  SQL_C_DOUBLE        currencyField     mapNumeric
00285   SQL_DECIMAL         3  SQL_C_DOUBLE        currencyField     mapNumeric
00286   SQL_INTEGER         4  SQL_C_LONG          longField         mapLong
00287   SQL_SMALLINT        5  SQL_C_SHORT         shortField        mapShort
00288   SQL_FLOAT           6  SQL_C_FLOAT         floatField        mapFloat
00289   SQL_REAL            7  SQL_C_FLOAT         floatField        mapFloat
00290   SQL_DOUBLE          8  SQL_C_DOUBLE        doubleField       mapDouble
00291   SQL_DATETIME        9  SQL_C_TIMESTAMP     dateTimeField     mapDateTime
00292   SQL_VARCHAR        12  SQL_C_CHAR          stringField       mapString
00293   SQL_DATE            9  SQL_C_TIMESTAMP     dateTimeField     mapDateTime
00294   SQL_INTERVAL       10  -
00295   SQL_TIME           10  SQL_C_TIMESTAMP     dateTimeField     mapDateTime
00296   SQL_TIMESTAMP      11  SQL_C_TIMESTAMP     dateTimeField     mapDateTime
00297 #define SQL_TYPE_DATE      91
00298 #define SQL_TYPE_TIME      92
00299 #define SQL_TYPE_TIMESTAMP 93
00300 
00301   SQL_LONGVARCHAR   (-1) SQL_C_CHAR          stringField       mapString
00302   SQL_BINARY        (-2) -
00303   SQL_VARBINARY     (-3) -
00304   SQL_LONGVARBINARY (-4) -
00305   SQL_BIGINT        (-5) SQL_C_LONG            longField       mapLong
00306   SQL_TINYINT       (-6) SQL_C_SHORT           shortField      mapShort
00307   SQL_BIT           (-7) SQL_C_BIT             boolField       mapBool
00308   ========================================================================
00309                       ( - means not handled here! )
00310 */
00311 struct odbcMap
00312 {
00313   sql_to_c_types data;
00314   odbcMap()
00315   {
00316     data.insert(make_pair(SQL_CHAR,new mapString));
00317     data.insert(make_pair(SQL_NUMERIC,new mapNumeric));
00318     data.insert(make_pair(SQL_DECIMAL,new mapNumeric));
00319     data.insert(make_pair(SQL_INTEGER,new mapLong));
00320     data.insert(make_pair(SQL_SMALLINT,new mapShort));
00321     data.insert(make_pair(SQL_FLOAT,new mapFloat));
00322     data.insert(make_pair(SQL_REAL,new mapFloat));
00323     data.insert(make_pair(SQL_DOUBLE,new mapDouble));
00324     data.insert(make_pair(SQL_DATETIME,new mapDateTime));
00325     data.insert(make_pair(SQL_VARCHAR,new mapString));
00326     data.insert(make_pair(SQL_DATE,new mapDateTime));
00327     data.insert(make_pair(SQL_TIME,new mapDateTime));
00328     data.insert(make_pair(SQL_TIMESTAMP,new mapDateTime));
00329     data.insert(make_pair(SQL_TYPE_DATE,new mapDateTime));
00330     data.insert(make_pair(SQL_TYPE_TIME,new mapDateTime));
00331     data.insert(make_pair(SQL_TYPE_TIMESTAMP,new mapDateTime));
00332     data.insert(make_pair(SQL_LONGVARCHAR,new mapString));
00333     data.insert(make_pair(SQL_BIGINT,new mapLong));
00334     data.insert(make_pair(SQL_TINYINT,new mapShort));
00335     data.insert(make_pair(SQL_BIT,new mapBool));
00336   }
00337   ~odbcMap()
00338   {
00339     sql_to_c_types::iterator pos;
00340 
00341     for( pos = data.begin(); pos != data.end(); ++pos )
00342     {
00343       delete pos->second;
00344     }
00345   }
00346 };
00347 #endif

Generated on Tue Jan 20 09:06:56 2004 for OpenTools by doxygen1.2.18