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 #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 } // namespace pq 00042 } // namespace internal 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 // TODO: Implement date conversions 00083 00085 00094 template<typename T> void from_string(const char Str[], T &Obj); 00095 00096 template<> void from_string(const char Str[], long &); //[t45] 00097 template<> void from_string(const char Str[], unsigned long &); //[t45] 00098 template<> void from_string(const char Str[], int &); //[t45] 00099 template<> void from_string(const char Str[], unsigned int &); //[t45] 00100 template<> void from_string(const char Str[], short &); //[t45] 00101 template<> void from_string(const char Str[], unsigned short &); //[t45] 00102 template<> void from_string(const char Str[], float &); //[t46] 00103 template<> void from_string(const char Str[], double &); //[t46] 00104 template<> void from_string(const char Str[], long double &); //[t46] 00105 template<> void from_string(const char Str[], bool &); //[t76] 00106 00107 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46] 00108 { Obj = Str; } 00109 00110 template<> 00111 inline void from_string(const char Str[], PGSTD::stringstream &Obj) //[t0] 00112 { Obj.clear(); Obj << Str; } 00113 00114 template<typename T> 00115 inline void from_string(const PGSTD::string &Str, T &Obj) //[t45] 00116 { from_string(Str.c_str(), Obj); } 00117 00118 template<typename T> 00119 inline void from_string(const PGSTD::stringstream &Str, T &Obj) //[t0] 00120 { from_string(Str.str(), Obj); } 00121 00122 template<> inline void 00123 from_string(const PGSTD::string &Str, PGSTD::string &Obj) //[t46] 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 &); //[t76] 00145 template<> PGSTD::string to_string(const unsigned short &); //[t76] 00146 template<> PGSTD::string to_string(const int &); //[t10] 00147 template<> PGSTD::string to_string(const unsigned int &); //[t13] 00148 template<> PGSTD::string to_string(const long &); //[t18] 00149 template<> PGSTD::string to_string(const unsigned long &); //[t20] 00150 template<> PGSTD::string to_string(const float &); //[t74] 00151 template<> PGSTD::string to_string(const double &); //[t74] 00152 template<> PGSTD::string to_string(const long double &); //[t74] 00153 template<> PGSTD::string to_string(const bool &); //[t76] 00154 00155 inline PGSTD::string to_string(const char Obj[]) //[t14] 00156 { return PGSTD::string(Obj); } 00157 00158 inline PGSTD::string to_string(const PGSTD::stringstream &Obj) //[t0] 00159 { return Obj.str(); } 00160 00161 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;} //[t21] 00162 00163 template<> PGSTD::string to_string(const char &); //[t21] 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() //[t80] 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 // TODO: Generalize--add transformation functor 00217 template<typename ITER> inline 00218 PGSTD::string separated_list(const PGSTD::string &sep, 00219 ITER begin, 00220 ITER end) //[t8] 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) //[t10] 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 } // namespace internal 00280 00282 00290 template<typename T> inline PGSTD::string ToString(const T &Obj) 00291 { 00292 // TODO: Find a decent way to determine max string length at compile time! 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 } // namespace internal 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[]); //[t0] 00400 00402 00412 PGSTD::string sqlesc(const char str[], size_t maxlen); //[t0] 00413 00415 00421 PGSTD::string sqlesc(const PGSTD::string &); //[t0] 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 &); // Not allowed 00552 PQAlloc &operator=(const PQAlloc &); // Not allowed 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; } //[t1] 00573 const PGSTD::string &classname() const throw () {return m_Classname;} //[t73] 00574 PGSTD::string description() const throw (); //[t73] 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 } // namespace internal 00619 } // namespace pqxx 00620

Generated on Mon Aug 9 01:47:24 2004 for libpqxx by doxygen 1.3.8