00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #if FX_SQLMODULE
00022
00023 #ifndef TNFXSQLDB_H
00024 #define TNFXSQLDB_H
00025
00026 #include "FXTime.h"
00027 #include "FXRefedObject.h"
00028 #include "QBuffer.h"
00029 #include "QHostAddress.h"
00030 #include "QTrans.h"
00031 #include <qcstring.h>
00032
00033 #if FX_SQLMODULE==1
00034 #define FXSQLMODULEAPI FXAPI
00035 #elif FX_SQLMODULE==2
00036 #ifdef FOXDLL
00037 #ifdef FX_SQLMODULE_EXPORTS
00038 #define FXSQLMODULEAPI FXEXPORT
00039 #else
00040 #define FXSQLMODULEAPI FXIMPORT
00041 #endif
00042 #else
00043 #define FXSQLMODULEAPI
00044 #endif
00045 #endif
00046
00047 namespace FX {
00048
00129 #ifdef _MSC_VER
00130 #pragma warning(push)
00131 #pragma warning(disable: 4251) // class 1 needs to have dll-interface to be used by clients of class 2
00132 #pragma warning(disable: 4244) // Conversion from bigger to smaller, possible loss of data
00133 #pragma warning(disable: 4275) // non DLL-interface used as base for DLL-interface class
00134 #endif
00135
00136 class QStringList;
00137
00138 namespace TnFXSQLDBImpl
00139 {
00140 template<bool isUnsignedInt, typename type, typename signedIntEquiv> struct checkForOverflow
00141 {
00142 static bool Do(const type *v) throw()
00143 {
00144 return false;
00145 }
00146 };
00147 template<typename type, typename signedIntEquiv> struct checkForOverflow<true, type, signedIntEquiv>
00148 {
00149 static bool Do(const type *v) throw()
00150 {
00151 if(v && *v>Generic::BiggestValue<signedIntEquiv>::value)
00152 {
00153 return true;
00154 }
00155 return false;
00156 }
00157 };
00158 template<> struct checkForOverflow<true, FXulong, FXlong>
00159 {
00160 static bool Do(const FXulong *v) throw()
00161 {
00162 if(v && *v>(FXulong) Generic::BiggestValue<FXlong>::value)
00163 {
00164 #ifdef DEBUG
00165 fxmessage("WARNING: Unsigned 64 bit value overflows signed 64 bit database type!\n");
00166 #endif
00167 }
00168 return false;
00169 }
00170 };
00171 template<bool unknownType, typename type> struct DoSerialise;
00172 template<int sql92type, bool isUnsignedInt, typename type> struct BindImpl;
00173 }
00174
00175 class TnFXSQLDBStatement;
00177 typedef FXRefingObject<TnFXSQLDBStatement> TnFXSQLDBStatementRef;
00178 class TnFXSQLDBCursor;
00180 typedef FXRefingObject<TnFXSQLDBCursor> TnFXSQLDBCursorRef;
00181 class TnFXSQLDBColumn;
00183 typedef FXRefingObject<TnFXSQLDBColumn> TnFXSQLDBColumnRef;
00184
00185
00239 struct TnFXSQLDBPrivate;
00240 class FXSQLMODULEAPI TnFXSQLDB
00241 {
00242 TnFXSQLDBPrivate *p;
00243 TnFXSQLDB(const TnFXSQLDB &);
00244 TnFXSQLDB &operator=(const TnFXSQLDB &);
00245 public:
00247 struct Capabilities
00248 {
00249 FXuint Transactions : 1;
00250 FXuint QueryRows : 1;
00251 FXuint NoTypeConstraints : 1;
00252 FXuint HasBackwardsCursor : 1;
00253 FXuint HasSettableCursor : 1;
00254 FXuint HasStaticCursor : 1;
00255 FXuint Asynchronous : 1;
00256 Capabilities() { *((FXuint *) this)=0; }
00258 Capabilities &setTransactions(bool v=true) { Transactions=v; return *this; }
00260 Capabilities &setQueryRows(bool v=true) { QueryRows=v; return *this; }
00262 Capabilities &setNoTypeConstraints(bool v=true) { NoTypeConstraints=v; return *this; }
00264 Capabilities &setHasBackwardsCursor(bool v=true) { HasBackwardsCursor=v; return *this; }
00266 Capabilities &setHasSettableCursor(bool v=true) { HasSettableCursor=v; return *this; }
00268 Capabilities &setHasStaticCursor(bool v=true) { HasStaticCursor=v; return *this; }
00270 Capabilities &setAsynchronous(bool v=true) { Asynchronous=v; return *this; }
00271 };
00272 protected:
00273 TnFXSQLDB(Capabilities caps, const FXString &driverName, const FXString &dbname=FXString::nullStr(), const FXString &user=FXString::nullStr(), const QHostAddress &host=QHOSTADDRESS_LOCALHOST, FXushort port=0);
00274 public:
00275 virtual ~TnFXSQLDB();
00276
00278 enum SQLDataType
00279 {
00280 Null=0,
00281
00282 VarChar,
00283 Char,
00284 WVarChar,
00285 WChar,
00286
00287 TinyInt,
00288 SmallInt,
00289 Integer,
00290 BigInt,
00291 Decimal,
00292 Numeric,
00293
00294 Real,
00295 Double,
00296 Float,
00297
00298 Timestamp,
00299 Date,
00300 Time,
00301
00302 BLOB,
00303
00304 LastSQLDataTypeEntry
00305 };
00307 static const char *sql92TypeAsString(SQLDataType type);
00308 typedef Generic::TL::create<void,
00309 FXString, FXString, FXString, FXString,
00310 FXchar, FXshort, FXint, FXlong,
00311 FXlong, FXlong
00312 >::value CPPDataTypes1;
00313 typedef Generic::TL::create<
00314 FXfloat, FXdouble,
00315 FXdouble,
00316 FXTime, FXTime, FXTime,
00317 QByteArray
00318 >::value CPPDataTypes2;
00320 typedef Generic::TL::append<CPPDataTypes1, CPPDataTypes2>::value CPPDataTypes;
00323 template<typename type> struct CPPToSQL92Type
00324 {
00325 static const int unsignedIntIdx=Generic::TL::find<Generic::IntegralLists::unsignedInts, type>::value;
00326 typedef typename Generic::TL::at<Generic::IntegralLists::signedInts, unsignedIntIdx>::value signedIntEquiv;
00327 typedef typename Generic::select<-1==unsignedIntIdx, type, signedIntEquiv>::value typeToUse;
00328
00329 static const int directidx=Generic::TL::find<CPPDataTypes, typeToUse>::value;
00330 static const SQLDataType value=(SQLDataType)((-1==directidx) ? Generic::TL::findParent<CPPDataTypes, typeToUse>::value : directidx);
00331 };
00336 template<typename type> static SQLDataType toSQL92Type(const type *v=0)
00337 {
00338 FXSTATIC_ASSERT(LastSQLDataTypeEntry==Generic::TL::length<CPPDataTypes>::value, Mismatched_SQLDataTypes_And_CPPDataTypes);
00339 typedef CPPToSQL92Type<type> sql92type;
00340
00341 return (SQLDataType)(sql92type::value+TnFXSQLDBImpl::checkForOverflow<-1!=sql92type::unsignedIntIdx, type, typename sql92type::signedIntEquiv>::Do(v));
00342 }
00344 template<template<typename type> class instance> struct toCPPType
00345 : Generic::TL::dynamicAt<CPPDataTypes1, instance>, Generic::TL::dynamicAt<CPPDataTypes2, instance>
00346 {
00347 typedef Generic::TL::dynamicAt<CPPDataTypes1, instance> Base1;
00348 typedef Generic::TL::dynamicAt<CPPDataTypes2, instance> Base2;
00350 toCPPType(SQLDataType datatype)
00351 : Base1(datatype<Generic::TL::length<CPPDataTypes1>::value ? datatype : Base1::DisableMagicIdx),
00352 Base2(datatype>=Generic::TL::length<CPPDataTypes1>::value ? datatype-Generic::TL::length<CPPDataTypes1>::value : Base1::DisableMagicIdx) { }
00354 template<typename P1, typename P2, typename P3, typename P4> toCPPType(SQLDataType datatype, P1 p1, P2 p2, P3 p3, P4 p4)
00355 : Base1(datatype<Generic::TL::length<CPPDataTypes1>::value ? datatype : Base1::DisableMagicIdx, p1, p2, p3, p4),
00356 Base2(datatype>=Generic::TL::length<CPPDataTypes1>::value ? datatype-Generic::TL::length<CPPDataTypes1>::value : Base1::DisableMagicIdx, p1, p2, p3, p4) { }
00357 };
00358
00360 const FXString &driverName() const throw();
00362 Capabilities capabilities() const throw();
00364 virtual const FXString &versionInfo() const=0;
00366 const FXString &dbName() const throw();
00368 void setDBName(const FXString &dbname);
00370 const FXString &user() const throw();
00372 void setUser(const FXString &user);
00374 const QHostAddress &host() const throw();
00376 void setHost(const QHostAddress &addr);
00378 FXushort port() const throw();
00380 void setPort(FXushort port);
00381
00383 virtual void open(const FXString &password=FXString::nullStr())=0;
00385 virtual void close()=0;
00387 virtual TnFXSQLDBStatementRef prepare(const FXString &text)=0;
00388
00390 virtual TnFXSQLDBCursorRef execute(const FXString &text, FXuint flags=2|4, QWaitCondition *latch=0);
00392 virtual void immediate(const FXString &text);
00393
00395 virtual void synchronise();
00396 };
00397
00407 class FXSQLMODULEAPI TnFXSQLDBTransaction
00408 {
00409 TnFXSQLDB *mydb;
00410 FXString myname;
00411 bool dismissed;
00412 void command(const char *_cmd)
00413 {
00414 if(mydb)
00415 {
00416 FXString cmd(_cmd);
00417 if(!myname.empty()) cmd.append(" '"+myname+"'");
00418 cmd.append(";");
00419 mydb->immediate(cmd);
00420 }
00421 }
00422 TnFXSQLDBTransaction(const TnFXSQLDBTransaction &);
00423 TnFXSQLDBTransaction &operator=(const TnFXSQLDBTransaction &);
00424 public:
00426 TnFXSQLDBTransaction(TnFXSQLDB *db, const FXString &name=FXString::nullStr()) : mydb(db), myname(name), dismissed(false) { command("BEGIN TRANSACTION"); }
00427 TnFXSQLDBTransaction(FXAutoPtr<TnFXSQLDB> &db, const FXString &name=FXString::nullStr()) : mydb(&(*db)), myname(name), dismissed(false) { command("BEGIN TRANSACTION"); }
00428 ~TnFXSQLDBTransaction()
00429 {
00430 rollback();
00431 }
00433 void commit()
00434 {
00435 if(mydb && !dismissed)
00436 {
00437 command("COMMIT TRANSACTION");
00438 dismissed=true;
00439 }
00440 }
00442 void rollback()
00443 {
00444 if(mydb && !dismissed)
00445 {
00446 command("ROLLBACK TRANSACTION");
00447 dismissed=true;
00448 }
00449 }
00450 };
00451
00468 struct TnFXSQLDBCursorPrivate;
00469 class FXSQLMODULEAPI TnFXSQLDBCursor : public FXRefedObject<int>
00470 {
00471 TnFXSQLDBCursorPrivate *p;
00472 TnFXSQLDBCursor &operator=(const TnFXSQLDBCursor &o);
00473 protected:
00474 TnFXSQLDBCursor(FXuint flags, TnFXSQLDBStatement *parent, QWaitCondition *latch, FXuint columns);
00475 TnFXSQLDBCursor(const TnFXSQLDBCursor &o);
00476 void int_setInternals(FXint *rows, FXuint *flags=0, FXuint *columns=0, QWaitCondition *latch=0);
00477 void int_setRowsReady(FXint start, FXint end);
00478 void int_setAtEnd(bool atend);
00479 public:
00480 virtual ~TnFXSQLDBCursor();
00482 virtual TnFXSQLDBCursorRef copy() const=0;
00483
00485 enum Flags
00486 {
00487 IsStatic=1,
00488 IsDynamic=2,
00489 ForwardOnly=4
00490 };
00491
00493 FXuint flags() const throw();
00495 TnFXSQLDBStatement *statement() const throw();
00497 QWaitCondition *resultsLatch() const throw();
00499 FXuint columns() const throw();
00501 FXint rows() const throw();
00503 bool rowsReady(FXint &start, FXint &end) const throw();
00504
00506 bool atEnd() const throw();
00508 FXint at() const throw();
00512 virtual FXint at(FXint newrow);
00514 virtual FXint backwards();
00516 FXint prev() { return backwards(); }
00518 virtual FXint forwards();
00520 FXint next() { return forwards(); }
00521
00524 virtual void type(TnFXSQLDB::SQLDataType &datatype, FXint &size, FXuint no) const=0;
00526 virtual TnFXSQLDBColumnRef header(FXuint no)=0;
00528 virtual TnFXSQLDBColumnRef data(FXuint no)=0;
00529 };
00530
00554 struct TnFXSQLDBStatementPrivate;
00555 class FXSQLMODULEAPI TnFXSQLDBStatement : public FXRefedObject<int>
00556 {
00557 TnFXSQLDBStatementPrivate *p;
00558 TnFXSQLDBStatement &operator=(const TnFXSQLDBStatement &o);
00559 protected:
00560 TnFXSQLDBStatement(TnFXSQLDB *parent, const FXString &text);
00561 TnFXSQLDBStatement(const TnFXSQLDBStatement &o);
00562 public:
00563 virtual ~TnFXSQLDBStatement();
00565 virtual TnFXSQLDBStatementRef copy() const=0;
00566
00568 TnFXSQLDB *driver() const throw();
00570 const FXString &text() const throw();
00571
00573 virtual FXint parameters() const=0;
00575 virtual FXint parameterIdx(const FXString &name) const=0;
00577 virtual FXString parameterName(FXint idx) const=0;
00582 virtual TnFXSQLDBStatement &bind(FXint idx, TnFXSQLDB::SQLDataType datatype, void *data);
00583 private:
00584 #if defined(_MSC_VER) && _MSC_VER<=1400 && !defined(__INTEL_COMPILER) && !defined(__GCCXML__)
00585 #if _MSC_VER<=1310
00586
00587 friend struct TnFXSQLDBImpl::DoSerialise;
00588 #else
00589
00590 public:
00591 #endif
00592 #else
00593
00594 template<bool unknownType, typename type> friend struct TnFXSQLDBImpl::DoSerialise;
00595 #endif
00596 void int_bindUnknownBLOB(FXint idx, FXAutoPtr<QBuffer> buff);
00597 public:
00599 template<typename type> TnFXSQLDBStatement &bind(FXint idx, const type &v)
00600 {
00601 typedef TnFXSQLDB::CPPToSQL92Type<type> sql92type;
00602 TnFXSQLDBImpl::BindImpl<sql92type::value, -1!=sql92type::unsignedIntIdx, type>(this, idx,
00603 TnFXSQLDBImpl::checkForOverflow<-1!=sql92type::unsignedIntIdx, type, typename sql92type::signedIntEquiv>::Do(&v), v);
00604 return *this;
00605 }
00607 TnFXSQLDBStatement &bind(FXint idx)
00608 {
00609 bind(idx, TnFXSQLDB::Null, 0);
00610 return *this;
00611 }
00615 template<typename type> FXint bind(const FXString &name, const type &v)
00616 {
00617 FXint idx=parameterIdx(name);
00618 bind<type>(idx, v);
00619 return idx;
00620 }
00622 FXint bind(const FXString &name)
00623 {
00624 FXint idx=parameterIdx(name);
00625 bind(idx, TnFXSQLDB::Null, 0);
00626 return idx;
00627 }
00631 virtual TnFXSQLDBCursorRef execute(FXuint flags=TnFXSQLDBCursor::IsDynamic|TnFXSQLDBCursor::ForwardOnly, QWaitCondition *latch=0)=0;
00633 virtual void immediate()=0;
00634 };
00635
00636
00637 namespace TnFXSQLDBImpl
00638 {
00639 template<bool override, typename type> struct SerialiseUnknownBLOB
00640 {
00641 SerialiseUnknownBLOB(FXStream &s, const type &v)
00642 {
00643 s << const_cast<type &>(v);
00644 }
00645 };
00646 template<bool override, typename type> struct DeserialiseUnknownBLOB
00647 {
00648 DeserialiseUnknownBLOB(type &v, FXStream &s)
00649 {
00650 s >> v;
00651 }
00652 };
00653
00654
00655
00656 template<int sql92type, bool isUnsignedInt, typename type> struct BindImpl
00657 {
00658 BindImpl(TnFXSQLDBStatement *s, FXint idx, bool upgrade, const type &v)
00659 {
00660 TnFXSQLDB::SQLDataType datatype=TnFXSQLDB::toSQL92Type<type>(&v) ;
00661 s->bind(idx, datatype, (void *) &v);
00662 }
00663 };
00664 template<int sql92type, typename type> struct BindImpl<sql92type, true, type>
00665 {
00666 BindImpl(TnFXSQLDBStatement *s, FXint idx, bool upgrade, const type &v)
00667 {
00668 TnFXSQLDB::SQLDataType datatype=TnFXSQLDB::toSQL92Type<type>(&v) ;
00669 if(upgrade)
00670 {
00671 typedef typename Generic::TL::at<TnFXSQLDB::CPPDataTypes, sql92type+1>::value biggerContainer;
00672 biggerContainer bv=v;
00673 s->bind(idx, datatype, (void *) &bv);
00674 }
00675 else
00676 s->bind(idx, datatype, (void *) &v);
00677 }
00678 };
00679 template<bool canSerialise, typename type> struct DoSerialise
00680 {
00681 DoSerialise(TnFXSQLDBStatement *s, FXint idx, const type &v)
00682 {
00683 FXERRG(FXString("No operator<< found for type %1").arg(Generic::typeInfo<type>().name()), 0, FXERRH_ISDEBUG);
00684 }
00685 };
00686 template<typename type> struct DoSerialise<true, type>
00687 {
00688 DoSerialise(TnFXSQLDBStatement *s, FXint idx, const type &v)
00689 {
00690 FXAutoPtr<QBuffer> buff;
00691 FXERRHM(buff=new QBuffer);
00692 buff->open(IO_WriteOnly);
00693 FXStream ds(PtrPtr(buff));
00694 SerialiseUnknownBLOB<true, type>(ds, v);
00695 s->int_bindUnknownBLOB(idx, buff);
00696 }
00697 };
00698 template<bool isUnsignedInt, typename type> struct BindImpl<-1, isUnsignedInt, type>
00699 {
00700 BindImpl(TnFXSQLDBStatement *s, FXint idx, bool upgrade, const type &v)
00701 {
00702 DoSerialise<Generic::hasSerialise<type>::value, type>(s, idx, v);
00703 }
00704 };
00705 template<bool isUnsignedInt> struct BindImpl<-1, isUnsignedInt, const char *>
00706 {
00707 BindImpl(TnFXSQLDBStatement *s, FXint idx, bool upgrade, const char *&v)
00708 {
00709 FXString l(v);
00710 TnFXSQLDB::SQLDataType datatype=TnFXSQLDB::toSQL92Type<FXString>(&l) ;
00711 s->bind(idx, datatype, (void *) &l);
00712 }
00713 };
00714
00715
00716
00717 template<bool isConvertible, typename rettype, typename srctype> struct GetImpl
00718 {
00719 GetImpl(rettype *dst, const srctype *src, TnFXSQLDB::SQLDataType sqldatatype, FXuval srcsize)
00720 {
00721 FXERRG(FXString("No conversion exists from %1 to %2").arg(Generic::typeInfo<srctype>().name()).arg(Generic::typeInfo<rettype>().name()), 0, FXERRH_ISDEBUG);
00722 }
00723 };
00724 template<typename rettype, typename srctype> struct GetImpl<true, rettype, srctype>
00725 {
00726 GetImpl(rettype *dst, const srctype *src, TnFXSQLDB::SQLDataType sqldatatype, FXuval srcsize)
00727 {
00728 *dst=*src;
00729 }
00730 };
00731 template<typename rettype> struct GetImpl<true, rettype, FXString>
00732 {
00733 GetImpl(rettype *dst, const FXString *src, TnFXSQLDB::SQLDataType sqldatatype, FXuval srcsize)
00734 {
00735 if(TnFXSQLDB::VarChar==sqldatatype || TnFXSQLDB::Char==sqldatatype)
00736 {
00737 *dst=FXString((const FXchar *) src, (FXint) srcsize);
00738 }
00739 else if(TnFXSQLDB::WVarChar==sqldatatype || TnFXSQLDB::WChar==sqldatatype)
00740 {
00741
00742 assert(0);
00743 }
00744 else { assert(0); }
00745 }
00746 };
00747 template<> struct GetImpl<false, const char *, FXString>
00748 {
00749 GetImpl(const char **dst, const FXString *src, TnFXSQLDB::SQLDataType sqldatatype, FXuval srcsize)
00750 {
00751 if(TnFXSQLDB::VarChar==sqldatatype || TnFXSQLDB::Char==sqldatatype)
00752 {
00753 *dst=(const FXchar *) src;
00754 }
00755 else
00756 *dst=0;
00757 }
00758 };
00759 template<> struct GetImpl<true, QByteArray, QByteArray>
00760 {
00761 GetImpl(QByteArray *dst, const QByteArray *src, TnFXSQLDB::SQLDataType sqldatatype, FXuval srcsize)
00762 {
00763 dst->setRawData((FXuchar *) src, (FXuint) srcsize, true);
00764 }
00765 };
00766 template<bool canDeserialise, typename rettype> struct DoDeserialise
00767 {
00768 DoDeserialise(rettype *dst, FXuchar *src, FXuint srcsize)
00769 {
00770 FXERRG(FXString("No operator>> found for type %1").arg(Generic::typeInfo<rettype>().name()), 0, FXERRH_ISDEBUG);
00771 }
00772 };
00773 template<typename rettype> struct DoDeserialise<true, rettype>
00774 {
00775 DoDeserialise(rettype *dst, FXuchar *src, FXuint srcsize)
00776 {
00777 QByteArray ba(src, srcsize);
00778 QBuffer buff(ba);
00779 buff.open(IO_ReadOnly);
00780 FXStream ds(&buff);
00781 DeserialiseUnknownBLOB<true, rettype>(*dst, ds);
00782 }
00783 };
00784 template<bool isConvertible, typename rettype> struct GetImpl<isConvertible, rettype, QByteArray>
00785 {
00786 GetImpl(rettype *dst, const QByteArray *src, TnFXSQLDB::SQLDataType sqldatatype, FXuval srcsize)
00787 {
00788 DoDeserialise<Generic::hasDeserialise<rettype>::value, rettype>(dst, (FXuchar *) src, (FXuint) srcsize);
00789 }
00790 };
00791 template<typename rettype> struct Get
00792 {
00793 template<typename type> struct Source
00794 {
00795 static void Do(rettype *dst, const void *src, TnFXSQLDB::SQLDataType sqldatatype, FXuval srcsize)
00796 {
00797 GetImpl<Generic::convertible<rettype, type>::value, rettype, type>(dst, (const type *) src, sqldatatype, srcsize);
00798 }
00799 };
00800 static void Invoke(rettype *dst, const void *src, TnFXSQLDB::SQLDataType sqldatatype, FXuval srcsize)
00801 {
00802 TnFXSQLDB::toCPPType<Source>(sqldatatype, dst, src, sqldatatype, srcsize);
00803 }
00804 };
00805 }
00806
00822 class FXSQLMODULEAPI TnFXSQLDBColumn : public FXRefedObject<int>
00823 {
00824 protected:
00825 FXint myflags;
00826 TnFXSQLDBCursorRef myparent;
00827 FXuint mycolumn;
00828 FXint myrow;
00829 TnFXSQLDB::SQLDataType mytype;
00830 const void *mydata;
00831 FXuval mydatalen;
00832 union Scratch
00833 {
00834 FXchar tinyint;
00835 FXshort smallint;
00836 FXint integer;
00837 FXlong bigint;
00838 FXfloat real;
00839 FXdouble double_;
00840 char timestamp[sizeof(FXTime)];
00841 } scratch;
00842 TnFXSQLDBColumn(const TnFXSQLDBColumn &o) : myflags(o.myflags), myparent(o.myparent), mycolumn(o.mycolumn), myrow(o.myrow), mytype(o.mytype),
00843 mydata(o.mydata), mydatalen(o.mydatalen) { }
00844 public:
00845 TnFXSQLDBColumn(FXuint flags, TnFXSQLDBCursor *parent, FXuint column, FXint row, TnFXSQLDB::SQLDataType type=TnFXSQLDB::Null)
00846 : myflags(flags), myparent(parent), mycolumn(column), myrow(row), mytype(type), mydata(0), mydatalen(0) { }
00847 virtual ~TnFXSQLDBColumn() { }
00849 virtual TnFXSQLDBColumnRef copy() const=0;
00851 enum Flags
00852 {
00853 IsHeader=1
00854 };
00855
00857 FXuint flags() const throw() { return myflags; }
00859 TnFXSQLDBCursor *cursor() const throw() { return const_cast<TnFXSQLDBCursor *>(PtrPtr(myparent)); }
00861 FXuint column() const throw() { return mycolumn; }
00863 FXint row() const throw() { return myrow; }
00865 TnFXSQLDBColumnRef header() const { return cursor()->header(column()); }
00867 TnFXSQLDB::SQLDataType type() const throw() { return mytype; }
00869 const void *data() const throw() { return mydata; }
00871 FXuval size() const throw() { return mydatalen; }
00875 TnFXSQLDB::SQLDataType effectiveType() const throw()
00876 {
00877 if(TnFXSQLDB::Decimal==mytype || TnFXSQLDB::Numeric==mytype)
00878 return (TnFXSQLDB::SQLDataType)(TnFXSQLDB::TinyInt+fxbitscan((FXulong) mydatalen));
00879 if(TnFXSQLDB::Float==mytype)
00880 return (TnFXSQLDB::SQLDataType)(TnFXSQLDB::Real-2+fxbitscan((FXulong) mydatalen));
00881 return mytype;
00882 }
00883
00886 template<class T> void get(T &dst) const
00887 {
00888
00889 TnFXSQLDB::SQLDataType coldatatype=effectiveType();
00890 TnFXSQLDBImpl::Get<T>::Invoke(&dst, mydata, coldatatype, mydatalen);
00891 }
00893 template<class T> T get() const
00894 {
00895 T ret;
00896 get<T>(ret);
00897 return ret;
00898 }
00899 };
00900
00901
00902
00911 struct TnFXSQLDBRegistryPrivate;
00912 class FXSQLMODULEAPI TnFXSQLDBRegistry
00913 {
00914 friend struct TnFXSQLDBRegistryPrivate;
00915 TnFXSQLDBRegistryPrivate *p;
00916 TnFXSQLDBRegistry(const TnFXSQLDBRegistry &);
00917 TnFXSQLDBRegistry &operator=(const TnFXSQLDBRegistry &);
00918 typedef FXAutoPtr<TnFXSQLDB> (*createSpec)(const FXString &dbname, const FXString &user, const QHostAddress &host, FXushort port);
00919 void int_register(const FXString &name, createSpec create);
00920 void int_deregister(const FXString &name, createSpec create);
00921 public:
00922 TnFXSQLDBRegistry();
00923 ~TnFXSQLDBRegistry();
00924
00926 static TnFXSQLDBRegistry *processRegistry();
00928 QStringList drivers() const;
00930 FXAutoPtr<TnFXSQLDB> instantiate(const FXString &name, const FXString &dbname=FXString::nullStr(), const FXString &user=FXString::nullStr(), const QHostAddress &host=QHOSTADDRESS_LOCALHOST, FXushort port=0) const;
00932 static FXAutoPtr<TnFXSQLDB> make(const FXString &name, const FXString &dbname=FXString::nullStr(), const FXString &user=FXString::nullStr(), const QHostAddress &host=QHOSTADDRESS_LOCALHOST, FXushort port=0)
00933 {
00934 return processRegistry()->instantiate(name, dbname, user, host, port);
00935 }
00936
00937 template<class type> struct Register
00938 {
00939 static FXAutoPtr<TnFXSQLDB> create(const FXString &dbname, const FXString &user, const QHostAddress &host, FXushort port) { return new type(dbname, user, host, port); }
00940 Register() { processRegistry()->int_register(type::MyName, create); }
00941 ~Register() { processRegistry()->int_deregister(type::MyName, create); }
00942 };
00943 template<class type> friend struct Register;
00944 };
00945
00946
00947 #ifdef _MSC_VER
00948 #pragma warning(pop)
00949 #endif
00950
00951 }
00952
00953 #endif
00954 #endif