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 } 00034 00035 00036 #ifdef PQXX_PQ_IN_NAMESPACE 00037 // We want libpq in the pqxx::internal::pq namespace 00038 00039 namespace pqxx 00040 { 00041 namespace internal 00042 { 00043 namespace pq 00044 { 00045 #define PQXXPQ pqxx::internal::pq 00046 extern "C" 00047 { 00048 #include "libpq-fe.h" 00049 } 00050 } // namespace pq 00051 } // namespace internal 00052 } // namespace pqxx 00053 00054 #else // PQXX_PQ_IN_NAMESPACE 00055 // We want libpq in the global namespace, with duplicates in pqxx::internal::pq 00056 00057 extern "C" 00058 { 00059 #include "libpq-fe.h" 00060 } 00061 00062 namespace pqxx 00063 { 00064 namespace internal 00065 { 00066 namespace pq 00067 { 00068 #define PQXXPQ 00069 typedef PQXXPQ::PGconn PGconn; 00070 typedef PQXXPQ::PGresult PGresult; 00071 00072 } // namespace pq 00073 } // namespace internal 00074 } // namespace pqxx 00075 00076 #endif // PQXX_PQ_IN_NAMESPACE 00077 00078 00079 namespace pqxx 00080 { 00081 typedef long result_size_type; 00082 typedef int tuple_size_type; 00083 00085 typedef PQXXPQ::Oid oid; 00086 00088 const oid oid_none = 0; 00089 00090 00092 00105 template<typename T> void error_unsupported_type_in_string_conversion(T); 00106 00107 00109 00115 template<typename T> PGSTD::string error_ambiguous_string_conversion(T); 00116 00117 00118 00119 // TODO: Implement date conversions 00120 00122 00131 template<typename T> void from_string(const char Str[], T &Obj); 00132 00133 template<> void from_string(const char Str[], long &); //[t45] 00134 template<> void from_string(const char Str[], unsigned long &); //[t45] 00135 template<> void from_string(const char Str[], int &); //[t45] 00136 template<> void from_string(const char Str[], unsigned int &); //[t45] 00137 template<> void from_string(const char Str[], short &); //[t45] 00138 template<> void from_string(const char Str[], unsigned short &); //[t45] 00139 template<> void from_string(const char Str[], float &); //[t46] 00140 template<> void from_string(const char Str[], double &); //[t46] 00141 template<> void from_string(const char Str[], long double &); //[t46] 00142 template<> void from_string(const char Str[], bool &); //[t76] 00143 00144 template<> inline void from_string(const char Str[],PGSTD::string &Obj) //[t46] 00145 { Obj = Str; } 00146 00147 template<> 00148 inline void from_string(const char Str[], PGSTD::stringstream &Obj) //[t0] 00149 { Obj.clear(); Obj << Str; } 00150 00151 template<typename T> 00152 inline void from_string(const PGSTD::string &Str, T &Obj) //[t45] 00153 { from_string(Str.c_str(), Obj); } 00154 00155 template<typename T> 00156 inline void from_string(const PGSTD::stringstream &Str, T &Obj) //[t0] 00157 { from_string(Str.str(), Obj); } 00158 00159 template<> inline void 00160 from_string(const PGSTD::string &Str, PGSTD::string &Obj) //[t46] 00161 { Obj = Str; } 00162 00163 template<> inline void 00164 from_string(const PGSTD::string &, const char &Obj) 00165 { error_ambiguous_string_conversion(Obj); } 00166 template<> inline void 00167 from_string(const PGSTD::string &, const signed char &Obj) 00168 { error_ambiguous_string_conversion(Obj); } 00169 template<> inline void 00170 from_string(const PGSTD::string &, const unsigned char &Obj) 00171 { error_ambiguous_string_conversion(Obj); } 00172 00173 00175 00179 template<typename T> PGSTD::string to_string(const T &); 00180 00181 template<> PGSTD::string to_string(const short &); //[t76] 00182 template<> PGSTD::string to_string(const unsigned short &); //[t76] 00183 template<> PGSTD::string to_string(const int &); //[t10] 00184 template<> PGSTD::string to_string(const unsigned int &); //[t13] 00185 template<> PGSTD::string to_string(const long &); //[t18] 00186 template<> PGSTD::string to_string(const unsigned long &); //[t20] 00187 template<> PGSTD::string to_string(const float &); //[t74] 00188 template<> PGSTD::string to_string(const double &); //[t74] 00189 template<> PGSTD::string to_string(const long double &); //[t74] 00190 template<> PGSTD::string to_string(const bool &); //[t76] 00191 00192 inline PGSTD::string to_string(const char Obj[]) //[t14] 00193 { return PGSTD::string(Obj); } 00194 00195 inline PGSTD::string to_string(const PGSTD::stringstream &Obj) //[t0] 00196 { return Obj.str(); } 00197 00198 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;} //[t21] 00199 00200 template<> PGSTD::string to_string(const char &); //[t21] 00201 00202 00203 template<> inline PGSTD::string to_string(const signed char &Obj) 00204 { return error_ambiguous_string_conversion(Obj); } 00205 template<> inline PGSTD::string to_string(const unsigned char &Obj) 00206 { return error_ambiguous_string_conversion(Obj); } 00207 00208 00210 00227 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> > 00228 class items : public CONT 00229 { 00230 public: 00232 items() : CONT() {} //[t80] 00234 explicit items(const T &t) : CONT() { push_back(t); } //[] 00235 items(const T &t1, const T &t2) : CONT() //[t80] 00236 { push_back(t1); push_back(t2); } 00237 items(const T &t1, const T &t2, const T &t3) : CONT() //[] 00238 { push_back(t1); push_back(t2); push_back(t3); } 00239 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT() //[] 00240 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); } 00241 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT() //[] 00242 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);} 00244 items(const CONT &c) : CONT(c) {} //[] 00245 00247 items &operator()(const T &t) //[t80] 00248 { 00249 push_back(t); 00250 return *this; 00251 } 00252 }; 00253 00254 00255 // TODO: Generalize--add transformation functor 00257 template<typename ITER> inline 00258 PGSTD::string separated_list(const PGSTD::string &sep, 00259 ITER begin, 00260 ITER end) //[t8] 00261 { 00262 PGSTD::string result; 00263 if (begin != end) 00264 { 00265 result = to_string(*begin); 00266 for (++begin; begin != end; ++begin) 00267 { 00268 result += sep; 00269 result += to_string(*begin); 00270 } 00271 } 00272 return result; 00273 } 00274 00276 template<typename CONTAINER> inline 00277 PGSTD::string separated_list(const PGSTD::string &sep, 00278 const CONTAINER &c) //[t10] 00279 { 00280 return separated_list(sep, c.begin(), c.end()); 00281 } 00282 00283 00285 00290 namespace internal 00291 { 00293 00301 template<typename T> inline const char *FmtString(T t) 00302 { 00303 error_unsupported_type_in_string_conversion(t); 00304 return 0; 00305 } 00306 00307 template<> inline const char *FmtString(short) { return "%hd"; } 00308 template<> inline const char *FmtString(unsigned short){ return "%hu"; } 00309 template<> inline const char *FmtString(int) { return "%i"; } 00310 template<> inline const char *FmtString(long) { return "%li"; } 00311 template<> inline const char *FmtString(unsigned) { return "%u"; } 00312 template<> inline const char *FmtString(unsigned long) { return "%lu"; } 00313 template<> inline const char *FmtString(float) { return "%f"; } 00314 template<> inline const char *FmtString(double) { return "%lf"; } 00315 template<> inline const char *FmtString(long double) { return "%Lf"; } 00316 template<> inline const char *FmtString(char) { return "%c"; } 00317 template<> inline const char *FmtString(unsigned char) { return "%c"; } 00318 00319 } // namespace internal 00320 00322 00330 template<typename T> inline PGSTD::string ToString(const T &Obj) 00331 { 00332 // TODO: Find a decent way to determine max string length at compile time! 00333 char Buf[500]; 00334 sprintf(Buf, internal::FmtString(Obj), Obj); 00335 return PGSTD::string(Buf); 00336 } 00337 00338 00339 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;} 00340 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; } 00341 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; } 00342 00343 template<> inline PGSTD::string ToString(const unsigned char *const &Obj) 00344 { 00345 return reinterpret_cast<const char *>(Obj); 00346 } 00347 00348 template<> inline PGSTD::string ToString(const bool &Obj) 00349 { 00350 return ToString(unsigned(Obj)); 00351 } 00352 00353 template<> inline PGSTD::string ToString(const short &Obj) 00354 { 00355 return ToString(int(Obj)); 00356 } 00357 00358 template<> inline PGSTD::string ToString(const unsigned short &Obj) 00359 { 00360 return ToString(unsigned(Obj)); 00361 } 00362 00363 00365 00373 template<typename T> inline void FromString(const char Str[], T &Obj) 00374 { 00375 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " + 00376 PGSTD::string(typeid(T).name())); 00377 00378 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1) 00379 throw PGSTD::runtime_error("Cannot convert value '" + 00380 PGSTD::string(Str) + 00381 "' to " + typeid(T).name()); 00382 } 00383 00384 00385 namespace internal 00386 { 00388 00390 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj); 00391 00393 00395 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[], 00396 const unsigned char *&Obj); 00397 00399 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj, 00400 bool EmptyIsNull); 00401 00403 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull); 00404 } // namespace internal 00405 00406 00407 template<> inline void FromString(const char Str[], PGSTD::string &Obj) 00408 { 00409 internal::FromString_string(Str, Obj); 00410 } 00411 00412 template<> inline void FromString(const char Str[], const char *&Obj) 00413 { 00414 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string"); 00415 Obj = Str; 00416 } 00417 00418 template<> inline void FromString(const char Str[], const unsigned char *&Obj) 00419 { 00420 internal::FromString_ucharptr(Str, Obj); 00421 } 00422 00423 template<> inline void FromString(const char Str[], bool &Obj) 00424 { 00425 from_string(Str, Obj); 00426 } 00427 00428 00430 00439 PGSTD::string sqlesc(const char str[]); //[t0] 00440 00442 00452 PGSTD::string sqlesc(const char str[], size_t maxlen); //[t0] 00453 00455 00461 PGSTD::string sqlesc(const PGSTD::string &); //[t0] 00462 00463 00465 00469 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull); 00470 00471 00473 00475 template<> 00476 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull) 00477 { 00478 return internal::Quote_string(Obj, EmptyIsNull); 00479 } 00480 00482 00484 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull) 00485 { 00486 return internal::Quote_charptr(Obj, EmptyIsNull); 00487 } 00488 00489 00491 00496 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN], 00497 bool EmptyIsNull) 00498 { 00499 return internal::Quote_charptr(Obj, EmptyIsNull); 00500 } 00501 00502 00503 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull) 00504 { 00505 return Quote(ToString(Obj), EmptyIsNull); 00506 } 00507 00508 00510 00513 template<typename T> inline PGSTD::string Quote(T Obj) 00514 { 00515 return Quote(Obj, false); 00516 } 00517 00518 00519 namespace internal 00520 { 00521 void freepqmem(void *); 00522 void freenotif(PQXXPQ::PGnotify *); 00523 00525 00531 template<typename T> class PQAlloc 00532 { 00533 T *m_Obj; 00534 public: 00535 typedef T content_type; 00536 00537 PQAlloc() : m_Obj(0) {} 00538 00540 explicit PQAlloc(T *obj) : m_Obj(obj) {} 00541 00542 ~PQAlloc() throw () { close(); } 00543 00545 00547 PQAlloc &operator=(T *obj) throw () 00548 { 00549 if (obj != m_Obj) 00550 { 00551 close(); 00552 m_Obj = obj; 00553 } 00554 return *this; 00555 } 00556 00558 operator bool() const throw () { return m_Obj != 0; } 00559 00561 bool operator!() const throw () { return !m_Obj; } 00562 00564 00566 T *operator->() const throw (PGSTD::logic_error) 00567 { 00568 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced"); 00569 return m_Obj; 00570 } 00571 00573 00575 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); } 00576 00578 00580 T *c_ptr() const throw () { return m_Obj; } 00581 00583 void close() throw () { if (m_Obj) freemem(); m_Obj = 0; } 00584 00585 private: 00586 void freemem() throw () 00587 { 00588 freepqmem(m_Obj); 00589 } 00590 00591 PQAlloc(const PQAlloc &); // Not allowed 00592 PQAlloc &operator=(const PQAlloc &); // Not allowed 00593 }; 00594 00595 00597 template<> inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw () 00598 { 00599 freenotif(m_Obj); 00600 } 00601 00602 00603 class PQXX_LIBEXPORT namedclass 00604 { 00605 public: 00606 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) : 00607 m_Name(Name), 00608 m_Classname(Classname) 00609 { 00610 } 00611 00612 const PGSTD::string &name() const throw () { return m_Name; } //[t1] 00613 const PGSTD::string &classname() const throw () {return m_Classname;} //[t73] 00614 PGSTD::string description() const; 00615 00616 private: 00617 PGSTD::string m_Name, m_Classname; 00618 }; 00619 00620 00621 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old); 00622 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old); 00623 00624 00626 00629 template<typename GUEST> 00630 class unique 00631 { 00632 public: 00633 unique() : m_Guest(0) {} 00634 00635 GUEST *get() const throw () { return m_Guest; } 00636 00637 void Register(GUEST *G) 00638 { 00639 CheckUniqueRegistration(G, m_Guest); 00640 m_Guest = G; 00641 } 00642 00643 void Unregister(GUEST *G) 00644 { 00645 CheckUniqueUnregistration(G, m_Guest); 00646 m_Guest = 0; 00647 } 00648 00649 private: 00650 GUEST *m_Guest; 00651 00653 unique(const unique &); 00655 unique &operator=(const unique &); 00656 }; 00657 00658 } // namespace internal 00659 } // namespace pqxx 00660

Generated on Sat Aug 21 03:39:33 2004 for libpqxx by doxygen 1.3.8