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 char &Obj) 00121 { error_ambiguous_string_conversion(Obj); } 00122 template<> inline void 00123 from_string(const PGSTD::string &, const signed char &Obj) 00124 { error_ambiguous_string_conversion(Obj); } 00125 template<> inline void 00126 from_string(const PGSTD::string &, const unsigned char &Obj) 00127 { error_ambiguous_string_conversion(Obj); } 00128 00129 00131 00135 template<typename T> PGSTD::string to_string(const T &); 00136 00137 template<> PGSTD::string to_string(const short &); //[t76] 00138 template<> PGSTD::string to_string(const unsigned short &); //[t76] 00139 template<> PGSTD::string to_string(const int &); //[t10] 00140 template<> PGSTD::string to_string(const unsigned int &); //[t13] 00141 template<> PGSTD::string to_string(const long &); //[t18] 00142 template<> PGSTD::string to_string(const unsigned long &); //[t20] 00143 template<> PGSTD::string to_string(const float &); //[t74] 00144 template<> PGSTD::string to_string(const double &); //[t74] 00145 template<> PGSTD::string to_string(const long double &); //[t74] 00146 template<> PGSTD::string to_string(const bool &); //[t76] 00147 00148 inline PGSTD::string to_string(const char Obj[]) //[t14] 00149 { return PGSTD::string(Obj); } 00150 00151 inline PGSTD::string to_string(const PGSTD::stringstream &Obj) //[t0] 00152 { return Obj.str(); } 00153 00154 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;} //[t21] 00155 00156 template<> PGSTD::string to_string(const char &); //[t21] 00157 00158 00159 template<> inline PGSTD::string to_string(const signed char &Obj) 00160 { return error_ambiguous_string_conversion(Obj); } 00161 template<> inline PGSTD::string to_string(const unsigned char &Obj) 00162 { return error_ambiguous_string_conversion(Obj); } 00163 00164 00166 00180 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> > 00181 class items : public CONT 00182 { 00183 public: 00185 items() : CONT() {} //[] 00187 explicit items(const T &t) : CONT() { push_back(t); } //[] 00188 items(const T &t1, const T &t2) : CONT() //[t80] 00189 { push_back(t1); push_back(t2); } 00190 items(const T &t1, const T &t2, const T &t3) : CONT() //[] 00191 { push_back(t1); push_back(t2); push_back(t3); } 00192 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT() //[] 00193 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); } 00194 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT() //[] 00195 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);} 00197 items(const CONT &c) : CONT(c) {} //[] 00198 00200 items &operator()(const T &t) //[] 00201 { 00202 push_back(t); 00203 return *this; 00204 } 00205 }; 00206 00207 00208 // TODO: Generalize--add transformation functor 00210 template<typename ITER> inline 00211 PGSTD::string separated_list(const PGSTD::string &sep, 00212 ITER begin, 00213 ITER end) //[t8] 00214 { 00215 PGSTD::string result; 00216 if (begin != end) 00217 { 00218 result = to_string(*begin); 00219 for (++begin; begin != end; ++begin) 00220 { 00221 result += sep; 00222 result += to_string(*begin); 00223 } 00224 } 00225 return result; 00226 } 00227 00229 template<typename CONTAINER> inline 00230 PGSTD::string separated_list(const PGSTD::string &sep, 00231 const CONTAINER &c) //[t10] 00232 { 00233 return separated_list(sep, c.begin(), c.end()); 00234 } 00235 00236 00238 00243 namespace internal 00244 { 00246 00254 template<typename T> inline const char *FmtString(T t) 00255 { 00256 error_unsupported_type_in_string_conversion(t); 00257 return 0; 00258 } 00259 00260 template<> inline const char *FmtString(short) { return "%hd"; } 00261 template<> inline const char *FmtString(unsigned short){ return "%hu"; } 00262 template<> inline const char *FmtString(int) { return "%i"; } 00263 template<> inline const char *FmtString(long) { return "%li"; } 00264 template<> inline const char *FmtString(unsigned) { return "%u"; } 00265 template<> inline const char *FmtString(unsigned long) { return "%lu"; } 00266 template<> inline const char *FmtString(float) { return "%f"; } 00267 template<> inline const char *FmtString(double) { return "%lf"; } 00268 template<> inline const char *FmtString(long double) { return "%Lf"; } 00269 template<> inline const char *FmtString(char) { return "%c"; } 00270 template<> inline const char *FmtString(unsigned char) { return "%c"; } 00271 00272 } // namespace internal 00273 00275 00283 template<typename T> inline PGSTD::string ToString(const T &Obj) 00284 { 00285 // TODO: Find a decent way to determine max string length at compile time! 00286 char Buf[500]; 00287 sprintf(Buf, internal::FmtString(Obj), Obj); 00288 return PGSTD::string(Buf); 00289 } 00290 00291 00292 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;} 00293 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; } 00294 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; } 00295 00296 template<> inline PGSTD::string ToString(const unsigned char *const &Obj) 00297 { 00298 return reinterpret_cast<const char *>(Obj); 00299 } 00300 00301 template<> inline PGSTD::string ToString(const bool &Obj) 00302 { 00303 return ToString(unsigned(Obj)); 00304 } 00305 00306 template<> inline PGSTD::string ToString(const short &Obj) 00307 { 00308 return ToString(int(Obj)); 00309 } 00310 00311 template<> inline PGSTD::string ToString(const unsigned short &Obj) 00312 { 00313 return ToString(unsigned(Obj)); 00314 } 00315 00316 00318 00326 template<typename T> inline void FromString(const char Str[], T &Obj) 00327 { 00328 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " + 00329 PGSTD::string(typeid(T).name())); 00330 00331 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1) 00332 throw PGSTD::runtime_error("Cannot convert value '" + 00333 PGSTD::string(Str) + 00334 "' to " + typeid(T).name()); 00335 } 00336 00337 00338 namespace internal 00339 { 00341 00343 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj); 00344 00346 00348 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[], 00349 const unsigned char *&Obj); 00350 00352 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj, 00353 bool EmptyIsNull); 00354 00356 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull); 00357 } // namespace internal 00358 00359 00360 template<> inline void FromString(const char Str[], PGSTD::string &Obj) 00361 { 00362 internal::FromString_string(Str, Obj); 00363 } 00364 00365 template<> inline void FromString(const char Str[], const char *&Obj) 00366 { 00367 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string"); 00368 Obj = Str; 00369 } 00370 00371 template<> inline void FromString(const char Str[], const unsigned char *&Obj) 00372 { 00373 internal::FromString_ucharptr(Str, Obj); 00374 } 00375 00376 template<> inline void FromString(const char Str[], bool &Obj) 00377 { 00378 from_string(Str, Obj); 00379 } 00380 00381 00383 00392 PGSTD::string sqlesc(const char str[]); //[t0] 00393 00395 00405 PGSTD::string sqlesc(const char str[], size_t maxlen); //[t0] 00406 00408 00414 PGSTD::string sqlesc(const PGSTD::string &); //[t0] 00415 00416 00418 00422 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull); 00423 00424 00426 00428 template<> 00429 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull) 00430 { 00431 return internal::Quote_string(Obj, EmptyIsNull); 00432 } 00433 00435 00437 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull) 00438 { 00439 return internal::Quote_charptr(Obj, EmptyIsNull); 00440 } 00441 00442 00444 00449 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN], 00450 bool EmptyIsNull) 00451 { 00452 return internal::Quote_charptr(Obj, EmptyIsNull); 00453 } 00454 00455 00460 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull) 00461 { 00462 return Quote(ToString(Obj), EmptyIsNull); 00463 } 00464 00465 00467 00470 template<typename T> inline PGSTD::string Quote(T Obj) 00471 { 00472 return Quote(Obj, false); 00473 } 00474 00475 00476 namespace internal 00477 { 00478 void freepqmem(void *); 00479 void freenotif(PGnotify *); 00480 00482 00488 template<typename T> class PQAlloc 00489 { 00490 T *m_Obj; 00491 public: 00492 typedef T content_type; 00493 00494 PQAlloc() : m_Obj(0) {} 00495 00497 explicit PQAlloc(T *obj) : m_Obj(obj) {} 00498 00499 ~PQAlloc() throw () { close(); } 00500 00502 00504 PQAlloc &operator=(T *obj) throw () 00505 { 00506 if (obj != m_Obj) 00507 { 00508 close(); 00509 m_Obj = obj; 00510 } 00511 return *this; 00512 } 00513 00515 operator bool() const throw () { return m_Obj != 0; } 00516 00518 bool operator!() const throw () { return !m_Obj; } 00519 00521 00523 T *operator->() const throw (PGSTD::logic_error) 00524 { 00525 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced"); 00526 return m_Obj; 00527 } 00528 00530 00532 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); } 00533 00535 00537 T *c_ptr() const throw () { return m_Obj; } 00538 00540 void close() throw () { if (m_Obj) freemem(); m_Obj = 0; } 00541 00542 private: 00543 void freemem() throw () 00544 { 00545 freepqmem(m_Obj); 00546 } 00547 00548 PQAlloc(const PQAlloc &); // Not allowed 00549 PQAlloc &operator=(const PQAlloc &); // Not allowed 00550 }; 00551 00552 00554 template<> inline void PQAlloc<PGnotify>::freemem() throw () 00555 { 00556 freenotif(m_Obj); 00557 } 00558 00559 00560 class PQXX_LIBEXPORT namedclass 00561 { 00562 public: 00563 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) : 00564 m_Name(Name), 00565 m_Classname(Classname) 00566 { 00567 } 00568 00569 const PGSTD::string &name() const throw () { return m_Name; } //[t1] 00570 const PGSTD::string &classname() const throw () {return m_Classname;} //[t73] 00571 PGSTD::string description() const throw (); //[t73] 00572 00573 private: 00574 PGSTD::string m_Name, m_Classname; 00575 }; 00576 00577 00578 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old); 00579 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old); 00580 00581 00583 00586 template<typename GUEST> 00587 class unique 00588 { 00589 public: 00590 unique() : m_Guest(0) {} 00591 00592 GUEST *get() const throw () { return m_Guest; } 00593 00594 void Register(GUEST *G) 00595 { 00596 CheckUniqueRegistration(G, m_Guest); 00597 m_Guest = G; 00598 } 00599 00600 void Unregister(GUEST *G) 00601 { 00602 CheckUniqueUnregistration(G, m_Guest); 00603 m_Guest = 0; 00604 } 00605 00606 private: 00607 GUEST *m_Guest; 00608 00610 unique(const unique &); 00612 unique &operator=(const unique &); 00613 }; 00614 00615 } // namespace internal 00616 } // namespace pqxx 00617

Generated on Sun Jun 20 00:35:44 2004 for libpqxx by doxygen 1.3.7