libpqxx
The C++ client library for PostgreSQL
Loading...
Searching...
No Matches
blob.hxx
Go to the documentation of this file.
1/* Binary Large Objects interface.
2 *
3 * Read or write large objects, stored in their own storage on the server.
4 *
5 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/largeobject instead.
6 *
7 * Copyright (c) 2000-2025, Jeroen T. Vermeulen.
8 *
9 * See COPYING for copyright license. If you did not receive a file called
10 * COPYING with this source code, please notify the distributor of this
11 * mistake, or contact the author.
12 */
13#ifndef PQXX_H_BLOB
14#define PQXX_H_BLOB
15
16#if !defined(PQXX_HEADER_PRE)
17# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
18#endif
19
20#include <cstdint>
21
22#if defined(PQXX_HAVE_PATH)
23# include <filesystem>
24#endif
25
26// C++20: Assume support.
27#if defined(PQXX_HAVE_RANGES)
28# include <ranges>
29#endif
30
31// C++20: Assume support.
32#if __has_include(<span>)
33# include <span>
34#endif
35
37
38
39namespace pqxx
40{
54class PQXX_LIBEXPORT blob
55{
56public:
58
62 [[nodiscard]] static oid create(dbtransaction &, oid = 0);
63
65 static void remove(dbtransaction &, oid);
66
68 [[nodiscard]] static blob open_r(dbtransaction &, oid);
69 // Open blob for writing. Any attempt to read from it will fail.
70 [[nodiscard]] static blob open_w(dbtransaction &, oid);
71 // Open blob for reading and/or writing.
72 [[nodiscard]] static blob open_rw(dbtransaction &, oid);
73
75
78 blob() = default;
79
81 blob(blob &&);
83 blob &operator=(blob &&);
84
85 blob(blob const &) = delete;
86 blob &operator=(blob const &) = delete;
87 ~blob();
88
90
96 static constexpr std::size_t chunk_limit = 0x7fffffff;
97
99
107 std::size_t read(bytes &buf, std::size_t size);
108
109#if defined(PQXX_HAVE_SPAN)
111
116 template<std::size_t extent = std::dynamic_extent>
117 std::span<std::byte> read(std::span<std::byte, extent> buf)
118 {
119 return buf.subspan(0, raw_read(std::data(buf), std::size(buf)));
120 }
121#endif // PQXX_HAVE_SPAN
122
123#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES) && \
124 defined(PQXX_HAVE_SPAN)
126
131 template<binary DATA> std::span<std::byte> read(DATA &buf)
132 {
133 return {std::data(buf), raw_read(std::data(buf), std::size(buf))};
134 }
135#else // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN
137
149 template<typename ALLOC> bytes_view read(std::vector<std::byte, ALLOC> &buf)
150 {
151 return {std::data(buf), raw_read(std::data(buf), std::size(buf))};
152 }
153#endif // PQXX_HAVE_CONCEPTS && PQXX_HAVE_SPAN
154
155#if defined(PQXX_HAVE_CONCEPTS) && defined(PQXX_HAVE_RANGES)
157
175 template<binary DATA> void write(DATA const &data)
176 {
177 raw_write(std::data(data), std::size(data));
178 }
179#else
181
199 template<typename DATA> void write(DATA const &data)
200 {
201 raw_write(std::data(data), std::size(data));
202 }
203#endif
204
206
212 void resize(std::int64_t size);
213
215 [[nodiscard]] std::int64_t tell() const;
216
218
219 std::int64_t seek_abs(std::int64_t offset = 0);
221
225 std::int64_t seek_rel(std::int64_t offset = 0);
227
231 std::int64_t seek_end(std::int64_t offset = 0);
232
234
237 static oid from_buf(dbtransaction &tx, bytes_view data, oid id = 0);
238
240
242 static void append_from_buf(dbtransaction &tx, bytes_view data, oid id);
243
245 [[nodiscard]] static oid from_file(dbtransaction &, char const path[]);
246
247#if defined(PQXX_HAVE_PATH) && !defined(_WIN32)
249
252 [[nodiscard]] static oid
253 from_file(dbtransaction &tx, std::filesystem::path const &path)
254 {
255 return from_file(tx, path.c_str());
256 }
257#endif
258
260
263 static oid from_file(dbtransaction &, char const path[], oid);
264
265#if defined(PQXX_HAVE_PATH) && !defined(_WIN32)
267
273 static oid
274 from_file(dbtransaction &tx, std::filesystem::path const &path, oid id)
275 {
276 return from_file(tx, path.c_str(), id);
277 }
278#endif
279
281
284 static void to_buf(dbtransaction &, oid, bytes &, std::size_t max_size);
285
287
293 static std::size_t append_to_buf(
294 dbtransaction &tx, oid id, std::int64_t offset, bytes &buf,
295 std::size_t append_max);
296
298 static void to_file(dbtransaction &, oid, char const path[]);
299
300#if defined(PQXX_HAVE_PATH) && !defined(_WIN32)
302
305 static void
306 to_file(dbtransaction &tx, oid id, std::filesystem::path const &path)
307 {
308 to_file(tx, id, path.c_str());
309 }
310#endif
311
313
324 void close();
325
326private:
327 PQXX_PRIVATE blob(connection &cx, int fd) noexcept : m_conn{&cx}, m_fd{fd} {}
328 static PQXX_PRIVATE blob open_internal(dbtransaction &, oid, int);
330 raw_conn(pqxx::connection *) noexcept;
332 raw_conn(pqxx::dbtransaction const &) noexcept;
333 static PQXX_PRIVATE std::string errmsg(connection const *);
334 static PQXX_PRIVATE std::string errmsg(dbtransaction const &tx)
335 {
336 return errmsg(&tx.conn());
337 }
338 PQXX_PRIVATE std::string errmsg() const { return errmsg(m_conn); }
339 PQXX_PRIVATE std::int64_t seek(std::int64_t offset, int whence);
340 std::size_t raw_read(std::byte buf[], std::size_t size);
341 void raw_write(std::byte const buf[], std::size_t size);
342
343 connection *m_conn = nullptr;
344 int m_fd = -1;
345};
346} // namespace pqxx
347#endif
#define PQXX_LIBEXPORT
Definition header-pre.hxx:157
#define PQXX_PRIVATE
Definition header-pre.hxx:158
pg_conn PGconn
Definition libpq-forward.hxx:24
The home of all libpqxx classes, functions, templates, etc.
Definition array.cxx:27
unsigned int oid
PostgreSQL database row identifier.
Definition libpq-forward.hxx:33
std::vector< std::string_view > to_buf(char *here, char const *end, TYPE... value)
Convert multiple values to strings inside a single buffer.
Definition strconv.hxx:494
std::conditional< has_generic_bytes_char_traits, std::basic_string_view< std::byte >, std::basic_string_view< std::byte, byte_char_traits > >::type bytes_view
Type alias for a view of bytes.
Definition util.hxx:383