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 <cstdio>
00022 #include <cctype>
00023 #include <sstream>
00024 #include <stdexcept>
00025 #include <string>
00026 #include <typeinfo>
00027 #include <vector>
00028
00048
00049 namespace pqxx {}
00050
00051 #ifdef PQXX_PQ_IN_NAMESPACE
00052
00053
00054 namespace pqxx
00055 {
00056 namespace internal
00057 {
00058 namespace pq
00059 {
00060 #define PQXXPQ pqxx::internal::pq
00061 extern "C"
00062 {
00063 #include "libpq-fe.h"
00064 }
00065 }
00066 }
00067 }
00068
00069 #else // PQXX_PQ_IN_NAMESPACE
00070
00071
00072 extern "C"
00073 {
00074 #include "libpq-fe.h"
00075 }
00076
00077 namespace pqxx
00078 {
00079 namespace internal
00080 {
00081 namespace pq
00082 {
00083 #define PQXXPQ
00084 typedef PQXXPQ::PGconn PGconn;
00085 typedef PQXXPQ::PGresult PGresult;
00086
00087 }
00088 }
00089 }
00090
00091 #endif // PQXX_PQ_IN_NAMESPACE
00092
00093
00094 namespace pqxx
00095 {
00097 typedef PQXXPQ::Oid oid;
00098
00100 const oid oid_none = 0;
00101
00103
00116 template<typename T> void error_unsupported_type_in_string_conversion(T);
00117
00118
00120
00126 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00127
00128
00129
00130
00131
00133
00142 template<typename T> void from_string(const char Str[], T &Obj);
00143
00144 template<> void from_string(const char Str[], long &);
00145 template<> void from_string(const char Str[], unsigned long &);
00146 template<> void from_string(const char Str[], int &);
00147 template<> void from_string(const char Str[], unsigned int &);
00148 template<> void from_string(const char Str[], short &);
00149 template<> void from_string(const char Str[], unsigned short &);
00150 template<> void from_string(const char Str[], float &);
00151 template<> void from_string(const char Str[], double &);
00152 template<> void from_string(const char Str[], bool &);
00153 #if defined(PQXX_HAVE_LONG_DOUBLE)
00154 template<> void from_string(const char Str[], long double &);
00155 #endif
00156
00157
00158 template<> inline void from_string(const char Str[],PGSTD::string &Obj)
00159 { Obj = Str; }
00160
00161 template<>
00162 inline void from_string(const char Str[], PGSTD::stringstream &Obj)
00163 { Obj.clear(); Obj << Str; }
00164
00165 template<typename T>
00166 inline void from_string(const PGSTD::string &Str, T &Obj)
00167 { from_string(Str.c_str(), Obj); }
00168
00169 template<typename T>
00170 inline void from_string(const PGSTD::stringstream &Str, T &Obj)
00171 { from_string(Str.str(), Obj); }
00172
00173 template<> inline void
00174 from_string(const PGSTD::string &Str, PGSTD::string &Obj)
00175 { Obj = Str; }
00176
00177 template<> inline void
00178 from_string(const PGSTD::string &, const char &Obj)
00179 { error_ambiguous_string_conversion(Obj); }
00180 template<> inline void
00181 from_string(const PGSTD::string &, const signed char &Obj)
00182 { error_ambiguous_string_conversion(Obj); }
00183 template<> inline void
00184 from_string(const PGSTD::string &, const unsigned char &Obj)
00185 { error_ambiguous_string_conversion(Obj); }
00186
00187
00189
00193 template<typename T> PGSTD::string to_string(const T &);
00194
00195 template<> PGSTD::string to_string(const short &);
00196 template<> PGSTD::string to_string(const unsigned short &);
00197 template<> PGSTD::string to_string(const int &);
00198 template<> PGSTD::string to_string(const unsigned int &);
00199 template<> PGSTD::string to_string(const long &);
00200 template<> PGSTD::string to_string(const unsigned long &);
00201 template<> PGSTD::string to_string(const float &);
00202 template<> PGSTD::string to_string(const double &);
00203 template<> PGSTD::string to_string(const bool &);
00204 #if defined(PQXX_HAVE_LONG_DOUBLE)
00205 template<> PGSTD::string to_string(const long double &);
00206 #endif
00207
00208 inline PGSTD::string to_string(const char Obj[])
00209 { return PGSTD::string(Obj); }
00210
00211 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)
00212 { return Obj.str(); }
00213
00214 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}
00215
00216 template<> PGSTD::string to_string(const char &);
00217
00218
00219 template<> inline PGSTD::string to_string(const signed char &Obj)
00220 { return error_ambiguous_string_conversion(Obj); }
00221 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00222 { return error_ambiguous_string_conversion(Obj); }
00223
00224
00226
00243 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00244 class items : public CONT
00245 {
00246 public:
00248 items() : CONT() {}
00250 explicit items(const T &t) : CONT() { push_back(t); }
00251 items(const T &t1, const T &t2) : CONT()
00252 { push_back(t1); push_back(t2); }
00253 items(const T &t1, const T &t2, const T &t3) : CONT()
00254 { push_back(t1); push_back(t2); push_back(t3); }
00255 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()
00256 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00257 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()
00258 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00260 items(const CONT &c) : CONT(c) {}
00261
00263 items &operator()(const T &t)
00264 {
00265 push_back(t);
00266 return *this;
00267 }
00268 };
00269
00270
00271
00273 template<typename ITER> inline
00274 PGSTD::string separated_list(const PGSTD::string &sep,
00275 ITER begin,
00276 ITER end)
00277 {
00278 PGSTD::string result;
00279 if (begin != end)
00280 {
00281 result = to_string(*begin);
00282 for (++begin; begin != end; ++begin)
00283 {
00284 result += sep;
00285 result += to_string(*begin);
00286 }
00287 }
00288 return result;
00289 }
00290
00292 template<typename CONTAINER> inline
00293 PGSTD::string separated_list(const PGSTD::string &sep,
00294 const CONTAINER &c)
00295 {
00296 return separated_list(sep, c.begin(), c.end());
00297 }
00298
00299
00301
00310 namespace internal
00311 {
00312 typedef unsigned long result_size_type;
00313 typedef long result_difference_type;
00314
00316
00324 template<typename T> inline const char *FmtString(T t)
00325 {
00326 error_unsupported_type_in_string_conversion(t);
00327 return 0;
00328 }
00329
00330 template<> inline const char *FmtString(short) { return "%hd"; }
00331 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00332 template<> inline const char *FmtString(int) { return "%i"; }
00333 template<> inline const char *FmtString(long) { return "%li"; }
00334 template<> inline const char *FmtString(unsigned) { return "%u"; }
00335 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00336 template<> inline const char *FmtString(float) { return "%f"; }
00337 template<> inline const char *FmtString(double) { return "%lf"; }
00338 template<> inline const char *FmtString(char) { return "%c"; }
00339 template<> inline const char *FmtString(unsigned char) { return "%c"; }
00340 #if defined(PQXX_HAVE_LONG_DOUBLE)
00341 template<> inline const char *FmtString(long double) { return "%Lf"; }
00342 #endif
00343
00344 }
00345
00347
00355 template<typename T> inline PGSTD::string ToString(const T &Obj)
00356 {
00357
00358 char Buf[500];
00359 sprintf(Buf, internal::FmtString(Obj), Obj);
00360 return PGSTD::string(Buf);
00361 }
00362
00363
00364 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00365 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00366 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00367
00368 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00369 {
00370 return reinterpret_cast<const char *>(Obj);
00371 }
00372
00373 template<> inline PGSTD::string ToString(const bool &Obj)
00374 {
00375 return ToString(unsigned(Obj));
00376 }
00377
00378 template<> inline PGSTD::string ToString(const short &Obj)
00379 {
00380 return ToString(int(Obj));
00381 }
00382
00383 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00384 {
00385 return ToString(unsigned(Obj));
00386 }
00387
00388
00390
00398 template<typename T> inline void FromString(const char Str[], T &Obj)
00399 {
00400 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00401 PGSTD::string(typeid(T).name()));
00402
00403 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00404 throw PGSTD::runtime_error("Cannot convert value '" +
00405 PGSTD::string(Str) +
00406 "' to " + typeid(T).name());
00407 }
00408
00409
00410 namespace internal
00411 {
00413
00415 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00416
00418
00420 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00421 const unsigned char *&Obj);
00422
00424 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00425 bool EmptyIsNull);
00426
00428 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00429 }
00430
00431
00432 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00433 {
00434 internal::FromString_string(Str, Obj);
00435 }
00436
00437 template<> inline void FromString(const char Str[], const char *&Obj)
00438 {
00439 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00440 Obj = Str;
00441 }
00442
00443 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00444 {
00445 internal::FromString_ucharptr(Str, Obj);
00446 }
00447
00448 template<> inline void FromString(const char Str[], bool &Obj)
00449 {
00450 from_string(Str, Obj);
00451 }
00452
00453
00455
00464 PGSTD::string sqlesc(const char str[]);
00465
00467
00477 PGSTD::string sqlesc(const char str[], size_t maxlen);
00478
00480
00486 PGSTD::string sqlesc(const PGSTD::string &);
00487
00488
00490
00494 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00495
00496
00498
00500 template<>
00501 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00502 {
00503 return internal::Quote_string(Obj, EmptyIsNull);
00504 }
00505
00507
00509 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00510 {
00511 return internal::Quote_charptr(Obj, EmptyIsNull);
00512 }
00513
00514
00516
00521 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00522 bool EmptyIsNull)
00523 {
00524 return internal::Quote_charptr(Obj, EmptyIsNull);
00525 }
00526
00527
00528 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00529 {
00530 return Quote(ToString(Obj), EmptyIsNull);
00531 }
00532
00533
00535
00538 template<typename T> inline PGSTD::string Quote(T Obj)
00539 {
00540 return Quote(Obj, false);
00541 }
00542
00543
00544 namespace internal
00545 {
00546 void freepqmem(void *);
00547 void freenotif(PQXXPQ::PGnotify *);
00548
00550
00556 template<typename T> class PQAlloc
00557 {
00558 T *m_Obj;
00559 mutable const PQAlloc *m_l, *m_r;
00560 public:
00561 typedef T content_type;
00562
00563 PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00564 PQAlloc(const PQAlloc &rhs) throw () :
00565 m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00566 ~PQAlloc() throw () { loseref(); }
00567
00568 PQAlloc &operator=(const PQAlloc &rhs) throw ()
00569 { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00570
00572
00574 explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00575
00576 void swap(PQAlloc &rhs) throw ()
00577 {
00578 PQAlloc tmp(*this);
00579 *this = rhs;
00580 rhs = tmp;
00581 }
00582
00583 PQAlloc &operator=(T *obj) throw () { loseref(); makeref(obj); return *this; }
00584
00586 operator bool() const throw () { return m_Obj != 0; }
00587
00589 bool operator!() const throw () { return !m_Obj; }
00590
00592
00594 T *operator->() const throw (PGSTD::logic_error)
00595 {
00596 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00597 return m_Obj;
00598 }
00599
00601
00603 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00604
00606
00608 T *c_ptr() const throw () { return m_Obj; }
00609
00610 void clear() throw () { loseref(); }
00611
00612 private:
00613 void makeref(T *p) throw () { m_Obj = p; }
00614
00615 void makeref(const PQAlloc &rhs) throw ()
00616 {
00617 m_l = &rhs;
00618 m_r = rhs.m_r;
00619 m_l->m_r = m_r->m_l = this;
00620 m_Obj = rhs.m_Obj;
00621 }
00622
00624 void loseref() throw ()
00625 {
00626 if (m_l == this && m_Obj) freemem();
00627 m_Obj = 0;
00628 m_l->m_r = m_r;
00629 m_r->m_l = m_l;
00630 m_l = m_r = this;
00631 }
00632
00633 void freemem() throw () { freepqmem(m_Obj); }
00634 };
00635
00636
00638 template<> inline void PQAlloc<PQXXPQ::PGresult>::freemem() throw ()
00639 { PQclear(m_Obj); }
00641 template<> inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw ()
00642 { freenotif(m_Obj); }
00643
00644
00645 class PQXX_LIBEXPORT namedclass
00646 {
00647 public:
00648 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00649 m_Name(Name),
00650 m_Classname(Classname)
00651 {
00652 }
00653
00654 const PGSTD::string &name() const throw () { return m_Name; }
00655 const PGSTD::string &classname() const throw () {return m_Classname;}
00656 PGSTD::string description() const;
00657
00658 private:
00659 PGSTD::string m_Name, m_Classname;
00660 };
00661
00662
00663 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00664 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00665
00666
00668
00671 template<typename GUEST>
00672 class unique
00673 {
00674 public:
00675 unique() : m_Guest(0) {}
00676
00677 GUEST *get() const throw () { return m_Guest; }
00678
00679 void Register(GUEST *G)
00680 {
00681 CheckUniqueRegistration(G, m_Guest);
00682 m_Guest = G;
00683 }
00684
00685 void Unregister(GUEST *G)
00686 {
00687 CheckUniqueUnregistration(G, m_Guest);
00688 m_Guest = 0;
00689 }
00690
00691 private:
00692 GUEST *m_Guest;
00693
00695 unique(const unique &);
00697 unique &operator=(const unique &);
00698 };
00699
00701 void sleep_seconds(int);
00702
00703 }
00704 }
00705