libpqxx
stream_from.hxx
1
13#ifndef PQXX_H_STREAM_FROM
14#define PQXX_H_STREAM_FROM
15
16#include "pqxx/compiler-public.hxx"
17#include "pqxx/compiler-internal-pre.hxx"
18#include "pqxx/transaction_base.hxx"
19#include "pqxx/stream_base.hxx"
20#include "pqxx/internal/type_utils.hxx"
21
22#include <string>
23
24
25namespace pqxx
26{
27
29class PQXX_LIBEXPORT stream_from : public stream_base
30{
31public:
34 const std::string &table_name
35 );
36 template<typename Columns> stream_from(
38 const std::string &table_name,
39 const Columns& columns
40 );
41 template<typename Iter> stream_from(
43 const std::string &table_name,
44 Iter columns_begin,
45 Iter columns_end
46 );
47
48 ~stream_from() noexcept;
49
50 void complete() override;
51
52 bool get_raw_line(std::string &);
53 template<typename Tuple> stream_from & operator>>(Tuple &);
54
55private:
56 internal::encoding_group m_copy_encoding;
57 std::string m_current_line;
58 bool m_retry_line;
59
60 void set_up(transaction_base &, const std::string &table_name);
61 void set_up(
63 const std::string &table_name,
64 const std::string &columns
65 );
66
67 void close() override;
68
69 bool extract_field(
70 const std::string &,
71 std::string::size_type &,
72 std::string &
73 ) const;
74
75 template<typename Tuple, std::size_t I> auto tokenize_ith(
76 const std::string &,
77 Tuple &,
78 std::string::size_type,
79 std::string &
80 ) const -> typename std::enable_if<(
81 std::tuple_size<Tuple>::value > I
82 )>::type;
83 template<typename Tuple, std::size_t I> auto tokenize_ith(
84 const std::string &,
85 Tuple &,
86 std::string::size_type,
87 std::string &
88 ) const -> typename std::enable_if<(
89 std::tuple_size<Tuple>::value <= I
90 )>::type;
91
92 template<typename T> void extract_value(
93 const std::string &line,
94 T& t,
95 std::string::size_type &here,
96 std::string &workspace
97 ) const;
98};
99
100
101template<typename Columns> stream_from::stream_from(
103 const std::string &table_name,
104 const Columns& columns
105) : stream_from{
106 tb,
107 table_name,
108 std::begin(columns),
109 std::end(columns)
110} {}
111
112
113template<typename Iter> stream_from::stream_from(
115 const std::string &table_name,
116 Iter columns_begin,
117 Iter columns_end
118) :
119 namedclass{"stream_from", table_name},
120 stream_base{tb}
121{
122 set_up(
123 tb,
124 table_name,
125 columnlist(columns_begin, columns_end)
126 );
127}
128
129
130template<typename Tuple> stream_from & stream_from::operator>>(
131 Tuple &t
132)
133{
134 if (m_retry_line or get_raw_line(m_current_line))
135 {
136 std::string workspace;
137 try
138 {
139 tokenize_ith<Tuple, 0>(m_current_line, t, 0, workspace);
140 m_retry_line = false;
141 }
142 catch (...)
143 {
144 m_retry_line = true;
145 throw;
146 }
147 }
148 return *this;
149}
150
151
152template<typename Tuple, std::size_t I> auto stream_from::tokenize_ith(
153 const std::string &line,
154 Tuple &t,
155 std::string::size_type here,
156 std::string &workspace
157) const -> typename std::enable_if<(
158 std::tuple_size<Tuple>::value > I
159)>::type
160{
161 if (here >= line.size())
162 throw usage_error{"Too few fields to extract from stream_from line."};
163
164 extract_value(line, std::get<I>(t), here, workspace);
165 tokenize_ith<Tuple, I+1>(line, t, here, workspace);
166}
167
168
169template<typename Tuple, std::size_t I> auto stream_from::tokenize_ith(
170 const std::string &line,
171 Tuple & /* t */,
172 std::string::size_type here,
173 std::string & /* workspace */
174) const -> typename std::enable_if<(
175 std::tuple_size<Tuple>::value <= I
176)>::type
177{
178 // Zero-column line may still have a trailing newline
179 if (
180 here < line.size() and
181 not (here == line.size() - 1 and line[here] == '\n'))
182 throw usage_error{"Not all fields extracted from stream_from line"};
183}
184
185
186template<typename T> void stream_from::extract_value(
187 const std::string &line,
188 T& t,
189 std::string::size_type &here,
190 std::string &workspace
191) const
192{
193 if (extract_field(line, here, workspace))
194 from_string<T>(workspace, t);
195 else
196 t = internal::null_value<T>();
197}
198
199template<> void stream_from::extract_value<std::nullptr_t>(
200 const std::string &line,
201 std::nullptr_t&,
202 std::string::size_type &here,
203 std::string &workspace
204) const;
205
206} // namespace pqxx
207
208
209#include "pqxx/compiler-internal-post.hxx"
210#endif
STL namespace.
The home of all libpqxx classes, functions, templates, etc.
Definition: array.hxx:26
Error in usage of libpqxx library, similar to std::logic_error.
Definition: except.hxx:220
Definition: stream_base.hxx:29
static std::string columnlist(const C &)
Definition: stream_base.hxx:48
Efficiently pull data directly out of a table.
Definition: stream_from.hxx:30
stream_from & operator>>(Tuple &)
Definition: stream_from.hxx:130
stream_from(transaction_base &, const std::string &table_name)
Definition: stream_from.cxx:41
bool get_raw_line(std::string &)
Definition: stream_from.cxx:72
Interface definition (and common code) for "transaction" classes.
Definition: transaction_base.hxx:138