13 #ifndef PQXX_H_STREAM_TO
14 #define PQXX_H_STREAM_TO
16 #include "pqxx/compiler-public.hxx"
17 #include "pqxx/internal/compiler-internal-pre.hxx"
19 #include "pqxx/separated_list.hxx"
20 #include "pqxx/transaction_base.hxx"
69 class PQXX_LIBEXPORT
stream_to : internal::transactionfocus
83 template<
typename Columns>
88 template<
typename Iter>
95 [[nodiscard]]
operator bool() const noexcept {
return not m_finished; }
96 [[nodiscard]]
bool operator!() const noexcept {
return m_finished; }
149 fill_buffer(fields...);
154 bool m_finished =
false;
157 std::string m_buffer;
160 std::string m_field_buf;
163 void write_raw_line(std::string_view);
171 static constexpr std::string_view null_field{
"\\N\t"};
175 static std::enable_if_t<nullness<T>::always_null, std::size_t>
176 estimate_buffer(T
const &)
178 return null_field.size();
186 static std::enable_if_t<not nullness<T>::always_null, std::size_t>
187 estimate_buffer(T
const &field)
189 return is_null(field) ? null_field.size() :
194 void escape_field_to_buffer(std::string_view);
203 template<
typename Field>
204 std::enable_if_t<not nullness<Field>::always_null>
205 append_to_buffer(Field
const &f)
213 m_buffer.append(null_field);
219 using traits = string_traits<Field>;
220 auto const budget{estimate_buffer(f)};
221 auto const offset{m_buffer.size()};
223 if constexpr (std::is_arithmetic_v<Field>)
231 auto const total{offset + budget};
232 m_buffer.resize(total);
233 char *
const end{traits::into_buf(
234 m_buffer.data() + offset, m_buffer.data() + total, f)};
237 m_buffer.resize(
static_cast<std::size_t
>(end - m_buffer.data()));
244 m_field_buf.resize(budget);
245 escape_field_to_buffer(traits::to_buf(
246 m_field_buf.data(), m_field_buf.data() + m_field_buf.size(), f));
258 template<
typename Field>
259 std::enable_if_t<nullness<Field>::always_null>
260 append_to_buffer(Field
const &)
262 m_buffer.append(null_field);
266 template<
typename Container>
void fill_buffer(Container
const &c)
271 std::size_t budget{0};
272 for (
auto const &f : c) budget += estimate_buffer(f);
273 m_buffer.reserve(budget);
274 for (
auto const &f : c) append_to_buffer(f);
278 template<
typename Tuple, std::size_t... indexes>
280 budget_tuple(Tuple
const &t, std::index_sequence<indexes...>)
282 return (estimate_buffer(std::get<indexes>(t)) + ...);
286 template<
typename Tuple, std::size_t... indexes>
287 void append_tuple(Tuple
const &t, std::index_sequence<indexes...>)
289 (append_to_buffer(std::get<indexes>(t)), ...);
293 template<
typename... Elts>
void fill_buffer(std::tuple<Elts...>
const &t)
295 using indexes = std::make_index_sequence<
sizeof...(Elts)>;
297 m_buffer.reserve(budget_tuple(t, indexes{}));
298 append_tuple(t, indexes{});
301 void set_up(transaction_base &, std::string_view table_name);
303 transaction_base &, std::string_view table_name,
304 std::string
const &columns);
307 template<
typename... Ts>
void fill_buffer(
const Ts &... fields)
309 (..., append_to_buffer(fields));
314 template<
typename Columns>
316 transaction_base &tb, std::string_view table_name, Columns
const &columns) :
317 stream_to{tb, table_name, std::begin(columns), std::end(columns)}
321 template<
typename Iter>
325 namedclass{
"stream_to", table_name}, internal::transactionfocus{tb}
327 set_up(tb, table_name,
separated_list(
",", columns_begin, columns_end));
331 #include "pqxx/internal/compiler-internal-post.hxx"