00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "pqxx/libcompiler.h"
00019
00020 #include <cstdio>
00021 #include <cctype>
00022 #include <stdexcept>
00023 #include <string>
00024 #include <typeinfo>
00025
00026 extern "C"
00027 {
00028 #include "libpq-fe.h"
00029 }
00030
00031
00033 namespace pqxx
00034 {
00035 typedef long result_size_type;
00036 typedef int tuple_size_type;
00037
00039 typedef Oid oid;
00040
00042 const oid oid_none = InvalidOid;
00043
00044
00046
00059 template<typename T> void error_unsupported_type_in_string_conversion(T);
00060
00061
00063
00069 template<typename T> PGSTD::string error_ambiguous_string_conversion(T);
00070
00071
00072
00073
00074
00076
00085 template<typename T> void from_string(const char Str[], T &Obj);
00086
00087 template<> void from_string(const char Str[], long &);
00088 template<> void from_string(const char Str[], unsigned long &);
00089 template<> void from_string(const char Str[], int &);
00090 template<> void from_string(const char Str[], unsigned int &);
00091 template<> void from_string(const char Str[], short &);
00092 template<> void from_string(const char Str[], unsigned short &);
00093 template<> void from_string(const char Str[], float &);
00094 template<> void from_string(const char Str[], double &);
00095 template<> void from_string(const char Str[], long double &);
00096 template<> void from_string(const char Str[], bool &);
00097
00098 template<> inline void from_string(const char Str[],PGSTD::string &Obj)
00099 { Obj = Str; }
00100
00101 template<typename T>
00102 inline void from_string(const PGSTD::string &Str, T &Obj)
00103 { from_string(Str.c_str(), Obj); }
00104
00105 template<> inline void
00106 from_string(const PGSTD::string &Str, PGSTD::string &Obj)
00107 { Obj = Str; }
00108
00109 template<> inline void
00110 from_string(const PGSTD::string &, const signed char &Obj)
00111 { error_ambiguous_string_conversion(Obj); }
00112 template<> inline void
00113 from_string(const PGSTD::string &, const unsigned char &Obj)
00114 { error_ambiguous_string_conversion(Obj); }
00115
00116
00118
00122 template<typename T> PGSTD::string to_string(const T &);
00123
00124 template<> PGSTD::string to_string(const short &);
00125 template<> PGSTD::string to_string(const unsigned short &);
00126 template<> PGSTD::string to_string(const int &);
00127 template<> PGSTD::string to_string(const unsigned int &);
00128 template<> PGSTD::string to_string(const long &);
00129 template<> PGSTD::string to_string(const unsigned long &);
00130 template<> PGSTD::string to_string(const float &);
00131 template<> PGSTD::string to_string(const double &);
00132 template<> PGSTD::string to_string(const long double &);
00133 template<> PGSTD::string to_string(const bool &);
00134
00135 inline PGSTD::string to_string(const char Obj[])
00136 { return PGSTD::string(Obj); }
00137
00138 inline PGSTD::string to_string(const PGSTD::string &Obj) {return Obj;}
00139
00140 template<> PGSTD::string to_string(const char &);
00141
00142 template<> inline PGSTD::string to_string(const signed char &Obj)
00143 { return error_ambiguous_string_conversion(Obj); }
00144 template<> inline PGSTD::string to_string(const unsigned char &Obj)
00145 { return error_ambiguous_string_conversion(Obj); }
00146
00147
00148
00150
00155 namespace internal
00156 {
00158
00166 template<typename T> inline const char *FmtString(T t)
00167 {
00168 error_unsupported_type_in_string_conversion(t);
00169 return 0;
00170 }
00171
00172 template<> inline const char *FmtString(short) { return "%hd"; }
00173 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00174 template<> inline const char *FmtString(int) { return "%i"; }
00175 template<> inline const char *FmtString(long) { return "%li"; }
00176 template<> inline const char *FmtString(unsigned) { return "%u"; }
00177 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00178 template<> inline const char *FmtString(float) { return "%f"; }
00179 template<> inline const char *FmtString(double) { return "%lf"; }
00180 template<> inline const char *FmtString(long double) { return "%Lf"; }
00181 template<> inline const char *FmtString(char) { return "%c"; }
00182 template<> inline const char *FmtString(unsigned char) { return "%c"; }
00183
00184 }
00185
00187
00195 template<typename T> inline PGSTD::string ToString(const T &Obj)
00196 {
00197
00198 char Buf[500];
00199 sprintf(Buf, internal::FmtString(Obj), Obj);
00200 return PGSTD::string(Buf);
00201 }
00202
00203
00204 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00205 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00206 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00207
00208 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00209 {
00210 return reinterpret_cast<const char *>(Obj);
00211 }
00212
00213 template<> inline PGSTD::string ToString(const bool &Obj)
00214 {
00215 return ToString(unsigned(Obj));
00216 }
00217
00218 template<> inline PGSTD::string ToString(const short &Obj)
00219 {
00220 return ToString(int(Obj));
00221 }
00222
00223 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00224 {
00225 return ToString(unsigned(Obj));
00226 }
00227
00228
00230
00238 template<typename T> inline void FromString(const char Str[], T &Obj)
00239 {
00240 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00241 PGSTD::string(typeid(T).name()));
00242
00243 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00244 throw PGSTD::runtime_error("Cannot convert value '" +
00245 PGSTD::string(Str) +
00246 "' to " + typeid(T).name());
00247 }
00248
00249
00250 namespace internal
00251 {
00253
00255 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00256
00258
00260 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00261 const unsigned char *&Obj);
00262
00264 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00265 bool EmptyIsNull);
00266
00268 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00269 }
00270
00271
00272 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00273 {
00274 internal::FromString_string(Str, Obj);
00275 }
00276
00277 template<> inline void FromString(const char Str[], const char *&Obj)
00278 {
00279 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00280 Obj = Str;
00281 }
00282
00283 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00284 {
00285 internal::FromString_ucharptr(Str, Obj);
00286 }
00287
00288 template<> inline void FromString(const char Str[], bool &Obj)
00289 {
00290 from_string(Str, Obj);
00291 }
00292
00293
00295
00304 PGSTD::string sqlesc(const char str[]);
00305
00307
00316 PGSTD::string sqlesc(const char str[], size_t maxlen);
00317
00319
00325 PGSTD::string sqlesc(const PGSTD::string &);
00326
00327
00329
00333 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00334
00335
00337
00339 template<>
00340 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00341 {
00342 return internal::Quote_string(Obj, EmptyIsNull);
00343 }
00344
00346
00348 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00349 {
00350 return internal::Quote_charptr(Obj, EmptyIsNull);
00351 }
00352
00353
00355
00360 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00361 bool EmptyIsNull)
00362 {
00363 return internal::Quote_charptr(Obj, EmptyIsNull);
00364 }
00365
00366
00371 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00372 {
00373 return Quote(ToString(Obj), EmptyIsNull);
00374 }
00375
00376
00378
00381 template<typename T> inline PGSTD::string Quote(T Obj)
00382 {
00383 return Quote(Obj, false);
00384 }
00385
00386
00387 namespace internal
00388 {
00389 void freepqmem(void *);
00390 void freenotif(PGnotify *);
00391
00393
00399 template<typename T> class PQAlloc
00400 {
00401 T *m_Obj;
00402 public:
00403 typedef T content_type;
00404
00405 PQAlloc() : m_Obj(0) {}
00406
00408 explicit PQAlloc(T *obj) : m_Obj(obj) {}
00409
00410 ~PQAlloc() throw () { close(); }
00411
00413
00415 PQAlloc &operator=(T *obj) throw ()
00416 {
00417 if (obj != m_Obj)
00418 {
00419 close();
00420 m_Obj = obj;
00421 }
00422 return *this;
00423 }
00424
00426 operator bool() const throw () { return m_Obj != 0; }
00427
00429 bool operator!() const throw () { return !m_Obj; }
00430
00432
00434 T *operator->() const throw (PGSTD::logic_error)
00435 {
00436 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00437 return m_Obj;
00438 }
00439
00441
00443 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00444
00446
00448 T *c_ptr() const throw () { return m_Obj; }
00449
00451 void close() throw () { if (m_Obj) freemem(); m_Obj = 0; }
00452
00453 private:
00454 void freemem() throw ()
00455 {
00456 freepqmem(m_Obj);
00457 }
00458
00459 PQAlloc(const PQAlloc &);
00460 PQAlloc &operator=(const PQAlloc &);
00461 };
00462
00463
00465 template<> inline void PQAlloc<PGnotify>::freemem() throw ()
00466 {
00467 freenotif(m_Obj);
00468 }
00469
00470
00471 class PQXX_LIBEXPORT namedclass
00472 {
00473 public:
00474 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00475 m_Name(Name),
00476 m_Classname(Classname)
00477 {
00478 }
00479
00480 const PGSTD::string &name() const throw () { return m_Name; }
00481 const PGSTD::string &classname() const throw () {return m_Classname;}
00482 PGSTD::string description() const throw ();
00483
00484 private:
00485 PGSTD::string m_Name, m_Classname;
00486 };
00487
00488
00489 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00490 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00491
00492
00494
00497 template<typename GUEST>
00498 class unique
00499 {
00500 public:
00501 unique() : m_Guest(0) {}
00502
00503 GUEST *get() const throw () { return m_Guest; }
00504
00505 void Register(GUEST *G)
00506 {
00507 CheckUniqueRegistration(G, m_Guest);
00508 m_Guest = G;
00509 }
00510
00511 void Unregister(GUEST *G)
00512 {
00513 CheckUniqueUnregistration(G, m_Guest);
00514 m_Guest = 0;
00515 }
00516
00517 private:
00518 GUEST *m_Guest;
00519
00521 unique(const unique &);
00523 unique &operator=(const unique &);
00524 };
00525
00526 }
00527 }
00528