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 { return AdjustEOF(m_Obj.cseek(offset, dir)); }
00438
00439 virtual pos_type seekpos(pos_type pos, openmode)
00440 { return AdjustEOF(m_Obj.cseek(pos, PGSTD::ios::beg)); }
00441
00442 virtual int_type overflow(int_type ch = EoF())
00443 {
00444 char *const pp = this->pptr();
00445 if (!pp) return EoF();
00446 char *const pb = this->pbase();
00447 int_type res = 0;
00448
00449 if (pp > pb) res = int_type(AdjustEOF(m_Obj.cwrite(pb, pp-pb)));
00450 setp(m_P, m_P + m_BufSize);
00451
00452
00453 if (ch != EoF())
00454 {
00455 *this->pptr() = char(ch);
00456 this->pbump(1);
00457 }
00458 return res;
00459 }
00460
00461 virtual int_type underflow()
00462 {
00463 if (!this->gptr()) return EoF();
00464 char *const eb = this->eback();
00465 const int_type res(static_cast<int_type>(AdjustEOF(m_Obj.cread(this->eback(), m_BufSize))));
00466 setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
00467 return (!res || (res == EoF())) ? EoF() : *eb;
00468 }
00469
00470 private:
00472 static int_type EoF() { return traits_type::eof(); }
00473
00475 template<typename INTYPE>
00476 static PGSTD::streampos AdjustEOF(INTYPE pos)
00477 { return (pos==-1) ? PGSTD::streampos(EoF()) : PGSTD::streampos(pos); }
00478
00479 void initialize(openmode mode)
00480 {
00481 if (mode & PGSTD::ios::in)
00482 {
00483 m_G = new char_type[m_BufSize];
00484 setg(m_G, m_G, m_G);
00485 }
00486 if (mode & PGSTD::ios::out)
00487 {
00488 m_P = new char_type[m_BufSize];
00489 setp(m_P, m_P + m_BufSize);
00490 }
00491 }
00492
00493 const size_type m_BufSize;
00494 largeobjectaccess m_Obj;
00495
00496
00497 char_type *m_G, *m_P;
00498 };
00499
00500
00502
00510 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00511 class basic_ilostream :
00512 #ifdef PQXX_HAVE_STREAMBUF
00513 public PGSTD::basic_istream<CHAR, TRAITS>
00514 #else
00515 public PGSTD::istream
00516 #endif
00517 {
00518 #ifdef PQXX_HAVE_STREAMBUF
00519 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00520 #else
00521 typedef PGSTD::istream super;
00522 #endif
00523
00524 public:
00525 typedef CHAR char_type;
00526 typedef TRAITS traits_type;
00527 typedef typename traits_type::int_type int_type;
00528 typedef typename traits_type::pos_type pos_type;
00529 typedef typename traits_type::off_type off_type;
00530
00532
00537 basic_ilostream(dbtransaction &T,
00538 largeobject O,
00539 largeobject::size_type BufSize=512) :
00540 super(0),
00541 m_Buf(T, O, PGSTD::ios::in, BufSize)
00542 { super::init(&m_Buf); }
00543
00545
00550 basic_ilostream(dbtransaction &T,
00551 oid O,
00552 largeobject::size_type BufSize=512) :
00553 super(0),
00554 m_Buf(T, O, PGSTD::ios::in, BufSize)
00555 { super::init(&m_Buf); }
00556
00557 private:
00558 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00559 };
00560
00561 typedef basic_ilostream<char> ilostream;
00562
00563
00565
00573 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00574 class basic_olostream :
00575 #ifdef PQXX_HAVE_STREAMBUF
00576 public PGSTD::basic_ostream<CHAR, TRAITS>
00577 #else
00578 public PGSTD::ostream
00579 #endif
00580 {
00581 #ifdef PQXX_HAVE_STREAMBUF
00582 typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00583 #else
00584 typedef PGSTD::ostream super;
00585 #endif
00586 public:
00587 typedef CHAR char_type;
00588 typedef TRAITS traits_type;
00589 typedef typename traits_type::int_type int_type;
00590 typedef typename traits_type::pos_type pos_type;
00591 typedef typename traits_type::off_type off_type;
00592
00594
00599 basic_olostream(dbtransaction &T,
00600 largeobject O,
00601 largeobject::size_type BufSize=512) :
00602 super(0),
00603 m_Buf(T, O, PGSTD::ios::out, BufSize)
00604 { super::init(&m_Buf); }
00605
00607
00612 basic_olostream(dbtransaction &T,
00613 oid O,
00614 largeobject::size_type BufSize=512) :
00615 super(0),
00616 m_Buf(T, O, PGSTD::ios::out, BufSize)
00617 { super::init(&m_Buf); }
00618
00619 ~basic_olostream()
00620 {
00621 try
00622 {
00623 #ifdef PQXX_HAVE_STREAMBUF
00624 m_Buf.pubsync(); m_Buf.pubsync();
00625 #else
00626 m_Buf.sync(); m_Buf.sync();
00627 #endif
00628 }
00629 catch (const PGSTD::exception &e)
00630 {
00631 m_Buf.process_notice(e.what());
00632 }
00633 }
00634
00635 private:
00636 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00637 };
00638
00639 typedef basic_olostream<char> olostream;
00640
00641
00643
00651 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00652 class basic_lostream :
00653 #ifdef PQXX_HAVE_STREAMBUF
00654 public PGSTD::basic_iostream<CHAR, TRAITS>
00655 #else
00656 public PGSTD::iostream
00657 #endif
00658 {
00659 #ifdef PQXX_HAVE_STREAMBUF
00660 typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00661 #else
00662 typedef PGSTD::iostream super;
00663 #endif
00664
00665 public:
00666 typedef CHAR char_type;
00667 typedef TRAITS traits_type;
00668 typedef typename traits_type::int_type int_type;
00669 typedef typename traits_type::pos_type pos_type;
00670 typedef typename traits_type::off_type off_type;
00671
00673
00678 basic_lostream(dbtransaction &T,
00679 largeobject O,
00680 largeobject::size_type BufSize=512) :
00681 super(0),
00682 m_Buf(T, O, PGSTD::ios::in | PGSTD::ios::out, BufSize)
00683 { super::init(&m_Buf); }
00684
00686
00691 basic_lostream(dbtransaction &T,
00692 oid O,
00693 largeobject::size_type BufSize=512) :
00694 super(0),
00695 m_Buf(T, O, PGSTD::ios::in | PGSTD::ios::out, BufSize)
00696 { super::init(&m_Buf); }
00697
00698 ~basic_lostream()
00699 {
00700 try
00701 {
00702 #ifdef PQXX_HAVE_STREAMBUF
00703 m_Buf.pubsync(); m_Buf.pubsync();
00704 #else
00705 m_Buf.sync(); m_Buf.sync();
00706 #endif
00707 }
00708 catch (const PGSTD::exception &e)
00709 {
00710 m_Buf.process_notice(e.what());
00711 }
00712 }
00713
00714 private:
00715 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00716 };
00717
00718 typedef basic_lostream<char> lostream;
00719
00720 }
00721
00722 #include "pqxx/compiler-internal-post.hxx"
00723
00724 #endif
00725