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 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
00622
00623
00624
00625 template <class T> class CleanVector : public std::vector<T> {
00626 private:
00627 CleanVector(const CleanVector<T>&);
00628 CleanVector<T>& operator=(const CleanVector<T>&);
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
00737
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&);
00754 SQLWarning& operator=(const SQLWarning&);
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 };
00795
00796
00797 #endif // __ODBCXX_TYPES_H