00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
#include "pqxx/libcompiler.h"
00019
#include "pqxx/config-public-libpq.h"
00020
00021
#include <cstdio>
00022
#include <cctype>
00023
#include <sstream>
00024
#include <stdexcept>
00025
#include <string>
00026
#include <typeinfo>
00027
#include <vector>
00028
00029
00031
namespace pqxx
00032 {
00033 }
00034
00035
00036
#ifdef PQXX_PQ_IN_NAMESPACE
00037
00038
00039
namespace pqxx
00040 {
00041
namespace internal
00042 {
00043
namespace pq
00044 {
00045
#define PQXXPQ pqxx::internal::pq
00046
extern "C"
00047 {
00048
#include "libpq-fe.h"
00049 }
00050 }
00051 }
00052 }
00053
00054
#else // PQXX_PQ_IN_NAMESPACE
00055
00056
00057
extern "C"
00058 {
00059
#include "libpq-fe.h"
00060 }
00061
00062
namespace pqxx
00063 {
00064
namespace internal
00065 {
00066 namespace pq
00067 {
00068 #define PQXXPQ
00069 typedef PQXXPQ::PGconn
PGconn;
00070 typedef PQXXPQ::PGresult
PGresult;
00071
00072 }
00073 }
00074 }
00075
00076
#endif // PQXX_PQ_IN_NAMESPACE
00077
00078
00079
namespace pqxx
00080 {
00081 typedef long result_size_type;
00082 typedef int tuple_size_type;
00083
00085 typedef PQXXPQ::Oid
oid;
00086
00088 const oid oid_none = 0;
00089
00090
00092
00105
template<
typename T>
void error_unsupported_type_in_string_conversion(T);
00106
00107
00109
00115
template<
typename T> PGSTD::string
error_ambiguous_string_conversion(T);
00116
00117
00118
00119
00120
00122
00131
template<
typename T>
void from_string(
const char Str[], T &Obj);
00132
00133
template<>
void from_string(
const char Str[],
long &);
00134
template<>
void from_string(
const char Str[],
unsigned long &);
00135
template<>
void from_string(
const char Str[],
int &);
00136
template<>
void from_string(
const char Str[],
unsigned int &);
00137
template<>
void from_string(
const char Str[],
short &);
00138
template<>
void from_string(
const char Str[],
unsigned short &);
00139
template<>
void from_string(
const char Str[],
float &);
00140
template<>
void from_string(
const char Str[],
double &);
00141
template<>
void from_string(
const char Str[],
long double &);
00142
template<>
void from_string(
const char Str[],
bool &);
00143
00144 template<>
inline void from_string(
const char Str[],PGSTD::string &Obj)
00145 { Obj = Str; }
00146
00147
template<>
00148 inline void from_string(
const char Str[], PGSTD::stringstream &Obj)
00149 { Obj.clear(); Obj << Str; }
00150
00151
template<
typename T>
00152 inline void from_string(
const PGSTD::string &Str, T &Obj)
00153 {
from_string(Str.c_str(), Obj); }
00154
00155
template<
typename T>
00156 inline void from_string(
const PGSTD::stringstream &Str, T &Obj)
00157 {
from_string(Str.str(), Obj); }
00158
00159
template<>
inline void
00160 from_string(
const PGSTD::string &Str, PGSTD::string &Obj)
00161 { Obj = Str; }
00162
00163
template<>
inline void
00164 from_string(
const PGSTD::string &,
const char &Obj)
00165 {
error_ambiguous_string_conversion(Obj); }
00166
template<>
inline void
00167 from_string(
const PGSTD::string &,
const signed char &Obj)
00168 {
error_ambiguous_string_conversion(Obj); }
00169
template<>
inline void
00170 from_string(
const PGSTD::string &,
const unsigned char &Obj)
00171 {
error_ambiguous_string_conversion(Obj); }
00172
00173
00175
00179
template<
typename T> PGSTD::string
to_string(
const T &);
00180
00181
template<> PGSTD::string
to_string(
const short &);
00182
template<> PGSTD::string
to_string(
const unsigned short &);
00183
template<> PGSTD::string
to_string(
const int &);
00184
template<> PGSTD::string
to_string(
const unsigned int &);
00185
template<> PGSTD::string
to_string(
const long &);
00186
template<> PGSTD::string
to_string(
const unsigned long &);
00187
template<> PGSTD::string
to_string(
const float &);
00188
template<> PGSTD::string
to_string(
const double &);
00189
template<> PGSTD::string
to_string(
const long double &);
00190
template<> PGSTD::string
to_string(
const bool &);
00191
00192 inline PGSTD::string
to_string(
const char Obj[])
00193 {
return PGSTD::string(Obj); }
00194
00195 inline PGSTD::string
to_string(
const PGSTD::stringstream &Obj)
00196 {
return Obj.str(); }
00197
00198 inline PGSTD::string
to_string(
const PGSTD::string &Obj) {
return Obj;}
00199
00200
template<> PGSTD::string
to_string(
const char &);
00201
00202
00203 template<>
inline PGSTD::string
to_string(
const signed char &Obj)
00204 {
return error_ambiguous_string_conversion(Obj); }
00205 template<>
inline PGSTD::string
to_string(
const unsigned char &Obj)
00206 {
return error_ambiguous_string_conversion(Obj); }
00207
00208
00210
00227
template<
typename T=PGSTD::string,
typename CONT=PGSTD::vector<T> >
00228 class items :
public CONT
00229 {
00230
public:
00232 items() : CONT() {}
00234 explicit items(
const T &t) : CONT() { push_back(t); }
00235 items(
const T &t1,
const T &t2) : CONT()
00236 { push_back(t1); push_back(t2); }
00237 items(
const T &t1,
const T &t2,
const T &t3) : CONT()
00238 { push_back(t1); push_back(t2); push_back(t3); }
00239 items(
const T &t1,
const T &t2,
const T &t3,
const T &t4) : CONT()
00240 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00241 items(
const T&t1,
const T&t2,
const T&t3,
const T&t4,
const T&t5):CONT()
00242 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00244 items(
const CONT &c) : CONT(c) {}
00245
00247 items &
operator()(
const T &t)
00248 {
00249 push_back(t);
00250
return *
this;
00251 }
00252 };
00253
00254
00255
00257
template<
typename ITER>
inline
00258 PGSTD::string
separated_list(
const PGSTD::string &sep,
00259 ITER begin,
00260 ITER end)
00261 {
00262 PGSTD::string
result;
00263
if (begin != end)
00264 {
00265 result =
to_string(*begin);
00266
for (++begin; begin != end; ++begin)
00267 {
00268 result += sep;
00269 result +=
to_string(*begin);
00270 }
00271 }
00272
return result;
00273 }
00274
00276
template<
typename CONTAINER>
inline
00277 PGSTD::string
separated_list(
const PGSTD::string &sep,
00278
const CONTAINER &c)
00279 {
00280
return separated_list(sep, c.begin(), c.end());
00281 }
00282
00283
00285
00290
namespace internal
00291 {
00293
00301 template<
typename T>
inline const char *
FmtString(T t)
00302 {
00303
error_unsupported_type_in_string_conversion(t);
00304
return 0;
00305 }
00306
00307 template<>
inline const char *
FmtString(
short) {
return "%hd"; }
00308 template<>
inline const char *
FmtString(
unsigned short){
return "%hu"; }
00309 template<>
inline const char *
FmtString(
int) {
return "%i"; }
00310 template<>
inline const char *
FmtString(
long) {
return "%li"; }
00311
template<>
inline const char *
FmtString(
unsigned) {
return "%u"; }
00312
template<>
inline const char *
FmtString(
unsigned long) {
return "%lu"; }
00313 template<>
inline const char *
FmtString(
float) {
return "%f"; }
00314 template<>
inline const char *
FmtString(
double) {
return "%lf"; }
00315
template<>
inline const char *
FmtString(
long double) {
return "%Lf"; }
00316 template<>
inline const char *
FmtString(
char) {
return "%c"; }
00317
template<>
inline const char *
FmtString(
unsigned char) {
return "%c"; }
00318
00319 }
00320
00322
00330 template<
typename T>
inline PGSTD::string
ToString(
const T &Obj)
00331 {
00332
00333
char Buf[500];
00334 sprintf(Buf, internal::FmtString(Obj), Obj);
00335
return PGSTD::string(Buf);
00336 }
00337
00338
00339 template<>
inline PGSTD::string
ToString(
const PGSTD::string &Obj) {
return Obj;}
00340 template<>
inline PGSTD::string
ToString(
const char *
const &Obj) {
return Obj; }
00341 template<>
inline PGSTD::string
ToString(
char *
const &Obj) {
return Obj; }
00342
00343 template<>
inline PGSTD::string
ToString(
const unsigned char *
const &Obj)
00344 {
00345
return reinterpret_cast<const char *>(Obj);
00346 }
00347
00348 template<>
inline PGSTD::string
ToString(
const bool &Obj)
00349 {
00350
return ToString(
unsigned(Obj));
00351 }
00352
00353 template<>
inline PGSTD::string
ToString(
const short &Obj)
00354 {
00355
return ToString(
int(Obj));
00356 }
00357
00358 template<>
inline PGSTD::string
ToString(
const unsigned short &Obj)
00359 {
00360
return ToString(
unsigned(Obj));
00361 }
00362
00363
00365
00373 template<
typename T>
inline void FromString(
const char Str[], T &Obj)
00374 {
00375
if (!Str)
throw PGSTD::runtime_error(
"Attempt to convert NULL string to " +
00376 PGSTD::string(
typeid(T).name()));
00377
00378
if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00379
throw PGSTD::runtime_error(
"Cannot convert value '" +
00380 PGSTD::string(Str) +
00381
"' to " +
typeid(T).name());
00382 }
00383
00384
00385
namespace internal
00386 {
00388
00390
void PQXX_LIBEXPORT
FromString_string(
const char Str[], PGSTD::string &Obj);
00391
00393
00395
void PQXX_LIBEXPORT
FromString_ucharptr(
const char Str[],
00396
const unsigned char *&Obj);
00397
00399 PGSTD::string PQXX_LIBEXPORT
Quote_string(
const PGSTD::string &Obj,
00400
bool EmptyIsNull);
00401
00403 PGSTD::string PQXX_LIBEXPORT
Quote_charptr(
const char Obj[],
bool EmptyIsNull);
00404 }
00405
00406
00407 template<>
inline void FromString(
const char Str[], PGSTD::string &Obj)
00408 {
00409
internal::FromString_string(Str, Obj);
00410 }
00411
00412 template<>
inline void FromString(
const char Str[],
const char *&Obj)
00413 {
00414
if (!Str)
throw PGSTD::runtime_error(
"Attempt to read NULL string");
00415 Obj = Str;
00416 }
00417
00418 template<>
inline void FromString(
const char Str[],
const unsigned char *&Obj)
00419 {
00420
internal::FromString_ucharptr(Str, Obj);
00421 }
00422
00423 template<>
inline void FromString(
const char Str[],
bool &Obj)
00424 {
00425
from_string(Str, Obj);
00426 }
00427
00428
00430
00439 PGSTD::string
sqlesc(
const char str[]);
00440
00442
00452 PGSTD::string
sqlesc(
const char str[], size_t maxlen);
00453
00455
00461 PGSTD::string
sqlesc(
const PGSTD::string &);
00462
00463
00465
00469
template<
typename T> PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull);
00470
00471
00473
00475
template<>
00476 inline PGSTD::string
Quote(
const PGSTD::string &Obj,
bool EmptyIsNull)
00477 {
00478
return internal::Quote_string(Obj, EmptyIsNull);
00479 }
00480
00482
00484 template<>
inline PGSTD::string
Quote(
const char *
const & Obj,
bool EmptyIsNull)
00485 {
00486
return internal::Quote_charptr(Obj, EmptyIsNull);
00487 }
00488
00489
00491
00496 template<
int LEN>
inline PGSTD::string
Quote(
const char (&Obj)[LEN],
00497
bool EmptyIsNull)
00498 {
00499
return internal::Quote_charptr(Obj, EmptyIsNull);
00500 }
00501
00502
00503 template<
typename T>
inline PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull)
00504 {
00505
return Quote(
ToString(Obj), EmptyIsNull);
00506 }
00507
00508
00510
00513 template<
typename T>
inline PGSTD::string
Quote(T Obj)
00514 {
00515
return Quote(Obj,
false);
00516 }
00517
00518
00519
namespace internal
00520 {
00521
void freepqmem(
void *);
00522
void freenotif(PQXXPQ::PGnotify *);
00523
00525
00531 template<
typename T>
class PQAlloc
00532 {
00533 T *m_Obj;
00534
public:
00535 typedef T
content_type;
00536
00537 PQAlloc() : m_Obj(0) {}
00538
00540 explicit PQAlloc(T *obj) : m_Obj(obj) {}
00541
00542 ~PQAlloc() throw () {
close(); }
00543
00545
00547 PQAlloc &
operator=(T *obj)
throw ()
00548 {
00549
if (obj != m_Obj)
00550 {
00551
close();
00552 m_Obj = obj;
00553 }
00554
return *
this;
00555 }
00556
00558 operator bool() const throw () {
return m_Obj != 0; }
00559
00561 bool operator!() const throw () {
return !m_Obj; }
00562
00564
00566 T *
operator->() const throw (PGSTD::logic_error)
00567 {
00568
if (!m_Obj)
throw PGSTD::logic_error(
"Null pointer dereferenced");
00569
return m_Obj;
00570 }
00571
00573
00575 T &
operator*() const throw (PGSTD::logic_error) {
return *
operator->(); }
00576
00578
00580 T *
c_ptr() const throw () {
return m_Obj; }
00581
00583 void close() throw () {
if (m_Obj) freemem(); m_Obj = 0; }
00584
00585
private:
00586
void freemem() throw ()
00587 {
00588
freepqmem(m_Obj);
00589 }
00590
00591
PQAlloc(
const PQAlloc &);
00592 PQAlloc &
operator=(
const PQAlloc &);
00593 };
00594
00595
00597 template<>
inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw ()
00598 {
00599
freenotif(m_Obj);
00600 }
00601
00602
00603 class PQXX_LIBEXPORT namedclass
00604 {
00605
public:
00606 namedclass(
const PGSTD::string &Name,
const PGSTD::string &Classname) :
00607 m_Name(Name),
00608 m_Classname(Classname)
00609 {
00610 }
00611
00612 const PGSTD::string &name() const throw () {
return m_Name; }
00613 const PGSTD::string &classname() const throw () {
return m_Classname;}
00614 PGSTD::string description() const;
00615
00616 private:
00617 PGSTD::string m_Name, m_Classname;
00618 };
00619
00620
00621
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00622
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00623
00624
00626
00629 template<typename GUEST>
00630 class
unique
00631 {
00632
public:
00633 unique() : m_Guest(0) {}
00634
00635 GUEST *get() const throw () {
return m_Guest; }
00636
00637 void Register(GUEST *G)
00638 {
00639
CheckUniqueRegistration(G, m_Guest);
00640 m_Guest = G;
00641 }
00642
00643 void Unregister(GUEST *G)
00644 {
00645
CheckUniqueUnregistration(G, m_Guest);
00646 m_Guest = 0;
00647 }
00648
00649
private:
00650 GUEST *m_Guest;
00651
00653 unique(
const unique &);
00655 unique &operator=(
const unique &);
00656 };
00657
00658 }
00659 }
00660