libpqxx 7.8.1
largeobject.hxx
1/* Large Objects interface. Deprecated; use blob instead.
2 *
3 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead.
4 *
5 * Copyright (c) 2000-2023, Jeroen T. Vermeulen.
6 *
7 * See COPYING for copyright license. If you did not receive a file called
8 * COPYING with this source code, please notify the distributor of this
9 * mistake, or contact the author.
10 */
11#ifndef PQXX_H_LARGEOBJECT
12#define PQXX_H_LARGEOBJECT
13
14#if !defined(PQXX_HEADER_PRE)
15# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
16#endif
17
18#include <streambuf>
19
20#include "pqxx/dbtransaction.hxx"
21
22
23namespace pqxx
24{
26
33class PQXX_LIBEXPORT largeobject
34{
35public:
37
40 [[deprecated("Use blob instead.")]] largeobject() noexcept = default;
41
43
45 [[deprecated("Use blob instead.")]] explicit largeobject(dbtransaction &t);
46
48
52 [[deprecated("Use blob instead.")]] explicit largeobject(oid o) noexcept :
53 m_id{o}
54 {}
55
57
61 [[deprecated("Use blob instead.")]] largeobject(
62 dbtransaction &t, std::string_view file);
63
65
69 [[deprecated("Use blob instead.")]] largeobject(
70 largeobjectaccess const &o) noexcept;
71
73
77 [[nodiscard]] oid id() const noexcept { return m_id; }
78
88
89 [[nodiscard]] bool operator==(largeobject const &other) const
90 {
91 return m_id == other.m_id;
92 }
94
95 [[nodiscard]] bool operator!=(largeobject const &other) const
96 {
97 return m_id != other.m_id;
98 }
100
101 [[nodiscard]] bool operator<=(largeobject const &other) const
102 {
103 return m_id <= other.m_id;
104 }
106
107 [[nodiscard]] bool operator>=(largeobject const &other) const
108 {
109 return m_id >= other.m_id;
110 }
112
113 [[nodiscard]] bool operator<(largeobject const &other) const
114 {
115 return m_id < other.m_id;
116 }
118
119 [[nodiscard]] bool operator>(largeobject const &other) const
120 {
121 return m_id > other.m_id;
122 }
124
126
130 void to_file(dbtransaction &t, std::string_view file) const;
131
133
137 void remove(dbtransaction &t) const;
138
139protected:
140 PQXX_PURE static internal::pq::PGconn *
141 raw_connection(dbtransaction const &T);
142
143 PQXX_PRIVATE std::string reason(connection const &, int err) const;
144
145private:
146 oid m_id = oid_none;
147};
148
149
151
153class PQXX_LIBEXPORT largeobjectaccess : private largeobject
154{
155public:
159
161
168 using openmode = std::ios::openmode;
169
171 static constexpr auto default_mode{
172 std::ios::in | std::ios::out | std::ios::binary};
173
175 using seekdir = std::ios::seekdir;
176
178
183 [[deprecated("Use blob instead.")]] explicit largeobjectaccess(
184 dbtransaction &t, openmode mode = default_mode);
185
187
194 [[deprecated("Use blob instead.")]] largeobjectaccess(
195 dbtransaction &t, oid o, openmode mode = default_mode);
196
198
204 [[deprecated("Use blob instead.")]] largeobjectaccess(
205 dbtransaction &t, largeobject o, openmode mode = default_mode);
206
208
213 [[deprecated("Use blob instead.")]] largeobjectaccess(
214 dbtransaction &t, std::string_view file, openmode mode = default_mode);
215
216 ~largeobjectaccess() noexcept { close(); }
217
219
222 using largeobject::id;
223
225
228 void to_file(std::string_view file) const
229 {
230 largeobject::to_file(m_trans, file);
231 }
232
234
240
245 void write(char const buf[], std::size_t len);
246
248
251 void write(std::string_view buf) { write(std::data(buf), std::size(buf)); }
252
254
260 size_type read(char buf[], std::size_t len);
261
263
266 size_type seek(size_type dest, seekdir dir);
267
269
272 [[nodiscard]] size_type tell() const;
274
288
296 pos_type cseek(off_type dest, seekdir dir) noexcept;
297
299
305 off_type cwrite(char const buf[], std::size_t len) noexcept;
306
308
314 off_type cread(char buf[], std::size_t len) noexcept;
315
317
321 [[nodiscard]] pos_type ctell() const noexcept;
323
329 void process_notice(zview) noexcept;
331
332 using largeobject::remove;
333
334 using largeobject::operator==;
335 using largeobject::operator!=;
336 using largeobject::operator<;
337 using largeobject::operator<=;
338 using largeobject::operator>;
339 using largeobject::operator>=;
340
343 largeobjectaccess operator=(largeobjectaccess const &) = delete;
344
345private:
346 PQXX_PRIVATE std::string reason(int err) const;
347 internal::pq::PGconn *raw_connection() const
348 {
349 return largeobject::raw_connection(m_trans);
350 }
351
352 PQXX_PRIVATE void open(openmode mode);
353 void close() noexcept;
354
355 dbtransaction &m_trans;
356 int m_fd = -1;
357};
358
359
361
372template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
373class largeobject_streambuf : public std::basic_streambuf<CHAR, TRAITS>
374{
375 using size_type = largeobject::size_type;
376
377public:
378 using char_type = CHAR;
379 using traits_type = TRAITS;
380 using int_type = typename traits_type::int_type;
381 using pos_type = typename traits_type::pos_type;
382 using off_type = typename traits_type::off_type;
385
387 static constexpr auto default_mode{
388 std::ios::in | std::ios::out | std::ios::binary};
389
390#include "pqxx/internal/ignore-deprecated-pre.hxx"
391 [[deprecated("Use blob instead.")]] largeobject_streambuf(
392 dbtransaction &t, largeobject o, openmode mode = default_mode,
393 size_type buf_size = 512) :
394 m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr}
395 {
396 initialize(mode);
397 }
398#include "pqxx/internal/ignore-deprecated-post.hxx"
399
400 [[deprecated("Use blob instead.")]] largeobject_streambuf(
401 dbtransaction &t, oid o, openmode mode = default_mode,
402 size_type buf_size = 512) :
403 m_bufsize{buf_size}, m_obj{t, o, mode}, m_g{nullptr}, m_p{nullptr}
404 {
405 initialize(mode);
406 }
407
408 virtual ~largeobject_streambuf() noexcept
409 {
410 delete[] m_p;
411 delete[] m_g;
412 }
413
415 void process_notice(zview const &s) { m_obj.process_notice(s); }
416
417protected:
418 virtual int sync() override
419 {
420 // setg() sets eback, gptr, egptr.
421 this->setg(this->eback(), this->eback(), this->egptr());
422 return overflow(eof());
423 }
424
425 virtual pos_type seekoff(off_type offset, seekdir dir, openmode) override
426 {
427 return adjust_eof(m_obj.cseek(largeobjectaccess::off_type(offset), dir));
428 }
429
430 virtual pos_type seekpos(pos_type pos, openmode) override
431 {
432 largeobjectaccess::pos_type const newpos{
433 m_obj.cseek(largeobjectaccess::off_type(pos), std::ios::beg)};
434 return adjust_eof(newpos);
435 }
436
437 virtual int_type overflow(int_type ch) override
438 {
439 auto *const pp{this->pptr()};
440 if (pp == nullptr)
441 return eof();
442 auto *const pb{this->pbase()};
443 int_type res{0};
444
445 if (pp > pb)
446 {
447 auto const write_sz{pp - pb};
448 auto const written_sz{
449 m_obj.cwrite(pb, static_cast<std::size_t>(pp - pb))};
450 if (internal::cmp_less_equal(written_sz, 0))
451 throw internal_error{
452 "pqxx::largeobject: write failed "
453 "(is transaction still valid on write or flush?), "
454 "libpq reports error"};
455 else if (write_sz != written_sz)
456 throw internal_error{
457 "pqxx::largeobject: write failed "
458 "(is transaction still valid on write or flush?), " +
459 std::to_string(written_sz) + "/" + std::to_string(write_sz) +
460 " bytes written"};
461 auto const out{adjust_eof(written_sz)};
462
463 if constexpr (std::is_arithmetic_v<decltype(out)>)
464 res = check_cast<int_type>(out, "largeobject position"sv);
465 else
466 res = int_type(out);
467 }
468 this->setp(m_p, m_p + m_bufsize);
469
470 // Write that one more character, if it's there.
471 if (ch != eof())
472 {
473 *this->pptr() = static_cast<char_type>(ch);
474 this->pbump(1);
475 }
476 return res;
477 }
478
479 virtual int_type overflow() { return overflow(eof()); }
480
481 virtual int_type underflow() override
482 {
483 if (this->gptr() == nullptr)
484 return eof();
485 auto *const eb{this->eback()};
486 auto const res{adjust_eof(
487 m_obj.cread(this->eback(), static_cast<std::size_t>(m_bufsize)))};
488 this->setg(
489 eb, eb, eb + (res == eof() ? 0 : static_cast<std::size_t>(res)));
490 return (res == eof() or res == 0) ? eof() : traits_type::to_int_type(*eb);
491 }
492
493private:
495 static int_type eof() { return traits_type::eof(); }
496
498 template<typename INTYPE> static std::streampos adjust_eof(INTYPE pos)
499 {
500 bool const at_eof{pos == -1};
501 if constexpr (std::is_arithmetic_v<std::streampos>)
502 {
503 return check_cast<std::streampos>(
504 (at_eof ? eof() : pos), "large object seek"sv);
505 }
506 else
507 {
508 return std::streampos(at_eof ? eof() : pos);
509 }
510 }
511
512 void initialize(openmode mode)
513 {
514 if ((mode & std::ios::in) != 0)
515 {
516 m_g = new char_type[unsigned(m_bufsize)];
517 this->setg(m_g, m_g, m_g);
518 }
519 if ((mode & std::ios::out) != 0)
520 {
521 m_p = new char_type[unsigned(m_bufsize)];
522 this->setp(m_p, m_p + m_bufsize);
523 }
524 }
525
526 size_type const m_bufsize;
527 largeobjectaccess m_obj;
528
530 char_type *m_g, *m_p;
531};
532
533
535
544template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
545class basic_ilostream : public std::basic_istream<CHAR, TRAITS>
546{
547 using super = std::basic_istream<CHAR, TRAITS>;
548
549public:
550 using char_type = CHAR;
551 using traits_type = TRAITS;
552 using int_type = typename traits_type::int_type;
553 using pos_type = typename traits_type::pos_type;
554 using off_type = typename traits_type::off_type;
555
556#include "pqxx/internal/ignore-deprecated-pre.hxx"
558
563 [[deprecated("Use blob instead.")]] basic_ilostream(
564 dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) :
565 super{nullptr},
566 m_buf{t, o, std::ios::in | std::ios::binary, buf_size}
567 {
568 super::init(&m_buf);
569 }
570#include "pqxx/internal/ignore-deprecated-post.hxx"
571
573
578 [[deprecated("Use blob instead.")]] basic_ilostream(
579 dbtransaction &t, oid o, largeobject::size_type buf_size = 512) :
580 super{nullptr},
581 m_buf{t, o, std::ios::in | std::ios::binary, buf_size}
582 {
583 super::init(&m_buf);
584 }
585
586private:
588};
589
591
592
594
602template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
603class basic_olostream : public std::basic_ostream<CHAR, TRAITS>
604{
605 using super = std::basic_ostream<CHAR, TRAITS>;
606
607public:
608 using char_type = CHAR;
609 using traits_type = TRAITS;
610 using int_type = typename traits_type::int_type;
611 using pos_type = typename traits_type::pos_type;
612 using off_type = typename traits_type::off_type;
613
614#include "pqxx/internal/ignore-deprecated-pre.hxx"
616
621 [[deprecated("Use blob instead.")]] basic_olostream(
622 dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) :
623 super{nullptr},
624 m_buf{t, o, std::ios::out | std::ios::binary, buf_size}
625 {
626 super::init(&m_buf);
627 }
628#include "pqxx/internal/ignore-deprecated-post.hxx"
629
631
636 [[deprecated("Use blob instead.")]] basic_olostream(
637 dbtransaction &t, oid o, largeobject::size_type buf_size = 512) :
638 super{nullptr},
639 m_buf{t, o, std::ios::out | std::ios::binary, buf_size}
640 {
641 super::init(&m_buf);
642 }
643
645 {
646 try
647 {
648 m_buf.pubsync();
649 m_buf.pubsync();
650 }
651 catch (std::exception const &e)
652 {
653 m_buf.process_notice(e.what());
654 }
655 }
656
657private:
659};
660
662
663
665
674template<typename CHAR = char, typename TRAITS = std::char_traits<CHAR>>
675class basic_lostream : public std::basic_iostream<CHAR, TRAITS>
676{
677 using super = std::basic_iostream<CHAR, TRAITS>;
678
679public:
680 using char_type = CHAR;
681 using traits_type = TRAITS;
682 using int_type = typename traits_type::int_type;
683 using pos_type = typename traits_type::pos_type;
684 using off_type = typename traits_type::off_type;
685
687
692 [[deprecated("Use blob instead.")]] basic_lostream(
693 dbtransaction &t, largeobject o, largeobject::size_type buf_size = 512) :
694 super{nullptr},
695 m_buf{
696 t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size}
697 {
698 super::init(&m_buf);
699 }
700
702
707 [[deprecated("Use blob instead.")]] basic_lostream(
708 dbtransaction &t, oid o, largeobject::size_type buf_size = 512) :
709 super{nullptr},
710 m_buf{
711 t, o, std::ios::in | std::ios::out | std::ios::binary, buf_size}
712 {
713 super::init(&m_buf);
714 }
715
717 {
718 try
719 {
720 m_buf.pubsync();
721 m_buf.pubsync();
722 }
723 catch (std::exception const &e)
724 {
725 m_buf.process_notice(e.what());
726 }
727 }
728
729private:
731};
732
734} // namespace pqxx
735#endif
The home of all libpqxx classes, functions, templates, etc.
Definition array.hxx:33
constexpr oid oid_none
The "null" oid.
Definition util.hxx:342
int64_t large_object_size_type
Number of bytes in a large object.
Definition types.hxx:43
constexpr bool cmp_less_equal(LEFT lhs, RIGHT rhs) noexcept
C++20 std::cmp_less_equal, or workaround if not available.
Definition util.hxx:98
Definition blob.hxx:53
Connection to a database.
Definition connection.hxx:253
Abstract transaction base class: bracket transactions on the database.
Definition dbtransaction.hxx:54
Internal error in libpqxx library.
Definition except.hxx:242
Identity of a large object.
Definition largeobject.hxx:34
bool operator==(largeobject const &other) const
Compare object identities.
Definition largeobject.hxx:89
bool operator>=(largeobject const &other) const
Compare object identities.
Definition largeobject.hxx:107
static PQXX_PURE internal::pq::PGconn * raw_connection(dbtransaction const &T)
Definition largeobject.cxx:139
bool operator<=(largeobject const &other) const
Compare object identities.
Definition largeobject.hxx:101
large_object_size_type size_type
Definition largeobject.hxx:36
bool operator<(largeobject const &other) const
Compare object identities.
Definition largeobject.hxx:113
largeobject() noexcept=default
void to_file(dbtransaction &t, std::string_view file) const
Export large object's contents to a local file.
Definition largeobject.cxx:107
bool operator!=(largeobject const &other) const
Compare object identities.
Definition largeobject.hxx:95
bool operator>(largeobject const &other) const
Compare object identities.
Definition largeobject.hxx:119
oid id() const noexcept
Object identifier.
Definition largeobject.hxx:77
Accessor for large object's contents.
Definition largeobject.hxx:154
size_type pos_type
Definition largeobject.hxx:158
std::ios::openmode openmode
Open mode: in, out (can be combined using "bitwise or").
Definition largeobject.hxx:168
std::ios::seekdir seekdir
Seek direction: beg, cur, end.
Definition largeobject.hxx:175
void to_file(std::string_view file) const
Export large object's contents to a local file.
Definition largeobject.hxx:228
~largeobjectaccess() noexcept
Definition largeobject.hxx:216
void write(std::string_view buf)
Write string to large object.
Definition largeobject.hxx:251
size_type off_type
Definition largeobject.hxx:157
Streambuf to use large objects in standard I/O streams.
Definition largeobject.hxx:374
virtual pos_type seekoff(off_type offset, seekdir dir, openmode) override
Definition largeobject.hxx:425
virtual int_type overflow(int_type ch) override
Definition largeobject.hxx:437
TRAITS traits_type
Definition largeobject.hxx:379
typename traits_type::int_type int_type
Definition largeobject.hxx:380
virtual pos_type seekpos(pos_type pos, openmode) override
Definition largeobject.hxx:430
largeobject_streambuf(dbtransaction &t, oid o, openmode mode=default_mode, size_type buf_size=512)
Definition largeobject.hxx:400
CHAR char_type
Definition largeobject.hxx:378
typename traits_type::off_type off_type
Definition largeobject.hxx:382
virtual int_type overflow()
Definition largeobject.hxx:479
virtual ~largeobject_streambuf() noexcept
Definition largeobject.hxx:408
void process_notice(zview const &s)
For use by large object stream classes.
Definition largeobject.hxx:415
virtual int sync() override
Definition largeobject.hxx:418
largeobjectaccess::seekdir seekdir
Definition largeobject.hxx:384
virtual int_type underflow() override
Definition largeobject.hxx:481
largeobjectaccess::openmode openmode
Definition largeobject.hxx:383
typename traits_type::pos_type pos_type
Definition largeobject.hxx:381
largeobject_streambuf(dbtransaction &t, largeobject o, openmode mode=default_mode, size_type buf_size=512)
Definition largeobject.hxx:391
Input stream that gets its data from a large object.
Definition largeobject.hxx:546
basic_ilostream(dbtransaction &t, oid o, largeobject::size_type buf_size=512)
Create a basic_ilostream.
Definition largeobject.hxx:578
CHAR char_type
Definition largeobject.hxx:550
basic_ilostream(dbtransaction &t, largeobject o, largeobject::size_type buf_size=512)
Create a basic_ilostream.
Definition largeobject.hxx:563
typename traits_type::int_type int_type
Definition largeobject.hxx:552
TRAITS traits_type
Definition largeobject.hxx:551
typename traits_type::off_type off_type
Definition largeobject.hxx:554
typename traits_type::pos_type pos_type
Definition largeobject.hxx:553
Output stream that writes data back to a large object.
Definition largeobject.hxx:604
typename traits_type::off_type off_type
Definition largeobject.hxx:612
typename traits_type::pos_type pos_type
Definition largeobject.hxx:611
basic_olostream(dbtransaction &t, largeobject o, largeobject::size_type buf_size=512)
Create a basic_olostream.
Definition largeobject.hxx:621
typename traits_type::int_type int_type
Definition largeobject.hxx:610
~basic_olostream()
Definition largeobject.hxx:644
CHAR char_type
Definition largeobject.hxx:608
basic_olostream(dbtransaction &t, oid o, largeobject::size_type buf_size=512)
Create a basic_olostream.
Definition largeobject.hxx:636
TRAITS traits_type
Definition largeobject.hxx:609
Stream that reads and writes a large object.
Definition largeobject.hxx:676
typename traits_type::pos_type pos_type
Definition largeobject.hxx:683
~basic_lostream()
Definition largeobject.hxx:716
typename traits_type::int_type int_type
Definition largeobject.hxx:682
typename traits_type::off_type off_type
Definition largeobject.hxx:684
basic_lostream(dbtransaction &t, largeobject o, largeobject::size_type buf_size=512)
Create a basic_lostream.
Definition largeobject.hxx:692
basic_lostream(dbtransaction &t, oid o, largeobject::size_type buf_size=512)
Create a basic_lostream.
Definition largeobject.hxx:707
TRAITS traits_type
Definition largeobject.hxx:681
CHAR char_type
Definition largeobject.hxx:680
Marker-type wrapper: zero-terminated std::string_view.
Definition zview.hxx:38