Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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-2005, 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/libcompiler.h"
00019 
00020 #include <cstdio>
00021 #include <cctype>
00022 #include <sstream>
00023 #include <stdexcept>
00024 #include <string>
00025 #include <typeinfo>
00026 #include <vector>
00027 
00047 
00048 namespace pqxx {}
00049 
00050 #ifdef PQXX_PQ_IN_NAMESPACE
00051 // We want libpq in the pqxx::internal::pq namespace
00052 
00053 namespace pqxx
00054 {
00055 namespace internal
00056 {
00057 namespace pq
00058 {
00059 #define PQXXPQ pqxx::internal::pq
00060 extern "C"
00061 {
00062 #include "libpq-fe.h"
00063 }
00064 } // namespace pq
00065 } // namespace internal
00066 } // namespace pqxx
00067 
00068 #else   // PQXX_PQ_IN_NAMESPACE
00069 // We want libpq in the global namespace, with duplicates in pqxx::internal::pq
00070 
00071 extern "C"
00072 {
00073 #include "libpq-fe.h"
00074 }
00075 
00076 namespace pqxx
00077 {
00078 namespace internal
00079 {
00080 namespace pq
00081 {
00082 #define PQXXPQ
00083 typedef PQXXPQ::PGconn PGconn;
00084 typedef PQXXPQ::PGresult PGresult;
00085 
00086 } // namespace pq
00087 } // namespace internal
00088 } // namespace pqxx
00089 
00090 #endif  // PQXX_PQ_IN_NAMESPACE
00091 
00092 
00093 namespace pqxx
00094 {
00096 typedef PQXXPQ::Oid oid;
00097 
00099 const oid oid_none = 0;
00100 
00102 
00115 template<typename T> void error_unsupported_type_in_string_conversion(T);
00116 
00117 
00119 
00125 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00126 
00127 
00128 
00129 // TODO: Implement date conversions
00130 
00132 
00142 template<typename T> void from_string(const char Str[], T &Obj);
00143 
00144 template<> void PQXX_LIBEXPORT from_string(const char Str[], long &);   //[t45]
00145 template<>
00146   void PQXX_LIBEXPORT from_string(const char Str[], unsigned long &);   //[t45]
00147 template<> void PQXX_LIBEXPORT from_string(const char Str[], int &);    //[t45]
00148 template<>
00149   void PQXX_LIBEXPORT from_string(const char Str[], unsigned int &);    //[t45]
00150 template<> void PQXX_LIBEXPORT from_string(const char Str[], short &);  //[t45]
00151 template<>
00152   void PQXX_LIBEXPORT from_string(const char Str[], unsigned short &);  //[t45]
00153 template<> void PQXX_LIBEXPORT from_string(const char Str[], float &);  //[t46]
00154 template<> void PQXX_LIBEXPORT from_string(const char Str[], double &); //[t46]
00155 template<> void PQXX_LIBEXPORT from_string(const char Str[], bool &);   //[t76]
00156 #if defined(PQXX_HAVE_LONG_DOUBLE)
00157 template<>
00158   void PQXX_LIBEXPORT from_string(const char Str[], long double &);     //[t46]
00159 #endif
00160 
00161 
00162 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00163         { Obj = Str; }
00164 
00165 template<>
00166   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00167         { Obj.clear(); Obj << Str; }
00168 
00169 template<typename T>
00170   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00171         { from_string(Str.c_str(), Obj); }
00172 
00173 template<typename T>
00174   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00175         { from_string(Str.str(), Obj); }
00176 
00177 template<> inline void
00178 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00179         { Obj = Str; }
00180 
00181 template<> inline void
00182 from_string(const PGSTD::string &, const char &Obj)
00183         { error_ambiguous_string_conversion(Obj); }
00184 template<> inline void
00185 from_string(const PGSTD::string &, const signed char &Obj)
00186         { error_ambiguous_string_conversion(Obj); }
00187 template<> inline void
00188 from_string(const PGSTD::string &, const unsigned char &Obj)
00189         { error_ambiguous_string_conversion(Obj); }
00190 
00191 
00193 
00197 template<typename T> PGSTD::string to_string(const T &);
00198 
00199 template<> PGSTD::string PQXX_LIBEXPORT to_string(const short &);       //[t76]
00200 template<>
00201   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned short &);       //[t76]
00202 template<> PGSTD::string PQXX_LIBEXPORT to_string(const int &);         //[t10]
00203 template<>
00204   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned int &);         //[t13]
00205 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long &);        //[t18]
00206 template<>
00207   PGSTD::string PQXX_LIBEXPORT to_string(const unsigned long &);        //[t20]
00208 template<> PGSTD::string PQXX_LIBEXPORT to_string(const float &);       //[t74]
00209 template<> PGSTD::string PQXX_LIBEXPORT to_string(const double &);      //[t74]
00210 template<> PGSTD::string PQXX_LIBEXPORT to_string(const bool &);        //[t76]
00211 #if defined(PQXX_HAVE_LONG_DOUBLE)
00212 template<> PGSTD::string PQXX_LIBEXPORT to_string(const long double &); //[t74]
00213 #endif
00214 
00215 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00216         { return PGSTD::string(Obj); }
00217 
00218 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00219         { return Obj.str(); }
00220 
00221 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00222 
00223 template<> PGSTD::string PQXX_LIBEXPORT to_string(const char &);        //[t21]
00224 
00225 
00226 template<> inline PGSTD::string to_string(const signed char &Obj)
00227         { return error_ambiguous_string_conversion(Obj); }
00228 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00229         { return error_ambiguous_string_conversion(Obj); }
00230 
00231 
00233 
00250 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00251 class items : public CONT
00252 {
00253 public:
00255   items() : CONT() {}                                                   //[t80]
00257   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00258   items(const T &t1, const T &t2) : CONT()                              //[t80]
00259         { push_back(t1); push_back(t2); }
00260   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00261         { push_back(t1); push_back(t2); push_back(t3); }
00262   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00263         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00264   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00265         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00267   items(const CONT &c) : CONT(c) {}                                     //[t0]
00268 
00270   items &operator()(const T &t)                                         //[t80]
00271   {
00272     push_back(t);
00273     return *this;
00274   }
00275 };
00276 
00277 
00278 // TODO: Generalize--add transformation functor
00280 template<typename ITER> inline
00281 PGSTD::string separated_list(const PGSTD::string &sep,
00282     ITER begin,
00283     ITER end)                                                           //[t8]
00284 {
00285   PGSTD::string result;
00286   if (begin != end)
00287   {
00288     result = to_string(*begin);
00289     for (++begin; begin != end; ++begin)
00290     {
00291       result += sep;
00292       result += to_string(*begin);
00293     }
00294   }
00295   return result;
00296 }
00297 
00299 template<typename CONTAINER> inline
00300 PGSTD::string separated_list(const PGSTD::string &sep,
00301     const CONTAINER &c)                                                 //[t10]
00302 {
00303   return separated_list(sep, c.begin(), c.end());
00304 }
00305 
00306 
00308 
00317 namespace internal
00318 {
00319 typedef unsigned long result_size_type;
00320 typedef long result_difference_type;
00321 
00323 
00331 template<typename T> inline const char *FmtString(T t)
00332 {
00333   error_unsupported_type_in_string_conversion(t);
00334   return 0;
00335 }
00336 
00337 template<> inline const char *FmtString(short)         { return "%hd"; }
00338 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00339 template<> inline const char *FmtString(int)           { return  "%i"; }
00340 template<> inline const char *FmtString(long)          { return "%li"; }
00341 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00342 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00343 template<> inline const char *FmtString(float)         { return  "%f"; }
00344 template<> inline const char *FmtString(double)        { return "%lf"; }
00345 template<> inline const char *FmtString(char)          { return  "%c"; }
00346 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00347 #if defined(PQXX_HAVE_LONG_DOUBLE)
00348 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00349 #endif
00350 
00351 } // namespace internal
00352 
00354 
00362 template<typename T> inline PGSTD::string ToString(const T &Obj)
00363 {
00364   // TODO: Find a decent way to determine max string length at compile time!
00365   char Buf[500];
00366   sprintf(Buf, internal::FmtString(Obj), Obj);
00367   return PGSTD::string(Buf);
00368 }
00369 
00370 
00371 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00372 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00373 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00374 
00375 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00376 {
00377   return reinterpret_cast<const char *>(Obj);
00378 }
00379 
00380 template<> inline PGSTD::string ToString(const bool &Obj)
00381 {
00382   return ToString(unsigned(Obj));
00383 }
00384 
00385 template<> inline PGSTD::string ToString(const short &Obj)
00386 {
00387   return ToString(int(Obj));
00388 }
00389 
00390 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00391 {
00392   return ToString(unsigned(Obj));
00393 }
00394 
00395 
00397 
00405 template<typename T> inline void FromString(const char Str[], T &Obj)
00406 {
00407   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00408                                      PGSTD::string(typeid(T).name()));
00409 
00410   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00411     throw PGSTD::runtime_error("Cannot convert value '" +
00412                              PGSTD::string(Str) +
00413                              "' to " + typeid(T).name());
00414 }
00415 
00416 
00417 namespace internal
00418 {
00420 
00422 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00423 
00425 
00427 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00428         const unsigned char *&Obj);
00429 
00431 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00432         bool EmptyIsNull);
00433 
00435 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00436 } // namespace internal
00437 
00438 
00439 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00440 {
00441   internal::FromString_string(Str, Obj);
00442 }
00443 
00444 template<> inline void FromString(const char Str[], const char *&Obj)
00445 {
00446   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00447   Obj = Str;
00448 }
00449 
00450 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00451 {
00452   internal::FromString_ucharptr(Str, Obj);
00453 }
00454 
00455 template<> inline void FromString(const char Str[], bool &Obj)
00456 {
00457   from_string(Str, Obj);
00458 }
00459 
00460 
00462 
00471 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[]);                  //[t0]
00472 
00474 
00484 PGSTD::string PQXX_LIBEXPORT sqlesc(const char str[], size_t maxlen);   //[t0]
00485 
00487 
00493 PGSTD::string PQXX_LIBEXPORT sqlesc(const PGSTD::string &);             //[t0]
00494 
00495 
00497 
00501 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00502 
00503 
00505 
00507 template<>
00508 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00509 {
00510   return internal::Quote_string(Obj, EmptyIsNull);
00511 }
00512 
00514 
00516 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00517 {
00518   return internal::Quote_charptr(Obj, EmptyIsNull);
00519 }
00520 
00521 
00523 
00528 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00529                                              bool EmptyIsNull)
00530 {
00531   return internal::Quote_charptr(Obj, EmptyIsNull);
00532 }
00533 
00534 
00535 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00536 {
00537   return Quote(ToString(Obj), EmptyIsNull);
00538 }
00539 
00540 
00542 
00545 template<typename T> inline PGSTD::string Quote(T Obj)
00546 {
00547   return Quote(Obj, false);
00548 }
00549 
00550 
00551 namespace internal
00552 {
00553 void freepqmem(void *);
00554 void freenotif(PQXXPQ::PGnotify *);
00555 
00557 
00563 template<typename T> class PQAlloc
00564 {
00565   T *m_Obj;
00566   mutable const PQAlloc *m_l, *m_r;
00567 public:
00568   typedef T content_type;
00569 
00570   PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00571   PQAlloc(const PQAlloc &rhs) throw () :
00572     m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00573   ~PQAlloc() throw () { loseref(); }
00574 
00575   PQAlloc &operator=(const PQAlloc &rhs) throw ()
00576         { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00577 
00579 
00581   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00582 
00583   void swap(PQAlloc &rhs) throw ()
00584   {
00585     PQAlloc tmp(*this);
00586     *this = rhs;
00587     rhs = tmp;
00588   }
00589 
00590   PQAlloc &operator=(T *obj) throw () { loseref(); makeref(obj); return *this; }
00591 
00593   operator bool() const throw () { return m_Obj != 0; }
00594 
00596   bool operator!() const throw () { return !m_Obj; }
00597 
00599 
00601   T *operator->() const throw (PGSTD::logic_error)
00602   {
00603     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00604     return m_Obj;
00605   }
00606 
00608 
00610   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00611 
00613 
00615   T *c_ptr() const throw () { return m_Obj; }
00616 
00617   void clear() throw () { loseref(); }
00618 
00619 private:
00620   void makeref(T *p) throw () { m_Obj = p; }
00621 
00622   void makeref(const PQAlloc &rhs) throw ()
00623   {
00624     m_l = &rhs;
00625     m_r = rhs.m_r;
00626     m_l->m_r = m_r->m_l = this;
00627     m_Obj = rhs.m_Obj;
00628   }
00629 
00631   void loseref() throw ()
00632   {
00633     if (m_l == this && m_Obj) freemem();
00634     m_Obj = 0;
00635     m_l->m_r = m_r;
00636     m_r->m_l = m_l;
00637     m_l = m_r = this;
00638   }
00639 
00640   void freemem() throw () { freepqmem(m_Obj); }
00641 };
00642 
00643 
00645 template<> inline void PQAlloc<PQXXPQ::PGresult>::freemem() throw ()
00646         { PQclear(m_Obj); }
00648 template<> inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw ()
00649         { freenotif(m_Obj); }
00650 
00651 
00652 class PQXX_LIBEXPORT namedclass
00653 {
00654 public:
00655   namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00656     m_Name(Name),
00657     m_Classname(Classname)
00658   {
00659   }
00660 
00661   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00662   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00663   PGSTD::string description() const;
00664 
00665 private:
00666   PGSTD::string m_Name, m_Classname;
00667 };
00668 
00669 
00670 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00671 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00672 
00673 
00675 
00678 template<typename GUEST>
00679 class unique
00680 {
00681 public:
00682   unique() : m_Guest(0) {}
00683 
00684   GUEST *get() const throw () { return m_Guest; }
00685 
00686   void Register(GUEST *G)
00687   {
00688     CheckUniqueRegistration(G, m_Guest);
00689     m_Guest = G;
00690   }
00691 
00692   void Unregister(GUEST *G)
00693   {
00694     CheckUniqueUnregistration(G, m_Guest);
00695     m_Guest = 0;
00696   }
00697 
00698 private:
00699   GUEST *m_Guest;
00700 
00702   unique(const unique &);
00704   unique &operator=(const unique &);
00705 };
00706 
00708 void PQXX_LIBEXPORT sleep_seconds(int);
00709 
00710 } // namespace internal
00711 } // namespace pqxx
00712 

Generated on Mon Feb 28 10:24:56 2005 for libpqxx by  doxygen 1.4.1