fastcgi++
data.hpp
Go to the documentation of this file.
1 #ifndef ASQLDATA_HPP
2 #define ASQLDATA_HPP
3 
4 #include <boost/date_time/posix_time/posix_time_types.hpp>
5 #include <ostream>
6 #include <vector>
7 #include <string>
8 #include <map>
9 
10 #include <boost/preprocessor/seq/size.hpp>
11 #include <boost/preprocessor/seq/for_each_i.hpp>
12 #define ASQL_BUILDSETLINE(r, data, i, elem) case i: return elem;
13 
14 #define ASQL_BUILDSET(elements) \
15  size_t numberOfSqlElements() const { return BOOST_PP_SEQ_SIZE(elements); } \
16  ASql::Data::Index getSqlIndex(size_t index) const \
17  { \
18  switch(index) \
19  { \
20  BOOST_PP_SEQ_FOR_EACH_I(ASQL_BUILDSETLINE, 0, elements) \
21  default: return ASql::Data::Index(); \
22  } \
23  }
24 
25 namespace ASql
26 {
28  namespace Data
29  {
31 
36  enum Type { U_TINY=0,
42  INT,
54  BIT,
75 
77 
83  struct NullablePar
84  {
85  NullablePar(bool _nullness): nullness(_nullness) { }
86  bool nullness;
88 
91  virtual void* getVoid() =0;
92  };
93 
95  template<class T> struct Nullable: public NullablePar
96  {
97  T object;
98  void* getVoid() { return &object; }
99  operator T() { return object; }
100  operator const T() const { return object; }
101  Nullable<T>& operator=(const T& x) { object=x; nullness=false; return *this; }
102  Nullable(): NullablePar(true) {}
103  Nullable(const T& x): NullablePar(false), object(x) { }
104  };
105 
107  template<class T, int size> struct NullableArray: public NullablePar
108  {
109  T object[size];
110  void* getVoid() { return object; }
111  operator T*() { return object; }
113  NullableArray(const T& x): NullablePar(false), object(x) { }
114  };
115 
117  template<class charT, class Traits, class T> inline std::basic_ostream<charT, Traits>& operator<<(std::basic_ostream<charT, Traits>& os, const Nullable<T>& x)
118  {
119  if(x.nullness)
120  os << "NULL";
121  else
122  os << x.object;
123 
124  return os;
125  }
126 
127  typedef unsigned char Utiny;
128  typedef signed char Tiny;
129  typedef unsigned short int Ushort;
130  typedef short int Short;
131  typedef unsigned int Uint;
132  typedef int Int;
133  typedef unsigned long long int Ubigint;
134  typedef long long int Bigint;
135  typedef float Float;
136  typedef double Double;
137  typedef boost::posix_time::time_duration Time;
138  typedef boost::gregorian::date Date;
139  typedef boost::posix_time::ptime Datetime;
140  typedef std::string Text;
141  typedef std::wstring Wtext;
142  typedef bool Boolean;
144 
149  struct Blob
150  {
151  virtual size_t size() const =0;
152  virtual void resize(const size_t size) =0;
153  virtual char& operator[](const size_t index) =0;
154  };
155  struct VectorBlob: public Blob
156  {
157  std::vector<char>& m_data;
158  VectorBlob(std::vector<char>& data): m_data(data) {}
159  size_t size() const { return m_data.size(); }
160  void resize(const size_t size) { m_data.resize(size); };
161  char& operator[](const size_t index) { return m_data[index]; };
162  };
163 
180 
182 
186  struct Index
187  {
189  void* data;
190  size_t size;
191 
192  Index(const Utiny& x): type(U_TINY), data(const_cast<Utiny*>(&x)) { }
193  Index(const Tiny& x): type(TINY), data(const_cast<Tiny*>(&x)) { }
194  Index(const Ushort& x): type(U_SHORT), data(const_cast<Ushort*>(&x)) { }
195  Index(const Short& x): type(SHORT), data(const_cast<Short*>(&x)) { }
196  Index(const Uint& x): type(U_INT), data(const_cast<Uint*>(&x)) { }
197  Index(const Int& x): type(INT), data(const_cast<Int*>(&x)) { }
198  Index(const Ubigint& x): type(U_BIGINT), data(const_cast<Ubigint*>(&x)) { }
199  Index(const Bigint& x): type(BIGINT), data(const_cast<Bigint*>(&x)) { }
200  Index(const Float& x): type(FLOAT), data(const_cast<Float*>(&x)) { }
201  Index(const Double& x): type(DOUBLE), data(const_cast<Double*>(&x)) { }
202  Index(const Time& x): type(TIME), data(const_cast<Time*>(&x)) { }
203  Index(const Date& x): type(DATE), data(const_cast<Date*>(&x)) { }
204  Index(const Datetime& x): type(DATETIME), data(const_cast<Datetime*>(&x)) { }
205  Index(const Blob& x): type(BLOB), data(const_cast<Blob*>(&x)) { }
206  Index(const Text& x): type(TEXT), data(const_cast<Text*>(&x)) { }
207  Index(const Wtext& x): type(WTEXT), data(const_cast<Wtext*>(&x)) { }
208  Index(const Boolean& x): type(U_TINY), data(const_cast<Boolean*>(&x)) { }
209  Index(const char* const x, const size_t size_): type(CHAR), data(const_cast<char*>(x)), size(size_) { }
210  template<class T> explicit Index(const T& x): type(BINARY), data(const_cast<T*>(&x)), size(sizeof(T)) { }
211  Index(const UtinyN& x): type(U_TINY_N), data(const_cast<UtinyN*>(&x)) { }
212  Index(const TinyN& x): type(TINY_N), data(const_cast<TinyN*>(&x)) { }
213  Index(const UshortN& x): type(U_SHORT_N), data(const_cast<UshortN*>(&x)) { }
214  Index(const ShortN& x): type(SHORT_N), data(const_cast<ShortN*>(&x)) { }
215  Index(const UintN& x): type(U_INT_N), data(const_cast<UintN*>(&x)) { }
216  Index(const IntN& x): type(INT_N), data(const_cast<IntN*>(&x)) { }
217  Index(const UbigintN& x): type(U_BIGINT_N), data(const_cast<UbigintN*>(&x)) { }
218  Index(const BigintN& x): type(BIGINT_N), data(const_cast<BigintN*>(&x)) { }
219  Index(const FloatN& x): type(FLOAT_N), data(const_cast<FloatN*>(&x)) { }
220  Index(const DoubleN& x): type(DOUBLE_N), data(const_cast<DoubleN*>(&x)) { }
221  Index(const TimeN& x): type(TIME_N), data(const_cast<TimeN*>(&x)) { }
222  Index(const DateN& x): type(DATE_N), data(const_cast<DateN*>(&x)) { }
223  Index(const DatetimeN& x): type(DATETIME_N), data(const_cast<DatetimeN*>(&x)) { }
224  Index(const TextN& x): type(TEXT_N), data(const_cast<TextN*>(&x)) { }
225  Index(const WtextN& x): type(WTEXT_N), data(const_cast<WtextN*>(&x)) { }
226  Index(const BooleanN& x): type(U_TINY_N), data(const_cast<BooleanN*>(&x)) { }
227  template<int size_> Index(const NullableArray<char, size_>& x): type(CHAR_N), data(const_cast<NullableArray<char, size_>*>(&x)), size(size_) { }
228  template<class T> explicit Index(const Nullable<T>& x): type(BINARY_N), data(const_cast<Nullable<T>*>(&x)), size(sizeof(T)) { }
229 
230  Index(const Index& x): type(x.type), data(x.data), size(x.size) {}
231  Index(): type(NOTHING), data(0), size(0) {}
232 
233  const Index& operator=(const Index& x) { type=x.type; data=x.data; size=x.size; return *this; }
234  bool operator==(const Index& x) { return type==x.type && data==x.data && size==x.size; }
235  };
236 
239 
342  struct Set
343  {
345 
348  virtual size_t numberOfSqlElements() const =0;
349 
351 
359  virtual Index getSqlIndex(const size_t index) const =0;
360 
361  virtual ~Set() {}
362  };
363 
365 
369  template<class T> class SetBuilder: public Set
370  {
371  public:
373  T data;
375  private:
377  virtual size_t numberOfSqlElements() const { return data.numberOfSqlElements(); }
379  virtual Index getSqlIndex(const size_t index) const { return data.getSqlIndex(index); }
380  };
381 
383 
387  template<class T> class SetRefBuilder: public Set
388  {
390  virtual size_t numberOfSqlElements() const { return m_data.numberOfSqlElements(); }
392  virtual Index getSqlIndex(const size_t index) const { return m_data.getSqlIndex(index); }
394  const T& m_data;
395  public:
399  inline SetRefBuilder(const T& x): m_data(x) {}
400  };
401 
403 
410  template<class T> class SetPtrBuilder: public Set
411  {
413  const T* m_data;
414 
416  virtual size_t numberOfSqlElements() const { return m_data->numberOfSqlElements(); }
417 
419  virtual Index getSqlIndex(const size_t index) const { return m_data->getSqlIndex(index); }
420  public:
422  inline SetPtrBuilder(): m_data(0) {}
423 
425  inline SetPtrBuilder(const T& x): m_data(&x) {}
426 
428 
430  inline void set(const T& data) { m_data=&data; }
431 
433  inline void clear() { m_data=0; }
434 
436  operator bool() const { return m_data; }
437  };
438 
440 
447  template<class T> class SetSharedPtrBuilder: public Set
448  {
450  virtual size_t numberOfSqlElements() const { return data->numberOfSqlElements(); }
452  public:
453  virtual Index getSqlIndex(const size_t index) const { return data->getSqlIndex(index); }
455  inline SetSharedPtrBuilder(const boost::shared_ptr<T>& x): data(x) {}
458  boost::shared_ptr<T> data;
459  };
460 
462 
465  template<class T> class IndySetBuilder: public Set
466  {
467  public:
469  T data;
471  private:
473  virtual size_t numberOfSqlElements() const { return 1; }
475  virtual Index getSqlIndex(const size_t index) const { return data; }
476  };
477 
479 
482  template<class T> class IndySetRefBuilder: public Set
483  {
485  const T& data;
487  virtual size_t numberOfSqlElements() const { return 1; }
489  virtual Index getSqlIndex(const size_t index) const { return data; }
490  public:
494  inline IndySetRefBuilder(const T& x): data(x) {}
495  };
496 
498 
501  template<class T> class IndySetPtrBuilder: public Set
502  {
504  const T* m_data;
505 
507  virtual size_t numberOfSqlElements() const { return 1; }
508 
510  virtual Index getSqlIndex(const size_t index) const { return *m_data; }
511  public:
513  inline IndySetPtrBuilder(): m_data(0) {}
514 
516  inline IndySetPtrBuilder(const T& x): m_data(&x) {}
517 
519 
521  inline void set(const T& data) { m_data=&data; }
522 
524  inline void clear() { m_data=0; }
525 
527  operator bool() const { return m_data; }
528  };
529 
532  {
534  virtual Set& manufacture() =0;
536  virtual void trim() =0;
537  virtual ~SetContainer() {}
539 
542  virtual const Set* pull() const =0;
543  virtual void init() const =0;
544  };
545 
547 
556  template<class T> class STLSetContainer: public SetContainer
557  {
559  mutable typename T::iterator m_itBuffer;
560 
562  {
563  data.push_back(typename T::value_type());
564  m_buffer.set(data.back());
565  return m_buffer;
566  }
567  void trim() { data.pop_back(); }
568  const Set* pull() const
569  {
570  if(m_itBuffer == const_cast<T&>(data).end()) return 0;
571  m_buffer.set(*m_itBuffer++);
572  return &m_buffer;
573  }
574  public:
576  T data;
577  void init() const { m_itBuffer = const_cast<T&>(data).begin(); }
579  };
580 
582 
591  template<class T> class IndySTLSetContainer: public SetContainer
592  {
594  mutable typename T::iterator m_itBuffer;
595 
597  {
598  data.push_back(typename T::value_type());
599  m_buffer.set(data.back());
600  return m_buffer;
601  }
602  void trim() { data.pop_back(); }
603  const Set* pull() const
604  {
605  if(m_itBuffer == const_cast<T&>(data).end()) return 0;
606  m_buffer.set(*m_itBuffer++);
607  return &m_buffer;
608  }
609  public:
611  T data;
612  void init() const { m_itBuffer = const_cast<T&>(data).begin(); }
614  };
615 
617 
626  template<class T> class STLSetRefContainer: public SetContainer
627  {
628  T& data;
630  mutable typename T::iterator m_itBuffer;
631 
633  {
634  data.push_back(typename T::value_type());
635  m_buffer.set(data.back());
636  return m_buffer;
637  }
638  void trim() { data.pop_back(); }
639  const Set* pull() const
640  {
641  if(m_itBuffer == const_cast<T&>(data).end()) return 0;
642  m_buffer.set(*m_itBuffer++);
643  return &m_buffer;
644  }
645  public:
646  void init() const { m_itBuffer = const_cast<T&>(data).begin(); }
650  STLSetRefContainer(T& x): data(x), m_itBuffer(data.begin()) {}
651  };
652 
654 
663  template<class T> class STLSharedSetContainer: public SetContainer
664  {
666  mutable typename T::iterator m_itBuffer;
667 
669  {
670  data->push_back(typename T::value_type());
671  m_buffer.set(data->back());
672  return m_buffer;
673  }
674  void trim() { data->pop_back(); }
675  const Set* pull() const
676  {
677  if(m_itBuffer == const_cast<T*>(data)->end()) return 0;
678  m_buffer.set(*m_itBuffer++);
679  return &m_buffer;
680  }
681  public:
683  boost::shared_ptr<T> data;
684  STLSharedSetContainer(const boost::shared_ptr<T>& x): data(x) {}
686  void init() const { m_itBuffer = const_cast<T*>(data)->begin(); }
687  };
688 
690  struct Conversion
691  {
693 
696  virtual void* getPointer() =0;
697 
699  virtual void convertResult() =0;
700 
702  virtual void convertParam() =0;
703 
705  void* external;
706  };
707 
708  typedef std::map<int, boost::shared_ptr<Conversion> > Conversions;
709  }
710 }
711 
712 #endif