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
00032 namespace pqxx
00033 {
00034 typedef long result_size_type;
00035 typedef int tuple_size_type;
00036
00038 typedef Oid oid;
00039
00041 const oid oid_none = InvalidOid;
00042
00043
00045
00058 template<typename T> void error_unsupported_type_in_string_conversion(T);
00059
00060
00062
00068 template<typename T> inline const char *FmtString(T t)
00069 {
00070 error_unsupported_type_in_string_conversion(t);
00071 return 0;
00072 }
00073
00074
00075
00076
00077 template<> inline const char *FmtString(short) { return "%hd"; }
00078 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00079 template<> inline const char *FmtString(int) { return "%i"; }
00080 template<> inline const char *FmtString(long) { return "%li"; }
00081 template<> inline const char *FmtString(unsigned) { return "%u"; }
00082 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00083 template<> inline const char *FmtString(float) { return "%f"; }
00084 template<> inline const char *FmtString(double) { return "%lf"; }
00085 template<> inline const char *FmtString(long double) { return "%Lf"; }
00086 template<> inline const char *FmtString(char) { return "%c"; }
00087 template<> inline const char *FmtString(unsigned char) { return "%c"; }
00088
00089
00091
00098 template<typename T> inline PGSTD::string ToString(const T &Obj)
00099 {
00100
00101 char Buf[500];
00102 sprintf(Buf, FmtString(Obj), Obj);
00103 return PGSTD::string(Buf);
00104 }
00105
00106
00107
00108 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00109 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00110 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00111
00112 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00113 {
00114 return reinterpret_cast<const char *>(Obj);
00115 }
00116
00117 template<> inline PGSTD::string ToString(const bool &Obj)
00118 {
00119 return ToString(unsigned(Obj));
00120 }
00121
00122 template<> inline PGSTD::string ToString(const short &Obj)
00123 {
00124 return ToString(int(Obj));
00125 }
00126
00127 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00128 {
00129 return ToString(unsigned(Obj));
00130 }
00131
00132
00134
00141 template<typename T> inline void FromString(const char Str[], T &Obj)
00142 {
00143 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00144 PGSTD::string(typeid(T).name()));
00145
00146 if (sscanf(Str, FmtString(Obj), &Obj) != 1)
00147 throw PGSTD::runtime_error("Cannot convert value '" +
00148 PGSTD::string(Str) +
00149 "' to " + typeid(T).name());
00150 }
00151
00152
00154 void FromString_string(const char Str[], PGSTD::string &Obj);
00155
00156
00157 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00158 {
00159 FromString_string(Str, Obj);
00160 }
00161
00162
00163 template<> inline void FromString(const char Str[], const char *&Obj)
00164 {
00165 if (!Str)
00166 throw PGSTD::runtime_error("Attempt to read NULL string");
00167 Obj = Str;
00168 }
00169
00170
00171 void FromString_ucharptr(const char Str[], const unsigned char *&Obj);
00172
00173 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00174 {
00175 FromString_ucharptr(Str, Obj);
00176 }
00177
00178
00180 void FromString_bool(const char Str[], bool &Obj);
00181
00182 template<> inline void FromString(const char Str[], bool &Obj)
00183 {
00184 FromString_bool(Str, Obj);
00185 }
00186
00187
00189
00192 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00193
00194
00196 PGSTD::string Quote_string(const PGSTD::string &Obj, bool EmptyIsNull);
00197
00198
00200 template<>
00201 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00202 {
00203 return Quote_string(Obj, EmptyIsNull);
00204 }
00205
00207 PGSTD::string Quote_charptr(const char Obj[], bool EmptyIsNull);
00208
00209
00211 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00212 {
00213 return Quote_charptr(Obj, EmptyIsNull);
00214 }
00215
00216
00218
00223 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00224 bool EmptyIsNull)
00225 {
00226 return Quote_charptr(Obj, EmptyIsNull);
00227 }
00228
00229
00233 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00234 {
00235 return Quote(ToString(Obj), EmptyIsNull);
00236 }
00237
00238
00240
00242 template<typename T> inline PGSTD::string Quote(T Obj)
00243 {
00244 return Quote(Obj, false);
00245 }
00246
00247
00249 template<typename T> PGSTD::string Classname(const T *);
00250
00251
00253
00259 template<typename T> class PQAlloc
00260 {
00261 T *m_Obj;
00262 public:
00263 typedef T content_type;
00264
00265 PQAlloc() : m_Obj(0) {}
00266
00268 explicit PQAlloc(T *obj) : m_Obj(obj) {}
00269
00270 ~PQAlloc() { close(); }
00271
00273
00275 PQAlloc &operator=(T *obj) throw ()
00276 {
00277 if (obj != m_Obj)
00278 {
00279 close();
00280 m_Obj = obj;
00281 }
00282 return *this;
00283 }
00284
00286 operator bool() const throw () { return m_Obj != 0; }
00287
00289 bool operator!() const throw () { return !m_Obj; }
00290
00292
00294 T *operator->() const throw (PGSTD::logic_error)
00295 {
00296 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00297 return m_Obj;
00298 }
00299
00301
00303 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00304
00306
00308 T *c_ptr() const throw () { return m_Obj; }
00309
00311 void close() throw () { if (m_Obj) freemem(); m_Obj = 0; }
00312
00313 private:
00314 void freemem() throw ()
00315 {
00316 #if defined(PQXX_HAVE_PQFREEMEM)
00317 PQfreemem(reinterpret_cast<unsigned char *>(m_Obj));
00318 #else
00319 free(m_Obj);
00320 #endif
00321 }
00322
00323 PQAlloc(const PQAlloc &);
00324 PQAlloc &operator=(const PQAlloc &);
00325 };
00326
00327
00329 template<> inline void PQAlloc<PGnotify>::freemem() throw ()
00330 {
00331 #if defined(PQXX_HAVE_PQFREEMEM)
00332 PQfreemem(reinterpret_cast<unsigned char *>(m_Obj));
00333 #elif defined(PQXX_HAVE_PQFREENOTIFY)
00334 PQfreeNotify(m_Obj);
00335 #else
00336 free(m_Obj);
00337 #endif
00338 }
00339
00340
00342 PGSTD::string UniqueRegisterError(const void *New,
00343 const void *Old,
00344 const PGSTD::string &ClassName,
00345 const PGSTD::string &NewName);
00346
00348 PGSTD::string UniqueUnregisterError(const void *New,
00349 const void *Old,
00350 const PGSTD::string &ClassName,
00351 const PGSTD::string &NewName,
00352 const PGSTD::string &OldName);
00353
00354
00356
00363 template<typename GUEST>
00364 class unique
00365 {
00366 public:
00367 unique() : m_Guest(0) {}
00368
00369 GUEST *get() const throw () { return m_Guest; }
00370
00371 void Register(GUEST *G)
00372 {
00373 if (!G || m_Guest)
00374 throw PGSTD::logic_error(UniqueRegisterError(G,
00375 m_Guest,
00376 Classname(G),
00377 (G ? G->name() : "")));
00378
00379 m_Guest = G;
00380 }
00381
00382 void Unregister(GUEST *G)
00383 {
00384 if (G != m_Guest)
00385 throw PGSTD::logic_error(UniqueUnregisterError(G,
00386 m_Guest,
00387 Classname(G),
00388 (G ? G->name() : ""),
00389 (m_Guest ? m_Guest->name() : "")));
00390
00391 m_Guest = 0;
00392 }
00393
00394 private:
00395 GUEST *m_Guest;
00396
00397
00398 unique(const unique &);
00399 unique &operator=(const unique &);
00400 };
00401
00402 }
00403
00404