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 char &Obj)
00121 {
error_ambiguous_string_conversion(Obj); }
00122
template<>
inline void
00123 from_string(
const PGSTD::string &,
const signed char &Obj)
00124 {
error_ambiguous_string_conversion(Obj); }
00125
template<>
inline void
00126 from_string(
const PGSTD::string &,
const unsigned char &Obj)
00127 {
error_ambiguous_string_conversion(Obj); }
00128
00129
00131
00135
template<
typename T> PGSTD::string
to_string(
const T &);
00136
00137
template<> PGSTD::string
to_string(
const short &);
00138
template<> PGSTD::string
to_string(
const unsigned short &);
00139
template<> PGSTD::string
to_string(
const int &);
00140
template<> PGSTD::string
to_string(
const unsigned int &);
00141
template<> PGSTD::string
to_string(
const long &);
00142
template<> PGSTD::string
to_string(
const unsigned long &);
00143
template<> PGSTD::string
to_string(
const float &);
00144
template<> PGSTD::string
to_string(
const double &);
00145
template<> PGSTD::string
to_string(
const long double &);
00146
template<> PGSTD::string
to_string(
const bool &);
00147
00148 inline PGSTD::string
to_string(
const char Obj[])
00149 {
return PGSTD::string(Obj); }
00150
00151 inline PGSTD::string
to_string(
const PGSTD::stringstream &Obj)
00152 {
return Obj.str(); }
00153
00154 inline PGSTD::string
to_string(
const PGSTD::string &Obj) {
return Obj;}
00155
00156
template<> PGSTD::string
to_string(
const char &);
00157
00158
00159 template<>
inline PGSTD::string
to_string(
const signed char &Obj)
00160 {
return error_ambiguous_string_conversion(Obj); }
00161 template<>
inline PGSTD::string
to_string(
const unsigned char &Obj)
00162 {
return error_ambiguous_string_conversion(Obj); }
00163
00164
00166
00180
template<
typename T=PGSTD::string,
typename CONT=PGSTD::vector<T> >
00181 class items :
public CONT
00182 {
00183
public:
00185 items() : CONT() {}
00187 explicit items(
const T &t) : CONT() { push_back(t); }
00188 items(
const T &t1,
const T &t2) : CONT()
00189 { push_back(t1); push_back(t2); }
00190 items(
const T &t1,
const T &t2,
const T &t3) : CONT()
00191 { push_back(t1); push_back(t2); push_back(t3); }
00192 items(
const T &t1,
const T &t2,
const T &t3,
const T &t4) : CONT()
00193 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00194 items(
const T&t1,
const T&t2,
const T&t3,
const T&t4,
const T&t5):CONT()
00195 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00197 items(
const CONT &c) : CONT(c) {}
00198
00200 items &
operator()(
const T &t)
00201 {
00202 push_back(t);
00203
return *
this;
00204 }
00205 };
00206
00207
00208
00210
template<
typename ITER>
inline
00211 PGSTD::string
separated_list(
const PGSTD::string &sep,
00212 ITER begin,
00213 ITER end)
00214 {
00215 PGSTD::string
result;
00216
if (begin != end)
00217 {
00218 result =
to_string(*begin);
00219
for (++begin; begin != end; ++begin)
00220 {
00221 result += sep;
00222 result +=
to_string(*begin);
00223 }
00224 }
00225
return result;
00226 }
00227
00229
template<
typename CONTAINER>
inline
00230 PGSTD::string
separated_list(
const PGSTD::string &sep,
00231
const CONTAINER &c)
00232 {
00233
return separated_list(sep, c.begin(), c.end());
00234 }
00235
00236
00238
00243
namespace internal
00244 {
00246
00254 template<
typename T>
inline const char *
FmtString(T t)
00255 {
00256
error_unsupported_type_in_string_conversion(t);
00257
return 0;
00258 }
00259
00260 template<>
inline const char *
FmtString(
short) {
return "%hd"; }
00261 template<>
inline const char *
FmtString(
unsigned short){
return "%hu"; }
00262 template<>
inline const char *
FmtString(
int) {
return "%i"; }
00263 template<>
inline const char *
FmtString(
long) {
return "%li"; }
00264
template<>
inline const char *
FmtString(
unsigned) {
return "%u"; }
00265
template<>
inline const char *
FmtString(
unsigned long) {
return "%lu"; }
00266 template<>
inline const char *
FmtString(
float) {
return "%f"; }
00267 template<>
inline const char *
FmtString(
double) {
return "%lf"; }
00268
template<>
inline const char *
FmtString(
long double) {
return "%Lf"; }
00269 template<>
inline const char *
FmtString(
char) {
return "%c"; }
00270
template<>
inline const char *
FmtString(
unsigned char) {
return "%c"; }
00271
00272 }
00273
00275
00283 template<
typename T>
inline PGSTD::string
ToString(
const T &Obj)
00284 {
00285
00286
char Buf[500];
00287 sprintf(Buf, internal::FmtString(Obj), Obj);
00288
return PGSTD::string(Buf);
00289 }
00290
00291
00292 template<>
inline PGSTD::string
ToString(
const PGSTD::string &Obj) {
return Obj;}
00293 template<>
inline PGSTD::string
ToString(
const char *
const &Obj) {
return Obj; }
00294 template<>
inline PGSTD::string
ToString(
char *
const &Obj) {
return Obj; }
00295
00296 template<>
inline PGSTD::string
ToString(
const unsigned char *
const &Obj)
00297 {
00298
return reinterpret_cast<const char *>(Obj);
00299 }
00300
00301 template<>
inline PGSTD::string
ToString(
const bool &Obj)
00302 {
00303
return ToString(
unsigned(Obj));
00304 }
00305
00306 template<>
inline PGSTD::string
ToString(
const short &Obj)
00307 {
00308
return ToString(
int(Obj));
00309 }
00310
00311 template<>
inline PGSTD::string
ToString(
const unsigned short &Obj)
00312 {
00313
return ToString(
unsigned(Obj));
00314 }
00315
00316
00318
00326 template<
typename T>
inline void FromString(
const char Str[], T &Obj)
00327 {
00328
if (!Str)
throw PGSTD::runtime_error(
"Attempt to convert NULL string to " +
00329 PGSTD::string(
typeid(T).name()));
00330
00331
if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00332
throw PGSTD::runtime_error(
"Cannot convert value '" +
00333 PGSTD::string(Str) +
00334
"' to " +
typeid(T).name());
00335 }
00336
00337
00338
namespace internal
00339 {
00341
00343
void PQXX_LIBEXPORT
FromString_string(
const char Str[], PGSTD::string &Obj);
00344
00346
00348
void PQXX_LIBEXPORT
FromString_ucharptr(
const char Str[],
00349
const unsigned char *&Obj);
00350
00352 PGSTD::string PQXX_LIBEXPORT
Quote_string(
const PGSTD::string &Obj,
00353
bool EmptyIsNull);
00354
00356 PGSTD::string PQXX_LIBEXPORT
Quote_charptr(
const char Obj[],
bool EmptyIsNull);
00357 }
00358
00359
00360 template<>
inline void FromString(
const char Str[], PGSTD::string &Obj)
00361 {
00362 internal::FromString_string(Str, Obj);
00363 }
00364
00365 template<>
inline void FromString(
const char Str[],
const char *&Obj)
00366 {
00367
if (!Str)
throw PGSTD::runtime_error(
"Attempt to read NULL string");
00368 Obj = Str;
00369 }
00370
00371 template<>
inline void FromString(
const char Str[],
const unsigned char *&Obj)
00372 {
00373 internal::FromString_ucharptr(Str, Obj);
00374 }
00375
00376 template<>
inline void FromString(
const char Str[],
bool &Obj)
00377 {
00378
from_string(Str, Obj);
00379 }
00380
00381
00383
00392 PGSTD::string
sqlesc(
const char str[]);
00393
00395
00405 PGSTD::string
sqlesc(
const char str[], size_t maxlen);
00406
00408
00414 PGSTD::string
sqlesc(
const PGSTD::string &);
00415
00416
00418
00422
template<
typename T> PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull);
00423
00424
00426
00428
template<>
00429 inline PGSTD::string
Quote(
const PGSTD::string &Obj,
bool EmptyIsNull)
00430 {
00431
return internal::Quote_string(Obj, EmptyIsNull);
00432 }
00433
00435
00437 template<>
inline PGSTD::string
Quote(
const char *
const & Obj,
bool EmptyIsNull)
00438 {
00439
return internal::Quote_charptr(Obj, EmptyIsNull);
00440 }
00441
00442
00444
00449 template<
int LEN>
inline PGSTD::string
Quote(
const char (&Obj)[LEN],
00450
bool EmptyIsNull)
00451 {
00452
return internal::Quote_charptr(Obj, EmptyIsNull);
00453 }
00454
00455
00460 template<
typename T>
inline PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull)
00461 {
00462
return Quote(
ToString(Obj), EmptyIsNull);
00463 }
00464
00465
00467
00470 template<
typename T>
inline PGSTD::string
Quote(T Obj)
00471 {
00472
return Quote(Obj,
false);
00473 }
00474
00475
00476
namespace internal
00477 {
00478
void freepqmem(
void *);
00479
void freenotif(PGnotify *);
00480
00482
00488 template<
typename T>
class PQAlloc
00489 {
00490 T *m_Obj;
00491
public:
00492 typedef T
content_type;
00493
00494 PQAlloc() : m_Obj(0) {}
00495
00497 explicit PQAlloc(T *obj) : m_Obj(obj) {}
00498
00499 ~PQAlloc() throw () {
close(); }
00500
00502
00504 PQAlloc &operator=(T *obj)
throw ()
00505 {
00506
if (obj != m_Obj)
00507 {
00508
close();
00509 m_Obj = obj;
00510 }
00511
return *
this;
00512 }
00513
00515 operator bool() const throw () {
return m_Obj != 0; }
00516
00518 bool operator!() const throw () {
return !m_Obj; }
00519
00521
00523 T *
operator->() const throw (PGSTD::logic_error)
00524 {
00525
if (!m_Obj)
throw PGSTD::logic_error(
"Null pointer dereferenced");
00526
return m_Obj;
00527 }
00528
00530
00532 T &
operator*() const throw (PGSTD::logic_error) {
return *
operator->(); }
00533
00535
00537 T *
c_ptr() const throw () {
return m_Obj; }
00538
00540 void close() throw () {
if (m_Obj) freemem(); m_Obj = 0; }
00541
00542
private:
00543
void freemem() throw ()
00544 {
00545
freepqmem(m_Obj);
00546 }
00547
00548
PQAlloc(
const PQAlloc &);
00549 PQAlloc &operator=(
const PQAlloc &);
00550 };
00551
00552
00554
template<>
inline void PQAlloc<PGnotify>::freemem() throw ()
00555 {
00556
freenotif(m_Obj);
00557 }
00558
00559
00560 class PQXX_LIBEXPORT namedclass
00561 {
00562
public:
00563 namedclass(
const PGSTD::string &Name,
const PGSTD::string &Classname) :
00564 m_Name(Name),
00565 m_Classname(Classname)
00566 {
00567 }
00568
00569 const PGSTD::string &name() const throw () {
return m_Name; }
00570 const PGSTD::string &classname() const throw () {
return m_Classname;}
00571 PGSTD::string description() const throw ();
00572
00573 private:
00574 PGSTD::string m_Name, m_Classname;
00575 };
00576
00577
00578
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00579
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00580
00581
00583
00586 template<typename GUEST>
00587 class
unique
00588 {
00589
public:
00590 unique() : m_Guest(0) {}
00591
00592 GUEST *get() const throw () {
return m_Guest; }
00593
00594 void Register(GUEST *G)
00595 {
00596
CheckUniqueRegistration(G, m_Guest);
00597 m_Guest = G;
00598 }
00599
00600 void Unregister(GUEST *G)
00601 {
00602
CheckUniqueUnregistration(G, m_Guest);
00603 m_Guest = 0;
00604 }
00605
00606
private:
00607 GUEST *m_Guest;
00608
00610 unique(
const unique &);
00612 unique &operator=(
const unique &);
00613 };
00614
00615 }
00616 }
00617