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 <cassert>// DEBUG CODE
00022 #include <cstdio>
00023 #include <cctype>
00024 #include <sstream>
00025 #include <stdexcept>
00026 #include <string>
00027 #include <typeinfo>
00028 #include <vector>
00029 
00030 
00032 namespace pqxx
00033 {
00034 }
00035 
00036 
00037 #ifdef PQXX_PQ_IN_NAMESPACE
00038 // We want libpq in the pqxx::internal::pq namespace
00039 
00040 namespace pqxx
00041 {
00042 namespace internal
00043 {
00044 namespace pq
00045 {
00046 #define PQXXPQ pqxx::internal::pq
00047 extern "C"
00048 {
00049 #include "libpq-fe.h"
00050 }
00051 } // namespace pq
00052 } // namespace internal
00053 } // namespace pqxx
00054 
00055 #else   // PQXX_PQ_IN_NAMESPACE
00056 // We want libpq in the global namespace, with duplicates in pqxx::internal::pq
00057 
00058 extern "C"
00059 {
00060 #include "libpq-fe.h"
00061 }
00062 
00063 namespace pqxx
00064 {
00065 namespace internal
00066 {
00067 namespace pq
00068 {
00069 #define PQXXPQ
00070 typedef PQXXPQ::PGconn PGconn;
00071 typedef PQXXPQ::PGresult PGresult;
00072 
00073 } // namespace pq
00074 } // namespace internal
00075 } // namespace pqxx
00076 
00077 #endif  // PQXX_PQ_IN_NAMESPACE
00078 
00079 
00080 namespace pqxx
00081 {
00083 typedef PQXXPQ::Oid oid;
00084 
00086 const oid oid_none = 0;
00087 
00089 
00102 template<typename T> void error_unsupported_type_in_string_conversion(T);
00103 
00104 
00106 
00112 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00113 
00114 
00115 
00116 // TODO: Implement date conversions
00117 
00119 
00128 template<typename T> void from_string(const char Str[], T &Obj);
00129 
00130 template<> void from_string(const char Str[], long &);                  //[t45]
00131 template<> void from_string(const char Str[], unsigned long &);         //[t45]
00132 template<> void from_string(const char Str[], int &);                   //[t45]
00133 template<> void from_string(const char Str[], unsigned int &);          //[t45]
00134 template<> void from_string(const char Str[], short &);                 //[t45]
00135 template<> void from_string(const char Str[], unsigned short &);        //[t45]
00136 template<> void from_string(const char Str[], float &);                 //[t46]
00137 template<> void from_string(const char Str[], double &);                //[t46]
00138 template<> void from_string(const char Str[], long double &);           //[t46]
00139 template<> void from_string(const char Str[], bool &);                  //[t76]
00140 
00141 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00142         { Obj = Str; }
00143 
00144 template<> 
00145   inline void from_string(const char Str[], PGSTD::stringstream &Obj)   //[t0]
00146         { Obj.clear(); Obj << Str; }
00147 
00148 template<typename T> 
00149   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00150         { from_string(Str.c_str(), Obj); }
00151 
00152 template<typename T>
00153   inline void from_string(const PGSTD::stringstream &Str, T &Obj)       //[t0]
00154         { from_string(Str.str(), Obj); }
00155 
00156 template<> inline void 
00157 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00158         { Obj = Str; }
00159 
00160 template<> inline void
00161 from_string(const PGSTD::string &, const char &Obj)
00162         { error_ambiguous_string_conversion(Obj); }
00163 template<> inline void
00164 from_string(const PGSTD::string &, const signed char &Obj)
00165         { error_ambiguous_string_conversion(Obj); }
00166 template<> inline void
00167 from_string(const PGSTD::string &, const unsigned char &Obj)
00168         { error_ambiguous_string_conversion(Obj); }
00169 
00170 
00172 
00176 template<typename T> PGSTD::string to_string(const T &);
00177 
00178 template<> PGSTD::string to_string(const short &);                      //[t76]
00179 template<> PGSTD::string to_string(const unsigned short &);             //[t76]
00180 template<> PGSTD::string to_string(const int &);                        //[t10]
00181 template<> PGSTD::string to_string(const unsigned int &);               //[t13]
00182 template<> PGSTD::string to_string(const long &);                       //[t18]
00183 template<> PGSTD::string to_string(const unsigned long &);              //[t20]
00184 template<> PGSTD::string to_string(const float &);                      //[t74]
00185 template<> PGSTD::string to_string(const double &);                     //[t74]
00186 template<> PGSTD::string to_string(const long double &);                //[t74]
00187 template<> PGSTD::string to_string(const bool &);                       //[t76]
00188 
00189 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00190         { return PGSTD::string(Obj); }
00191 
00192 inline PGSTD::string to_string(const PGSTD::stringstream &Obj)          //[t0]
00193         { return Obj.str(); }
00194 
00195 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00196 
00197 template<> PGSTD::string to_string(const char &);                       //[t21]
00198 
00199 
00200 template<> inline PGSTD::string to_string(const signed char &Obj)
00201         { return error_ambiguous_string_conversion(Obj); }
00202 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00203         { return error_ambiguous_string_conversion(Obj); }
00204 
00205 
00207 
00224 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> >
00225 class items : public CONT
00226 {
00227 public:
00229   items() : CONT() {}                                                   //[t80]
00231   explicit items(const T &t) : CONT() { push_back(t); }                 //[t0]
00232   items(const T &t1, const T &t2) : CONT()                              //[t80]
00233         { push_back(t1); push_back(t2); }
00234   items(const T &t1, const T &t2, const T &t3) : CONT()                 //[t0]
00235         { push_back(t1); push_back(t2); push_back(t3); }
00236   items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT()    //[t0]
00237         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00238   items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT()  //[t0]
00239         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00241   items(const CONT &c) : CONT(c) {}                                     //[t0]
00242 
00244   items &operator()(const T &t)                                         //[t80]
00245   {
00246     push_back(t);
00247     return *this;
00248   }
00249 };
00250 
00251 
00252 // TODO: Generalize--add transformation functor
00254 template<typename ITER> inline
00255 PGSTD::string separated_list(const PGSTD::string &sep,
00256     ITER begin,
00257     ITER end)                                                           //[t8]
00258 {
00259   PGSTD::string result;
00260   if (begin != end)
00261   {
00262     result = to_string(*begin);
00263     for (++begin; begin != end; ++begin)
00264     {
00265       result += sep;
00266       result += to_string(*begin);
00267     }
00268   }
00269   return result;
00270 }
00271 
00273 template<typename CONTAINER> inline
00274 PGSTD::string separated_list(const PGSTD::string &sep,
00275     const CONTAINER &c)                                                 //[t10]
00276 {
00277   return separated_list(sep, c.begin(), c.end());
00278 }
00279 
00280 
00282 
00291 namespace internal
00292 {
00293 typedef unsigned long result_size_type;
00294 typedef long result_difference_type;
00295 
00297 
00305 template<typename T> inline const char *FmtString(T t)
00306 {
00307   error_unsupported_type_in_string_conversion(t);
00308   return 0;
00309 }
00310 
00311 template<> inline const char *FmtString(short)         { return "%hd"; }
00312 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00313 template<> inline const char *FmtString(int)           { return  "%i"; }
00314 template<> inline const char *FmtString(long)          { return "%li"; }
00315 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00316 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00317 template<> inline const char *FmtString(float)         { return  "%f"; }
00318 template<> inline const char *FmtString(double)        { return "%lf"; }
00319 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00320 template<> inline const char *FmtString(char)          { return  "%c"; }
00321 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00322 
00323 } // namespace internal
00324 
00326 
00334 template<typename T> inline PGSTD::string ToString(const T &Obj)
00335 {
00336   // TODO: Find a decent way to determine max string length at compile time!
00337   char Buf[500];
00338   sprintf(Buf, internal::FmtString(Obj), Obj);
00339   return PGSTD::string(Buf);
00340 }
00341 
00342 
00343 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00344 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00345 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00346 
00347 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00348 {
00349   return reinterpret_cast<const char *>(Obj);
00350 }
00351 
00352 template<> inline PGSTD::string ToString(const bool &Obj) 
00353 { 
00354   return ToString(unsigned(Obj));
00355 }
00356 
00357 template<> inline PGSTD::string ToString(const short &Obj)
00358 {
00359   return ToString(int(Obj));
00360 }
00361 
00362 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00363 {
00364   return ToString(unsigned(Obj));
00365 }
00366 
00367 
00369 
00377 template<typename T> inline void FromString(const char Str[], T &Obj)
00378 {
00379   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00380                                      PGSTD::string(typeid(T).name()));
00381 
00382   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00383     throw PGSTD::runtime_error("Cannot convert value '" + 
00384                              PGSTD::string(Str) + 
00385                              "' to " + typeid(T).name());
00386 }
00387 
00388 
00389 namespace internal
00390 {
00392 
00394 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00395 
00397 
00399 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[], 
00400         const unsigned char *&Obj);
00401 
00403 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj, 
00404         bool EmptyIsNull);
00405 
00407 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00408 } // namespace internal
00409 
00410 
00411 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00412 {
00413   internal::FromString_string(Str, Obj);
00414 }
00415 
00416 template<> inline void FromString(const char Str[], const char *&Obj)
00417 {
00418   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00419   Obj = Str;
00420 }
00421 
00422 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00423 {
00424   internal::FromString_ucharptr(Str, Obj);
00425 }
00426 
00427 template<> inline void FromString(const char Str[], bool &Obj)
00428 {
00429   from_string(Str, Obj);
00430 }
00431 
00432 
00434 
00443 PGSTD::string sqlesc(const char str[]);                                 //[t0]
00444 
00446 
00456 PGSTD::string sqlesc(const char str[], size_t maxlen);                  //[t0]
00457 
00459 
00465 PGSTD::string sqlesc(const PGSTD::string &);                            //[t0]
00466 
00467 
00469 
00473 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00474 
00475 
00477 
00479 template<> 
00480 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00481 {
00482   return internal::Quote_string(Obj, EmptyIsNull);
00483 }
00484 
00486 
00488 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00489 {
00490   return internal::Quote_charptr(Obj, EmptyIsNull);
00491 }
00492 
00493 
00495 
00500 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00501                                              bool EmptyIsNull)
00502 {
00503   return internal::Quote_charptr(Obj, EmptyIsNull);
00504 }
00505 
00506 
00507 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00508 {
00509   return Quote(ToString(Obj), EmptyIsNull);
00510 }
00511 
00512 
00514 
00517 template<typename T> inline PGSTD::string Quote(T Obj)
00518 {
00519   return Quote(Obj, false);
00520 }
00521 
00522 
00523 namespace internal
00524 {
00525 void freepqmem(void *);
00526 void freenotif(PQXXPQ::PGnotify *);
00527 
00529 
00535 template<typename T> class PQAlloc
00536 {
00537   T *m_Obj;
00538   mutable const PQAlloc *m_l, *m_r;
00539 public:
00540   typedef T content_type;
00541 
00542   PQAlloc() throw () : m_Obj(0), m_l(this), m_r(this) {}
00543   PQAlloc(const PQAlloc &rhs) throw () :
00544     m_Obj(0), m_l(this), m_r(this) { makeref(rhs); }
00545   ~PQAlloc() throw () { loseref(); }
00546 
00547   PQAlloc &operator=(const PQAlloc &rhs) throw () 
00548         { if (&rhs != this) { loseref(); makeref(rhs); } return *this; }
00549 
00551 
00553   explicit PQAlloc(T *obj) throw () : m_Obj(obj), m_l(this), m_r(this) {}
00554 
00555   void swap(PQAlloc &rhs) throw ()
00556   {
00557     PQAlloc tmp(*this);
00558     *this = rhs;
00559     rhs = tmp;
00560   }
00561 
00562   PQAlloc &operator=(T *obj) throw ()
00563         { assert(!obj || obj != m_Obj); loseref(); makeref(obj); return *this; }
00564 
00566   operator bool() const throw () { return m_Obj != 0; }
00567 
00569   bool operator!() const throw () { return !m_Obj; }
00570 
00572 
00574   T *operator->() const throw (PGSTD::logic_error)
00575   {
00576     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00577     return m_Obj;
00578   }
00579 
00581 
00583   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00584 
00586 
00588   T *c_ptr() const throw () { return m_Obj; }
00589 
00590   void clear() throw () { loseref(); }
00591 
00592 private:
00593   void makeref(T *p) throw ()
00594   {
00595     assert(m_l == this);
00596     assert(m_r == this);
00597     assert(!m_Obj);
00598     m_Obj = p;
00599   }
00600 
00601   void makeref(const PQAlloc &rhs) throw ()
00602   {
00603     assert(m_l == this);
00604     assert(m_r == this);
00605     assert(&rhs != this);
00606     assert(!m_Obj);
00607     m_l = &rhs;
00608     m_r = rhs.m_r;
00609     m_l->m_r = m_r->m_l = this;
00610     m_Obj = rhs.m_Obj;
00611   }
00612 
00614   void loseref() throw ()
00615   {
00616     assert(m_r->m_l == this);
00617     assert(m_l->m_r == this);
00618     assert((m_l==this) == (m_r==this));
00619 
00620     if (m_l == this && m_Obj) freemem();
00621     m_Obj = 0;
00622     m_l->m_r = m_r;
00623     m_r->m_l = m_l;
00624     m_l = m_r = this;
00625   }
00626 
00627   void freemem() throw ()
00628   {
00629     freepqmem(m_Obj);
00630   }
00631 };
00632 
00633 
00635 template<> inline void PQAlloc<PQXXPQ::PGresult>::freemem() throw ()
00636 {
00637   PQclear(m_Obj);
00638 }
00639 
00640 
00642 template<> inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw ()
00643 {
00644   freenotif(m_Obj);
00645 }
00646 
00647 
00648 class PQXX_LIBEXPORT namedclass
00649 {
00650 public:
00651   namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00652     m_Name(Name),
00653     m_Classname(Classname)
00654   {
00655   }
00656 
00657   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00658   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00659   PGSTD::string description() const;
00660 
00661 private:
00662   PGSTD::string m_Name, m_Classname;
00663 };
00664 
00665 
00666 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00667 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00668 
00669 
00671 
00674 template<typename GUEST>
00675 class unique
00676 {
00677 public:
00678   unique() : m_Guest(0) {}
00679 
00680   GUEST *get() const throw () { return m_Guest; }
00681 
00682   void Register(GUEST *G)
00683   {
00684     CheckUniqueRegistration(G, m_Guest);
00685     m_Guest = G;
00686   }
00687 
00688   void Unregister(GUEST *G)
00689   {
00690     CheckUniqueUnregistration(G, m_Guest);
00691     m_Guest = 0;
00692   }
00693 
00694 private:
00695   GUEST *m_Guest;
00696 
00698   unique(const unique &);
00700   unique &operator=(const unique &);
00701 };
00702 
00704 void sleep_seconds(int);
00705 
00706 } // namespace internal
00707 } // namespace pqxx
00708 

Generated on Mon Nov 1 19:13:36 2004 for libpqxx by  doxygen 1.3.9.1