00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "pqxx/libcompiler.h"
00019
00020 #include <cstdio>
00021 #include <cctype>
00022 #include <sstream>
00023 #include <stdexcept>
00024 #include <string>
00025 #include <typeinfo>
00026 #include <vector>
00027
00047
00048 namespace pqxx {}
00049
00050 #ifdef PQXX_PQ_IN_NAMESPACE
00051
00052
00053 namespace pqxx
00054 {
00055 namespace internal
00056 {
00057 namespace pq
00058 {
00059 #define PQXXPQ pqxx::internal::pq
00060 extern "C"
00061 {
00062 #include "libpq-fe.h"
00063 }
00064 }
00065 }
00066 }
00067
00068 #else // PQXX_PQ_IN_NAMESPACE
00069
00070
00071 extern "C"
00072 {
00073 #include "libpq-fe.h"
00074 }
00075
00076 namespace pqxx
00077 {
00078 namespace internal
00079 {
00080 namespace pq
00081 {
00082 #define PQXXPQ
00083 typedef PQXXPQ::PGconn PGconn;
00084 typedef PQXXPQ::PGresult PGresult;
00085
00086 }
00087 }
00088 }
00089
00090 #endif // PQXX_PQ_IN_NAMESPACE
00091
00092
00093 namespace pqxx
00094 {
00096 typedef PQXXPQ::Oid oid;
00097
00099 const oid oid_none = 0;
00100
00102
00115 template<typename T> void error_unsupported_type_in_string_conversion(T);
00116
00117
00119
00125 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00126
00127
00128
00129
00130
00132
00142 template<typename T> void from_string(const char Str[], T &Obj);
00143
00144 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);
00145 template<>
00146 void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);
00147 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);
00148 template<>
00149 void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);
00150 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);
00151 template<>
00152 void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);
00153 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);
00154 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &);
00155 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);
00156 #if defined(PQXX_HAVE_LONG_DOUBLE)
00157 template<>
00158 void PQXX_LIBEXPORT from_string(const char Str[], long double &);
00159 #endif
00160
00161
00162 template<> inline void from_string(const char Str[],PGSTD::string &Obj)
00163 { Obj = Str; }
00164
00165 template<>
00166 inline void from_string(const char Str[], PGSTD::stringstream &Obj)
00167 { Obj.clear(); Obj << Str; }
00168
00169 template<typename T>
00170 inline void from_string(const PGSTD::string &Str, T &Obj)
00171 { from_string(Str.c_str(), Obj); }
00172
00173 template<typename T>
00174 inline void from_string(const PGSTD::stringstream &Str, T &Obj)
00175 { from_string(Str.str(), Obj); }
00176
00177 template<> inline void
00178 from_string(const PGSTD::string &Str, PGSTD::string &Obj)
00179 { Obj = Str; }
00180
00181 template<> inline void
00182 from_string(const PGSTD::string &, const char &Obj)
00183 { error_ambiguous_string_conversion(Obj); }
00184 template<> inline void
00185 from_string(const PGSTD::string &, const signed char &Obj)
00186 { error_ambiguous_string_conversion(Obj); }
00187 template<> inline void
00188 from_string(const PGSTD::string &, const unsigned char &Obj)
00189 { error_ambiguous_string_conversion(Obj); }
00190
00191
00193
00197 template<typename T> PGSTD::string to_string(const T &);
00198
00199 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);
00200 template<>
00201 PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);
00202 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);
00203 template<>
00204 PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);
00205 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);
00206 template<>
00207 PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);
00208 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);
00209 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);
00210 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);
00211 #if defined(PQXX_HAVE_LONG_DOUBLE)
00212 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &);
00213 #endif
00214
00215 inline PGSTD::string to_string(const char Obj[])
00216 { return PGSTD::string(Obj); }
00217
00218 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)
00219 { return Obj.str(); }
00220
00221 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}
00222
00223 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);
00224
00225
00226 template<> inline PGSTD::string to_string(const signed char &Obj)
00227 { return error_ambiguous_string_conversion(Obj); }
00228 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00229 { return error_ambiguous_string_conversion(Obj); }
00230
00231
00233
00250 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00251 class items : public CONT
00252 {
00253 public:
00255 items() : CONT() {}
00257 explicit items(const T &t) : CONT() { push_back(t); }
00258 items(const T &t1, const T &t2) : CONT()
00259 { push_back(t1); push_back(t2); }
00260 items(const T &t1, const T &t2, const T &t3) : CONT()
00261 { push_back(t1); push_back(t2); push_back(t3); }
00262 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()
00263 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00264 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()
00265 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00267 items(const CONT &c) : CONT(c) {}
00268
00270 items &operator()(const T &t)
00271 {
00272 push_back(t);
00273 return *this;
00274 }
00275 };
00276
00277
00278
00280 template<typename ITER> inline
00281 PGSTD::string separated_list(const PGSTD::string &sep,
00282 ITER begin,
00283 ITER end)
00284 {
00285 PGSTD::string result;
00286 if (begin != end)
00287 {
00288 result = to_string(*begin);
00289 for (++begin; begin != end; ++begin)
00290 {
00291 result += sep;
00292 result += to_string(*begin);
00293 }
00294 }
00295 return result;
00296 }
00297
00299 template<typename CONTAINER> inline
00300 PGSTD::string separated_list(const PGSTD::string &sep,
00301 const CONTAINER &c)
00302 {
00303 return separated_list(sep, c.begin(), c.end());
00304 }
00305
00306
00308
00317 namespace internal
00318 {
00319 typedef unsigned long result_size_type;
00320 typedef long result_difference_type;
00321
00323
00331 template<typename T> inline const char *FmtString(T t)
00332 {
00333 error_unsupported_type_in_string_conversion(t);
00334 return 0;
00335 }
00336
00337 template<> inline const char *FmtString(short) { return "%hd"; }
00338 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00339 template<> inline const char *FmtString(int) { return "%i"; }
00340 template<> inline const char *FmtString(long) { return "%li"; }
00341 template<> inline const char *FmtString(unsigned) { return "%u"; }
00342 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00343 template<> inline const char *FmtString(float) { return "%f"; }
00344 template<> inline const char *FmtString(double) { return "%lf"; }
00345 template<> inline const char *FmtString(char) { return "%c"; }
00346 template<> inline const char *FmtString(unsigned char) { return "%c"; }
00347 #if defined(PQXX_HAVE_LONG_DOUBLE)
00348 template<> inline const char *FmtString(long double) { return "%Lf"; }
00349 #endif
00350
00351 }
00352
00354
00362 template<typename T> inline PGSTD::string ToString(const T &Obj)
00363 {
00364
00365 char Buf[500];
00366 sprintf(Buf, internal::FmtString(Obj), Obj);
00367 return PGSTD::string(Buf);
00368 }
00369
00370
00371 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00372 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00373 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00374
00375 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00376 {
00377 return reinterpret_cast<const char *>(Obj);
00378 }
00379
00380 template<> inline PGSTD::string ToString(const bool &Obj)
00381 {
00382 return ToString(unsigned(Obj));
00383 }
00384
00385 template<> inline PGSTD::string ToString(const short &Obj)
00386 {
00387 return ToString(int(Obj));
00388 }
00389
00390 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00391 {
00392 return ToString(unsigned(Obj));
00393 }
00394
00395
00397
00405 template<typename T> inline void FromString(const char Str[], T &Obj)
00406 {
00407 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00408 PGSTD::string(typeid(T).name()));
00409
00410 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00411 throw PGSTD::runtime_error("Cannot convert value '" +
00412 PGSTD::string(Str) +
00413 "' to " + typeid(T).name());
00414 }
00415
00416
00417 namespace internal
00418 {
00420
00422 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00423
00425
00427 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00428 const unsigned char *&Obj);
00429
00431 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00432 bool EmptyIsNull);
00433
00435 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00436 }
00437
00438
00439 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00440 {
00441 internal::FromString_string(Str, Obj);
00442 }
00443
00444 template<> inline void FromString(const char Str[], const char *&Obj)
00445 {
00446 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00447 Obj = Str;
00448 }
00449
00450 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00451 {
00452 internal::FromString_ucharptr(Str, Obj);
00453 }
00454
00455 template<> inline void FromString(const char Str[], bool &Obj)
00456 {
00457 from_string(Str, Obj);
00458 }
00459
00460
00462
00471 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]);
00472
00474
00484 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen);
00485
00487
00493 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &);
00494
00495
00497
00501 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00502
00503
00505
00507 template<>
00508 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00509 {
00510 return internal::Quote_string(Obj, EmptyIsNull);
00511 }
00512
00514
00516 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00517 {
00518 return internal::Quote_charptr(Obj, EmptyIsNull);
00519 }
00520
00521
00523
00528 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00529 bool EmptyIsNull)
00530 {
00531 return internal::Quote_charptr(Obj, EmptyIsNull);
00532 }
00533
00534
00535 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00536 {
00537 return Quote(ToString(Obj), EmptyIsNull);
00538 }
00539
00540
00542
00545 template<typename T> inline PGSTD::string Quote(T Obj)
00546 {
00547 return Quote(Obj, false);
00548 }
00549
00550
00551 namespace internal
00552 {
00553 void freepqmem(void *);
00554 void freenotif(PQXXPQ::PGnotify *);
00555
00557
00563 template<typename T> class PQAlloc
00564 {
00565 T *m_Obj;
00566 mutable const PQAlloc *m_l, *m_r;
00567 public:
00568 typedef T content_type;
00569
00570 PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00571 PQAlloc(const PQAlloc &rhs) throw () :
00572 m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00573 ~PQAlloc() throw () { loseref(); }
00574
00575 PQAlloc &operator=(const PQAlloc &rhs) throw ()
00576 { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00577
00579
00581 explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00582
00583 void swap(PQAlloc &rhs) throw ()
00584 {
00585 PQAlloc tmp(*this);
00586 *this = rhs;
00587 rhs = tmp;
00588 }
00589
00590 PQAlloc &operator=(T *obj) throw () { loseref(); makeref(obj); return *this; }
00591
00593 operator bool() const throw () { return m_Obj != 0; }
00594
00596 bool operator!() const throw () { return !m_Obj; }
00597
00599
00601 T *operator->() const throw (PGSTD::logic_error)
00602 {
00603 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00604 return m_Obj;
00605 }
00606
00608
00610 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00611
00613
00615 T *c_ptr() const throw () { return m_Obj; }
00616
00617 void clear() throw () { loseref(); }
00618
00619 private:
00620 void makeref(T *p) throw () { m_Obj = p; }
00621
00622 void makeref(const PQAlloc &rhs) throw ()
00623 {
00624 m_l = &rhs;
00625 m_r = rhs.m_r;
00626 m_l->m_r = m_r->m_l = this;
00627 m_Obj = rhs.m_Obj;
00628 }
00629
00631 void loseref() throw ()
00632 {
00633 if (m_l == this && m_Obj) freemem();
00634 m_Obj = 0;
00635 m_l->m_r = m_r;
00636 m_r->m_l = m_l;
00637 m_l = m_r = this;
00638 }
00639
00640 void freemem() throw () { freepqmem(m_Obj); }
00641 };
00642
00643
00645 template<> inline void PQAlloc<PQXXPQ::PGresult>::freemem() throw ()
00646 { PQclear(m_Obj); }
00648 template<> inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw ()
00649 { freenotif(m_Obj); }
00650
00651
00652 class PQXX_LIBEXPORT namedclass
00653 {
00654 public:
00655 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00656 m_Name(Name),
00657 m_Classname(Classname)
00658 {
00659 }
00660
00661 const PGSTD::string &name() const throw () { return m_Name; }
00662 const PGSTD::string &classname() const throw () {return m_Classname;}
00663 PGSTD::string description() const;
00664
00665 private:
00666 PGSTD::string m_Name, m_Classname;
00667 };
00668
00669
00670 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00671 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00672
00673
00675
00678 template<typename GUEST>
00679 class unique
00680 {
00681 public:
00682 unique() : m_Guest(0) {}
00683
00684 GUEST *get() const throw () { return m_Guest; }
00685
00686 void Register(GUEST *G)
00687 {
00688 CheckUniqueRegistration(G, m_Guest);
00689 m_Guest = G;
00690 }
00691
00692 void Unregister(GUEST *G)
00693 {
00694 CheckUniqueUnregistration(G, m_Guest);
00695 m_Guest = 0;
00696 }
00697
00698 private:
00699 GUEST *m_Guest;
00700
00702 unique(const unique &);
00704 unique &operator=(const unique &);
00705 };
00706
00708 void PQXX_LIBEXPORT sleep_seconds(int);
00709
00710 }
00711 }
00712