fastcgi++
data.hpp
Go to the documentation of this file.
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