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 00224 template<typename T=PGSTD::string, typename CONT=PGSTD::vector<T> > 00225 class items : public CONT 00226 { 00227 public: 00229 items() : CONT() {} //[] 00231 explicit items(const T &t) : CONT() { push_back(t); } //[] 00232 items(const T &t1, const T &t2) : CONT() //[t80] 00233 { push_back(t1); push_back(t2); } 00234 items(const T &t1, const T &t2, const T &t3) : CONT() //[] 00235 { push_back(t1); push_back(t2); push_back(t3); } 00236 items(const T &t1, const T &t2, const T &t3, const T &t4) : CONT() //[] 00237 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); } 00238 items(const T&t1,const T&t2,const T&t3,const T&t4,const T&t5):CONT() //[] 00239 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);} 00241 items(const CONT &c) : CONT(c) {} //[] 00242 00244 items &operator()(const T &t) //[] 00245 { 00246 push_back(t); 00247 return *this; 00248 } 00249 }; 00250 00251 00252 // TODO: Generalize--add transformation functor 00254 template<typename ITER> inline 00255 PGSTD::string separated_list(const PGSTD::string &sep, 00256 ITER begin, 00257 ITER end) //[t8] 00258 { 00259 PGSTD::string result; 00260 if (begin != end) 00261 { 00262 result = to_string(*begin); 00263 for (++begin; begin != end; ++begin) 00264 { 00265 result += sep; 00266 result += to_string(*begin); 00267 } 00268 } 00269 return result; 00270 } 00271 00273 template<typename CONTAINER> inline 00274 PGSTD::string separated_list(const PGSTD::string &sep, 00275 const CONTAINER &c) //[t10] 00276 { 00277 return separated_list(sep, c.begin(), c.end()); 00278 } 00279 00280 00282 00287 namespace internal 00288 { 00290 00298 template<typename T> inline const char *FmtString(T t) 00299 { 00300 error_unsupported_type_in_string_conversion(t); 00301 return 0; 00302 } 00303 00304 template<> inline const char *FmtString(short) { return "%hd"; } 00305 template<> inline const char *FmtString(unsigned short){ return "%hu"; } 00306 template<> inline const char *FmtString(int) { return "%i"; } 00307 template<> inline const char *FmtString(long) { return "%li"; } 00308 template<> inline const char *FmtString(unsigned) { return "%u"; } 00309 template<> inline const char *FmtString(unsigned long) { return "%lu"; } 00310 template<> inline const char *FmtString(float) { return "%f"; } 00311 template<> inline const char *FmtString(double) { return "%lf"; } 00312 template<> inline const char *FmtString(long double) { return "%Lf"; } 00313 template<> inline const char *FmtString(char) { return "%c"; } 00314 template<> inline const char *FmtString(unsigned char) { return "%c"; } 00315 00316 } // namespace internal 00317 00319 00327 template<typename T> inline PGSTD::string ToString(const T &Obj) 00328 { 00329 // TODO: Find a decent way to determine max string length at compile time! 00330 char Buf[500]; 00331 sprintf(Buf, internal::FmtString(Obj), Obj); 00332 return PGSTD::string(Buf); 00333 } 00334 00335 00336 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;} 00337 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; } 00338 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; } 00339 00340 template<> inline PGSTD::string ToString(const unsigned char *const &Obj) 00341 { 00342 return reinterpret_cast<const char *>(Obj); 00343 } 00344 00345 template<> inline PGSTD::string ToString(const bool &Obj) 00346 { 00347 return ToString(unsigned(Obj)); 00348 } 00349 00350 template<> inline PGSTD::string ToString(const short &Obj) 00351 { 00352 return ToString(int(Obj)); 00353 } 00354 00355 template<> inline PGSTD::string ToString(const unsigned short &Obj) 00356 { 00357 return ToString(unsigned(Obj)); 00358 } 00359 00360 00362 00370 template<typename T> inline void FromString(const char Str[], T &Obj) 00371 { 00372 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " + 00373 PGSTD::string(typeid(T).name())); 00374 00375 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1) 00376 throw PGSTD::runtime_error("Cannot convert value '" + 00377 PGSTD::string(Str) + 00378 "' to " + typeid(T).name()); 00379 } 00380 00381 00382 namespace internal 00383 { 00385 00387 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj); 00388 00390 00392 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[], 00393 const unsigned char *&Obj); 00394 00396 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj, 00397 bool EmptyIsNull); 00398 00400 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull); 00401 } // namespace internal 00402 00403 00404 template<> inline void FromString(const char Str[], PGSTD::string &Obj) 00405 { 00406 internal::FromString_string(Str, Obj); 00407 } 00408 00409 template<> inline void FromString(const char Str[], const char *&Obj) 00410 { 00411 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string"); 00412 Obj = Str; 00413 } 00414 00415 template<> inline void FromString(const char Str[], const unsigned char *&Obj) 00416 { 00417 internal::FromString_ucharptr(Str, Obj); 00418 } 00419 00420 template<> inline void FromString(const char Str[], bool &Obj) 00421 { 00422 from_string(Str, Obj); 00423 } 00424 00425 00427 00436 PGSTD::string sqlesc(const char str[]); //[t0] 00437 00439 00449 PGSTD::string sqlesc(const char str[], size_t maxlen); //[t0] 00450 00452 00458 PGSTD::string sqlesc(const PGSTD::string &); //[t0] 00459 00460 00462 00466 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull); 00467 00468 00470 00472 template<> 00473 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull) 00474 { 00475 return internal::Quote_string(Obj, EmptyIsNull); 00476 } 00477 00479 00481 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull) 00482 { 00483 return internal::Quote_charptr(Obj, EmptyIsNull); 00484 } 00485 00486 00488 00493 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN], 00494 bool EmptyIsNull) 00495 { 00496 return internal::Quote_charptr(Obj, EmptyIsNull); 00497 } 00498 00499 00500 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull) 00501 { 00502 return Quote(ToString(Obj), EmptyIsNull); 00503 } 00504 00505 00507 00510 template<typename T> inline PGSTD::string Quote(T Obj) 00511 { 00512 return Quote(Obj, false); 00513 } 00514 00515 00516 namespace internal 00517 { 00518 void freepqmem(void *); 00519 void freenotif(PQXXPQ::PGnotify *); 00520 00522 00528 template<typename T> class PQAlloc 00529 { 00530 T *m_Obj; 00531 public: 00532 typedef T content_type; 00533 00534 PQAlloc() : m_Obj(0) {} 00535 00537 explicit PQAlloc(T *obj) : m_Obj(obj) {} 00538 00539 ~PQAlloc() throw () { close(); } 00540 00542 00544 PQAlloc &operator=(T *obj) throw () 00545 { 00546 if (obj != m_Obj) 00547 { 00548 close(); 00549 m_Obj = obj; 00550 } 00551 return *this; 00552 } 00553 00555 operator bool() const throw () { return m_Obj != 0; } 00556 00558 bool operator!() const throw () { return !m_Obj; } 00559 00561 00563 T *operator->() const throw (PGSTD::logic_error) 00564 { 00565 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced"); 00566 return m_Obj; 00567 } 00568 00570 00572 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); } 00573 00575 00577 T *c_ptr() const throw () { return m_Obj; } 00578 00580 void close() throw () { if (m_Obj) freemem(); m_Obj = 0; } 00581 00582 private: 00583 void freemem() throw () 00584 { 00585 freepqmem(m_Obj); 00586 } 00587 00588 PQAlloc(const PQAlloc &); // Not allowed 00589 PQAlloc &operator=(const PQAlloc &); // Not allowed 00590 }; 00591 00592 00594 template<> inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw () 00595 { 00596 freenotif(m_Obj); 00597 } 00598 00599 00600 class PQXX_LIBEXPORT namedclass 00601 { 00602 public: 00603 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) : 00604 m_Name(Name), 00605 m_Classname(Classname) 00606 { 00607 } 00608 00609 const PGSTD::string &name() const throw () { return m_Name; } //[t1] 00610 const PGSTD::string &classname() const throw () {return m_Classname;} //[t73] 00611 PGSTD::string description() const; 00612 00613 private: 00614 PGSTD::string m_Name, m_Classname; 00615 }; 00616 00617 00618 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old); 00619 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old); 00620 00621 00623 00626 template<typename GUEST> 00627 class unique 00628 { 00629 public: 00630 unique() : m_Guest(0) {} 00631 00632 GUEST *get() const throw () { return m_Guest; } 00633 00634 void Register(GUEST *G) 00635 { 00636 CheckUniqueRegistration(G, m_Guest); 00637 m_Guest = G; 00638 } 00639 00640 void Unregister(GUEST *G) 00641 { 00642 CheckUniqueUnregistration(G, m_Guest); 00643 m_Guest = 0; 00644 } 00645 00646 private: 00647 GUEST *m_Guest; 00648 00650 unique(const unique &); 00652 unique &operator=(const unique &); 00653 }; 00654 00655 } // namespace internal 00656 } // namespace pqxx 00657

Generated on Thu Aug 12 23:56:28 2004 for libpqxx by doxygen 1.3.8