00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
#include "pqxx/libcompiler.h"
00020
00021
#include <new>
00022
00023
#ifdef PQXX_HAVE_STREAMBUF
00024
#include <streambuf>
00025
#else
00026
#include <streambuf.h>
00027
#endif
00028
00029
#include "pqxx/dbtransaction"
00030
00031
00032
namespace pqxx
00033 {
00034
00035
class largeobjectaccess;
00036
00038
00045 class PQXX_LIBEXPORT largeobject
00046 {
00047
public:
00048 typedef long size_type;
00049
00051 largeobject() throw ();
00052
00054
00056 explicit largeobject(
dbtransaction &T);
00057
00059
00063 explicit largeobject(oid O) throw () : m_ID(O) {}
00064
00066
00070 largeobject(
dbtransaction &T,
const PGSTD::string &File);
00071
00073
00077 largeobject(
const largeobjectaccess &O)
throw ();
00078
00080
00084 oid id() const throw () {
return m_ID; }
00085
00087 bool operator==(
const largeobject &other)
const
00088 {
return m_ID == other.m_ID; }
00090 bool operator!=(
const largeobject &other)
const
00091 {
return m_ID != other.m_ID; }
00093 bool operator<=(
const largeobject &other)
const
00094 {
return m_ID <= other.m_ID; }
00096 bool operator>=(
const largeobject &other)
const
00097 {
return m_ID >= other.m_ID; }
00099 bool operator<(
const largeobject &other)
const
00100 {
return m_ID < other.m_ID; }
00102 bool operator>(
const largeobject &other)
const
00103 {
return m_ID > other.m_ID; }
00104
00106
00110
void to_file(
dbtransaction &T,
const PGSTD::string &File)
const;
00111
00113
00117
void remove(
dbtransaction &T)
const;
00118
00119
protected:
00120 static PGconn *RawConnection(
const dbtransaction &T)
00121 {
00122
return T.
conn().
RawConnection();
00123 }
00124
00125 PGSTD::string Reason() const;
00126
00127 private:
00128
oid m_ID;
00129 };
00130
00131
00132
00133
00135 class PQXX_LIBEXPORT
largeobjectaccess : private largeobject
00136 {
00137
public:
00138
using largeobject::size_type;
00139 typedef long off_type;
00140 typedef size_type pos_type;
00141
00143
00147 typedef PGSTD::ios::openmode
openmode;
00148
00150
00154 typedef PGSTD::ios::seekdir
seekdir;
00155
00157
00161
explicit largeobjectaccess(
dbtransaction &T,
00162 openmode mode =
00163 PGSTD::ios::in |
00164 PGSTD::ios::out);
00165
00167
00173
largeobjectaccess(
dbtransaction &T,
00174
oid O,
00175 openmode mode =
00176 PGSTD::ios::in |
00177 PGSTD::ios::out);
00178
00180
00185
largeobjectaccess(
dbtransaction &T,
00186 largeobject O,
00187 openmode mode = PGSTD::ios::in | PGSTD::ios::out);
00188
00190
00195
largeobjectaccess(
dbtransaction &T,
00196
const PGSTD::string &File,
00197 openmode mode =
00198 PGSTD::ios::in | PGSTD::ios::out);
00199
00200 ~
largeobjectaccess() throw () { close(); }
00201
00203
00206
using largeobject::id;
00207
00209
00212 void to_file(
const PGSTD::string &File)
const
00213 {
00214 largeobject::to_file(m_Trans, File);
00215 }
00216
00217
#ifdef PQXX_BROKEN_USING_DECL
00218
00219
00223
void to_file(
dbtransaction &T,
const PGSTD::string &F)
const
00224
{ largeobject::to_file(T, F); }
00225
#else
00226
using largeobject::to_file;
00227
#endif
00228
00229
00231
00235
void write(
const char Buf[], size_type Len);
00236
00238
00241 void write(
const PGSTD::string &Buf)
00242 { write(Buf.c_str(), Buf.size()); }
00243
00245
00251 size_type read(
char Buf[], size_type Len);
00252
00254
00257 size_type seek(size_type dest, seekdir dir);
00258
00260
00268 pos_type cseek(off_type dest, seekdir dir)
throw ();
00269
00271
00277 off_type cwrite(
const char Buf[], size_type Len)
throw ();
00278
00280
00286 off_type cread(
char Buf[], size_type Len)
throw ();
00287
00288
00290
void process_notice(
const PGSTD::string &) throw ();
00291
00292 using largeobject::remove;
00293
00294 using largeobject::operator==;
00295 using largeobject::operator!=;
00296 using largeobject::operator<;
00297 using largeobject::operator<=;
00298 using largeobject::operator>;
00299 using largeobject::operator>=;
00300
00301 private:
00302 PGSTD::string Reason() const;
00303 PGconn *RawConnection() {
return largeobject::RawConnection(m_Trans); }
00304
00305
void open(openmode mode);
00306
void close() throw ();
00307
00308 dbtransaction &m_Trans;
00309
int m_fd;
00310
00311
00312 largeobjectaccess();
00313 largeobjectaccess(const largeobjectaccess &);
00314 largeobjectaccess operator=(const largeobjectaccess &);
00315 };
00316
00317
00319
00327 template<typename CHAR=
char, typename TRAITS=PGSTD::char_traits<CHAR> >
00328 class
largeobject_streambuf :
00329 #ifdef PQXX_HAVE_STREAMBUF
00330 public PGSTD::basic_streambuf<CHAR, TRAITS>
00331 #else
00332 public PGSTD::streambuf
00333 #endif
00334 {
00335
typedef long size_type;
00336
public:
00337 typedef CHAR char_type;
00338 typedef TRAITS
traits_type;
00339 typedef typename traits_type::int_type
int_type;
00340
#ifdef PQXX_HAVE_STREAMBUF
00341
typedef typename traits_type::pos_type pos_type;
00342
typedef typename traits_type::off_type off_type;
00343
#else
00344 typedef streamoff off_type;
00345 typedef streampos pos_type;
00346
#endif
00347 typedef largeobjectaccess::openmode openmode;
00348 typedef largeobjectaccess::seekdir seekdir;
00349
00350 largeobject_streambuf(
dbtransaction &T,
00351 largeobject O,
00352 openmode mode = PGSTD::ios::in | PGSTD::ios::out,
00353 size_type BufSize=512) :
00354 m_BufSize(BufSize),
00355 m_Obj(T, O),
00356 m_G(0),
00357 m_P(0)
00358 {
00359 initialize(mode);
00360 }
00361
00362 largeobject_streambuf(
dbtransaction &T,
00363
oid O,
00364 openmode mode = PGSTD::ios::in | PGSTD::ios::out,
00365 size_type BufSize=512) :
00366 m_BufSize(BufSize),
00367 m_Obj(T, O),
00368 m_G(0),
00369 m_P(0)
00370 {
00371 initialize(mode);
00372 }
00373
00374 virtual ~
largeobject_streambuf() throw ()
00375 {
00376
delete [] m_P;
00377
delete [] m_G;
00378 }
00379
00380
00382 void process_notice(
const PGSTD::string &s) { m_Obj.process_notice(s); }
00383
00384
#ifdef PQXX_HAVE_STREAMBUF
00385
protected:
00386
#endif
00387 virtual int sync()
00388 {
00389
00390 setg(this->eback(), this->eback(), this->egptr());
00391
return overflow(EoF());
00392 }
00393
00394
protected:
00395 virtual pos_type seekoff(off_type offset,
00396 seekdir dir,
00397 openmode mode)
00398 {
00399
if (mode != SEEK_CUR)
00400
throw PGSTD::logic_error(
"Offset "+
to_string(
int(mode))+
" in seekoff()");
00401
return AdjustEOF(m_Obj.cseek(offset, dir));
00402 }
00403
00404 virtual pos_type seekpos(pos_type pos, openmode mode)
00405 {
00406
if (mode != SEEK_SET)
00407
throw PGSTD::logic_error(
"Offset "+
to_string(
int(mode))+
" in seekpos()");
00408
return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios::beg));
00409 }
00410
00411 virtual int_type overflow(int_type ch = EoF())
00412 {
00413
char *
const pp = this->pptr();
00414
if (!pp)
return EoF();
00415
char *
const pb = this->pbase();
00416 int_type res = 0;
00417
00418
if (pp > pb) res = AdjustEOF(m_Obj.cwrite(pb, pp-pb));
00419 setp(m_P, m_P + m_BufSize);
00420
00421
00422
if (ch != EoF())
00423 {
00424 *this->pptr() = char(ch);
00425 this->pbump(1);
00426 }
00427
return res;
00428 }
00429
00430 virtual int_type underflow()
00431 {
00432
if (!this->gptr())
return EoF();
00433
char *
const eb = this->eback();
00434
const int res = AdjustEOF(m_Obj.cread(this->eback(), m_BufSize));
00435 setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
00436
return (!res || (res == EoF())) ? EoF() : *eb;
00437 }
00438
00439
private:
00441
static int_type EoF() {
return traits_type::eof(); }
00442
00444
static PGSTD::streampos AdjustEOF(
int pos)
00445 {
00446
return (pos == -1) ? EoF() : pos;
00447 }
00448
00449
void initialize(openmode mode)
00450 {
00451
if (mode & PGSTD::ios::in)
00452 {
00453 m_G =
new char_type[m_BufSize];
00454 setg(m_G, m_G, m_G);
00455 }
00456
if (mode & PGSTD::ios::out)
00457 {
00458 m_P =
new char_type[m_BufSize];
00459 setp(m_P, m_P + m_BufSize);
00460 }
00461 }
00462
00463
const size_type m_BufSize;
00464 largeobjectaccess m_Obj;
00465
00466
00467 char_type *m_G, *m_P;
00468 };
00469
00470
00472
00480
template<
typename CHAR=
char,
typename TRAITS=PGSTD::
char_traits<CHAR> >
00481 class basic_ilostream :
00482 #ifdef
PQXX_HAVE_STREAMBUF
00483
public PGSTD::basic_istream<CHAR, TRAITS>
00484 #else
00485
public PGSTD::istream
00486 #endif
00487 {
00488
#ifdef PQXX_HAVE_STREAMBUF
00489
typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00490
#else
00491
typedef PGSTD::istream super;
00492
#endif
00493
00494
public:
00495 typedef CHAR char_type;
00496 typedef TRAITS traits_type;
00497 typedef typename traits_type::int_type int_type;
00498 typedef typename traits_type::pos_type pos_type;
00499 typedef typename traits_type::off_type off_type;
00500
00502
00506 basic_ilostream(
dbtransaction &T,
00507 largeobject O,
00508
largeobject::size_type BufSize=512) :
00509 super(&m_Buf),
00510 m_Buf(T, O,
PGSTD::ios::in, BufSize)
00511 {
00512 }
00513
00515
00519 basic_ilostream(
dbtransaction &T,
00520
oid O,
00521 largeobject::size_type BufSize=512) :
00522 super(&m_Buf),
00523 m_Buf(T, O,
PGSTD::ios::in, BufSize)
00524 {
00525 }
00526
00527
private:
00528
largeobject_streambuf<CHAR,TRAITS> m_Buf;
00529 };
00530
00531 typedef basic_ilostream<char> ilostream;
00532
00533
00535
00543
template<
typename CHAR=
char,
typename TRAITS=PGSTD::
char_traits<CHAR> >
00544 class basic_olostream :
00545 #ifdef
PQXX_HAVE_STREAMBUF
00546
public PGSTD::basic_ostream<CHAR, TRAITS>
00547 #else
00548
public PGSTD::ostream
00549 #endif
00550 {
00551
#ifdef PQXX_HAVE_STREAMBUF
00552
typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00553
#else
00554
typedef PGSTD::ostream super;
00555
#endif
00556
public:
00557 typedef CHAR char_type;
00558 typedef TRAITS traits_type;
00559 typedef typename traits_type::int_type int_type;
00560 typedef typename traits_type::pos_type pos_type;
00561 typedef typename traits_type::off_type off_type;
00562
00564
00568 basic_olostream(
dbtransaction &T,
00569 largeobject O,
00570
largeobject::size_type BufSize=512) :
00571 super(&m_Buf),
00572 m_Buf(T, O,
PGSTD::ios::out, BufSize)
00573 {
00574 }
00575
00577
00581 basic_olostream(
dbtransaction &T,
00582
oid O,
00583 largeobject::size_type BufSize=512) :
00584 super(&m_Buf),
00585 m_Buf(T, O,
PGSTD::ios::out, BufSize)
00586 {
00587 }
00588
00589 ~
basic_olostream()
00590 {
00591
try
00592 {
00593
#ifdef PQXX_HAVE_STREAMBUF
00594
m_Buf.pubsync(); m_Buf.pubsync();
00595
#else
00596
m_Buf.sync(); m_Buf.sync();
00597
#endif
00598
}
00599
catch (
const PGSTD::exception &e)
00600 {
00601 m_Buf.process_notice(e.what());
00602 }
00603 }
00604
00605
private:
00606
largeobject_streambuf<CHAR,TRAITS> m_Buf;
00607 };
00608
00609 typedef basic_olostream<char> olostream;
00610
00611
00613
00621
template<
typename CHAR=
char,
typename TRAITS=PGSTD::
char_traits<CHAR> >
00622 class basic_lostream :
00623 #ifdef
PQXX_HAVE_STREAMBUF
00624
public PGSTD::basic_iostream<CHAR, TRAITS>
00625 #else
00626
public PGSTD::iostream
00627 #endif
00628 {
00629
#ifdef PQXX_HAVE_STREAMBUF
00630
typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00631
#else
00632
typedef PGSTD::iostream super;
00633
#endif
00634
00635
public:
00636 typedef CHAR char_type;
00637 typedef TRAITS traits_type;
00638 typedef typename traits_type::int_type int_type;
00639 typedef typename traits_type::pos_type pos_type;
00640 typedef typename traits_type::off_type off_type;
00641
00643
00647 basic_lostream(
dbtransaction &T,
00648 largeobject O,
00649
largeobject::size_type BufSize=512) :
00650 super(&m_Buf),
00651 m_Buf(T, O,
PGSTD::ios::in |
PGSTD::ios::out, BufSize)
00652 {
00653 }
00654
00656
00660 basic_lostream(
dbtransaction &T,
00661
oid O,
00662 largeobject::size_type BufSize=512) :
00663 super(&m_Buf),
00664 m_Buf(T, O,
PGSTD::ios::in |
PGSTD::ios::out, BufSize)
00665 {
00666 }
00667
00668 ~
basic_lostream()
00669 {
00670
try
00671 {
00672
#ifdef PQXX_HAVE_STREAMBUF
00673
m_Buf.pubsync(); m_Buf.pubsync();
00674
#else
00675
m_Buf.sync(); m_Buf.sync();
00676
#endif
00677
}
00678
catch (
const PGSTD::exception &e)
00679 {
00680 m_Buf.process_notice(e.what());
00681 }
00682 }
00683
00684
private:
00685
largeobject_streambuf<CHAR,TRAITS> m_Buf;
00686 };
00687
00688 typedef basic_lostream<char> lostream;
00689
00690 }
00691
00692