Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members  

/trees/alex/src/libodbc++/include/odbc++/types.h

00001 /* 
00002    This file is part of libodbc++.
00003    
00004    Copyright (C) 1999-2000 Manush Dodunekov <manush@stendahls.net>
00005    
00006    This library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Library General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010    
00011    This library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Library General Public License for more details.
00015    
00016    You should have received a copy of the GNU Library General Public License
00017    along with this library; see the file COPYING.  If not, write to
00018    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, USA.
00020 */
00021 
00022 #ifndef __ODBCXX_TYPES_H
00023 #define __ODBCXX_TYPES_H
00024 
00025 #include <odbc++/setup.h>
00026 
00027 #include <exception>
00028 
00029 #if !defined(ODBCXX_QT)
00030 # include <string>
00031 # else
00032 # include <qstring.h>
00033 #endif
00034 
00035 #include <ctime>
00036 #if defined(ODBCXX_NO_STD_TIME_T)
00037 namespace std {
00038   using ::time_t;
00039 };
00040 #endif
00041 
00042 #if defined(ODBCXX_QT)
00043 class QIODevice;
00044 #endif
00045 
00046 #if defined(ODBCXX_HAVE_ISQL_H) && defined(ODBCXX_HAVE_ISQLEXT_H)
00047 # include <isql.h>
00048 # include <isqlext.h>
00049 #elif defined(ODBCXX_HAVE_SQL_H) && defined(ODBCXX_HAVE_SQLEXT_H)
00050 # include <sql.h>
00051 # include <sqlext.h>
00052 #else
00053 # error "Whoops. Can not recognize the ODBC subsystem."
00054 #endif
00055 
00056 #if defined(ODBCXX_HAVE_SQLUCODE_H)
00057 # include <sqlucode.h>
00058 #endif
00059 
00060 // fixups for current iODBC, which kindly doesn't provide SQL_TRUE and
00061 // SQL_FALSE macros
00062 
00063 #if !defined(SQL_TRUE)
00064 # define SQL_TRUE 1
00065 #endif
00066 
00067 #if !defined(SQL_FALSE)
00068 # define SQL_FALSE 0
00069 #endif
00070 
00071 // MS ODBC SDK misses this in some releases
00072 #if ODBCVER >= 0x0300 && !defined(SQL_NOT_DEFERRABLE)
00073 # define SQL_NOT_DEFERRABLE 7
00074 #endif
00075 
00076 
00077 // Setup our ODBC3_C (odbc3 conditional) macro
00078 #if ODBCVER >= 0x0300
00079 
00080 # define ODBC3_C(odbc3_value,old_value) odbc3_value
00081 
00082 #else
00083 
00084 # define ODBC3_C(odbc3_value,old_value) old_value
00085 
00086 #endif
00087 
00088 
00089 // ODBC3_DC (odbc3 dynamic conditional)
00090 // Every context using this macro should provide
00091 // a this->_getDriverInfo() method returning
00092 // a const DriverInfo*
00093 
00094 #if ODBCVER >= 0x0300
00095 
00096 # define ODBC3_DC(odbc3_value,old_value) \
00097 (this->_getDriverInfo()->getMajorVersion()>=3?odbc3_value:old_value)
00098 
00099 #else
00100 
00101 # define ODBC3_DC(odbc3_value,old_value) old_value
00102 
00103 #endif
00104 
00105 #if defined(ODBCXX_HAVE_INTTYPES_H)
00106 # include <inttypes.h>
00107 #endif
00108 
00109 #include <vector>
00110 
00111 
00112 namespace odbc {
00113 
00114   // We want Long to be at least 64 bits
00115 
00116 #if defined(WIN32)
00117   
00118   typedef __int64 Long;
00119 
00120 #elif defined(ODBCXX_HAVE_INTTYPES_H)
00121 
00122   typedef int64_t Long;
00123 
00124 #else
00125 
00126 # if ODBCXX_SIZEOF_INT == 8
00127 
00128   typedef int Long;
00129 
00130 # elif ODBCXX_SIZEOF_LONG == 8
00131   
00132   typedef long Long;
00133 
00134 # elif ODBCXX_SIZEOF_LONG_LONG == 8
00135 
00136   typedef long long Long;
00137 
00138 # else
00139   
00140 #  error "Can't find an appropriate at-least-64-bit integer"
00141 
00142 # endif
00143 
00144 #endif
00145 
00146 
00147   //constants:
00148   //how much we try to fetch with each SQLGetData call
00149   const int GETDATA_CHUNK_SIZE=4*1024;
00150   //how much we write with each SQLPutData call
00151   const int PUTDATA_CHUNK_SIZE=GETDATA_CHUNK_SIZE;
00152 
00153   //how much we read/write in string<->stream conversion
00154   //better names for those?
00155   const int STRING_TO_STREAM_CHUNK_SIZE=1024;
00156   const int STREAM_TO_STRING_CHUNK_SIZE=STRING_TO_STREAM_CHUNK_SIZE;
00157 
00158 
00159 
00160 
00161 
00164   struct Types {
00167     enum SQLType {
00169       BIGINT            = SQL_BIGINT, 
00171       BINARY            = SQL_BINARY,
00173       BIT               = SQL_BIT,
00175       CHAR              = SQL_CHAR,
00177       DATE              = ODBC3_C(SQL_TYPE_DATE,SQL_DATE),
00179       DECIMAL           = SQL_DECIMAL,
00181       DOUBLE            = SQL_DOUBLE,
00183       FLOAT             = SQL_FLOAT,
00185       INTEGER           = SQL_INTEGER,
00187       LONGVARBINARY     = SQL_LONGVARBINARY,
00189       LONGVARCHAR       = SQL_LONGVARCHAR,
00191       NUMERIC           = SQL_NUMERIC,
00193       REAL              = SQL_REAL,
00195       SMALLINT          = SQL_SMALLINT,
00197       TIME              = ODBC3_C(SQL_TYPE_TIME,SQL_TIME),
00199       TIMESTAMP         = ODBC3_C(SQL_TYPE_TIMESTAMP,SQL_TIMESTAMP),
00201       TINYINT           = SQL_TINYINT,
00203       VARBINARY         = SQL_VARBINARY,
00205       VARCHAR           = SQL_VARCHAR
00206 #if defined(ODBCXX_HAVE_SQLUCODE_H)
00207       ,
00209       WVARCHAR          = SQL_WCHAR,
00211       WCHAR          = SQL_WVARCHAR,
00213       WLONGVARCHAR   = SQL_WLONGVARCHAR
00214 #endif
00215     };
00216   };
00217 
00218 
00219 #if !defined(ODBCXX_QT)
00220 
00226   class ODBCXX_EXPORT Bytes {
00227   private:
00228     struct Rep {
00229       signed char* buf_;
00230       size_t len_;
00231       int refCount_;
00232       Rep(const signed char* b, size_t l)
00233         :len_(l), refCount_(0) {
00234         if(len_>0) {
00235           buf_=new signed char[len_];
00236           memcpy((void*)buf_,(void*)b,len_);
00237         } else {
00238           buf_=NULL;
00239         }
00240       }
00241       ~Rep() {
00242         delete [] buf_;
00243       }
00244     };
00245 
00246     Rep* rep_;
00247   public:
00249     Bytes()
00250       :rep_(new Rep(NULL,0)) {
00251       rep_->refCount_++;
00252     }
00253 
00255     Bytes(const signed char* data, size_t dataLen)
00256       :rep_(new Rep(data,dataLen)) {
00257       rep_->refCount_++;
00258     }
00259 
00261     Bytes(const Bytes& b)
00262       :rep_(b.rep_) {
00263       rep_->refCount_++;
00264     }
00265 
00267     Bytes& operator=(const Bytes& b) {
00268       if(--rep_->refCount_==0) {
00269         delete rep_;
00270       }
00271       rep_=b.rep_;
00272       rep_->refCount_++;
00273       return *this;
00274     }
00275     
00277     ~Bytes() { 
00278       if(--rep_->refCount_==0) {
00279         delete rep_;
00280       }
00281     }
00282 
00284     const signed char* getData() const { 
00285       return rep_->buf_;
00286     }
00287 
00289     size_t getSize() const {
00290       return rep_->len_;
00291     }
00292   };
00293 #endif
00294 
00296   class ODBCXX_EXPORT Date {
00297   protected:
00298     int year_;
00299     int month_;
00300     int day_;
00301 
00302     virtual void _invalid(const char* what, int value);
00303 
00304     int _validateYear(int y) {
00305       return y;
00306     }
00307     
00308     int _validateMonth(int m) {
00309       if(m<1 || m>12) {
00310         this->_invalid("month",m);
00311       }
00312       return m;
00313     }
00314     
00315     int _validateDay(int d) {
00316       if(d<1 || d>31) {
00317         this->_invalid("day",d);
00318       }
00319       return d;
00320     }
00321 
00322   public:
00325     Date(int year, int month, int day) {
00326       this->setYear(year);
00327       this->setMonth(month);
00328       this->setDay(day);
00329     }
00330 
00335     explicit Date();
00336 
00341     Date(std::time_t t) {
00342       this->setTime(t);
00343     }
00344 
00349     Date(const ODBCXX_STRING& str) {
00350       this->parse(str);
00351     }
00352 
00354     Date(const Date& d)
00355       :year_(d.year_),
00356        month_(d.month_),
00357        day_(d.day_) {}
00358 
00360     Date& operator=(const Date& d) {
00361       year_=d.year_;
00362       month_=d.month_;
00363       day_=d.day_;
00364       return *this;
00365     }
00366 
00368     virtual ~Date() {}
00369 
00371     virtual void setTime(std::time_t t);
00372 
00374     std::time_t getTime() const;
00375 
00377     void parse(const ODBCXX_STRING& str);
00378 
00380     int getYear() const {
00381       return year_;
00382     }
00383 
00385     int getMonth() const {
00386       return month_;
00387     }
00388 
00390     int getDay() const {
00391       return day_;
00392     }
00393 
00395     void setYear(int year) {
00396       year_=this->_validateYear(year);
00397     }
00398 
00400     void setMonth(int month) {
00401       month_=this->_validateMonth(month);
00402     }
00403 
00405     void setDay(int day) {
00406       day_=this->_validateDay(day);
00407     }
00408 
00410     virtual ODBCXX_STRING toString() const;
00411   };
00412 
00414   class ODBCXX_EXPORT Time {
00415   protected:
00416     int hour_;
00417     int minute_;
00418     int second_;
00419 
00420     virtual void _invalid(const char* what, int value);
00421 
00422     int _validateHour(int h) {
00423       if(h<0 || h>23) {
00424         this->_invalid("hour",h);
00425       }
00426       return h;
00427     }
00428 
00429     int _validateMinute(int m) {
00430       if(m<0 || m>59) {
00431         this->_invalid("minute",m);
00432       }
00433       return m;
00434     }
00435 
00436     int _validateSecond(int s) {
00437       if(s<0 || s>61) {
00438         this->_invalid("second",s);
00439       }
00440       return s;
00441     }
00442 
00443   public:
00445     Time(int hour, int minute, int second) {
00446       this->setHour(hour);
00447       this->setMinute(minute);
00448       this->setSecond(second);
00449     }
00450 
00455     explicit Time();
00456 
00461     Time(std::time_t t) {
00462       this->setTime(t);
00463     }
00464 
00469     Time(const ODBCXX_STRING& str) {
00470       this->parse(str);
00471     }
00472 
00474     Time(const Time& t)
00475       :hour_(t.hour_),
00476        minute_(t.minute_),
00477        second_(t.second_) {}
00478 
00480     Time& operator=(const Time& t) {
00481       hour_=t.hour_;
00482       minute_=t.minute_;
00483       second_=t.second_;
00484       return *this;
00485     }
00486 
00488     virtual ~Time() {}
00489 
00491     virtual void setTime(std::time_t t);
00492 
00494     std::time_t getTime() const;
00495 
00497     void parse(const ODBCXX_STRING& str);
00498 
00500     int getHour() const {
00501       return hour_;
00502     }
00503 
00505     int getMinute() const {
00506       return minute_;
00507     }
00508 
00510     int getSecond() const {
00511       return second_;
00512     }
00513 
00515     void setHour(int h) {
00516       hour_=this->_validateHour(h);
00517     }
00518 
00520     void setMinute(int m) {
00521       minute_=this->_validateMinute(m);
00522     }
00523 
00525     void setSecond(int s) {
00526       second_=this->_validateSecond(s);
00527     }
00528 
00529     virtual ODBCXX_STRING toString() const;
00530   };
00531 
00532 
00535   class ODBCXX_EXPORT Timestamp : public Date, public Time {
00536   private:
00537     int nanos_;
00538     
00539     virtual void _invalid(const char* what, int value);
00540 
00541     int _validateNanos(int n) {
00542       if(n<0) {
00543         this->_invalid("nanoseconds",n);
00544       }
00545       return n;
00546     }
00547 
00548   public:
00550     Timestamp(int year, int month, int day,
00551               int hour, int minute, int second,
00552               int nanos =0)
00553       :Date(year,month,day), Time(hour,minute,second) {
00554       this->setNanos(nanos);
00555     }
00556 
00561     explicit Timestamp();
00562 
00567     Timestamp(std::time_t t) {
00568       this->setTime(t);
00569     }
00570 
00575     Timestamp(const ODBCXX_STRING& s) {
00576       this->parse(s);
00577     }
00578 
00579 
00581     Timestamp(const Timestamp& t)
00582       :Date(t),Time(t),nanos_(t.nanos_) {}
00583 
00585     Timestamp& operator=(const Timestamp& t) {
00586       Date::operator=(t);
00587       Time::operator=(t);
00588       nanos_=t.nanos_;
00589       return *this;
00590     }
00591 
00593     virtual ~Timestamp() {}
00594 
00596     virtual void setTime(std::time_t t);
00597     
00599     virtual std::time_t getTime() {
00600       return Date::getTime()+Time::getTime();
00601     }
00602 
00605     void parse(const ODBCXX_STRING& s);
00606 
00608     int getNanos() const {
00609       return nanos_;
00610     }
00611 
00613     void setNanos(int nanos) {
00614       nanos_=this->_validateNanos(nanos);
00615     }
00616 
00617     virtual ODBCXX_STRING toString() const;
00618   };
00619 
00620 
00621   //this is used for several 'lists of stuff' below
00622   //expects T to be a pointer-to-something, and
00623   //the contents will get deleted when the vector 
00624   //itself is deleted
00625   template <class T> class CleanVector : public std::vector<T> {
00626   private:
00627     CleanVector(const CleanVector<T>&); //forbid
00628     CleanVector<T>& operator=(const CleanVector<T>&); //forbid
00629 
00630   public:
00631     explicit CleanVector() {}
00632     virtual ~CleanVector() {
00633       typename std::vector<T>::iterator i=this->begin();
00634       typename std::vector<T>::iterator end=this->end();
00635       while(i!=end) {
00636         delete *i;
00637         ++i;
00638       }
00639       this->clear();
00640     }
00641   };
00642 
00643 
00646   class ODBCXX_EXPORT DriverMessage {
00647     friend class ErrorHandler;
00648 
00649   private:
00650     char state_[SQL_SQLSTATE_SIZE+1];
00651     char description_[SQL_MAX_MESSAGE_LENGTH];
00652     SQLINTEGER nativeCode_;
00653 
00654     DriverMessage() {}
00655 #if ODBCVER < 0x0300
00656     static DriverMessage* fetchMessage(SQLHENV henv,
00657                                        SQLHDBC hdbc,
00658                                        SQLHSTMT hstmt);
00659 #else
00660     static DriverMessage* fetchMessage(SQLINTEGER handleType,
00661                                        SQLHANDLE h,
00662                                        int idx);
00663 #endif
00664 
00665   public:
00666     virtual ~DriverMessage() {}
00667 
00668     const char* getSQLState() const {
00669       return state_;
00670     }
00671 
00672     const char* getDescription() const {
00673       return description_;
00674     }
00675 
00676     int getNativeCode() const {
00677       return nativeCode_;
00678     }
00679   };
00680 
00681   
00684   class SQLException : public std::exception {
00685   private:
00686     ODBCXX_STRING reason_;
00687     ODBCXX_STRING sqlState_;
00688     int errorCode_;
00689 #if defined(ODBCXX_QT)
00690     QCString reason8_;
00691 #endif
00692     
00693   public:
00695     SQLException(const ODBCXX_STRING& reason ="", 
00696                  const ODBCXX_STRING& sqlState ="",
00697                  int vendorCode =0)
00698       :reason_(reason), 
00699        sqlState_(sqlState),
00700        errorCode_(vendorCode) 
00701 #if defined(ODBCXX_QT)
00702       ,reason8_(reason.local8Bit())
00703 #endif
00704 {}
00705 
00707     SQLException(const DriverMessage& dm)
00708       :reason_(dm.getDescription()),
00709        sqlState_(dm.getSQLState()),
00710        errorCode_(dm.getNativeCode()) {}
00711 
00713     virtual ~SQLException() throw() {}
00714 
00716     int getErrorCode() const {
00717       return errorCode_;
00718     }
00719     
00724     const ODBCXX_STRING& getSQLState() const {
00725       return sqlState_;
00726     }
00727     
00729     const ODBCXX_STRING& getMessage() const {
00730       return reason_;
00731     }
00732 
00733 
00735     virtual const char* what() const throw() {
00736       // the conversion from QString involves a temporary, which
00737       // doesn't survive this scope. So here, we do a conditional
00738 #if defined(ODBCXX_QT)
00739       return reason8_.data();
00740 #else
00741       return reason_.c_str();
00742 #endif
00743     }
00744   };
00745 
00746 
00751   class SQLWarning : public SQLException {
00752 
00753     SQLWarning(const SQLWarning&); //forbid
00754     SQLWarning& operator=(const SQLWarning&); //forbid
00755 
00756   public:
00758     SQLWarning(const ODBCXX_STRING& reason ="",
00759                const ODBCXX_STRING& sqlState ="",
00760                int vendorCode =0)
00761       :SQLException(reason,sqlState,vendorCode) {}
00762     
00764     SQLWarning(const DriverMessage& dm)
00765       :SQLException(dm) {}
00766     
00768     virtual ~SQLWarning() throw() {}
00769   };
00770 
00771   typedef CleanVector<SQLWarning*> WarningList;
00772   
00773 
00774   template <class T> class Deleter {
00775   private:
00776     T* ptr_;
00777     bool isArray_;
00778 
00779     Deleter(const Deleter<T>&);
00780     Deleter<T>& operator=(const Deleter<T>&);
00781 
00782   public:
00783     explicit Deleter(T* ptr, bool isArray =false) 
00784       :ptr_(ptr), isArray_(isArray) {}
00785     ~Deleter() {
00786       if(!isArray_) {
00787         delete ptr_;
00788       } else {
00789         delete[] ptr_;
00790       }
00791     }
00792   };
00793 
00794 }; // namespace odbc
00795 
00796 
00797 #endif // __ODBCXX_TYPES_H

Go back to the freeodbc++ homepage