00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef PQXX_H_LARGEOBJECT
00020 #define PQXX_H_LARGEOBJECT
00021
00022 #include "pqxx/compiler-public.hxx"
00023 #include "pqxx/compiler-internal-pre.hxx"
00024
00025 #ifdef PQXX_HAVE_STREAMBUF
00026 #include <streambuf>
00027 #else
00028 #include <streambuf.h>
00029 #endif
00030
00031 #include "pqxx/dbtransaction"
00032
00033
00034 namespace pqxx
00035 {
00036
00037 class largeobjectaccess;
00038
00040
00047 class PQXX_LIBEXPORT largeobject
00048 {
00049 public:
00050 typedef long size_type;
00051
00053 largeobject() throw ();
00054
00056
00058 explicit largeobject(dbtransaction &T);
00059
00061
00065 explicit largeobject(oid O) throw () : m_ID(O) {}
00066
00068
00072 largeobject(dbtransaction &T, const PGSTD::string &File);
00073
00075
00079 largeobject(const largeobjectaccess &O) throw ();
00080
00082
00086 oid id() const throw () { return m_ID; }
00087
00096
00097
00098 bool operator==(const largeobject &other) const
00099 { return m_ID == other.m_ID; }
00101
00102 bool operator!=(const largeobject &other) const
00103 { return m_ID != other.m_ID; }
00105
00106 bool operator<=(const largeobject &other) const
00107 { return m_ID <= other.m_ID; }
00109
00110 bool operator>=(const largeobject &other) const
00111 { return m_ID >= other.m_ID; }
00113
00114 bool operator<(const largeobject &other) const
00115 { return m_ID < other.m_ID; }
00117
00118 bool operator>(const largeobject &other) const
00119 { return m_ID > other.m_ID; }
00121
00123
00127 void to_file(dbtransaction &T, const PGSTD::string &File) const;
00128
00130
00134 void remove(dbtransaction &T) const;
00135
00136 protected:
00137 static internal::pq::PGconn *RawConnection(const dbtransaction &T)
00138 {
00139 return T.conn().RawConnection();
00140 }
00141
00142 PGSTD::string Reason(int err) const;
00143
00144 private:
00145 oid m_ID;
00146 };
00147
00148
00149
00150
00152 class PQXX_LIBEXPORT largeobjectaccess : private largeobject
00153 {
00154 public:
00155 using largeobject::size_type;
00156 typedef long off_type;
00157 typedef size_type pos_type;
00158
00160
00164 typedef PGSTD::ios::openmode openmode;
00165
00167
00171 typedef PGSTD::ios::seekdir seekdir;
00172
00174
00178 explicit largeobjectaccess(dbtransaction &T,
00179 openmode mode =
00180 PGSTD::ios::in |
00181 PGSTD::ios::out);
00182
00184
00190 largeobjectaccess(dbtransaction &T,
00191 oid O,
00192 openmode mode =
00193 PGSTD::ios::in |
00194 PGSTD::ios::out);
00195
00197
00202 largeobjectaccess(dbtransaction &T,
00203 largeobject O,
00204 openmode mode = PGSTD::ios::in | PGSTD::ios::out);
00205
00207
00212 largeobjectaccess(dbtransaction &T,
00213 const PGSTD::string &File,
00214 openmode mode =
00215 PGSTD::ios::in | PGSTD::ios::out);
00216
00217 ~largeobjectaccess() throw () { close(); }
00218
00220
00223 using largeobject::id;
00224
00226
00229 void to_file(const PGSTD::string &File) const
00230 { largeobject::to_file(m_Trans, File); }
00231
00232 #ifdef PQXX_BROKEN_USING_DECL
00234
00238 void to_file(dbtransaction &T, const PGSTD::string &F) const
00239 { largeobject::to_file(T, F); }
00240 #else
00241 using largeobject::to_file;
00242 #endif
00243
00248
00249
00253 void write(const char Buf[], size_type Len);
00254
00256
00259 void write(const PGSTD::string &Buf)
00260 { write(Buf.c_str(), static_cast<size_type>(Buf.size())); }
00261
00263
00269 size_type read(char Buf[], size_type Len);
00270
00272
00275 size_type seek(size_type dest, seekdir dir);
00276
00278
00281 size_type tell() const;
00283
00293
00294
00302 pos_type cseek(off_type dest, seekdir dir) throw ();
00303
00305
00311 off_type cwrite(const char Buf[], size_type Len) throw ();
00312
00314
00320 off_type cread(char Buf[], size_type Len) throw ();
00321
00323
00327 pos_type ctell() const throw ();
00329
00334
00335 void process_notice(const PGSTD::string &) throw ();
00337
00338 using largeobject::remove;
00339
00340 using largeobject::operator==;
00341 using largeobject::operator!=;
00342 using largeobject::operator<;
00343 using largeobject::operator<=;
00344 using largeobject::operator>;
00345 using largeobject::operator>=;
00346
00347 private:
00348 PGSTD::string PQXX_PRIVATE Reason(int err) const;
00349 internal::pq::PGconn *RawConnection() const
00350 { return largeobject::RawConnection(m_Trans); }
00351
00352 void open(openmode mode);
00353 void close() throw ();
00354
00355 dbtransaction &m_Trans;
00356 int m_fd;
00357
00358
00359 largeobjectaccess();
00360 largeobjectaccess(const largeobjectaccess &);
00361 largeobjectaccess operator=(const largeobjectaccess &);
00362 };
00363
00364
00366
00374 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00375 class largeobject_streambuf :
00376 #ifdef PQXX_HAVE_STREAMBUF
00377 public PGSTD::basic_streambuf<CHAR, TRAITS>
00378 #else
00379 public PGSTD::streambuf
00380 #endif
00381 {
00382 typedef long size_type;
00383 public:
00384 typedef CHAR char_type;
00385 typedef TRAITS traits_type;
00386 typedef typename traits_type::int_type int_type;
00387 #ifdef PQXX_HAVE_STREAMBUF
00388 typedef typename traits_type::pos_type pos_type;
00389 typedef typename traits_type::off_type off_type;
00390 #else
00391 typedef streamoff off_type;
00392 typedef streampos pos_type;
00393 #endif
00394 typedef largeobjectaccess::openmode openmode;
00395 typedef largeobjectaccess::seekdir seekdir;
00396
00397 largeobject_streambuf(dbtransaction &T,
00398 largeobject O,
00399 openmode mode = PGSTD::ios::in | PGSTD::ios::out,
00400 size_type BufSize=512) :
00401 m_BufSize(BufSize),
00402 m_Obj(T, O),
00403 m_G(0),
00404 m_P(0)
00405 { initialize(mode); }
00406
00407 largeobject_streambuf(dbtransaction &T,
00408 oid O,
00409 openmode mode = PGSTD::ios::in | PGSTD::ios::out,
00410 size_type BufSize=512) :
00411 m_BufSize(BufSize),
00412 m_Obj(T, O),
00413 m_G(0),
00414 m_P(0)
00415 { initialize(mode); }
00416
00417 virtual ~largeobject_streambuf() throw () { delete [] m_P; delete [] m_G; }
00418
00419
00421 void process_notice(const PGSTD::string &s) { m_Obj.process_notice(s); }
00422
00423 #ifdef PQXX_HAVE_STREAMBUF
00424 protected:
00425 #endif
00426 virtual int sync()
00427 {
00428
00429 setg(this->eback(), this->eback(), this->egptr());
00430 return overflow(EoF());
00431 }
00432
00433 protected:
00434 virtual pos_type seekoff(off_type offset,
00435 seekdir dir,
00436 openmode)
00437 {
00438 return AdjustEOF(m_Obj.cseek(largeobjectaccess::off_type(offset), dir));
00439 }
00440
00441 virtual pos_type seekpos(pos_type pos, openmode)
00442 {
00443 const largeobjectaccess::pos_type newpos = m_Obj.cseek(
00444 largeobjectaccess::off_type(pos),
00445 PGSTD::ios::beg);
00446 return AdjustEOF(newpos);
00447 }
00448
00449 virtual int_type overflow(int_type ch = EoF())
00450 {
00451 char *const pp = this->pptr();
00452 if (!pp) return EoF();
00453 char *const pb = this->pbase();
00454 int_type res = 0;
00455
00456 if (pp > pb) res = int_type(AdjustEOF(m_Obj.cwrite(pb, pp-pb)));
00457 setp(m_P, m_P + m_BufSize);
00458
00459
00460 if (ch != EoF())
00461 {
00462 *this->pptr() = char(ch);
00463 this->pbump(1);
00464 }
00465 return res;
00466 }
00467
00468 virtual int_type underflow()
00469 {
00470 if (!this->gptr()) return EoF();
00471 char *const eb = this->eback();
00472 const int_type res(static_cast<int_type>(AdjustEOF(m_Obj.cread(this->eback(), m_BufSize))));
00473 setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
00474 return (!res || (res == EoF())) ? EoF() : *eb;
00475 }
00476
00477 private:
00479 static int_type EoF() { return traits_type::eof(); }
00480
00482 template<typename INTYPE>
00483 static PGSTD::streampos AdjustEOF(INTYPE pos)
00484 { return (pos==-1) ? PGSTD::streampos(EoF()) : PGSTD::streampos(pos); }
00485
00486 void initialize(openmode mode)
00487 {
00488 if (mode & PGSTD::ios::in)
00489 {
00490 m_G = new char_type[m_BufSize];
00491 setg(m_G, m_G, m_G);
00492 }
00493 if (mode & PGSTD::ios::out)
00494 {
00495 m_P = new char_type[m_BufSize];
00496 setp(m_P, m_P + m_BufSize);
00497 }
00498 }
00499
00500 const size_type m_BufSize;
00501 largeobjectaccess m_Obj;
00502
00503
00504 char_type *m_G, *m_P;
00505 };
00506
00507
00509
00517 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00518 class basic_ilostream :
00519 #ifdef PQXX_HAVE_STREAMBUF
00520 public PGSTD::basic_istream<CHAR, TRAITS>
00521 #else
00522 public PGSTD::istream
00523 #endif
00524 {
00525 #ifdef PQXX_HAVE_STREAMBUF
00526 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00527 #else
00528 typedef PGSTD::istream super;
00529 #endif
00530
00531 public:
00532 typedef CHAR char_type;
00533 typedef TRAITS traits_type;
00534 typedef typename traits_type::int_type int_type;
00535 typedef typename traits_type::pos_type pos_type;
00536 typedef typename traits_type::off_type off_type;
00537
00539
00544 basic_ilostream(dbtransaction &T,
00545 largeobject O,
00546 largeobject::size_type BufSize=512) :
00547 super(0),
00548 m_Buf(T, O, PGSTD::ios::in, BufSize)
00549 { super::init(&m_Buf); }
00550
00552
00557 basic_ilostream(dbtransaction &T,
00558 oid O,
00559 largeobject::size_type BufSize=512) :
00560 super(0),
00561 m_Buf(T, O, PGSTD::ios::in, BufSize)
00562 { super::init(&m_Buf); }
00563
00564 private:
00565 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00566 };
00567
00568 typedef basic_ilostream<char> ilostream;
00569
00570
00572
00580 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00581 class basic_olostream :
00582 #ifdef PQXX_HAVE_STREAMBUF
00583 public PGSTD::basic_ostream<CHAR, TRAITS>
00584 #else
00585 public PGSTD::ostream
00586 #endif
00587 {
00588 #ifdef PQXX_HAVE_STREAMBUF
00589 typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00590 #else
00591 typedef PGSTD::ostream super;
00592 #endif
00593 public:
00594 typedef CHAR char_type;
00595 typedef TRAITS traits_type;
00596 typedef typename traits_type::int_type int_type;
00597 typedef typename traits_type::pos_type pos_type;
00598 typedef typename traits_type::off_type off_type;
00599
00601
00606 basic_olostream(dbtransaction &T,
00607 largeobject O,
00608 largeobject::size_type BufSize=512) :
00609 super(0),
00610 m_Buf(T, O, PGSTD::ios::out, BufSize)
00611 { super::init(&m_Buf); }
00612
00614
00619 basic_olostream(dbtransaction &T,
00620 oid O,
00621 largeobject::size_type BufSize=512) :
00622 super(0),
00623 m_Buf(T, O, PGSTD::ios::out, BufSize)
00624 { super::init(&m_Buf); }
00625
00626 ~basic_olostream()
00627 {
00628 try
00629 {
00630 #ifdef PQXX_HAVE_STREAMBUF
00631 m_Buf.pubsync(); m_Buf.pubsync();
00632 #else
00633 m_Buf.sync(); m_Buf.sync();
00634 #endif
00635 }
00636 catch (const PGSTD::exception &e)
00637 {
00638 m_Buf.process_notice(e.what());
00639 }
00640 }
00641
00642 private:
00643 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00644 };
00645
00646 typedef basic_olostream<char> olostream;
00647
00648
00650
00658 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00659 class basic_lostream :
00660 #ifdef PQXX_HAVE_STREAMBUF
00661 public PGSTD::basic_iostream<CHAR, TRAITS>
00662 #else
00663 public PGSTD::iostream
00664 #endif
00665 {
00666 #ifdef PQXX_HAVE_STREAMBUF
00667 typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00668 #else
00669 typedef PGSTD::iostream super;
00670 #endif
00671
00672 public:
00673 typedef CHAR char_type;
00674 typedef TRAITS traits_type;
00675 typedef typename traits_type::int_type int_type;
00676 typedef typename traits_type::pos_type pos_type;
00677 typedef typename traits_type::off_type off_type;
00678
00680
00685 basic_lostream(dbtransaction &T,
00686 largeobject O,
00687 largeobject::size_type BufSize=512) :
00688 super(0),
00689 m_Buf(T, O, PGSTD::ios::in | PGSTD::ios::out, BufSize)
00690 { super::init(&m_Buf); }
00691
00693
00698 basic_lostream(dbtransaction &T,
00699 oid O,
00700 largeobject::size_type BufSize=512) :
00701 super(0),
00702 m_Buf(T, O, PGSTD::ios::in | PGSTD::ios::out, BufSize)
00703 { super::init(&m_Buf); }
00704
00705 ~basic_lostream()
00706 {
00707 try
00708 {
00709 #ifdef PQXX_HAVE_STREAMBUF
00710 m_Buf.pubsync(); m_Buf.pubsync();
00711 #else
00712 m_Buf.sync(); m_Buf.sync();
00713 #endif
00714 }
00715 catch (const PGSTD::exception &e)
00716 {
00717 m_Buf.process_notice(e.what());
00718 }
00719 }
00720
00721 private:
00722 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00723 };
00724
00725 typedef basic_lostream<char> lostream;
00726
00727 }
00728
00729 #include "pqxx/compiler-internal-post.hxx"
00730
00731 #endif
00732