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-2004, 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 #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 // We want libpq in the pqxx::internal::pq namespace
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 } // namespace pq
00066 } // namespace internal
00067 } // namespace pqxx
00068 
00069 #else   // PQXX_PQ_IN_NAMESPACE
00070 // We want libpq in the global namespace, with duplicates in pqxx::internal::pq
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 } // namespace pq
00088 } // namespace internal
00089 } // namespace pqxx
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 // TODO: Implement date conversions
00131 
00133 
00143 template<typename T> void from_string(const char Str[], T &Obj);
00144 
00145 template<> void from_string(const char Str[], long &);                  //[t45]
00146 template<> void from_string(const char Str[], unsigned long &);         //[t45]
00147 template<> void from_string(const char Str[], int &);                   //[t45]
00148 template<> void from_string(const char Str[], unsigned int &);          //[t45]
00149 template<> void from_string(const char Str[], short &);                 //[t45]
00150 template<> void from_string(const char Str[], unsigned short &);        //[t45]
00151 template<> void from_string(const char Str[], float &);                 //[t46]
00152 template<> void from_string(const char Str[], double &);                //[t46]
00153 template<> void from_string(const char Str[], bool &);                  //[t76]
00154 #if defined(PQXX_HAVE_LONG_DOUBLE)
00155 template<> void from_string(const char Str[], long double &);           //[t46]
00156 #endif
00157 
00158 
00159 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00160         { Obj = Str; }
00161 
00162 template<> 
00163   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00164         { Obj.clear(); Obj << Str; }
00165 
00166 template<typename T> 
00167   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00168         { from_string(Str.c_str(), Obj); }
00169 
00170 template<typename T>
00171   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00172         { from_string(Str.str(), Obj); }
00173 
00174 template<> inline void 
00175 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
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 &);                      //[t76]
00197 template<> PGSTD::string to_string(const unsigned short &);             //[t76]
00198 template<> PGSTD::string to_string(const int &);                        //[t10]
00199 template<> PGSTD::string to_string(const unsigned int &);               //[t13]
00200 template<> PGSTD::string to_string(const long &);                       //[t18]
00201 template<> PGSTD::string to_string(const unsigned long &);              //[t20]
00202 template<> PGSTD::string to_string(const float &);                      //[t74]
00203 template<> PGSTD::string to_string(const double &);                     //[t74]
00204 template<> PGSTD::string to_string(const bool &);                       //[t76]
00205 #if defined(PQXX_HAVE_LONG_DOUBLE)
00206 template<> PGSTD::string to_string(const long double &);                //[t74]
00207 #endif
00208 
00209 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00210         { return PGSTD::string(Obj); }
00211 
00212 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00213         { return Obj.str(); }
00214 
00215 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00216 
00217 template<> PGSTD::string to_string(const char &);                       //[t21]
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() {}                                                   //[t80]
00251   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00252   items(const T &t1, const T &t2) : CONT()                              //[t80]
00253         { push_back(t1); push_back(t2); }
00254   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
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()    //[t0]
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()  //[t0]
00259         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00261   items(const CONT &c) : CONT(c) {}                                     //[t0]
00262 
00264   items &operator()(const T &t)                                         //[t80]
00265   {
00266     push_back(t);
00267     return *this;
00268   }
00269 };
00270 
00271 
00272 // TODO: Generalize--add transformation functor
00274 template<typename ITER> inline
00275 PGSTD::string separated_list(const PGSTD::string &sep,
00276     ITER begin,
00277     ITER end)                                                           //[t8]
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)                                                 //[t10]
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 } // namespace internal
00346 
00348 
00356 template<typename T> inline PGSTD::string ToString(const T &Obj)
00357 {
00358   // TODO: Find a decent way to determine max string length at compile time!
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 } // namespace internal
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[]);                                 //[t0]
00466 
00468 
00478 PGSTD::string sqlesc(const char str[], size_t maxlen);                  //[t0]
00479 
00481 
00487 PGSTD::string sqlesc(const PGSTD::string &);                            //[t0]
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; }         //[t1]
00656   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
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 } // namespace internal
00705 } // namespace pqxx
00706 

Generated on Tue Feb 8 09:17:14 2005 for libpqxx by  doxygen 1.4.1