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
namespace internal
00034 {
00035 namespace pq
00036 {
00037
extern "C"
00038 {
00039
#include "libpq-fe.h"
00040 }
00041 }
00042 }
00043
00044 typedef long result_size_type;
00045 typedef int tuple_size_type;
00046
00048 typedef internal::pq::Oid
oid;
00049
00051 const oid oid_none = 0;
00052
00053
00055
00068
template<
typename T>
void error_unsupported_type_in_string_conversion(T);
00069
00070
00072
00078
template<
typename T> PGSTD::string
error_ambiguous_string_conversion(T);
00079
00080
00081
00082
00083
00085
00094
template<
typename T>
void from_string(
const char Str[], T &Obj);
00095
00096
template<>
void from_string(
const char Str[],
long &);
00097
template<>
void from_string(
const char Str[],
unsigned long &);
00098
template<>
void from_string(
const char Str[],
int &);
00099
template<>
void from_string(
const char Str[],
unsigned int &);
00100
template<>
void from_string(
const char Str[],
short &);
00101
template<>
void from_string(
const char Str[],
unsigned short &);
00102
template<>
void from_string(
const char Str[],
float &);
00103
template<>
void from_string(
const char Str[],
double &);
00104
template<>
void from_string(
const char Str[],
long double &);
00105
template<>
void from_string(
const char Str[],
bool &);
00106
00107 template<>
inline void from_string(
const char Str[],PGSTD::string &Obj)
00108 { Obj = Str; }
00109
00110
template<>
00111 inline void from_string(
const char Str[], PGSTD::stringstream &Obj)
00112 { Obj.clear(); Obj << Str; }
00113
00114
template<
typename T>
00115 inline void from_string(
const PGSTD::string &Str, T &Obj)
00116 {
from_string(Str.c_str(), Obj); }
00117
00118
template<
typename T>
00119 inline void from_string(
const PGSTD::stringstream &Str, T &Obj)
00120 {
from_string(Str.str(), Obj); }
00121
00122
template<>
inline void
00123 from_string(
const PGSTD::string &Str, PGSTD::string &Obj)
00124 { Obj = Str; }
00125
00126
template<>
inline void
00127 from_string(
const PGSTD::string &,
const char &Obj)
00128 {
error_ambiguous_string_conversion(Obj); }
00129
template<>
inline void
00130 from_string(
const PGSTD::string &,
const signed char &Obj)
00131 {
error_ambiguous_string_conversion(Obj); }
00132
template<>
inline void
00133 from_string(
const PGSTD::string &,
const unsigned char &Obj)
00134 {
error_ambiguous_string_conversion(Obj); }
00135
00136
00138
00142
template<
typename T> PGSTD::string
to_string(
const T &);
00143
00144
template<> PGSTD::string
to_string(
const short &);
00145
template<> PGSTD::string
to_string(
const unsigned short &);
00146
template<> PGSTD::string
to_string(
const int &);
00147
template<> PGSTD::string
to_string(
const unsigned int &);
00148
template<> PGSTD::string
to_string(
const long &);
00149
template<> PGSTD::string
to_string(
const unsigned long &);
00150
template<> PGSTD::string
to_string(
const float &);
00151
template<> PGSTD::string
to_string(
const double &);
00152
template<> PGSTD::string
to_string(
const long double &);
00153
template<> PGSTD::string
to_string(
const bool &);
00154
00155 inline PGSTD::string
to_string(
const char Obj[])
00156 {
return PGSTD::string(Obj); }
00157
00158 inline PGSTD::string
to_string(
const PGSTD::stringstream &Obj)
00159 {
return Obj.str(); }
00160
00161 inline PGSTD::string
to_string(
const PGSTD::string &Obj) {
return Obj;}
00162
00163
template<> PGSTD::string
to_string(
const char &);
00164
00165
00166 template<>
inline PGSTD::string
to_string(
const signed char &Obj)
00167 {
return error_ambiguous_string_conversion(Obj); }
00168 template<>
inline PGSTD::string
to_string(
const unsigned char &Obj)
00169 {
return error_ambiguous_string_conversion(Obj); }
00170
00171
00173
00187
template<
typename T=PGSTD::string,
typename CONT=PGSTD::vector<T> >
00188 class items :
public CONT
00189 {
00190
public:
00192 items() : CONT() {}
00194 explicit items(
const T &t) : CONT() { push_back(t); }
00195 items(
const T &t1,
const T &t2) : CONT()
00196 { push_back(t1); push_back(t2); }
00197 items(
const T &t1,
const T &t2,
const T &t3) : CONT()
00198 { push_back(t1); push_back(t2); push_back(t3); }
00199 items(
const T &t1,
const T &t2,
const T &t3,
const T &t4) : CONT()
00200 { push_back(t1); push_back(t2); push_back(t3); push_back(t4); }
00201 items(
const T&t1,
const T&t2,
const T&t3,
const T&t4,
const T&t5):CONT()
00202 {push_back(t1);push_back(t2);push_back(t3);push_back(t4);push_back(t5);}
00204 items(
const CONT &c) : CONT(c) {}
00205
00207 items &
operator()(
const T &t)
00208 {
00209 push_back(t);
00210
return *
this;
00211 }
00212 };
00213
00214
00215
00217
template<
typename ITER>
inline
00218 PGSTD::string
separated_list(
const PGSTD::string &sep,
00219 ITER begin,
00220 ITER end)
00221 {
00222 PGSTD::string
result;
00223
if (begin != end)
00224 {
00225 result =
to_string(*begin);
00226
for (++begin; begin != end; ++begin)
00227 {
00228 result += sep;
00229 result +=
to_string(*begin);
00230 }
00231 }
00232
return result;
00233 }
00234
00236
template<
typename CONTAINER>
inline
00237 PGSTD::string
separated_list(
const PGSTD::string &sep,
00238
const CONTAINER &c)
00239 {
00240
return separated_list(sep, c.begin(), c.end());
00241 }
00242
00243
00245
00250
namespace internal
00251 {
00253
00261 template<
typename T>
inline const char *
FmtString(T t)
00262 {
00263
error_unsupported_type_in_string_conversion(t);
00264
return 0;
00265 }
00266
00267 template<>
inline const char *
FmtString(
short) {
return "%hd"; }
00268 template<>
inline const char *
FmtString(
unsigned short){
return "%hu"; }
00269 template<>
inline const char *
FmtString(
int) {
return "%i"; }
00270 template<>
inline const char *
FmtString(
long) {
return "%li"; }
00271
template<>
inline const char *
FmtString(
unsigned) {
return "%u"; }
00272
template<>
inline const char *
FmtString(
unsigned long) {
return "%lu"; }
00273 template<>
inline const char *
FmtString(
float) {
return "%f"; }
00274 template<>
inline const char *
FmtString(
double) {
return "%lf"; }
00275
template<>
inline const char *
FmtString(
long double) {
return "%Lf"; }
00276 template<>
inline const char *
FmtString(
char) {
return "%c"; }
00277
template<>
inline const char *
FmtString(
unsigned char) {
return "%c"; }
00278
00279 }
00280
00282
00290 template<
typename T>
inline PGSTD::string
ToString(
const T &Obj)
00291 {
00292
00293
char Buf[500];
00294 sprintf(Buf, internal::FmtString(Obj), Obj);
00295
return PGSTD::string(Buf);
00296 }
00297
00298
00299 template<>
inline PGSTD::string
ToString(
const PGSTD::string &Obj) {
return Obj;}
00300 template<>
inline PGSTD::string
ToString(
const char *
const &Obj) {
return Obj; }
00301 template<>
inline PGSTD::string
ToString(
char *
const &Obj) {
return Obj; }
00302
00303 template<>
inline PGSTD::string
ToString(
const unsigned char *
const &Obj)
00304 {
00305
return reinterpret_cast<const char *>(Obj);
00306 }
00307
00308 template<>
inline PGSTD::string
ToString(
const bool &Obj)
00309 {
00310
return ToString(
unsigned(Obj));
00311 }
00312
00313 template<>
inline PGSTD::string
ToString(
const short &Obj)
00314 {
00315
return ToString(
int(Obj));
00316 }
00317
00318 template<>
inline PGSTD::string
ToString(
const unsigned short &Obj)
00319 {
00320
return ToString(
unsigned(Obj));
00321 }
00322
00323
00325
00333 template<
typename T>
inline void FromString(
const char Str[], T &Obj)
00334 {
00335
if (!Str)
throw PGSTD::runtime_error(
"Attempt to convert NULL string to " +
00336 PGSTD::string(
typeid(T).name()));
00337
00338
if (sscanf(Str, internal::FmtString(Obj), &Obj) != 1)
00339
throw PGSTD::runtime_error(
"Cannot convert value '" +
00340 PGSTD::string(Str) +
00341
"' to " +
typeid(T).name());
00342 }
00343
00344
00345
namespace internal
00346 {
00348
00350
void PQXX_LIBEXPORT
FromString_string(
const char Str[], PGSTD::string &Obj);
00351
00353
00355
void PQXX_LIBEXPORT
FromString_ucharptr(
const char Str[],
00356
const unsigned char *&Obj);
00357
00359 PGSTD::string PQXX_LIBEXPORT
Quote_string(
const PGSTD::string &Obj,
00360
bool EmptyIsNull);
00361
00363 PGSTD::string PQXX_LIBEXPORT
Quote_charptr(
const char Obj[],
bool EmptyIsNull);
00364 }
00365
00366
00367 template<>
inline void FromString(
const char Str[], PGSTD::string &Obj)
00368 {
00369
internal::FromString_string(Str, Obj);
00370 }
00371
00372 template<>
inline void FromString(
const char Str[],
const char *&Obj)
00373 {
00374
if (!Str)
throw PGSTD::runtime_error(
"Attempt to read NULL string");
00375 Obj = Str;
00376 }
00377
00378 template<>
inline void FromString(
const char Str[],
const unsigned char *&Obj)
00379 {
00380
internal::FromString_ucharptr(Str, Obj);
00381 }
00382
00383 template<>
inline void FromString(
const char Str[],
bool &Obj)
00384 {
00385
from_string(Str, Obj);
00386 }
00387
00388
00390
00399 PGSTD::string
sqlesc(
const char str[]);
00400
00402
00412 PGSTD::string
sqlesc(
const char str[], size_t maxlen);
00413
00415
00421 PGSTD::string
sqlesc(
const PGSTD::string &);
00422
00423
00425
00429
template<
typename T> PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull);
00430
00431
00433
00435
template<>
00436 inline PGSTD::string
Quote(
const PGSTD::string &Obj,
bool EmptyIsNull)
00437 {
00438
return internal::Quote_string(Obj, EmptyIsNull);
00439 }
00440
00442
00444 template<>
inline PGSTD::string
Quote(
const char *
const & Obj,
bool EmptyIsNull)
00445 {
00446
return internal::Quote_charptr(Obj, EmptyIsNull);
00447 }
00448
00449
00451
00456 template<
int LEN>
inline PGSTD::string
Quote(
const char (&Obj)[LEN],
00457
bool EmptyIsNull)
00458 {
00459
return internal::Quote_charptr(Obj, EmptyIsNull);
00460 }
00461
00462
00463 template<
typename T>
inline PGSTD::string
Quote(
const T &Obj,
bool EmptyIsNull)
00464 {
00465
return Quote(
ToString(Obj), EmptyIsNull);
00466 }
00467
00468
00470
00473 template<
typename T>
inline PGSTD::string
Quote(T Obj)
00474 {
00475
return Quote(Obj,
false);
00476 }
00477
00478
00479
namespace internal
00480 {
00481
void freepqmem(
void *);
00482
void freenotif(internal::pq::PGnotify *);
00483
00485
00491 template<
typename T>
class PQAlloc
00492 {
00493 T *m_Obj;
00494
public:
00495 typedef T
content_type;
00496
00497 PQAlloc() : m_Obj(0) {}
00498
00500 explicit PQAlloc(T *obj) : m_Obj(obj) {}
00501
00502 ~PQAlloc() throw () {
close(); }
00503
00505
00507 PQAlloc &
operator=(T *obj)
throw ()
00508 {
00509
if (obj != m_Obj)
00510 {
00511
close();
00512 m_Obj = obj;
00513 }
00514
return *
this;
00515 }
00516
00518 operator bool() const throw () {
return m_Obj != 0; }
00519
00521 bool operator!() const throw () {
return !m_Obj; }
00522
00524
00526 T *
operator->() const throw (PGSTD::logic_error)
00527 {
00528
if (!m_Obj)
throw PGSTD::logic_error(
"Null pointer dereferenced");
00529
return m_Obj;
00530 }
00531
00533
00535 T &
operator*() const throw (PGSTD::logic_error) {
return *
operator->(); }
00536
00538
00540 T *
c_ptr() const throw () {
return m_Obj; }
00541
00543 void close() throw () {
if (m_Obj) freemem(); m_Obj = 0; }
00544
00545
private:
00546
void freemem() throw ()
00547 {
00548
freepqmem(m_Obj);
00549 }
00550
00551
PQAlloc(
const PQAlloc &);
00552 PQAlloc &
operator=(
const PQAlloc &);
00553 };
00554
00555
00557 template<>
inline void PQAlloc<internal::pq::PGnotify>::freemem() throw ()
00558 {
00559
freenotif(m_Obj);
00560 }
00561
00562
00563 class PQXX_LIBEXPORT namedclass
00564 {
00565
public:
00566 namedclass(
const PGSTD::string &Name,
const PGSTD::string &Classname) :
00567 m_Name(Name),
00568 m_Classname(Classname)
00569 {
00570 }
00571
00572 const PGSTD::string &name() const throw () {
return m_Name; }
00573 const PGSTD::string &classname() const throw () {
return m_Classname;}
00574 PGSTD::string description() const throw ();
00575
00576 private:
00577 PGSTD::string m_Name, m_Classname;
00578 };
00579
00580
00581
void CheckUniqueRegistration(const namedclass *New, const namedclass *Old);
00582
void CheckUniqueUnregistration(const namedclass *New, const namedclass *Old);
00583
00584
00586
00589 template<typename GUEST>
00590 class
unique
00591 {
00592
public:
00593 unique() : m_Guest(0) {}
00594
00595 GUEST *get() const throw () {
return m_Guest; }
00596
00597 void Register(GUEST *G)
00598 {
00599
CheckUniqueRegistration(G, m_Guest);
00600 m_Guest = G;
00601 }
00602
00603 void Unregister(GUEST *G)
00604 {
00605
CheckUniqueUnregistration(G, m_Guest);
00606 m_Guest = 0;
00607 }
00608
00609
private:
00610 GUEST *m_Guest;
00611
00613 unique(
const unique &);
00615 unique &operator=(
const unique &);
00616 };
00617
00618 }
00619 }
00620