13 #ifndef PQXX_INTERNAL_STREAM_QUERY_HXX
14 #define PQXX_INTERNAL_STREAM_QUERY_HXX
16 #if !defined(PQXX_HEADER_PRE)
17 # error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
27 class transaction_base;
70 using line_handle = std::unique_ptr<
char[], void (*)(
void const *)>;
87 catch (std::exception
const &e)
94 [[nodiscard]]
bool done() const & noexcept
96 return m_char_finder ==
nullptr;
100 [[nodiscard]]
inline auto begin() &;
114 auto const line_size{std::size(line)};
124 m_row.resize(line_size + 1);
126 std::size_t offset{0u};
127 char *write{m_row.data()};
134 std::tuple<TYPE...> data{parse_field<TYPE>(line, offset, write, m_ctx)...};
136 assert(offset == line_size + 1u);
141 std::pair<line_handle, std::size_t>
read_line(
sl) &;
166 std::tuple<std::size_t, char *, std::string_view>
167 read_field(std::string_view line, std::size_t offset,
char *write,
ctx c)
170 auto const line_size{std::size(line)};
173 assert(offset <= line_size);
175 char const *lp{std::data(line)};
179 assert(lp[line_size] ==
'\t');
180 assert(lp[line_size + 1] ==
'\0');
182 if ((lp[offset] ==
'\\') and (lp[offset + 1] ==
'N'))
186 assert(offset <= (line_size + 1));
187 assert(lp[offset - 1] ==
'\t');
189 return {offset, write, {}};
193 char const *
const field_begin{write};
202 while (lp[offset] !=
'\t')
204 assert(lp[offset] !=
'\0');
210 auto const stop_char{m_char_finder(line, offset, c.loc)};
212 assert(stop_char < (line_size + 1));
215 std::memcpy(write, &lp[offset], stop_char - offset);
216 write += (stop_char - offset);
220 char const special{lp[offset]};
226 assert(offset < line_size);
230 char const escaped{lp[offset]};
235 assert((escaped >> 7) == 0);
242 assert(special ==
'\t');
247 assert(lp[offset] ==
'\t');
254 {field_begin,
static_cast<std::size_t
>(write - field_begin - 1)}};
271 template<
typename TARGET>
273 parse_field(std::string_view line, std::size_t &offset,
char *&write,
ctx c)
275 using field_type = std::remove_cvref_t<TARGET>;
277 assert(offset <= std::size(line));
279 auto [new_offset, new_write,
text]{read_field(line, offset, write, c)};
284 if constexpr (pqxx::always_null<TARGET>())
286 if (std::data(text) !=
nullptr)
288 "Streaming a non-null value into a {}, which must always be null.",
289 name_type<field_type>())};
291 else if (std::data(text) ==
nullptr)
293 if constexpr (has_null<TARGET>())
301 return from_string<field_type>(text, c);
306 void close() noexcept
310 m_char_finder =
nullptr;
330 conversion_context
const m_ctx;
Stream query results from the database. Used by transaction_base::stream.
Definition: stream_query.hxx:68
stream_query(transaction_base &tx, std::string_view query, conversion_context c)
Execute query on tx, stream results.
Definition: stream_query_impl.hxx:12
bool done() const &noexcept
Has this stream reached the end of its data?
Definition: stream_query.hxx:94
stream_query & operator=(stream_query &&)=delete
stream_query(stream_query const &)=delete
std::pair< line_handle, std::size_t > read_line(sl) &
Read a COPY line from the server.
Definition: stream_query_impl.hxx:151
std::tuple< TYPE... > parse_line(std::string_view line) &
Parse and convert the latest line of data we received.
Definition: stream_query.hxx:110
~stream_query() noexcept
Definition: stream_query.hxx:81
stream_query & operator=(stream_query const &)=delete
stream_query(stream_query &&)=delete
std::unique_ptr< char[], void(*)(void const *)> line_handle
Definition: stream_query.hxx:70
auto begin() &
Begin iterator. Only for use by "range for.".
Definition: stream_query_impl.hxx:143
auto end() const &
End iterator. Only for use by "range for.".
Definition: stream_query.hxx:107
Base class for things that monopolise a transaction's attention.
Definition: transaction_focus.hxx:29
void unregister_me() noexcept
Definition: transaction_base.cxx:568
void reg_pending_error(std::string const &, sl) noexcept
Definition: transaction_base.cxx:576
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:151
Private namespace for libpqxx's internal use; do not access.
Definition: connection.cxx:333
void throw_null_conversion(std::string const &type, sl loc)
Throw exception for attempt to convert SQL NULL to given type.
Definition: strconv.cxx:142
constexpr PQXX_PURE char unescape_char(char escaped) noexcept
Return original byte for escaped character.
Definition: util.hxx:617
std::size_t(std::string_view haystack, std::size_t start, sl) char_finder_func
Function type: "find first occurrence of any of these ASCII characters.".
Definition: encoding_group.hxx:110
The end() iterator for a stream_query.
Definition: stream_query.hxx:35
The home of all libpqxx classes, functions, templates, etc.
Definition: array.cxx:26
constexpr TYPE make_null() requires(pqxx
Return a null value of TYPE.
Definition: strconv.hxx:781
std::source_location sl
Convenience alias for std::source_location. It's just too long.
Definition: types.hxx:38
constexpr std::string_view name_type() noexcept
Return human-readable name for TYPE.
Definition: types.hxx:277
conversion_context const & ctx
Convenience alias: const reference to a pqxx::conversion_context.
Definition: strconv.hxx:201
format
Format code: is data text or binary?
Definition: types.hxx:121
Contextual parameters for string conversions implementations.
Definition: strconv.hxx:163