util.hxx
/*-------------------------------------------------------------------------
*
* FILE
* pqxx/util.hxx
*
* DESCRIPTION
* Various utility definitions for libpqxx
* DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead.
*
* Copyright (c) 2001-2012, Jeroen T. Vermeulen <jtv@xs4all.nl>
*
* See COPYING for copyright license. If you did not receive a file called
* COPYING with this source code, please notify the distributor of this mistake,
* or contact the author.
*
*-------------------------------------------------------------------------
*/
#ifndef PQXX_H_UTIL
#define PQXX_H_UTIL
#include "pqxx/compiler-public.hxx"
#include <cstdio>
#include <cctype>
#include <stdexcept>
#include <string>
#include <typeinfo>
#include <vector>
#ifdef PQXX_TR1_HEADERS
#include <tr1/memory>
#else
#include <memory>
#endif
#include "pqxx/strconv"
namespace pqxx {}
namespace PGSTD {}
#include <pqxx/internal/libpq-forward.hxx>
namespace pqxx
{
struct PQXX_LIBEXPORT thread_safety_model
{
bool have_safe_strerror;
bool safe_libpq;
bool safe_query_cancel;
bool safe_result_copy;
bool safe_kerberos;
PGSTD::string description;
};
thread_safety_model PQXX_LIBEXPORT describe_thread_safety() throw ();
const oid oid_none = 0;
template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
class items : public CONT
{
public:
items() : CONT() {} //[t0]
explicit items(const T &t) : CONT() { this->push_back(t); } //[t0]
items(const T &t1, const T &t2) : CONT() //[t0]
{ this->push_back(t1); this->push_back(t2); }
items(const T &t1, const T &t2, const T &t3) : CONT() //[t0]
{ this->push_back(t1); this->push_back(t2); this->push_back(t3); }
items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT() //[t0]
{
this->push_back(t1);
this->push_back(t2);
this->push_back(t3);
this->push_back(t4);
}
items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT() //[t0]
{
this->push_back(t1);
this->push_back(t2);
this->push_back(t3);
this->push_back(t4);
this->push_back(t5);
}
items(const CONT &c) : CONT(c) {} //[t0]
items &operator()(const T &t) //[t0]
{
this->push_back(t);
return *this;
}
};
namespace internal
{
// TODO: Does standard library provide a ready-made version of this?
template<typename ITER> struct dereference
{
typename ITER::value_type operator()(ITER i) const { return *i; }
};
template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
} // namespace internal
template<typename ITER, typename ACCESS> inline
PGSTD::string separated_list(const PGSTD::string &sep, //[t0]
ITER begin,
ITER end,
ACCESS access)
{
PGSTD::string result;
if (begin != end)
{
result = to_string(access(begin));
for (++begin; begin != end; ++begin)
{
result += sep;
result += to_string(access(begin));
}
}
return result;
}
template<typename ITER> inline PGSTD::string
separated_list(const PGSTD::string &sep, ITER begin, ITER end) //[t0]
{ return separated_list(sep,begin,end,internal::dereference<ITER>()); }
template<typename OBJ> inline PGSTD::string
separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end) //[t0]
{ return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
template<typename CONTAINER> inline PGSTD::string
separated_list(const PGSTD::string &sep, const CONTAINER &c) //[t10]
{ return separated_list(sep, c.begin(), c.end()); }
namespace internal
{
typedef unsigned long result_size_type;
typedef long result_difference_type;
} // namespace internal
namespace internal
{
void PQXX_LIBEXPORT freepqmem(const void *) throw ();
template<typename P> inline void freepqmem_templated(P *p) throw ()
{
freepqmem(p);
}
void PQXX_LIBEXPORT freemallocmem(const void *) throw ();
template<typename P> inline void freemallocmem_templated(P *p) throw ()
{
freemallocmem(p);
}
#ifdef PQXX_HAVE_SHARED_PTR
template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
class PQAlloc
{
public:
typedef T content_type;
PQAlloc() throw () : m_ptr() {}
PQAlloc(const PQAlloc &rhs) throw () : m_ptr(rhs.m_ptr) {}
explicit PQAlloc(T *t) : m_ptr(t, DELETER) {}
T *get() const throw () { return m_ptr.get(); }
PQAlloc &operator=(const PQAlloc &rhs) throw ()
{
m_ptr = rhs.m_ptr;
return *this;
}
T *operator->() const throw () { return m_ptr.get(); }
T &operator*() const throw () { return *m_ptr; }
void reset() throw () { m_ptr.reset(); }
void swap(PQAlloc &other) throw () { m_ptr.swap(other.m_ptr); }
private:
PQXXTR1::shared_ptr<T> m_ptr;
};
#else // !PQXX_HAVE_SHARED_PTR
class PQXX_LIBEXPORT refcount
{
refcount *volatile m_l, *volatile m_r;
public:
refcount();
~refcount();
void makeref(refcount &) throw ();
bool loseref() throw ();
private:
refcount(const refcount &);
refcount &operator=(const refcount &);
};
template<typename T, void (*DELETER)(T *) = freepqmem_templated<T> >
class PQAlloc
{
T *m_Obj;
mutable refcount m_rc;
public:
typedef T content_type;
PQAlloc() throw () : m_Obj(0), m_rc() {}
PQAlloc(const PQAlloc &rhs) throw () : m_Obj(0), m_rc() { makeref(rhs); }
~PQAlloc() throw () { loseref(); }
PQAlloc &operator=(const PQAlloc &rhs) throw () {redoref(rhs); return *this;}
explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_rc() {}
void swap(PQAlloc &rhs) throw ()
{
PQAlloc tmp(*this);
*this = rhs;
rhs = tmp;
}
//PQAlloc &operator=(T *obj) throw () { redoref(obj); return *this; }
operator bool() const throw () { return m_Obj != 0; }
bool operator!() const throw () { return !m_Obj; }
T *operator->() const throw (PGSTD::logic_error)
{
if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
return m_Obj;
}
T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
T *get() const throw () { return m_Obj; }
void reset() throw () { loseref(); }
private:
void makeref(T *p) throw () { m_Obj = p; }
void makeref(const PQAlloc &rhs) throw ()
{
m_Obj = rhs.m_Obj;
m_rc.makeref(rhs.m_rc);
}
void loseref() throw ()
{
if (m_rc.loseref() && m_Obj) DELETER(m_Obj);
m_Obj = 0;
}
void redoref(const PQAlloc &rhs) throw ()
{ if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
void redoref(T *obj) throw ()
{ if (obj != m_Obj) { loseref(); makeref(obj); } }
};
#endif // PQXX_HAVE_SHARED_PTR
template<typename T> class scoped_array
{
T *m_ptr;
public:
typedef size_t size_type;
typedef long difference_type;
scoped_array() : m_ptr(0) {}
explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
explicit scoped_array(T *t) : m_ptr(t) {}
~scoped_array() { delete [] m_ptr; }
T *get() const throw () { return m_ptr; }
T &operator*() const throw () { return *m_ptr; }
template<typename INDEX> T &operator[](INDEX i) const throw ()
{ return m_ptr[i]; }
scoped_array &operator=(T *t) throw ()
{
if (t != m_ptr)
{
delete [] m_ptr;
m_ptr = t;
}
return *this;
}
private:
scoped_array(const scoped_array &);
scoped_array &operator=(const scoped_array &);
};
class PQXX_LIBEXPORT namedclass
{
public:
namedclass(const PGSTD::string &Classname, const PGSTD::string &Name="") :
m_Classname(Classname),
m_Name(Name)
{
}
const PGSTD::string &name() const throw () { return m_Name; } //[t1]
const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
PGSTD::string description() const;
private:
PGSTD::string m_Classname, m_Name;
};
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
template<typename GUEST>
class unique
{
public:
unique() : m_Guest(0) {}
GUEST *get() const throw () { return m_Guest; }
void Register(GUEST *G)
{
CheckUniqueRegistration(G, m_Guest);
m_Guest = G;
}
void Unregister(GUEST *G)
{
CheckUniqueUnregistration(G, m_Guest);
m_Guest = 0;
}
private:
GUEST *m_Guest;
unique(const unique &);
unique &operator=(const unique &);
};
void PQXX_LIBEXPORT sleep_seconds(int);
typedef const char *cstring;
cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
throw ();
extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
template<typename T> inline PGSTD::ptrdiff_t distance(T first, T last)
{
#ifdef PQXX_HAVE_DISTANCE
return PGSTD::distance(first, last);
#else
// Naive implementation. All we really need for now.
PGSTD::ptrdiff_t d;
for (d=0; first != last; ++d) ++first;
return d;
#endif
}
} // namespace internal
} // namespace pqxx
#endif
pqxx::thread_safety_model
Descriptor of library&#39;s thread-safety model.
Definition: util.hxx:280
pqxx::result
Result set containing data returned by a query or command.
Definition: result.hxx:81
pqxx::internal::scoped_array
Definition: util.hxx:638
pqxx::internal::deref_ptr
Definition: util.hxx:405
pqxx::internal::unique::unique
unique()
Definition: util.hxx:702
pqxx::internal::PQAlloc::~PQAlloc
~PQAlloc()
Definition: util.hxx:568
pqxx::internal::PQAlloc::PQAlloc
PQAlloc()
Definition: util.hxx:566
pqxx::thread_safety_model::safe_query_cancel
bool safe_query_cancel
Is canceling queries thread-safe?
Definition: util.hxx:306
pqxx::internal::CheckUniqueUnregistration
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old)
Definition: util.cxx:177
pqxx::internal::PQAlloc::swap
void swap(PQAlloc &rhs)
Definition: util.hxx:577
pqxx::internal::scoped_array::operator*
T & operator*() const
Definition: util.hxx:651
pqxx::internal::scoped_array::scoped_array
scoped_array(T *t)
Definition: util.hxx:647
pqxx::internal::result_difference_type
long result_difference_type
Definition: util.hxx:471
pqxx::internal::unique
Ensure proper opening/closing of GUEST objects related to a "host" object.
Definition: util.hxx:699
pqxx::internal::freemallocmem_templated
void freemallocmem_templated(P *p)
Definition: util.hxx:484
pqxx::internal::sleep_seconds
void sleep_seconds(int)
Sleep for the given number of seconds.
Definition: util.cxx:205
pqxx::internal::distance
std::ptrdiff_t distance(T first, T last)
Wrapper for std::distance; not all platforms have std::distance().
Definition: util.hxx:755
pqxx::internal::PQAlloc::PQAlloc
PQAlloc(const PQAlloc &rhs)
Definition: util.hxx:567
pqxx::internal::scoped_array::scoped_array
scoped_array()
Definition: util.hxx:645
pqxx::internal::namedclass::classname
const std::string & classname() const
Definition: util.hxx:682
pqxx::internal::PQAlloc::get
T * get() const
Obtain underlying pointer.
Definition: util.hxx:609
pqxx::internal::refcount::makeref
void makeref(refcount &)
Create additional reference based on existing refcount object.
Definition: util.cxx:124
pqxx::thread_safety_model::safe_kerberos
bool safe_kerberos
Is Kerberos thread-safe?
Definition: util.hxx:323
pqxx::internal::dereference::operator()
ITER::value_type operator()(ITER i) const
Definition: util.hxx:403
pqxx::internal::scoped_array::difference_type
long difference_type
Definition: util.hxx:643
pqxx::internal::sql_rollback_work
const char sql_rollback_work[]
Definition: util.cxx:54
pqxx::internal::scoped_array::size_type
size_t size_type
Definition: util.hxx:642
pqxx::items::items
items(const T &t1, const T &t2, const T &t3)
Definition: util.hxx:368
pqxx::items::items
items(const T &t1, const T &t2, const T &t3, const T &t4, const T &t5)
Definition: util.hxx:377
pqxx::internal::sql_commit_work
const char sql_commit_work[]
Definition: util.cxx:53
pqxx::items
Container of items with easy contents initialization and string rendering.
Definition: util.hxx:359
pqxx::internal::PQAlloc::operator=
PQAlloc & operator=(const PQAlloc &rhs)
Definition: util.hxx:570
pqxx::internal::freepqmem_templated
void freepqmem_templated(P *p)
Definition: util.hxx:478
pqxx::separated_list
std::string separated_list(const std::string &sep, ITER begin, ITER end, ACCESS access)
Access iterators using ACCESS functor, returning separator-separated list.
Definition: util.hxx:417
pqxx::items::items
items(const T &t1, const T &t2, const T &t3, const T &t4)
Definition: util.hxx:370
pqxx::items::items
items(const T &t)
Create items list with one element.
Definition: util.hxx:365
pqxx::thread_safety_model::safe_libpq
bool safe_libpq
Is the underlying libpq build thread-safe?
Definition: util.hxx:300
pqxx::internal::result_size_type
unsigned long result_size_type
Definition: util.hxx:470
pqxx::thread_safety_model::have_safe_strerror
bool have_safe_strerror
Does standard C library have a thread-safe alternative to strerror?
Definition: util.hxx:290
pqxx::internal::CheckUniqueRegistration
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old)
Definition: util.cxx:162
pqxx::items::items
items(const T &t1, const T &t2)
Definition: util.hxx:366
pqxx::internal::PQAlloc::operator->
T * operator->() const
Dereference pointer.
Definition: util.hxx:595
pqxx::items::items
items()
Create empty items list.
Definition: util.hxx:363
pqxx::internal::namedclass::name
const std::string & name() const
Definition: util.hxx:681
pqxx::items::operator()
items & operator()(const T &t)
Add element to items list.
Definition: util.hxx:389
pqxx::internal::PQAlloc
Reference-counted smart pointer to libpq-allocated object.
Definition: util.hxx:559
pqxx::internal::freemallocmem
void freemallocmem(const void *)
Definition: util.cxx:199
pqxx::internal::dereference
Functor: dereference iterator.
Definition: util.hxx:401
pqxx::internal::strerror_wrapper
cstring strerror_wrapper(int err, char buf[], std::size_t len)
Human-readable description for error code, possibly using given buffer.
Definition: util.cxx:253
pqxx::to_string
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.hxx:467
pqxx::internal::PQAlloc::operator*
T & operator*() const
Dereference pointer.
Definition: util.hxx:604
pqxx::internal::PQAlloc::PQAlloc
PQAlloc(T *obj)
Assume ownership of a pointer.
Definition: util.hxx:575
pqxx::internal::namedclass
Definition: util.hxx:672
pqxx::internal::PQAlloc::reset
void reset()
Definition: util.hxx:611
pqxx::internal::PQAlloc::operator!
bool operator!() const
Is this pointer null?
Definition: util.hxx:590
pqxx::internal::freepqmem
void freepqmem(const void *)
Definition: util.cxx:193
pqxx::internal::PQAlloc::content_type
T content_type
Definition: util.hxx:564
pqxx::thread_safety_model::description
std::string description
A human-readable description of any thread-safety issues.
Definition: util.hxx:326
pqxx::items::items
items(const CONT &c)
Copy container.
Definition: util.hxx:386
pqxx::describe_thread_safety
thread_safety_model describe_thread_safety()
Describe thread safety available in this build.
Definition: util.cxx:57
pqxx::internal::sql_begin_work
const char sql_begin_work[]
Commonly used SQL commands.
Definition: util.cxx:52
pqxx::internal::cstring
const char * cstring
Work around problem with library export directives and pointers.
Definition: util.hxx:734
pqxx::internal::unique::Unregister
void Unregister(GUEST *G)
Definition: util.hxx:712
pqxx::internal::scoped_array::scoped_array
scoped_array(size_type n)
Definition: util.hxx:646
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: basic_connection.hxx:35
pqxx::internal::refcount
Definition: util.hxx:522
pqxx::internal::unique::Register
void Register(GUEST *G)
Definition: util.hxx:706
pqxx::internal::scoped_array::operator=
scoped_array & operator=(T *t)
Definition: util.hxx:655
pqxx::internal::namedclass::namedclass
namedclass(const std::string &Classname, const std::string &Name="")
Definition: util.hxx:675
pqxx::internal::scoped_array::operator[]
T & operator[](INDEX i) const
Definition: util.hxx:652
pqxx::thread_safety_model::safe_result_copy
bool safe_result_copy
Are copies of pqxx::result and pqxx::binarystring objects thread-safe?
Definition: util.hxx:314
pqxx::internal::deref_ptr::operator()
T operator()(T *i) const
Definition: util.hxx:405
pqxx::oid_none
const oid oid_none
The "null" oid.
Definition: util.hxx:333
pqxx::internal::refcount::loseref
bool loseref()
Drop this reference; return whether we were the last reference.
Definition: util.cxx:133
pqxx::internal::scoped_array::~scoped_array
~scoped_array()
Definition: util.hxx:648