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-2003, 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 
00032 namespace pqxx
00033 {
00034 typedef long result_size_type;
00035 typedef int tuple_size_type;
00036 
00038 typedef Oid oid;
00039 
00041 const oid oid_none = InvalidOid;
00042 
00043 
00045 
00058 template<typename T> void error_unsupported_type_in_string_conversion(T);
00059 
00060 
00062 
00068 template<typename T> inline const char *FmtString(T t)
00069 {
00070   error_unsupported_type_in_string_conversion(t);
00071   return 0;
00072 }
00073 
00074 // Not implemented to prevent accidents with irregular meaning of argument:
00075 // template<> inline const char *FmtString(const char *&) { return "%s"; }
00076 
00077 template<> inline const char *FmtString(short)         { return "%hd"; }
00078 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00079 template<> inline const char *FmtString(int)           { return  "%i"; }
00080 template<> inline const char *FmtString(long)          { return "%li"; }
00081 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00082 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00083 template<> inline const char *FmtString(float)         { return  "%f"; }
00084 template<> inline const char *FmtString(double)        { return "%lf"; }
00085 template<> inline const char *FmtString(long double)   { return "%Lf"; }
00086 template<> inline const char *FmtString(char)          { return  "%c"; }
00087 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00088 
00089 
00091 
00098 template<typename T> inline PGSTD::string ToString(const T &Obj)
00099 {
00100   // TODO: Find a decent way to determine max string length at compile time!
00101   char Buf[500];
00102   sprintf(Buf, FmtString(Obj), Obj);
00103   return PGSTD::string(Buf);
00104 }
00105 
00106 // TODO: Implement date conversions
00107 
00108 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00109 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00110 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00111 
00112 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00113 {
00114   return reinterpret_cast<const char *>(Obj);
00115 }
00116 
00117 template<> inline PGSTD::string ToString(const bool &Obj) 
00118 { 
00119   return ToString(unsigned(Obj));
00120 }
00121 
00122 template<> inline PGSTD::string ToString(const short &Obj)
00123 {
00124   return ToString(int(Obj));
00125 }
00126 
00127 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00128 {
00129   return ToString(unsigned(Obj));
00130 }
00131 
00132 
00134 
00141 template<typename T> inline void FromString(const char Str[], T &Obj)
00142 {
00143   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00144                                      PGSTD::string(typeid(T).name()));
00145 
00146   if (sscanf(Str, FmtString(Obj), &Obj) != 1)
00147     throw PGSTD::runtime_error("Cannot convert value '" + 
00148                              PGSTD::string(Str) + 
00149                              "' to " + typeid(T).name());
00150 }
00151 
00152 
00154 void FromString_string(const char Str[], PGSTD::string &Obj);
00155 
00156 
00157 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00158 {
00159   FromString_string(Str, Obj);
00160 }
00161 
00162 
00163 template<> inline void FromString(const char Str[], const char *&Obj)
00164 {
00165   if (!Str)
00166     throw PGSTD::runtime_error("Attempt to read NULL string");
00167   Obj = Str;
00168 }
00169 
00170 
00171 void FromString_ucharptr(const char Str[], const unsigned char *&Obj);
00172 
00173 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00174 {
00175   FromString_ucharptr(Str, Obj);
00176 }
00177 
00178 
00180 void FromString_bool(const char Str[], bool &Obj);
00181 
00182 template<> inline void FromString(const char Str[], bool &Obj)
00183 {
00184   FromString_bool(Str, Obj);
00185 }
00186 
00187 
00189 
00192 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00193 
00194 
00196 PGSTD::string Quote_string(const PGSTD::string &Obj, bool EmptyIsNull);
00197 
00198 
00200 template<> 
00201 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00202 {
00203   return Quote_string(Obj, EmptyIsNull);
00204 }
00205 
00207 PGSTD::string Quote_charptr(const char Obj[], bool EmptyIsNull);
00208 
00209 
00211 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00212 {
00213   return Quote_charptr(Obj, EmptyIsNull);
00214 }
00215 
00216 
00218 
00223 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00224                                              bool EmptyIsNull)          //[t18]
00225 {
00226   return Quote_charptr(Obj, EmptyIsNull);
00227 }
00228 
00229 
00233 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00234 {
00235   return Quote(ToString(Obj), EmptyIsNull);
00236 }
00237 
00238 
00240 
00242 template<typename T> inline PGSTD::string Quote(T Obj)
00243 {
00244   return Quote(Obj, false);
00245 }
00246 
00247 
00249 template<typename T> PGSTD::string Classname(const T *);
00250 
00251 
00253 
00259 template<typename T> class PQAlloc
00260 {
00261   T *m_Obj;
00262 public:
00263   PQAlloc() : m_Obj(0) {}
00264 
00266   explicit PQAlloc(T *obj) : m_Obj(obj) {}
00267 
00268   ~PQAlloc() { close(); }
00269 
00271 
00273   PQAlloc &operator=(T *obj) throw ()
00274   { 
00275     if (obj != m_Obj)
00276     {
00277       close();
00278       m_Obj = obj;
00279     }
00280     return *this;
00281   }
00282 
00284   operator bool() const throw () { return m_Obj != 0; }
00285 
00287   bool operator!() const throw () { return !m_Obj; }
00288 
00290 
00292   T *operator->() const throw (PGSTD::logic_error)
00293   {
00294     if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00295     return m_Obj;
00296   }
00297 
00299 
00301   T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00302 
00304 
00306   T *c_ptr() const throw () { return m_Obj; }
00307 
00309   void close() throw () { if (m_Obj) freemem(); m_Obj = 0; }
00310 
00311 private:
00312   void freemem() throw ()
00313   {
00314 #if defined(PQXX_HAVE_PQFREEMEM)
00315     PQfreemem(reinterpret_cast<unsigned char *>(m_Obj));
00316 #else
00317     free(m_Obj);
00318 #endif
00319   }
00320 
00321   PQAlloc(const PQAlloc &);             // Not allowed
00322   PQAlloc &operator=(const PQAlloc &);  // Not allowed
00323 };
00324 
00325 
00327 template<> inline void PQAlloc<PGnotify>::freemem() throw ()
00328 {
00329 #if defined(PQXX_HAVE_PQFREEMEM)
00330     PQfreemem(reinterpret_cast<unsigned char *>(m_Obj));
00331 #elif defined(PQXX_HAVE_PQFREENOTIFY)
00332     PQfreeNotify(m_Obj);
00333 #else
00334     free(m_Obj);
00335 #endif
00336 }
00337 
00338 
00340 PGSTD::string UniqueRegisterError(const void *New,
00341                                   const void *Old,
00342                                   const PGSTD::string &ClassName,
00343                                   const PGSTD::string &NewName);
00344 
00346 PGSTD::string UniqueUnregisterError(const void *New,
00347                                     const void *Old,
00348                                     const PGSTD::string &ClassName,
00349                                     const PGSTD::string &NewName,
00350                                     const PGSTD::string &OldName);
00351 
00352 
00354 
00361 template<typename GUEST>
00362 class unique
00363 {
00364 public:
00365   unique() : m_Guest(0) {}
00366 
00367   GUEST *get() const throw () { return m_Guest; }
00368 
00369   void Register(GUEST *G)
00370   {
00371     if (!G || m_Guest)
00372       throw PGSTD::logic_error(UniqueRegisterError(G,
00373             m_Guest,
00374             Classname(G),
00375             (G ? G->name() : "")));
00376 
00377     m_Guest = G;
00378   }
00379 
00380   void Unregister(GUEST *G)
00381   {
00382     if (G != m_Guest)
00383       throw PGSTD::logic_error(UniqueUnregisterError(G, 
00384           m_Guest,
00385           Classname(G),
00386           (G ? G->name() : ""),
00387           (m_Guest ? m_Guest->name() : "")));
00388 
00389     m_Guest = 0;
00390   }
00391 
00392 private:
00393   GUEST *m_Guest;
00394 
00395   // Not allowed:
00396   unique(const unique &);
00397   unique &operator=(const unique &);
00398 };
00399 
00400 }
00401 
00402 

Generated on Fri Nov 14 19:37:18 2003 for libpqxx by doxygen 1.3.4