00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "pqxx/libcompiler.h"
00019 #include "pqxx/config-public-libpq.h"
00020
00021 #include <cassert>
00022 #include <cstdio>
00023 #include <cctype>
00024 #include <sstream>
00025 #include <stdexcept>
00026 #include <string>
00027 #include <typeinfo>
00028 #include <vector>
00029
00030
00032 namespace pqxx
00033 {
00034 }
00035
00036
00037 #ifdef PQXX_PQ_IN_NAMESPACE
00038
00039
00040 namespace pqxx
00041 {
00042 namespace internal
00043 {
00044 namespace pq
00045 {
00046 #define PQXXPQ pqxx::internal::pq
00047 extern "C"
00048 {
00049 #include "libpq-fe.h"
00050 }
00051 }
00052 }
00053 }
00054
00055 #else // PQXX_PQ_IN_NAMESPACE
00056
00057
00058 extern "C"
00059 {
00060 #include "libpq-fe.h"
00061 }
00062
00063 namespace pqxx
00064 {
00065 namespace internal
00066 {
00067 namespace pq
00068 {
00069 #define PQXXPQ
00070 typedef PQXXPQ::PGconn PGconn;
00071 typedef PQXXPQ::PGresult PGresult;
00072
00073 }
00074 }
00075 }
00076
00077 #endif // PQXX_PQ_IN_NAMESPACE
00078
00079
00080 namespace pqxx
00081 {
00083 typedef PQXXPQ::Oid oid;
00084
00086 const oid oid_none = 0;
00087
00089
00102 template<typename T> void error_unsupported_type_in_string_conversion(T);
00103
00104
00106
00112 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00113
00114
00115
00116
00117
00119
00128 template<typename T> void from_string(const char Str[], T &Obj);
00129
00130 template<> void from_string(const char Str[], long &);
00131 template<> void from_string(const char Str[], unsigned long &);
00132 template<> void from_string(const char Str[], int &);
00133 template<> void from_string(const char Str[], unsigned int &);
00134 template<> void from_string(const char Str[], short &);
00135 template<> void from_string(const char Str[], unsigned short &);
00136 template<> void from_string(const char Str[], float &);
00137 template<> void from_string(const char Str[], double &);
00138 template<> void from_string(const char Str[], long double &);
00139 template<> void from_string(const char Str[], bool &);
00140
00141 template<> inline void from_string(const char Str[],PGSTD::string &Obj)
00142 { Obj = Str; }
00143
00144 template<>
00145 inline void from_string(const char Str[], PGSTD::stringstream &Obj)
00146 { Obj.clear(); Obj << Str; }
00147
00148 template<typename T>
00149 inline void from_string(const PGSTD::string &Str, T &Obj)
00150 { from_string(Str.c_str(), Obj); }
00151
00152 template<typename T>
00153 inline void from_string(const PGSTD::stringstream &Str, T &Obj)
00154 { from_string(Str.str(), Obj); }
00155
00156 template<> inline void
00157 from_string(const PGSTD::string &Str, PGSTD::string &Obj)
00158 { Obj = Str; }
00159
00160 template<> inline void
00161 from_string(const PGSTD::string &, const char &Obj)
00162 { error_ambiguous_string_conversion(Obj); }
00163 template<> inline void
00164 from_string(const PGSTD::string &, const signed char &Obj)
00165 { error_ambiguous_string_conversion(Obj); }
00166 template<> inline void
00167 from_string(const PGSTD::string &, const unsigned char &Obj)
00168 { error_ambiguous_string_conversion(Obj); }
00169
00170
00172
00176 template<typename T> PGSTD::string to_string(const T &);
00177
00178 template<> PGSTD::string to_string(const short &);
00179 template<> PGSTD::string to_string(const unsigned short &);
00180 template<> PGSTD::string to_string(const int &);
00181 template<> PGSTD::string to_string(const unsigned int &);
00182 template<> PGSTD::string to_string(const long &);
00183 template<> PGSTD::string to_string(const unsigned long &);
00184 template<> PGSTD::string to_string(const float &);
00185 template<> PGSTD::string to_string(const double &);
00186 template<> PGSTD::string to_string(const long double &);
00187 template<> PGSTD::string to_string(const bool &);
00188
00189 inline PGSTD::string to_string(const char Obj[])
00190 { return PGSTD::string(Obj); }
00191
00192 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)
00193 { return Obj.str(); }
00194
00195 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}
00196
00197 template<> PGSTD::string to_string(const char &);
00198
00199
00200 template<> inline PGSTD::string to_string(const signed char &Obj)
00201 { return error_ambiguous_string_conversion(Obj); }
00202 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00203 { return error_ambiguous_string_conversion(Obj); }
00204
00205
00207
00224 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00225 class items : public CONT
00226 {
00227 public:
00229 items() : CONT() {}
00231 explicit items(const T &t) : CONT() { push_back(t); }
00232 items(const T &t1, const T &t2) : CONT()
00233 { push_back(t1); push_back(t2); }
00234 items(const T &t1, const T &t2, const T &t3) : CONT()
00235 { push_back(t1); push_back(t2); push_back(t3); }
00236 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()
00237 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00238 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()
00239 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00241 items(const CONT &c) : CONT(c) {}
00242
00244 items &operator()(const T &t)
00245 {
00246 push_back(t);
00247 return *this;
00248 }
00249 };
00250
00251
00252
00254 template<typename ITER> inline
00255 PGSTD::string separated_list(const PGSTD::string &sep,
00256 ITER begin,
00257 ITER end)
00258 {
00259 PGSTD::string result;
00260 if (begin != end)
00261 {
00262 result = to_string(*begin);
00263 for (++begin; begin != end; ++begin)
00264 {
00265 result += sep;
00266 result += to_string(*begin);
00267 }
00268 }
00269 return result;
00270 }
00271
00273 template<typename CONTAINER> inline
00274 PGSTD::string separated_list(const PGSTD::string &sep,
00275 const CONTAINER &c)
00276 {
00277 return separated_list(sep, c.begin(), c.end());
00278 }
00279
00280
00282
00291 namespace internal
00292 {
00293 typedef unsigned long result_size_type;
00294 typedef long result_difference_type;
00295
00297
00305 template<typename T> inline const char *FmtString(T t)
00306 {
00307 error_unsupported_type_in_string_conversion(t);
00308 return 0;
00309 }
00310
00311 template<> inline const char *FmtString(short) { return "%hd"; }
00312 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00313 template<> inline const char *FmtString(int) { return "%i"; }
00314 template<> inline const char *FmtString(long) { return "%li"; }
00315 template<> inline const char *FmtString(unsigned) { return "%u"; }
00316 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00317 template<> inline const char *FmtString(float) { return "%f"; }
00318 template<> inline const char *FmtString(double) { return "%lf"; }
00319 template<> inline const char *FmtString(long double) { return "%Lf"; }
00320 template<> inline const char *FmtString(char) { return "%c"; }
00321 template<> inline const char *FmtString(unsigned char) { return "%c"; }
00322
00323 }
00324
00326
00334 template<typename T> inline PGSTD::string ToString(const T &Obj)
00335 {
00336
00337 char Buf[500];
00338 sprintf(Buf, internal::FmtString(Obj), Obj);
00339 return PGSTD::string(Buf);
00340 }
00341
00342
00343 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00344 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00345 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00346
00347 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00348 {
00349 return reinterpret_cast<const char *>(Obj);
00350 }
00351
00352 template<> inline PGSTD::string ToString(const bool &Obj)
00353 {
00354 return ToString(unsigned(Obj));
00355 }
00356
00357 template<> inline PGSTD::string ToString(const short &Obj)
00358 {
00359 return ToString(int(Obj));
00360 }
00361
00362 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00363 {
00364 return ToString(unsigned(Obj));
00365 }
00366
00367
00369
00377 template<typename T> inline void FromString(const char Str[], T &Obj)
00378 {
00379 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00380 PGSTD::string(typeid(T).name()));
00381
00382 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00383 throw PGSTD::runtime_error("Cannot convert value '" +
00384 PGSTD::string(Str) +
00385 "' to " + typeid(T).name());
00386 }
00387
00388
00389 namespace internal
00390 {
00392
00394 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00395
00397
00399 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00400 const unsigned char *&Obj);
00401
00403 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00404 bool EmptyIsNull);
00405
00407 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00408 }
00409
00410
00411 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00412 {
00413 internal::FromString_string(Str, Obj);
00414 }
00415
00416 template<> inline void FromString(const char Str[], const char *&Obj)
00417 {
00418 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00419 Obj = Str;
00420 }
00421
00422 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00423 {
00424 internal::FromString_ucharptr(Str, Obj);
00425 }
00426
00427 template<> inline void FromString(const char Str[], bool &Obj)
00428 {
00429 from_string(Str, Obj);
00430 }
00431
00432
00434
00443 PGSTD::string sqlesc(const char str[]);
00444
00446
00456 PGSTD::string sqlesc(const char str[], size_t maxlen);
00457
00459
00465 PGSTD::string sqlesc(const PGSTD::string &);
00466
00467
00469
00473 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00474
00475
00477
00479 template<>
00480 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00481 {
00482 return internal::Quote_string(Obj, EmptyIsNull);
00483 }
00484
00486
00488 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00489 {
00490 return internal::Quote_charptr(Obj, EmptyIsNull);
00491 }
00492
00493
00495
00500 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00501 bool EmptyIsNull)
00502 {
00503 return internal::Quote_charptr(Obj, EmptyIsNull);
00504 }
00505
00506
00507 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00508 {
00509 return Quote(ToString(Obj), EmptyIsNull);
00510 }
00511
00512
00514
00517 template<typename T> inline PGSTD::string Quote(T Obj)
00518 {
00519 return Quote(Obj, false);
00520 }
00521
00522
00523 namespace internal
00524 {
00525 void freepqmem(void *);
00526 void freenotif(PQXXPQ::PGnotify *);
00527
00529
00535 template<typename T> class PQAlloc
00536 {
00537 T *m_Obj;
00538 mutable const PQAlloc *m_l, *m_r;
00539 public:
00540 typedef T content_type;
00541
00542 PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00543 PQAlloc(const PQAlloc &rhs) throw () :
00544 m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00545 ~PQAlloc() throw () { loseref(); }
00546
00547 PQAlloc &operator=(const PQAlloc &rhs) throw ()
00548 { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00549
00551
00553 explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00554
00555 void swap(PQAlloc &rhs) throw ()
00556 {
00557 PQAlloc tmp(*this);
00558 *this = rhs;
00559 rhs = tmp;
00560 }
00561
00562 PQAlloc &operator=(T *obj) throw ()
00563 { assert(!obj || obj != m_Obj); loseref(); makeref(obj); return *this; }
00564
00566 operator bool() const throw () { return m_Obj != 0; }
00567
00569 bool operator!() const throw () { return !m_Obj; }
00570
00572
00574 T *operator->() const throw (PGSTD::logic_error)
00575 {
00576 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00577 return m_Obj;
00578 }
00579
00581
00583 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00584
00586
00588 T *c_ptr() const throw () { return m_Obj; }
00589
00590 void clear() throw () { loseref(); }
00591
00592 private:
00593 void makeref(T *p) throw ()
00594 {
00595 assert(m_l == this);
00596 assert(m_r == this);
00597 assert(!m_Obj);
00598 m_Obj = p;
00599 }
00600
00601 void makeref(const PQAlloc &rhs) throw ()
00602 {
00603 assert(m_l == this);
00604 assert(m_r == this);
00605 assert(&rhs != this);
00606 assert(!m_Obj);
00607 m_l = &rhs;
00608 m_r = rhs.m_r;
00609 m_l->m_r = m_r->m_l = this;
00610 m_Obj = rhs.m_Obj;
00611 }
00612
00614 void loseref() throw ()
00615 {
00616 assert(m_r->m_l == this);
00617 assert(m_l->m_r == this);
00618 assert((m_l==this) == (m_r==this));
00619
00620 if (m_l == this && m_Obj) freemem();
00621 m_Obj = 0;
00622 m_l->m_r = m_r;
00623 m_r->m_l = m_l;
00624 m_l = m_r = this;
00625 }
00626
00627 void freemem() throw ()
00628 {
00629 freepqmem(m_Obj);
00630 }
00631 };
00632
00633
00635 template<> inline void PQAlloc<PQXXPQ::PGresult>::freemem() throw ()
00636 {
00637 PQclear(m_Obj);
00638 }
00639
00640
00642 template<> inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw ()
00643 {
00644 freenotif(m_Obj);
00645 }
00646
00647
00648 class PQXX_LIBEXPORT namedclass
00649 {
00650 public:
00651 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00652 m_Name(Name),
00653 m_Classname(Classname)
00654 {
00655 }
00656
00657 const PGSTD::string &name() const throw () { return m_Name; }
00658 const PGSTD::string &classname() const throw () {return m_Classname;}
00659 PGSTD::string description() const;
00660
00661 private:
00662 PGSTD::string m_Name, m_Classname;
00663 };
00664
00665
00666 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00667 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00668
00669
00671
00674 template<typename GUEST>
00675 class unique
00676 {
00677 public:
00678 unique() : m_Guest(0) {}
00679
00680 GUEST *get() const throw () { return m_Guest; }
00681
00682 void Register(GUEST *G)
00683 {
00684 CheckUniqueRegistration(G, m_Guest);
00685 m_Guest = G;
00686 }
00687
00688 void Unregister(GUEST *G)
00689 {
00690 CheckUniqueUnregistration(G, m_Guest);
00691 m_Guest = 0;
00692 }
00693
00694 private:
00695 GUEST *m_Guest;
00696
00698 unique(const unique &);
00700 unique &operator=(const unique &);
00701 };
00702
00704 void sleep_seconds(int);
00705
00706 }
00707 }
00708