13#ifndef PQXX_H_STREAM_TO
14#define PQXX_H_STREAM_TO
16#if !defined(PQXX_HEADER_PRE)
17# error "Include libpqxx headers as <pqxx/header>, not <pqxx/header.hxx>."
20#include "pqxx/separated_list.hxx"
21#include "pqxx/transaction_base.hxx"
107 return {
tx,
path, columns};
122 std::initializer_list<std::string_view> columns = {})
124 auto const &conn{
tx.conn()};
125 return raw_table(
tx, conn.quote_table(
path), conn.quote_columns(columns));
128#if defined(PQXX_HAVE_CONCEPTS)
137 template<PQXX_CHAR_STRINGS_ARG COLUMNS>
141 auto const &conn{
tx.conn()};
143 tx, conn.quote_table(
path),
tx.conn().quote_columns(columns));
154 template<PQXX_CHAR_STRINGS_ARG COLUMNS>
156 table(transaction_base &
tx, std::string_view
path,
COLUMNS const &columns)
166 m_finished{
other.m_finished},
167 m_buffer{std::move(
other.m_buffer)},
168 m_field_buf{std::move(
other.m_field_buf)},
169 m_finder{
other.m_finder}
171 other.m_finished =
true;
178 return not m_finished;
251 [[deprecated(
"Use table() or raw_table() factory.")]]
stream_to(
259 template<
typename Columns>
260 [[deprecated(
"Use table() or raw_table() factory.")]]
stream_to(
266 template<
typename Iter>
267 [[deprecated(
"Use table() or raw_table() factory.")]]
stream_to(
276 bool m_finished =
false;
279 std::string m_buffer;
282 std::string m_field_buf;
285 internal::char_finder_func *m_finder;
288 void write_raw_line(std::string_view);
296 static constexpr std::string_view null_field{
"\\N\t"};
300 static std::enable_if_t<nullness<T>::always_null, std::size_t>
301 estimate_buffer(T
const &)
303 return std::size(null_field);
311 static std::enable_if_t<not nullness<T>::always_null, std::size_t>
312 estimate_buffer(T
const &field)
318 void escape_field_to_buffer(std::string_view data);
327 template<
typename Field>
328 std::enable_if_t<not nullness<Field>::always_null>
329 append_to_buffer(
Field const &
f)
337 m_buffer.append(null_field);
344 auto const budget{estimate_buffer(
f)};
345 auto const offset{std::size(m_buffer)};
347 if constexpr (std::is_arithmetic_v<Field>)
356 m_buffer.resize(
total);
357 auto const data{m_buffer.data()};
358 char *
const end{traits::into_buf(data +
offset, data +
total,
f)};
361 m_buffer.resize(
static_cast<std::size_t
>(end - data));
364 std::is_same_v<Field, std::string>
or
365 std::is_same_v<Field, std::string_view>
or
366 std::is_same_v<Field, zview>)
369 m_field_buf.resize(
budget);
370 escape_field_to_buffer(
f);
373 std::is_same_v<Field, std::optional<std::string>>
or
374 std::is_same_v<Field, std::optional<std::string_view>>
or
375 std::is_same_v<Field, std::optional<zview>>)
379 m_field_buf.resize(
budget);
380 escape_field_to_buffer(
f.value());
384 std::is_same_v<Field, std::unique_ptr<std::string>>
or
385 std::is_same_v<Field, std::unique_ptr<std::string_view>>
or
386 std::is_same_v<Field, std::unique_ptr<zview>>
or
387 std::is_same_v<Field, std::shared_ptr<std::string>>
or
388 std::is_same_v<Field, std::shared_ptr<std::string_view>>
or
389 std::is_same_v<Field, std::shared_ptr<zview>>)
394 m_field_buf.resize(
budget);
395 escape_field_to_buffer(*
f);
401 m_field_buf.resize(
budget);
402 auto const data{m_field_buf.data()};
403 escape_field_to_buffer(
404 traits::to_buf(data, data + std::size(m_field_buf),
f));
416 template<
typename Field>
417 std::enable_if_t<nullness<Field>::always_null>
418 append_to_buffer(
Field const &)
420 m_buffer.append(null_field);
424 template<
typename Container>
425 std::enable_if_t<not std::is_same_v<typename Container::value_type, char>>
432 for (
auto const &
f :
c)
budget += estimate_buffer(
f);
434 for (
auto const &
f :
c) append_to_buffer(
f);
440 budget_tuple(
Tuple const &
t, std::index_sequence<indexes...>)
442 return (estimate_buffer(std::get<indexes>(
t)) + ...);
447 void append_tuple(
Tuple const &
t, std::index_sequence<indexes...>)
449 (append_to_buffer(std::get<indexes>(
t)), ...);
453 template<
typename...
Elts>
void fill_buffer(std::tuple<Elts...>
const &
t)
455 using indexes = std::make_index_sequence<
sizeof...(Elts)>;
457 m_buffer.reserve(budget_tuple(
t,
indexes{}));
462 template<
typename...
Ts>
void fill_buffer(
const Ts &...
fields)
464 (..., append_to_buffer(
fields));
467 constexpr static std::string_view s_classname{
"stream_to"};
471template<
typename Columns>
478template<
typename Iter>
487 return tx.quote_name(*col);
The home of all libpqxx classes, functions, templates, etc.
Definition array.hxx:33
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:44
std::basic_ostream< CHAR > & operator<<(std::basic_ostream< CHAR > &s, field const &value)
Write a result field to any type of stream.
Definition field.hxx:520
constexpr char array_separator
Element separator between SQL array elements of this type.
Definition strconv.hxx:557
std::size_t size_buffer(TYPE const &...value) noexcept
Estimate how much buffer space is needed to represent values as a string.
Definition strconv.hxx:524
std::initializer_list< std::string_view > table_path
Representation of a PostgreSQL table path.
Definition connection.hxx:185
constexpr bool is_null(TYPE const &value) noexcept
Is value null?
Definition strconv.hxx:513
Reference to one row in a result.
Definition row.hxx:47
Stream data from the database.
Definition stream_from.hxx:79
Efficiently write data directly to a database table.
Definition stream_to.hxx:81
static stream_to raw_table(transaction_base &tx, std::string_view path, std::string_view columns="")
Stream data to a pre-quoted table and columns.
Definition stream_to.hxx:104
constexpr bool operator!() const noexcept
Has this stream been through its concluding complete()?
Definition stream_to.hxx:181
static stream_to table(transaction_base &tx, table_path path, std::initializer_list< std::string_view > columns={})
Create a stream_to writing to a named table and columns.
Definition stream_to.hxx:120
void write_values(Ts const &...fields)
Insert values as a row.
Definition stream_to.hxx:235
stream_to(transaction_base &tx, std::string_view table_name)
Create a stream, without specifying columns.
Definition stream_to.hxx:251
stream_to(stream_to &&other)
Definition stream_to.hxx:162
stream_to & operator<<(Row const &row)
Insert a row of data.
Definition stream_to.hxx:205
void write_row(Row const &row)
Insert a row of data, given in the form of a std::tuple or container.
Definition stream_to.hxx:225
Interface definition (and common code) for "transaction" classes.
Definition transaction_base.hxx:88
Base class for things that monopolise a transaction's attention.
Definition transaction_focus.hxx:29