Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

util.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  *   FILE
00004  *      pqxx/util.h
00005  *
00006  *   DESCRIPTION
00007  *      Various utility definitions for libpqxx
00008  *
00009  * Copyright (c) 2001-2002, Jeroen T. Vermeulen <jtv@xs4all.nl>
00010  *
00011  *-------------------------------------------------------------------------
00012  */
00013 #ifndef PQXX_UTIL_H
00014 #define PQXX_UTIL_H
00015 
00016 #include "pqxx/compiler.h"
00017 
00018 #include <cstdio>
00019 #include <stdexcept>
00020 #include <string>
00021 #include <typeinfo>
00022 
00023 extern "C"
00024 {
00025 #include "libpq-fe.h"
00026 }
00027 
00028 
00029 namespace pqxx
00030 {
00031 typedef long Result_size_type;
00032 typedef int Tuple_size_type;
00033 
00036 template<typename T> inline const char *FmtString(T);
00037 
00038 // Not implemented to prevent accidents with irregular meaning of argument:
00039 // template<> inline const char *FmtString(const char *&) { return "%s"; }
00040 
00041 template<> inline const char *FmtString(int)           { return  "%i"; }
00042 template<> inline const char *FmtString(long)          { return "%li"; }
00043 template<> inline const char *FmtString(unsigned)      { return  "%u"; }
00044 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00045 template<> inline const char *FmtString(float)         { return  "%f"; }
00046 template<> inline const char *FmtString(double)        { return "%lf"; }
00047 template<> inline const char *FmtString(char)          { return  "%c"; }
00048 template<> inline const char *FmtString(unsigned char) { return  "%c"; }
00049 
00050 
00052 template<typename T> inline PGSTD::string ToString(const T &Obj)
00053 {
00054   // TODO: Find a decent way to determine max string length at compile time!
00055   char Buf[500];
00056   sprintf(Buf, FmtString(Obj), Obj);
00057   return PGSTD::string(Buf);
00058 }
00059 
00060 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00061 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00062 
00063 template<> inline PGSTD::string ToString(const bool &Obj) 
00064 { 
00065   return ToString(unsigned(Obj));
00066 }
00067 
00068 template<> inline PGSTD::string ToString(const short &Obj)
00069 {
00070   return ToString(int(Obj));
00071 }
00072 
00073 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00074 {
00075   return ToString(unsigned(Obj));
00076 }
00077 
00078 
00079 template<typename T> inline void FromString(const char Str[], T &Obj)
00080 {
00081   if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00082                                      PGSTD::string(typeid(T).name()));
00083 
00084   if (sscanf(Str, FmtString(Obj), &Obj) != 1)
00085     throw PGSTD::runtime_error("Cannot convert value '" + 
00086                              PGSTD::string(Str) + 
00087                              "' to " + typeid(T).name());
00088 }
00089 
00090 
00091 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00092 {
00093   if (!Str) 
00094     throw PGSTD::runtime_error("Attempt to convert NULL C string to C++ string");
00095   Obj = Str;
00096 }
00097 
00098 
00099 template<> inline void FromString(const char Str[], const char *&Obj)
00100 {
00101   if (!Str)
00102     throw PGSTD::runtime_error("Attempt to read NULL string");
00103   Obj = Str;
00104 }
00105 
00106 template<> inline void FromString(const char Str[], bool &Obj)
00107 {
00108   if (!Str)
00109     throw PGSTD::runtime_error("Attempt to read NULL string");
00110 
00111   switch (Str[0])
00112   {
00113   case 0:
00114   case 'f':
00115     Obj = false;
00116     break;
00117   case '0':
00118     {
00119       int I;
00120       FromString(Str, I);
00121       Obj = (I != 0);
00122     }
00123     break;
00124   default:
00125     Obj = true;
00126   }
00127 }
00128 
00129 
00132 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull=false);
00133 
00134 
00136 template<> inline PGSTD::string Quote(const PGSTD::string &Obj, 
00137                                       bool EmptyIsNull)
00138 {
00139   if (EmptyIsNull && Obj.empty()) return "null";
00140 
00141   PGSTD::string Result = "'";
00142 
00143 #ifdef HAVE_PQESCAPESTRING
00144 
00145   char *const Buf = new char[2*Obj.size() + 1];
00146   try
00147   {
00148     PQescapeString(Buf, Obj.c_str(), Obj.size());
00149     Result += Buf;
00150   }
00151   catch (const PGSTD::exception &)
00152   {
00153     delete [] Buf;
00154     throw;
00155   }
00156   delete [] Buf;
00157 
00158 #else
00159 
00160   for (PGSTD::string::size_type i=0; i < Obj.size(); ++i)
00161   {
00162     if (isgraph(Obj[i]))
00163     {
00164       switch (Obj[i])
00165       {
00166       case '\'':
00167       case '\\':
00168         Result += '\\';
00169       }
00170       Result += Obj[i];
00171     }
00172     else
00173     {
00174         char s[5];
00175         snprintf(s, 5, "\\%03hho", Obj[i]);
00176         Result.append(s, 4);
00177     }
00178   }
00179 
00180 #endif
00181 
00182   return Result + '\'';
00183 }
00184 
00185 
00188 template<> inline PGSTD::string Quote(const char *const & Obj, 
00189                                       bool EmptyIsNull)
00190 {
00191   if (!Obj) return "null";
00192   return Quote(PGSTD::string(Obj), EmptyIsNull);
00193 }
00194 
00195 
00199 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00200 {
00201   return Quote(ToString(Obj), EmptyIsNull);
00202 }
00203 
00204 
00205 
00207 template<typename T> PGSTD::string Classname(const T *);
00208 
00209 
00215 template<typename GUEST>
00216 class Unique
00217 {
00218 public:
00219   Unique() : m_Guest(0) {}
00220 
00221   const GUEST *get() const throw () { return m_Guest; }
00222 
00223   void Register(const GUEST *G)
00224   {
00225     if (!G) throw PGSTD::logic_error("Internal libpqxx error: NULL " + 
00226                                      Classname(G));
00227     
00228     if (m_Guest)
00229     {
00230       if (G == m_Guest)
00231         throw PGSTD::logic_error(Classname(G) +
00232                                  " '" +
00233                                  G->Name() +
00234                                  "' started more than once without closing");
00235 
00236       throw PGSTD::logic_error("Started " + 
00237                                Classname(G) +
00238                                " '" + 
00239                                G->Name() + 
00240                                "' while '" +
00241                                m_Guest->Name() +
00242                                "' was still active");
00243     }
00244     
00245     m_Guest = G;
00246   }
00247 
00248   void Unregister(const GUEST *G)
00249   {
00250     if (G != m_Guest)
00251     {
00252       if (!G) 
00253         throw PGSTD::logic_error("Closing NULL " + Classname(G));
00254       else if (!m_Guest)
00255         throw PGSTD::logic_error("Closing " + 
00256                                  Classname(G) +
00257                                  " '" +
00258                                  G->Name() +
00259                                  "' which wasn't open");
00260       else
00261         throw PGSTD::logic_error("Closing wrong " + 
00262                                  Classname(G) +
00263                                  "; expected '" +
00264                                  m_Guest->Name() +
00265                                  "' but got '" +
00266                                  G->Name() +
00267                                  "'");
00268     }
00269 
00270     m_Guest = 0;
00271   }
00272 
00273 private:
00274   const GUEST *m_Guest;
00275 
00276   // Not allowed:
00277   Unique(const Unique &);
00278   Unique &operator=(const Unique &);
00279 };
00280 
00281 
00282 const Result_size_type Result_size_type_min =
00283   PGSTD::numeric_limits<Result_size_type>::min();
00284 const Result_size_type Result_size_type_max =
00285   PGSTD::numeric_limits<Result_size_type>::max();
00286 
00287 }
00288 
00289 #endif
00290 

Generated on Mon Dec 9 01:51:45 2002 for libpqxx by doxygen1.3-rc1