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 PGSTD::string Reason(int err) const;
00140
00141 private:
00142 oid m_ID;
00143 };
00144
00145
00146
00147
00149 class PQXX_LIBEXPORT largeobjectaccess : private largeobject
00150 {
00151 public:
00152 using largeobject::size_type;
00153 typedef long off_type;
00154 typedef size_type pos_type;
00155
00157
00161 typedef PGSTD::ios::openmode openmode;
00162
00164
00168 typedef PGSTD::ios::seekdir seekdir;
00169
00171
00175 explicit largeobjectaccess(dbtransaction &T,
00176 openmode mode =
00177 PGSTD::ios::in |
00178 PGSTD::ios::out);
00179
00181
00187 largeobjectaccess(dbtransaction &T,
00188 oid O,
00189 openmode mode =
00190 PGSTD::ios::in |
00191 PGSTD::ios::out);
00192
00194
00199 largeobjectaccess(dbtransaction &T,
00200 largeobject O,
00201 openmode mode = PGSTD::ios::in | PGSTD::ios::out);
00202
00204
00209 largeobjectaccess(dbtransaction &T,
00210 const PGSTD::string &File,
00211 openmode mode =
00212 PGSTD::ios::in | PGSTD::ios::out);
00213
00214 ~largeobjectaccess() throw () { close(); }
00215
00217
00220 using largeobject::id;
00221
00223
00226 void to_file(const PGSTD::string &File) const
00227 { largeobject::to_file(m_Trans, File); }
00228
00229 #ifdef PQXX_BROKEN_USING_DECL
00231
00235 void to_file(dbtransaction &T, const PGSTD::string &F) const
00236 { largeobject::to_file(T, F); }
00237 #else
00238 using largeobject::to_file;
00239 #endif
00240
00245
00246
00250 void write(const char Buf[], size_type Len);
00251
00253
00256 void write(const PGSTD::string &Buf)
00257 { write(Buf.c_str(), static_cast<size_type>(Buf.size())); }
00258
00260
00266 size_type read(char Buf[], size_type Len);
00267
00269
00272 size_type seek(size_type dest, seekdir dir);
00273
00275
00278 size_type tell() const;
00280
00290
00291
00299 pos_type cseek(off_type dest, seekdir dir) throw ();
00300
00302
00308 off_type cwrite(const char Buf[], size_type Len) throw ();
00309
00311
00317 off_type cread(char Buf[], size_type Len) throw ();
00318
00320
00324 pos_type ctell() const throw ();
00326
00331
00332 void process_notice(const PGSTD::string &) throw ();
00334
00335 using largeobject::remove;
00336
00337 using largeobject::operator==;
00338 using largeobject::operator!=;
00339 using largeobject::operator<;
00340 using largeobject::operator<=;
00341 using largeobject::operator>;
00342 using largeobject::operator>=;
00343
00344 private:
00345 PGSTD::string PQXX_PRIVATE Reason(int err) const;
00346 internal::pq::PGconn *RawConnection() const
00347 { return largeobject::RawConnection(m_Trans); }
00348
00349 void open(openmode mode);
00350 void close() throw ();
00351
00352 dbtransaction &m_Trans;
00353 int m_fd;
00354
00355
00356 largeobjectaccess();
00357 largeobjectaccess(const largeobjectaccess &);
00358 largeobjectaccess operator=(const largeobjectaccess &);
00359 };
00360
00361
00363
00371 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00372 class largeobject_streambuf :
00373 #ifdef PQXX_HAVE_STREAMBUF
00374 public PGSTD::basic_streambuf<CHAR, TRAITS>
00375 #else
00376 public PGSTD::streambuf
00377 #endif
00378 {
00379 typedef long size_type;
00380 public:
00381 typedef CHAR char_type;
00382 typedef TRAITS traits_type;
00383 typedef typename traits_type::int_type int_type;
00384 #ifdef PQXX_HAVE_STREAMBUF
00385 typedef typename traits_type::pos_type pos_type;
00386 typedef typename traits_type::off_type off_type;
00387 #else
00388 typedef streamoff off_type;
00389 typedef streampos pos_type;
00390 #endif
00391 typedef largeobjectaccess::openmode openmode;
00392 typedef largeobjectaccess::seekdir seekdir;
00393
00394 largeobject_streambuf(dbtransaction &T,
00395 largeobject O,
00396 openmode mode = PGSTD::ios::in | PGSTD::ios::out,
00397 size_type BufSize=512) :
00398 m_BufSize(BufSize),
00399 m_Obj(T, O),
00400 m_G(0),
00401 m_P(0)
00402 { initialize(mode); }
00403
00404 largeobject_streambuf(dbtransaction &T,
00405 oid O,
00406 openmode mode = PGSTD::ios::in | PGSTD::ios::out,
00407 size_type BufSize=512) :
00408 m_BufSize(BufSize),
00409 m_Obj(T, O),
00410 m_G(0),
00411 m_P(0)
00412 { initialize(mode); }
00413
00414 virtual ~largeobject_streambuf() throw () { delete [] m_P; delete [] m_G; }
00415
00416
00418 void process_notice(const PGSTD::string &s) { m_Obj.process_notice(s); }
00419
00420 #ifdef PQXX_HAVE_STREAMBUF
00421 protected:
00422 #endif
00423 virtual int sync()
00424 {
00425
00426 setg(this->eback(), this->eback(), this->egptr());
00427 return overflow(EoF());
00428 }
00429
00430 protected:
00431 virtual pos_type seekoff(off_type offset,
00432 seekdir dir,
00433 openmode)
00434 {
00435 return AdjustEOF(m_Obj.cseek(largeobjectaccess::off_type(offset), dir));
00436 }
00437
00438 virtual pos_type seekpos(pos_type pos, openmode)
00439 {
00440 const largeobjectaccess::pos_type newpos = m_Obj.cseek(
00441 largeobjectaccess::off_type(pos),
00442 PGSTD::ios::beg);
00443 return AdjustEOF(newpos);
00444 }
00445
00446 virtual int_type overflow(int_type ch = EoF())
00447 {
00448 char *const pp = this->pptr();
00449 if (!pp) return EoF();
00450 char *const pb = this->pbase();
00451 int_type res = 0;
00452
00453 if (pp > pb) res = int_type(AdjustEOF(m_Obj.cwrite(pb, pp-pb)));
00454 setp(m_P, m_P + m_BufSize);
00455
00456
00457 if (ch != EoF())
00458 {
00459 *this->pptr() = char(ch);
00460 this->pbump(1);
00461 }
00462 return res;
00463 }
00464
00465 virtual int_type underflow()
00466 {
00467 if (!this->gptr()) return EoF();
00468 char *const eb = this->eback();
00469 const int_type res(static_cast<int_type>(AdjustEOF(m_Obj.cread(this->eback(), m_BufSize))));
00470 setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
00471 return (!res || (res == EoF())) ? EoF() : *eb;
00472 }
00473
00474 private:
00476 static int_type EoF() { return traits_type::eof(); }
00477
00479 template<typename INTYPE>
00480 static PGSTD::streampos AdjustEOF(INTYPE pos)
00481 { return (pos==-1) ? PGSTD::streampos(EoF()) : PGSTD::streampos(pos); }
00482
00483 void initialize(openmode mode)
00484 {
00485 if (mode & PGSTD::ios::in)
00486 {
00487 m_G = new char_type[m_BufSize];
00488 setg(m_G, m_G, m_G);
00489 }
00490 if (mode & PGSTD::ios::out)
00491 {
00492 m_P = new char_type[m_BufSize];
00493 setp(m_P, m_P + m_BufSize);
00494 }
00495 }
00496
00497 const size_type m_BufSize;
00498 largeobjectaccess m_Obj;
00499
00500
00501 char_type *m_G, *m_P;
00502 };
00503
00504
00506
00514 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00515 class basic_ilostream :
00516 #ifdef PQXX_HAVE_STREAMBUF
00517 public PGSTD::basic_istream<CHAR, TRAITS>
00518 #else
00519 public PGSTD::istream
00520 #endif
00521 {
00522 #ifdef PQXX_HAVE_STREAMBUF
00523 typedef PGSTD::basic_istream<CHAR, TRAITS> super;
00524 #else
00525 typedef PGSTD::istream super;
00526 #endif
00527
00528 public:
00529 typedef CHAR char_type;
00530 typedef TRAITS traits_type;
00531 typedef typename traits_type::int_type int_type;
00532 typedef typename traits_type::pos_type pos_type;
00533 typedef typename traits_type::off_type off_type;
00534
00536
00541 basic_ilostream(dbtransaction &T,
00542 largeobject O,
00543 largeobject::size_type BufSize=512) :
00544 super(0),
00545 m_Buf(T, O, PGSTD::ios::in, BufSize)
00546 { super::init(&m_Buf); }
00547
00549
00554 basic_ilostream(dbtransaction &T,
00555 oid O,
00556 largeobject::size_type BufSize=512) :
00557 super(0),
00558 m_Buf(T, O, PGSTD::ios::in, BufSize)
00559 { super::init(&m_Buf); }
00560
00561 private:
00562 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00563 };
00564
00565 typedef basic_ilostream<char> ilostream;
00566
00567
00569
00577 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00578 class basic_olostream :
00579 #ifdef PQXX_HAVE_STREAMBUF
00580 public PGSTD::basic_ostream<CHAR, TRAITS>
00581 #else
00582 public PGSTD::ostream
00583 #endif
00584 {
00585 #ifdef PQXX_HAVE_STREAMBUF
00586 typedef PGSTD::basic_ostream<CHAR, TRAITS> super;
00587 #else
00588 typedef PGSTD::ostream super;
00589 #endif
00590 public:
00591 typedef CHAR char_type;
00592 typedef TRAITS traits_type;
00593 typedef typename traits_type::int_type int_type;
00594 typedef typename traits_type::pos_type pos_type;
00595 typedef typename traits_type::off_type off_type;
00596
00598
00603 basic_olostream(dbtransaction &T,
00604 largeobject O,
00605 largeobject::size_type BufSize=512) :
00606 super(0),
00607 m_Buf(T, O, PGSTD::ios::out, BufSize)
00608 { super::init(&m_Buf); }
00609
00611
00616 basic_olostream(dbtransaction &T,
00617 oid O,
00618 largeobject::size_type BufSize=512) :
00619 super(0),
00620 m_Buf(T, O, PGSTD::ios::out, BufSize)
00621 { super::init(&m_Buf); }
00622
00623 ~basic_olostream()
00624 {
00625 try
00626 {
00627 #ifdef PQXX_HAVE_STREAMBUF
00628 m_Buf.pubsync(); m_Buf.pubsync();
00629 #else
00630 m_Buf.sync(); m_Buf.sync();
00631 #endif
00632 }
00633 catch (const PGSTD::exception &e)
00634 {
00635 m_Buf.process_notice(e.what());
00636 }
00637 }
00638
00639 private:
00640 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00641 };
00642
00643 typedef basic_olostream<char> olostream;
00644
00645
00647
00655 template<typename CHAR=char, typename TRAITS=PGSTD::char_traits<CHAR> >
00656 class basic_lostream :
00657 #ifdef PQXX_HAVE_STREAMBUF
00658 public PGSTD::basic_iostream<CHAR, TRAITS>
00659 #else
00660 public PGSTD::iostream
00661 #endif
00662 {
00663 #ifdef PQXX_HAVE_STREAMBUF
00664 typedef PGSTD::basic_iostream<CHAR, TRAITS> super;
00665 #else
00666 typedef PGSTD::iostream super;
00667 #endif
00668
00669 public:
00670 typedef CHAR char_type;
00671 typedef TRAITS traits_type;
00672 typedef typename traits_type::int_type int_type;
00673 typedef typename traits_type::pos_type pos_type;
00674 typedef typename traits_type::off_type off_type;
00675
00677
00682 basic_lostream(dbtransaction &T,
00683 largeobject O,
00684 largeobject::size_type BufSize=512) :
00685 super(0),
00686 m_Buf(T, O, PGSTD::ios::in | PGSTD::ios::out, BufSize)
00687 { super::init(&m_Buf); }
00688
00690
00695 basic_lostream(dbtransaction &T,
00696 oid O,
00697 largeobject::size_type BufSize=512) :
00698 super(0),
00699 m_Buf(T, O, PGSTD::ios::in | PGSTD::ios::out, BufSize)
00700 { super::init(&m_Buf); }
00701
00702 ~basic_lostream()
00703 {
00704 try
00705 {
00706 #ifdef PQXX_HAVE_STREAMBUF
00707 m_Buf.pubsync(); m_Buf.pubsync();
00708 #else
00709 m_Buf.sync(); m_Buf.sync();
00710 #endif
00711 }
00712 catch (const PGSTD::exception &e)
00713 {
00714 m_Buf.process_notice(e.what());
00715 }
00716 }
00717
00718 private:
00719 largeobject_streambuf<CHAR,TRAITS> m_Buf;
00720 };
00721
00722 typedef basic_lostream<char> lostream;
00723
00724 }
00725
00726 #include "pqxx/compiler-internal-post.hxx"
00727
00728 #endif
00729