00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
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 
00029 
00031 
namespace pqxx
00032 {
00033 
namespace internal
00034 {
00035 namespace pq
00036 {
00037 
extern "C"
00038 {
00039 
#include "libpq-fe.h"
00040 }
00041 } 
00042 } 
00043 
00044 typedef long result_size_type;
00045 typedef int tuple_size_type;
00046 
00048 typedef internal::pq::Oid 
oid;
00049 
00051 const oid oid_none = 0;
00052 
00053 
00055 
00068 
template<
typename T> 
void error_unsupported_type_in_string_conversion(T);
00069 
00070 
00072 
00078 
template<
typename T> PGSTD::string 
error_ambiguous_string_conversion(T);
00079 
00080 
00081 
00082 
00083 
00085 
00094 
template<
typename T> 
void from_string(
const char Str[], T &Obj);
00095 
00096 
template<> 
void from_string(
const char Str[], 
long &);                  
00097 
template<> 
void from_string(
const char Str[], 
unsigned long &);         
00098 
template<> 
void from_string(
const char Str[], 
int &);                   
00099 
template<> 
void from_string(
const char Str[], 
unsigned int &);          
00100 
template<> 
void from_string(
const char Str[], 
short &);                 
00101 
template<> 
void from_string(
const char Str[], 
unsigned short &);        
00102 
template<> 
void from_string(
const char Str[], 
float &);                 
00103 
template<> 
void from_string(
const char Str[], 
double &);                
00104 
template<> 
void from_string(
const char Str[], 
long double &);           
00105 
template<> 
void from_string(
const char Str[], 
bool &);                  
00106 
00107 template<> 
inline void from_string(
const char Str[],PGSTD::string &Obj) 
00108         { Obj = Str; }
00109 
00110 
template<> 
00111   inline void from_string(
const char Str[], PGSTD::stringstream &Obj)   
00112         { Obj.clear(); Obj << Str; }
00113 
00114 
template<
typename T> 
00115   inline void from_string(
const PGSTD::string &Str, T &Obj)             
00116         { 
from_string(Str.c_str(), Obj); }
00117 
00118 
template<
typename T>
00119   inline void from_string(
const PGSTD::stringstream &Str, T &Obj)       
00120         { 
from_string(Str.str(), Obj); }
00121 
00122 
template<> 
inline void 
00123 from_string(
const PGSTD::string &Str, PGSTD::string &Obj)               
00124         { Obj = Str; }
00125 
00126 
template<> 
inline void
00127 from_string(
const PGSTD::string &, 
const char &Obj)
00128         { 
error_ambiguous_string_conversion(Obj); }
00129 
template<> 
inline void
00130 from_string(
const PGSTD::string &, 
const signed char &Obj)
00131         { 
error_ambiguous_string_conversion(Obj); }
00132 
template<> 
inline void
00133 from_string(
const PGSTD::string &, 
const unsigned char &Obj)
00134         { 
error_ambiguous_string_conversion(Obj); }
00135 
00136 
00138 
00142 
template<
typename T> PGSTD::string 
to_string(
const T &);
00143 
00144 
template<> PGSTD::string 
to_string(
const short &);                      
00145 
template<> PGSTD::string 
to_string(
const unsigned short &);             
00146 
template<> PGSTD::string 
to_string(
const int &);                        
00147 
template<> PGSTD::string 
to_string(
const unsigned int &);               
00148 
template<> PGSTD::string 
to_string(
const long &);                       
00149 
template<> PGSTD::string 
to_string(
const unsigned long &);              
00150 
template<> PGSTD::string 
to_string(
const float &);                      
00151 
template<> PGSTD::string 
to_string(
const double &);                     
00152 
template<> PGSTD::string 
to_string(
const long double &);                
00153 
template<> PGSTD::string 
to_string(
const bool &);                       
00154 
00155 inline PGSTD::string 
to_string(
const char Obj[])                        
00156         { 
return PGSTD::string(Obj); }
00157 
00158 inline PGSTD::string 
to_string(
const PGSTD::stringstream &Obj)          
00159         { 
return Obj.str(); }
00160 
00161 inline PGSTD::string 
to_string(
const PGSTD::string &Obj) {
return Obj;}  
00162 
00163 
template<> PGSTD::string 
to_string(
const char &);                       
00164 
00165 
00166 template<> 
inline PGSTD::string 
to_string(
const signed char &Obj)
00167         { 
return error_ambiguous_string_conversion(Obj); }
00168 template<> 
inline PGSTD::string 
to_string(
const unsigned char &Obj)
00169         { 
return error_ambiguous_string_conversion(Obj); }
00170 
00171 
00173 
00187 
template<
typename T=PGSTD::string, 
typename CONT=PGSTD::vector<T> >
00188 class items : 
public CONT
00189 {
00190 
public:
00192   items() : CONT() {}                                                   
00194   explicit items(
const T &t) : CONT() { push_back(t); }                 
00195   items(
const T &t1, 
const T &t2) : CONT()                              
00196         { push_back(t1); push_back(t2); }
00197   items(
const T &t1, 
const T &t2, 
const T &t3) : CONT()                 
00198         { push_back(t1); push_back(t2); push_back(t3); }
00199   items(
const T &t1, 
const T &t2, 
const T &t3, 
const T &t4) : CONT()    
00200         { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00201   items(
const T&t1,
const T&t2,
const T&t3,
const T&t4,
const T&t5):CONT()  
00202         {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00204   items(
const CONT &c) : CONT(c) {}                                     
00205 
00207   items &
operator()(
const T &t)                                         
00208   {
00209     push_back(t);
00210     
return *
this;
00211   }
00212 };
00213 
00214 
00215 
00217 
template<
typename ITER> 
inline
00218 PGSTD::string 
separated_list(
const PGSTD::string &sep,
00219     ITER begin,
00220     ITER end)                                                           
00221 {
00222   PGSTD::string 
result;
00223   
if (begin != end)
00224   {
00225     result = 
to_string(*begin);
00226     
for (++begin; begin != end; ++begin)
00227     {
00228       result += sep;
00229       result += 
to_string(*begin);
00230     }
00231   }
00232   
return result;
00233 }
00234 
00236 
template<
typename CONTAINER> 
inline
00237 PGSTD::string 
separated_list(
const PGSTD::string &sep,
00238     
const CONTAINER &c)                                                 
00239 {
00240   
return separated_list(sep, c.begin(), c.end());
00241 }
00242 
00243 
00245 
00250 
namespace internal
00251 {
00253 
00261 template<
typename T> 
inline const char *
FmtString(T t)
00262 {
00263   
error_unsupported_type_in_string_conversion(t);
00264   
return 0;
00265 }
00266 
00267 template<> 
inline const char *
FmtString(
short)         { 
return "%hd"; }
00268 template<> 
inline const char *
FmtString(
unsigned short){ 
return "%hu"; }
00269 template<> 
inline const char *
FmtString(
int)           { 
return  "%i"; }
00270 template<> 
inline const char *
FmtString(
long)          { 
return "%li"; }
00271 
template<> 
inline const char *
FmtString(
unsigned)      { 
return  "%u"; }
00272 
template<> 
inline const char *
FmtString(
unsigned long) { 
return "%lu"; }
00273 template<> 
inline const char *
FmtString(
float)         { 
return  "%f"; }
00274 template<> 
inline const char *
FmtString(
double)        { 
return "%lf"; }
00275 
template<> 
inline const char *
FmtString(
long double)   { 
return "%Lf"; }
00276 template<> 
inline const char *
FmtString(
char)          { 
return  "%c"; }
00277 
template<> 
inline const char *
FmtString(
unsigned char) { 
return  "%c"; }
00278 
00279 } 
00280 
00282 
00290 template<
typename T> 
inline PGSTD::string 
ToString(
const T &Obj)
00291 {
00292   
00293   
char Buf[500];
00294   sprintf(Buf, internal::FmtString(Obj), Obj);
00295   
return PGSTD::string(Buf);
00296 }
00297 
00298 
00299 template<> 
inline PGSTD::string 
ToString(
const PGSTD::string &Obj) {
return Obj;}
00300 template<> 
inline PGSTD::string 
ToString(
const char *
const &Obj) { 
return Obj; }
00301 template<> 
inline PGSTD::string 
ToString(
char *
const &Obj) { 
return Obj; }
00302 
00303 template<> 
inline PGSTD::string 
ToString(
const unsigned char *
const &Obj)
00304 {
00305   
return reinterpret_cast<const char *>(Obj);
00306 }
00307 
00308 template<> 
inline PGSTD::string 
ToString(
const bool &Obj) 
00309 { 
00310   
return ToString(
unsigned(Obj));
00311 }
00312 
00313 template<> 
inline PGSTD::string 
ToString(
const short &Obj)
00314 {
00315   
return ToString(
int(Obj));
00316 }
00317 
00318 template<> 
inline PGSTD::string 
ToString(
const unsigned short &Obj)
00319 {
00320   
return ToString(
unsigned(Obj));
00321 }
00322 
00323 
00325 
00333 template<
typename T> 
inline void FromString(
const char Str[], T &Obj)
00334 {
00335   
if (!Str) 
throw PGSTD::runtime_error(
"Attempt to convert NULL string to " +
00336                                      PGSTD::string(
typeid(T).name()));
00337 
00338   
if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00339     
throw PGSTD::runtime_error(
"Cannot convert value '" + 
00340                              PGSTD::string(Str) + 
00341                              
"' to " + 
typeid(T).name());
00342 }
00343 
00344 
00345 
namespace internal
00346 {
00348 
00350 
void PQXX_LIBEXPORT 
FromString_string(
const char Str[], PGSTD::string &Obj);
00351 
00353 
00355 
void PQXX_LIBEXPORT 
FromString_ucharptr(
const char Str[], 
00356         
const unsigned char *&Obj);
00357 
00359 PGSTD::string PQXX_LIBEXPORT 
Quote_string(
const PGSTD::string &Obj, 
00360         
bool EmptyIsNull);
00361 
00363 PGSTD::string PQXX_LIBEXPORT 
Quote_charptr(
const char Obj[], 
bool EmptyIsNull);
00364 } 
00365 
00366 
00367 template<> 
inline void FromString(
const char Str[], PGSTD::string &Obj)
00368 {
00369   
internal::FromString_string(Str, Obj);
00370 }
00371 
00372 template<> 
inline void FromString(
const char Str[], 
const char *&Obj)
00373 {
00374   
if (!Str) 
throw PGSTD::runtime_error(
"Attempt to read NULL string");
00375   Obj = Str;
00376 }
00377 
00378 template<> 
inline void FromString(
const char Str[], 
const unsigned char *&Obj)
00379 {
00380   
internal::FromString_ucharptr(Str, Obj);
00381 }
00382 
00383 template<> 
inline void FromString(
const char Str[], 
bool &Obj)
00384 {
00385   
from_string(Str, Obj);
00386 }
00387 
00388 
00390 
00399 PGSTD::string 
sqlesc(
const char str[]);                                 
00400 
00402 
00412 PGSTD::string 
sqlesc(
const char str[], size_t maxlen);                  
00413 
00415 
00421 PGSTD::string 
sqlesc(
const PGSTD::string &);                            
00422 
00423 
00425 
00429 
template<
typename T> PGSTD::string 
Quote(
const T &Obj, 
bool EmptyIsNull);
00430 
00431 
00433 
00435 
template<> 
00436 inline PGSTD::string 
Quote(
const PGSTD::string &Obj, 
bool EmptyIsNull)
00437 {
00438   
return internal::Quote_string(Obj, EmptyIsNull);
00439 }
00440 
00442 
00444 template<> 
inline PGSTD::string 
Quote(
const char *
const & Obj, 
bool EmptyIsNull)
00445 {
00446   
return internal::Quote_charptr(Obj, EmptyIsNull);
00447 }
00448 
00449 
00451 
00456 template<
int LEN> 
inline PGSTD::string 
Quote(
const char (&Obj)[LEN],
00457                                              
bool EmptyIsNull)
00458 {
00459   
return internal::Quote_charptr(Obj, EmptyIsNull);
00460 }
00461 
00462 
00463 template<
typename T> 
inline PGSTD::string 
Quote(
const T &Obj, 
bool EmptyIsNull)
00464 {
00465   
return Quote(
ToString(Obj), EmptyIsNull);
00466 }
00467 
00468 
00470 
00473 template<
typename T> 
inline PGSTD::string 
Quote(T Obj)
00474 {
00475   
return Quote(Obj, 
false);
00476 }
00477 
00478 
00479 
namespace internal
00480 {
00481 
void freepqmem(
void *);
00482 
void freenotif(internal::pq::PGnotify *);
00483 
00485 
00491 template<
typename T> 
class PQAlloc
00492 {
00493   T *m_Obj;
00494 
public:
00495   typedef T 
content_type;
00496 
00497   PQAlloc() : m_Obj(0) {}
00498 
00500   explicit PQAlloc(T *obj) : m_Obj(obj) {}
00501 
00502   ~PQAlloc() throw () { 
close(); }
00503 
00505 
00507   PQAlloc &
operator=(T *obj) 
throw ()
00508   { 
00509     
if (obj != m_Obj)
00510     {
00511       
close();
00512       m_Obj = obj;
00513     }
00514     
return *
this;
00515   }
00516 
00518   operator bool() const throw () { 
return m_Obj != 0; }
00519 
00521   bool operator!() const throw () { 
return !m_Obj; }
00522 
00524 
00526   T *
operator->() const throw (PGSTD::logic_error)
00527   {
00528     
if (!m_Obj) 
throw PGSTD::logic_error(
"Null pointer dereferenced");
00529     
return m_Obj;
00530   }
00531 
00533 
00535   T &
operator*() const throw (PGSTD::logic_error) { 
return *
operator->(); }
00536 
00538 
00540   T *
c_ptr() const throw () { 
return m_Obj; }
00541 
00543   void close() throw () { 
if (m_Obj) freemem(); m_Obj = 0; }
00544 
00545 
private:
00546   
void freemem() throw ()
00547   {
00548     
freepqmem(m_Obj);
00549   }
00550 
00551   
PQAlloc(
const PQAlloc &);             
00552   PQAlloc &
operator=(
const PQAlloc &);  
00553 };
00554 
00555 
00557 template<> 
inline void PQAlloc<internal::pq::PGnotify>::freemem() throw ()
00558 {
00559   
freenotif(m_Obj);
00560 }
00561 
00562 
00563 class PQXX_LIBEXPORT namedclass
00564 {
00565 
public:
00566   namedclass(
const PGSTD::string &Name, 
const PGSTD::string &Classname) :
00567     m_Name(Name),
00568     m_Classname(Classname)
00569   {
00570   }
00571 
00572   const PGSTD::string &name() const throw () { 
return m_Name; }         
00573   const PGSTD::string &classname() const throw () {
return m_Classname;} 
00574   PGSTD::string description() const throw ();                           
00575 
00576 private:
00577   PGSTD::string m_Name, m_Classname;
00578 };
00579 
00580 
00581 
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00582 
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00583 
00584 
00586 
00589 template<typename GUEST>
00590 class 
unique
00591 {
00592 
public:
00593   unique() : m_Guest(0) {}
00594 
00595   GUEST *get() const throw () { 
return m_Guest; }
00596 
00597   void Register(GUEST *G)
00598   {
00599     
CheckUniqueRegistration(G, m_Guest);
00600     m_Guest = G;
00601   }
00602 
00603   void Unregister(GUEST *G)
00604   {
00605     
CheckUniqueUnregistration(G, m_Guest);
00606     m_Guest = 0;
00607   }
00608 
00609 
private:
00610   GUEST *m_Guest;
00611 
00613   unique(
const unique &);
00615   unique &operator=(
const unique &);
00616 };
00617 
00618 } 
00619 } 
00620