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
00143 template<typename T> void from_string(const char Str[], T &Obj);
00144
00145 template<> void from_string(const char Str[], long &);
00146 template<> void from_string(const char Str[], unsigned long &);
00147 template<> void from_string(const char Str[], int &);
00148 template<> void from_string(const char Str[], unsigned int &);
00149 template<> void from_string(const char Str[], short &);
00150 template<> void from_string(const char Str[], unsigned short &);
00151 template<> void from_string(const char Str[], float &);
00152 template<> void from_string(const char Str[], double &);
00153 template<> void from_string(const char Str[], bool &);
00154 #if defined(PQXX_HAVE_LONG_DOUBLE)
00155 template<> void from_string(const char Str[], long double &);
00156 #endif
00157
00158
00159 template<> inline void from_string(const char Str[],PGSTD::string &Obj)
00160 { Obj = Str; }
00161
00162 template<>
00163 inline void from_string(const char Str[], PGSTD::stringstream &Obj)
00164 { Obj.clear(); Obj << Str; }
00165
00166 template<typename T>
00167 inline void from_string(const PGSTD::string &Str, T &Obj)
00168 { from_string(Str.c_str(), Obj); }
00169
00170 template<typename T>
00171 inline void from_string(const PGSTD::stringstream &Str, T &Obj)
00172 { from_string(Str.str(), Obj); }
00173
00174 template<> inline void
00175 from_string(const PGSTD::string &Str, PGSTD::string &Obj)
00176 { Obj = Str; }
00177
00178 template<> inline void
00179 from_string(const PGSTD::string &, const char &Obj)
00180 { error_ambiguous_string_conversion(Obj); }
00181 template<> inline void
00182 from_string(const PGSTD::string &, const signed char &Obj)
00183 { error_ambiguous_string_conversion(Obj); }
00184 template<> inline void
00185 from_string(const PGSTD::string &, const unsigned char &Obj)
00186 { error_ambiguous_string_conversion(Obj); }
00187
00188
00190
00194 template<typename T> PGSTD::string to_string(const T &);
00195
00196 template<> PGSTD::string to_string(const short &);
00197 template<> PGSTD::string to_string(const unsigned short &);
00198 template<> PGSTD::string to_string(const int &);
00199 template<> PGSTD::string to_string(const unsigned int &);
00200 template<> PGSTD::string to_string(const long &);
00201 template<> PGSTD::string to_string(const unsigned long &);
00202 template<> PGSTD::string to_string(const float &);
00203 template<> PGSTD::string to_string(const double &);
00204 template<> PGSTD::string to_string(const bool &);
00205 #if defined(PQXX_HAVE_LONG_DOUBLE)
00206 template<> PGSTD::string to_string(const long double &);
00207 #endif
00208
00209 inline PGSTD::string to_string(const char Obj[])
00210 { return PGSTD::string(Obj); }
00211
00212 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)
00213 { return Obj.str(); }
00214
00215 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}
00216
00217 template<> PGSTD::string to_string(const char &);
00218
00219
00220 template<> inline PGSTD::string to_string(const signed char &Obj)
00221 { return error_ambiguous_string_conversion(Obj); }
00222 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00223 { return error_ambiguous_string_conversion(Obj); }
00224
00225
00227
00244 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00245 class items : public CONT
00246 {
00247 public:
00249 items() : CONT() {}
00251 explicit items(const T &t) : CONT() { push_back(t); }
00252 items(const T &t1, const T &t2) : CONT()
00253 { push_back(t1); push_back(t2); }
00254 items(const T &t1, const T &t2, const T &t3) : CONT()
00255 { push_back(t1); push_back(t2); push_back(t3); }
00256 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()
00257 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00258 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()
00259 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00261 items(const CONT &c) : CONT(c) {}
00262
00264 items &operator()(const T &t)
00265 {
00266 push_back(t);
00267 return *this;
00268 }
00269 };
00270
00271
00272
00274 template<typename ITER> inline
00275 PGSTD::string separated_list(const PGSTD::string &sep,
00276 ITER begin,
00277 ITER end)
00278 {
00279 PGSTD::string result;
00280 if (begin != end)
00281 {
00282 result = to_string(*begin);
00283 for (++begin; begin != end; ++begin)
00284 {
00285 result += sep;
00286 result += to_string(*begin);
00287 }
00288 }
00289 return result;
00290 }
00291
00293 template<typename CONTAINER> inline
00294 PGSTD::string separated_list(const PGSTD::string &sep,
00295 const CONTAINER &c)
00296 {
00297 return separated_list(sep, c.begin(), c.end());
00298 }
00299
00300
00302
00311 namespace internal
00312 {
00313 typedef unsigned long result_size_type;
00314 typedef long result_difference_type;
00315
00317
00325 template<typename T> inline const char *FmtString(T t)
00326 {
00327 error_unsupported_type_in_string_conversion(t);
00328 return 0;
00329 }
00330
00331 template<> inline const char *FmtString(short) { return "%hd"; }
00332 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00333 template<> inline const char *FmtString(int) { return "%i"; }
00334 template<> inline const char *FmtString(long) { return "%li"; }
00335 template<> inline const char *FmtString(unsigned) { return "%u"; }
00336 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00337 template<> inline const char *FmtString(float) { return "%f"; }
00338 template<> inline const char *FmtString(double) { return "%lf"; }
00339 template<> inline const char *FmtString(char) { return "%c"; }
00340 template<> inline const char *FmtString(unsigned char) { return "%c"; }
00341 #if defined(PQXX_HAVE_LONG_DOUBLE)
00342 template<> inline const char *FmtString(long double) { return "%Lf"; }
00343 #endif
00344
00345 }
00346
00348
00356 template<typename T> inline PGSTD::string ToString(const T &Obj)
00357 {
00358
00359 char Buf[500];
00360 sprintf(Buf, internal::FmtString(Obj), Obj);
00361 return PGSTD::string(Buf);
00362 }
00363
00364
00365 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00366 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00367 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00368
00369 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00370 {
00371 return reinterpret_cast<const char *>(Obj);
00372 }
00373
00374 template<> inline PGSTD::string ToString(const bool &Obj)
00375 {
00376 return ToString(unsigned(Obj));
00377 }
00378
00379 template<> inline PGSTD::string ToString(const short &Obj)
00380 {
00381 return ToString(int(Obj));
00382 }
00383
00384 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00385 {
00386 return ToString(unsigned(Obj));
00387 }
00388
00389
00391
00399 template<typename T> inline void FromString(const char Str[], T &Obj)
00400 {
00401 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00402 PGSTD::string(typeid(T).name()));
00403
00404 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00405 throw PGSTD::runtime_error("Cannot convert value '" +
00406 PGSTD::string(Str) +
00407 "' to " + typeid(T).name());
00408 }
00409
00410
00411 namespace internal
00412 {
00414
00416 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00417
00419
00421 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00422 const unsigned char *&Obj);
00423
00425 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00426 bool EmptyIsNull);
00427
00429 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00430 }
00431
00432
00433 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00434 {
00435 internal::FromString_string(Str, Obj);
00436 }
00437
00438 template<> inline void FromString(const char Str[], const char *&Obj)
00439 {
00440 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00441 Obj = Str;
00442 }
00443
00444 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00445 {
00446 internal::FromString_ucharptr(Str, Obj);
00447 }
00448
00449 template<> inline void FromString(const char Str[], bool &Obj)
00450 {
00451 from_string(Str, Obj);
00452 }
00453
00454
00456
00465 PGSTD::string sqlesc(const char str[]);
00466
00468
00478 PGSTD::string sqlesc(const char str[], size_t maxlen);
00479
00481
00487 PGSTD::string sqlesc(const PGSTD::string &);
00488
00489
00491
00495 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00496
00497
00499
00501 template<>
00502 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00503 {
00504 return internal::Quote_string(Obj, EmptyIsNull);
00505 }
00506
00508
00510 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00511 {
00512 return internal::Quote_charptr(Obj, EmptyIsNull);
00513 }
00514
00515
00517
00522 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00523 bool EmptyIsNull)
00524 {
00525 return internal::Quote_charptr(Obj, EmptyIsNull);
00526 }
00527
00528
00529 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00530 {
00531 return Quote(ToString(Obj), EmptyIsNull);
00532 }
00533
00534
00536
00539 template<typename T> inline PGSTD::string Quote(T Obj)
00540 {
00541 return Quote(Obj, false);
00542 }
00543
00544
00545 namespace internal
00546 {
00547 void freepqmem(void *);
00548 void freenotif(PQXXPQ::PGnotify *);
00549
00551
00557 template<typename T> class PQAlloc
00558 {
00559 T *m_Obj;
00560 mutable const PQAlloc *m_l, *m_r;
00561 public:
00562 typedef T content_type;
00563
00564 PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00565 PQAlloc(const PQAlloc &rhs) throw () :
00566 m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00567 ~PQAlloc() throw () { loseref(); }
00568
00569 PQAlloc &operator=(const PQAlloc &rhs) throw ()
00570 { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00571
00573
00575 explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00576
00577 void swap(PQAlloc &rhs) throw ()
00578 {
00579 PQAlloc tmp(*this);
00580 *this = rhs;
00581 rhs = tmp;
00582 }
00583
00584 PQAlloc &operator=(T *obj) throw () { loseref(); makeref(obj); return *this; }
00585
00587 operator bool() const throw () { return m_Obj != 0; }
00588
00590 bool operator!() const throw () { return !m_Obj; }
00591
00593
00595 T *operator->() const throw (PGSTD::logic_error)
00596 {
00597 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00598 return m_Obj;
00599 }
00600
00602
00604 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00605
00607
00609 T *c_ptr() const throw () { return m_Obj; }
00610
00611 void clear() throw () { loseref(); }
00612
00613 private:
00614 void makeref(T *p) throw () { m_Obj = p; }
00615
00616 void makeref(const PQAlloc &rhs) throw ()
00617 {
00618 m_l = &rhs;
00619 m_r = rhs.m_r;
00620 m_l->m_r = m_r->m_l = this;
00621 m_Obj = rhs.m_Obj;
00622 }
00623
00625 void loseref() throw ()
00626 {
00627 if (m_l == this && m_Obj) freemem();
00628 m_Obj = 0;
00629 m_l->m_r = m_r;
00630 m_r->m_l = m_l;
00631 m_l = m_r = this;
00632 }
00633
00634 void freemem() throw () { freepqmem(m_Obj); }
00635 };
00636
00637
00639 template<> inline void PQAlloc<PQXXPQ::PGresult>::freemem() throw ()
00640 { PQclear(m_Obj); }
00642 template<> inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw ()
00643 { freenotif(m_Obj); }
00644
00645
00646 class PQXX_LIBEXPORT namedclass
00647 {
00648 public:
00649 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00650 m_Name(Name),
00651 m_Classname(Classname)
00652 {
00653 }
00654
00655 const PGSTD::string &name() const throw () { return m_Name; }
00656 const PGSTD::string &classname() const throw () {return m_Classname;}
00657 PGSTD::string description() const;
00658
00659 private:
00660 PGSTD::string m_Name, m_Classname;
00661 };
00662
00663
00664 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00665 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00666
00667
00669
00672 template<typename GUEST>
00673 class unique
00674 {
00675 public:
00676 unique() : m_Guest(0) {}
00677
00678 GUEST *get() const throw () { return m_Guest; }
00679
00680 void Register(GUEST *G)
00681 {
00682 CheckUniqueRegistration(G, m_Guest);
00683 m_Guest = G;
00684 }
00685
00686 void Unregister(GUEST *G)
00687 {
00688 CheckUniqueUnregistration(G, m_Guest);
00689 m_Guest = 0;
00690 }
00691
00692 private:
00693 GUEST *m_Guest;
00694
00696 unique(const unique &);
00698 unique &operator=(const unique &);
00699 };
00700
00702 void PQXX_LIBEXPORT sleep_seconds(int);
00703
00704 }
00705 }
00706