util.hxx

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/util.hxx
00005  *
00006  *   DESCRIPTION
00007  *      Various utility definitions for libpqxx
00008  *      DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/util instead.
00009  *
00010  * Copyright (c) 2001-2006, Jeroen T. Vermeulen <jtv@xs4all.nl>
00011  *
00012  * See COPYING for copyright license.  If you did not receive a file called
00013  * COPYING with this source code, please notify the distributor of this mistake,
00014  * or contact the author.
00015  *
00016  *-------------------------------------------------------------------------
00017  */
00018 #include "pqxx/compiler-public.hxx"
00019 
00020 #include <cstdio>
00021 #include <cctype>
00022 #include <sstream>
00023 #include <stdexcept>
00024 #include <string>
00025 #include <typeinfo>
00026 #include <vector>
00027 
00065 
00066 namespace pqxx {}
00067 
00069 
00074 namespace PGSTD {}
00075 
00076 #include <pqxx/libpq-forward.hxx>
00077 
00078 
00079 namespace pqxx
00080 {
00082 const oid oid_none = 0;
00083 
00106 
00108 
00121 template<typename T> void error_unsupported_type_in_string_conversion(T);
00122 
00123 
00125 
00131 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00132 
00133 
00134 
00135 // TODO: Implement date conversions
00136 
00138 
00150 template<typename T> void from_string(const char Str[], T &Obj);
00151 
00152 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);   //[t45]
00153 template<>
00154   void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);   //[t45]
00155 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);    //[t45]
00156 template<>
00157   void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);    //[t45]
00158 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);  //[t45]
00159 template<>
00160   void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);  //[t45]
00161 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);  //[t46]
00162 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &); //[t46]
00163 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);   //[t76]
00164 #if defined(PQXX_HAVE_LONG_DOUBLE)
00165 template<>
00166   void PQXX_LIBEXPORT from_string(const char Str[], long double &);     //[t46]
00167 #endif
00168 
00169 
00170 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00171         { Obj = Str; }
00172 
00173 template<>
00174   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00175         { Obj.clear(); Obj << Str; }
00176 
00177 template<typename T>
00178   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00179         { from_string(Str.c_str(), Obj); }
00180 
00181 template<typename T>
00182   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00183         { from_string(Str.str(), Obj); }
00184 
00185 template<> inline void
00186 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00187         { Obj = Str; }
00188 
00189 template<> inline void
00190 from_string(const char [], char &Obj)
00191         { error_ambiguous_string_conversion(Obj); }
00192 template<> inline void
00193 from_string(const char [], signed char &Obj)
00194         { error_ambiguous_string_conversion(Obj); }
00195 template<> inline void
00196 from_string(const char [], unsigned char &Obj)
00197         { error_ambiguous_string_conversion(Obj); }
00198 
00199 template<> inline void
00200 from_string(const PGSTD::string &, char &Obj)
00201         { error_ambiguous_string_conversion(Obj); }
00202 template<> inline void
00203 from_string(const PGSTD::string &, signed char &Obj)
00204         { error_ambiguous_string_conversion(Obj); }
00205 template<> inline void
00206 from_string(const PGSTD::string &, unsigned char &Obj)
00207         { error_ambiguous_string_conversion(Obj); }
00208 
00209 
00210 namespace internal
00211 {
00213 inline int digit_to_number(char c) throw () { return c-'0'; }
00214 inline char number_to_digit(int i) throw () { return static_cast<char>(i)+'0'; }
00215 }
00216 
00217 
00219 
00223 template<typename T> PGSTD::string to_string(const T &);
00224 
00225 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);       //[t76]
00226 template<>
00227   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);       //[t76]
00228 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);         //[t10]
00229 template<>
00230   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);         //[t13]
00231 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);        //[t18]
00232 template<>
00233   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);        //[t20]
00234 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);       //[t74]
00235 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);      //[t74]
00236 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);        //[t76]
00237 #if defined(PQXX_HAVE_LONG_DOUBLE)
00238 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &); //[t74]
00239 #endif
00240 
00241 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00242         { return PGSTD::string(Obj); }
00243 
00244 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00245         { return Obj.str(); }
00246 
00247 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00248 
00249 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);        //[t21]
00250 
00251 
00252 template<> inline PGSTD::string to_string(const signed char &Obj)
00253         { return error_ambiguous_string_conversion(Obj); }
00254 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00255         { return error_ambiguous_string_conversion(Obj); }
00257 
00259 
00281 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00282 class items : public CONT
00283 {
00284 public:
00286   items() : CONT() {}                                                   //[t80]
00288   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00289   items(const T &t1, const T &t2) : CONT()                              //[t80]
00290         { push_back(t1); push_back(t2); }
00291   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00292         { push_back(t1); push_back(t2); push_back(t3); }
00293   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00294         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00295   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00296         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00298   items(const CONT &c) : CONT(c) {}                                     //[t0]
00299 
00301   items &operator()(const T &t)                                         //[t80]
00302   {
00303     push_back(t);
00304     return *this;
00305   }
00306 };
00307 
00308 
00309 namespace internal
00310 {
00311 // TODO: Does standard library provide a ready-made version of this?
00313 template<typename ITER> struct dereference
00314 {
00315   typename ITER::value_type operator()(ITER i) const { return *i; }
00316 };
00317 template<typename T> struct deref_ptr { T operator()(T *i) const {return *i;} };
00318 }
00319 
00320 
00322 
00328 template<typename ITER, typename ACCESS> inline
00329 PGSTD::string separated_list(const PGSTD::string &sep,                  //[t0]
00330     ITER begin,
00331     ITER end,
00332     ACCESS access)
00333 {
00334   PGSTD::string result;
00335   if (begin != end)
00336   {
00337     result = to_string(access(begin));
00338     for (++begin; begin != end; ++begin)
00339     {
00340       result += sep;
00341       result += to_string(access(begin));
00342     }
00343   }
00344   return result;
00345 }
00346 
00351 
00353 template<typename ITER> inline PGSTD::string
00354 separated_list(const PGSTD::string &sep, ITER begin, ITER end)          //[t8]
00355         { return separated_list(sep,begin,end,internal::dereference<ITER>()); }
00356 
00357 
00359 template<typename OBJ> inline PGSTD::string
00360 separated_list(const PGSTD::string &sep, OBJ *begin, OBJ *end)          //[t9]
00361         { return separated_list(sep,begin,end,internal::deref_ptr<OBJ>()); }
00362 
00363 
00365 template<typename CONTAINER> inline PGSTD::string
00366 separated_list(const PGSTD::string &sep, const CONTAINER &c)            //[t10]
00367         { return separated_list(sep, c.begin(), c.end()); }
00369 
00371 
00380 namespace internal
00381 {
00382 typedef unsigned long result_size_type;
00383 typedef long result_difference_type;
00384 
00386 
00394 template<typename T> inline const char *FmtString(T t) PQXX_DEPRECATED
00395 {
00396   error_unsupported_type_in_string_conversion(t);
00397   return 0;
00398 }
00399 
00400 template<> inline const char *FmtString(short)         { return "%hd"; }
00401 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00402 template<> inline const char *FmtString(int)           { return  "%i"; }
00403 template<> inline const char *FmtString(long)          { return "%li"; }
00404 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00405 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00406 template<> inline const char *FmtString(float)         { return  "%f"; }
00407 template<> inline const char *FmtString(double)        { return "%lf"; }
00408 template<> inline const char *FmtString(char)          { return  "%c"; }
00409 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00410 #if defined(PQXX_HAVE_LONG_DOUBLE)
00411 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00412 #endif
00413 
00414 } // namespace internal
00415 
00417 
00425 template<typename T> inline PGSTD::string ToString(const T &Obj) PQXX_DEPRECATED
00426 {
00427   // TODO: Find a decent way to determine max string length at compile time!
00428   char Buf[500];
00429   sprintf(Buf, internal::FmtString(Obj), Obj);
00430   return PGSTD::string(Buf);
00431 }
00432 
00433 
00434 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00435 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00436 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00437 
00438 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00439 {
00440   return reinterpret_cast<const char *>(Obj);
00441 }
00442 
00443 template<> inline PGSTD::string ToString(const bool &Obj)
00444 {
00445   return ToString(unsigned(Obj));
00446 }
00447 
00448 template<> inline PGSTD::string ToString(const short &Obj)
00449 {
00450   return ToString(int(Obj));
00451 }
00452 
00453 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00454 {
00455   return ToString(unsigned(Obj));
00456 }
00457 
00458 
00460 
00468 template<typename T> inline void FromString(const char Str[], T &Obj)
00469   PQXX_DEPRECATED
00470 {
00471   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00472                                      PGSTD::string(typeid(T).name()));
00473 
00474   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00475     throw PGSTD::runtime_error("Cannot convert value '" +
00476                              PGSTD::string(Str) +
00477                              "' to " + typeid(T).name());
00478 }
00479 
00480 
00481 namespace internal
00482 {
00484 
00486 PGSTD::string escape_string(const char str[], size_t maxlen);
00487 
00489 
00491 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj)
00492   PQXX_DEPRECATED;
00493 
00495 
00497 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00498         const unsigned char *&Obj)
00499   PQXX_DEPRECATED;
00500 
00502 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00503         bool EmptyIsNull);
00504 
00506 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00507 } // namespace internal
00508 
00509 
00510 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00511 {
00512   internal::FromString_string(Str, Obj);
00513 }
00514 
00515 template<> inline void FromString(const char Str[], const char *&Obj)
00516 {
00517   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00518   Obj = Str;
00519 }
00520 
00521 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00522 {
00523   internal::FromString_ucharptr(Str, Obj);
00524 }
00525 
00526 template<> inline void FromString(const char Str[], bool &Obj)
00527 {
00528   from_string(Str, Obj);
00529 }
00530 
00531 
00598 
00599 
00611 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]);
00612 
00614 
00627 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen);
00628 
00630 
00636 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &);
00637 
00638 
00640 
00645 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00646   PQXX_DEPRECATED;
00647 
00648 
00650 
00652 template<>
00653 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00654   PQXX_DEPRECATED
00655 {
00656   return internal::Quote_string(Obj, EmptyIsNull);
00657 }
00658 
00660 
00662 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00663   PQXX_DEPRECATED
00664 {
00665   return internal::Quote_charptr(Obj, EmptyIsNull);
00666 }
00667 
00668 
00670 
00677 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00678                                              bool EmptyIsNull)
00679   PQXX_DEPRECATED
00680 {
00681   return internal::Quote_charptr(Obj, EmptyIsNull);
00682 }
00683 
00684 
00687 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00688   PQXX_DEPRECATED
00689 {
00690   return Quote(ToString(Obj), EmptyIsNull);
00691 }
00692 
00693 
00695 
00699 template<typename T> inline PGSTD::string Quote(T Obj) PQXX_DEPRECATED
00700 {
00701   return Quote(Obj, false);
00702 }
00704 
00705 
00706 namespace internal
00707 {
00708 void PQXX_LIBEXPORT freepqmem(void *);
00709 
00711 
00725 template<typename T> class PQXX_LIBEXPORT PQAlloc
00726 {
00727   T *m_Obj;
00728   mutable const PQAlloc *m_l, *m_r;
00729 public:
00730   typedef T content_type;
00731 
00732   PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00733   PQAlloc(const PQAlloc &rhs) throw () :
00734     m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00735   ~PQAlloc() throw () { loseref(); }
00736 
00737   PQAlloc &operator=(const PQAlloc &rhs) throw ()
00738         { redoref(rhs); return *this; }
00739 
00741 
00743   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00744 
00745   void swap(PQAlloc &rhs) throw ()
00746   {
00747     PQAlloc tmp(*this);
00748     *this = rhs;
00749     rhs = tmp;
00750   }
00751 
00752   PQAlloc &operator=(T *obj) throw () { redoref(obj); return *this; }
00753 
00755   operator bool() const throw () { return m_Obj != 0; }
00756 
00758   bool operator!() const throw () { return !m_Obj; }
00759 
00761 
00763   T *operator->() const throw (PGSTD::logic_error)
00764   {
00765     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00766     return m_Obj;
00767   }
00768 
00770 
00772   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00773 
00775 
00777   T *c_ptr() const throw () { return m_Obj; }
00778 
00779   void clear() throw () { loseref(); }
00780 
00781 private:
00782   void makeref(T *p) throw () { m_Obj = p; }
00783 
00784   void makeref(const PQAlloc &rhs) throw ()
00785   {
00786     // TODO: Make threadsafe
00787     m_l = &rhs;
00788     m_r = rhs.m_r;
00789     m_Obj = rhs.m_Obj;
00790     m_l->m_r = m_r->m_l = this;
00791   }
00792 
00794   void loseref() throw ()
00795   {
00796     // TODO: Make threadsafe
00797     if (m_l == this && m_Obj) freemem();
00798     m_Obj = 0;
00799     m_l->m_r = m_r;
00800     m_r->m_l = m_l;
00801     m_l = m_r = this;
00802   }
00803 
00804   // TODO: Make threadsafe
00805   void redoref(const PQAlloc &rhs) throw ()
00806         { if (rhs.m_Obj != m_Obj) { loseref(); makeref(rhs); } }
00807   void redoref(T *obj) throw ()
00808         { if (obj != m_Obj) { loseref(); makeref(obj); } }
00809 
00810   void freemem() throw () { freepqmem(m_Obj); }
00811 };
00812 
00813 
00814 void PQXX_LIBEXPORT freemem_result(pq::PGresult *) throw ();
00815 template<> inline void PQAlloc<pq::PGresult>::freemem() throw ()
00816         { freemem_result(m_Obj); }
00817 
00818 void PQXX_LIBEXPORT freemem_notif(pq::PGnotify *) throw ();
00819 template<> inline void PQAlloc<pq::PGnotify>::freemem() throw ()
00820         { freemem_notif(m_Obj); }
00821 
00822 
00823 
00824 template<typename T> class scoped_array
00825 {
00826   T *m_ptr;
00827 public:
00828   typedef size_t size_type;
00829   typedef long difference_type;
00830 
00831   scoped_array() : m_ptr(0) {}
00832   explicit scoped_array(size_type n) : m_ptr(new T[n]) {}
00833   explicit scoped_array(T *t) : m_ptr(t) {}
00834   ~scoped_array() { delete [] m_ptr; }
00835 
00836   T *c_ptr() const throw () { return m_ptr; }
00837   T &operator*() const throw () { return *m_ptr; }
00838   T &operator[](difference_type i) const throw () { return m_ptr[i]; }
00839 
00840   scoped_array &operator=(T *t) throw ()
00841   {
00842     if (t != m_ptr)
00843     {
00844       delete [] m_ptr;
00845       m_ptr = t;
00846     }
00847     return *this;
00848   }
00849 
00850 private:
00852   scoped_array(const scoped_array &);
00853   scoped_array &operator=(const scoped_array &);
00854 };
00855 
00856 
00857 class PQXX_LIBEXPORT namedclass
00858 {
00859 public:
00860   namedclass(const PGSTD::string &Classname, const PGSTD::string &Name="") :
00861     m_Classname(Classname),
00862     m_Name(Name)
00863   {
00864   }
00865 
00866   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00867   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00868   PGSTD::string description() const;
00869 
00870 private:
00871   PGSTD::string m_Classname, m_Name;
00872 };
00873 
00874 
00875 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00876 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00877 
00878 
00880 
00883 template<typename GUEST>
00884 class unique
00885 {
00886 public:
00887   unique() : m_Guest(0) {}
00888 
00889   GUEST *get() const throw () { return m_Guest; }
00890 
00891   void Register(GUEST *G)
00892   {
00893     CheckUniqueRegistration(G, m_Guest);
00894     m_Guest = G;
00895   }
00896 
00897   void Unregister(GUEST *G)
00898   {
00899     CheckUniqueUnregistration(G, m_Guest);
00900     m_Guest = 0;
00901   }
00902 
00903 private:
00904   GUEST *m_Guest;
00905 
00907   unique(const unique &);
00909   unique &operator=(const unique &);
00910 };
00911 
00913 
00916 void PQXX_LIBEXPORT sleep_seconds(int);
00917 
00919 typedef const char *cstring;
00920 
00922 
00931 cstring PQXX_LIBEXPORT strerror_wrapper(int err, char buf[], PGSTD::size_t len)
00932   throw ();
00933 
00934 
00936 extern const char sql_begin_work[], sql_commit_work[], sql_rollback_work[];
00937 
00938 } // namespace internal
00939 } // namespace pqxx
00940 

Generated on Sun Jun 18 14:51:00 2006 for libpqxx by  doxygen 1.4.6