libpqxx  7.0.1
stream_from.hxx
1 /* Definition of the pqxx::stream_from class.
2  *
3  * pqxx::stream_from enables optimized batch reads from a database table.
4  *
5  * DO NOT INCLUDE THIS FILE DIRECTLY; include pqxx/stream_from instead.
6  *
7  * Copyright (c) 2000-2020, Jeroen T. Vermeulen.
8  *
9  * See COPYING for copyright license. If you did not receive a file called
10  * COPYING with this source code, please notify the distributor of this
11  * mistake, or contact the author.
12  */
13 #ifndef PQXX_H_STREAM_FROM
14 #define PQXX_H_STREAM_FROM
15 
16 #include "pqxx/compiler-public.hxx"
17 #include "pqxx/internal/compiler-internal-pre.hxx"
18 
19 #include "pqxx/separated_list.hxx"
20 #include "pqxx/transaction_base.hxx"
21 #include <variant>
22 
23 
24 namespace pqxx
25 {
28 {
29 public:
30  stream_from(transaction_base &, std::string_view table_name);
31  template<typename Columns>
33  transaction_base &, std::string_view table_name, Columns const &columns);
34  template<typename Iter>
36  transaction_base &, std::string_view table_name, Iter columns_begin,
37  Iter columns_end);
38 
39  ~stream_from() noexcept;
40 
41  [[nodiscard]] operator bool() const noexcept { return not m_finished; }
42  [[nodiscard]] bool operator!() const noexcept { return m_finished; }
43 
45 
51  void complete();
52 
53  bool get_raw_line(std::string &);
54  template<typename Tuple> stream_from &operator>>(Tuple &);
55 
57  template<typename... Vs>
58  stream_from &operator>>(std::variant<Vs...> &) = delete;
59 
60 private:
61  internal::encoding_group m_copy_encoding =
62  internal::encoding_group::MONOBYTE;
63  std::string m_current_line;
64  bool m_finished = false;
65  bool m_retry_line = false;
66 
67  void set_up(transaction_base &, std::string_view table_name);
68  void set_up(
69  transaction_base &, std::string_view table_name,
70  std::string const &columns);
71 
72  void close();
73 
74  bool extract_field(
75  std::string const &, std::string::size_type &, std::string &) const;
76 
77  template<typename T>
78  void extract_value(
79  std::string const &line, T &t, std::string::size_type &here,
80  std::string &workspace) const;
81 
82  template<typename Tuple, std::size_t... I>
83  void do_extract(
84  const std::string &line, Tuple &t, std::string &workspace,
85  std::index_sequence<I...>)
86  {
87  std::string::size_type here{};
88  (extract_value(line, std::get<I>(t), here, workspace), ...);
89  if (
90  here < line.size() and
91  not(here == line.size() - 1 and line[here] == '\n'))
92  throw usage_error{"Not all fields extracted from stream_from line"};
93  }
94 };
95 
96 
97 template<typename Columns>
99  transaction_base &tb, std::string_view table_name, Columns const &columns) :
100  stream_from{tb, table_name, std::begin(columns), std::end(columns)}
101 {}
102 
103 
104 template<typename Iter>
106  transaction_base &tb, std::string_view table_name, Iter columns_begin,
107  Iter columns_end) :
108  namedclass{"stream_from", table_name}, transactionfocus{tb}
109 {
110  set_up(tb, table_name, separated_list(",", columns_begin, columns_end));
111 }
112 
113 
114 template<typename Tuple> stream_from &stream_from::operator>>(Tuple &t)
115 {
116  if (m_retry_line or get_raw_line(m_current_line))
117  {
118  std::string workspace;
119  try
120  {
121  constexpr auto tsize = std::tuple_size_v<Tuple>;
122  using indexes = std::make_index_sequence<tsize>;
123  do_extract(m_current_line, t, workspace, indexes{});
124  m_retry_line = false;
125  }
126  catch (...)
127  {
128  m_retry_line = true;
129  throw;
130  }
131  }
132  return *this;
133 }
134 
135 
136 template<typename T>
137 void stream_from::extract_value(
138  std::string const &line, T &t, std::string::size_type &here,
139  std::string &workspace) const
140 {
141  if (extract_field(line, here, workspace))
142  t = from_string<T>(workspace);
143  else if constexpr (nullness<T>::has_null)
144  t = nullness<T>::null();
145  else
146  internal::throw_null_conversion(type_name<T>);
147 }
148 
149 template<>
150 void PQXX_LIBEXPORT stream_from::extract_value<std::nullptr_t>(
151  std::string const &line, std::nullptr_t &, std::string::size_type &here,
152  std::string &workspace) const;
153 } // namespace pqxx
154 
155 #include "pqxx/internal/compiler-internal-post.hxx"
156 #endif
stream_from(transaction_base &, std::string_view table_name)
Definition: stream_from.cxx:58
Definition: transaction_base.hxx:42
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
bool operator!() const noexcept
Definition: stream_from.hxx:42
Dedicated namespace for helper types related to prepared statements.
Definition: array.hxx:25
Efficiently pull data directly out of a table.
Definition: stream_from.hxx:27
bool get_raw_line(std::string &)
Definition: stream_from.cxx:80
stream_from & operator>>(Tuple &)
Definition: stream_from.hxx:114