00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "pqxx/compiler-public.hxx"
00019
00020 #include <cstdio>
00021 #include <cctype>
00022 #include <sstream>
00023 #include <stdexcept>
00024 #include <string>
00025 #include <typeinfo>
00026 #include <vector>
00027
00065
00066 namespace pqxx {}
00067
00069
00074 namespace PGSTD {}
00075
00076 #include <pqxx/libpq-forward.hxx>
00077
00078
00079 namespace pqxx
00080 {
00082 const oid oid_none = 0;
00083
00106
00108
00121 template<typename T> void error_unsupported_type_in_string_conversion(T);
00122
00123
00125
00131 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00132
00133
00134
00135
00136
00138
00150 template<typename T> void from_string(const char Str[], T &Obj);
00151
00153
00159 template<typename T> void from_string(const char Str[], T &Obj, size_t)
00160 {
00161 return from_string(Str, Obj);
00162 }
00163
00164 template<> void PQXX_LIBEXPORT from_string(const char Str[],
00165 PGSTD::string &,
00166 size_t);
00167
00168 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);
00169 template<>
00170 void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);
00171 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);
00172 template<>
00173 void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);
00174 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);
00175 template<>
00176 void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);
00177 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);
00178 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &);
00179 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);
00180
00181 #if defined(PQXX_HAVE_LONG_LONG) && defined(PQXX_ALLOW_LONG_LONG)
00182 template<> void PQXX_LIBEXPORT
00183 from_string(const char Str[], long long &);
00184 template<> void PQXX_LIBEXPORT
00185 from_string(const char Str[], unsigned long long &);
00186 #endif
00187
00188 #if defined(PQXX_HAVE_LONG_DOUBLE)
00189 template<>
00190 void PQXX_LIBEXPORT from_string(const char Str[], long double &);
00191 #endif
00192
00193
00194 template<> inline void from_string(const char Str[],PGSTD::string &Obj)
00195 { Obj = Str; }
00196
00197 template<>
00198 inline void from_string(const char Str[], PGSTD::stringstream &Obj)
00199 { Obj.clear(); Obj << Str; }
00200
00201 template<typename T>
00202 inline void from_string(const PGSTD::string &Str, T &Obj)
00203 { from_string(Str.c_str(), Obj); }
00204
00205 template<typename T>
00206 inline void from_string(const PGSTD::stringstream &Str, T &Obj)
00207 { from_string(Str.str(), Obj); }
00208
00209 template<> inline void
00210 from_string(const PGSTD::string &Str, PGSTD::string &Obj)
00211 { Obj = Str; }
00212
00213 template<> inline void
00214 from_string(const char [], char &Obj)
00215 { error_ambiguous_string_conversion(Obj); }
00216 template<> inline void
00217 from_string(const char [], signed char &Obj)
00218 { error_ambiguous_string_conversion(Obj); }
00219 template<> inline void
00220 from_string(const char [], unsigned char &Obj)
00221 { error_ambiguous_string_conversion(Obj); }
00222
00223 template<> inline void
00224 from_string(const PGSTD::string &, char &Obj)
00225 { error_ambiguous_string_conversion(Obj); }
00226 template<> inline void
00227 from_string(const PGSTD::string &, signed char &Obj)
00228 { error_ambiguous_string_conversion(Obj); }
00229 template<> inline void
00230 from_string(const PGSTD::string &, unsigned char &Obj)
00231 { error_ambiguous_string_conversion(Obj); }
00232
00233
00234 namespace internal
00235 {
00237 inline int digit_to_number(char c) throw () { return c-'0'; }
00238 inline char number_to_digit(int i) throw () { return static_cast<char>(i)+'0'; }
00239 }
00240
00241
00243
00247 template<typename T> PGSTD::string to_string(const T &);
00248
00249 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);
00250 template<>
00251 PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);
00252 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);
00253 template<>
00254 PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);
00255 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);
00256 template<>
00257 PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);
00258 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);
00259 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);
00260 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);
00261
00262
00263
00264
00265
00266
00267
00268
00269 #if defined(PQXX_HAVE_LONG_LONG) && defined(PQXX_ALLOW_LONG_LONG)
00271 template<> PGSTD::string PQXX_LIBEXPORT
00272 to_string(const long long &);
00274 template<> PGSTD::string PQXX_LIBEXPORT
00275 to_string(const unsigned long long &);
00276 #endif
00277
00278 #if defined(PQXX_HAVE_LONG_DOUBLE)
00279 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &);
00280 #endif
00281
00282 inline PGSTD::string to_string(const char Obj[])
00283 { return PGSTD::string(Obj); }
00284
00285 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)
00286 { return Obj.str(); }
00287
00288 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}
00289
00290 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);
00291
00292
00293 template<> inline PGSTD::string to_string(const signed char &Obj)
00294 { return error_ambiguous_string_conversion(Obj); }
00295 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00296 { return error_ambiguous_string_conversion(Obj); }
00298
00300
00322 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00323 class items : public CONT
00324 {
00325 public:
00327 items() : CONT() {}
00329 explicit items(const T &t) : CONT() { push_back(t); }
00330 items(const T &t1, const T &t2) : CONT()
00331 { push_back(t1); push_back(t2); }
00332 items(const T &t1, const T &t2, const T &t3) : CONT()
00333 { push_back(t1); push_back(t2); push_back(t3); }
00334 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()
00335 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00336 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()
00337 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00339 items(const CONT &c) : CONT(c) {}
00340
00342 items &operator()(const T &t)
00343 {
00344 push_back(t);
00345 return *this;
00346 }
00347 };
00348
00349
00350 namespace internal
00351 {
00352
00354 template<typename ITER> struct dereference
00355 {
00356 typename ITER::value_type operator()(ITER i) const { return *i; }
00357 };
00358 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00359 }
00360
00361
00363
00369 template<typename ITER, typename ACCESS> inline
00370 PGSTD::string separated_list(const PGSTD::string &sep,
00371 ITER begin,
00372 ITER end,
00373 ACCESS access)
00374 {
00375 PGSTD::string result;
00376 if (begin != end)
00377 {
00378 result = to_string(access(begin));
00379 for (++begin; begin != end; ++begin)
00380 {
00381 result += sep;
00382 result += to_string(access(begin));
00383 }
00384 }
00385 return result;
00386 }
00387
00392
00394 template<typename ITER> inline PGSTD::string
00395 separated_list(const PGSTD::string &sep, ITER begin, ITER end)
00396 { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00397
00398
00400 template<typename OBJ> inline PGSTD::string
00401 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)
00402 { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00403
00404
00406 template<typename CONTAINER> inline PGSTD::string
00407 separated_list(const PGSTD::string &sep, const CONTAINER &c)
00408 { return separated_list(sep, c.begin(), c.end()); }
00410
00412
00421 namespace internal
00422 {
00423 typedef unsigned long result_size_type;
00424 typedef long result_difference_type;
00425 }
00426
00427
00428 namespace internal
00429 {
00431
00433 PGSTD::string escape_string(const char str[], size_t maxlen) PQXX_DEPRECATED;
00434 }
00435
00436
00437
00504
00505
00516 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]) PQXX_DEPRECATED;
00517
00519
00531 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen)
00532 PQXX_DEPRECATED;
00533
00535
00541 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &) PQXX_DEPRECATED;
00542
00544
00545
00546 namespace internal
00547 {
00548 void PQXX_LIBEXPORT freepqmem(void *);
00549
00550
00552 class PQXX_LIBEXPORT refcount
00553 {
00554 refcount *volatile m_l, *volatile m_r;
00555
00556 public:
00557 refcount();
00558 ~refcount();
00559
00561 void makeref(refcount &) throw ();
00562
00564 bool loseref() throw ();
00565
00566 private:
00568 refcount(const refcount &);
00570 refcount &operator=(const refcount &);
00571 };
00572
00573
00575
00589 template<typename T> class PQAlloc
00590 {
00591 T *m_Obj;
00592 mutable refcount m_rc;
00593 public:
00594 typedef T content_type;
00595
00596 PQAlloc() throw () : m_Obj(0), m_rc() {}
00597 PQAlloc(const PQAlloc &rhs) throw () : m_Obj(0), m_rc() { makeref(rhs); }
00598 ~PQAlloc() throw () { loseref(); }
00599
00600 PQAlloc &operator=(const PQAlloc &rhs) throw () {redoref(rhs); return *this;}
00601
00603
00605 explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_rc() {}
00606
00607 void swap(PQAlloc &rhs) throw ()
00608 {
00609 PQAlloc tmp(*this);
00610 *this = rhs;
00611 rhs = tmp;
00612 }
00613
00614 PQAlloc &operator=(T *obj) throw () { redoref(obj); return *this; }
00615
00617 operator bool() const throw () { return m_Obj != 0; }
00618
00620 bool operator!() const throw () { return !m_Obj; }
00621
00623
00625 T *operator->() const throw (PGSTD::logic_error)
00626 {
00627 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00628 return m_Obj;
00629 }
00630
00632
00634 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00635
00637
00639 T *c_ptr() const throw () { return m_Obj; }
00640
00641 void clear() throw () { loseref(); }
00642
00643 private:
00644 void makeref(T *p) throw () { m_Obj = p; }
00645
00646 void makeref(const PQAlloc &rhs) throw ()
00647 {
00648 m_Obj = rhs.m_Obj;
00649 m_rc.makeref(rhs.m_rc);
00650 }
00651
00653 void loseref() throw ()
00654 {
00655 if (m_rc.loseref() && m_Obj) freemem();
00656 m_Obj = 0;
00657 }
00658
00659 void redoref(const PQAlloc &rhs) throw ()
00660 { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
00661 void redoref(T *obj) throw ()
00662 { if (obj != m_Obj) { loseref(); makeref(obj); } }
00663
00664 void freemem() throw () { freepqmem(m_Obj); }
00665 };
00666
00667
00668 void PQXX_LIBEXPORT freemem_notif(pq::PGnotify *) throw ();
00669 template<> inline void PQAlloc<pq::PGnotify>::freemem() throw ()
00670 { freemem_notif(m_Obj); }
00671
00672
00673
00674 template<typename T> class scoped_array
00675 {
00676 T *m_ptr;
00677 public:
00678 typedef size_t size_type;
00679 typedef long difference_type;
00680
00681 scoped_array() : m_ptr(0) {}
00682 explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
00683 explicit scoped_array(T *t) : m_ptr(t) {}
00684 ~scoped_array() { delete [] m_ptr; }
00685
00686 T *c_ptr() const throw () { return m_ptr; }
00687 T &operator*() const throw () { return *m_ptr; }
00688 T &operator[](difference_type i) const throw () { return m_ptr[i]; }
00689
00690 scoped_array &operator=(T *t) throw ()
00691 {
00692 if (t != m_ptr)
00693 {
00694 delete [] m_ptr;
00695 m_ptr = t;
00696 }
00697 return *this;
00698 }
00699
00700 private:
00702 scoped_array(const scoped_array &);
00703 scoped_array &operator=(const scoped_array &);
00704 };
00705
00706
00707 class PQXX_LIBEXPORT namedclass
00708 {
00709 public:
00710 namedclass(const PGSTD::string &Classname, const PGSTD::string &Name="") :
00711 m_Classname(Classname),
00712 m_Name(Name)
00713 {
00714 }
00715
00716 const PGSTD::string &name() const throw () { return m_Name; }
00717 const PGSTD::string &classname() const throw () {return m_Classname;}
00718 PGSTD::string description() const;
00719
00720 private:
00721 PGSTD::string m_Classname, m_Name;
00722 };
00723
00724
00725 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00726 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00727
00728
00730
00733 template<typename GUEST>
00734 class unique
00735 {
00736 public:
00737 unique() : m_Guest(0) {}
00738
00739 GUEST *get() const throw () { return m_Guest; }
00740
00741 void Register(GUEST *G)
00742 {
00743 CheckUniqueRegistration(G, m_Guest);
00744 m_Guest = G;
00745 }
00746
00747 void Unregister(GUEST *G)
00748 {
00749 CheckUniqueUnregistration(G, m_Guest);
00750 m_Guest = 0;
00751 }
00752
00753 private:
00754 GUEST *m_Guest;
00755
00757 unique(const unique &);
00759 unique &operator=(const unique &);
00760 };
00761
00763
00766 void PQXX_LIBEXPORT sleep_seconds(int);
00767
00769 typedef const char *cstring;
00770
00772
00781 cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
00782 throw ();
00783
00784
00786 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
00787
00788 }
00789 }
00790