libpqxx 7.7.5
stream_from.hxx
1/* Definition of the pqxx::stream_from class.
2 *
3 * pqxx::stream_from enables optimized batch reads from a database table.
4 *
5 * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_from instead.
6 *
7 * Copyright (c) 2000-2023, 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_STREAM_FROM
14#define PQXX_H_STREAM_FROM
15
16#if !defined(PQXX_HEADER_PRE)
17# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
18#endif
19
20#include <cassert>
21#include <functional>
22#include <variant>
23
24#include "pqxx/connection.hxx"
25#include "pqxx/except.hxx"
26#include "pqxx/internal/concat.hxx"
27#include "pqxx/internal/encoding_group.hxx"
28#include "pqxx/internal/stream_iterator.hxx"
29#include "pqxx/separated_list.hxx"
30#include "pqxx/transaction_focus.hxx"
31
32
33namespace pqxx
34{
35class transaction_base;
36
37
39
43
46
47
49
77class PQXX_LIBEXPORT stream_from : transaction_focus
78{
79public:
80 using raw_line =
81 std::pair<std::unique_ptr<char, std::function<void(char *)>>, std::size_t>;
82
84
93 static stream_from query(transaction_base &tx, std::string_view q)
94 {
95#include "pqxx/internal/ignore-deprecated-pre.hxx"
96 return {tx, from_query, q};
97#include "pqxx/internal/ignore-deprecated-post.hxx"
98 }
99
110
112
128 static stream_from raw_table(
129 transaction_base &tx, std::string_view path,
130 std::string_view columns = ""sv);
131
133
135 static stream_from table(
137 std::initializer_list<std::string_view> columns = {});
139
141
143 [[deprecated("Use query() factory instead.")]] stream_from(
144 transaction_base &, from_query_t, std::string_view query);
145
147
149 [[deprecated("Use table() or raw_table() factory instead.")]] stream_from(
150 transaction_base &, from_table_t, std::string_view table);
151
153
155 template<typename Iter>
156 [[deprecated("Use table() or raw_table() factory instead.")]] stream_from(
157 transaction_base &, from_table_t, std::string_view table,
158 Iter columns_begin, Iter columns_end);
159
161
163 template<typename Columns>
164 [[deprecated("Use table() or raw_table() factory instead.")]] stream_from(
165 transaction_base &tx, from_table_t, std::string_view table,
166 Columns const &columns);
167
168#include "pqxx/internal/ignore-deprecated-pre.hxx"
170 [[deprecated("Use the from_table_t overload instead.")]] stream_from(
171 transaction_base &tx, std::string_view table) :
172 stream_from{tx, from_table, table}
173 {}
174#include "pqxx/internal/ignore-deprecated-post.hxx"
175
177 template<typename Columns>
178 [[deprecated("Use the from_table_t overload instead.")]] stream_from(
179 transaction_base &tx, std::string_view table, Columns const &columns) :
180 stream_from{tx, from_table, table, columns}
181 {}
182
184 template<typename Iter>
185 [[deprecated("Use the from_table_t overload instead.")]] stream_from(
186 transaction_base &, std::string_view table, Iter columns_begin,
187 Iter columns_end);
188
189 ~stream_from() noexcept;
190
192 [[nodiscard]] constexpr operator bool() const noexcept
193 {
194 return not m_finished;
195 }
197 [[nodiscard]] constexpr bool operator!() const noexcept
198 {
199 return m_finished;
200 }
201
203
209 void complete();
210
212
219 template<typename Tuple> stream_from &operator>>(Tuple &);
220
222 template<typename... Vs>
223 stream_from &operator>>(std::variant<Vs...> &) = delete;
224
226
230 template<typename... TYPE> [[nodiscard]] auto iter() &
231 {
232 return pqxx::internal::stream_input_iteration<TYPE...>{*this};
233 }
234
236
252 std::vector<zview> const *read_row() &;
253
255
256 raw_line get_raw_line();
257
258private:
259 // TODO: Clean up this signature once we cull the deprecated constructors.
262 transaction_base &tx, std::string_view table, std::string_view columns,
264
265 // TODO: Clean up this signature once we cull the deprecated constructors.
268 transaction_base &, std::string_view unquoted_table,
269 std::string_view columns, from_table_t, int);
270
271 template<typename Tuple, std::size_t... indexes>
272 void extract_fields(Tuple &t, std::index_sequence<indexes...>) const
273 {
274 (extract_value<Tuple, indexes>(t), ...);
275 }
276
277 pqxx::internal::glyph_scanner_func *m_glyph_scanner;
278
280 std::string m_row;
281
283 std::vector<zview> m_fields;
284
285 bool m_finished = false;
286
287 void close();
288
289 template<typename Tuple, std::size_t index>
290 void extract_value(Tuple &) const;
291
293 void parse_line();
294};
295
296
297template<typename Columns>
299 transaction_base &tx, from_table_t, std::string_view table_name,
300 Columns const &columns) :
302 tx, from_table, table_name, std::begin(columns), std::end(columns)}
303{}
304
305
306template<typename Iter>
308 transaction_base &tx, from_table_t, std::string_view table,
309 Iter columns_begin, Iter columns_end) :
311 tx, table, separated_list(",", columns_begin, columns_end),
312 from_table, 1}
313{}
314
315
316template<typename Tuple> inline stream_from &stream_from::operator>>(Tuple &t)
317{
318 if (m_finished)
319 return *this;
320 static constexpr auto tup_size{std::tuple_size_v<Tuple>};
321 m_fields.reserve(tup_size);
322 parse_line();
323 if (m_finished)
324 return *this;
325
326 if (std::size(m_fields) != tup_size)
327 throw usage_error{internal::concat(
328 "Tried to extract ", tup_size, " field(s) from a stream of ",
329 std::size(m_fields), ".")};
330
331 extract_fields(t, std::make_index_sequence<tup_size>{});
332 return *this;
333}
334
335
336template<typename Tuple, std::size_t index>
337inline void stream_from::extract_value(Tuple &t) const
338{
339 using field_type = strip_t<decltype(std::get<index>(t))>;
340 using nullity = nullness<field_type>;
341 assert(index < std::size(m_fields));
342 if constexpr (nullity::always_null)
343 {
344 if (std::data(m_fields[index]) != nullptr)
345 throw conversion_error{"Streaming non-null value into null field."};
346 }
347 else if (std::data(m_fields[index]) == nullptr)
348 {
349 if constexpr (nullity::has_null)
350 std::get<index>(t) = nullity::null();
351 else
352 internal::throw_null_conversion(type_name<field_type>);
353 }
354 else
355 {
356 // Don't ever try to convert a non-null value to nullptr_t!
357 std::get<index>(t) = from_string<field_type>(m_fields[index]);
358 }
359}
360} // namespace pqxx
361#endif
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:27
std::string separated_list(std::string_view sep, ITER begin, ITER end, ACCESS access)
Represent sequence of values as a string, joined by a given separator.
Definition: separated_list.hxx:43
std::remove_cv_t< std::remove_reference_t< TYPE > > strip_t
Remove any constness, volatile, and reference-ness from a type.
Definition: types.hxx:91
constexpr from_query_t from_query
Pass this to a stream_from constructor to stream query results.
Definition: stream_from.hxx:45
constexpr from_table_t from_table
Pass this to a stream_from constructor to stream table contents.
Definition: stream_from.hxx:41
std::initializer_list< std::string_view > table_path
Representation of a PostgreSQL table path.
Definition: connection.hxx:123
void PQXX_COLD throw_null_conversion(std::string const &type)
Definition: strconv.cxx:253
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:174
Value conversion failed, e.g. when converting "Hello" to int.
Definition: except.hxx:188
Traits describing a type's "null value," if any.
Definition: strconv.hxx:93
Stream data from the database.
Definition: stream_from.hxx:78
static stream_from query(transaction_base &tx, std::string_view q)
Factory: Execute query, and stream the results.
Definition: stream_from.hxx:93
std::pair< std::unique_ptr< char, std::function< void(char *)> >, std::size_t > raw_line
Definition: stream_from.hxx:81
stream_from & operator>>(std::variant< Vs... > &)=delete
Doing this with a std::variant is going to be horrifically borked.
stream_from(transaction_base &, from_query_t, std::string_view query)
Execute query, and stream over the results.
Definition: stream_from.cxx:39
stream_from & operator>>(Tuple &)
Read one row into a tuple.
Definition: stream_from.hxx:316
stream_from(transaction_base &tx, std::string_view table, Columns const &columns)
Definition: stream_from.hxx:178
stream_from(transaction_base &, std::string_view table, Iter columns_begin, Iter columns_end)
stream_from(transaction_base &tx, std::string_view table)
Definition: stream_from.hxx:170
auto iter() &
Iterate over this stream. Supports range-based "for" loops.
Definition: stream_from.hxx:230
constexpr bool operator!() const noexcept
Has this stream produced all the data it is going to produce?
Definition: stream_from.hxx:197
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:77
Base class for things that monopolise a transaction's attention.
Definition: transaction_focus.hxx:29
Marker for stream_from constructors: "stream from table.".
Definition: types.hxx:68
Marker for stream_from constructors: "stream from query.".
Definition: types.hxx:74