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 std::size(null_field);
186 static std::enable_if_t<not nullness<T>::always_null, std::size_t>
187 estimate_buffer(T
const &field)
193 void escape_field_to_buffer(std::string_view);
202 template<
typename Field>
203 std::enable_if_t<not nullness<Field>::always_null>
204 append_to_buffer(Field
const &f)
212 m_buffer.append(null_field);
218 using traits = string_traits<Field>;
219 auto const budget{estimate_buffer(f)};
220 auto const offset{std::size(m_buffer)};
222 if constexpr (std::is_arithmetic_v<Field>)
230 auto const total{offset + budget};
231 m_buffer.resize(total);
232 char *
const end{traits::into_buf(
233 m_buffer.data() + offset, m_buffer.data() + total, f)};
236 m_buffer.resize(static_cast<std::size_t>(end - m_buffer.data()));
243 m_field_buf.resize(budget);
244 escape_field_to_buffer(traits::to_buf(
245 m_field_buf.data(), m_field_buf.data() + std::size(m_field_buf), f));
257 template<
typename Field>
258 std::enable_if_t<nullness<Field>::always_null>
259 append_to_buffer(Field
const &)
261 m_buffer.append(null_field);
265 template<
typename Container>
void fill_buffer(Container
const &c)
270 std::size_t budget{0};
271 for (
auto const &f : c) budget += estimate_buffer(f);
272 m_buffer.reserve(budget);
273 for (
auto const &f : c) append_to_buffer(f);
277 template<
typename Tuple, std::size_t... indexes>
279 budget_tuple(Tuple
const &t, std::index_sequence<indexes...>)
281 return (estimate_buffer(std::get<indexes>(t)) + ...);
285 template<
typename Tuple, std::size_t... indexes>
286 void append_tuple(Tuple
const &t, std::index_sequence<indexes...>)
288 (append_to_buffer(std::get<indexes>(t)), ...);
292 template<
typename... Elts>
void fill_buffer(std::tuple<Elts...>
const &t)
294 using indexes = std::make_index_sequence<
sizeof...(Elts)>;
296 m_buffer.reserve(budget_tuple(t, indexes{}));
297 append_tuple(t, indexes{});
300 void set_up(transaction_base &, std::string_view table_name);
302 transaction_base &, std::string_view table_name,
303 std::string
const &columns);
306 template<
typename... Ts>
void fill_buffer(
const Ts &... fields)
308 (..., append_to_buffer(fields));
313 template<
typename Columns>
315 transaction_base &tb, std::string_view table_name, Columns
const &columns) :
316 stream_to{tb, table_name, std::begin(columns), std::end(columns)}
320 template<
typename Iter>
324 namedclass{
"stream_to", table_name}, internal::transactionfocus{tb}
326 set_up(tb, table_name,
separated_list(
",", columns_begin, columns_end));
330 #include "pqxx/internal/compiler-internal-post.hxx" Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:67
std::size_t size_buffer(TYPE const &value) noexcept
Estimate how much buffer space is needed to represent value as a string.
Definition: strconv.hxx:321
Efficiently write data directly to a database table.
Definition: stream_to.hxx:69
Stream data from the database.
Definition: stream_from.hxx:60
bool operator!() const noexcept
Definition: stream_to.hxx:96
bool is_null(TYPE const &value) noexcept
Is value null?
Definition: strconv.hxx:310
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:40
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:25
Reference to one row in a result.
Definition: row.hxx:43
stream_to(transaction_base &, std::string_view table_name)
Create a stream, without specifying columns.
Definition: stream_to.cxx:46
void write_values(const Ts &... fields)
Insert values as a row.
Definition: stream_to.hxx:147
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:137
stream_to & operator<<(Row const &row)
Insert a row of data.
Definition: stream_to.hxx:117
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:366