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 <sstream> 00023 #include <stdexcept> 00024 #include <string> 00025 #include <typeinfo> 00026 #include <vector> 00027 00028 extern "C" 00029 { 00030 #include "libpq-fe.h" 00031 } 00032 00033 00035 namespace pqxx 00036 { 00037 typedef long result_size_type; 00038 typedef int tuple_size_type; 00039 00041 typedef Oid oid; 00042 00044 const oid oid_none = InvalidOid; 00045 00046 00048 00061 template<typename T> void error_unsupported_type_in_string_conversion(T); 00062 00063 00065 00071 template<typename T> PGSTD::string error_ambiguous_string_conversion(T); 00072 00073 00074 00075 // TODO: Implement date conversions 00076 00078 00087 template<typename T> void from_string(const char Str[], T &Obj); 00088 00089 template<> void from_string(const char Str[], long &); //[t45] 00090 template<> void from_string(const char Str[], unsigned long &); //[t45] 00091 template<> void from_string(const char Str[], int &); //[t45] 00092 template<> void from_string(const char Str[], unsigned int &); //[t45] 00093 template<> void from_string(const char Str[], short &); //[t45] 00094 template<> void from_string(const char Str[], unsigned short &); //[t45] 00095 template<> void from_string(const char Str[], float &); //[t46] 00096 template<> void from_string(const char Str[], double &); //[t46] 00097 template<> void from_string(const char Str[], long double &); //[t46] 00098 template<> void from_string(const char Str[], bool &); //[t76] 00099 00100 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46] 00101 { Obj = Str; } 00102 00103 template<> 00104 inline void from_string(const char Str[], PGSTD::stringstream &Obj) //[t0] 00105 { Obj.clear(); Obj << Str; } 00106 00107 template<typename T> 00108 inline void from_string(const PGSTD::string &Str, T &Obj) //[t45] 00109 { from_string(Str.c_str(), Obj); } 00110 00111 template<typename T> 00112 inline void from_string(const PGSTD::stringstream &Str, T &Obj) //[t0] 00113 { from_string(Str.str(), Obj); } 00114 00115 template<> inline void 00116 from_string(const PGSTD::string &Str, PGSTD::string &Obj) //[t46] 00117 { Obj = Str; } 00118 00119 template<> inline void 00120 from_string(const PGSTD::string &, const signed char &Obj) 00121 { error_ambiguous_string_conversion(Obj); } 00122 template<> inline void 00123 from_string(const PGSTD::string &, const unsigned char &Obj) 00124 { error_ambiguous_string_conversion(Obj); } 00125 00126 00128 00132 template<typename T> PGSTD::string to_string(const T &); 00133 00134 template<> PGSTD::string to_string(const short &); //[t76] 00135 template<> PGSTD::string to_string(const unsigned short &); //[t76] 00136 template<> PGSTD::string to_string(const int &); //[t10] 00137 template<> PGSTD::string to_string(const unsigned int &); //[t13] 00138 template<> PGSTD::string to_string(const long &); //[t18] 00139 template<> PGSTD::string to_string(const unsigned long &); //[t20] 00140 template<> PGSTD::string to_string(const float &); //[t74] 00141 template<> PGSTD::string to_string(const double &); //[t74] 00142 template<> PGSTD::string to_string(const long double &); //[t74] 00143 template<> PGSTD::string to_string(const bool &); //[t76] 00144 00145 inline PGSTD::string to_string(const char Obj[]) //[t14] 00146 { return PGSTD::string(Obj); } 00147 00148 inline PGSTD::string to_string(const PGSTD::stringstream &Obj) //[t0] 00149 { return Obj.str(); } 00150 00151 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;} //[t21] 00152 00153 template<> PGSTD::string to_string(const char &); //[t21] 00154 00155 00156 template<> inline PGSTD::string to_string(const signed char &Obj) 00157 { return error_ambiguous_string_conversion(Obj); } 00158 template<> inline PGSTD::string to_string(const unsigned char &Obj) 00159 { return error_ambiguous_string_conversion(Obj); } 00160 00161 00163 00177 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> > 00178 class items : public CONT 00179 { 00180 public: 00182 items() : CONT() {} //[] 00184 explicit items(const T &t) : CONT() { push_back(t); } //[] 00185 items(const T &t1, const T &t2) : CONT() //[t80] 00186 { push_back(t1); push_back(t2); } 00187 items(const T &t1, const T &t2, const T &t3) : CONT() //[] 00188 { push_back(t1); push_back(t2); push_back(t3); } 00189 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT() //[] 00190 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); } 00191 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT() //[] 00192 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);} 00194 items(const CONT &c) : CONT(c) {} //[] 00195 00197 items &operator()(const T &t) //[] 00198 { 00199 push_back(t); 00200 return *this; 00201 } 00202 }; 00203 00204 00205 // TODO: Generalize--add transformation functor 00207 template<typename ITER> inline 00208 PGSTD::string separated_list(const PGSTD::string &sep, 00209 ITER begin, 00210 ITER end) //[t8] 00211 { 00212 PGSTD::string result; 00213 if (begin != end) 00214 { 00215 result = to_string(*begin); 00216 for (++begin; begin != end; ++begin) 00217 { 00218 result += sep; 00219 result += to_string(*begin); 00220 } 00221 } 00222 return result; 00223 } 00224 00226 template<typename CONTAINER> inline 00227 PGSTD::string separated_list(const PGSTD::string &sep, 00228 const CONTAINER &c) //[t10] 00229 { 00230 return separated_list(sep, c.begin(), c.end()); 00231 } 00232 00233 00235 00240 namespace internal 00241 { 00243 00251 template<typename T> inline const char *FmtString(T t) 00252 { 00253 error_unsupported_type_in_string_conversion(t); 00254 return 0; 00255 } 00256 00257 template<> inline const char *FmtString(short) { return "%hd"; } 00258 template<> inline const char *FmtString(unsigned short){ return "%hu"; } 00259 template<> inline const char *FmtString(int) { return "%i"; } 00260 template<> inline const char *FmtString(long) { return "%li"; } 00261 template<> inline const char *FmtString(unsigned) { return "%u"; } 00262 template<> inline const char *FmtString(unsigned long) { return "%lu"; } 00263 template<> inline const char *FmtString(float) { return "%f"; } 00264 template<> inline const char *FmtString(double) { return "%lf"; } 00265 template<> inline const char *FmtString(long double) { return "%Lf"; } 00266 template<> inline const char *FmtString(char) { return "%c"; } 00267 template<> inline const char *FmtString(unsigned char) { return "%c"; } 00268 00269 } // namespace internal 00270 00272 00280 template<typename T> inline PGSTD::string ToString(const T &Obj) 00281 { 00282 // TODO: Find a decent way to determine max string length at compile time! 00283 char Buf[500]; 00284 sprintf(Buf, internal::FmtString(Obj), Obj); 00285 return PGSTD::string(Buf); 00286 } 00287 00288 00289 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;} 00290 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; } 00291 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; } 00292 00293 template<> inline PGSTD::string ToString(const unsigned char *const &Obj) 00294 { 00295 return reinterpret_cast<const char *>(Obj); 00296 } 00297 00298 template<> inline PGSTD::string ToString(const bool &Obj) 00299 { 00300 return ToString(unsigned(Obj)); 00301 } 00302 00303 template<> inline PGSTD::string ToString(const short &Obj) 00304 { 00305 return ToString(int(Obj)); 00306 } 00307 00308 template<> inline PGSTD::string ToString(const unsigned short &Obj) 00309 { 00310 return ToString(unsigned(Obj)); 00311 } 00312 00313 00315 00323 template<typename T> inline void FromString(const char Str[], T &Obj) 00324 { 00325 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " + 00326 PGSTD::string(typeid(T).name())); 00327 00328 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1) 00329 throw PGSTD::runtime_error("Cannot convert value '" + 00330 PGSTD::string(Str) + 00331 "' to " + typeid(T).name()); 00332 } 00333 00334 00335 namespace internal 00336 { 00338 00340 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj); 00341 00343 00345 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[], 00346 const unsigned char *&Obj); 00347 00349 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj, 00350 bool EmptyIsNull); 00351 00353 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull); 00354 } // namespace internal 00355 00356 00357 template<> inline void FromString(const char Str[], PGSTD::string &Obj) 00358 { 00359 internal::FromString_string(Str, Obj); 00360 } 00361 00362 template<> inline void FromString(const char Str[], const char *&Obj) 00363 { 00364 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string"); 00365 Obj = Str; 00366 } 00367 00368 template<> inline void FromString(const char Str[], const unsigned char *&Obj) 00369 { 00370 internal::FromString_ucharptr(Str, Obj); 00371 } 00372 00373 template<> inline void FromString(const char Str[], bool &Obj) 00374 { 00375 from_string(Str, Obj); 00376 } 00377 00378 00380 00389 PGSTD::string sqlesc(const char str[]); //[t0] 00390 00392 00402 PGSTD::string sqlesc(const char str[], size_t maxlen); //[t0] 00403 00405 00411 PGSTD::string sqlesc(const PGSTD::string &); //[t0] 00412 00413 00415 00419 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull); 00420 00421 00423 00425 template<> 00426 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull) 00427 { 00428 return internal::Quote_string(Obj, EmptyIsNull); 00429 } 00430 00432 00434 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull) 00435 { 00436 return internal::Quote_charptr(Obj, EmptyIsNull); 00437 } 00438 00439 00441 00446 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN], 00447 bool EmptyIsNull) 00448 { 00449 return internal::Quote_charptr(Obj, EmptyIsNull); 00450 } 00451 00452 00457 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull) 00458 { 00459 return Quote(ToString(Obj), EmptyIsNull); 00460 } 00461 00462 00464 00467 template<typename T> inline PGSTD::string Quote(T Obj) 00468 { 00469 return Quote(Obj, false); 00470 } 00471 00472 00473 namespace internal 00474 { 00475 void freepqmem(void *); 00476 void freenotif(PGnotify *); 00477 00479 00485 template<typename T> class PQAlloc 00486 { 00487 T *m_Obj; 00488 public: 00489 typedef T content_type; 00490 00491 PQAlloc() : m_Obj(0) {} 00492 00494 explicit PQAlloc(T *obj) : m_Obj(obj) {} 00495 00496 ~PQAlloc() throw () { close(); } 00497 00499 00501 PQAlloc &operator=(T *obj) throw () 00502 { 00503 if (obj != m_Obj) 00504 { 00505 close(); 00506 m_Obj = obj; 00507 } 00508 return *this; 00509 } 00510 00512 operator bool() const throw () { return m_Obj != 0; } 00513 00515 bool operator!() const throw () { return !m_Obj; } 00516 00518 00520 T *operator->() const throw (PGSTD::logic_error) 00521 { 00522 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced"); 00523 return m_Obj; 00524 } 00525 00527 00529 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); } 00530 00532 00534 T *c_ptr() const throw () { return m_Obj; } 00535 00537 void close() throw () { if (m_Obj) freemem(); m_Obj = 0; } 00538 00539 private: 00540 void freemem() throw () 00541 { 00542 freepqmem(m_Obj); 00543 } 00544 00545 PQAlloc(const PQAlloc &); // Not allowed 00546 PQAlloc &operator=(const PQAlloc &); // Not allowed 00547 }; 00548 00549 00551 template<> inline void PQAlloc<PGnotify>::freemem() throw () 00552 { 00553 freenotif(m_Obj); 00554 } 00555 00556 00557 class PQXX_LIBEXPORT namedclass 00558 { 00559 public: 00560 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) : 00561 m_Name(Name), 00562 m_Classname(Classname) 00563 { 00564 } 00565 00566 const PGSTD::string &name() const throw () { return m_Name; } //[t1] 00567 const PGSTD::string &classname() const throw () {return m_Classname;} //[t73] 00568 PGSTD::string description() const throw (); //[t73] 00569 00570 private: 00571 PGSTD::string m_Name, m_Classname; 00572 }; 00573 00574 00575 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old); 00576 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old); 00577 00578 00580 00583 template<typename GUEST> 00584 class unique 00585 { 00586 public: 00587 unique() : m_Guest(0) {} 00588 00589 GUEST *get() const throw () { return m_Guest; } 00590 00591 void Register(GUEST *G) 00592 { 00593 CheckUniqueRegistration(G, m_Guest); 00594 m_Guest = G; 00595 } 00596 00597 void Unregister(GUEST *G) 00598 { 00599 CheckUniqueUnregistration(G, m_Guest); 00600 m_Guest = 0; 00601 } 00602 00603 private: 00604 GUEST *m_Guest; 00605 00607 unique(const unique &); 00609 unique &operator=(const unique &); 00610 }; 00611 00612 } // namespace internal 00613 } // namespace pqxx 00614

Generated on Sun Jun 6 20:55:11 2004 for libpqxx by doxygen 1.3.7