13#ifndef PQXX_H_STREAM_QUERY
14#define PQXX_H_STREAM_QUERY
16#if !defined(PQXX_HEADER_PRE)
17# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
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/encodings.hxx"
29#include "pqxx/internal/gates/connection-stream_from.hxx"
30#include "pqxx/internal/stream_iterator.hxx"
31#include "pqxx/separated_list.hxx"
32#include "pqxx/transaction_base.hxx"
33#include "pqxx/transaction_focus.hxx"
34#include "pqxx/util.hxx"
39class transaction_base;
82 using line_handle = std::unique_ptr<char, void (*)(
void const *)>;
88 transaction_base &tx, std::string_view query, params
const &);
99 catch (std::exception
const &e)
101 reg_pending_error(e.what());
106 bool done() const & noexcept {
return m_char_finder ==
nullptr; }
122 auto const line_size{std::size(line)};
132 m_row.resize(line_size + 1);
134 std::size_t offset{0u};
135 char *write{m_row.data()};
142 std::tuple<TYPE...> data{parse_field<TYPE>(line, offset, write)...};
144 assert(offset == line_size + 1u);
173 std::tuple<std::size_t, char *, zview>
174 read_field(
zview line, std::size_t offset,
char *write)
177 auto const line_size{std::size(line)};
180 assert(offset <= line_size);
182 char const *lp{std::data(line)};
186 assert(lp[line_size] ==
'\t');
187 assert(lp[line_size + 1] ==
'\0');
189 if ((lp[offset] ==
'\\') and (lp[offset + 1] ==
'N'))
193 assert(offset <= (line_size + 1));
194 assert(lp[offset - 1] ==
'\t');
196 return {offset, write, {}};
200 char const *
const field_begin{write};
209 while (lp[offset] !=
'\t')
211 assert(lp[offset] !=
'\0');
214 auto const stop_char{m_char_finder(line, offset)};
215 PQXX_ASSUME(stop_char > offset);
216 assert(stop_char < (line_size + 1));
219 std::memcpy(write, &lp[offset], stop_char - offset);
220 write += (stop_char - offset);
224 char const special{lp[offset]};
230 assert(offset < line_size);
234 char const escaped{lp[offset]};
235 assert((escaped >> 7) == 0);
242 assert(special ==
'\t');
247 assert(lp[offset] ==
'\t');
251 return {offset, write, {field_begin, write - field_begin - 1}};
268 template<
typename TARGET>
269 TARGET parse_field(zview line, std::size_t &offset,
char *&write)
272 using nullity = nullness<field_type>;
274 assert(offset <= std::size(line));
276 auto [new_offset, new_write, text]{read_field(line, offset, write)};
277 PQXX_ASSUME(new_offset > offset);
278 PQXX_ASSUME(new_write >= write);
281 if constexpr (nullity::always_null)
283 if (std::data(text) !=
nullptr)
284 throw conversion_error{
concat(
286 ", which must always be null.")};
288 else if (std::data(text) ==
nullptr)
290 if constexpr (nullity::has_null)
291 return nullity::null();
303 void close() noexcept
307 m_char_finder =
nullptr;
bool done() const &noexcept
Has this stream reached the end of its data?
Definition stream_query.hxx:106
stream_query(transaction_base &tx, std::string_view query)
Execute query on tx, stream results.
Definition stream_query_impl.hxx:12
std::tuple< TYPE... > parse_line(zview line) &
Parse and convert the latest line of data we received.
Definition stream_query.hxx:118
auto begin() &
Begin iterator. Only for use by "range for.".
Definition stream_query_impl.hxx:166
stream_query(transaction_base &tx, std::string_view query, params const &)
Execute query on tx, stream results.
Definition stream_query_impl.hxx:24
std::pair< line_handle, std::size_t > read_line() &
Read a COPY line from the server.
Definition stream_query_impl.hxx:174
auto end() const &
End iterator. Only for use by "range for.".
Definition stream_query.hxx:115
Marker-type wrapper: zero-terminated std::string_view.
Definition zview.hxx:38
Internal items for libpqxx' own use. Do not use these yourself.
Definition encodings.cxx:33
std::string concat(TYPE... item)
Efficiently combine a bunch of items into one big string.
Definition concat.hxx:31
void throw_null_conversion(std::string const &type)
Throw exception for attempt to convert SQL NULL to given type.
Definition strconv.cxx:264
std::size_t(std::string_view haystack, std::size_t start) char_finder_func
Function type: "find first occurrence of specific any of ASCII characters.".
Definition encoding_group.hxx:70
constexpr char unescape_char(char escaped) noexcept
Return original byte for escaped character.
Definition util.hxx:633
The end() iterator for a stream_query.
Definition stream_query.hxx:47
The home of all libpqxx classes, functions, templates, etc.
Definition array.cxx:27
std::string const type_name
A human-readable name for a type, used in error messages and such.
Definition strconv.hxx:80
std::remove_cv_t< std::remove_reference_t< TYPE > > strip_t
Remove any constness, volatile, and reference-ness from a type.
Definition types.hxx:80
T from_string(field const &value)
Convert a field's value to type T.
Definition field.hxx:548