largeobject.hxx
#ifndef PQXX_H_LARGEOBJECT
#define PQXX_H_LARGEOBJECT
#include "pqxx/compiler-public.hxx"
#include "pqxx/compiler-internal-pre.hxx"
#include <streambuf>
#include "pqxx/dbtransaction.hxx"
namespace pqxx
{
class PQXX_LIBEXPORT largeobject
{
public:
using size_type = large_object_size_type;
largeobject() noexcept =default; //[t48]
explicit largeobject(dbtransaction &T); //[t48]
explicit largeobject(oid O) noexcept : m_id{O} {} //[t48]
largeobject(dbtransaction &T, const std::string &File); //[t53]
largeobject(const largeobjectaccess &O) noexcept; //[t50]
oid id() const noexcept { return m_id; } //[t48]
bool operator==(const largeobject &other) const //[t51]
{ return m_id == other.m_id; }
bool operator!=(const largeobject &other) const //[t51]
{ return m_id != other.m_id; }
bool operator<=(const largeobject &other) const //[t51]
{ return m_id <= other.m_id; }
bool operator>=(const largeobject &other) const //[t51]
{ return m_id >= other.m_id; }
bool operator<(const largeobject &other) const //[t51]
{ return m_id < other.m_id; }
bool operator>(const largeobject &other) const //[t51]
{ return m_id > other.m_id; }
void to_file(dbtransaction &T, const std::string &File) const; //[t52]
void remove(dbtransaction &T) const; //[t48]
protected:
PQXX_PURE static internal::pq::PGconn *raw_connection(
const dbtransaction &T);
PQXX_PRIVATE std::string reason(const connection_base &, int err) const;
private:
oid m_id = oid_none;
};
// TODO: New hierarchy with separate read / write / mixed-mode access
class PQXX_LIBEXPORT largeobjectaccess : private largeobject
{
public:
using largeobject::size_type;
using off_type = long;
using pos_type = size_type;
using openmode = std::ios::openmode;
using seekdir = std::ios::seekdir;
explicit largeobjectaccess( //[t51]
dbtransaction &T,
openmode mode=std::ios::in|std::ios::out);
largeobjectaccess( //[t52]
dbtransaction &T,
oid O,
openmode mode=std::ios::in|std::ios::out);
largeobjectaccess( //[t50]
dbtransaction &T,
largeobject O,
openmode mode=std::ios::in|std::ios::out);
largeobjectaccess( //[t55]
dbtransaction &T,
const std::string &File,
openmode mode=std::ios::in|std::ios::out);
~largeobjectaccess() noexcept { close(); }
using largeobject::id;
void to_file(const std::string &File) const //[t54]
{ largeobject::to_file(m_trans, File); }
using largeobject::to_file;
void write(const char Buf[], size_type Len); //[t51]
void write(const std::string &Buf) //[t50]
{ write(Buf.c_str(), static_cast<size_type>(Buf.size())); }
size_type read(char Buf[], size_type Len); //[t50]
size_type seek(size_type dest, seekdir dir); //[t51]
size_type tell() const; //[t50]
pos_type cseek(off_type dest, seekdir dir) noexcept; //[t50]
off_type cwrite(const char Buf[], size_type Len) noexcept; //[t50]
off_type cread(char Buf[], size_type Len) noexcept; //[t50]
pos_type ctell() const noexcept; //[t50]
void process_notice(const std::string &) noexcept; //[t50]
using largeobject::remove;
using largeobject::operator==;
using largeobject::operator!=;
using largeobject::operator<;
using largeobject::operator<=;
using largeobject::operator>;
using largeobject::operator>=;
private:
PQXX_PRIVATE std::string reason(int err) const;
internal::pq::PGconn *raw_connection() const
{ return largeobject::raw_connection(m_trans); }
PQXX_PRIVATE void open(openmode mode);
void close() noexcept;
dbtransaction &m_trans;
int m_fd = -1;
largeobjectaccess() =delete;
largeobjectaccess(const largeobjectaccess &) =delete;
largeobjectaccess operator=(const largeobjectaccess &) =delete;
};
template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
class largeobject_streambuf :
public std::basic_streambuf<CHAR, TRAITS>
{
using size_type = long;
public:
using char_type = CHAR;
using traits_type = TRAITS;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
using openmode = largeobjectaccess::openmode;
using seekdir = largeobjectaccess::seekdir;
largeobject_streambuf( //[t48]
dbtransaction &T,
largeobject O,
openmode mode=std::ios::in|std::ios::out,
size_type BufSize=512) :
m_bufsize{BufSize},
m_obj{T, O, mode},
m_g{nullptr},
m_p{nullptr}
{ initialize(mode); }
largeobject_streambuf( //[t48]
dbtransaction &T,
oid O,
openmode mode=std::ios::in|std::ios::out,
size_type BufSize=512) :
m_bufsize{BufSize},
m_obj{T, O, mode},
m_g{nullptr},
m_p{nullptr}
{ initialize(mode); }
virtual ~largeobject_streambuf() noexcept
{ delete [] m_p; delete [] m_g; }
void process_notice(const std::string &s) { m_obj.process_notice(s); }
protected:
virtual int sync() override
{
// setg() sets eback, gptr, egptr
this->setg(this->eback(), this->eback(), this->egptr());
return overflow(EoF());
}
virtual pos_type seekoff(
off_type offset,
seekdir dir,
openmode)
override
{
return AdjustEOF(m_obj.cseek(largeobjectaccess::off_type(offset), dir));
}
virtual pos_type seekpos(pos_type pos, openmode) override
{
const largeobjectaccess::pos_type newpos = m_obj.cseek(
largeobjectaccess::off_type(pos),
std::ios::beg);
return AdjustEOF(newpos);
}
virtual int_type overflow(int_type ch = EoF()) override
{
char *const pp = this->pptr();
if (pp == nullptr) return EoF();
char *const pb = this->pbase();
int_type res = 0;
if (pp > pb) res = int_type(AdjustEOF(m_obj.cwrite(pb, pp-pb)));
this->setp(m_p, m_p + m_bufsize);
// Write that one more character, if it's there.
if (ch != EoF())
{
*this->pptr() = char(ch);
this->pbump(1);
}
return res;
}
virtual int_type underflow() override
{
if (this->gptr() == nullptr) return EoF();
char *const eb = this->eback();
const int_type res(static_cast<int_type>(
AdjustEOF(m_obj.cread(this->eback(), m_bufsize))));
this->setg(eb, eb, eb + ((res==EoF()) ? 0 : res));
return ((res == 0) or (res == EoF())) ? EoF() : *eb;
}
private:
static int_type EoF() { return traits_type::eof(); }
template<typename INTYPE>
static std::streampos AdjustEOF(INTYPE pos)
{ return (pos==-1) ? std::streampos(EoF()) : std::streampos(pos); }
void initialize(openmode mode)
{
if (mode & std::ios::in)
{
m_g = new char_type[unsigned(m_bufsize)];
this->setg(m_g, m_g, m_g);
}
if (mode & std::ios::out)
{
m_p = new char_type[unsigned(m_bufsize)];
this->setp(m_p, m_p + m_bufsize);
}
}
const size_type m_bufsize;
largeobjectaccess m_obj;
char_type *m_g, *m_p;
};
template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
class basic_ilostream :
public std::basic_istream<CHAR, TRAITS>
{
using super = std::basic_istream<CHAR, TRAITS>;
public:
using char_type = CHAR;
using traits_type = TRAITS;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
basic_ilostream( //[t57]
dbtransaction &T,
largeobject O,
largeobject::size_type BufSize=512) :
super{nullptr},
m_buf{T, O, std::ios::in, BufSize}
{ super::init(&m_buf); }
basic_ilostream( //[t48]
dbtransaction &T,
oid O,
largeobject::size_type BufSize=512) :
super{nullptr},
m_buf{T, O, std::ios::in, BufSize}
{ super::init(&m_buf); }
private:
largeobject_streambuf<CHAR,TRAITS> m_buf;
};
using ilostream = basic_ilostream<char>;
template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
class basic_olostream :
public std::basic_ostream<CHAR, TRAITS>
{
using super = std::basic_ostream<CHAR, TRAITS>;
public:
using char_type = CHAR;
using traits_type = TRAITS;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
basic_olostream( //[t48]
dbtransaction &T,
largeobject O,
largeobject::size_type BufSize=512) :
super{nullptr},
m_buf{T, O, std::ios::out, BufSize}
{ super::init(&m_buf); }
basic_olostream( //[t57]
dbtransaction &T,
oid O,
largeobject::size_type BufSize=512) :
super{nullptr},
m_buf{T, O, std::ios::out, BufSize}
{ super::init(&m_buf); }
~basic_olostream()
{
try
{
m_buf.pubsync(); m_buf.pubsync();
}
catch (const std::exception &e)
{
m_buf.process_notice(e.what());
}
}
private:
largeobject_streambuf<CHAR,TRAITS> m_buf;
};
using olostream = basic_olostream<char>;
template<typename CHAR=char, typename TRAITS=std::char_traits<CHAR>>
class basic_lostream :
public std::basic_iostream<CHAR, TRAITS>
{
using super = std::basic_iostream<CHAR, TRAITS>;
public:
using char_type = CHAR;
using traits_type = TRAITS;
using int_type = typename traits_type::int_type;
using pos_type = typename traits_type::pos_type;
using off_type = typename traits_type::off_type;
basic_lostream( //[t59]
dbtransaction &T,
largeobject O,
largeobject::size_type BufSize=512) :
super{nullptr},
m_buf{T, O, std::ios::in | std::ios::out, BufSize}
{ super::init(&m_buf); }
basic_lostream( //[t59]
dbtransaction &T,
oid O,
largeobject::size_type BufSize=512) :
super{nullptr},
m_buf{T, O, std::ios::in | std::ios::out, BufSize}
{ super::init(&m_buf); }
~basic_lostream()
{
try
{
m_buf.pubsync(); m_buf.pubsync();
}
catch (const std::exception &e)
{
m_buf.process_notice(e.what());
}
}
private:
largeobject_streambuf<CHAR,TRAITS> m_buf;
};
using lostream = basic_lostream<char>;
} // namespace pqxx
#include "pqxx/compiler-internal-post.hxx"
#endif
pqxx::largeobjectaccess::cwrite
off_type cwrite(const char Buf[], size_type Len) noexcept
Write to large object's data stream.
Definition: largeobject.cxx:213
pqxx::largeobjectaccess::~largeobjectaccess
~largeobjectaccess() noexcept
Definition: largeobject.hxx:201
pqxx::basic_olostream::int_type
typename traits_type::int_type int_type
Definition: largeobject.hxx:549
pqxx::largeobject_streambuf::seekoff
virtual pos_type seekoff(off_type offset, seekdir dir, openmode) override
Definition: largeobject.hxx:398
pqxx::largeobject::to_file
void to_file(dbtransaction &T, const std::string &File) const
Export large object's contents to a local file.
Definition: largeobject.cxx:106
pqxx::largeobject::reason
std::string reason(const connection_base &, int err) const
Definition: largeobject.cxx:141
pqxx::basic_olostream::traits_type
TRAITS traits_type
Definition: largeobject.hxx:548
pqxx::largeobjectaccess
Accessor for large object's contents.
Definition: largeobject.hxx:137
pqxx::largeobject_streambuf::~largeobject_streambuf
virtual ~largeobject_streambuf() noexcept
Definition: largeobject.hxx:383
pqxx::largeobject_streambuf< char, std::char_traits< char > >::traits_type
std::char_traits< char > traits_type
Definition: largeobject.hxx:354
pqxx::basic_olostream::char_type
CHAR char_type
Definition: largeobject.hxx:547
pqxx::basic_lostream::basic_lostream
basic_lostream(dbtransaction &T, oid O, largeobject::size_type BufSize=512)
Create a basic_lostream.
Definition: largeobject.hxx:642
pqxx::internal
Private namespace for libpqxx's internal use; do not access.
Definition: connection_base.hxx:43
pqxx::large_object_size_type
long large_object_size_type
Number of bytes in a large object. (Unusual: it's signed.)
Definition: types.hxx:33
pqxx::largeobjectaccess::to_file
void to_file(const std::string &File) const
Export large object's contents to a local file.
Definition: largeobject.hxx:213
pqxx::largeobjectaccess::size_type
large_object_size_type size_type
Definition: largeobject.hxx:37
pqxx::largeobject_streambuf< char, std::char_traits< char > >::char_type
char char_type
Definition: largeobject.hxx:353
pqxx::largeobject_streambuf::overflow
virtual int_type overflow(int_type ch=EoF()) override
Definition: largeobject.hxx:415
pqxx::largeobject::largeobject
largeobject() noexcept=default
Refer to a nonexistent large object (similar to what a null pointer does)
pqxx::largeobject_streambuf::largeobject_streambuf
largeobject_streambuf(dbtransaction &T, largeobject O, openmode mode=std::ios::in|std::ios::out, size_type BufSize=512)
Definition: largeobject.hxx:361
pqxx::largeobject::id
oid id() const noexcept
Object identifier.
Definition: largeobject.hxx:73
pqxx::failure
Run-time failure encountered by libpqxx, similar to std::runtime_error.
Definition: except.hxx:89
pqxx::basic_ilostream::off_type
typename traits_type::off_type off_type
Definition: largeobject.hxx:495
pqxx::largeobjectaccess::seekdir
std::ios::seekdir seekdir
Seek direction: beg, cur, end.
Definition: largeobject.hxx:156
pqxx::largeobject::operator>=
bool operator>=(const largeobject &other) const
Compare object identities.
Definition: largeobject.hxx:97
pqxx::basic_ilostream::basic_ilostream
basic_ilostream(dbtransaction &T, oid O, largeobject::size_type BufSize=512)
Create a basic_ilostream.
Definition: largeobject.hxx:517
pqxx::largeobjectaccess::cread
off_type cread(char Buf[], size_type Len) noexcept
Read from large object's data stream.
Definition: largeobject.cxx:223
pqxx::largeobject::size_type
large_object_size_type size_type
Definition: largeobject.hxx:37
pqxx::largeobject_streambuf::underflow
virtual int_type underflow() override
Definition: largeobject.hxx:434
pqxx::basic_lostream::traits_type
TRAITS traits_type
Definition: largeobject.hxx:617
pqxx::basic_ilostream
Input stream that gets its data from a large object.
Definition: largeobject.hxx:485
pqxx::basic_lostream::~basic_lostream
~basic_lostream()
Definition: largeobject.hxx:650
pqxx::largeobject::remove
void remove(dbtransaction &T) const
Delete large object from database.
Definition: largeobject.cxx:121
pqxx::largeobject::raw_connection
static PQXX_PURE internal::pq::PGconn * raw_connection(const dbtransaction &T)
Definition: largeobject.cxx:134
pqxx::largeobjectaccess::process_notice
void process_notice(const std::string &) noexcept
Issue message to transaction's notice processor.
Definition: largeobject.cxx:310
pqxx::largeobject_streambuf::process_notice
void process_notice(const std::string &s)
For use by large object stream classes.
Definition: largeobject.hxx:388
pqxx::basic_olostream::~basic_olostream
~basic_olostream()
Definition: largeobject.hxx:581
pqxx::basic_lostream
Stream that reads and writes a large object.
Definition: largeobject.hxx:610
pqxx::largeobjectaccess::seek
size_type seek(size_type dest, seekdir dir)
Seek in large object's data stream.
Definition: largeobject.cxx:191
pqxx::largeobject_streambuf::seekpos
virtual pos_type seekpos(pos_type pos, openmode) override
Definition: largeobject.hxx:407
pqxx::largeobject::operator==
bool operator==(const largeobject &other) const
Compare object identities.
Definition: largeobject.hxx:85
pqxx::largeobject_streambuf
Streambuf to use large objects in standard I/O streams.
Definition: largeobject.hxx:348
pqxx::basic_lostream::off_type
typename traits_type::off_type off_type
Definition: largeobject.hxx:620
pqxx::basic_ilostream::pos_type
typename traits_type::pos_type pos_type
Definition: largeobject.hxx:494
pqxx::basic_lostream::basic_lostream
basic_lostream(dbtransaction &T, largeobject O, largeobject::size_type BufSize=512)
Create a basic_lostream.
Definition: largeobject.hxx:628
pqxx::basic_olostream::pos_type
typename traits_type::pos_type pos_type
Definition: largeobject.hxx:550
pqxx::basic_lostream::int_type
typename traits_type::int_type int_type
Definition: largeobject.hxx:618
pqxx::largeobjectaccess::pos_type
size_type pos_type
Definition: largeobject.hxx:142
pqxx::largeobject::operator!=
bool operator!=(const largeobject &other) const
Compare object identities.
Definition: largeobject.hxx:89
pqxx::largeobjectaccess::write
void write(const std::string &Buf)
Write string to large object.
Definition: largeobject.hxx:233
pqxx::basic_ilostream::char_type
CHAR char_type
Definition: largeobject.hxx:491
pqxx::basic_ilostream::basic_ilostream
basic_ilostream(dbtransaction &T, largeobject O, largeobject::size_type BufSize=512)
Create a basic_ilostream.
Definition: largeobject.hxx:503
pqxx::largeobject_streambuf< char, std::char_traits< char > >::int_type
typename traits_type::int_type int_type
Definition: largeobject.hxx:355
pqxx::largeobject_streambuf< char, std::char_traits< char > >::seekdir
largeobjectaccess::seekdir seekdir
Definition: largeobject.hxx:359
pqxx::oid_none
constexpr oid oid_none
The "null" oid.
Definition: util.hxx:77
pqxx::largeobjectaccess::read
size_type read(char Buf[], size_type Len)
Read data from large object.
Definition: largeobject.cxx:260
pqxx::transaction_base::conn
connection_base & conn() const
Connection this transaction is running in.
Definition: transaction_base.hxx:492
pqxx::largeobject::operator<=
bool operator<=(const largeobject &other) const
Compare object identities.
Definition: largeobject.hxx:93
pqxx::largeobjectaccess::ctell
pos_type ctell() const noexcept
Report current position in large object's data stream.
Definition: largeobject.cxx:230
pqxx::basic_ilostream::int_type
typename traits_type::int_type int_type
Definition: largeobject.hxx:493
pqxx::basic_ilostream::traits_type
TRAITS traits_type
Definition: largeobject.hxx:492
pqxx::largeobject::operator>
bool operator>(const largeobject &other) const
Compare object identities.
Definition: largeobject.hxx:105
pqxx::largeobject_streambuf< char, std::char_traits< char > >::off_type
typename traits_type::off_type off_type
Definition: largeobject.hxx:357
pqxx::basic_olostream::off_type
typename traits_type::off_type off_type
Definition: largeobject.hxx:551
pqxx::largeobjectaccess::cseek
pos_type cseek(off_type dest, seekdir dir) noexcept
Seek in large object's data stream.
Definition: largeobject.cxx:206
pqxx::basic_olostream::basic_olostream
basic_olostream(dbtransaction &T, largeobject O, largeobject::size_type BufSize=512)
Create a basic_olostream.
Definition: largeobject.hxx:559
pqxx::largeobject_streambuf< char, std::char_traits< char > >::openmode
largeobjectaccess::openmode openmode
Definition: largeobject.hxx:358
pqxx::basic_lostream::pos_type
typename traits_type::pos_type pos_type
Definition: largeobject.hxx:619
pqxx::largeobject_streambuf< char, std::char_traits< char > >::pos_type
typename traits_type::pos_type pos_type
Definition: largeobject.hxx:356
pqxx::to_string
std::string to_string(const field &Obj)
Convert a field to a string.
Definition: result.cxx:451
pqxx::largeobject
Identity of a large object.
Definition: largeobject.hxx:34
pqxx::connection_base
connection_base abstract base class; represents a connection to a database.
Definition: connection_base.hxx:139
pqxx::basic_olostream
Output stream that writes data back to a large object.
Definition: largeobject.hxx:542
pqxx::dbtransaction
Abstract base class responsible for bracketing a backend transaction.
Definition: dbtransaction.hxx:62
pqxx::largeobjectaccess::write
void write(const char Buf[], size_type Len)
Write data to large object.
Definition: largeobject.cxx:236
pqxx::largeobject_streambuf::largeobject_streambuf
largeobject_streambuf(dbtransaction &T, oid O, openmode mode=std::ios::in|std::ios::out, size_type BufSize=512)
Definition: largeobject.hxx:372
pqxx::largeobjectaccess::openmode
std::ios::openmode openmode
Open mode: in, out (can be combined with the "or" operator)
Definition: largeobject.hxx:149
pqxx::basic_olostream::basic_olostream
basic_olostream(dbtransaction &T, oid O, largeobject::size_type BufSize=512)
Create a basic_olostream.
Definition: largeobject.hxx:573
pqxx::largeobjectaccess::largeobjectaccess
largeobjectaccess(dbtransaction &T, openmode mode=std::ios::in|std::ios::out)
Create new large object and open it.
Definition: largeobject.cxx:149
pqxx::largeobjectaccess::tell
size_type tell() const
Report current position in large object's data stream.
Definition: largeobject.cxx:295
pqxx
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
pqxx::basic_lostream::char_type
CHAR char_type
Definition: largeobject.hxx:616
pqxx::largeobject_streambuf::sync
virtual int sync() override
Definition: largeobject.hxx:391
pqxx::largeobjectaccess::off_type
long off_type
Definition: largeobject.hxx:141
pqxx::largeobject::operator<
bool operator<(const largeobject &other) const
Compare object identities.
Definition: largeobject.hxx:101