00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00061
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
00072 #if ODBCVER >= 0x0300 && !defined(SQL_NOT_DEFERRABLE)
00073 # define SQL_NOT_DEFERRABLE 7
00074 #endif
00075
00076
00077
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
00090
00091
00092
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
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
00148
00149 const int GETDATA_CHUNK_SIZE=4*1024;
00150
00151 const int PUTDATA_CHUNK_SIZE=GETDATA_CHUNK_SIZE;
00152
00153
00154
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 WCHAR = SQL_WCHAR,
00211 WVARCHAR = 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 ODBCXX_SIGNED_CHAR_TYPE* buf_;
00230 size_t len_;
00231 int refCount_;
00232 Rep(const ODBCXX_SIGNED_CHAR_TYPE* b, size_t l)
00233 :len_(l), refCount_(0) {
00234 if(len_>0) {
00235 buf_=new ODBCXX_SIGNED_CHAR_TYPE[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 ODBCXX_SIGNED_CHAR_TYPE* 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 bool operator==(const Bytes& b) const {
00278 if (getSize()!=b.getSize())
00279 return false;
00280 for(size_t i=0;i<getSize();i++) {
00281 if(*(getData()+i)!=*(b.getData()+i))
00282 return false;
00283 }
00284 return true;
00285 }
00286
00288 ~Bytes() {
00289 if(--rep_->refCount_==0) {
00290 delete rep_;
00291 }
00292 }
00293
00295 const ODBCXX_SIGNED_CHAR_TYPE* getData() const {
00296 return rep_->buf_;
00297 }
00298
00300 size_t getSize() const {
00301 return rep_->len_;
00302 }
00303 };
00304 #endif
00305
00307 class ODBCXX_EXPORT Date {
00308 protected:
00309 int year_;
00310 int month_;
00311 int day_;
00312
00313 virtual void _invalid(const ODBCXX_CHAR_TYPE* what, int value);
00314
00315 int _validateYear(int y) {
00316 return y;
00317 }
00318
00319 int _validateMonth(int m) {
00320 if(m<1 || m>12) {
00321 this->_invalid(ODBCXX_STRING_CONST("month"),m);
00322 }
00323 return m;
00324 }
00325
00326 int _validateDay(int d) {
00327 if(d<1 || d>31) {
00328 this->_invalid(ODBCXX_STRING_CONST("day"),d);
00329 }
00330 return d;
00331 }
00332
00333 public:
00336 Date(int year, int month, int day) {
00337 this->setYear(year);
00338 this->setMonth(month);
00339 this->setDay(day);
00340 }
00341
00346 explicit Date();
00347
00352 Date(std::time_t t) {
00353 this->setTime(t);
00354 }
00355
00360 Date(const ODBCXX_STRING& str) {
00361 this->parse(str);
00362 }
00363
00365 Date(const Date& d)
00366 :year_(d.year_),
00367 month_(d.month_),
00368 day_(d.day_) {}
00369
00371 Date& operator=(const Date& d) {
00372 year_=d.year_;
00373 month_=d.month_;
00374 day_=d.day_;
00375 return *this;
00376 }
00377
00379 virtual ~Date() {}
00380
00382 virtual void setTime(std::time_t t);
00383
00385 std::time_t getTime() const;
00386
00388 void parse(const ODBCXX_STRING& str);
00389
00391 int getYear() const {
00392 return year_;
00393 }
00394
00396 int getMonth() const {
00397 return month_;
00398 }
00399
00401 int getDay() const {
00402 return day_;
00403 }
00404
00406 void setYear(int year) {
00407 year_=this->_validateYear(year);
00408 }
00409
00411 void setMonth(int month) {
00412 month_=this->_validateMonth(month);
00413 }
00414
00416 void setDay(int day) {
00417 day_=this->_validateDay(day);
00418 }
00419
00421 virtual ODBCXX_STRING toString() const;
00422 };
00423
00425 class ODBCXX_EXPORT Time {
00426 protected:
00427 int hour_;
00428 int minute_;
00429 int second_;
00430
00431 virtual void _invalid(const ODBCXX_CHAR_TYPE* what, int value);
00432
00433 int _validateHour(int h) {
00434 if(h<0 || h>23) {
00435 this->_invalid(ODBCXX_STRING_CONST("hour"),h);
00436 }
00437 return h;
00438 }
00439
00440 int _validateMinute(int m) {
00441 if(m<0 || m>59) {
00442 this->_invalid(ODBCXX_STRING_CONST("minute"),m);
00443 }
00444 return m;
00445 }
00446
00447 int _validateSecond(int s) {
00448 if(s<0 || s>61) {
00449 this->_invalid(ODBCXX_STRING_CONST("second"),s);
00450 }
00451 return s;
00452 }
00453
00454 public:
00456 Time(int hour, int minute, int second) {
00457 this->setHour(hour);
00458 this->setMinute(minute);
00459 this->setSecond(second);
00460 }
00461
00466 explicit Time();
00467
00472 Time(std::time_t t) {
00473 this->setTime(t);
00474 }
00475
00480 Time(const ODBCXX_STRING& str) {
00481 this->parse(str);
00482 }
00483
00485 Time(const Time& t)
00486 :hour_(t.hour_),
00487 minute_(t.minute_),
00488 second_(t.second_) {}
00489
00491 Time& operator=(const Time& t) {
00492 hour_=t.hour_;
00493 minute_=t.minute_;
00494 second_=t.second_;
00495 return *this;
00496 }
00497
00499 virtual ~Time() {}
00500
00502 virtual void setTime(std::time_t t);
00503
00505 std::time_t getTime() const;
00506
00508 void parse(const ODBCXX_STRING& str);
00509
00511 int getHour() const {
00512 return hour_;
00513 }
00514
00516 int getMinute() const {
00517 return minute_;
00518 }
00519
00521 int getSecond() const {
00522 return second_;
00523 }
00524
00526 void setHour(int h) {
00527 hour_=this->_validateHour(h);
00528 }
00529
00531 void setMinute(int m) {
00532 minute_=this->_validateMinute(m);
00533 }
00534
00536 void setSecond(int s) {
00537 second_=this->_validateSecond(s);
00538 }
00539
00540 virtual ODBCXX_STRING toString() const;
00541 };
00542
00543
00546 class ODBCXX_EXPORT Timestamp : public Date, public Time {
00547 private:
00548 int nanos_;
00549
00550 virtual void _invalid(const ODBCXX_CHAR_TYPE* what, int value);
00551
00552 int _validateNanos(int n) {
00553 if(n<0) {
00554 this->_invalid(ODBCXX_STRING_CONST("nanoseconds"),n);
00555 }
00556 return n;
00557 }
00558
00559 public:
00561 Timestamp(int year, int month, int day,
00562 int hour, int minute, int second,
00563 int nanos =0)
00564 :Date(year,month,day), Time(hour,minute,second) {
00565 this->setNanos(nanos);
00566 }
00567
00572 explicit Timestamp();
00573
00578 Timestamp(std::time_t t) {
00579 this->setTime(t);
00580 }
00581
00586 Timestamp(const ODBCXX_STRING& s) {
00587 this->parse(s);
00588 }
00589
00590
00592 Timestamp(const Timestamp& t)
00593 :Date(t),Time(t),nanos_(t.nanos_) {}
00594
00596 Timestamp& operator=(const Timestamp& t) {
00597 Date::operator=(t);
00598 Time::operator=(t);
00599 nanos_=t.nanos_;
00600 return *this;
00601 }
00602
00604 virtual ~Timestamp() {}
00605
00607 virtual void setTime(std::time_t t);
00608
00610 virtual std::time_t getTime() {
00611 return Date::getTime()+Time::getTime();
00612 }
00613
00616 void parse(const ODBCXX_STRING& s);
00617
00619 int getNanos() const {
00620 return nanos_;
00621 }
00622
00624 void setNanos(int nanos) {
00625 nanos_=this->_validateNanos(nanos);
00626 }
00627
00628 virtual ODBCXX_STRING toString() const;
00629 };
00630
00631
00632
00633
00634
00635
00636 template <class T> class CleanVector : public std::vector<T> {
00637 private:
00638 CleanVector(const CleanVector<T>&);
00639 CleanVector<T>& operator=(const CleanVector<T>&);
00640
00641 public:
00642 explicit CleanVector() {}
00643 virtual ~CleanVector() {
00644 typename std::vector<T>::iterator i=this->begin();
00645 typename std::vector<T>::iterator end=this->end();
00646 while(i!=end) {
00647 delete *i;
00648 ++i;
00649 }
00650 this->clear();
00651 }
00652 };
00653
00654
00657 class ODBCXX_EXPORT DriverMessage {
00658 friend class ErrorHandler;
00659
00660 private:
00661 ODBCXX_CHAR_TYPE state_[SQL_SQLSTATE_SIZE+1];
00662 ODBCXX_CHAR_TYPE description_[SQL_MAX_MESSAGE_LENGTH];
00663 SQLINTEGER nativeCode_;
00664
00665 DriverMessage() {}
00666 #if ODBCVER < 0x0300
00667 static DriverMessage* fetchMessage(SQLHENV henv,
00668 SQLHDBC hdbc,
00669 SQLHSTMT hstmt);
00670 #else
00671 static DriverMessage* fetchMessage(SQLINTEGER handleType,
00672 SQLHANDLE h,
00673 int idx);
00674 #endif
00675
00676 public:
00677 virtual ~DriverMessage() {}
00678
00679 const ODBCXX_CHAR_TYPE* getSQLState() const {
00680 return state_;
00681 }
00682
00683 const ODBCXX_CHAR_TYPE* getDescription() const {
00684 return description_;
00685 }
00686
00687 int getNativeCode() const {
00688 return nativeCode_;
00689 }
00690 };
00691
00692
00695 class SQLException : public std::exception {
00696 private:
00697 ODBCXX_STRING reason_;
00698 ODBCXX_STRING sqlState_;
00699 int errorCode_;
00700 #if defined(ODBCXX_UNICODE)
00701 std::string reason8_;
00702 #elif defined(ODBCXX_QT)
00703 QCString reason8_;
00704 #endif
00705 public:
00707 SQLException(const ODBCXX_STRING& reason =ODBCXX_STRING_CONST(""),
00708 const ODBCXX_STRING& sqlState =ODBCXX_STRING_CONST(""),
00709 int vendorCode =0)
00710 :reason_(reason),
00711 sqlState_(sqlState),
00712 errorCode_(vendorCode)
00713 #if defined(ODBCXX_UNICODE)
00714 {
00715 const size_t length =sizeof(wchar_t)*reason_.size();
00716 char* temp =new char[length+1];
00717 wcstombs(temp,reason_.c_str(),length);
00718 reason8_ =temp;
00719 delete[] temp;
00720 }
00721 #else
00722 # if defined(ODBCXX_QT)
00723 ,reason8_(reason.local8Bit())
00724 # endif
00725 {}
00726 #endif
00727
00729 SQLException(const DriverMessage& dm)
00730 :reason_(dm.getDescription()),
00731 sqlState_(dm.getSQLState()),
00732 errorCode_(dm.getNativeCode()) {}
00733
00735 virtual ~SQLException() throw() {}
00736
00738 int getErrorCode() const {
00739 return errorCode_;
00740 }
00741
00746 const ODBCXX_STRING& getSQLState() const {
00747 return sqlState_;
00748 }
00749
00751 const ODBCXX_STRING& getMessage() const {
00752 return reason_;
00753 }
00754
00755
00757 virtual const char* what() const throw() {
00758
00759
00760 #if defined(ODBCXX_QT)
00761 return reason8_.data();
00762 #else
00763 # if defined(ODBCXX_UNICODE)
00764 return reason8_.c_str();
00765 # else
00766 return reason_.c_str();
00767 # endif
00768 #endif
00769 }
00770 };
00771
00772
00777 class SQLWarning : public SQLException {
00778
00779 SQLWarning(const SQLWarning&);
00780 SQLWarning& operator=(const SQLWarning&);
00781
00782 public:
00784 SQLWarning(const ODBCXX_STRING& reason = ODBCXX_STRING_CONST(""),
00785 const ODBCXX_STRING& sqlState = ODBCXX_STRING_CONST(""),
00786 int vendorCode =0)
00787 :SQLException(reason,sqlState,vendorCode) {}
00788
00790 SQLWarning(const DriverMessage& dm)
00791 :SQLException(dm) {}
00792
00794 virtual ~SQLWarning() throw() {}
00795 };
00796
00797 typedef CleanVector<SQLWarning*> WarningList;
00798
00799
00800 template <class T> class Deleter {
00801 private:
00802 T* ptr_;
00803 bool isArray_;
00804
00805 Deleter(const Deleter<T>&);
00806 Deleter<T>& operator=(const Deleter<T>&);
00807
00808 public:
00809 explicit Deleter(T* ptr, bool isArray =false)
00810 :ptr_(ptr), isArray_(isArray) {}
00811 ~Deleter() {
00812 if(!isArray_) {
00813 delete ptr_;
00814 } else {
00815 delete[] ptr_;
00816 }
00817 }
00818 };
00819
00820 }
00821
00822
00823 #endif // __ODBCXX_TYPES_H