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>
139 table(transaction_base &tx, table_path path, COLUMNS
const &columns)
141 auto const &conn{tx.conn()};
142 return stream_to::raw_table(
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)
158 return stream_to::raw_table(tx, path, tx.conn().quote_columns(columns));
172 [[deprecated(
"Use table() or raw_table() factory.")]]
stream_to(
180 template<
typename Columns>
181 [[deprecated(
"Use table() or raw_table() factory.")]]
stream_to(
187 template<
typename Iter>
188 [[deprecated(
"Use table() or raw_table() factory.")]]
stream_to(
195 [[nodiscard]] constexpr operator
bool() const noexcept
197 return not m_finished;
256 fill_buffer(fields...);
265 bool m_finished =
false;
268 std::string m_buffer;
271 std::string m_field_buf;
274 internal::glyph_scanner_func *m_scanner;
277 void write_raw_line(std::string_view);
285 static constexpr std::string_view null_field{
"\\N\t"};
289 static std::enable_if_t<nullness<T>::always_null, std::size_t>
290 estimate_buffer(T
const &)
292 return std::size(null_field);
300 static std::enable_if_t<not nullness<T>::always_null, std::size_t>
301 estimate_buffer(T
const &field)
303 return is_null(field) ? std::size(null_field) : size_buffer(field);
307 void escape_field_to_buffer(std::string_view data);
316 template<
typename Field>
317 std::enable_if_t<not nullness<Field>::always_null>
318 append_to_buffer(Field
const &f)
326 m_buffer.append(null_field);
332 using traits = string_traits<Field>;
333 auto const budget{estimate_buffer(f)};
334 auto const offset{std::size(m_buffer)};
336 if constexpr (std::is_arithmetic_v<Field>)
344 auto const total{offset + budget};
345 m_buffer.resize(total);
346 auto const data{m_buffer.data()};
347 char *
const end{traits::into_buf(data + offset, data + total, f)};
350 m_buffer.resize(
static_cast<std::size_t
>(end - data));
353 std::is_same_v<Field, std::string> or
354 std::is_same_v<Field, std::string_view> or
355 std::is_same_v<Field, zview>)
358 m_field_buf.resize(budget);
359 escape_field_to_buffer(f);
365 m_field_buf.resize(budget);
366 auto const data{m_field_buf.data()};
367 escape_field_to_buffer(
368 traits::to_buf(data, data + std::size(m_field_buf), f));
380 template<
typename Field>
381 std::enable_if_t<nullness<Field>::always_null>
382 append_to_buffer(Field
const &)
384 m_buffer.append(null_field);
388 template<
typename Container>
389 std::enable_if_t<not std::is_same_v<typename Container::value_type, char>>
390 fill_buffer(Container
const &c)
395 std::size_t budget{0};
396 for (
auto const &f : c) budget += estimate_buffer(f);
397 m_buffer.reserve(budget);
398 for (
auto const &f : c) append_to_buffer(f);
402 template<
typename Tuple, std::size_t... indexes>
404 budget_tuple(Tuple
const &t, std::index_sequence<indexes...>)
406 return (estimate_buffer(std::get<indexes>(t)) + ...);
410 template<
typename Tuple, std::size_t... indexes>
411 void append_tuple(Tuple
const &t, std::index_sequence<indexes...>)
413 (append_to_buffer(std::get<indexes>(t)), ...);
417 template<
typename... Elts>
void fill_buffer(std::tuple<Elts...>
const &t)
419 using indexes = std::make_index_sequence<
sizeof...(Elts)>;
421 m_buffer.reserve(budget_tuple(t, indexes{}));
422 append_tuple(t, indexes{});
426 template<
typename... Ts>
void fill_buffer(
const Ts &...fields)
428 (..., append_to_buffer(fields));
431 constexpr static std::string_view s_classname{
"stream_to"};
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