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
00068 namespace internal
00069 {
00071
00077 template<typename T> inline const char *FmtString(T t)
00078 {
00079 error_unsupported_type_in_string_conversion(t);
00080 return 0;
00081 }
00082
00083
00084
00085
00086 template<> inline const char *FmtString(short) { return "%hd"; }
00087 template<> inline const char *FmtString(unsigned short){ return "%hu"; }
00088 template<> inline const char *FmtString(int) { return "%i"; }
00089 template<> inline const char *FmtString(long) { return "%li"; }
00090 template<> inline const char *FmtString(unsigned) { return "%u"; }
00091 template<> inline const char *FmtString(unsigned long) { return "%lu"; }
00092 template<> inline const char *FmtString(float) { return "%f"; }
00093 template<> inline const char *FmtString(double) { return "%lf"; }
00094 template<> inline const char *FmtString(long double) { return "%Lf"; }
00095 template<> inline const char *FmtString(char) { return "%c"; }
00096 template<> inline const char *FmtString(unsigned char) { return "%c"; }
00097
00098 }
00099
00101
00108 template<typename T> inline PGSTD::string ToString(const T &Obj)
00109 {
00110
00111 char Buf[500];
00112 sprintf(Buf, internal::FmtString(Obj), Obj);
00113 return PGSTD::string(Buf);
00114 }
00115
00116
00117
00118 template<> inline PGSTD::string ToString(const PGSTD::string &Obj) {return Obj;}
00119 template<> inline PGSTD::string ToString(const char *const &Obj) { return Obj; }
00120 template<> inline PGSTD::string ToString(char *const &Obj) { return Obj; }
00121
00122 template<> inline PGSTD::string ToString(const unsigned char *const &Obj)
00123 {
00124 return reinterpret_cast<const char *>(Obj);
00125 }
00126
00127 template<> inline PGSTD::string ToString(const bool &Obj)
00128 {
00129 return ToString(unsigned(Obj));
00130 }
00131
00132 template<> inline PGSTD::string ToString(const short &Obj)
00133 {
00134 return ToString(int(Obj));
00135 }
00136
00137 template<> inline PGSTD::string ToString(const unsigned short &Obj)
00138 {
00139 return ToString(unsigned(Obj));
00140 }
00141
00142
00144
00151 template<typename T> inline void FromString(const char Str[], T &Obj)
00152 {
00153 if (!Str) throw PGSTD::runtime_error("Attempt to convert NULL string to " +
00154 PGSTD::string(typeid(T).name()));
00155
00156 if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00157 throw PGSTD::runtime_error("Cannot convert value '" +
00158 PGSTD::string(Str) +
00159 "' to " + typeid(T).name());
00160 }
00161
00162
00163 namespace internal
00164 {
00166 void PQXX_LIBEXPORT FromString_string(const char Str[], PGSTD::string &Obj);
00167
00169 void PQXX_LIBEXPORT FromString_ucharptr(const char Str[],
00170 const unsigned char *&Obj);
00171
00173 void PQXX_LIBEXPORT FromString_bool(const char Str[], bool &Obj);
00174
00176 PGSTD::string PQXX_LIBEXPORT Quote_string(const PGSTD::string &Obj,
00177 bool EmptyIsNull);
00178
00180 PGSTD::string PQXX_LIBEXPORT Quote_charptr(const char Obj[], bool EmptyIsNull);
00181 }
00182
00183
00184 template<> inline void FromString(const char Str[], PGSTD::string &Obj)
00185 {
00186 internal::FromString_string(Str, Obj);
00187 }
00188
00189 template<> inline void FromString(const char Str[], const char *&Obj)
00190 {
00191 if (!Str) throw PGSTD::runtime_error("Attempt to read NULL string");
00192 Obj = Str;
00193 }
00194
00195 template<> inline void FromString(const char Str[], const unsigned char *&Obj)
00196 {
00197 internal::FromString_ucharptr(Str, Obj);
00198 }
00199
00200 template<> inline void FromString(const char Str[], bool &Obj)
00201 {
00202 internal::FromString_bool(Str, Obj);
00203 }
00204
00205
00207
00210 template<typename T> PGSTD::string Quote(const T &Obj, bool EmptyIsNull);
00211
00212
00214 template<>
00215 inline PGSTD::string Quote(const PGSTD::string &Obj, bool EmptyIsNull)
00216 {
00217 return internal::Quote_string(Obj, EmptyIsNull);
00218 }
00219
00221 template<> inline PGSTD::string Quote(const char *const & Obj, bool EmptyIsNull)
00222 {
00223 return internal::Quote_charptr(Obj, EmptyIsNull);
00224 }
00225
00226
00228
00233 template<int LEN> inline PGSTD::string Quote(const char (&Obj)[LEN],
00234 bool EmptyIsNull)
00235 {
00236 return internal::Quote_charptr(Obj, EmptyIsNull);
00237 }
00238
00239
00243 template<typename T> inline PGSTD::string Quote(const T &Obj, bool EmptyIsNull)
00244 {
00245 return Quote(ToString(Obj), EmptyIsNull);
00246 }
00247
00248
00250
00252 template<typename T> inline PGSTD::string Quote(T Obj)
00253 {
00254 return Quote(Obj, false);
00255 }
00256
00257
00258 namespace internal
00259 {
00261
00267 template<typename T> class PQAlloc
00268 {
00269 T *m_Obj;
00270 public:
00271 typedef T content_type;
00272
00273 PQAlloc() : m_Obj(0) {}
00274
00276 explicit PQAlloc(T *obj) : m_Obj(obj) {}
00277
00278 ~PQAlloc() throw () { close(); }
00279
00281
00283 PQAlloc &operator=(T *obj) throw ()
00284 {
00285 if (obj != m_Obj)
00286 {
00287 close();
00288 m_Obj = obj;
00289 }
00290 return *this;
00291 }
00292
00294 operator bool() const throw () { return m_Obj != 0; }
00295
00297 bool operator!() const throw () { return !m_Obj; }
00298
00300
00302 T *operator->() const throw (PGSTD::logic_error)
00303 {
00304 if (!m_Obj) throw PGSTD::logic_error("Null pointer dereferenced");
00305 return m_Obj;
00306 }
00307
00309
00311 T &operator*() const throw (PGSTD::logic_error) { return *operator->(); }
00312
00314
00316 T *c_ptr() const throw () { return m_Obj; }
00317
00319 void close() throw () { if (m_Obj) freemem(); m_Obj = 0; }
00320
00321 private:
00322 void freemem() throw ()
00323 {
00324 #if defined(PQXX_HAVE_PQFREEMEM)
00325 PQfreemem(reinterpret_cast<unsigned char *>(m_Obj));
00326 #else
00327 free(m_Obj);
00328 #endif
00329 }
00330
00331 PQAlloc(const PQAlloc &);
00332 PQAlloc &operator=(const PQAlloc &);
00333 };
00334
00335
00337 template<> inline void PQAlloc<PGnotify>::freemem() throw ()
00338 {
00339 #if defined(PQXX_HAVE_PQFREEMEM)
00340 PQfreemem(reinterpret_cast<unsigned char *>(m_Obj));
00341 #elif defined(PQXX_HAVE_PQFREENOTIFY)
00342 PQfreeNotify(m_Obj);
00343 #else
00344 free(m_Obj);
00345 #endif
00346 }
00347
00348
00349 class PQXX_LIBEXPORT namedclass
00350 {
00351 public:
00352 namedclass(const PGSTD::string &Name, const PGSTD::string &Classname) :
00353 m_Name(Name),
00354 m_Classname(Classname)
00355 {
00356 }
00357
00358 const PGSTD::string &name() const throw () { return m_Name; }
00359 const PGSTD::string &classname() const throw () {return m_Classname;}
00360 PGSTD::string description() const throw ();
00361
00362 private:
00363 PGSTD::string m_Name, m_Classname;
00364 };
00365
00366
00367 void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00368 void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00369
00370
00372
00375 template<typename GUEST>
00376 class unique
00377 {
00378 public:
00379 unique() : m_Guest(0) {}
00380
00381 GUEST *get() const throw () { return m_Guest; }
00382
00383 void Register(GUEST *G)
00384 {
00385 CheckUniqueRegistration(G, m_Guest);
00386 m_Guest = G;
00387 }
00388
00389 void Unregister(GUEST *G)
00390 {
00391 CheckUniqueUnregistration(G, m_Guest);
00392 m_Guest = 0;
00393 }
00394
00395 private:
00396 GUEST *m_Guest;
00397
00399 unique(const unique &);
00401 unique &operator=(const unique &);
00402 };
00403
00404 }
00405 }
00406