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
00224
template<
typename T=PGSTD::string,
typename CONT=PGSTD::vector<T> >
00225 class items :
public CONT
00226 {
00227
public:
00229 items() : CONT() {}
00231 explicit items(
const T &t) : CONT() { push_back(t); }
00232 items(
const T &t1,
const T &t2) : CONT()
00233 { push_back(t1); push_back(t2); }
00234 items(
const T &t1,
const T &t2,
const T &t3) : CONT()
00235 { push_back(t1); push_back(t2); push_back(t3); }
00236 items(
const T &t1,
const T &t2,
const T &t3,
const T &t4) : CONT()
00237 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00238 items(
const T&t1,
const T&t2,
const T&t3,
const T&t4,
const T&t5):CONT()
00239 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00241 items(
const CONT &c) : CONT(c) {}
00242
00244 items &
operator()(
const T &t)
00245 {
00246 push_back(t);
00247
return *
this;
00248 }
00249 };
00250
00251
00252
00254
template<
typename ITER>
inline
00255 PGSTD::string
separated_list(
const PGSTD::string &sep,
00256 ITER begin,
00257 ITER end)
00258 {
00259 PGSTD::string
result;
00260
if (begin != end)
00261 {
00262 result =
to_string(*begin);
00263
for (++begin; begin != end; ++begin)
00264 {
00265 result += sep;
00266 result +=
to_string(*begin);
00267 }
00268 }
00269
return result;
00270 }
00271
00273
template<
typename CONTAINER>
inline
00274 PGSTD::string
separated_list(
const PGSTD::string &sep,
00275
const CONTAINER &c)
00276 {
00277
return separated_list(sep, c.begin(), c.end());
00278 }
00279
00280
00282
00287
namespace internal
00288 {
00290
00298 template<
typename T>
inline const char *
FmtString(T t)
00299 {
00300
error_unsupported_type_in_string_conversion(t);
00301
return 0;
00302 }
00303
00304 template<>
inline const char *
FmtString(
short) {
return "%hd"; }
00305 template<>
inline const char *
FmtString(
unsigned short){
return "%hu"; }
00306 template<>
inline const char *
FmtString(
int) {
return "%i"; }
00307 template<>
inline const char *
FmtString(
long) {
return "%li"; }
00308
template<>
inline const char *
FmtString(
unsigned) {
return "%u"; }
00309
template<>
inline const char *
FmtString(
unsigned long) {
return "%lu"; }
00310 template<>
inline const char *
FmtString(
float) {
return "%f"; }
00311 template<>
inline const char *
FmtString(
double) {
return "%lf"; }
00312
template<>
inline const char *
FmtString(
long double) {
return "%Lf"; }
00313 template<>
inline const char *
FmtString(
char) {
return "%c"; }
00314
template<>
inline const char *
FmtString(
unsigned char) {
return "%c"; }
00315
00316 }
00317
00319
00327 template<
typename T>
inline PGSTD::string
ToString(
const T &Obj)
00328 {
00329
00330
char Buf[500];
00331 sprintf(Buf, internal::FmtString(Obj), Obj);
00332
return PGSTD::string(Buf);
00333 }
00334
00335
00336 template<>
inline PGSTD::string
ToString(
const PGSTD::string &Obj) {
return Obj;}
00337 template<>
inline PGSTD::string
ToString(
const char *
const &Obj) {
return Obj; }
00338 template<>
inline PGSTD::string
ToString(
char *
const &Obj) {
return Obj; }
00339
00340 template<>
inline PGSTD::string
ToString(
const unsigned char *
const &Obj)
00341 {
00342
return reinterpret_cast<const char *>(Obj);
00343 }
00344
00345 template<>
inline PGSTD::string
ToString(
const bool &Obj)
00346 {
00347
return ToString(
unsigned(Obj));
00348 }
00349
00350 template<>
inline PGSTD::string
ToString(
const short &Obj)
00351 {
00352
return ToString(
int(Obj));
00353 }
00354
00355 template<>
inline PGSTD::string
ToString(
const unsigned short &Obj)
00356 {
00357
return ToString(
unsigned(Obj));
00358 }
00359
00360
00362
00370 template<
typename T>
inline void FromString(
const char Str[], T &Obj)
00371 {
00372
if (!Str)
throw PGSTD::runtime_error(
"Attempt to convert NULL string to " +
00373 PGSTD::string(
typeid(T).name()));
00374
00375
if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00376
throw PGSTD::runtime_error(
"Cannot convert value '" +
00377 PGSTD::string(Str) +
00378
"' to " +
typeid(T).name());
00379 }
00380
00381
00382
namespace internal
00383 {
00385
00387
void PQXX_LIBEXPORT
FromString_string(
const char Str[], PGSTD::string &Obj);
00388
00390
00392
void PQXX_LIBEXPORT
FromString_ucharptr(
const char Str[],
00393
const unsigned char *&Obj);
00394
00396 PGSTD::string PQXX_LIBEXPORT
Quote_string(
const PGSTD::string &Obj,
00397
bool EmptyIsNull);
00398
00400 PGSTD::string PQXX_LIBEXPORT
Quote_charptr(
const char Obj[],
bool EmptyIsNull);
00401 }
00402
00403
00404 template<>
inline void FromString(
const char Str[], PGSTD::string &Obj)
00405 {
00406
internal::FromString_string(Str, Obj);
00407 }
00408
00409 template<>
inline void FromString(
const char Str[],
const char *&Obj)
00410 {
00411
if (!Str)
throw PGSTD::runtime_error(
"Attempt to read NULL string");
00412 Obj = Str;
00413 }
00414
00415 template<>
inline void FromString(
const char Str[],
const unsigned char *&Obj)
00416 {
00417
internal::FromString_ucharptr(Str, Obj);
00418 }
00419
00420 template<>
inline void FromString(
const char Str[],
bool &Obj)
00421 {
00422
from_string(Str, Obj);
00423 }
00424
00425
00427
00436 PGSTD::string
sqlesc(
const char str[]);
00437
00439
00449 PGSTD::string
sqlesc(
const char str[], size_t maxlen);
00450
00452
00458 PGSTD::string
sqlesc(
const PGSTD::string &);
00459
00460
00462
00466
template<
typename T> PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull);
00467
00468
00470
00472
template<>
00473 inline PGSTD::string
Quote(
const PGSTD::string &Obj,
bool EmptyIsNull)
00474 {
00475
return internal::Quote_string(Obj, EmptyIsNull);
00476 }
00477
00479
00481 template<>
inline PGSTD::string
Quote(
const char *
const & Obj,
bool EmptyIsNull)
00482 {
00483
return internal::Quote_charptr(Obj, EmptyIsNull);
00484 }
00485
00486
00488
00493 template<
int LEN>
inline PGSTD::string
Quote(
const char (&Obj)[LEN],
00494
bool EmptyIsNull)
00495 {
00496
return internal::Quote_charptr(Obj, EmptyIsNull);
00497 }
00498
00499
00500 template<
typename T>
inline PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull)
00501 {
00502
return Quote(
ToString(Obj), EmptyIsNull);
00503 }
00504
00505
00507
00510 template<
typename T>
inline PGSTD::string
Quote(T Obj)
00511 {
00512
return Quote(Obj,
false);
00513 }
00514
00515
00516
namespace internal
00517 {
00518
void freepqmem(
void *);
00519
void freenotif(PQXXPQ::PGnotify *);
00520
00522
00528 template<
typename T>
class PQAlloc
00529 {
00530 T *m_Obj;
00531
public:
00532 typedef T
content_type;
00533
00534 PQAlloc() : m_Obj(0) {}
00535
00537 explicit PQAlloc(T *obj) : m_Obj(obj) {}
00538
00539 ~PQAlloc() throw () {
close(); }
00540
00542
00544 PQAlloc &
operator=(T *obj)
throw ()
00545 {
00546
if (obj != m_Obj)
00547 {
00548
close();
00549 m_Obj = obj;
00550 }
00551
return *
this;
00552 }
00553
00555 operator bool() const throw () {
return m_Obj != 0; }
00556
00558 bool operator!() const throw () {
return !m_Obj; }
00559
00561
00563 T *
operator->() const throw (PGSTD::logic_error)
00564 {
00565
if (!m_Obj)
throw PGSTD::logic_error(
"Null pointer dereferenced");
00566
return m_Obj;
00567 }
00568
00570
00572 T &
operator*() const throw (PGSTD::logic_error) {
return *
operator->(); }
00573
00575
00577 T *
c_ptr() const throw () {
return m_Obj; }
00578
00580 void close() throw () {
if (m_Obj) freemem(); m_Obj = 0; }
00581
00582
private:
00583
void freemem() throw ()
00584 {
00585
freepqmem(m_Obj);
00586 }
00587
00588
PQAlloc(
const PQAlloc &);
00589 PQAlloc &
operator=(
const PQAlloc &);
00590 };
00591
00592
00594 template<>
inline void PQAlloc<PQXXPQ::PGnotify>::freemem() throw ()
00595 {
00596
freenotif(m_Obj);
00597 }
00598
00599
00600 class PQXX_LIBEXPORT namedclass
00601 {
00602
public:
00603 namedclass(
const PGSTD::string &Name,
const PGSTD::string &Classname) :
00604 m_Name(Name),
00605 m_Classname(Classname)
00606 {
00607 }
00608
00609 const PGSTD::string &name() const throw () {
return m_Name; }
00610 const PGSTD::string &classname() const throw () {
return m_Classname;}
00611 PGSTD::string description() const;
00612
00613 private:
00614 PGSTD::string m_Name, m_Classname;
00615 };
00616
00617
00618
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00619
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00620
00621
00623
00626 template<typename GUEST>
00627 class
unique
00628 {
00629
public:
00630 unique() : m_Guest(0) {}
00631
00632 GUEST *get() const throw () {
return m_Guest; }
00633
00634 void Register(GUEST *G)
00635 {
00636
CheckUniqueRegistration(G, m_Guest);
00637 m_Guest = G;
00638 }
00639
00640 void Unregister(GUEST *G)
00641 {
00642
CheckUniqueUnregistration(G, m_Guest);
00643 m_Guest = 0;
00644 }
00645
00646
private:
00647 GUEST *m_Guest;
00648
00650 unique(
const unique &);
00652 unique &operator=(
const unique &);
00653 };
00654
00655 }
00656 }
00657