fastcgi++
|
00001 #ifndef ASQLDATA_HPP 00002 #define ASQLDATA_HPP 00003 00004 #include <boost/date_time/posix_time/posix_time_types.hpp> 00005 #include <ostream> 00006 #include <vector> 00007 #include <string> 00008 #include <map> 00009 00010 #include <boost/preprocessor/seq/size.hpp> 00011 #include <boost/preprocessor/seq/for_each_i.hpp> 00012 #define ASQL_BUILDSETLINE(r, data, i, elem) case i: return elem; 00013 00014 #define ASQL_BUILDSET(elements) \ 00015 size_t numberOfSqlElements() const { return BOOST_PP_SEQ_SIZE(elements); } \ 00016 ASql::Data::Index getSqlIndex(size_t index) const \ 00017 { \ 00018 switch(index) \ 00019 { \ 00020 BOOST_PP_SEQ_FOR_EACH_I(ASQL_BUILDSETLINE, 0, elements) \ 00021 default: return ASql::Data::Index(); \ 00022 } \ 00023 } 00024 00025 namespace ASql 00026 { 00028 namespace Data 00029 { 00031 00036 enum Type { U_TINY=0, 00037 U_SHORT, 00038 U_INT, 00039 U_BIGINT, 00040 TINY, 00041 SHORT, 00042 INT, 00043 BIGINT, 00044 FLOAT, 00045 DOUBLE, 00046 TIME, 00047 DATE, 00048 DATETIME, 00049 BLOB, 00050 TEXT, 00051 WTEXT, 00052 CHAR, 00053 BINARY, 00054 BIT, 00055 U_TINY_N, 00056 U_SHORT_N, 00057 U_INT_N, 00058 U_BIGINT_N, 00059 TINY_N, 00060 SHORT_N, 00061 INT_N, 00062 BIGINT_N, 00063 FLOAT_N, 00064 DOUBLE_N, 00065 TIME_N, 00066 DATE_N, 00067 DATETIME_N, 00068 BLOB_N, 00069 TEXT_N, 00070 WTEXT_N, 00071 CHAR_N, 00072 BINARY_N, 00073 BIT_N, 00074 NOTHING }; 00075 00077 00083 struct NullablePar 00084 { 00085 NullablePar(bool _nullness): nullness(_nullness) { } 00086 bool nullness; 00088 00091 virtual void* getVoid() =0; 00092 }; 00093 00095 template<class T> struct Nullable: public NullablePar 00096 { 00097 T object; 00098 void* getVoid() { return &object; } 00099 operator T() { return object; } 00100 operator const T() const { return object; } 00101 Nullable<T>& operator=(const T& x) { object=x; nullness=false; return *this; } 00102 Nullable(): NullablePar(true) {} 00103 Nullable(const T& x): NullablePar(false), object(x) { } 00104 }; 00105 00107 template<class T, int size> struct NullableArray: public NullablePar 00108 { 00109 T object[size]; 00110 void* getVoid() { return object; } 00111 operator T*() { return object; } 00112 NullableArray(): NullablePar(false) {} 00113 NullableArray(const T& x): NullablePar(false), object(x) { } 00114 }; 00115 00117 template<class charT, class Traits, class T> inline std::basic_ostream<charT, Traits>& operator<<(std::basic_ostream<charT, Traits>& os, const Nullable<T>& x) 00118 { 00119 if(x.nullness) 00120 os << "NULL"; 00121 else 00122 os << x.object; 00123 00124 return os; 00125 } 00126 00127 typedef unsigned char Utiny; 00128 typedef signed char Tiny; 00129 typedef unsigned short int Ushort; 00130 typedef short int Short; 00131 typedef unsigned int Uint; 00132 typedef int Int; 00133 typedef unsigned long long int Ubigint; 00134 typedef long long int Bigint; 00135 typedef float Float; 00136 typedef double Double; 00137 typedef boost::posix_time::time_duration Time; 00138 typedef boost::gregorian::date Date; 00139 typedef boost::posix_time::ptime Datetime; 00140 typedef std::string Text; 00141 typedef std::wstring Wtext; 00142 typedef bool Boolean; 00144 00149 struct Blob 00150 { 00151 virtual size_t size() const =0; 00152 virtual void resize(const size_t size) =0; 00153 virtual char& operator[](const size_t index) =0; 00154 }; 00155 struct VectorBlob: public Blob 00156 { 00157 std::vector<char>& m_data; 00158 VectorBlob(std::vector<char>& data): m_data(data) {} 00159 size_t size() const { return m_data.size(); } 00160 void resize(const size_t size) { m_data.resize(size); }; 00161 char& operator[](const size_t index) { return m_data[index]; }; 00162 }; 00163 00164 typedef Nullable<Utiny> UtinyN; 00165 typedef Nullable<Tiny> TinyN; 00166 typedef Nullable<Ushort> UshortN; 00167 typedef Nullable<Short> ShortN; 00168 typedef Nullable<Uint> UintN; 00169 typedef Nullable<Int> IntN; 00170 typedef Nullable<Ubigint> UbigintN; 00171 typedef Nullable<Bigint> BigintN; 00172 typedef Nullable<Float> FloatN; 00173 typedef Nullable<Double> DoubleN; 00174 typedef Nullable<Time> TimeN; 00175 typedef Nullable<Date> DateN; 00176 typedef Nullable<Datetime> DatetimeN; 00177 typedef Nullable<Text> TextN; 00178 typedef Nullable<Wtext> WtextN; 00179 typedef Nullable<Boolean> BooleanN; 00180 00182 00186 struct Index 00187 { 00188 Type type; 00189 void* data; 00190 size_t size; 00191 00192 Index(const Utiny& x): type(U_TINY), data(const_cast<Utiny*>(&x)) { } 00193 Index(const Tiny& x): type(TINY), data(const_cast<Tiny*>(&x)) { } 00194 Index(const Ushort& x): type(U_SHORT), data(const_cast<Ushort*>(&x)) { } 00195 Index(const Short& x): type(SHORT), data(const_cast<Short*>(&x)) { } 00196 Index(const Uint& x): type(U_INT), data(const_cast<Uint*>(&x)) { } 00197 Index(const Int& x): type(INT), data(const_cast<Int*>(&x)) { } 00198 Index(const Ubigint& x): type(U_BIGINT), data(const_cast<Ubigint*>(&x)) { } 00199 Index(const Bigint& x): type(BIGINT), data(const_cast<Bigint*>(&x)) { } 00200 Index(const Float& x): type(FLOAT), data(const_cast<Float*>(&x)) { } 00201 Index(const Double& x): type(DOUBLE), data(const_cast<Double*>(&x)) { } 00202 Index(const Time& x): type(TIME), data(const_cast<Time*>(&x)) { } 00203 Index(const Date& x): type(DATE), data(const_cast<Date*>(&x)) { } 00204 Index(const Datetime& x): type(DATETIME), data(const_cast<Datetime*>(&x)) { } 00205 Index(const Blob& x): type(BLOB), data(const_cast<Blob*>(&x)) { } 00206 Index(const Text& x): type(TEXT), data(const_cast<Text*>(&x)) { } 00207 Index(const Wtext& x): type(WTEXT), data(const_cast<Wtext*>(&x)) { } 00208 Index(const Boolean& x): type(U_TINY), data(const_cast<Boolean*>(&x)) { } 00209 Index(const char* const x, const size_t size_): type(CHAR), data(const_cast<char*>(x)), size(size_) { } 00210 template<class T> explicit Index(const T& x): type(BINARY), data(const_cast<T*>(&x)), size(sizeof(T)) { } 00211 Index(const UtinyN& x): type(U_TINY_N), data(const_cast<UtinyN*>(&x)) { } 00212 Index(const TinyN& x): type(TINY_N), data(const_cast<TinyN*>(&x)) { } 00213 Index(const UshortN& x): type(U_SHORT_N), data(const_cast<UshortN*>(&x)) { } 00214 Index(const ShortN& x): type(SHORT_N), data(const_cast<ShortN*>(&x)) { } 00215 Index(const UintN& x): type(U_INT_N), data(const_cast<UintN*>(&x)) { } 00216 Index(const IntN& x): type(INT_N), data(const_cast<IntN*>(&x)) { } 00217 Index(const UbigintN& x): type(U_BIGINT_N), data(const_cast<UbigintN*>(&x)) { } 00218 Index(const BigintN& x): type(BIGINT_N), data(const_cast<BigintN*>(&x)) { } 00219 Index(const FloatN& x): type(FLOAT_N), data(const_cast<FloatN*>(&x)) { } 00220 Index(const DoubleN& x): type(DOUBLE_N), data(const_cast<DoubleN*>(&x)) { } 00221 Index(const TimeN& x): type(TIME_N), data(const_cast<TimeN*>(&x)) { } 00222 Index(const DateN& x): type(DATE_N), data(const_cast<DateN*>(&x)) { } 00223 Index(const DatetimeN& x): type(DATETIME_N), data(const_cast<DatetimeN*>(&x)) { } 00224 Index(const TextN& x): type(TEXT_N), data(const_cast<TextN*>(&x)) { } 00225 Index(const WtextN& x): type(WTEXT_N), data(const_cast<WtextN*>(&x)) { } 00226 Index(const BooleanN& x): type(U_TINY_N), data(const_cast<BooleanN*>(&x)) { } 00227 template<int size_> Index(const NullableArray<char, size_>& x): type(CHAR_N), data(const_cast<NullableArray<char, size_>*>(&x)), size(size_) { } 00228 template<class T> explicit Index(const Nullable<T>& x): type(BINARY_N), data(const_cast<Nullable<T>*>(&x)), size(sizeof(T)) { } 00229 00230 Index(const Index& x): type(x.type), data(x.data), size(x.size) {} 00231 Index(): type(NOTHING), data(0), size(0) {} 00232 00233 const Index& operator=(const Index& x) { type=x.type; data=x.data; size=x.size; return *this; } 00234 bool operator==(const Index& x) { return type==x.type && data==x.data && size==x.size; } 00235 }; 00236 00239 00342 struct Set 00343 { 00345 00348 virtual size_t numberOfSqlElements() const =0; 00349 00351 00359 virtual Index getSqlIndex(const size_t index) const =0; 00360 00361 virtual ~Set() {} 00362 }; 00363 00365 00369 template<class T> class SetBuilder: public Set 00370 { 00371 public: 00373 T data; 00374 SetBuilder() {} 00375 private: 00377 virtual size_t numberOfSqlElements() const { return data.numberOfSqlElements(); } 00379 virtual Index getSqlIndex(const size_t index) const { return data.getSqlIndex(index); } 00380 }; 00381 00383 00387 template<class T> class SetRefBuilder: public Set 00388 { 00390 virtual size_t numberOfSqlElements() const { return m_data.numberOfSqlElements(); } 00392 virtual Index getSqlIndex(const size_t index) const { return m_data.getSqlIndex(index); } 00394 const T& m_data; 00395 public: 00399 inline SetRefBuilder(const T& x): m_data(x) {} 00400 }; 00401 00403 00410 template<class T> class SetPtrBuilder: public Set 00411 { 00413 const T* m_data; 00414 00416 virtual size_t numberOfSqlElements() const { return m_data->numberOfSqlElements(); } 00417 00419 virtual Index getSqlIndex(const size_t index) const { return m_data->getSqlIndex(index); } 00420 public: 00422 inline SetPtrBuilder(): m_data(0) {} 00423 00425 inline SetPtrBuilder(const T& x): m_data(&x) {} 00426 00427 inline SetPtrBuilder(SetPtrBuilder& x): m_data(x.m_data) {} 00428 00430 inline void set(const T& data) { m_data=&data; } 00431 00433 inline void clear() { m_data=0; } 00434 00436 operator bool() const { return m_data; } 00437 }; 00438 00440 00447 template<class T> class SetSharedPtrBuilder: public Set 00448 { 00450 virtual size_t numberOfSqlElements() const { return data->numberOfSqlElements(); } 00452 public: 00453 virtual Index getSqlIndex(const size_t index) const { return data->getSqlIndex(index); } 00454 inline SetSharedPtrBuilder() {} 00455 inline SetSharedPtrBuilder(const boost::shared_ptr<T>& x): data(x) {} 00456 inline SetSharedPtrBuilder(SetSharedPtrBuilder& x): data(x.data) {} 00458 boost::shared_ptr<T> data; 00459 }; 00460 00462 00465 template<class T> class IndySetBuilder: public Set 00466 { 00467 public: 00469 T data; 00470 IndySetBuilder() {} 00471 private: 00473 virtual size_t numberOfSqlElements() const { return 1; } 00475 virtual Index getSqlIndex(const size_t index) const { return data; } 00476 }; 00477 00479 00482 template<class T> class IndySetRefBuilder: public Set 00483 { 00485 const T& data; 00487 virtual size_t numberOfSqlElements() const { return 1; } 00489 virtual Index getSqlIndex(const size_t index) const { return data; } 00490 public: 00494 inline IndySetRefBuilder(const T& x): data(x) {} 00495 }; 00496 00498 00501 template<class T> class IndySetPtrBuilder: public Set 00502 { 00504 const T* m_data; 00505 00507 virtual size_t numberOfSqlElements() const { return 1; } 00508 00510 virtual Index getSqlIndex(const size_t index) const { return *m_data; } 00511 public: 00513 inline IndySetPtrBuilder(): m_data(0) {} 00514 00516 inline IndySetPtrBuilder(const T& x): m_data(&x) {} 00517 00518 inline IndySetPtrBuilder(IndySetPtrBuilder& x): m_data(x.m_data) {} 00519 00521 inline void set(const T& data) { m_data=&data; } 00522 00524 inline void clear() { m_data=0; } 00525 00527 operator bool() const { return m_data; } 00528 }; 00529 00531 struct SetContainer 00532 { 00534 virtual Set& manufacture() =0; 00536 virtual void trim() =0; 00537 virtual ~SetContainer() {} 00539 00542 virtual const Set* pull() const =0; 00543 virtual void init() const =0; 00544 }; 00545 00547 00556 template<class T> class STLSetContainer: public SetContainer 00557 { 00558 mutable SetPtrBuilder<typename T::value_type> m_buffer; 00559 mutable typename T::iterator m_itBuffer; 00560 00561 Set& manufacture() 00562 { 00563 data.push_back(typename T::value_type()); 00564 m_buffer.set(data.back()); 00565 return m_buffer; 00566 } 00567 void trim() { data.pop_back(); } 00568 const Set* pull() const 00569 { 00570 if(m_itBuffer == const_cast<T&>(data).end()) return 0; 00571 m_buffer.set(*m_itBuffer++); 00572 return &m_buffer; 00573 } 00574 public: 00576 T data; 00577 void init() const { m_itBuffer = const_cast<T&>(data).begin(); } 00578 STLSetContainer(): m_itBuffer(data.begin()) {} 00579 }; 00580 00582 00591 template<class T> class IndySTLSetContainer: public SetContainer 00592 { 00593 mutable IndySetPtrBuilder<typename T::value_type> m_buffer; 00594 mutable typename T::iterator m_itBuffer; 00595 00596 Set& manufacture() 00597 { 00598 data.push_back(typename T::value_type()); 00599 m_buffer.set(data.back()); 00600 return m_buffer; 00601 } 00602 void trim() { data.pop_back(); } 00603 const Set* pull() const 00604 { 00605 if(m_itBuffer == const_cast<T&>(data).end()) return 0; 00606 m_buffer.set(*m_itBuffer++); 00607 return &m_buffer; 00608 } 00609 public: 00611 T data; 00612 void init() const { m_itBuffer = const_cast<T&>(data).begin(); } 00613 IndySTLSetContainer(): m_itBuffer(data.begin()) {} 00614 }; 00615 00617 00626 template<class T> class STLSetRefContainer: public SetContainer 00627 { 00628 T& data; 00629 mutable SetPtrBuilder<typename T::value_type> m_buffer; 00630 mutable typename T::iterator m_itBuffer; 00631 00632 Set& manufacture() 00633 { 00634 data.push_back(typename T::value_type()); 00635 m_buffer.set(data.back()); 00636 return m_buffer; 00637 } 00638 void trim() { data.pop_back(); } 00639 const Set* pull() const 00640 { 00641 if(m_itBuffer == const_cast<T&>(data).end()) return 0; 00642 m_buffer.set(*m_itBuffer++); 00643 return &m_buffer; 00644 } 00645 public: 00646 void init() const { m_itBuffer = const_cast<T&>(data).begin(); } 00650 STLSetRefContainer(T& x): data(x), m_itBuffer(data.begin()) {} 00651 }; 00652 00654 00663 template<class T> class STLSharedSetContainer: public SetContainer 00664 { 00665 mutable SetPtrBuilder<typename T::value_type> m_buffer; 00666 mutable typename T::iterator m_itBuffer; 00667 00668 Set& manufacture() 00669 { 00670 data->push_back(typename T::value_type()); 00671 m_buffer.set(data->back()); 00672 return m_buffer; 00673 } 00674 void trim() { data->pop_back(); } 00675 const Set* pull() const 00676 { 00677 if(m_itBuffer == const_cast<T*>(data)->end()) return 0; 00678 m_buffer.set(*m_itBuffer++); 00679 return &m_buffer; 00680 } 00681 public: 00683 boost::shared_ptr<T> data; 00684 STLSharedSetContainer(const boost::shared_ptr<T>& x): data(x) {} 00685 STLSharedSetContainer(): m_itBuffer(data->begin()) {} 00686 void init() const { m_itBuffer = const_cast<T*>(data)->begin(); } 00687 }; 00688 00690 struct Conversion 00691 { 00693 00696 virtual void* getPointer() =0; 00697 00699 virtual void convertResult() =0; 00700 00702 virtual void convertParam() =0; 00703 00705 void* external; 00706 }; 00707 00708 typedef std::map<int, boost::shared_ptr<Conversion> > Conversions; 00709 } 00710 } 00711 00712 #endif