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 <sstream>
00023
#include <stdexcept>
00024
#include <string>
00025
#include <typeinfo>
00026
#include <vector>
00027
00028
extern "C"
00029 {
00030
#include "libpq-fe.h"
00031 }
00032
00033
00035
namespace pqxx
00036 {
00037 typedef long result_size_type;
00038 typedef int tuple_size_type;
00039
00041 typedef Oid
oid;
00042
00044 const oid oid_none = InvalidOid;
00045
00046
00048
00061
template<
typename T>
void error_unsupported_type_in_string_conversion(T);
00062
00063
00065
00071
template<
typename T> PGSTD::string
error_ambiguous_string_conversion(T);
00072
00073
00074
00075
00076
00078
00087
template<
typename T>
void from_string(
const char Str[], T &Obj);
00088
00089
template<>
void from_string(
const char Str[],
long &);
00090
template<>
void from_string(
const char Str[],
unsigned long &);
00091
template<>
void from_string(
const char Str[],
int &);
00092
template<>
void from_string(
const char Str[],
unsigned int &);
00093
template<>
void from_string(
const char Str[],
short &);
00094
template<>
void from_string(
const char Str[],
unsigned short &);
00095
template<>
void from_string(
const char Str[],
float &);
00096
template<>
void from_string(
const char Str[],
double &);
00097
template<>
void from_string(
const char Str[],
long double &);
00098
template<>
void from_string(
const char Str[],
bool &);
00099
00100 template<>
inline void from_string(
const char Str[],PGSTD::string &Obj)
00101 { Obj = Str; }
00102
00103
template<>
00104 inline void from_string(
const char Str[], PGSTD::stringstream &Obj)
00105 { Obj.clear(); Obj << Str; }
00106
00107
template<
typename T>
00108 inline void from_string(
const PGSTD::string &Str, T &Obj)
00109 {
from_string(Str.c_str(), Obj); }
00110
00111
template<
typename T>
00112 inline void from_string(
const PGSTD::stringstream &Str, T &Obj)
00113 {
from_string(Str.str(), Obj); }
00114
00115
template<>
inline void
00116 from_string(
const PGSTD::string &Str, PGSTD::string &Obj)
00117 { Obj = Str; }
00118
00119
template<>
inline void
00120 from_string(
const PGSTD::string &,
const signed char &Obj)
00121 {
error_ambiguous_string_conversion(Obj); }
00122
template<>
inline void
00123 from_string(
const PGSTD::string &,
const unsigned char &Obj)
00124 {
error_ambiguous_string_conversion(Obj); }
00125
00126
00128
00132
template<
typename T> PGSTD::string
to_string(
const T &);
00133
00134
template<> PGSTD::string
to_string(
const short &);
00135
template<> PGSTD::string
to_string(
const unsigned short &);
00136
template<> PGSTD::string
to_string(
const int &);
00137
template<> PGSTD::string
to_string(
const unsigned int &);
00138
template<> PGSTD::string
to_string(
const long &);
00139
template<> PGSTD::string
to_string(
const unsigned long &);
00140
template<> PGSTD::string
to_string(
const float &);
00141
template<> PGSTD::string
to_string(
const double &);
00142
template<> PGSTD::string
to_string(
const long double &);
00143
template<> PGSTD::string
to_string(
const bool &);
00144
00145 inline PGSTD::string
to_string(
const char Obj[])
00146 {
return PGSTD::string(Obj); }
00147
00148 inline PGSTD::string
to_string(
const PGSTD::stringstream &Obj)
00149 {
return Obj.str(); }
00150
00151 inline PGSTD::string
to_string(
const PGSTD::string &Obj) {
return Obj;}
00152
00153
template<> PGSTD::string
to_string(
const char &);
00154
00155
00156 template<>
inline PGSTD::string
to_string(
const signed char &Obj)
00157 {
return error_ambiguous_string_conversion(Obj); }
00158 template<>
inline PGSTD::string
to_string(
const unsigned char &Obj)
00159 {
return error_ambiguous_string_conversion(Obj); }
00160
00161
00163
00177
template<
typename T=PGSTD::string,
typename CONT=PGSTD::vector<T> >
00178 class items :
public CONT
00179 {
00180
public:
00182 items() : CONT() {}
00184 explicit items(
const T &t) : CONT() { push_back(t); }
00185 items(
const T &t1,
const T &t2) : CONT()
00186 { push_back(t1); push_back(t2); }
00187 items(
const T &t1,
const T &t2,
const T &t3) : CONT()
00188 { push_back(t1); push_back(t2); push_back(t3); }
00189 items(
const T &t1,
const T &t2,
const T &t3,
const T &t4) : CONT()
00190 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00191 items(
const T&t1,
const T&t2,
const T&t3,
const T&t4,
const T&t5):CONT()
00192 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00194 items(
const CONT &c) : CONT(c) {}
00195
00197 items &
operator()(
const T &t)
00198 {
00199 push_back(t);
00200
return *
this;
00201 }
00202 };
00203
00204
00205
00207
template<
typename ITER>
inline
00208 PGSTD::string
separated_list(
const PGSTD::string &sep,
00209 ITER begin,
00210 ITER end)
00211 {
00212 PGSTD::string
result;
00213
if (begin != end)
00214 {
00215 result =
to_string(*begin);
00216
for (++begin; begin != end; ++begin)
00217 {
00218 result += sep;
00219 result +=
to_string(*begin);
00220 }
00221 }
00222
return result;
00223 }
00224
00226
template<
typename CONTAINER>
inline
00227 PGSTD::string
separated_list(
const PGSTD::string &sep,
00228
const CONTAINER &c)
00229 {
00230
return separated_list(sep, c.begin(), c.end());
00231 }
00232
00233
00235
00240
namespace internal
00241 {
00243
00251 template<
typename T>
inline const char *
FmtString(T t)
00252 {
00253
error_unsupported_type_in_string_conversion(t);
00254
return 0;
00255 }
00256
00257 template<>
inline const char *
FmtString(
short) {
return "%hd"; }
00258 template<>
inline const char *
FmtString(
unsigned short){
return "%hu"; }
00259 template<>
inline const char *
FmtString(
int) {
return "%i"; }
00260 template<>
inline const char *
FmtString(
long) {
return "%li"; }
00261
template<>
inline const char *
FmtString(
unsigned) {
return "%u"; }
00262
template<>
inline const char *
FmtString(
unsigned long) {
return "%lu"; }
00263 template<>
inline const char *
FmtString(
float) {
return "%f"; }
00264 template<>
inline const char *
FmtString(
double) {
return "%lf"; }
00265
template<>
inline const char *
FmtString(
long double) {
return "%Lf"; }
00266 template<>
inline const char *
FmtString(
char) {
return "%c"; }
00267
template<>
inline const char *
FmtString(
unsigned char) {
return "%c"; }
00268
00269 }
00270
00272
00280 template<
typename T>
inline PGSTD::string
ToString(
const T &Obj)
00281 {
00282
00283
char Buf[500];
00284 sprintf(Buf, internal::FmtString(Obj), Obj);
00285
return PGSTD::string(Buf);
00286 }
00287
00288
00289 template<>
inline PGSTD::string
ToString(
const PGSTD::string &Obj) {
return Obj;}
00290 template<>
inline PGSTD::string
ToString(
const char *
const &Obj) {
return Obj; }
00291 template<>
inline PGSTD::string
ToString(
char *
const &Obj) {
return Obj; }
00292
00293 template<>
inline PGSTD::string
ToString(
const unsigned char *
const &Obj)
00294 {
00295
return reinterpret_cast<const char *>(Obj);
00296 }
00297
00298 template<>
inline PGSTD::string
ToString(
const bool &Obj)
00299 {
00300
return ToString(
unsigned(Obj));
00301 }
00302
00303 template<>
inline PGSTD::string
ToString(
const short &Obj)
00304 {
00305
return ToString(
int(Obj));
00306 }
00307
00308 template<>
inline PGSTD::string
ToString(
const unsigned short &Obj)
00309 {
00310
return ToString(
unsigned(Obj));
00311 }
00312
00313
00315
00323 template<
typename T>
inline void FromString(
const char Str[], T &Obj)
00324 {
00325
if (!Str)
throw PGSTD::runtime_error(
"Attempt to convert NULL string to " +
00326 PGSTD::string(
typeid(T).name()));
00327
00328
if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00329
throw PGSTD::runtime_error(
"Cannot convert value '" +
00330 PGSTD::string(Str) +
00331
"' to " +
typeid(T).name());
00332 }
00333
00334
00335
namespace internal
00336 {
00338
00340
void PQXX_LIBEXPORT
FromString_string(
const char Str[], PGSTD::string &Obj);
00341
00343
00345
void PQXX_LIBEXPORT
FromString_ucharptr(
const char Str[],
00346
const unsigned char *&Obj);
00347
00349 PGSTD::string PQXX_LIBEXPORT
Quote_string(
const PGSTD::string &Obj,
00350
bool EmptyIsNull);
00351
00353 PGSTD::string PQXX_LIBEXPORT
Quote_charptr(
const char Obj[],
bool EmptyIsNull);
00354 }
00355
00356
00357 template<>
inline void FromString(
const char Str[], PGSTD::string &Obj)
00358 {
00359 internal::FromString_string(Str, Obj);
00360 }
00361
00362 template<>
inline void FromString(
const char Str[],
const char *&Obj)
00363 {
00364
if (!Str)
throw PGSTD::runtime_error(
"Attempt to read NULL string");
00365 Obj = Str;
00366 }
00367
00368 template<>
inline void FromString(
const char Str[],
const unsigned char *&Obj)
00369 {
00370 internal::FromString_ucharptr(Str, Obj);
00371 }
00372
00373 template<>
inline void FromString(
const char Str[],
bool &Obj)
00374 {
00375
from_string(Str, Obj);
00376 }
00377
00378
00380
00389 PGSTD::string
sqlesc(
const char str[]);
00390
00392
00402 PGSTD::string
sqlesc(
const char str[], size_t maxlen);
00403
00405
00411 PGSTD::string
sqlesc(
const PGSTD::string &);
00412
00413
00415
00419
template<
typename T> PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull);
00420
00421
00423
00425
template<>
00426 inline PGSTD::string
Quote(
const PGSTD::string &Obj,
bool EmptyIsNull)
00427 {
00428
return internal::Quote_string(Obj, EmptyIsNull);
00429 }
00430
00432
00434 template<>
inline PGSTD::string
Quote(
const char *
const & Obj,
bool EmptyIsNull)
00435 {
00436
return internal::Quote_charptr(Obj, EmptyIsNull);
00437 }
00438
00439
00441
00446 template<
int LEN>
inline PGSTD::string
Quote(
const char (&Obj)[LEN],
00447
bool EmptyIsNull)
00448 {
00449
return internal::Quote_charptr(Obj, EmptyIsNull);
00450 }
00451
00452
00457 template<
typename T>
inline PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull)
00458 {
00459
return Quote(
ToString(Obj), EmptyIsNull);
00460 }
00461
00462
00464
00467 template<
typename T>
inline PGSTD::string
Quote(T Obj)
00468 {
00469
return Quote(Obj,
false);
00470 }
00471
00472
00473
namespace internal
00474 {
00475
void freepqmem(
void *);
00476
void freenotif(PGnotify *);
00477
00479
00485 template<
typename T>
class PQAlloc
00486 {
00487 T *m_Obj;
00488
public:
00489 typedef T
content_type;
00490
00491 PQAlloc() : m_Obj(0) {}
00492
00494 explicit PQAlloc(T *obj) : m_Obj(obj) {}
00495
00496 ~PQAlloc() throw () {
close(); }
00497
00499
00501 PQAlloc &operator=(T *obj)
throw ()
00502 {
00503
if (obj != m_Obj)
00504 {
00505
close();
00506 m_Obj = obj;
00507 }
00508
return *
this;
00509 }
00510
00512 operator bool() const throw () {
return m_Obj != 0; }
00513
00515 bool operator!() const throw () {
return !m_Obj; }
00516
00518
00520 T *
operator->() const throw (PGSTD::logic_error)
00521 {
00522
if (!m_Obj)
throw PGSTD::logic_error(
"Null pointer dereferenced");
00523
return m_Obj;
00524 }
00525
00527
00529 T &
operator*() const throw (PGSTD::logic_error) {
return *
operator->(); }
00530
00532
00534 T *
c_ptr() const throw () {
return m_Obj; }
00535
00537 void close() throw () {
if (m_Obj) freemem(); m_Obj = 0; }
00538
00539
private:
00540
void freemem() throw ()
00541 {
00542
freepqmem(m_Obj);
00543 }
00544
00545
PQAlloc(
const PQAlloc &);
00546 PQAlloc &operator=(
const PQAlloc &);
00547 };
00548
00549
00551
template<>
inline void PQAlloc<PGnotify>::freemem() throw ()
00552 {
00553
freenotif(m_Obj);
00554 }
00555
00556
00557 class PQXX_LIBEXPORT namedclass
00558 {
00559
public:
00560 namedclass(
const PGSTD::string &Name,
const PGSTD::string &Classname) :
00561 m_Name(Name),
00562 m_Classname(Classname)
00563 {
00564 }
00565
00566 const PGSTD::string &name() const throw () {
return m_Name; }
00567 const PGSTD::string &classname() const throw () {
return m_Classname;}
00568 PGSTD::string description() const throw ();
00569
00570 private:
00571 PGSTD::string m_Name, m_Classname;
00572 };
00573
00574
00575
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00576
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00577
00578
00580
00583 template<typename GUEST>
00584 class
unique
00585 {
00586
public:
00587 unique() : m_Guest(0) {}
00588
00589 GUEST *get() const throw () {
return m_Guest; }
00590
00591 void Register(GUEST *G)
00592 {
00593
CheckUniqueRegistration(G, m_Guest);
00594 m_Guest = G;
00595 }
00596
00597 void Unregister(GUEST *G)
00598 {
00599
CheckUniqueUnregistration(G, m_Guest);
00600 m_Guest = 0;
00601 }
00602
00603
private:
00604 GUEST *m_Guest;
00605
00607 unique(
const unique &);
00609 unique &operator=(
const unique &);
00610 };
00611
00612 }
00613 }
00614