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 #if !defined(ODBCXX_QT)
00029 # include <string>
00030 # else
00031 # include <qstring.h>
00032 #endif
00033 #include <ctime>
00034
00035 #if defined(ODBCXX_QT)
00036 class QIODevice;
00037 #endif
00038
00039 #if defined(ODBCXX_HAVE_ISQL_H) && defined(ODBCXX_HAVE_ISQLEXT_H)
00040 # include <isql.h>
00041 # include <isqlext.h>
00042 #elif defined(ODBCXX_HAVE_SQL_H) && defined(ODBCXX_HAVE_SQLEXT_H)
00043 # include <sql.h>
00044 # include <sqlext.h>
00045 #else
00046 # error "Whoops. Can not recognize the ODBC subsystem."
00047 #endif
00048
00049
00050
00051
00052 #if !defined(SQL_TRUE)
00053 # define SQL_TRUE 1
00054 #endif
00055
00056 #if !defined(SQL_FALSE)
00057 # define SQL_FALSE 0
00058 #endif
00059
00060
00061 #if ODBCVER >= 0x0300 && !defined(SQL_NOT_DEFERRABLE)
00062 # define SQL_NOT_DEFERRABLE 7
00063 #endif
00064
00065
00066
00067 #if ODBCVER >= 0x0300
00068
00069 # define ODBC3_C(odbc3_value,old_value) odbc3_value
00070
00071 #else
00072
00073 # define ODBC3_C(odbc3_value,old_value) old_value
00074
00075 #endif
00076
00077
00078
00079
00080
00081
00082
00083 #if ODBCVER >= 0x0300
00084
00085 # define ODBC3_DC(odbc3_value,old_value) \
00086 (this->_getDriverInfo()->getMajorVersion()>=3?odbc3_value:old_value)
00087
00088 #else
00089
00090 # define ODBC3_DC(odbc3_value,old_value) old_value
00091
00092 #endif
00093
00094 #if defined(ODBCXX_HAVE_INTTYPES_H)
00095 # include <inttypes.h>
00096 #endif
00097
00098 #include <vector>
00099
00100
00101 namespace odbc {
00102
00103
00104
00105 #if defined(WIN32)
00106
00107 typedef __int64 Long;
00108
00109 #elif defined(ODBCXX_HAVE_INTTYPES_H)
00110
00111 typedef int64_t Long;
00112
00113 #else
00114
00115 # if ODBCXX_SIZEOF_INT == 8
00116
00117 typedef int Long;
00118
00119 # elif ODBCXX_SIZEOF_LONG == 8
00120
00121 typedef long Long;
00122
00123 # elif ODBCXX_SIZEOF_LONG_LONG == 8
00124
00125 typedef long long Long;
00126
00127 # else
00128
00129 # error "Can't find an appropriate at-least-64-bit integer"
00130
00131 # endif
00132
00133 #endif
00134
00135
00136
00137
00138 const int GETDATA_CHUNK_SIZE=4*1024;
00139
00140 const int PUTDATA_CHUNK_SIZE=GETDATA_CHUNK_SIZE;
00141
00142
00143
00144 const int STRING_TO_STREAM_CHUNK_SIZE=1024;
00145 const int STREAM_TO_STRING_CHUNK_SIZE=STRING_TO_STREAM_CHUNK_SIZE;
00146
00147
00148
00149
00150
00153 struct Types {
00156 enum SQLType {
00158 BIGINT = SQL_BIGINT,
00160 BINARY = SQL_BINARY,
00162 BIT = SQL_BIT,
00164 CHAR = SQL_CHAR,
00166 DATE = ODBC3_C(SQL_TYPE_DATE,SQL_DATE),
00168 DECIMAL = SQL_DECIMAL,
00170 DOUBLE = SQL_DOUBLE,
00172 FLOAT = SQL_FLOAT,
00174 INTEGER = SQL_INTEGER,
00176 LONGVARBINARY = SQL_LONGVARBINARY,
00178 LONGVARCHAR = SQL_LONGVARCHAR,
00180 NUMERIC = SQL_NUMERIC,
00182 REAL = SQL_REAL,
00184 SMALLINT = SQL_SMALLINT,
00186 TIME = ODBC3_C(SQL_TYPE_TIME,SQL_TIME),
00188 TIMESTAMP = ODBC3_C(SQL_TYPE_TIMESTAMP,SQL_TIMESTAMP),
00190 TINYINT = SQL_TINYINT,
00192 VARBINARY = SQL_VARBINARY,
00194 VARCHAR = SQL_VARCHAR
00195 };
00196 };
00197
00198
00199 #if !defined(ODBCXX_QT)
00206 class ODBCXX_EXPORT Bytes {
00207 private:
00208 struct Rep {
00209 signed char* buf_;
00210 size_t len_;
00211 int refCount_;
00212 Rep(const signed char* b, size_t l)
00213 :len_(l), refCount_(0) {
00214 if(len_>0) {
00215 buf_=new signed char[len_];
00216 memcpy((void*)buf_,(void*)b,len_);
00217 } else {
00218 buf_=NULL;
00219 }
00220 }
00221 ~Rep() {
00222 delete buf_;
00223 }
00224 };
00225
00226 Rep* rep_;
00227 public:
00229 Bytes()
00230 :rep_(new Rep(NULL,0)) {
00231 rep_->refCount_++;
00232 }
00233
00235 Bytes(const signed char* data, size_t dataLen)
00236 :rep_(new Rep(data,dataLen)) {
00237 rep_->refCount_++;
00238 }
00239
00241 Bytes(const Bytes& b)
00242 :rep_(b.rep_) {
00243 rep_->refCount_++;
00244 }
00245
00247 Bytes& operator=(const Bytes& b) {
00248 if(--rep_->refCount_==0) {
00249 delete rep_;
00250 }
00251 rep_=b.rep_;
00252 rep_->refCount_++;
00253 return *this;
00254 }
00255
00257 ~Bytes() {
00258 if(--rep_->refCount_==0) {
00259 delete rep_;
00260 }
00261 }
00262
00264 const signed char* getData() const {
00265 return rep_->buf_;
00266 }
00267
00269 size_t getSize() const {
00270 return rep_->len_;
00271 }
00272 };
00273 #endif
00274
00276 class ODBCXX_EXPORT Date {
00277 protected:
00278 int year_;
00279 int month_;
00280 int day_;
00281
00282 virtual void _invalid(const char* what, int value);
00283
00284 int _validateYear(int y) {
00285 return y;
00286 }
00287
00288 int _validateMonth(int m) {
00289 if(m<1 || m>12) {
00290 this->_invalid("month",m);
00291 }
00292 return m;
00293 }
00294
00295 int _validateDay(int d) {
00296 if(d<1 || d>31) {
00297 this->_invalid("day",d);
00298 }
00299 return d;
00300 }
00301
00302 public:
00305 Date(int year, int month, int day) {
00306 this->setYear(year);
00307 this->setMonth(month);
00308 this->setDay(day);
00309 }
00310
00315 explicit Date();
00316
00321 Date(time_t t) {
00322 this->setTime(t);
00323 }
00324
00329 Date(const ODBCXX_STRING& str) {
00330 this->parse(str);
00331 }
00332
00334 Date(const Date& d)
00335 :year_(d.year_),
00336 month_(d.month_),
00337 day_(d.day_) {}
00338
00340 Date& operator=(const Date& d) {
00341 year_=d.year_;
00342 month_=d.month_;
00343 day_=d.day_;
00344 return *this;
00345 }
00346
00348 virtual ~Date() {}
00349
00351 virtual void setTime(time_t t);
00352
00354 time_t getTime() const;
00355
00357 void parse(const ODBCXX_STRING& str);
00358
00360 int getYear() const {
00361 return year_;
00362 }
00363
00365 int getMonth() const {
00366 return month_;
00367 }
00368
00370 int getDay() const {
00371 return day_;
00372 }
00373
00375 void setYear(int year) {
00376 year_=this->_validateYear(year);
00377 }
00378
00380 void setMonth(int month) {
00381 month_=this->_validateMonth(month);
00382 }
00383
00385 void setDay(int day) {
00386 day_=this->_validateDay(day);
00387 }
00388
00390 virtual ODBCXX_STRING toString() const;
00391 };
00392
00394 class ODBCXX_EXPORT Time {
00395 protected:
00396 int hour_;
00397 int minute_;
00398 int second_;
00399
00400 virtual void _invalid(const char* what, int value);
00401
00402 int _validateHour(int h) {
00403 if(h<0 || h>23) {
00404 this->_invalid("hour",h);
00405 }
00406 return h;
00407 }
00408
00409 int _validateMinute(int m) {
00410 if(m<0 || m>59) {
00411 this->_invalid("minute",m);
00412 }
00413 return m;
00414 }
00415
00416 int _validateSecond(int s) {
00417 if(s<0 || s>61) {
00418 this->_invalid("second",s);
00419 }
00420 return s;
00421 }
00422
00423 public:
00425 Time(int hour, int minute, int second) {
00426 this->setHour(hour);
00427 this->setMinute(minute);
00428 this->setSecond(second);
00429 }
00430
00435 explicit Time();
00436
00441 Time(time_t t) {
00442 this->setTime(t);
00443 }
00444
00449 Time(const ODBCXX_STRING& str) {
00450 this->parse(str);
00451 }
00452
00454 Time(const Time& t)
00455 :hour_(t.hour_),
00456 minute_(t.minute_),
00457 second_(t.second_) {}
00458
00460 Time& operator=(const Time& t) {
00461 hour_=t.hour_;
00462 minute_=t.minute_;
00463 second_=t.second_;
00464 return *this;
00465 }
00466
00468 virtual ~Time() {}
00469
00471 virtual void setTime(time_t t);
00472
00474 time_t getTime() const;
00475
00477 void parse(const ODBCXX_STRING& str);
00478
00480 int getHour() const {
00481 return hour_;
00482 }
00483
00485 int getMinute() const {
00486 return minute_;
00487 }
00488
00490 int getSecond() const {
00491 return second_;
00492 }
00493
00495 void setHour(int h) {
00496 hour_=this->_validateHour(h);
00497 }
00498
00500 void setMinute(int m) {
00501 minute_=this->_validateMinute(m);
00502 }
00503
00505 void setSecond(int s) {
00506 second_=this->_validateSecond(s);
00507 }
00508
00509 virtual ODBCXX_STRING toString() const;
00510 };
00511
00512
00515 class ODBCXX_EXPORT Timestamp : public Date, public Time {
00516 private:
00517 int nanos_;
00518
00519 virtual void _invalid(const char* what, int value);
00520
00521 int _validateNanos(int n) {
00522 if(n<0) {
00523 this->_invalid("nanoseconds",n);
00524 }
00525 return n;
00526 }
00527
00528 public:
00530 Timestamp(int year, int month, int day,
00531 int hour, int minute, int second,
00532 int nanos =0)
00533 :Date(year,month,day), Time(hour,minute,second) {
00534 this->setNanos(nanos);
00535 }
00536
00541 explicit Timestamp();
00542
00547 Timestamp(time_t t) {
00548 this->setTime(t);
00549 }
00550
00555 Timestamp(const ODBCXX_STRING& s) {
00556 this->parse(s);
00557 }
00558
00559
00561 Timestamp(const Timestamp& t)
00562 :Date(t),Time(t),nanos_(t.nanos_) {}
00563
00565 Timestamp& operator=(const Timestamp& t) {
00566 Date::operator=(t);
00567 Time::operator=(t);
00568 nanos_=t.nanos_;
00569 return *this;
00570 }
00571
00573 virtual ~Timestamp() {}
00574
00576 virtual void setTime(time_t t);
00577
00579 virtual time_t getTime() {
00580 return Date::getTime()+Time::getTime();
00581 }
00582
00585 void parse(const ODBCXX_STRING& s);
00586
00588 int getNanos() const {
00589 return nanos_;
00590 }
00591
00593 void setNanos(int nanos) {
00594 nanos_=this->_validateNanos(nanos);
00595 }
00596
00597 virtual ODBCXX_STRING toString() const;
00598 };
00599
00600
00601
00602
00603
00604
00605 template <class T> class CleanVector : public std::vector<T> {
00606 private:
00607 CleanVector(const CleanVector<T>&);
00608 CleanVector<T>& operator=(const CleanVector<T>&);
00609
00610 public:
00611 explicit CleanVector() {}
00612 virtual ~CleanVector() {
00613 typename std::vector<T>::iterator i=this->begin();
00614 typename std::vector<T>::iterator end=this->end();
00615 while(i!=end) {
00616 delete *i;
00617 ++i;
00618 }
00619 this->clear();
00620 }
00621 };
00622
00623
00626 class ODBCXX_EXPORT DriverMessage {
00627 friend class ErrorHandler;
00628
00629 private:
00630 char state_[SQL_SQLSTATE_SIZE+1];
00631 char description_[SQL_MAX_MESSAGE_LENGTH];
00632 SQLINTEGER nativeCode_;
00633
00634 DriverMessage() {}
00635
00636 public:
00637 virtual ~DriverMessage() {}
00638
00639 const char* getSQLState() const {
00640 return state_;
00641 }
00642
00643 const char* getDescription() const {
00644 return description_;
00645 }
00646
00647 int getNativeCode() const {
00648 return nativeCode_;
00649 }
00650 };
00651
00652
00655 class SQLException : public std::exception {
00656 private:
00657 ODBCXX_STRING reason_;
00658 ODBCXX_STRING sqlState_;
00659 int errorCode_;
00660 #if defined(ODBCXX_QT)
00661 QCString reason8_;
00662 #endif
00663
00664 public:
00666 SQLException(const ODBCXX_STRING& reason ="",
00667 const ODBCXX_STRING& sqlState ="",
00668 int vendorCode =0)
00669 :reason_(reason),
00670 sqlState_(sqlState),
00671 errorCode_(vendorCode)
00672 #if defined(ODBCXX_QT)
00673 ,reason8_(reason.local8Bit())
00674 #endif
00675 {}
00676
00678 SQLException(const DriverMessage& dm)
00679 :reason_(dm.getDescription()),
00680 sqlState_(dm.getSQLState()),
00681 errorCode_(dm.getNativeCode()) {}
00682
00684 virtual ~SQLException() throw() {}
00685
00687 int getErrorCode() const {
00688 return errorCode_;
00689 }
00690
00695 const ODBCXX_STRING& getSQLState() const {
00696 return sqlState_;
00697 }
00698
00700 const ODBCXX_STRING& getMessage() const {
00701 return reason_;
00702 }
00703
00704
00706 virtual const char* what() const throw() {
00707
00708
00709 #if defined(ODBCXX_QT)
00710 return reason8_.data();
00711 #else
00712 return reason_.c_str();
00713 #endif
00714 }
00715 };
00716
00717
00722 class SQLWarning : public SQLException {
00723
00724 SQLWarning(const SQLWarning&);
00725 SQLWarning& operator=(const SQLWarning&);
00726
00727 public:
00729 SQLWarning(const ODBCXX_STRING& reason ="",
00730 const ODBCXX_STRING& sqlState ="",
00731 int vendorCode =0)
00732 :SQLException(reason,sqlState,vendorCode) {}
00733
00735 SQLWarning(const DriverMessage& dm)
00736 :SQLException(dm) {}
00737
00739 virtual ~SQLWarning() throw() {}
00740 };
00741
00742 typedef CleanVector<SQLWarning*> WarningList;
00743
00744
00745 template <class T> class Deleter {
00746 private:
00747 T* ptr_;
00748 bool isArray_;
00749
00750 Deleter(const Deleter<T>&);
00751 Deleter<T>& operator=(const Deleter<T>&);
00752
00753 public:
00754 explicit Deleter(T* ptr, bool isArray =false)
00755 :ptr_(ptr), isArray_(isArray) {}
00756 ~Deleter() {
00757 if(!isArray_) {
00758 delete ptr_;
00759 } else {
00760 delete[] ptr_;
00761 }
00762 }
00763 };
00764
00765 };
00766
00767
00768 #endif // __ODBCXX_TYPES_H