00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef PQXX_H_UTIL
00019 #define PQXX_H_UTIL
00020
00021 #include "pqxx/compiler-public.hxx"
00022
00023 #include <cstdio>
00024 #include <cctype>
00025 #include <stdexcept>
00026 #include <string>
00027 #include <typeinfo>
00028 #include <vector>
00029
00030 #ifdef PQXX_TR1_HEADERS
00031 #include <tr1/memory>
00032 #else
00033 #include <memory>
00034 #endif
00035
00036
00259
00260 namespace pqxx {}
00261
00263
00268 namespace PGSTD {}
00269
00270 #include <pqxx/libpq-forward.hxx>
00271
00272
00273 namespace pqxx
00274 {
00276
00278 struct PQXX_LIBEXPORT thread_safety_model
00279 {
00281
00288 bool have_strerror_r;
00289
00291
00298 bool safe_libpq;
00299
00301
00304 bool safe_query_cancel;
00305
00307
00312 bool safe_result_copy;
00313
00315
00321 bool safe_kerberos;
00322
00324 PGSTD::string description;
00325 };
00326
00328 thread_safety_model describe_thread_safety() throw ();
00329
00331 const oid oid_none = 0;
00332
00334
00356 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00357 class items : public CONT
00358 {
00359 public:
00361 items() : CONT() {}
00363 explicit items(const T &t) : CONT() { push_back(t); }
00364 items(const T &t1, const T &t2) : CONT()
00365 { push_back(t1); push_back(t2); }
00366 items(const T &t1, const T &t2, const T &t3) : CONT()
00367 { push_back(t1); push_back(t2); push_back(t3); }
00368 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()
00369 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00370 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()
00371 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00373 items(const CONT &c) : CONT(c) {}
00374
00376 items &operator()(const T &t)
00377 {
00378 push_back(t);
00379 return *this;
00380 }
00381 };
00382
00383
00384 namespace internal
00385 {
00386
00388 template<typename ITER> struct dereference
00389 {
00390 typename ITER::value_type operator()(ITER i) const { return *i; }
00391 };
00392 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00393 }
00394
00395
00397
00403 template<typename ITER, typename ACCESS> inline
00404 PGSTD::string separated_list(const PGSTD::string &sep,
00405 ITER begin,
00406 ITER end,
00407 ACCESS access)
00408 {
00409 PGSTD::string result;
00410 if (begin != end)
00411 {
00412 result = to_string(access(begin));
00413 for (++begin; begin != end; ++begin)
00414 {
00415 result += sep;
00416 result += to_string(access(begin));
00417 }
00418 }
00419 return result;
00420 }
00421
00426
00428 template<typename ITER> inline PGSTD::string
00429 separated_list(const PGSTD::string &sep, ITER begin, ITER end)
00430 { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00431
00432
00434 template<typename OBJ> inline PGSTD::string
00435 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)
00436 { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00437
00438
00440 template<typename CONTAINER> inline PGSTD::string
00441 separated_list(const PGSTD::string &sep, const CONTAINER &c)
00442 { return separated_list(sep, c.begin(), c.end()); }
00444
00446
00455 namespace internal
00456 {
00457 typedef unsigned long result_size_type;
00458 typedef long result_difference_type;
00459 }
00460
00461
00462 namespace internal
00463 {
00464 void PQXX_LIBEXPORT freepqmem(const void *);
00465 template<typename P> inline void freepqmem_templated(P *p)
00466 {
00467 freepqmem(p);
00468 }
00469
00470
00471 #ifdef PQXX_HAVE_SHARED_PTR
00472
00474 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
00475 class PQAlloc : protected PQXXTR1::shared_ptr<T>
00476 {
00477 typedef PQXXTR1::shared_ptr<T> super;
00478 public:
00479 typedef T content_type;
00480 PQAlloc() : super() {}
00481 explicit PQAlloc(T *t) : super(t, DELETER) {}
00482
00483 using super::get;
00484 using super::operator=;
00485 using super::operator->;
00486 using super::operator*;
00487 using super::reset;
00488 using super::swap;
00489 };
00490
00491 #else // !PQXX_HAVE_SHARED_PTR
00492
00495 class PQXX_LIBEXPORT refcount
00496 {
00497 refcount *volatile m_l, *volatile m_r;
00498
00499 public:
00500 refcount();
00501 ~refcount();
00502
00504 void makeref(refcount &) throw ();
00505
00507 bool loseref() throw ();
00508
00509 private:
00511 refcount(const refcount &);
00513 refcount &operator=(const refcount &);
00514 };
00515
00516
00518
00532 template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
00533 class PQAlloc
00534 {
00535 T *m_Obj;
00536 mutable refcount m_rc;
00537 public:
00538 typedef T content_type;
00539
00540 PQAlloc() throw () : m_Obj(0), m_rc() {}
00541 PQAlloc(const PQAlloc &rhs) throw () : m_Obj(0), m_rc() { makeref(rhs); }
00542 ~PQAlloc() throw () { loseref(); }
00543
00544 PQAlloc &operator=(const PQAlloc &rhs) throw () {redoref(rhs); return *this;}
00545
00547
00549 explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_rc() {}
00550
00551 void swap(PQAlloc &rhs) throw ()
00552 {
00553 PQAlloc tmp(*this);
00554 *this = rhs;
00555 rhs = tmp;
00556 }
00557
00558
00559
00561 operator bool() const throw () { return m_Obj != 0; }
00562
00564 bool operator!() const throw () { return !m_Obj; }
00565
00567
00569 T *operator->() const throw (PGSTD::logic_error)
00570 {
00571 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00572 return m_Obj;
00573 }
00574
00576
00578 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00579
00581
00583 T *get() const throw () { return m_Obj; }
00584
00585 void reset() throw () { loseref(); }
00586
00587 private:
00588 void makeref(T *p) throw () { m_Obj = p; }
00589
00590 void makeref(const PQAlloc &rhs) throw ()
00591 {
00592 m_Obj = rhs.m_Obj;
00593 m_rc.makeref(rhs.m_rc);
00594 }
00595
00597 void loseref() throw ()
00598 {
00599 if (m_rc.loseref() && m_Obj) DELETER(m_Obj);
00600 m_Obj = 0;
00601 }
00602
00603 void redoref(const PQAlloc &rhs) throw ()
00604 { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
00605 void redoref(T *obj) throw ()
00606 { if (obj != m_Obj) { loseref(); makeref(obj); } }
00607 };
00608
00609 #endif // PQXX_HAVE_SHARED_PTR
00610
00611
00612 template<typename T> class scoped_array
00613 {
00614 T *m_ptr;
00615 public:
00616 typedef size_t size_type;
00617 typedef long difference_type;
00618
00619 scoped_array() : m_ptr(0) {}
00620 explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
00621 explicit scoped_array(T *t) : m_ptr(t) {}
00622 ~scoped_array() { delete [] m_ptr; }
00623
00624 T *get() const throw () { return m_ptr; }
00625 T &operator*() const throw () { return *m_ptr; }
00626 template<typename INDEX> T &operator[](INDEX i) const throw ()
00627 { return m_ptr[i]; }
00628
00629 scoped_array &operator=(T *t) throw ()
00630 {
00631 if (t != m_ptr)
00632 {
00633 delete [] m_ptr;
00634 m_ptr = t;
00635 }
00636 return *this;
00637 }
00638
00639 private:
00641 scoped_array(const scoped_array &);
00642 scoped_array &operator=(const scoped_array &);
00643 };
00644
00645
00646 class PQXX_LIBEXPORT namedclass
00647 {
00648 public:
00649 namedclass(const PGSTD::string &Classname, const PGSTD::string &Name="") :
00650 m_Classname(Classname),
00651 m_Name(Name)
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_Classname, m_Name;
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
00705 void PQXX_LIBEXPORT sleep_seconds(int);
00706
00708 typedef const char *cstring;
00709
00711
00720 cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
00721 throw ();
00722
00723
00725 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
00726
00727 }
00728 }
00729
00730 #endif
00731