Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | 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 
00020 #include <cstdio>
00021 #include <cctype>
00022 #include <stdexcept>
00023 #include <string>
00024 #include <typeinfo>
00025 
00026 extern "C"
00027 {
00028 #include "libpq-fe.h"
00029 }
00030 
00031 
00033 namespace pqxx
00034 {
00035 typedef long result_size_type;
00036 typedef int tuple_size_type;
00037 
00039 typedef Oid oid;
00040 
00042 const oid oid_none = InvalidOid;
00043 
00044 
00046 
00059 template<typename T> void error_unsupported_type_in_string_conversion(T);
00060 
00061 
00063 
00069 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00070 
00071 
00072 
00073 // TODO: Implement date conversions
00074 
00076 
00085 template<typename T> void from_string(const char Str[], T &Obj);
00086 
00087 template<> void from_string(const char Str[], long &);                  //[t45]
00088 template<> void from_string(const char Str[], unsigned long &);         //[t45]
00089 template<> void from_string(const char Str[], int &);                   //[t45]
00090 template<> void from_string(const char Str[], unsigned int &);          //[t45]
00091 template<> void from_string(const char Str[], short &);                 //[t45]
00092 template<> void from_string(const char Str[], unsigned short &);        //[t45]
00093 template<> void from_string(const char Str[], float &);                 //[t46]
00094 template<> void from_string(const char Str[], double &);                //[t46]
00095 template<> void from_string(const char Str[], long double &);           //[t46]
00096 template<> void from_string(const char Str[], bool &);                  //[t76]
00097 
00098 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46]
00099         { Obj = Str; }
00100 
00101 template<typename T> 
00102   inline void from_string(const PGSTD::string &Str, T &Obj)             //[t45]
00103         { from_string(Str.c_str(), Obj); }
00104 
00105 template<> inline void 
00106 from_string(const PGSTD::string &Str, PGSTD::string &Obj)               //[t46]
00107         { Obj = Str; }
00108 
00109 template<> inline void
00110 from_string(const PGSTD::string &, const signed char &Obj)
00111         { error_ambiguous_string_conversion(Obj); }
00112 template<> inline void
00113 from_string(const PGSTD::string &, const unsigned char &Obj)
00114         { error_ambiguous_string_conversion(Obj); }
00115 
00116 
00118 
00122 template<typename T> PGSTD::string to_string(const T &);
00123 
00124 template<> PGSTD::string to_string(const short &);                      //[t76]
00125 template<> PGSTD::string to_string(const unsigned short &);             //[t76]
00126 template<> PGSTD::string to_string(const int &);                        //[t10]
00127 template<> PGSTD::string to_string(const unsigned int &);               //[t13]
00128 template<> PGSTD::string to_string(const long &);                       //[t18]
00129 template<> PGSTD::string to_string(const unsigned long &);              //[t20]
00130 template<> PGSTD::string to_string(const float &);                      //[t74]
00131 template<> PGSTD::string to_string(const double &);                     //[t74]
00132 template<> PGSTD::string to_string(const long double &);                //[t74]
00133 template<> PGSTD::string to_string(const bool &);                       //[t76]
00134 
00135 inline PGSTD::string to_string(const char Obj[])                        //[t14]
00136         { return PGSTD::string(Obj); }
00137 
00138 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}  //[t21]
00139 
00140 template<> PGSTD::string to_string(const char &);                       //[t21]
00141 
00142 template<> inline PGSTD::string to_string(const signed char &Obj)
00143         { return error_ambiguous_string_conversion(Obj); }
00144 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00145         { return error_ambiguous_string_conversion(Obj); }
00146 
00147 
00148 
00150 
00155 namespace internal
00156 {
00158 
00166 template<typename T> inline const char *FmtString(T t)
00167 {
00168   error_unsupported_type_in_string_conversion(t);
00169   return 0;
00170 }
00171 
00172 template<> inline const char *FmtString(short)         { return "%hd"; }
00173 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00174 template<> inline const char *FmtString(int)           { return  "%i"; }
00175 template<> inline const char *FmtString(long)          { return "%li"; }
00176 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00177 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00178 template<> inline const char *FmtString(float)         { return  "%f"; }
00179 template<> inline const char *FmtString(double)        { return "%lf"; }
00180 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00181 template<> inline const char *FmtString(char)          { return  "%c"; }
00182 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00183 
00184 } // namespace internal
00185 
00187 
00195 template<typename T> inline PGSTD::string ToString(const T &Obj)
00196 {
00197   // TODO: Find a decent way to determine max string length at compile time!
00198   char Buf[500];
00199   sprintf(Buf, internal::FmtString(Obj), Obj);
00200   return PGSTD::string(Buf);
00201 }
00202 
00203 
00204 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00205 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00206 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00207 
00208 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00209 {
00210   return reinterpret_cast<const char *>(Obj);
00211 }
00212 
00213 template<> inline PGSTD::string ToString(const bool &Obj) 
00214 { 
00215   return ToString(unsigned(Obj));
00216 }
00217 
00218 template<> inline PGSTD::string ToString(const short &Obj)
00219 {
00220   return ToString(int(Obj));
00221 }
00222 
00223 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00224 {
00225   return ToString(unsigned(Obj));
00226 }
00227 
00228 
00230 
00238 template<typename T> inline void FromString(const char Str[], T &Obj)
00239 {
00240   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00241                                      PGSTD::string(typeid(T).name()));
00242 
00243   if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00244     throw PGSTD::runtime_error("Cannot convert value '" + 
00245                              PGSTD::string(Str) + 
00246                              "' to " + typeid(T).name());
00247 }
00248 
00249 
00250 namespace internal
00251 {
00253 
00255 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00256 
00258 
00260 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[], 
00261         const unsigned char *&Obj);
00262 
00264 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj, 
00265         bool EmptyIsNull);
00266 
00268 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00269 } // namespace internal
00270 
00271 
00272 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00273 {
00274   internal::FromString_string(Str, Obj);
00275 }
00276 
00277 template<> inline void FromString(const char Str[], const char *&Obj)
00278 {
00279   if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00280   Obj = Str;
00281 }
00282 
00283 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00284 {
00285   internal::FromString_ucharptr(Str, Obj);
00286 }
00287 
00288 template<> inline void FromString(const char Str[], bool &Obj)
00289 {
00290   from_string(Str, Obj);
00291 }
00292 
00293 
00295 
00304 PGSTD::string sqlesc(const char str[]);                                 //[t0]
00305 
00307 
00316 PGSTD::string sqlesc(const char str[], size_t maxlen);                  //[t0]
00317 
00319 
00325 PGSTD::string sqlesc(const PGSTD::string &);                            //[t0]
00326 
00327 
00329 
00333 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00334 
00335 
00337 
00339 template<> 
00340 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00341 {
00342   return internal::Quote_string(Obj, EmptyIsNull);
00343 }
00344 
00346 
00348 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00349 {
00350   return internal::Quote_charptr(Obj, EmptyIsNull);
00351 }
00352 
00353 
00355 
00360 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00361                                              bool EmptyIsNull)
00362 {
00363   return internal::Quote_charptr(Obj, EmptyIsNull);
00364 }
00365 
00366 
00371 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00372 {
00373   return Quote(ToString(Obj), EmptyIsNull);
00374 }
00375 
00376 
00378 
00381 template<typename T> inline PGSTD::string Quote(T Obj)
00382 {
00383   return Quote(Obj, false);
00384 }
00385 
00386 
00387 namespace internal
00388 {
00389 void freepqmem(void *);
00390 void freenotif(PGnotify *);
00391 
00393 
00399 template<typename T> class PQAlloc
00400 {
00401   T *m_Obj;
00402 public:
00403   typedef T content_type;
00404 
00405   PQAlloc() : m_Obj(0) {}
00406 
00408   explicit PQAlloc(T *obj) : m_Obj(obj) {}
00409 
00410   ~PQAlloc() throw () { close(); }
00411 
00413 
00415   PQAlloc &operator=(T *obj) throw ()
00416   { 
00417     if (obj != m_Obj)
00418     {
00419       close();
00420       m_Obj = obj;
00421     }
00422     return *this;
00423   }
00424 
00426   operator bool() const throw () { return m_Obj != 0; }
00427 
00429   bool operator!() const throw () { return !m_Obj; }
00430 
00432 
00434   T *operator->() const throw (PGSTD::logic_error)
00435   {
00436     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00437     return m_Obj;
00438   }
00439 
00441 
00443   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00444 
00446 
00448   T *c_ptr() const throw () { return m_Obj; }
00449 
00451   void close() throw () { if (m_Obj) freemem(); m_Obj = 0; }
00452 
00453 private:
00454   void freemem() throw ()
00455   {
00456     freepqmem(m_Obj);
00457   }
00458 
00459   PQAlloc(const PQAlloc &);             // Not allowed
00460   PQAlloc &operator=(const PQAlloc &);  // Not allowed
00461 };
00462 
00463 
00465 template<> inline void PQAlloc<PGnotify>::freemem() throw ()
00466 {
00467   freenotif(m_Obj);
00468 }
00469 
00470 
00471 class PQXX_LIBEXPORT namedclass
00472 {
00473 public:
00474   namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00475     m_Name(Name),
00476     m_Classname(Classname)
00477   {
00478   }
00479 
00480   const PGSTD::string &name() const throw () { return m_Name; }         //[t1]
00481   const PGSTD::string &classname() const throw () {return m_Classname;} //[t73]
00482   PGSTD::string description() const throw ();                           //[t73]
00483 
00484 private:
00485   PGSTD::string m_Name, m_Classname;
00486 };
00487 
00488 
00489 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00490 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00491 
00492 
00494 
00497 template<typename GUEST>
00498 class unique
00499 {
00500 public:
00501   unique() : m_Guest(0) {}
00502 
00503   GUEST *get() const throw () { return m_Guest; }
00504 
00505   void Register(GUEST *G)
00506   {
00507     CheckUniqueRegistration(G, m_Guest);
00508     m_Guest = G;
00509   }
00510 
00511   void Unregister(GUEST *G)
00512   {
00513     CheckUniqueUnregistration(G, m_Guest);
00514     m_Guest = 0;
00515   }
00516 
00517 private:
00518   GUEST *m_Guest;
00519 
00521   unique(const unique &);
00523   unique &operator=(const unique &);
00524 };
00525 
00526 } // namespace internal
00527 } // namespace pqxx
00528 

Generated on Mon May 10 13:19:10 2004 for libpqxx by doxygen 1.3.6-20040222